]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-dict: Added dict_iterate_set_limit()
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Sun, 16 Oct 2016 19:40:18 +0000 (22:40 +0300)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Wed, 19 Oct 2016 12:38:51 +0000 (15:38 +0300)
src/lib-dict/dict-private.h
src/lib-dict/dict.c
src/lib-dict/dict.h

index 43d768d87df08134a51a11e25870a2822cd539af..2abb80dc91dc22bdb555f4fc813acfad365e83ad 100644 (file)
@@ -54,6 +54,7 @@ struct dict_iterate_context {
        void *async_context;
 
        unsigned int has_more:1;
+       uint64_t row_count, max_rows;
 };
 
 struct dict_transaction_context {
index 5b775396af3eed7bad276f8f0cf0aede51fe0889..92d5570883fe21c1144fbb0b57a178d2c87fd2f9 100644 (file)
@@ -175,8 +175,16 @@ dict_iterate_init_multiple(struct dict *dict, const char *const *paths,
 bool dict_iterate(struct dict_iterate_context *ctx,
                  const char **key_r, const char **value_r)
 {
-       return ctx == &dict_iter_unsupported ? FALSE :
-               ctx->dict->v.iterate(ctx, key_r, value_r);
+       if (ctx == &dict_iter_unsupported)
+               return FALSE;
+       if (ctx->max_rows > 0 && ctx->row_count >= ctx->max_rows) {
+               /* row count was limited */
+               return FALSE;
+       }
+       if (!ctx->dict->v.iterate(ctx, key_r, value_r))
+               return FALSE;
+       ctx->row_count++;
+       return TRUE;
 }
 
 void dict_iterate_set_async_callback(struct dict_iterate_context *ctx,
@@ -187,6 +195,12 @@ void dict_iterate_set_async_callback(struct dict_iterate_context *ctx,
        ctx->async_context = context;
 }
 
+void dict_iterate_set_limit(struct dict_iterate_context *ctx,
+                           uint64_t max_rows)
+{
+       ctx->max_rows = max_rows;
+}
+
 bool dict_iterate_has_more(struct dict_iterate_context *ctx)
 {
        return ctx->has_more;
index 150834dba5be1ce7ed698065c764b258570e746c..69e213d41c4ace57cc82cd714b1b97b3eaf4baf0 100644 (file)
@@ -107,6 +107,10 @@ dict_iterate_init_multiple(struct dict *dict, const char *const *paths,
 void dict_iterate_set_async_callback(struct dict_iterate_context *ctx,
                                     dict_iterate_callback_t *callback,
                                     void *context);
+/* Limit how many rows will be returned by the iteration (0 = unlimited).
+   This allows backends to optimize the query (e.g. use LIMIT 1 with SQL). */
+void dict_iterate_set_limit(struct dict_iterate_context *ctx,
+                           uint64_t max_rows);
 /* If dict_iterate() returns FALSE, the iteration may be finished or if this
    is an async iteration it may be waiting for more data. If this function
    returns TRUE, the dict callback is called again with more data. */