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; }
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; }
static void ssleb128_test(stc *cx) { char buffer[16]; int len; uint64_t value; len = ss_leb128write(buffer, INT8_MAX); t( len == 1 ); value = 0; len = ss_leb128read(buffer, &value); t( len == 1 ); t( value == INT8_MAX ); len = ss_leb128write(buffer, UINT8_MAX); t( len == 2 ); value = 0; len = ss_leb128read(buffer, &value); t( len == 2 ); t( value == UINT8_MAX ); len = ss_leb128write(buffer, INT16_MAX); t( len == 3 ); value = 0; len = ss_leb128read(buffer, &value); t( len == 3 ); t( value == INT16_MAX ); len = ss_leb128write(buffer, UINT16_MAX); t( len == 3 ); value = 0; len = ss_leb128read(buffer, &value); t( len == 3 ); t( value == UINT16_MAX ); len = ss_leb128write(buffer, INT32_MAX); t( len == 5 ); value = 0; len = ss_leb128read(buffer, &value); t( len == 5 ); t( value == INT32_MAX ); len = ss_leb128write(buffer, UINT32_MAX); t( len == 5 ); value = 0; len = ss_leb128read(buffer, &value); t( len == 5 ); t( value == UINT32_MAX ); len = ss_leb128write(buffer, INT64_MAX); t( len == 9 ); value = 0; len = ss_leb128read(buffer, &value); t( len == 9 ); t( value == INT64_MAX ); len = ss_leb128write(buffer, UINT64_MAX); t( len == 10 ); value = 0; len = ss_leb128read(buffer, &value); t( len == 10 ); t( value == UINT64_MAX ); }