blob: a06cfd19beedee6985c6decc633ad537386354f1 [file] [log] [blame]
/*
* Copyright (C) Igor Sysoev
* Copyright (C) NGINX, Inc.
*/
#include <njs_main.h>
static njs_int_t
lvlhsh_unit_test_key_test(njs_lvlhsh_query_t *lhq, void *data)
{
if (*(uintptr_t *) lhq->key.start == (uintptr_t) data) {
return NJS_OK;
}
return NJS_DECLINED;
}
static void *
lvlhsh_unit_test_pool_alloc(void *pool, size_t size)
{
return njs_mp_align(pool, size, size);
}
static void
lvlhsh_unit_test_pool_free(void *pool, void *p, size_t size)
{
njs_mp_free(pool, p);
}
static const njs_lvlhsh_proto_t lvlhsh_proto njs_aligned(64) = {
NJS_LVLHSH_LARGE_SLAB,
lvlhsh_unit_test_key_test,
lvlhsh_unit_test_pool_alloc,
lvlhsh_unit_test_pool_free,
};
static njs_int_t
lvlhsh_unit_test_add(njs_lvlhsh_t *lh, const njs_lvlhsh_proto_t *proto,
void *pool, uintptr_t key)
{
njs_lvlhsh_query_t lhq;
lhq.key_hash = key;
lhq.replace = 0;
lhq.key.length = sizeof(uintptr_t);
lhq.key.start = (u_char *) &key;
lhq.value = (void *) key;
lhq.proto = proto;
lhq.pool = pool;
switch (njs_lvlhsh_insert(lh, &lhq)) {
case NJS_OK:
return NJS_OK;
case NJS_DECLINED:
njs_printf("lvlhsh unit test failed: key %08Xl is already in hash\n",
(long) key);
/* Fall through. */
default:
return NJS_ERROR;
}
}
static njs_int_t
lvlhsh_unit_test_get(njs_lvlhsh_t *lh, const njs_lvlhsh_proto_t *proto,
uintptr_t key)
{
njs_lvlhsh_query_t lhq;
lhq.key_hash = key;
lhq.key.length = sizeof(uintptr_t);
lhq.key.start = (u_char *) &key;
lhq.proto = proto;
if (njs_lvlhsh_find(lh, &lhq) == NJS_OK) {
if (key == (uintptr_t) lhq.value) {
return NJS_OK;
}
}
njs_printf("lvlhsh unit test failed: key %08Xl not found in hash\n",
(long) key);
return NJS_ERROR;
}
static njs_int_t
lvlhsh_unit_test_delete(njs_lvlhsh_t *lh, const njs_lvlhsh_proto_t *proto,
void *pool, uintptr_t key)
{
njs_int_t ret;
njs_lvlhsh_query_t lhq;
lhq.key_hash = key;
lhq.key.length = sizeof(uintptr_t);
lhq.key.start = (u_char *) &key;
lhq.proto = proto;
lhq.pool = pool;
ret = njs_lvlhsh_delete(lh, &lhq);
if (ret != NJS_OK) {
njs_printf("lvlhsh unit test failed: key %08lX not found in hash\n",
(long) key);
}
return ret;
}
static njs_int_t
lvlhsh_unit_test(njs_uint_t n)
{
njs_mp_t *pool;
uint32_t key;
njs_uint_t i;
njs_lvlhsh_t lh;
njs_lvlhsh_each_t lhe;
const size_t min_chunk_size = 32;
const size_t page_size = 1024;
const size_t page_alignment = 128;
const size_t cluster_size = 4096;
pool = njs_mp_create(cluster_size, page_alignment, page_size,
min_chunk_size);
if (pool == NULL) {
return NJS_ERROR;
}
njs_printf("lvlhsh unit test started: %l items\n", (long) n);
njs_memzero(&lh, sizeof(njs_lvlhsh_t));
key = 0;
for (i = 0; i < n; i++) {
key = njs_murmur_hash2(&key, sizeof(uint32_t));
if (lvlhsh_unit_test_add(&lh, &lvlhsh_proto, pool, key) != NJS_OK) {
njs_printf("lvlhsh add unit test failed at %l\n", (long) i);
return NJS_ERROR;
}
}
key = 0;
for (i = 0; i < n; i++) {
key = njs_murmur_hash2(&key, sizeof(uint32_t));
if (lvlhsh_unit_test_get(&lh, &lvlhsh_proto, key) != NJS_OK) {
return NJS_ERROR;
}
}
njs_lvlhsh_each_init(&lhe, &lvlhsh_proto);
for (i = 0; i < n + 1; i++) {
if (njs_lvlhsh_each(&lh, &lhe) == NULL) {
break;
}
}
if (i != n) {
njs_printf("lvlhsh each unit test failed at %l of %l\n",
(long) i, (long) n);
return NJS_ERROR;
}
key = 0;
for (i = 0; i < n; i++) {
key = njs_murmur_hash2(&key, sizeof(uint32_t));
if (lvlhsh_unit_test_delete(&lh, &lvlhsh_proto, pool, key) != NJS_OK) {
return NJS_ERROR;
}
}
if (!njs_mp_is_empty(pool)) {
njs_printf("mem cache pool is not empty\n");
return NJS_ERROR;
}
njs_mp_destroy(pool);
njs_printf("lvlhsh unit test passed\n");
return NJS_OK;
}
int
main(void)
{
return lvlhsh_unit_test(1000 * 1000);
}