diff options
Diffstat (limited to 'src/core/idhash.c')
| -rw-r--r-- | src/core/idhash.c | 87 |
1 files changed, 43 insertions, 44 deletions
diff --git a/src/core/idhash.c b/src/core/idhash.c index 0b680bc9..07368a65 100644 --- a/src/core/idhash.c +++ b/src/core/idhash.c @@ -11,54 +11,58 @@ #include <string.h> -typedef struct { +struct nni_idhash_entry { uint32_t ihe_key; uint32_t ihe_skips; void * ihe_val; -} nni_idhash_entry; - -struct nni_idhash { - uint32_t ih_cap; - uint32_t ih_count; - uint32_t ih_load; - uint32_t ih_minload; // considers placeholders - uint32_t ih_maxload; - uint32_t ih_walkers; - uint32_t ih_minval; - uint32_t ih_maxval; - uint32_t ih_dynval; - nni_idhash_entry * ih_entries; }; + int -nni_idhash_create(nni_idhash **hp) +nni_idhash_init(nni_idhash *h) { - nni_idhash *h; - - if ((h = NNI_ALLOC_STRUCT(h)) == NULL) { - return (NNG_ENOMEM); - } - h->ih_entries = nni_alloc(8 * sizeof (nni_idhash_entry)); - if (h->ih_entries == NULL) { - NNI_FREE_STRUCT(h); - return (NNG_ENOMEM); - } - (void) memset(h->ih_entries, 0, (8 * sizeof (nni_idhash_entry))); + h->ih_entries = NULL; h->ih_count = 0; h->ih_load = 0; - h->ih_cap = 8; - h->ih_maxload = 5; + h->ih_cap = 0; + h->ih_maxload = 0; h->ih_minload = 0; // never shrink below this h->ih_walkers = 0; h->ih_minval = 0; h->ih_maxval = 0xffffffff; h->ih_dynval = 0; - *hp = h; return (0); } void +nni_idhash_fini(nni_idhash *h) +{ + NNI_ASSERT(h->ih_walkers == 0); + if (h->ih_entries != NULL) { + nni_free(h->ih_entries, h->ih_cap * sizeof (nni_idhash_entry)); + h->ih_entries = NULL; + h->ih_cap = h->ih_count = 0; + h->ih_load = h->ih_minload = h->ih_maxload = 0; + } +} + + +void +nni_idhash_reclaim(nni_idhash *h) +{ + // Reclaim the buffer if we want, but preserve the limits. + if ((h->ih_count == 0) && (h->ih_cap != 0) && (h->ih_walkers == 0)) { + nni_free(h->ih_entries, h->ih_cap * sizeof (nni_idhash_entry)); + h->ih_cap = 0; + h->ih_entries = NULL; + h->ih_minload = 0; + h->ih_maxload = 0; + } +} + + +void nni_idhash_set_limits(nni_idhash *h, uint32_t minval, uint32_t maxval, uint32_t start) { @@ -71,16 +75,6 @@ nni_idhash_set_limits(nni_idhash *h, uint32_t minval, uint32_t maxval, } -void -nni_idhash_destroy(nni_idhash *h) -{ - if (h != NULL) { - nni_free(h->ih_entries, h->ih_cap * sizeof (nni_idhash_entry)); - NNI_FREE_STRUCT(h); - } -} - - // Inspired by Python dict implementation. This probe will visit every // cell. We always hash consecutively assigned IDs. #define NNI_IDHASH_NEXTPROBE(h, j) \ @@ -91,6 +85,10 @@ nni_idhash_find(nni_idhash *h, uint32_t id, void **valp) { uint32_t index = id & (h->ih_cap - 1); + if (h->ih_count == 0) { + return (NNG_ENOENT); + } + for (;;) { if ((h->ih_entries[index].ihe_val == NULL) && (h->ih_entries[index].ihe_skips == 0)) { @@ -165,7 +163,9 @@ nni_hash_resize(nni_idhash *h) index = NNI_IDHASH_NEXTPROBE(h, index); } } - nni_free(oldents, sizeof (nni_idhash_entry) * oldsize); + if (oldsize != 0) { + nni_free(oldents, sizeof (nni_idhash_entry) * oldsize); + } return (0); } @@ -286,11 +286,10 @@ nni_idhash_alloc(nni_idhash *h, uint32_t *idp, void *val) } -int -nni_idhash_count(nni_idhash *h, uint32_t *countp) +size_t +nni_idhash_count(nni_idhash *h) { - *countp = h->ih_count; - return (0); + return (h->ih_count); } |
