diff options
author | June McEnroe <june@causal.agency> | 2019-12-26 15:49:29 -0500 |
---|---|---|
committer | June McEnroe <june@causal.agency> | 2019-12-26 15:49:29 -0500 |
commit | fdd34239fc386f72b7be7210a647cca5ac467f21 (patch) | |
tree | bf9911c78952685598b7a095121575666f3383d4 | |
parent | Handle ERROR (diff) | |
download | litterbox-fdd34239fc386f72b7be7210a647cca5ac467f21.tar.gz litterbox-fdd34239fc386f72b7be7210a647cca5ac467f21.zip |
Use bsearch to find handler
The code is a bit cleaner this way I think, and performance would be better if the list of handlers ever got very long, and it was sorted anyway. However, I would prefer if there were a way to enforce the list being sorted at compile-time.
-rw-r--r-- | litterbox.c | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/litterbox.c b/litterbox.c index 3a54bf5..57d30cb 100644 --- a/litterbox.c +++ b/litterbox.c @@ -443,7 +443,7 @@ static void handleError(struct Message *msg) { errx(EX_UNAVAILABLE, "%s", msg->params[0]); } -static const struct { +static const struct Handler { const char *cmd; bool transaction; Handler *fn; @@ -469,18 +469,23 @@ static const struct { { "TOPIC", true, handleTopic }, }; +static int compar(const void *cmd, const void *_handler) { + const struct Handler *handler = _handler; + return strcmp(cmd, handler->cmd); +} + static void handle(struct Message msg) { if (!msg.cmd) return; - for (size_t i = 0; i < ARRAY_LEN(Handlers); ++i) { - if (strcmp(msg.cmd, Handlers[i].cmd)) continue; - if (Handlers[i].transaction) { - dbExec(SQL(BEGIN TRANSACTION;)); - Handlers[i].fn(&msg); - dbExec(SQL(COMMIT TRANSACTION;)); - } else { - Handlers[i].fn(&msg); - } - break; + const struct Handler *handler = bsearch( + msg.cmd, Handlers, ARRAY_LEN(Handlers), sizeof(*handler), compar + ); + if (!handler) return; + if (handler->transaction) { + dbExec(SQL(BEGIN TRANSACTION;)); + handler->fn(&msg); + dbExec(SQL(COMMIT TRANSACTION;)); + } else { + handler->fn(&msg); } } |