summaryrefslogtreecommitdiff
path: root/source3/lib/dbwrap
diff options
context:
space:
mode:
Diffstat (limited to 'source3/lib/dbwrap')
-rw-r--r--source3/lib/dbwrap/dbwrap_rbt.c89
1 files changed, 43 insertions, 46 deletions
diff --git a/source3/lib/dbwrap/dbwrap_rbt.c b/source3/lib/dbwrap/dbwrap_rbt.c
index 699f922fa5..db5b8e866d 100644
--- a/source3/lib/dbwrap/dbwrap_rbt.c
+++ b/source3/lib/dbwrap/dbwrap_rbt.c
@@ -200,21 +200,22 @@ static NTSTATUS db_rbt_delete(struct db_record *rec)
return NT_STATUS_OK;
}
+struct db_rbt_search_result {
+ TDB_DATA key;
+ TDB_DATA val;
+ struct db_rbt_node* node;
+};
-static struct db_record *db_rbt_fetch_locked(struct db_context *db_ctx,
- TALLOC_CTX *mem_ctx,
- TDB_DATA key)
+static bool db_rbt_search_internal(struct db_context *db, TDB_DATA key,
+ struct db_rbt_search_result *result)
{
struct db_rbt_ctx *ctx = talloc_get_type_abort(
- db_ctx->private_data, struct db_rbt_ctx);
+ db->private_data, struct db_rbt_ctx);
- struct db_rbt_rec *rec_priv;
- struct db_record *result;
struct rb_node *n;
- size_t size;
bool found = false;
struct db_rbt_node *r = NULL;
- TDB_DATA search_key = tdb_null, search_val = tdb_null;
+ TDB_DATA search_key, search_val;
n = ctx->tree.rb_node;
@@ -238,6 +239,32 @@ static struct db_record *db_rbt_fetch_locked(struct db_context *db_ctx,
break;
}
}
+ if (result != NULL) {
+ if (found) {
+ result->key = search_key;
+ result->val = search_val;
+ result->node = r;
+ } else {
+ ZERO_STRUCT(*result);
+ }
+ }
+ return found;
+}
+
+static struct db_record *db_rbt_fetch_locked(struct db_context *db_ctx,
+ TALLOC_CTX *mem_ctx,
+ TDB_DATA key)
+{
+ struct db_rbt_ctx *ctx = talloc_get_type_abort(
+ db_ctx->private_data, struct db_rbt_ctx);
+
+ struct db_rbt_rec *rec_priv;
+ struct db_record *result;
+ size_t size;
+ bool found;
+ struct db_rbt_search_result res;
+
+ found = db_rbt_search_internal(db_ctx, key, &res);
/*
* In this low-level routine, play tricks to reduce the number of
@@ -268,19 +295,17 @@ static struct db_record *db_rbt_fetch_locked(struct db_context *db_ctx,
result->delete_rec = db_rbt_delete;
result->private_data = rec_priv;
+ rec_priv->node = res.node;
+ result->value = res.val;
+
if (found) {
- rec_priv->node = r;
- result->key = search_key;
- result->value = search_val;
+ result->key = res.key;
}
else {
- rec_priv->node = NULL;
result->key.dptr = (uint8 *)
((char *)rec_priv + sizeof(*rec_priv));
result->key.dsize = key.dsize;
memcpy(result->key.dptr, key.dptr, key.dsize);
-
- result->value = tdb_null;
}
return result;
@@ -289,51 +314,23 @@ static struct db_record *db_rbt_fetch_locked(struct db_context *db_ctx,
static int db_rbt_fetch(struct db_context *db, TALLOC_CTX *mem_ctx,
TDB_DATA key, TDB_DATA *data)
{
- struct db_rbt_ctx *ctx = talloc_get_type_abort(
- db->private_data, struct db_rbt_ctx);
-
- struct rb_node *n;
- bool found = false;
- struct db_rbt_node *r = NULL;
- TDB_DATA search_key, search_val;
uint8_t *result;
+ struct db_rbt_search_result res;
- n = ctx->tree.rb_node;
-
- while (n != NULL) {
- int res;
-
- r = db_rbt2node(n);
-
- db_rbt_parse_node(r, &search_key, &search_val);
-
- res = db_rbt_compare(key, search_key);
-
- if (res == -1) {
- n = n->rb_left;
- }
- else if (res == 1) {
- n = n->rb_right;
- }
- else {
- found = true;
- break;
- }
- }
+ bool found = db_rbt_search_internal(db, key, &res);
if (!found) {
*data = tdb_null;
return 0;
}
- result = (uint8 *)talloc_memdup(mem_ctx, search_val.dptr,
- search_val.dsize);
+ result = (uint8_t*)talloc_memdup(mem_ctx, res.val.dptr, res.val.dsize);
if (result == NULL) {
return -1;
}
data->dptr = result;
- data->dsize = search_val.dsize;
+ data->dsize = res.val.dsize;
return 0;
}