changeset 20884:c9e829c8a36f

lib-dict: Added dict_iterate_set_limit()
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Sun, 16 Oct 2016 22:40:18 +0300
parents f57ce7cb62eb
children 3f713b46d3b3
files src/lib-dict/dict-private.h src/lib-dict/dict.c src/lib-dict/dict.h
diffstat 3 files changed, 21 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-dict/dict-private.h	Mon Oct 17 19:21:34 2016 +0300
+++ b/src/lib-dict/dict-private.h	Sun Oct 16 22:40:18 2016 +0300
@@ -54,6 +54,7 @@
 	void *async_context;
 
 	unsigned int has_more:1;
+	uint64_t row_count, max_rows;
 };
 
 struct dict_transaction_context {
--- a/src/lib-dict/dict.c	Mon Oct 17 19:21:34 2016 +0300
+++ b/src/lib-dict/dict.c	Sun Oct 16 22:40:18 2016 +0300
@@ -175,8 +175,16 @@
 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 @@
 	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;
--- a/src/lib-dict/dict.h	Mon Oct 17 19:21:34 2016 +0300
+++ b/src/lib-dict/dict.h	Sun Oct 16 22:40:18 2016 +0300
@@ -107,6 +107,10 @@
 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. */