Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend judy_128_map with iterator helpers #83

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,10 @@ include_HEADERS = \
src/traildb.h \
src/tdb_error.h \
src/tdb_types.h \
src/tdb_limits.h
src/tdb_limits.h \
src/judy_str_map.h \
src/judy_128_map.h \
src/xxhash/xxhash.c

bin_PROGRAMS = util/traildb_bench tdbcli/tdb
util_traildb_bench_SOURCES = util/traildb_bench.c
Expand Down
108 changes: 106 additions & 2 deletions src/judy_128_map.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
Expand Down Expand Up @@ -59,6 +58,112 @@ Word_t *j128m_get(const struct judy_128_map *j128m, __uint128_t key)
return NULL;
}

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wincompatible-pointer-types"

void j128m_find(const struct judy_128_map *j128m,
PWord_t *pv,
__uint128_t *start_key)
{
uint64_t hi_key = (*start_key >> 64) & UINT64_MAX;
uint64_t lo_key = *start_key & UINT64_MAX;
Word_t *lo_ptr;
Word_t *hi_ptr;
Pvoid_t lo_map;

JLF(hi_ptr, j128m->hi_map, hi_key);
if (hi_ptr) {
lo_map = (Pvoid_t)*hi_ptr;
JLF(lo_ptr, lo_map, lo_key);
if (lo_ptr) {
*pv = lo_ptr;
__uint128_t next;
next = hi_key;
next <<= 64;
next |= lo_key;
*start_key = next;
return;
} else
*pv = NULL;
} else
*pv = NULL;

return;

out_of_memory:
/* this really should be impossible:
iterating shouldn't consume extra memory */
fprintf(stderr, "j128m_find out of memory! this shouldn't happen\n");
exit(1);

}

#pragma GCC diagnostic pop


#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wincompatible-pointer-types"

void j128m_next(const struct judy_128_map *j128m,
PWord_t *pv,
__uint128_t *start_key)
{
uint64_t hi_key = (*start_key >> 64) & UINT64_MAX;
uint64_t lo_key = *start_key & UINT64_MAX;
Word_t *lo_ptr;
Word_t *hi_ptr;
Pvoid_t lo_map;
//fprintf(stderr, "j128m_next: hi %lu lo %lu\r\n", hi_key, lo_key);

JLG(hi_ptr, j128m->hi_map, hi_key);
if (hi_ptr) {
lo_map = (Pvoid_t)*hi_ptr;
JLN(lo_ptr, lo_map, lo_key);
if (lo_ptr) {
*pv = lo_ptr;
*start_key = hi_key;
*start_key <<= 64;
*start_key |= lo_key;
return;
} else {
// lo map is empty, call next on hi

JLN(hi_ptr, j128m->hi_map, hi_key);
if (hi_ptr) {
lo_map = (Pvoid_t)*hi_ptr;
uint64_t zero = 0;
JLF(lo_ptr, lo_map, zero);
if (lo_ptr) {
//fprintf(stderr, "j128m_next: zero %lu\r\n", zero);
*pv = lo_ptr;
*start_key = hi_key;
*start_key <<= 64;
*start_key |= zero;
return;
} else {
*pv = NULL;
return;
}
} else {
*pv = NULL;
return;
}
}
} else {
*pv = NULL;
return;
}

out_of_memory:
/* this really should be impossible:
iterating shouldn't consume extra memory */
fprintf(stderr, "j128m_next out of memory! this shouldn't happen\n");
exit(1);
}

#pragma GCC diagnostic pop


#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wincompatible-pointer-types"

Expand Down Expand Up @@ -135,4 +240,3 @@ void j128m_free(struct judy_128_map *j128m)
out_of_memory:
return;
}

6 changes: 6 additions & 0 deletions src/judy_128_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ Word_t *j128m_insert(struct judy_128_map *j128m, __uint128_t key);

Word_t *j128m_get(const struct judy_128_map *j128m, __uint128_t key);

int j128m_del(struct judy_128_map *j128m, __uint128_t key);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@knutin I guess j128_del doesn't exist so this can be removed?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does, at least in some local branch I was using it, let me see..


void j128m_find(const struct judy_128_map *j128m, PWord_t *pv, __uint128_t *key);

void j128m_next(const struct judy_128_map *j128m, PWord_t *pv, __uint128_t *key);

void *j128m_fold(const struct judy_128_map *j128m,
judy_128_fold_fn fun,
void *state);
Expand Down
55 changes: 55 additions & 0 deletions tests/c-tests/judy_128_map_iter_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdint.h>
#include <assert.h>
#include <float.h>

#include <sys/time.h>
#include <sys/resource.h>

#include <Judy.h>
#include <judy_128_map.h>

#include "tdb_test.h"


__uint128_t uint128_key(uint64_t hi, uint64_t lo) {
__uint128_t k = hi;
k <<= 64;
k |= lo;
return k;
}

int main(int argc, char **argv)
{
struct judy_128_map jm;

j128m_init(&jm);


PWord_t ptr = NULL;
ptr = j128m_insert(&jm, uint128_key(1, 1)); *ptr = 11;
ptr = j128m_insert(&jm, uint128_key(1, 2)); *ptr = 12;
ptr = j128m_insert(&jm, uint128_key(1, 3)); *ptr = 13;
ptr = j128m_insert(&jm, uint128_key(2, 1)); *ptr = 21;
ptr = j128m_insert(&jm, uint128_key(2, 2)); *ptr = 22;
ptr = j128m_insert(&jm, uint128_key(2, 3)); *ptr = 23;

__uint128_t idx = 0;
PWord_t pv = NULL;
j128m_find(&jm, &pv, &idx);

uint64_t expected[6] = {11, 12, 13,
21, 22, 23};

int i = 0;
while (pv != NULL) {
assert(*pv == expected[i]);
j128m_next(&jm, &pv, &idx);
i++;
}
assert(i == 6);

return 0;
}
1 change: 0 additions & 1 deletion tests/support/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,3 @@ def runTests(self, **kwargs):

t = Testing()
sys.exit(t.runTests(**{k: True for k in sys.argv[1:]}))