Merge pull request #5218 from urbit/ea/memset-to-wipe-dict32

vere: use memset to wipe hashmaps
This commit is contained in:
Edward Amsden 2021-09-15 10:13:25 -04:00 committed by GitHub
commit 698fd6f66f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 50 additions and 40 deletions

View File

@ -40,7 +40,6 @@ typedef uint32_t ur_mug;
#define ur_pail_max 10
typedef struct ur_pail32_s {
uint8_t fill;
ur_nref refs[ur_pail_max];
uint32_t vals[ur_pail_max];
} ur_pail32_t;
@ -48,11 +47,11 @@ typedef struct ur_pail32_s {
typedef struct ur_dict32_s {
uint64_t prev;
uint64_t size;
uint8_t *fills;
ur_pail32_t *buckets;
} ur_dict32_t;
typedef struct ur_pail64_s {
uint8_t fill;
ur_nref refs[ur_pail_max];
uint64_t vals[ur_pail_max];
} ur_pail64_t;
@ -60,17 +59,18 @@ typedef struct ur_pail64_s {
typedef struct ur_dict64_s {
uint64_t prev;
uint64_t size;
uint8_t *fills;
ur_pail64_t *buckets;
} ur_dict64_t;
typedef struct ur_pail_s {
uint8_t fill;
ur_nref refs[ur_pail_max];
} ur_pail_t;
typedef struct ur_dict_s {
uint64_t prev;
uint64_t size;
uint8_t *fills;
ur_pail_t *buckets;
} ur_dict_t;

View File

@ -33,15 +33,17 @@ void
ur_dict32_grow(ur_root_t *r, ur_dict32_t *dict, uint64_t prev, uint64_t size)
{
ur_pail32_t *buckets, *old_buckets = dict->buckets;
uint8_t *fills, *old_fills = dict->fills;
uint64_t old_size = dict->size;
uint64_t i, next = prev + size;
buckets = _oom("dict32_grow", calloc(next, sizeof(*buckets)));
fills = _oom("dict32_grow", calloc(next, sizeof(*fills)));
if ( old_buckets ) {
for ( i = 0; i < old_size; i++ ) {
ur_pail32_t *old_bucket = &(old_buckets[i]);
uint8_t j, old_fill = old_bucket->fill;
uint8_t j, old_fill = old_fills[i];
for ( j = 0; j < old_fill; j++ ) {
uint32_t val = old_bucket->vals[j];
@ -50,24 +52,27 @@ ur_dict32_grow(ur_root_t *r, ur_dict32_t *dict, uint64_t prev, uint64_t size)
uint64_t idx = ( mug % next );
ur_pail32_t *bucket = &(buckets[idx]);
uint8_t new_fill = bucket->fill;
uint8_t new_fill = fills[idx];
if ( ur_pail_max == new_fill ) {
free(buckets);
free(fills);
return ur_dict32_grow(r, dict, size, next);
}
bucket->refs[new_fill] = ref;
bucket->vals[new_fill] = val;
bucket->fill = 1 + new_fill;
fills[idx] = 1 + new_fill;
}
}
free(old_buckets);
free(old_fills);
}
dict->prev = size;
dict->size = next;
dict->fills = fills;
dict->buckets = buckets;
}
@ -78,7 +83,7 @@ ur_dict32_get(ur_root_t *r, ur_dict32_t *dict, ur_nref ref, uint32_t *out)
uint64_t idx = ( mug % dict->size );
ur_pail32_t *bucket = &(dict->buckets[idx]);
uint8_t i, fill = bucket->fill;
uint8_t i, fill = dict->fills[idx];
for ( i = 0; i < fill; i++ ) {
if ( ref == bucket->refs[i] ) {
@ -98,7 +103,7 @@ ur_dict32_put(ur_root_t *r, ur_dict32_t *dict, ur_nref ref, uint32_t val)
while ( 1 ) {
uint64_t idx = ( mug % dict->size );
ur_pail32_t *bucket = &(dict->buckets[idx]);
uint8_t i, fill = bucket->fill;
uint8_t i, fill = dict->fills[idx];
for ( i = 0; i < fill; i++ ) {
if ( ref == bucket->refs[i] ) {
@ -114,7 +119,7 @@ ur_dict32_put(ur_root_t *r, ur_dict32_t *dict, ur_nref ref, uint32_t val)
bucket->refs[fill] = ref;
bucket->vals[fill] = val;
bucket->fill = 1 + fill;
dict->fills[idx] = 1 + fill;
break;
}
}
@ -122,27 +127,27 @@ ur_dict32_put(ur_root_t *r, ur_dict32_t *dict, ur_nref ref, uint32_t val)
void
ur_dict32_wipe(ur_dict32_t *dict)
{
ur_pail32_t *buckets = dict->buckets;
uint64_t i, size = dict->size;
uint8_t *fills = dict->fills;
uint64_t size = dict->size;
for ( i = 0; i < size; i++ ) {
buckets[i].fill = 0;
}
memset(fills, 0, sizeof(*fills) * size);
}
void
ur_dict64_grow(ur_root_t *r, ur_dict64_t *dict, uint64_t prev, uint64_t size)
{
ur_pail64_t *buckets, *old_buckets = dict->buckets;
uint8_t *fills, *old_fills = dict->fills;
uint64_t old_size = dict->size;
uint64_t i, next = prev + size;
buckets = _oom("dict64_grow", calloc(next, sizeof(*buckets)));
fills = _oom("dict64_grow", calloc(next, sizeof(*fills)));
if ( old_buckets ) {
for ( i = 0; i < old_size; i++ ) {
ur_pail64_t *old_bucket = &(old_buckets[i]);
uint8_t j, old_fill = old_bucket->fill;
uint8_t j, old_fill = old_fills[i];
for ( j = 0; j < old_fill; j++ ) {
uint64_t val = old_bucket->vals[j];
@ -151,24 +156,27 @@ ur_dict64_grow(ur_root_t *r, ur_dict64_t *dict, uint64_t prev, uint64_t size)
uint64_t idx = ( mug % next );
ur_pail64_t *bucket = &(buckets[idx]);
uint8_t new_fill = bucket->fill;
uint8_t new_fill = fills[idx];
if ( ur_pail_max == new_fill ) {
free(buckets);
free(fills);
return ur_dict64_grow(r, dict, size, next);
}
bucket->refs[new_fill] = ref;
bucket->vals[new_fill] = val;
bucket->fill = 1 + new_fill;
fills[idx] = 1 + new_fill;
}
}
free(old_buckets);
free(old_fills);
}
dict->prev = size;
dict->size = next;
dict->fills = fills;
dict->buckets = buckets;
}
@ -179,7 +187,7 @@ ur_dict64_get(ur_root_t *r, ur_dict64_t *dict, ur_nref ref, uint64_t *out)
uint64_t idx = ( mug % dict->size );
ur_pail64_t *bucket = &(dict->buckets[idx]);
uint8_t i, fill = bucket->fill;
uint8_t i, fill = dict->fills[idx];
for ( i = 0; i < fill; i++ ) {
if ( ref == bucket->refs[i] ) {
@ -199,7 +207,7 @@ ur_dict64_put(ur_root_t *r, ur_dict64_t *dict, ur_nref ref, uint64_t val)
while ( 1 ) {
uint64_t idx = ( mug % dict->size );
ur_pail64_t *bucket = &(dict->buckets[idx]);
uint8_t i, fill = bucket->fill;
uint8_t i, fill = dict->fills[idx];
for ( i = 0; i < fill; i++ ) {
if ( ref == bucket->refs[i] ) {
@ -215,7 +223,7 @@ ur_dict64_put(ur_root_t *r, ur_dict64_t *dict, ur_nref ref, uint64_t val)
bucket->refs[fill] = ref;
bucket->vals[fill] = val;
bucket->fill = 1 + fill;
dict->fills[idx] = 1 + fill;
break;
}
}
@ -223,27 +231,27 @@ ur_dict64_put(ur_root_t *r, ur_dict64_t *dict, ur_nref ref, uint64_t val)
void
ur_dict64_wipe(ur_dict64_t *dict)
{
ur_pail64_t *buckets = dict->buckets;
uint64_t i, size = dict->size;
uint8_t *fills = dict->fills;
uint64_t size = dict->size;
for ( i = 0; i < size; i++ ) {
buckets[i].fill = 0;
}
memset(fills, 0, sizeof(*fills) * size);
}
void
ur_dict_grow(ur_root_t *r, ur_dict_t *dict, uint64_t prev, uint64_t size)
{
ur_pail_t *buckets, *old_buckets = dict->buckets;
uint8_t *fills, *old_fills = dict->fills;
uint64_t old_size = dict->size;
uint64_t i, next = prev + size;
buckets = _oom("dict_grow", calloc(next, sizeof(*buckets)));
fills = _oom("dict_grow", calloc(next, sizeof(*fills)));
if ( old_buckets ) {
for ( i = 0; i < old_size; i++ ) {
ur_pail_t *old_bucket = &(old_buckets[i]);
uint8_t j, old_fill = old_bucket->fill;
uint8_t j, old_fill = old_fills[i];
for ( j = 0; j < old_fill; j++ ) {
ur_nref ref = old_bucket->refs[j];
@ -251,23 +259,26 @@ ur_dict_grow(ur_root_t *r, ur_dict_t *dict, uint64_t prev, uint64_t size)
uint64_t idx = ( mug % next );
ur_pail_t *bucket = &(buckets[idx]);
uint8_t new_fill = bucket->fill;
uint8_t new_fill = fills[idx];
if ( ur_pail_max == new_fill ) {
free(buckets);
free(fills);
return ur_dict_grow(r, dict, size, next);
}
bucket->refs[new_fill] = ref;
bucket->fill = 1 + new_fill;
fills[idx] = 1 + new_fill;
}
}
free(old_buckets);
free(old_fills);
}
dict->prev = size;
dict->size = next;
dict->fills = fills;
dict->buckets = buckets;
}
@ -278,7 +289,7 @@ ur_dict_get(ur_root_t *r, ur_dict_t *dict, ur_nref ref)
uint64_t idx = ( mug % dict->size );
ur_pail_t *bucket = &(dict->buckets[idx]);
uint8_t i, fill = bucket->fill;
uint8_t i, fill = dict->fills[idx];
for ( i = 0; i < fill; i++ ) {
if ( ref == bucket->refs[i] ) {
@ -297,7 +308,7 @@ ur_dict_put(ur_root_t *r, ur_dict_t *dict, ur_nref ref)
while ( 1 ) {
uint64_t idx = ( mug % dict->size );
ur_pail_t *bucket = &(dict->buckets[idx]);
uint8_t i, fill = bucket->fill;
uint8_t i, fill = dict->fills[idx];
for ( i = 0; i < fill; i++ ) {
if ( ref == bucket->refs[i] ) {
@ -311,7 +322,7 @@ ur_dict_put(ur_root_t *r, ur_dict_t *dict, ur_nref ref)
}
bucket->refs[fill] = ref;
bucket->fill = 1 + fill;
dict->fills[idx] = 1 + fill;
break;
}
}
@ -319,18 +330,17 @@ ur_dict_put(ur_root_t *r, ur_dict_t *dict, ur_nref ref)
void
ur_dict_wipe(ur_dict_t *dict)
{
ur_pail_t *buckets = dict->buckets;
uint64_t i, size = dict->size;
uint8_t *fills = dict -> fills;
uint64_t size = dict->size;
for ( i = 0; i < size; i++ ) {
buckets[i].fill = 0;
}
memset(fills, 0, sizeof(*fills) * size);
}
void
ur_dict_free(ur_dict_t *dict)
{
free(dict->buckets);
free(dict->fills);
dict->buckets = 0;
}
@ -613,7 +623,7 @@ ur_coin_bytes_unsafe(ur_root_t *r, uint64_t len, uint8_t *byt)
while ( 1 ) {
uint64_t idx = ( mug % dict->size );
ur_pail_t *bucket = &(dict->buckets[idx]);
uint8_t i, b_fill = bucket->fill;
uint8_t i, b_fill = dict->fills[idx];
ur_nref tom;
for ( i = 0; i < b_fill; i++ ) {
@ -642,7 +652,7 @@ ur_coin_bytes_unsafe(ur_root_t *r, uint64_t len, uint8_t *byt)
tom = _coin_unsafe(atoms, mug, len, byt);
bucket->refs[b_fill] = tom;
bucket->fill = 1 + b_fill;
dict->fills[idx] = 1 + b_fill;
return tom;
}
@ -712,7 +722,7 @@ ur_cons(ur_root_t *r, ur_nref hed, ur_nref tal)
while ( 1 ) {
uint64_t idx = ( mug % dict->size );
ur_pail_t *bucket = &(dict->buckets[idx]);
uint8_t i, b_fill = bucket->fill;
uint8_t i, b_fill = dict->fills[idx];
ur_nref cel;
for ( i = 0; i < b_fill; i++ ) {
@ -737,7 +747,7 @@ ur_cons(ur_root_t *r, ur_nref hed, ur_nref tal)
cel = _cons_unsafe(cells, mug, hed, tal);
bucket->refs[b_fill] = cel;
bucket->fill = 1 + b_fill;
dict->fills[idx] = 1 + b_fill;
return cel;
}