s3:registry: remove the code to create and search the sorted subkeys cache records
authorMichael Adam <obnox@samba.org>
Fri, 1 Jul 2011 11:37:41 +0000 (13:37 +0200)
committerMichael Adam <obnox@samba.org>
Mon, 4 Jul 2011 18:02:09 +0000 (20:02 +0200)
This is not needed any more.

Pair-Programmed-With: Gregor Beck <gbeck@sernet.de>

source3/registry/reg_backend_db.c

index a9e06b30486f5afb48fdf6c0289683b61d2cce42..d9204a5a41ee2700852e91e8505209b9bd59007b 100644 (file)
@@ -49,7 +49,6 @@ static int regdb_fetch_values_internal(struct db_context *db, const char* key,
 static bool regdb_store_values_internal(struct db_context *db, const char *key,
                                        struct regval_ctr *values);
 
-static NTSTATUS create_sorted_subkeys(const char *key);
 static WERROR regdb_create_basekey(struct db_context *db, const char *key);
 static WERROR regdb_create_subkey_internal(struct db_context *db,
                                           const char *key,
@@ -1314,281 +1313,6 @@ done:
        return ret;
 }
 
-/*
- * regdb_key_exists() is a very frequent operation. It can be quite
- * time-consuming to fully fetch the parent's subkey list, talloc_strdup all
- * subkeys and then compare the keyname linearly to all the parent's subkeys.
- *
- * The following code tries to make this operation as efficient as possible:
- * Per registry key we create a list of subkeys that is very efficient to
- * search for existence of a subkey. Its format is:
- *
- * 4 bytes num_subkeys
- * 4*num_subkey bytes offset into the string array
- * then follows a sorted list of subkeys in uppercase
- *
- * This record is created by create_sorted_subkeys() on demand if it does not
- * exist. scan_parent_subkeys() uses regdb->parse_record to search the sorted
- * list, the parsing code and the binary search can be found in
- * parent_subkey_scanner. The code uses parse_record() to avoid a memcpy of
- * the potentially large subkey record.
- *
- * The sorted subkey record is deleted in regdb_store_keys_internal2 and
- * recreated on demand.
- */
-
-static int cmp_keynames(char **p1, char **p2)
-{
-       return strcasecmp_m(*p1, *p2);
-}
-
-struct create_sorted_subkeys_context {
-       const char *key;
-       const char *sorted_keyname;
-};
-
-static NTSTATUS create_sorted_subkeys_action(struct db_context *db,
-                                            void *private_data)
-{
-       char **sorted_subkeys;
-       struct regsubkey_ctr *ctr;
-       NTSTATUS status;
-       char *buf;
-       char *p;
-       int i;
-       size_t len;
-       int num_subkeys;
-       struct create_sorted_subkeys_context *sorted_ctx;
-
-       sorted_ctx = (struct create_sorted_subkeys_context *)private_data;
-
-       /*
-        * In this function, we only treat failing of the actual write to
-        * the db as a real error. All preliminary errors, at a stage when
-        * nothing has been written to the DB yet are treated as success
-        * to be committed (as an empty transaction).
-        *
-        * The reason is that this (disposable) call might be nested in other
-        * transactions. Doing a cancel here would destroy the possibility of
-        * a transaction_commit for transactions that we might be wrapped in.
-        */
-
-       status = werror_to_ntstatus(regsubkey_ctr_init(talloc_tos(), &ctr));
-       if (!NT_STATUS_IS_OK(status)) {
-               /* don't treat this as an error */
-               status = NT_STATUS_OK;
-               goto done;
-       }
-
-       status = werror_to_ntstatus(regdb_fetch_keys_internal(db,
-                                                             sorted_ctx->key,
-                                                             ctr));
-       if (!NT_STATUS_IS_OK(status)) {
-               /* don't treat this as an error */
-               status = NT_STATUS_OK;
-               goto done;
-       }
-
-       num_subkeys = regsubkey_ctr_numkeys(ctr);
-       sorted_subkeys = talloc_array(ctr, char *, num_subkeys);
-       if (sorted_subkeys == NULL) {
-               /* don't treat this as an error */
-               goto done;
-       }
-
-       len = 4 + 4*num_subkeys;
-
-       for (i = 0; i < num_subkeys; i++) {
-               sorted_subkeys[i] = talloc_strdup_upper(sorted_subkeys,
-                                       regsubkey_ctr_specific_key(ctr, i));
-               if (sorted_subkeys[i] == NULL) {
-                       /* don't treat this as an error */
-                       goto done;
-               }
-               len += strlen(sorted_subkeys[i])+1;
-       }
-
-       TYPESAFE_QSORT(sorted_subkeys, num_subkeys, cmp_keynames);
-
-       buf = talloc_array(ctr, char, len);
-       if (buf == NULL) {
-               /* don't treat this as an error */
-               goto done;
-       }
-       p = buf + 4 + 4*num_subkeys;
-
-       SIVAL(buf, 0, num_subkeys);
-
-       for (i=0; i < num_subkeys; i++) {
-               ptrdiff_t offset = p - buf;
-               SIVAL(buf, 4 + 4*i, offset);
-               strlcpy(p, sorted_subkeys[i], len-offset);
-               p += strlen(sorted_subkeys[i]) + 1;
-       }
-
-       status = dbwrap_store_bystring(
-               db, sorted_ctx->sorted_keyname, make_tdb_data((uint8_t *)buf,
-               len),
-               TDB_REPLACE);
-
-done:
-       talloc_free(ctr);
-       return status;
-}
-
-static NTSTATUS create_sorted_subkeys_internal(const char *key,
-                                              const char *sorted_keyname)
-{
-       NTSTATUS status;
-       struct create_sorted_subkeys_context sorted_ctx;
-
-       sorted_ctx.key = key;
-       sorted_ctx.sorted_keyname = sorted_keyname;
-
-       status = dbwrap_trans_do(regdb,
-                                create_sorted_subkeys_action,
-                                &sorted_ctx);
-
-       return status;
-}
-
-static NTSTATUS create_sorted_subkeys(const char *key)
-{
-       char *sorted_subkeys_keyname;
-       NTSTATUS status;
-
-       sorted_subkeys_keyname = talloc_asprintf(talloc_tos(), "%s\\%s",
-                                                REG_SORTED_SUBKEYS_PREFIX,
-                                                key);
-       if (sorted_subkeys_keyname == NULL) {
-               status = NT_STATUS_NO_MEMORY;
-               goto done;
-       }
-
-       status = create_sorted_subkeys_internal(key, sorted_subkeys_keyname);
-
-done:
-       return status;
-}
-
-struct scan_subkey_state {
-       char *name;
-       bool scanned;
-       bool found;
-};
-
-static int parent_subkey_scanner(TDB_DATA key, TDB_DATA data,
-                                void *private_data)
-{
-       struct scan_subkey_state *state =
-               (struct scan_subkey_state *)private_data;
-       uint32_t num_subkeys;
-       uint32_t l, u;
-
-       if (data.dsize < sizeof(uint32_t)) {
-               return -1;
-       }
-
-       state->scanned = true;
-       state->found = false;
-
-       tdb_unpack(data.dptr, data.dsize, "d", &num_subkeys);
-
-       l = 0;
-       u = num_subkeys;
-
-       while (l < u) {
-               uint32_t idx = (l+u)/2;
-               char *s = (char *)data.dptr + IVAL(data.dptr, 4 + 4*idx);
-               int comparison = strcmp(state->name, s);
-
-               if (comparison < 0) {
-                       u = idx;
-               } else if (comparison > 0) {
-                       l = idx + 1;
-               } else {
-                       state->found = true;
-                       return 0;
-               }
-       }
-       return 0;
-}
-
-static bool scan_parent_subkeys(struct db_context *db, const char *parent,
-                               const char *name)
-{
-       char *path = NULL;
-       char *key = NULL;
-       struct scan_subkey_state state = { 0, };
-       bool result = false;
-       int res;
-
-       state.name = NULL;
-
-       path = normalize_reg_path(talloc_tos(), parent);
-       if (path == NULL) {
-               goto fail;
-       }
-
-       key = talloc_asprintf(talloc_tos(), "%s\\%s",
-                             REG_SORTED_SUBKEYS_PREFIX, path);
-       if (key == NULL) {
-               goto fail;
-       }
-
-       state.name = talloc_strdup_upper(talloc_tos(), name);
-       if (state.name == NULL) {
-               goto fail;
-       }
-       state.scanned = false;
-
-       res = db->parse_record(db, string_term_tdb_data(key),
-                              parent_subkey_scanner, &state);
-
-       if (state.scanned) {
-               result = state.found;
-       } else {
-               NTSTATUS status;
-
-               res = db->transaction_start(db);
-               if (res != 0) {
-                       DEBUG(0, ("error starting transaction\n"));
-                       goto fail;
-               }
-
-               DEBUG(2, (__location__ " WARNING: recreating the sorted "
-                         "subkeys cache for key '%s' from scan_parent_subkeys "
-                         "this should not happen (too frequently)...\n",
-                         path));
-
-               status = create_sorted_subkeys_internal(path, key);
-               if (!NT_STATUS_IS_OK(status)) {
-                       res = db->transaction_cancel(db);
-                       if (res != 0) {
-                               smb_panic("Failed to cancel transaction.");
-                       }
-                       goto fail;
-               }
-
-               res = db->parse_record(db, string_term_tdb_data(key),
-                                      parent_subkey_scanner, &state);
-               if ((res == 0) && (state.scanned)) {
-                       result = state.found;
-               }
-
-               res = db->transaction_commit(db);
-               if (res != 0) {
-                       DEBUG(0, ("error committing transaction\n"));
-                       result = false;
-               }
-       }
-
- fail:
-       TALLOC_FREE(path);
-       TALLOC_FREE(state.name);
-       return result;
-}
-
 /**
  * Check for the existence of a key.
  *