Update arm_u state correctly in _ch_buck_trim

Previously, trimming the penultimate value from a hash bucket would
leave arm_u in an inconsistent state: mug_w would be pointing at
a key-value pair in a node, but arm_u.buc_o and arm_u.inx_w were
not updated to reflect this. Correspondingly, a rare edge case could
occur where said key-value pair would not be marked cold (due to
buc_o), which is a semantic error.
This commit is contained in:
Paul Driver 2017-11-15 10:00:11 -08:00
parent b65b23cbcb
commit c284c800bf

View File

@ -281,10 +281,12 @@ _ch_trim_buck(u3h_root* har_u, u3h_slot* sot_w)
u3h_slot* tos_w = &(hab_u->sot_w[har_u->arm_u.inx_w]);
if ( c3y == _ch_trim_slot(har_u, tos_w, 0, 0) ) {
if ( 2 == len_w ) {
// 2 things in bucket: pick the other and promote
//
// 2 things in bucket: debucketize to key-value pair, the next
// run will point at this pair (same mug_w, no longer in bucket)
*sot_w = hab_u->sot_w[ (0 == har_u->arm_u.inx_w) ? 1 : 0 ];
u3a_wfree(hab_u);
har_u->arm_u.inx_w = 0;
har_u->arm_u.buc_o = c3n;
}
else {
// shrink bucket in place; don't reallocate, we could be low on memory