ldb: skip indexes on full_search
authorAaron Haslett <aaronhaslett@catalyst.net.nz>
Tue, 23 Jul 2019 23:46:01 +0000 (11:46 +1200)
committerAndrew Bartlett <abartlet@samba.org>
Fri, 2 Aug 2019 02:29:42 +0000 (02:29 +0000)
Use iterate_range kv op to skip the index section of the database when
running a full search. Quick local testing showed 18% improved throughput
on a full search with no results on a 50k database. With more results,
improvement is smaller but still noticeable.

Signed-off-by: Aaron Haslett <aaronhaslett@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Garming Sam <garming@catalyst.net.nz>
Autobuild-User(master): Andrew Bartlett <abartlet@samba.org>
Autobuild-Date(master): Fri Aug  2 02:29:42 UTC 2019 on sn-devel-184

lib/ldb/ldb_key_value/ldb_kv_search.c

index f2d961981512161bd86c173cc868bff3329c685b..a0e1762bc9027113b0395ed0ab0931ed883b5099 100644 (file)
@@ -408,6 +408,18 @@ static int search_func(_UNUSED_ struct ldb_kv_private *ldb_kv,
        return 0;
 }
 
+/*
+ * Key pointing to just before the first GUID indexed record for
+ * iterate_range
+ */
+struct ldb_val start_of_db_key = {.data=discard_const_p(uint8_t, "GUID<"),
+                                 .length=6};
+/*
+ * Key pointing to just after the last GUID indexed record for
+ * iterate_range
+ */
+struct ldb_val end_of_db_key = {.data=discard_const_p(uint8_t, "GUID>"),
+                               .length=6};
 
 /*
   search the database with a LDAP-like expression.
@@ -420,8 +432,23 @@ static int ldb_kv_search_full(struct ldb_kv_context *ctx)
            talloc_get_type(data, struct ldb_kv_private);
        int ret;
 
+       /*
+        * If the backend has an iterate_range op, use it to start the search
+        * at the first GUID indexed record, skipping the indexes section.
+        */
        ctx->error = LDB_SUCCESS;
-       ret = ldb_kv->kv_ops->iterate(ldb_kv, search_func, ctx);
+       ret = ldb_kv->kv_ops->iterate_range(ldb_kv,
+                                           start_of_db_key,
+                                           end_of_db_key,
+                                           search_func,
+                                           ctx);
+       if (ret == LDB_ERR_OPERATIONS_ERROR) {
+               /*
+                * If iterate_range isn't defined, it'll return an error,
+                * so just iterate over the whole DB.
+                */
+               ret = ldb_kv->kv_ops->iterate(ldb_kv, search_func, ctx);
+       }
 
        if (ret < 0) {
                return LDB_ERR_OPERATIONS_ERROR;