From 58fc61217db68e553119bc49369362672590c19d Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 24 Feb 2009 15:19:18 +0100 Subject: s3:registry: replace typedef "REGSUBKEY_CTR" by "struct regsubkey_ctr" This paves the way for hiding the typedef and the implementation from the surface. Michael --- source3/registry/reg_objects.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/registry/reg_objects.c') diff --git a/source3/registry/reg_objects.c b/source3/registry/reg_objects.c index 47122ccad2..a9a4939034 100644 --- a/source3/registry/reg_objects.c +++ b/source3/registry/reg_objects.c @@ -40,7 +40,7 @@ Add a new key to the array **********************************************************************/ -WERROR regsubkey_ctr_addkey( REGSUBKEY_CTR *ctr, const char *keyname ) +WERROR regsubkey_ctr_addkey( struct regsubkey_ctr *ctr, const char *keyname ) { char **newkeys; @@ -77,7 +77,7 @@ WERROR regsubkey_ctr_addkey( REGSUBKEY_CTR *ctr, const char *keyname ) Delete a key from the array **********************************************************************/ -int regsubkey_ctr_delkey( REGSUBKEY_CTR *ctr, const char *keyname ) +int regsubkey_ctr_delkey( struct regsubkey_ctr *ctr, const char *keyname ) { int i; @@ -107,7 +107,7 @@ int regsubkey_ctr_delkey( REGSUBKEY_CTR *ctr, const char *keyname ) Check for the existance of a key **********************************************************************/ -bool regsubkey_ctr_key_exists( REGSUBKEY_CTR *ctr, const char *keyname ) +bool regsubkey_ctr_key_exists( struct regsubkey_ctr *ctr, const char *keyname ) { int i; @@ -127,7 +127,7 @@ bool regsubkey_ctr_key_exists( REGSUBKEY_CTR *ctr, const char *keyname ) How many keys does the container hold ? **********************************************************************/ -int regsubkey_ctr_numkeys( REGSUBKEY_CTR *ctr ) +int regsubkey_ctr_numkeys( struct regsubkey_ctr *ctr ) { return ctr->num_subkeys; } @@ -136,7 +136,7 @@ int regsubkey_ctr_numkeys( REGSUBKEY_CTR *ctr ) Retreive a specific key string **********************************************************************/ -char* regsubkey_ctr_specific_key( REGSUBKEY_CTR *ctr, uint32 key_index ) +char* regsubkey_ctr_specific_key( struct regsubkey_ctr *ctr, uint32 key_index ) { if ( ! (key_index < ctr->num_subkeys) ) return NULL; -- cgit From 060abd7e38bff8cecf5821e9a9878f18c04a7a1d Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 24 Feb 2009 22:41:40 +0100 Subject: s3:registry: fix a comment Michael --- source3/registry/reg_objects.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/registry/reg_objects.c') diff --git a/source3/registry/reg_objects.c b/source3/registry/reg_objects.c index a9a4939034..15f9879706 100644 --- a/source3/registry/reg_objects.c +++ b/source3/registry/reg_objects.c @@ -26,9 +26,9 @@ /********************************************************************** - Note that the REGSUB_CTR and REGVAL_CTR objects *must* be talloc()'d - since the methods use the object pointer as the talloc context for - internal private data. + Note that the struct regsubkey_ctr and REGVAL_CTR objects *must* be + talloc()'d since the methods use the object pointer as the talloc + context for internal private data. There is no longer a regXXX_ctr_intit() and regXXX_ctr_destroy() pair of functions. Simply TALLOC_ZERO_P() and TALLOC_FREE() the -- cgit From 763f41f39c2b3c3488992297bc1c0e1ab785ad07 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 24 Feb 2009 22:43:47 +0100 Subject: s3:registry: add a regsubkey_ctr_init function for allocating a regsubkey_ctr Michael --- source3/registry/reg_objects.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'source3/registry/reg_objects.c') diff --git a/source3/registry/reg_objects.c b/source3/registry/reg_objects.c index 15f9879706..10ad41e84b 100644 --- a/source3/registry/reg_objects.c +++ b/source3/registry/reg_objects.c @@ -30,12 +30,26 @@ talloc()'d since the methods use the object pointer as the talloc context for internal private data. - There is no longer a regXXX_ctr_intit() and regXXX_ctr_destroy() + There is no longer a regval_ctr_intit() and regval_ctr_destroy() pair of functions. Simply TALLOC_ZERO_P() and TALLOC_FREE() the object. **********************************************************************/ +WERROR regsubkey_ctr_init(TALLOC_CTX *mem_ctx, struct regsubkey_ctr **ctr) +{ + if (ctr == NULL) { + return WERR_INVALID_PARAM; + } + + *ctr = talloc_zero(mem_ctx, struct regsubkey_ctr); + if (*ctr == NULL) { + return WERR_NOMEM; + } + + return WERR_OK; +} + /*********************************************************************** Add a new key to the array **********************************************************************/ -- cgit From 63ed47c9e4c846d52c7a56b137d5059b1700007a Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 24 Feb 2009 23:10:35 +0100 Subject: s3:registry: add regsubkey_ctr_set_seqnum to hide implementation from caller. Michael --- source3/registry/reg_objects.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source3/registry/reg_objects.c') diff --git a/source3/registry/reg_objects.c b/source3/registry/reg_objects.c index 10ad41e84b..20bc906cfe 100644 --- a/source3/registry/reg_objects.c +++ b/source3/registry/reg_objects.c @@ -50,6 +50,17 @@ WERROR regsubkey_ctr_init(TALLOC_CTX *mem_ctx, struct regsubkey_ctr **ctr) return WERR_OK; } +WERROR regsubkey_ctr_set_seqnum(struct regsubkey_ctr *ctr, int seqnum) +{ + if (ctr == NULL) { + return WERR_INVALID_PARAM; + } + + ctr->seqnum = seqnum; + + return WERR_OK; +} + /*********************************************************************** Add a new key to the array **********************************************************************/ -- cgit From cd8bfd3a84a02cdaf74813bb7c09dc9a02621aa6 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 24 Feb 2009 23:15:55 +0100 Subject: s3:registry: add regsubkey_ctr_get_seqnum() to hide implementation Michael --- source3/registry/reg_objects.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'source3/registry/reg_objects.c') diff --git a/source3/registry/reg_objects.c b/source3/registry/reg_objects.c index 20bc906cfe..f97ca69139 100644 --- a/source3/registry/reg_objects.c +++ b/source3/registry/reg_objects.c @@ -61,6 +61,15 @@ WERROR regsubkey_ctr_set_seqnum(struct regsubkey_ctr *ctr, int seqnum) return WERR_OK; } +int regsubkey_ctr_get_seqnum(struct regsubkey_ctr *ctr) +{ + if (ctr == NULL) { + return -1; + } + + return ctr->seqnum; +} + /*********************************************************************** Add a new key to the array **********************************************************************/ -- cgit From 149d94dd8f5513af9f75d568507c880c63b9187e Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 25 Feb 2009 00:33:24 +0100 Subject: s3:registry: remove definition of regsubkey_ctr from the surface. All access is now through accessor functions in reg_objects.c This allows for performance tuning under the hood in the next step. Michael --- source3/registry/reg_objects.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/registry/reg_objects.c') diff --git a/source3/registry/reg_objects.c b/source3/registry/reg_objects.c index f97ca69139..c3d67a01ed 100644 --- a/source3/registry/reg_objects.c +++ b/source3/registry/reg_objects.c @@ -24,6 +24,12 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_REGISTRY +struct regsubkey_ctr { + uint32 num_subkeys; + char **subkeys; + int seqnum; +}; + /********************************************************************** Note that the struct regsubkey_ctr and REGVAL_CTR objects *must* be -- cgit From 0b22f8b99c0291f2e45166124358844127fb8edf Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 25 Feb 2009 09:53:16 +0100 Subject: s3:registry: hash the list of subkeys in the regsubkey_ctr This removes many loops over all the arrays (from regsubkey_ctr_key_exists) and thus reduces "net conf drop" from 1m55 to 48seconds and "net conf import" from 1m55 to 58 seconds for 2000 shares on my box. Michael --- source3/registry/reg_objects.c | 123 ++++++++++++++++++++++++++++++++++------- 1 file changed, 102 insertions(+), 21 deletions(-) (limited to 'source3/registry/reg_objects.c') diff --git a/source3/registry/reg_objects.c b/source3/registry/reg_objects.c index c3d67a01ed..b975ced324 100644 --- a/source3/registry/reg_objects.c +++ b/source3/registry/reg_objects.c @@ -25,8 +25,9 @@ #define DBGC_CLASS DBGC_REGISTRY struct regsubkey_ctr { - uint32 num_subkeys; + uint32_t num_subkeys; char **subkeys; + struct db_context *subkeys_hash; int seqnum; }; @@ -53,6 +54,12 @@ WERROR regsubkey_ctr_init(TALLOC_CTX *mem_ctx, struct regsubkey_ctr **ctr) return WERR_NOMEM; } + (*ctr)->subkeys_hash = db_open_rbt(*ctr); + if ((*ctr)->subkeys_hash == NULL) { + talloc_free(*ctr); + return WERR_NOMEM; + } + return WERR_OK; } @@ -76,6 +83,68 @@ int regsubkey_ctr_get_seqnum(struct regsubkey_ctr *ctr) return ctr->seqnum; } +static WERROR regsubkey_ctr_hash_keyname(struct regsubkey_ctr *ctr, + const char *keyname, + uint32 idx) +{ + WERROR werr; + + werr = ntstatus_to_werror(dbwrap_store_bystring(ctr->subkeys_hash, + keyname, + make_tdb_data((uint8 *)&idx, + sizeof(idx)), + TDB_REPLACE)); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(1, ("error hashing new key '%s' in container: %s\n", + keyname, win_errstr(werr))); + } + + return werr; +} + +static WERROR regsubkey_ctr_unhash_keyname(struct regsubkey_ctr *ctr, + const char *keyname) +{ + WERROR werr; + + werr = ntstatus_to_werror(dbwrap_delete_bystring(ctr->subkeys_hash, + keyname)); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(1, ("error unhashing key '%s' in container: %s\n", + keyname, win_errstr(werr))); + } + + return werr; +} + +static WERROR regsubkey_ctr_index_for_keyname(struct regsubkey_ctr *ctr, + const char *keyname, + uint32 *idx) +{ + TDB_DATA data; + + if ((ctr == NULL) || (keyname == NULL)) { + return WERR_INVALID_PARAM; + } + + data = dbwrap_fetch_bystring(ctr->subkeys_hash, ctr, keyname); + if (data.dptr == NULL) { + return WERR_NOT_FOUND; + } + + if (data.dsize != sizeof(*idx)) { + talloc_free(data.dptr); + return WERR_INVALID_DATATYPE; + } + + if (idx != NULL) { + *idx = *(uint32 *)data.dptr; + } + + talloc_free(data.dptr); + return WERR_OK; +} + /*********************************************************************** Add a new key to the array **********************************************************************/ @@ -83,6 +152,7 @@ int regsubkey_ctr_get_seqnum(struct regsubkey_ctr *ctr) WERROR regsubkey_ctr_addkey( struct regsubkey_ctr *ctr, const char *keyname ) { char **newkeys; + WERROR werr; if ( !keyname ) { return WERR_OK; @@ -108,6 +178,10 @@ WERROR regsubkey_ctr_addkey( struct regsubkey_ctr *ctr, const char *keyname ) */ return WERR_NOMEM; } + + werr = regsubkey_ctr_hash_keyname(ctr, keyname, ctr->num_subkeys); + W_ERROR_NOT_OK_RETURN(werr); + ctr->num_subkeys++; return WERR_OK; @@ -117,30 +191,37 @@ WERROR regsubkey_ctr_addkey( struct regsubkey_ctr *ctr, const char *keyname ) Delete a key from the array **********************************************************************/ -int regsubkey_ctr_delkey( struct regsubkey_ctr *ctr, const char *keyname ) +WERROR regsubkey_ctr_delkey( struct regsubkey_ctr *ctr, const char *keyname ) { - int i; + WERROR werr; + uint32 idx, j; - if ( !keyname ) - return ctr->num_subkeys; + if (keyname == NULL) { + return WERR_INVALID_PARAM; + } /* make sure the keyname is actually already there */ - for ( i=0; inum_subkeys; i++ ) { - if ( strequal( ctr->subkeys[i], keyname ) ) - break; - } + werr = regsubkey_ctr_index_for_keyname(ctr, keyname, &idx); + W_ERROR_NOT_OK_RETURN(werr); - if ( i == ctr->num_subkeys ) - return ctr->num_subkeys; + werr = regsubkey_ctr_unhash_keyname(ctr, keyname); + W_ERROR_NOT_OK_RETURN(werr); /* update if we have any keys left */ ctr->num_subkeys--; - if ( i < ctr->num_subkeys ) - memmove(&ctr->subkeys[i], &ctr->subkeys[i+1], - sizeof(char*) * (ctr->num_subkeys-i)); + if (idx < ctr->num_subkeys) { + memmove(&ctr->subkeys[idx], &ctr->subkeys[idx+1], + sizeof(char *) * (ctr->num_subkeys - idx)); + + /* we have to re-hash rest of the array... :-( */ + for (j = idx; j < ctr->num_subkeys; j++) { + werr = regsubkey_ctr_hash_keyname(ctr, ctr->subkeys[j], j); + W_ERROR_NOT_OK_RETURN(werr); + } + } - return ctr->num_subkeys; + return WERR_OK; } /*********************************************************************** @@ -149,18 +230,18 @@ int regsubkey_ctr_delkey( struct regsubkey_ctr *ctr, const char *keyname ) bool regsubkey_ctr_key_exists( struct regsubkey_ctr *ctr, const char *keyname ) { - int i; + WERROR werr; if (!ctr->subkeys) { return False; } - for ( i=0; inum_subkeys; i++ ) { - if ( strequal( ctr->subkeys[i],keyname ) ) - return True; + werr = regsubkey_ctr_index_for_keyname(ctr, keyname, NULL); + if (!W_ERROR_IS_OK(werr)) { + return false; } - return False; + return true; } /*********************************************************************** @@ -176,7 +257,7 @@ int regsubkey_ctr_numkeys( struct regsubkey_ctr *ctr ) Retreive a specific key string **********************************************************************/ -char* regsubkey_ctr_specific_key( struct regsubkey_ctr *ctr, uint32 key_index ) +char* regsubkey_ctr_specific_key( struct regsubkey_ctr *ctr, uint32_t key_index ) { if ( ! (key_index < ctr->num_subkeys) ) return NULL; -- cgit