diff options
-rw-r--r-- | lib/ntdb/ntdb.h | 15 | ||||
-rw-r--r-- | lib/ntdb/open.c | 28 |
2 files changed, 41 insertions, 2 deletions
diff --git a/lib/ntdb/ntdb.h b/lib/ntdb/ntdb.h index 09622787d4..8e8458e4d1 100644 --- a/lib/ntdb/ntdb.h +++ b/lib/ntdb/ntdb.h @@ -633,7 +633,8 @@ enum ntdb_attribute_type { NTDB_ATTRIBUTE_STATS = 3, NTDB_ATTRIBUTE_OPENHOOK = 4, NTDB_ATTRIBUTE_FLOCK = 5, - NTDB_ATTRIBUTE_ALLOCATOR = 6 + NTDB_ATTRIBUTE_ALLOCATOR = 6, + NTDB_ATTRIBUTE_HASHSIZE = 7 }; /** @@ -867,6 +868,17 @@ struct ntdb_attribute_flock { }; /** + * struct ntdb_attribute_hashsize - ntdb hashsize setting. + * + * This attribute is only settable on ntdb_open; it indicates that we create + * a hashtable of the given size, rather than the default. + */ +struct ntdb_attribute_hashsize { + struct ntdb_attribute_base base; /* .attr = NTDB_ATTRIBUTE_HASHSIZE */ + uint32_t size; +}; + +/** * struct ntdb_attribute_allocator - allocator for ntdb to use. * * You can replace malloc/free with your own allocation functions. @@ -910,6 +922,7 @@ union ntdb_attribute { struct ntdb_attribute_openhook openhook; struct ntdb_attribute_flock flock; struct ntdb_attribute_allocator alloc; + struct ntdb_attribute_hashsize hashsize; }; #ifdef __cplusplus diff --git a/lib/ntdb/open.c b/lib/ntdb/open.c index 4b8c45298b..9de9e9b48c 100644 --- a/lib/ntdb/open.c +++ b/lib/ntdb/open.c @@ -273,6 +273,7 @@ _PUBLIC_ enum NTDB_ERROR ntdb_set_attribute(struct ntdb_context *ntdb, case NTDB_ATTRIBUTE_HASH: case NTDB_ATTRIBUTE_SEED: case NTDB_ATTRIBUTE_OPENHOOK: + case NTDB_ATTRIBUTE_HASHSIZE: return ntdb_logerr(ntdb, NTDB_ERR_EINVAL, NTDB_LOG_USE_ERROR, "ntdb_set_attribute:" @@ -281,7 +282,9 @@ _PUBLIC_ enum NTDB_ERROR ntdb_set_attribute(struct ntdb_context *ntdb, ? "NTDB_ATTRIBUTE_HASH" : attr->base.attr == NTDB_ATTRIBUTE_SEED ? "NTDB_ATTRIBUTE_SEED" - : "NTDB_ATTRIBUTE_OPENHOOK"); + : attr->base.attr == NTDB_ATTRIBUTE_OPENHOOK + ? "NTDB_ATTRIBUTE_OPENHOOK" + : "NTDB_ATTRIBUTE_HASHSIZE"); case NTDB_ATTRIBUTE_STATS: return ntdb_logerr(ntdb, NTDB_ERR_EINVAL, NTDB_LOG_USE_ERROR, @@ -349,6 +352,9 @@ _PUBLIC_ enum NTDB_ERROR ntdb_get_attribute(struct ntdb_context *ntdb, attr->alloc.free = ntdb->free_fn; attr->alloc.priv_data = ntdb->alloc_data; break; + case NTDB_ATTRIBUTE_HASHSIZE: + attr->hashsize.size = 1 << ntdb->hash_bits; + break; default: return ntdb_logerr(ntdb, NTDB_ERR_EINVAL, NTDB_LOG_USE_ERROR, @@ -475,6 +481,15 @@ static struct ntdb_context *alloc_ntdb(const union ntdb_attribute *attr, return default_alloc(NULL, len, NULL); } +static unsigned int next_pow2(uint64_t size) +{ + unsigned int bits = 1; + + while ((1ULL << bits) < size) + bits++; + return bits; +} + _PUBLIC_ struct ntdb_context *ntdb_open(const char *name, int ntdb_flags, int open_flags, mode_t mode, union ntdb_attribute *attr) @@ -528,6 +543,17 @@ _PUBLIC_ struct ntdb_context *ntdb_open(const char *name, int ntdb_flags, ntdb->openhook = attr->openhook.fn; ntdb->openhook_data = attr->openhook.data; break; + case NTDB_ATTRIBUTE_HASHSIZE: + ntdb->hash_bits = next_pow2(attr->hashsize.size); + if (ntdb->hash_bits > 31) { + ecode = ntdb_logerr(ntdb, NTDB_ERR_EINVAL, + NTDB_LOG_USE_ERROR, + "ntdb_open: hash_size %u" + " too large", + attr->hashsize.size); + goto fail; + } + break; default: /* These are set as normal. */ ecode = ntdb_set_attribute(ntdb, attr); |