ur: refactors unsafe jam into a handle-based api

This commit is contained in:
Joe Bryan 2020-09-17 16:17:00 -07:00
parent 6b10dd0f7e
commit 8b5bc77565
3 changed files with 100 additions and 37 deletions

View File

@ -117,25 +117,22 @@ _jam_bench(void)
gettimeofday(&b4, 0);
{
ur_dict64_t dic_u = {0};
c3_d len_d;
c3_y* byt_y;
ur_dict64_grow((ur_root_t*)0, &dic_u, ur_fib10, ur_fib11);
ur_jam_t *jam_u = ur_jam_init(rot_u);
c3_d len_d;
c3_y* byt_y;
for ( i_w = 0; i_w < max_w; i_w++ ) {
ur_jam_unsafe(rot_u, ref, &dic_u, &len_d, &byt_y);
ur_jam_with(jam_u, ref, &len_d, &byt_y);
c3_free(byt_y);
ur_dict64_wipe(&dic_u);
}
ur_dict_free((ur_dict_t*)&dic_u);
ur_jam_done(jam_u);
}
gettimeofday(&f2, 0);
timersub(&f2, &b4, &d0);
mil_w = (d0.tv_sec * 1000) + (d0.tv_usec / 1000);
fprintf(stderr, " jam cons unsafe: %u ms\r\n", mil_w);
fprintf(stderr, " jam cons with: %u ms\r\n", mil_w);
}
ur_root_free(rot_u);

View File

@ -10,10 +10,13 @@
** supports up to 64-bits of bit-addressed output (nearly 2 EiB).
** (as this is an impractical volume data, cursor overflow is not checked.)
**
** unsafe variant is unsafe wrt its [dict] parameter, which must be empty,
** but can be passed in order to skip reallocation inside hot loops.
** jam_with* api factors out stack/dict (re)allocation,
** for better performance inside hot loops.
**
*/
typedef struct ur_jam_s ur_jam_t;
uint64_t
ur_jam_unsafe(ur_root_t *r,
ur_nref ref,
@ -22,7 +25,28 @@ ur_jam_unsafe(ur_root_t *r,
uint8_t **byt);
uint64_t
ur_jam(ur_root_t *r, ur_nref ref, uint64_t *len, uint8_t **byt);
ur_jam(ur_root_t *r,
ur_nref ref,
uint64_t *len,
uint8_t **byt);
ur_jam_t*
ur_jam_init_with(ur_root_t *r,
uint64_t d_prev,
uint64_t d_size,
uint32_t s_prev,
uint32_t s_size);
ur_jam_t*
ur_jam_init(ur_root_t *r);
uint64_t
ur_jam_with(ur_jam_t *j,
ur_nref ref,
uint64_t *len,
uint8_t **byt);
void
ur_jam_done(ur_jam_t *j);
/*
** bitwise deserialization of a byte-buffer into a noun.

View File

@ -30,16 +30,21 @@ _bsw_atom(ur_root_t *r, ur_nref ref, ur_bsw_t *bsw, uint64_t len)
}
}
typedef struct _jam_s {
ur_dict64_t *dict;
/*
** define opaque struct ur_jam_s (ie, ur_jam_t)
*/
struct ur_jam_s {
ur_root_t *r;
ur_walk_fore_t *w;
ur_dict64_t dict;
ur_bsw_t bsw;
} _jam_t;
};
static void
_jam_atom(ur_root_t *r, ur_nref ref, void *ptr)
{
_jam_t *j = ptr;
ur_dict64_t *dict = j->dict;
ur_jam_t *j = ptr;
ur_dict64_t *dict = &j->dict;
ur_bsw_t *bsw = &j->bsw;
uint64_t bak, len = ur_met(r, 0, ref);
@ -63,8 +68,8 @@ _jam_atom(ur_root_t *r, ur_nref ref, void *ptr)
static ur_bool_t
_jam_cell(ur_root_t *r, ur_nref ref, void *ptr)
{
_jam_t *j = ptr;
ur_dict64_t *dict = j->dict;
ur_jam_t *j = ptr;
ur_dict64_t *dict = &j->dict;
ur_bsw_t *bsw = &j->bsw;
uint64_t bak;
@ -80,32 +85,69 @@ _jam_cell(ur_root_t *r, ur_nref ref, void *ptr)
}
}
uint64_t
ur_jam_unsafe(ur_root_t *r,
ur_nref ref,
ur_dict64_t *dict,
uint64_t *len,
uint8_t **byt)
static uint64_t
_jam(ur_jam_t *j,
ur_nref ref,
uint64_t *len,
uint8_t **byt)
{
_jam_t j = { .dict = dict };
ur_bsw_init(&j.bsw, ur_fib11, ur_fib12);
ur_bsw_init(&j->bsw, ur_fib11, ur_fib12);
ur_walk_fore_with(j->w, ref, j, _jam_atom, _jam_cell);
return ur_bsw_done(&j->bsw, len, byt);
}
ur_walk_fore(r, ref, &j, _jam_atom, _jam_cell);
ur_jam_t*
ur_jam_init_with(ur_root_t *r,
uint64_t d_prev,
uint64_t d_size,
uint32_t s_prev,
uint32_t s_size)
{
ur_jam_t *j = _oom("jam_init", calloc(sizeof(*j), 1));
j->w = ur_walk_fore_init_with(r, s_prev, s_size);
j->r = r;
return ur_bsw_done(&j.bsw, len, byt);
ur_dict64_grow(r, &j->dict, d_prev, d_size);
return j;
}
ur_jam_t*
ur_jam_init(ur_root_t *r)
{
return ur_jam_init_with(r, ur_fib11, ur_fib12, // dict sizes
ur_fib10, ur_fib11); // stack sizes
}
uint64_t
ur_jam(ur_root_t *r, ur_nref ref, uint64_t *len, uint8_t **byt)
ur_jam_with(ur_jam_t *j,
ur_nref ref,
uint64_t *len,
uint8_t **byt)
{
ur_dict64_t dict = {0};
ur_dict64_grow(r, &dict, ur_fib11, ur_fib12);
uint64_t bits = _jam(j, ref, len, byt);
ur_dict64_wipe(&j->dict);
return bits;
}
{
uint64_t bits = ur_jam_unsafe(r, ref, &dict, len, byt);
ur_dict_free((ur_dict_t*)&dict);
return bits;
}
void
ur_jam_done(ur_jam_t *j)
{
ur_dict_free((ur_dict_t*)&j->dict);
free(j->w);
free(j);
}
uint64_t
ur_jam(ur_root_t *r,
ur_nref ref,
uint64_t *len,
uint8_t **byt)
{
ur_jam_t *j = ur_jam_init(r);
uint64_t bits = _jam(j, ref, len, byt);
ur_jam_done(j);
return bits;
}
/*