This commit is contained in:
Paul Driver 2017-11-06 21:05:25 -08:00 committed by Ted Blackman
parent 311b0b00f8
commit f6d30a0700
2 changed files with 28 additions and 151 deletions

View File

@ -51,7 +51,7 @@ _ch_buck_new(void)
return hab_u; return hab_u;
} }
/* ha_buck_add(): add to bucket. /* ch_buck_add(): add to bucket.
*/ */
static u3h_buck* static u3h_buck*
_ch_buck_add(u3h_buck* hab_u, u3_noun kev, c3_w *use_w) _ch_buck_add(u3h_buck* hab_u, u3_noun kev, c3_w *use_w)
@ -143,12 +143,13 @@ _ch_node_add(u3h_node* han_u, c3_w lef_w, c3_w rem_w, u3_noun kev, c3_w *use_w)
u3h_node* nah_u = u3a_walloc(c3_wiseof(u3h_node) + u3h_node* nah_u = u3a_walloc(c3_wiseof(u3h_node) +
((len_w + 1) * c3_wiseof(u3h_slot))); ((len_w + 1) * c3_wiseof(u3h_slot)));
nah_u->map_w = han_u->map_w | (1 << bit_w); nah_u->map_w = han_u->map_w | (1 << bit_w);
nah_u->arm_w = han_u->arm_w; // arm_w should always be one past the thing we just put in,
// to avoid pathological hash-ordering behavior
nah_u->arm_w = (inx_w + 1) % (len_w + 1);
for ( i_w = 0; i_w < inx_w; i_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[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)); 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++ ) { 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->sot_w[i_w + 1] = han_u->sot_w[i_w];
@ -160,7 +161,6 @@ _ch_node_add(u3h_node* han_u, c3_w lef_w, c3_w rem_w, u3_noun kev, c3_w *use_w)
} }
} }
/* _ch_some_add(): add to node or bucket. /* _ch_some_add(): add to node or bucket.
*/ */
static void* static void*
@ -177,14 +177,12 @@ static void
_ch_slot_put(u3h_slot* sot_w, u3_noun kev, c3_w lef_w, c3_w rem_w, c3_w* use_w) _ch_slot_put(u3h_slot* sot_w, u3_noun kev, c3_w lef_w, c3_w rem_w, c3_w* use_w)
{ {
if ( c3y == u3h_slot_is_null(*sot_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)); *sot_w = u3h_noun_be_warm(u3h_noun_to_slot(kev));
*use_w += 1; *use_w += 1;
} }
else if ( c3y == u3h_slot_is_noun(*sot_w) ) { else if ( c3y == u3h_slot_is_noun(*sot_w) ) {
u3_noun kov = u3h_slot_to_noun(*sot_w); u3_noun kov = u3h_slot_to_noun(*sot_w);
if ( c3y == u3r_sing(u3h(kev), u3h(kov)) ) { 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)); *sot_w = u3h_noun_be_warm(u3h_noun_to_slot(kev));
u3z(kov); u3z(kov);
} }
@ -193,8 +191,8 @@ _ch_slot_put(u3h_slot* sot_w, u3_noun kev, c3_w lef_w, c3_w rem_w, c3_w* use_w)
void* hav_v = _ch_some_new(lef_w); void* hav_v = _ch_some_new(lef_w);
*use_w -= 1; // take one out, add two *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); hav_v = _ch_some_add(hav_v, lef_w, rom_w, kov, use_w);
hav_v = _ch_some_add(hav_v, lef_w, rem_w, kev, use_w);
*sot_w = u3h_node_to_slot(hav_v); *sot_w = u3h_node_to_slot(hav_v);
} }
} }
@ -230,8 +228,9 @@ _ch_trim_buck(u3h_slot* sot_w)
u3h_buck* hab_u = (u3h_buck*) u3h_slot_to_node(*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; 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 ) { for ( i_w = hab_u->arm_w; i_w < len_w; ++i_w ) {
u3h_slot* tos_w = &(hab_u->sot_w[i_w]); u3h_slot* tos_w = &(hab_u->sot_w[i_w]);
hab_u->arm_w += 1;
if ( c3y == _ch_trim_slot(tos_w, 0) ) { if ( c3y == _ch_trim_slot(tos_w, 0) ) {
// child always shrinks in bucket // child always shrinks in bucket
if ( 2 == len_w ) { if ( 2 == len_w ) {
@ -240,16 +239,16 @@ _ch_trim_buck(u3h_slot* sot_w)
} }
else { else {
// make smaller bucket // make smaller bucket
len_w -= 1; c3_w nel_w = len_w - 1;
u3h_buck* bah_u = u3a_walloc(c3_wiseof(u3h_buck) + u3h_buck* bah_u = u3a_walloc(c3_wiseof(u3h_buck) +
len_w * c3_wiseof(u3h_slot)); nel_w * c3_wiseof(u3h_slot));
bah_u->len_w = len_w; bah_u->len_w = nel_w;
bah_u->arm_w = hab_u->arm_w; bah_u->arm_w = hab_u->arm_w;
for ( j_w = 0; j_w < i_w; ++j_w ) { for ( j_w = 0; j_w < i_w; ++j_w ) {
bah_u->sot_w[j_w] = hab_u->sot_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 ) { for ( j_w = i_w; j_w < nel_w; ++j_w ) {
bah_u->sot_w[j_w] = hab_u->sot_w[j_w + 1]; bah_u->sot_w[j_w] = hab_u->sot_w[j_w + 1];
} }
@ -259,6 +258,8 @@ _ch_trim_buck(u3h_slot* sot_w)
return c3y; return c3y;
} }
} }
hab_u->arm_w = 0;
return c3n;
} }
static c3_o static c3_o
@ -268,33 +269,36 @@ _ch_trim_node(u3h_slot* sot_w, c3_w lef_w)
c3_w i_w, j_w, len_w = _ch_popcount(han_u->map_w); c3_w i_w, j_w, len_w = _ch_popcount(han_u->map_w);
lef_w -= 5; lef_w -= 5;
for ( i_w = han_u->arm_w; i_w < len_w; han_u->arm_w = ++i_w ) { for ( i_w = han_u->arm_w; i_w < len_w; ++i_w ) {
u3h_slot* tos_w = &(han_u->sot_w[i_w]); u3h_slot* tos_w = &(han_u->sot_w[i_w]);
if ( c3y == _ch_trim_slot(tos_w, lef_w) ) { if ( c3y == _ch_trim_slot(tos_w, lef_w) ) {
if ( c3y == u3h_slot_is_null(*tos_w) ) { if ( 0 == *tos_w ) {
// child shrank // entire child is gone, need to shrink
if ( 2 == len_w ) { if ( 2 == len_w ) {
// shrink to a single key-value pair // shrink to a single key-value pair
*sot_w = han_u->sot_w[ (0 == i_w) ? 1 : 0 ]; *sot_w = han_u->sot_w[ (0 == i_w) ? 1 : 0 ];
} }
else { else {
// shrink to a smaller node // shrink to a smaller node
len_w -= 1; c3_w nel_w = len_w - 1;
u3h_node* nah_u = u3a_walloc(c3_wiseof(u3h_node) + u3h_node* nah_u = u3a_walloc(c3_wiseof(u3h_node) +
(len_w * c3_wiseof(u3h_slot))); (nel_w * c3_wiseof(u3h_slot)));
nah_u->arm_w = han_u->arm_w; nah_u->arm_w = han_u->arm_w;
nah_u->map_w = han_u->map_w & ~(1 << i_w); nah_u->map_w = han_u->map_w & ~(1 << i_w);
for ( j_w = 0; j_w < i_w; j_w++ ) { for ( j_w = 0; j_w < i_w; ++j_w ) {
nah_u->sot_w[j_w] = han_u->sot_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 ) { for ( j_w = i_w; j_w < nel_w; ++j_w ) {
nah_u->sot_w[j_w] = han_u->sot_w[j_w + 1]; nah_u->sot_w[j_w] = han_u->sot_w[j_w + 1];
} }
*sot_w = u3h_node_to_slot(nah_u); *sot_w = u3h_node_to_slot(nah_u);
} }
u3a_wfree(han_u); u3a_wfree(han_u);
} }
else {
han_u->arm_w += 1;
}
return c3y; return c3y;
} }
} }
@ -351,10 +355,11 @@ _ch_trim_root(u3h_root *har_u)
while ( 1 ) { while ( 1 ) {
sot_w = &(har_u->sot_w[har_u->arm_w]); sot_w = &(har_u->sot_w[har_u->arm_w]);
har_u->arm_w = (har_u->arm_w + 1) % 64;
if ( c3y == _ch_trim_slot(sot_w, 25) ) { if ( c3y == _ch_trim_slot(sot_w, 25) ) {
har_u->use_w -= 1;
return; return;
} }
har_u->arm_w = (har_u->arm_w + 1) % 64;
} }
} }
@ -369,134 +374,6 @@ u3h_trim_to(u3p(u3h_root) har_p, c3_w n_w)
} }
} }
/* _ch_trim_one_buck(): trim one key-value pair from a bucket.
*/
static c3_o
_ch_trim_one_buck(u3h_slot* hal_w)
{
u3h_buck* hab_u = (u3h_buck*)u3h_slot_to_node(*hal_w);
u3h_slot sot_w = hab_u->sot_w[hab_u->arm_w];
c3_assert(hab_u->len_w != 1);
// instead of assigning a bucket with only one element,
// assign a single key-value pair as a slot.
//
if ( hab_u->len_w == 2 ) {
u3h_slot fir_w = hab_u->sot_w[0];
u3h_slot sec_w = hab_u->sot_w[1];
if ( _(u3h_slot_is_warm(fir_w)) ) {
if ( _(u3h_slot_is_warm(sec_w)) ) {
hab_u->sot_w[0] = u3h_noun_be_cold(fir_w);
hab_u->sot_w[1] = u3h_noun_be_cold(sec_w);
return c3n;
}
else {
u3a_lose(u3h_slot_to_noun(sec_w));
*hal_w = u3h_noun_be_cold(u3h_slot_to_noun(fir_w));
return c3y;
}
}
else {
u3a_lose(u3h_slot_to_noun(fir_w));
*hal_w = u3h_slot_to_noun(sec_w);
return c3y;
}
}
else {
while ( hab_u->arm_w < hab_u->len_w ) {
sot_w = hab_u->sot_w[hab_u->arm_w];
if ( _(u3h_slot_is_warm(sot_w)) ) {
hab_u->sot_w[hab_u->arm_w] = u3h_noun_be_cold(sot_w);
hab_u->arm_w++;
// next
}
else {
c3_w i_w;
c3_w len_w = hab_u->len_w;
u3h_buck* bah_u = u3a_walloc(c3_wiseof(u3h_buck) +
(len_w - 1) * c3_wiseof(u3h_slot));
bah_u->len_w = len_w - 1;
bah_u->arm_w = hab_u->arm_w;
for ( i_w = 0; i_w < hab_u->arm_w; i_w++ ) {
bah_u->sot_w[i_w] = hab_u->sot_w[i_w];
}
u3a_lose(u3h_slot_to_noun(hab_u->sot_w[hab_u->arm_w]));
for ( i_w = hab_u->arm_w; i_w < bah_u->len_w; i_w++ ) {
bah_u->sot_w[i_w] = hab_u->sot_w[i_w + 1];
}
*hal_w = u3h_node_to_slot(bah_u);
return c3y;
}
}
hab_u->arm_w = 0;
return c3n;
}
}
/* _ch_trim_one_node(): trim one key-value pair from a node.
*/
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_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);
c3_assert(len_w != 1);
while (han_u->arm_w < len_w) {
sot_w = han_u->sot_w[han_u->arm_w];
if ( _(u3h_slot_is_node(sot_w)) ) {
if ( _(_ch_trim_one_some(&sot_w, lef_w - 5)) ) {
return c3y;
}
han_u->arm_w++; // next
}
else if ( _(u3h_slot_is_warm(sot_w)) ) {
han_u->sot_w[han_u->arm_w] = u3h_noun_be_cold(sot_w);
han_u->arm_w++; // next
}
else {
c3_w bit_w, i_w, inx_w;
u3h_node* nah_u = u3a_walloc(c3_wiseof(u3h_node) +
((len_w - 1) * c3_wiseof(u3h_slot)));
bit_w = han_u->arm_w;
nah_u->map_w = han_u->map_w & ~(1 << bit_w);
inx_w = _ch_popcount(nah_u->map_w & ((1 << bit_w) - 1));
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];
}
u3a_lose(u3h_slot_to_noun(han_u->sot_w[inx_w]));
for ( i_w = inx_w; i_w < len_w - 1; i_w++ ) {
nah_u->sot_w[i_w] = han_u->sot_w[i_w + 1];
}
*hal_w = u3h_node_to_slot(nah_u);
return c3y;
}
}
han_u->arm_w = 0;
return c3n;
}
/* _ch_buck_hum(): read in bucket. /* _ch_buck_hum(): read in bucket.
*/ */
static c3_o static c3_o

View File

@ -11,7 +11,7 @@ main(int argc, char* argv[])
{ {
_setup(); _setup();
_test_no_cache(); //_test_no_cache();
_test_cache_trimming(); _test_cache_trimming();
return 0; return 0;
@ -32,7 +32,7 @@ static void
_test_no_cache(void) _test_no_cache(void)
{ {
c3_w i_w; c3_w i_w;
c3_w max_w = 1000; c3_w max_w = 10000;
u3p(u3h_root) har_p = u3h_new(); u3p(u3h_root) har_p = u3h_new();
@ -51,7 +51,7 @@ _test_no_cache(void)
static void static void
_test_cache_trimming(void) _test_cache_trimming(void)
{ {
c3_w max_w = 10000; c3_w max_w = 620;
c3_w i_w, hit_w = 0, mis_w = 0; 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(max_w / 2);