mirror of
https://github.com/ilyakooo0/urbit.git
synced 2024-12-02 07:06:41 +03:00
stash
This commit is contained in:
parent
d5c7a458c1
commit
311b0b00f8
2
Makefile
2
Makefile
@ -458,7 +458,7 @@ $(LIBUV_MAKEFILE) $(LIBUV_MAKEFILE2):
|
||||
$(LIBUV_MAKEFILE2): $(LIBUV_MAKEFILE)
|
||||
|
||||
$(LIBUV): $(LIBUV_MAKEFILE) $(LIBUV_MAKEFILE2)
|
||||
$(MAKE) -C outs$(BIN)/test_hash/$(LIBUV_VER) all-am -j1
|
||||
$(MAKE) -C outside/$(LIBUV_VER) all-am -j1
|
||||
|
||||
$(LIBED25519):
|
||||
$(MAKE) -C outside/ed25519
|
||||
|
511
noun/hashtable.c
511
noun/hashtable.c
@ -3,17 +3,8 @@
|
||||
*/
|
||||
#include "all.h"
|
||||
|
||||
static void _ch_free_node(u3h_node*, c3_w);
|
||||
static void _ch_node_deflate(u3h_slot*, c3_w);
|
||||
static c3_c* _ch_pre(c3_w);
|
||||
static void _ch_print_node(u3h_node*, c3_w);
|
||||
static void* _ch_some_add(void*, c3_w, c3_w, u3_noun, c3_w*);
|
||||
static void* _ch_some_new(c3_w lef_w);
|
||||
static void _ch_trim_one(u3h_root*);
|
||||
static c3_o _ch_trim_one_some(u3h_slot*, c3_w);
|
||||
static c3_o _ch_trim_one_buck(u3h_slot*);
|
||||
static c3_o _ch_trim_one_node(u3h_slot*, c3_w);
|
||||
static void _ch_walk_node(u3h_node*, c3_w, void (*fun_f)(u3_noun));
|
||||
static void _ch_slot_put(u3h_slot* sot_w, u3_noun kev, c3_w lef_w, c3_w rem_w, c3_w* use_w);
|
||||
static c3_o _ch_trim_slot(u3h_slot *sot_w, c3_w lef_w);
|
||||
|
||||
/* u3h_new_cache(): create hashtable with bounded size.
|
||||
*/
|
||||
@ -114,102 +105,6 @@ _ch_node_new(void)
|
||||
return han_u;
|
||||
}
|
||||
|
||||
/* _ch_node_add(): add to node.
|
||||
*/
|
||||
static u3h_node*
|
||||
_ch_node_add(u3h_node* han_u, c3_w lef_w, c3_w rem_w, u3_noun kev, c3_w *use_w)
|
||||
{
|
||||
c3_w bit_w, inx_w, map_w, i_w;
|
||||
c3_c* pre = _ch_pre(lef_w);
|
||||
|
||||
lef_w -= 5;
|
||||
bit_w = (rem_w >> lef_w);
|
||||
rem_w = (rem_w & ((1 << lef_w) - 1));
|
||||
map_w = han_u->map_w;
|
||||
inx_w = _ch_popcount(map_w & ((1 << bit_w) - 1));
|
||||
|
||||
// there is already an entry at the slot with this index
|
||||
//
|
||||
if ( map_w & (1 << bit_w) ) {
|
||||
c3_w sot_w = han_u->sot_w[inx_w];
|
||||
|
||||
// this slot contains a node, so recurse into that node.
|
||||
//
|
||||
if ( _(u3h_slot_is_node(sot_w)) ) {
|
||||
fprintf(stderr, "node_add recursing\r\n");
|
||||
void* hav_v = u3h_slot_to_node(sot_w);
|
||||
|
||||
hav_v = _ch_some_add(hav_v, lef_w, rem_w, kev, use_w);
|
||||
han_u->sot_w[inx_w] = u3h_node_to_slot(hav_v);
|
||||
|
||||
return han_u;
|
||||
}
|
||||
// this slot contains just one key-value pair
|
||||
//
|
||||
else {
|
||||
u3_noun kov = u3h_slot_to_noun(sot_w);
|
||||
u3m_p("kov", kov);
|
||||
u3m_p("kev", kev);
|
||||
fprintf(stderr, "lef_w: %d\r\n", lef_w);
|
||||
if ( _(u3h_slot_is_null(sot_w)) ) {
|
||||
fprintf(stderr, "NULL\r\n");
|
||||
}
|
||||
if ( _(u3h_slot_is_node(sot_w)) ) {
|
||||
fprintf(stderr, "WTF\r\n");
|
||||
}
|
||||
|
||||
// the key is the same, so replace the value
|
||||
//
|
||||
if ( c3y == u3r_sing(u3h(kev), u3h(kov)) ) {
|
||||
fprintf(stderr, "replacing kov with kev\r\n");
|
||||
u3a_lose(kov);
|
||||
han_u->sot_w[inx_w] = u3h_noun_to_slot(kev);
|
||||
return han_u;
|
||||
}
|
||||
// the hash is the same, but the keys are different,
|
||||
// so create a new bucket or node.
|
||||
//
|
||||
else {
|
||||
c3_w rom_w = u3r_mug(u3h(kov)) & ((1 << lef_w) - 1);
|
||||
void* hav_v = _ch_some_new(lef_w);
|
||||
|
||||
// Optimize: need a custom collision create.
|
||||
//
|
||||
hav_v = _ch_some_add(hav_v, lef_w, rem_w, kev, use_w);
|
||||
hav_v = _ch_some_add(hav_v, lef_w, rom_w, kov, use_w);
|
||||
(*use_w)--;
|
||||
|
||||
han_u->sot_w[inx_w] = u3h_node_to_slot(hav_v);
|
||||
return han_u;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// nothing was at this slot.
|
||||
// Optimize: use u3a_wealloc.
|
||||
//
|
||||
c3_w len_w = _ch_popcount(map_w);
|
||||
u3h_node* nah_u = u3a_walloc(c3_wiseof(u3h_node) +
|
||||
((len_w + 1) * c3_wiseof(u3h_slot)));
|
||||
nah_u->map_w = han_u->map_w | (1 << bit_w);
|
||||
|
||||
for ( i_w = 0; i_w < inx_w; i_w++ ) {
|
||||
nah_u->sot_w[i_w] = han_u->sot_w[i_w];
|
||||
}
|
||||
nah_u->sot_w[inx_w] = u3h_noun_to_slot(kev);
|
||||
|
||||
for ( i_w = inx_w; i_w < len_w; i_w++ ) {
|
||||
nah_u->sot_w[i_w + 1] = han_u->sot_w[i_w];
|
||||
}
|
||||
nah_u->arm_w = han_u->arm_w;
|
||||
|
||||
u3a_wfree(han_u);
|
||||
|
||||
*use_w += 1;
|
||||
return nah_u;
|
||||
}
|
||||
}
|
||||
|
||||
/* _ch_some_new(): create node or bucket.
|
||||
*/
|
||||
static void*
|
||||
@ -223,6 +118,49 @@ _ch_some_new(c3_w lef_w)
|
||||
}
|
||||
}
|
||||
|
||||
/* _ch_node_add(): add to node.
|
||||
*/
|
||||
static u3h_node*
|
||||
_ch_node_add(u3h_node* han_u, c3_w lef_w, c3_w rem_w, u3_noun kev, c3_w *use_w)
|
||||
{
|
||||
c3_w bit_w, inx_w, map_w, i_w;
|
||||
|
||||
lef_w -= 5;
|
||||
bit_w = (rem_w >> lef_w);
|
||||
rem_w = (rem_w & ((1 << lef_w) - 1));
|
||||
map_w = han_u->map_w;
|
||||
inx_w = _ch_popcount(map_w & ((1 << bit_w) - 1));
|
||||
|
||||
if ( map_w & (1 << bit_w) ) {
|
||||
_ch_slot_put(&(han_u->sot_w[inx_w]), kev, lef_w, rem_w, use_w);
|
||||
return han_u;
|
||||
}
|
||||
else {
|
||||
// nothing was at this slot.
|
||||
// Optimize: use u3a_wealloc.
|
||||
//
|
||||
c3_w len_w = _ch_popcount(map_w);
|
||||
u3h_node* nah_u = u3a_walloc(c3_wiseof(u3h_node) +
|
||||
((len_w + 1) * c3_wiseof(u3h_slot)));
|
||||
nah_u->map_w = han_u->map_w | (1 << bit_w);
|
||||
nah_u->arm_w = han_u->arm_w;
|
||||
|
||||
for ( i_w = 0; i_w < inx_w; i_w++ ) {
|
||||
nah_u->sot_w[i_w] = han_u->sot_w[i_w];
|
||||
}
|
||||
u3m_p("empty node slot store", kev);
|
||||
nah_u->sot_w[inx_w] = u3h_noun_be_warm(u3h_noun_to_slot(kev));
|
||||
for ( i_w = inx_w; i_w < len_w; i_w++ ) {
|
||||
nah_u->sot_w[i_w + 1] = han_u->sot_w[i_w];
|
||||
}
|
||||
|
||||
u3a_wfree(han_u);
|
||||
*use_w += 1;
|
||||
return nah_u;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* _ch_some_add(): add to node or bucket.
|
||||
*/
|
||||
static void*
|
||||
@ -234,73 +172,37 @@ _ch_some_add(void* han_v, c3_w lef_w, c3_w rem_w, u3_noun kev, c3_w *use_w)
|
||||
else return _ch_node_add((u3h_node*)han_v, lef_w, rem_w, kev, use_w);
|
||||
}
|
||||
|
||||
/* _ch_print(): print hashtable.
|
||||
*/
|
||||
/* store a key-value pair in a u3h_slot (root or node, bucks work differently) */
|
||||
static void
|
||||
_ch_print_table(u3h_root* har_u)
|
||||
_ch_slot_put(u3h_slot* sot_w, u3_noun kev, c3_w lef_w, c3_w rem_w, c3_w* use_w)
|
||||
{
|
||||
u3h_slot sot_w;
|
||||
c3_w i_w;
|
||||
if ( c3y == u3h_slot_is_null(*sot_w) ) {
|
||||
u3m_p("empty slot store", kev);
|
||||
*sot_w = u3h_noun_be_warm(u3h_noun_to_slot(kev));
|
||||
*use_w += 1;
|
||||
}
|
||||
else if ( c3y == u3h_slot_is_noun(*sot_w) ) {
|
||||
u3_noun kov = u3h_slot_to_noun(*sot_w);
|
||||
if ( c3y == u3r_sing(u3h(kev), u3h(kov)) ) {
|
||||
u3m_p("same key store", u3nc(u3k(kev), u3k(kov)));
|
||||
*sot_w = u3h_noun_be_warm(u3h_noun_to_slot(kev));
|
||||
u3z(kov);
|
||||
}
|
||||
else {
|
||||
c3_w rom_w = u3r_mug(u3h(kov)) & ((1 << lef_w) - 1);
|
||||
void* hav_v = _ch_some_new(lef_w);
|
||||
|
||||
for ( i_w = 0; i_w < 64; i_w++ ) {
|
||||
sot_w = har_u->sot_w[i_w];
|
||||
if ( _(u3h_slot_is_null(sot_w)) ) {
|
||||
continue;
|
||||
}
|
||||
if ( _(u3h_slot_is_noun(sot_w)) ) {
|
||||
u3_noun elm = u3h_slot_to_noun(har_u->sot_w[i_w]);
|
||||
fprintf(stderr, "sot_w[%d]: {%d: %d}\r\n", i_w, u3h(elm), u3t(elm));
|
||||
}
|
||||
else if ( _(u3h_slot_is_node(sot_w)) ) {
|
||||
fprintf(stderr, "sot_w[%d]: <node>\r\n", i_w);
|
||||
_ch_print_node(u3h_slot_to_node(sot_w), 25);
|
||||
fprintf(stderr, "sot_w[%d]: </node>\r\n", i_w);
|
||||
*use_w -= 1; // take one out, add two
|
||||
hav_v = _ch_some_add(hav_v, lef_w, rem_w, kev, use_w);
|
||||
hav_v = _ch_some_add(hav_v, lef_w, rom_w, kov, use_w);
|
||||
*sot_w = u3h_node_to_slot(hav_v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* _ch_print_node(): print a node.
|
||||
*/
|
||||
static void
|
||||
_ch_print_node(u3h_node* han_u, c3_w lef_w)
|
||||
{
|
||||
c3_w len_w = _ch_popcount(han_u->map_w);
|
||||
c3_w i_w;
|
||||
c3_c* pre = _ch_pre(lef_w);
|
||||
|
||||
lef_w -= 5;
|
||||
|
||||
fprintf(stderr, "%snode %p\r\n", pre, han_u);
|
||||
|
||||
if ( 0 == lef_w ) {
|
||||
fprintf(stderr, "%s<bucket/>\r\n", pre);
|
||||
else {
|
||||
c3_assert( c3y == u3h_slot_is_node(*sot_w) );
|
||||
void* hav_v = _ch_some_add(u3h_slot_to_node(*sot_w), lef_w, rem_w, kev, use_w);
|
||||
*sot_w = u3h_node_to_slot(hav_v);
|
||||
}
|
||||
|
||||
for ( i_w = 0; i_w < len_w; i_w++ ) {
|
||||
c3_w sot_w = han_u->sot_w[i_w];
|
||||
|
||||
if ( _(u3h_slot_is_noun(sot_w)) ) {
|
||||
u3_noun kev = u3h_slot_to_noun(sot_w);
|
||||
|
||||
fprintf(stderr, "%snode[%d]: {%d: %d}\r\n", pre, i_w, u3h(kev), u3t(kev));
|
||||
}
|
||||
else if ( _(u3h_slot_is_node(sot_w)) ) {
|
||||
_ch_print_node(u3h_slot_to_node(sot_w), lef_w);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* _ch_pre(): get printing whitepsace prefix based on recursion depth.
|
||||
*/
|
||||
static c3_c*
|
||||
_ch_pre(c3_w lef_w)
|
||||
{
|
||||
if ( 25 == lef_w ) { return " "; }
|
||||
else if ( 20 == lef_w ) { return " "; }
|
||||
else if ( 15 == lef_w ) { return " "; }
|
||||
else if ( 10 == lef_w ) { return " "; }
|
||||
else if ( 5 == lef_w ) { return " "; }
|
||||
else { return " "; }
|
||||
}
|
||||
|
||||
/* u3h_put(): insert in hashtable.
|
||||
@ -314,50 +216,146 @@ u3h_put(u3p(u3h_root) har_p, u3_noun key, u3_noun val)
|
||||
u3_noun kev = u3nc(u3k(key), val);
|
||||
c3_w mug_w = u3r_mug(key);
|
||||
c3_w inx_w = (mug_w >> 25); // 6 bits
|
||||
c3_w rem_w = (mug_w & ((1 << 25) - 1)); // TODO: macro
|
||||
c3_w sot_w = har_u->sot_w[inx_w];
|
||||
|
||||
// TODO: remove
|
||||
//u3m_p("put", kev);
|
||||
//fprintf(stderr, "put: inx_w %d\r\n", inx_w);
|
||||
|
||||
// nothing stored for this 6-bit prefix
|
||||
//
|
||||
if ( _(u3h_slot_is_null(sot_w)) ) {
|
||||
har_u->sot_w[inx_w] = u3h_noun_to_slot(kev);
|
||||
har_u->use_w++;
|
||||
|
||||
}
|
||||
else {
|
||||
u3h_node* han_u;
|
||||
c3_w *use_w = &(har_u->use_w);
|
||||
|
||||
// one key-value pair for this prefix
|
||||
//
|
||||
if ( _(u3h_slot_is_noun(sot_w)) ) {
|
||||
u3_noun kov = u3h_slot_to_noun(sot_w);
|
||||
c3_w rom_w = u3r_mug(u3h(kov)) & ((1 << 25) - 1);
|
||||
|
||||
han_u = _ch_node_new();
|
||||
han_u = _ch_node_add(han_u, 25, rem_w, kev, use_w);
|
||||
han_u = _ch_node_add(han_u, 25, rom_w, kov, use_w);
|
||||
(*use_w)--;
|
||||
}
|
||||
// more than one key-value pair for this prefix; use a node
|
||||
//
|
||||
else {
|
||||
han_u = _ch_node_add(u3h_slot_to_node(sot_w), 25, rem_w, kev, use_w);
|
||||
}
|
||||
har_u->sot_w[inx_w] = u3h_node_to_slot(han_u);
|
||||
}
|
||||
c3_w rem_w = (mug_w & ((1 << 25) - 1));
|
||||
|
||||
_ch_slot_put(&(har_u->sot_w[inx_w]), kev, 25, rem_w, &(har_u->use_w));
|
||||
if ( har_u->clk_w > 0 ) {
|
||||
u3h_trim_to(har_p, har_u->clk_w);
|
||||
}
|
||||
//TODO:remove
|
||||
//fprintf(stderr, "put: final use_w: %d\r\n", har_u->use_w);
|
||||
}
|
||||
|
||||
//_ch_print_table(har_u);
|
||||
static c3_o
|
||||
_ch_trim_buck(u3h_slot* sot_w)
|
||||
{
|
||||
u3h_buck* hab_u = (u3h_buck*) u3h_slot_to_node(*sot_w);
|
||||
c3_w i_w, j_w, len_w = hab_u->len_w;
|
||||
|
||||
for ( i_w = hab_u->arm_w; i_w < len_w; hab_u->arm_w = ++i_w ) {
|
||||
u3h_slot* tos_w = &(hab_u->sot_w[i_w]);
|
||||
if ( c3y == _ch_trim_slot(tos_w, 0) ) {
|
||||
// child always shrinks in bucket
|
||||
if ( 2 == len_w ) {
|
||||
// pick one of two items in bucket
|
||||
*sot_w = hab_u->sot_w[ (0 == i_w) ? 1 : 0 ];
|
||||
}
|
||||
else {
|
||||
// make smaller bucket
|
||||
len_w -= 1;
|
||||
u3h_buck* bah_u = u3a_walloc(c3_wiseof(u3h_buck) +
|
||||
len_w * c3_wiseof(u3h_slot));
|
||||
bah_u->len_w = len_w;
|
||||
bah_u->arm_w = hab_u->arm_w;
|
||||
|
||||
for ( j_w = 0; j_w < i_w; ++j_w ) {
|
||||
bah_u->sot_w[j_w] = hab_u->sot_w[j_w];
|
||||
}
|
||||
for ( j_w = i_w; j_w < len_w; ++j_w ) {
|
||||
bah_u->sot_w[j_w] = hab_u->sot_w[j_w + 1];
|
||||
}
|
||||
|
||||
*sot_w = u3h_node_to_slot(bah_u);
|
||||
}
|
||||
u3a_wfree(hab_u);
|
||||
return c3y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static c3_o
|
||||
_ch_trim_node(u3h_slot* sot_w, c3_w lef_w)
|
||||
{
|
||||
u3h_node* han_u = (u3h_node*) u3h_slot_to_node(*sot_w);
|
||||
c3_w i_w, j_w, len_w = _ch_popcount(han_u->map_w);
|
||||
lef_w -= 5;
|
||||
|
||||
for ( i_w = han_u->arm_w; i_w < len_w; han_u->arm_w = ++i_w ) {
|
||||
u3h_slot* tos_w = &(han_u->sot_w[i_w]);
|
||||
if ( c3y == _ch_trim_slot(tos_w, lef_w) ) {
|
||||
if ( c3y == u3h_slot_is_null(*tos_w) ) {
|
||||
// child shrank
|
||||
if ( 2 == len_w ) {
|
||||
// shrink to a single key-value pair
|
||||
*sot_w = han_u->sot_w[ (0 == i_w) ? 1 : 0 ];
|
||||
}
|
||||
else {
|
||||
// shrink to a smaller node
|
||||
len_w -= 1;
|
||||
u3h_node* nah_u = u3a_walloc(c3_wiseof(u3h_node) +
|
||||
(len_w * c3_wiseof(u3h_slot)));
|
||||
nah_u->arm_w = han_u->arm_w;
|
||||
nah_u->map_w = han_u->map_w & ~(1 << i_w);
|
||||
|
||||
for ( j_w = 0; j_w < i_w; j_w++ ) {
|
||||
nah_u->sot_w[j_w] = han_u->sot_w[j_w];
|
||||
}
|
||||
for ( j_w = i_w; j_w < len_w; ++j_w ) {
|
||||
nah_u->sot_w[j_w] = han_u->sot_w[j_w + 1];
|
||||
}
|
||||
*sot_w = u3h_node_to_slot(nah_u);
|
||||
}
|
||||
u3a_wfree(han_u);
|
||||
}
|
||||
return c3y;
|
||||
}
|
||||
}
|
||||
|
||||
han_u->arm_w = 0;
|
||||
return c3n;
|
||||
}
|
||||
|
||||
static c3_o
|
||||
_ch_trim_some(u3h_slot* sot_w, c3_w lef_w)
|
||||
{
|
||||
if ( 0 == lef_w ) {
|
||||
return _ch_trim_buck(sot_w);
|
||||
}
|
||||
else {
|
||||
return _ch_trim_node(sot_w, lef_w);
|
||||
}
|
||||
}
|
||||
|
||||
/* _ch_trim_slot(): trim one key-value pair from slot */
|
||||
static c3_o
|
||||
_ch_trim_slot(u3h_slot *sot_w, c3_w lef_w)
|
||||
{
|
||||
if ( c3y == u3h_slot_is_null(*sot_w) ) {
|
||||
return c3n;
|
||||
}
|
||||
else {
|
||||
if ( c3y == u3h_slot_is_noun(*sot_w) ) {
|
||||
if ( c3y == u3h_slot_is_warm(*sot_w) ) {
|
||||
*sot_w = u3h_noun_be_cold(*sot_w);
|
||||
return c3n;
|
||||
}
|
||||
else {
|
||||
u3_noun kev = u3h_slot_to_noun(*sot_w);
|
||||
u3z(kev);
|
||||
*sot_w = 0;
|
||||
return c3y;
|
||||
}
|
||||
}
|
||||
else {
|
||||
c3_assert( c3y == u3h_slot_is_node(*sot_w) );
|
||||
return _ch_trim_some(sot_w, lef_w);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* _ch_trim_root(): trim one key-value pair from root
|
||||
*/
|
||||
static void
|
||||
_ch_trim_root(u3h_root *har_u)
|
||||
{
|
||||
u3h_slot* sot_w;
|
||||
c3_assert(har_u->use_w > 0);
|
||||
|
||||
while ( 1 ) {
|
||||
sot_w = &(har_u->sot_w[har_u->arm_w]);
|
||||
if ( c3y == _ch_trim_slot(sot_w, 25) ) {
|
||||
return;
|
||||
}
|
||||
har_u->arm_w = (har_u->arm_w + 1) % 64;
|
||||
}
|
||||
}
|
||||
|
||||
/* u3h_trim_to(): trim to n key-value pairs
|
||||
@ -367,77 +365,7 @@ u3h_trim_to(u3p(u3h_root) har_p, c3_w n_w)
|
||||
{
|
||||
u3h_root* har_u = u3to(u3h_root, har_p);
|
||||
while ( har_u->use_w > n_w ) {
|
||||
_ch_trim_one(har_u);
|
||||
}
|
||||
}
|
||||
|
||||
/* _ch_trim_one(): trim off one key-value pair
|
||||
*/
|
||||
static void
|
||||
_ch_trim_one(u3h_root *har_u)
|
||||
{
|
||||
u3h_slot* root_sot_w = &(har_u->sot_w[har_u->arm_w]);
|
||||
|
||||
c3_assert(har_u->use_w > 0);
|
||||
|
||||
while ( 1 ) {
|
||||
|
||||
if ( _(u3h_slot_is_null(*root_sot_w)) ) {
|
||||
// next
|
||||
}
|
||||
else if ( _(u3h_slot_is_node(*root_sot_w)) ) {
|
||||
c3_o trimmed = _ch_trim_one_some(root_sot_w, 25);
|
||||
if ( _(trimmed) ) {
|
||||
if ( _(u3h_slot_is_node(*root_sot_w)) ) {
|
||||
//_ch_print_node(root_sot_w, 25);
|
||||
}
|
||||
|
||||
har_u->use_w--;
|
||||
return;
|
||||
}
|
||||
// next
|
||||
}
|
||||
else if ( _(u3h_slot_is_warm(*root_sot_w)) ) {
|
||||
har_u->sot_w[har_u->arm_w] = u3h_noun_be_cold(har_u->sot_w[har_u->arm_w]);
|
||||
}
|
||||
else {
|
||||
c3_assert(_(u3h_slot_is_noun(*root_sot_w)));
|
||||
|
||||
u3_noun kev = u3h_slot_to_noun(*root_sot_w);
|
||||
u3a_lose(kev);
|
||||
har_u->sot_w[har_u->arm_w] = 0;
|
||||
|
||||
har_u->use_w--;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
do {
|
||||
har_u->arm_w = (har_u->arm_w + 1) % 64;
|
||||
}
|
||||
while ( _(u3h_slot_is_null(har_u->sot_w[har_u->arm_w])) );
|
||||
root_sot_w = &(har_u->sot_w[har_u->arm_w]);
|
||||
}
|
||||
}
|
||||
|
||||
/* _ch_trim_one_some(): trim one key-value pair from either a node or a bucket.
|
||||
*/
|
||||
static c3_o
|
||||
_ch_trim_one_some(u3h_slot* hal_w, c3_w lef_w)
|
||||
{
|
||||
c3_c* pre = _ch_pre(lef_w);
|
||||
|
||||
if ( 0 == lef_w ) {
|
||||
// TODO: _ch_buck_deflate()
|
||||
return _ch_trim_one_buck(hal_w);
|
||||
}
|
||||
else {
|
||||
c3_o del_o = _ch_trim_one_node(hal_w, lef_w);
|
||||
|
||||
if ( _(del_o) ) {
|
||||
_ch_node_deflate(hal_w, lef_w);
|
||||
}
|
||||
return del_o;
|
||||
_ch_trim_root(har_u);
|
||||
}
|
||||
}
|
||||
|
||||
@ -518,7 +446,7 @@ _ch_trim_one_buck(u3h_slot* hal_w)
|
||||
static c3_o
|
||||
_ch_trim_one_node(u3h_slot* hal_w, c3_w lef_w)
|
||||
{
|
||||
u3h_node* han_u = (u3h_node*)u3h_slot_to_node(*hal_w);
|
||||
u3h_node* han_u = (u3h_node*) u3h_slot_to_node(*hal_w);
|
||||
u3h_slot sot_w = han_u->sot_w[han_u->arm_w];
|
||||
c3_w len_w = _ch_popcount(han_u->map_w);
|
||||
c3_c* pre = _ch_pre(lef_w);
|
||||
@ -569,31 +497,6 @@ _ch_trim_one_node(u3h_slot* hal_w, c3_w lef_w)
|
||||
return c3n;
|
||||
}
|
||||
|
||||
/* _ch_node_deflate(); convert singleton node to key-value pair.
|
||||
*/
|
||||
static void
|
||||
_ch_node_deflate(u3h_slot* sot_w, c3_w lef_w)
|
||||
{
|
||||
u3h_node* han_u = (u3h_node*)u3h_slot_to_node(*sot_w);
|
||||
c3_w len_w = _ch_popcount(han_u->map_w);
|
||||
c3_c* pre = _ch_pre(lef_w);
|
||||
|
||||
if ( 1 == len_w ) {
|
||||
if ( _(u3h_slot_is_node(han_u->sot_w[0])) ) {
|
||||
_ch_node_deflate(&han_u->sot_w[0], lef_w);
|
||||
}
|
||||
|
||||
// bump refcount before freeing node to make sure kev
|
||||
// doesn't get freed.
|
||||
//
|
||||
u3_noun kev = u3k(u3h_slot_to_noun(han_u->sot_w[0]));
|
||||
|
||||
_ch_free_node(han_u, lef_w);
|
||||
|
||||
*sot_w = u3h_noun_to_slot(kev);
|
||||
}
|
||||
}
|
||||
|
||||
/* _ch_buck_hum(): read in bucket.
|
||||
*/
|
||||
static c3_o
|
||||
|
@ -1,35 +1,35 @@
|
||||
#include "all.h"
|
||||
|
||||
static void _ch_setup(void);
|
||||
static void _ch_test_cache_trimming(void);
|
||||
static void _ch_test_no_cache(void);
|
||||
static void _setup(void);
|
||||
static void _test_cache_trimming(void);
|
||||
static void _test_no_cache(void);
|
||||
|
||||
/* main(): run all test cases.
|
||||
*/
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
_ch_setup();
|
||||
_setup();
|
||||
|
||||
//_ch_test_no_cache();
|
||||
_ch_test_cache_trimming();
|
||||
_test_no_cache();
|
||||
_test_cache_trimming();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* _ch_setup(): prepare for tests.
|
||||
/* _setup(): prepare for tests.
|
||||
*/
|
||||
static void
|
||||
_ch_setup(void)
|
||||
_setup(void)
|
||||
{
|
||||
u3m_init(c3y);
|
||||
u3m_pave(c3y, c3n);
|
||||
}
|
||||
|
||||
/* _ch_test_no_cache(): test a hashtable without caching.
|
||||
/* _test_no_cache(): test a hashtable without caching.
|
||||
*/
|
||||
static void
|
||||
_ch_test_no_cache(void)
|
||||
_test_no_cache(void)
|
||||
{
|
||||
c3_w i_w;
|
||||
c3_w max_w = 1000;
|
||||
@ -43,22 +43,26 @@ _ch_test_no_cache(void)
|
||||
for ( i_w = 0; i_w < max_w; i_w++ ) {
|
||||
c3_assert(i_w + max_w == u3h_get(har_p, i_w));
|
||||
}
|
||||
printf("test_no_cache: ok\n");
|
||||
}
|
||||
|
||||
/* _ch_test_cache_trimming(): ensure a caching hashtable removes stale items.
|
||||
/* _test_cache_trimming(): ensure a caching hashtable removes stale items.
|
||||
*/
|
||||
static void
|
||||
_ch_test_cache_trimming(void)
|
||||
_test_cache_trimming(void)
|
||||
{
|
||||
c3_w max_w = 1000;
|
||||
c3_w max_w = 10000;
|
||||
c3_w i_w, hit_w = 0, mis_w = 0;
|
||||
|
||||
//u3p(u3h_root) har_p = u3h_new_cache(max_w / 2);
|
||||
u3p(u3h_root) har_p = u3h_new_cache(10);
|
||||
u3p(u3h_root) har_p = u3h_new_cache(max_w / 10 );
|
||||
u3h_root* har_u = u3to(u3h_root, har_p);
|
||||
|
||||
for ( i_w = 0; i_w < max_w; i_w++ ) {
|
||||
u3h_put(har_p, i_w, i_w + max_w);
|
||||
}
|
||||
|
||||
fprintf(stderr, "%d: %d\r\n", max_w - 1, u3h_get(har_p, max_w - 1));
|
||||
c3_assert( ( max_w + max_w - 1) == u3h_get(har_p, max_w - 1) );
|
||||
c3_assert( ( max_w / 10 ) == har_u->use_w );
|
||||
printf("test_cache_trimming: ok\n");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user