diff options
Diffstat (limited to 'src/nxt_lvlhsh.c')
-rw-r--r-- | src/nxt_lvlhsh.c | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/src/nxt_lvlhsh.c b/src/nxt_lvlhsh.c index bf730ada..07dcf1e9 100644 --- a/src/nxt_lvlhsh.c +++ b/src/nxt_lvlhsh.c @@ -188,6 +188,10 @@ static nxt_int_t nxt_lvlhsh_bucket_delete(nxt_lvlhsh_query_t *lhq, void **bkt); static void *nxt_lvlhsh_level_each(nxt_lvlhsh_each_t *lhe, void **level, nxt_uint_t nlvl, nxt_uint_t shift); static void *nxt_lvlhsh_bucket_each(nxt_lvlhsh_each_t *lhe); +static void *nxt_lvlhsh_level_peek(const nxt_lvlhsh_proto_t *proto, + void **level, nxt_uint_t nlvl); +static void *nxt_lvlhsh_bucket_peek(const nxt_lvlhsh_proto_t *proto, + void **bkt); nxt_int_t @@ -870,6 +874,80 @@ nxt_lvlhsh_bucket_each(nxt_lvlhsh_each_t *lhe) void * +nxt_lvlhsh_peek(nxt_lvlhsh_t *lh, const nxt_lvlhsh_proto_t *proto) +{ + void **slot; + + slot = lh->slot; + + if (slot != NULL) { + + if (nxt_lvlhsh_is_bucket(slot)) { + return nxt_lvlhsh_bucket_peek(proto, slot); + } + + return nxt_lvlhsh_level_peek(proto, slot, 0); + } + + return NULL; +} + + +static void * +nxt_lvlhsh_level_peek(const nxt_lvlhsh_proto_t *proto, void **level, + nxt_uint_t nlvl) +{ + void **slot; + uintptr_t mask; + nxt_uint_t n, shift; + + shift = proto->shift[nlvl]; + mask = ((uintptr_t) 1 << shift) - 1; + + level = nxt_lvlhsh_level(level, mask); + + n = 0; + + /* At least one valid level slot must present here. */ + + for ( ;; ) { + slot = level[n]; + + if (slot != NULL) { + + if (nxt_lvlhsh_is_bucket(slot)) { + return nxt_lvlhsh_bucket_peek(proto, slot); + } + + return nxt_lvlhsh_level_peek(proto, slot, nlvl + 1); + } + + n++; + } +} + + +static void * +nxt_lvlhsh_bucket_peek(const nxt_lvlhsh_proto_t *proto, void **bkt) +{ + void *value; + uint32_t *entry; + + /* At least one valid entry must present here. */ + + for (entry = nxt_lvlhsh_bucket(proto, bkt); + nxt_lvlhsh_free_entry(entry); + entry += NXT_LVLHSH_ENTRY_SIZE) + { + /* void */ + } + + value = nxt_lvlhsh_entry_value(entry); + return value; +} + + +void * nxt_lvlhsh_alloc(void *data, size_t size) { return nxt_memalign(size, size); |