s3:registry: tighten the subkey loop in reg_deletekey_recursive()
authorMichael Adam <obnox@samba.org>
Thu, 26 Feb 2009 01:59:07 +0000 (02:59 +0100)
committerMichael Adam <obnox@samba.org>
Thu, 26 Feb 2009 12:22:56 +0000 (13:22 +0100)
and loop from the end to the beginning so that we don't need
to rehash the subkeys...

This gets "net conf drop" with 2000 shares down to 14 seconds
on my box.

Michael

source3/registry/reg_api.c

index 3dc3bae6feba9a45d6eaf37c4f2dd6089f980051..67767a2e561ae9b0f58c6f79f2e5d2fd1ca8a042 100644 (file)
@@ -1062,6 +1062,7 @@ static WERROR reg_deletekey_recursive_internal(TALLOC_CTX *ctx,
        WERROR werr = WERR_OK;
        struct registry_key *key;
        char *subkey_name = NULL;
+       uint32 i;
 
        mem_ctx = talloc_new(ctx);
        if (mem_ctx == NULL) {
@@ -1075,25 +1076,21 @@ static WERROR reg_deletekey_recursive_internal(TALLOC_CTX *ctx,
                goto done;
        }
 
-       while (W_ERROR_IS_OK(werr = reg_enumkey(mem_ctx, key, 0,
-                                               &subkey_name, NULL)))
-       {
+       werr = fill_subkey_cache(key);
+       W_ERROR_NOT_OK_GOTO_DONE(werr);
+
+       /*
+        * loop from top to bottom for perfomance:
+        * this way, we need to rehash the regsubkey containers less
+        */
+       for (i = regsubkey_ctr_numkeys(key->subkeys) ; i > 0; i--) {
+               subkey_name = regsubkey_ctr_specific_key(key->subkeys, i-1);
                werr = reg_deletekey_recursive_internal(mem_ctx, key,
-                                                       subkey_name,
-                                                       true);
-               if (!W_ERROR_IS_OK(werr)) {
-                       goto done;
-               }
-       }
-       if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
-               DEBUG(1, ("reg_deletekey_recursive_internal: "
-                         "Error enumerating subkeys: %s\n",
-                         win_errstr(werr)));
-               goto done;
+                                       subkey_name,
+                                       true);
+               W_ERROR_NOT_OK_GOTO_DONE(werr);
        }
 
-       werr = WERR_OK;
-
        if (del_key) {
                /* now delete the actual key */
                werr = reg_deletekey(parent, path);