static void sd_v_test(void) { sdbuild b; sd_buildinit(&b); t( sd_buildbegin(&b, &st_r.r, 1, 0, 0) == 0); int i = 7; int j = 8; addv(&b, &st_r.r, 3, 0, &i); addv(&b, &st_r.r, 4, 0, &j); sd_buildend(&b, &st_r.r); ssbuf buf; ss_bufinit(&buf); ssbuf xfbuf; ss_bufinit(&xfbuf); t( ss_bufensure(&xfbuf, &st_r.a, 1024) == 0 ); t( sd_commitpage(&b, &st_r.r, &buf) == 0 ); sdpageheader *h = (sdpageheader*)buf.s; sdpage page; sd_pageinit(&page, h); ssiter it; ss_iterinit(sd_pageiter, &it); ss_iteropen(sd_pageiter, &it, &st_r.r, &xfbuf, &page, SS_GTE, NULL, 0); t( ss_iteratorhas(&it) != 0 ); sv *v = ss_iteratorof(&it); t( v != NULL ); t( *(int*)sv_key(v, &st_r.r, 0) == i ); t( sv_lsn(v) == 3 ); t( sv_flags(v) == 0 ); ss_iteratornext(&it); t( ss_iteratorhas(&it) != 0 ); v = ss_iteratorof(&it); t( v != NULL ); t( *(int*)sv_key(v, &st_r.r, 0) == j ); t( sv_lsn(v) == 4 ); t( sv_flags(v) == 0 ); ss_iteratornext(&it); v = ss_iteratorof(&it); t( v == NULL ); sd_buildfree(&b, &st_r.r); ss_buffree(&buf, &st_r.a); ss_buffree(&xfbuf, &st_r.a); }
static void sv_indexiter_iterate1(void) { svindex i; t( sv_indexinit(&i) == 0 ); int j = 0; while (j < 16) { svv *v = st_svv(&st_r.g, NULL, j, 0, j); t( sv_indexset(&i, &st_r.r, v) == 0 ); j++; } ssiter it; ss_iterinit(sv_indexiter, &it); ss_iteropen(sv_indexiter, &it, &st_r.r, &i, SS_GTE, NULL, 0); j = 0; while (ss_iteratorhas(&it)) { sv *v = ss_iteratorof(&it); t( sv_lsn(v) == j ); ss_iteratornext(&it); j++; } t( j == 16 ); sv_indexfree(&i, &st_r.r); }
int sd_buildadd(sdbuild *b, sr *r, sv *v, uint32_t flags) { /* prepare metadata reference */ int rc = sr_bufensure(&b->k, r->a, sizeof(sdv)); if (srunlikely(rc == -1)) return sr_error(r->e, "%s", "memory allocation failed"); sdpageheader *h = sd_buildheader(b); sdv *sv = (sdv*)b->k.p; sv->lsn = sv_lsn(v); sv->flags = sv_flags(v) | flags; sv->size = sv_size(v); sv->offset = sr_bufused(&b->v) - sd_buildref(b)->v; /* copy object */ rc = sr_bufensure(&b->v, r->a, sv->size); if (srunlikely(rc == -1)) return sr_error(r->e, "%s", "memory allocation failed"); memcpy(b->v.p, sv_pointer(v), sv->size); sr_bufadvance(&b->v, sv->size); sr_bufadvance(&b->k, sizeof(sdv)); /* update page header */ h->count++; h->size += sv->size + sizeof(sdv); if (sv->lsn > h->lsnmax) h->lsnmax = sv->lsn; if (sv->lsn < h->lsnmin) h->lsnmin = sv->lsn; if (sv->flags & SVDUP) { h->countdup++; if (sv->lsn < h->lsnmindup) h->lsnmindup = sv->lsn; } return 0; }
static inline int si_getresult(siread *q, sv *v, int compare) { int rc; if (compare) { rc = sr_compare(q->r->scheme, sv_pointer(v), sv_size(v), q->key, q->keysize); if (ssunlikely(rc != 0)) return 0; } if (q->prefix) { rc = sr_compareprefix(q->r->scheme, q->prefix, q->prefixsize, sv_pointer(v), sv_size(v)); if (ssunlikely(! rc)) return 0; } if (ssunlikely(q->has)) return sv_lsn(v) > q->vlsn; if (ssunlikely(sv_is(v, SVDELETE))) return 2; rc = si_readdup(q, v); if (ssunlikely(rc == -1)) return -1; return 1; }
static void sv_mergeiter_merge_ba(void) { stlist vlista; stlist vlistb; st_listinit(&vlista, 0); st_listinit(&vlistb, 0); int i = 0; while (i < 5) { st_sv(&st_r.g, &vlista, i, 0, i); i++; } while (i < 10) { st_sv(&st_r.g, &vlistb, i, 0, i); i++; } ssiter ita; ss_iterinit(ss_bufiterref, &ita); ss_iteropen(ss_bufiterref, &ita, &vlista.list, sizeof(sv*)); ssiter itb; ss_iterinit(ss_bufiterref, &itb); ss_iteropen(ss_bufiterref, &itb, &vlistb.list, sizeof(sv*)); svmerge m; sv_mergeinit(&m); sv_mergeprepare(&m, &st_r.r, 3); svmergesrc *s = sv_mergeadd(&m, NULL); t(s != NULL); s->src = ita; s = sv_mergeadd(&m, NULL); t(s != NULL); s->src = itb; ssiter merge; ss_iterinit(sv_mergeiter, &merge); ss_iteropen(sv_mergeiter, &merge, &st_r.r, &m, SS_GTE); i = 0; while (ss_iteratorhas(&merge)) { sv *v = (sv*)ss_iteratorof(&merge); t( *(int*)sv_key(v, &st_r.r, 0) == i ); t( sv_lsn(v) == i ); t( sv_flags(v) == 0 ); ss_iteratornext(&merge); i++; } t( i == 10 ); ss_iteratorclose(&merge); sv_mergefree(&m, &st_r.a); st_listfree(&vlista, &st_r.r); st_listfree(&vlistb, &st_r.r); }
static void svv_kv(stc *cx) { sra a; sr_aopen(&a, &sr_stda); srkey cmp; sr_keyinit(&cmp); srkeypart *part = sr_keyadd(&cmp, &a); t( sr_keypart_setname(part, &a, "key") == 0 ); t( sr_keypart_set(part, &a, "u32") == 0 ); sr r; sr_init(&r, NULL, &a, NULL, SR_FKV, &cmp, NULL, NULL, NULL); uint32_t key = 123; uint32_t value = 321; srformatv pv; pv.key = (char*)&key; pv.r.size = sizeof(key); pv.r.offset = 0; svv *vv = sv_vbuild(&r, &pv, 1, (char*)&value, sizeof(value)); t( vv != NULL ); vv->flags = SVSET; vv->lsn = 10; sv v; sv_init(&v, &sv_vif, vv, NULL); t( sv_flags(&v) == SVSET ); t( sv_lsn(&v) == 10 ); sv_lsnset(&v, 8); t( sv_lsn(&v) == 8 ); t( *(uint32_t*)sr_formatkey(sv_pointer(&v), 0) == key ); t( sr_formatkey_size(sv_pointer(&v), 0) == sizeof(key) ); t( *(uint32_t*)sr_formatvalue(SR_FKV, &cmp, sv_pointer(&v)) == value ); t( sr_formatvalue_size(SR_FKV, &cmp, sv_pointer(&v), sv_size(&v) ) == sizeof(value) ); sv_vfree(&a, vv); sr_keyfree(&cmp, &a); }
static int si_readcommited_branch(sr *r, sibranch *b, sv *v) { ssiter i; ss_iterinit(sd_indexiter, &i); ss_iteropen(sd_indexiter, &i, r, &b->index, SS_GTE, sv_pointer(v), sv_size(v)); sdindexpage *page = ss_iterof(sd_indexiter, &i); if (page == NULL) return 0; return page->lsnmax >= sv_lsn(v); }
static inline int sd_buildadd_raw(sdbuild *b, sr *r, sv *v) { uint64_t lsn = sv_lsn(v); uint32_t size = sv_size(v); uint32_t sizemeta = ss_leb128size(size) + ss_leb128size(lsn); int rc = ss_bufensure(&b->v, r->a, sizemeta + size); if (ssunlikely(rc == -1)) return sr_oom(r->e); ss_bufadvance(&b->v, ss_leb128write(b->v.p, size)); ss_bufadvance(&b->v, ss_leb128write(b->v.p, lsn)); memcpy(b->v.p, sv_pointer(v), size); ss_bufadvance(&b->v, size); return 0; }
int sd_buildadd(sdbuild *b, sr *r, sv *v, uint32_t flags) { /* prepare object metadata */ int rc = ss_bufensure(&b->m, r->a, sizeof(sdv)); if (ssunlikely(rc == -1)) return sr_oom(r->e); sdpageheader *h = sd_buildheader(b); sdv *sv = (sdv*)b->m.p; sv->flags = sv_flags(v) | flags; sv->offset = ss_bufused(&b->v) - sd_buildref(b)->v; ss_bufadvance(&b->m, sizeof(sdv)); /* copy object */ switch (r->fmt_storage) { case SF_SKEYVALUE: rc = sd_buildadd_keyvalue(b, r, v); break; case SF_SRAW: rc = sd_buildadd_raw(b, r, v); break; } if (ssunlikely(rc == -1)) return -1; /* update page header */ h->count++; uint32_t size = sizeof(sdv) + sv_size(v) + sizeof(sfref) * r->scheme->count; if (size > b->vmax) b->vmax = size; uint64_t lsn = sv_lsn(v); if (lsn > h->lsnmax) h->lsnmax = lsn; if (lsn < h->lsnmin) h->lsnmin = lsn; if (sv->flags & SVDUP) { h->countdup++; if (lsn < h->lsnmindup) h->lsnmindup = lsn; } return 0; }
static inline int sd_buildadd_keyvalue(sdbuild *b, sr *r, sv *v) { /* calculate key size */ uint32_t keysize = 0; int i = 0; while (i < r->scheme->count) { keysize += sv_keysize(v, r, i); i++; } uint32_t valuesize = sv_valuesize(v, r); uint32_t size = keysize + valuesize; /* prepare buffer */ uint64_t lsn = sv_lsn(v); uint32_t sizemeta = ss_leb128size(size) + ss_leb128size(lsn); int rc = ss_bufensure(&b->v, r->a, sizemeta); if (ssunlikely(rc == -1)) return sr_oom(r->e); /* write meta */ ss_bufadvance(&b->v, ss_leb128write(b->v.p, size)); ss_bufadvance(&b->v, ss_leb128write(b->v.p, lsn)); /* write key-parts */ i = 0; for (; i < r->scheme->count; i++) { uint32_t partsize = sv_keysize(v, r, i); char *part = sv_key(v, r, i); int offsetstart = ss_bufused(&b->k); int offset = (offsetstart - sd_buildref(b)->k); /* match a key copy */ int is_duplicate = 0; uint32_t hash = 0; int pos = 0; if (b->compress_dup) { hash = ss_fnv(part, partsize); pos = sd_buildsearch(&b->tracker, hash, part, partsize, b); if (b->tracker.i[pos]) { is_duplicate = 1; sdbuildkey *ref = sscast(b->tracker.i[pos], sdbuildkey, node); offset = ref->offset; } } /* offset */ rc = ss_bufensure(&b->v, r->a, ss_leb128size(offset)); if (ssunlikely(rc == -1)) return sr_oom(r->e); ss_bufadvance(&b->v, ss_leb128write(b->v.p, offset)); if (is_duplicate) continue; /* copy key */ int partsize_meta = ss_leb128size(partsize); rc = ss_bufensure(&b->k, r->a, partsize_meta + partsize); if (ssunlikely(rc == -1)) return sr_oom(r->e); ss_bufadvance(&b->k, ss_leb128write(b->k.p, partsize)); memcpy(b->k.p, part, partsize); ss_bufadvance(&b->k, partsize); /* add key reference */ if (b->compress_dup) { if (ssunlikely(ss_htisfull(&b->tracker))) { rc = ss_htresize(&b->tracker, r->a); if (ssunlikely(rc == -1)) return sr_oom(r->e); } sdbuildkey *ref = ss_malloc(r->a, sizeof(sdbuildkey)); if (ssunlikely(rc == -1)) return sr_oom(r->e); ref->node.hash = hash; ref->offset = offset; ref->offsetstart = offsetstart + partsize_meta; ref->size = partsize; ss_htset(&b->tracker, pos, &ref->node); } } /* write value */ rc = ss_bufensure(&b->v, r->a, valuesize); if (ssunlikely(rc == -1)) return sr_oom(r->e); memcpy(b->v.p, sv_value(v, r), valuesize); ss_bufadvance(&b->v, valuesize); return 0; }