diff options
author | Gregor Beck <gbeck@sernet.de> | 2011-08-01 15:27:46 +0200 |
---|---|---|
committer | Michael Adam <obnox@samba.org> | 2011-08-08 15:27:07 +0200 |
commit | 356ed8644c0099a70ece5b7d5104662454d03ef8 (patch) | |
tree | f74f3763b3167d197adc5a74ab511672218a470c /source3/registry/reg_api.c | |
parent | db06b61a1d3d38140578c004eb9d6cb3243d2870 (diff) | |
download | samba-356ed8644c0099a70ece5b7d5104662454d03ef8.tar.gz samba-356ed8644c0099a70ece5b7d5104662454d03ef8.tar.bz2 samba-356ed8644c0099a70ece5b7d5104662454d03ef8.zip |
s3:registry avoid updating keys which are going to be deleted in
reg_deletekey_recursive
this changes the complexity from O(n^2) to O(n) and reduces the time of
a 'net conf drop' with 10000 shares from 6min to 1.5s
Signed-off-by: Michael Adam <obnox@samba.org>
Diffstat (limited to 'source3/registry/reg_api.c')
-rw-r--r-- | source3/registry/reg_api.c | 57 |
1 files changed, 34 insertions, 23 deletions
diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c index c66a95e406..289f77df76 100644 --- a/source3/registry/reg_api.c +++ b/source3/registry/reg_api.c @@ -606,41 +606,29 @@ WERROR reg_createkey(TALLOC_CTX *ctx, struct registry_key *parent, return err; } -WERROR reg_deletekey(struct registry_key *parent, const char *path) +static WERROR reg_deletekey_internal(TALLOC_CTX *mem_ctx, + struct registry_key *parent, + const char *path, bool lazy) { WERROR err; char *name, *end; - struct registry_key *tmp_key, *key; - TALLOC_CTX *mem_ctx = talloc_stackframe(); - + struct registry_key *key; name = talloc_strdup(mem_ctx, path); if (name == NULL) { err = WERR_NOMEM; goto done; } - /* check if the key has subkeys */ - err = reg_openkey(mem_ctx, parent, name, REG_KEY_READ, &key); - W_ERROR_NOT_OK_GOTO_DONE(err); - - err = fill_subkey_cache(key); - W_ERROR_NOT_OK_GOTO_DONE(err); - - if (regsubkey_ctr_numkeys(key->subkeys) > 0) { - err = WERR_ACCESS_DENIED; - goto done; - } - /* no subkeys - proceed with delete */ end = strrchr(name, '\\'); if (end != NULL) { *end = '\0'; err = reg_openkey(mem_ctx, parent, name, - KEY_CREATE_SUB_KEY, &tmp_key); + KEY_CREATE_SUB_KEY, &key); W_ERROR_NOT_OK_GOTO_DONE(err); - parent = tmp_key; + parent = key; name = end+1; } @@ -649,13 +637,36 @@ WERROR reg_deletekey(struct registry_key *parent, const char *path) goto done; } - err = delete_reg_subkey(parent->key, name); + err = delete_reg_subkey(parent->key, name, lazy); + +done: + return err; +} + +WERROR reg_deletekey(struct registry_key *parent, const char *path) +{ + WERROR err; + struct registry_key *key; + TALLOC_CTX *mem_ctx = talloc_stackframe(); + + /* check if the key has subkeys */ + err = reg_openkey(mem_ctx, parent, path, REG_KEY_READ, &key); + W_ERROR_NOT_OK_GOTO_DONE(err); + + err = fill_subkey_cache(key); + W_ERROR_NOT_OK_GOTO_DONE(err); + if (regsubkey_ctr_numkeys(key->subkeys) > 0) { + err = WERR_ACCESS_DENIED; + goto done; + } + err = reg_deletekey_internal(mem_ctx, parent, path, false); done: TALLOC_FREE(mem_ctx); return err; } + WERROR reg_setvalue(struct registry_key *key, const char *name, const struct registry_value *val) { @@ -796,7 +807,7 @@ WERROR reg_deleteallvalues(struct registry_key *key) */ static WERROR reg_deletekey_recursive_internal(struct registry_key *parent, const char *path, - bool del_key) + bool del_key, bool lazy) { WERROR werr = WERR_OK; struct registry_key *key; @@ -819,13 +830,13 @@ static WERROR reg_deletekey_recursive_internal(struct registry_key *parent, */ 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(key, subkey_name, true); + werr = reg_deletekey_recursive_internal(key, subkey_name, true, del_key); W_ERROR_NOT_OK_GOTO_DONE(werr); } if (del_key) { /* now delete the actual key */ - werr = reg_deletekey(parent, path); + werr = reg_deletekey_internal(mem_ctx, parent, path, lazy); } done: @@ -847,7 +858,7 @@ static WERROR reg_deletekey_recursive_trans(struct registry_key *parent, return werr; } - werr = reg_deletekey_recursive_internal(parent, path, del_key); + werr = reg_deletekey_recursive_internal(parent, path, del_key, false); if (!W_ERROR_IS_OK(werr)) { WERROR werr2; |