ntdb: add NTDB_ATTRIBUTE_HASHSIZE
authorRusty Russell <rusty@rustcorp.com.au>
Tue, 19 Jun 2012 03:13:08 +0000 (12:43 +0930)
committerRusty Russell <rusty@rustcorp.com.au>
Tue, 19 Jun 2012 03:38:07 +0000 (05:38 +0200)
Since we've given up on expansion, let them frob the hashsize again.
We have attributes, so we should use them for optional stuff like
this.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
lib/ntdb/ntdb.h
lib/ntdb/open.c

index 09622787d4c3ba6d1019215e45e9bbf95952bee1..8e8458e4d17d811ae9d89eed19ed540a875a6a71 100644 (file)
@@ -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
 };
 
 /**
@@ -866,6 +867,17 @@ struct ntdb_attribute_flock {
        void *data;
 };
 
+/**
+ * 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.
  *
@@ -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
index 4b8c45298b4cacf68e09d6d57a7d014b895c4757..9de9e9b48cc992873933cd1ce248b3520a85dc20 100644 (file)
@@ -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);