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; }
int sd_buildbegin(sdbuild *b, sr *r, int crc, int compress) { b->crc = crc; b->compress = compress; int rc = sr_bufensure(&b->list, r->a, sizeof(sdbuildref)); if (srunlikely(rc == -1)) return sr_error(r->e, "%s", "memory allocation failed"); sdbuildref *ref = (sdbuildref*)sr_bufat(&b->list, sizeof(sdbuildref), b->n); ref->k = sr_bufused(&b->k); ref->ksize = 0; ref->v = sr_bufused(&b->v); ref->vsize = 0; ref->c = sr_bufused(&b->c); ref->csize = 0; rc = sr_bufensure(&b->k, r->a, sizeof(sdpageheader)); if (srunlikely(rc == -1)) return sr_error(r->e, "%s", "memory allocation failed"); sdpageheader *h = sd_buildheader(b); memset(h, 0, sizeof(*h)); h->lsnmin = UINT64_MAX; h->lsnmindup = UINT64_MAX; h->tsmin = 0; memset(h->reserve, 0, sizeof(h->reserve)); sr_bufadvance(&b->list, sizeof(sdbuildref)); sr_bufadvance(&b->k, sizeof(sdpageheader)); return 0; }
int sd_buildend(sdbuild *b, sr *r) { /* update sizes */ sdbuildref *ref = sd_buildref(b); ref->ksize = sr_bufused(&b->k) - ref->k; ref->vsize = sr_bufused(&b->v) - ref->v; ref->csize = 0; /* calculate data crc (non-compressed) */ sdpageheader *h = sd_buildheader(b); uint32_t crc = 0; if (srlikely(b->crc)) { crc = sr_crcp(r->crc, b->k.s + ref->k, ref->ksize, 0); crc = sr_crcp(r->crc, b->v.s + ref->v, ref->vsize, crc); } h->crcdata = crc; /* compression */ if (b->compress) { int rc = sd_buildcompress(b, r); if (srunlikely(rc == -1)) return -1; ref->csize = sr_bufused(&b->c) - ref->c; } /* update page header */ h->sizeorigin = h->size; if (b->compress) h->size = ref->csize - sizeof(sdpageheader); h->crc = sr_crcs(r->crc, h, sizeof(sdpageheader), 0); if (b->compress) memcpy(b->c.s + ref->c, h, sizeof(sdpageheader)); return 0; }
int sd_indexadd(sdindex *i, sr *r, sdbuild *build, uint64_t offset) { int rc = ss_bufensure(&i->i, r->a, sizeof(sdindexpage)); if (ssunlikely(rc == -1)) return sr_oom(r->e); sdpageheader *ph = sd_buildheader(build); int size = ph->size + sizeof(sdpageheader); int sizeorigin = ph->sizeorigin + sizeof(sdpageheader); /* prepare page header */ sdindexpage *p = (sdindexpage*)i->i.p; p->offset = offset; p->offsetindex = ss_bufused(&i->v); p->lsnmin = ph->lsnmin; p->lsnmax = ph->lsnmax; p->size = size; p->sizeorigin = sizeorigin; p->sizemin = 0; p->sizemax = 0; /* copy keys */ if (ssunlikely(ph->count > 0)) { char *min = sd_buildmin(build, r); char *max = sd_buildmax(build, r); rc = sd_indexadd_raw(i, r, p, min, max); if (ssunlikely(rc == -1)) return -1; } /* update index info */ sdindexheader *h = &i->build; h->count++; h->size += sizeof(sdindexpage) + p->sizemin + p->sizemax; h->keys += ph->count; h->total += size; h->totalorigin += sizeorigin; if (build->vmax > h->sizevmax) h->sizevmax = build->vmax; if (ph->lsnmin < h->lsnmin) h->lsnmin = ph->lsnmin; if (ph->lsnmax > h->lsnmax) h->lsnmax = ph->lsnmax; if (ph->tsmin < h->tsmin) h->tsmin = ph->tsmin; h->dupkeys += ph->countdup; if (ph->lsnmindup < h->dupmin) h->dupmin = ph->lsnmindup; ss_bufadvance(&i->i, sizeof(sdindexpage)); 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; }
int sd_buildbegin(sdbuild *b, sr *r, int crc, int compress, int compress_dup) { b->crc = crc; b->compress = compress; b->compress_dup = compress_dup; int rc; if (compress_dup && b->tracker.size == 0) { rc = ss_htinit(&b->tracker, r->a, 32768); if (ssunlikely(rc == -1)) return sr_oom(r->e); } rc = ss_bufensure(&b->list, r->a, sizeof(sdbuildref)); if (ssunlikely(rc == -1)) return sr_oom(r->e); sdbuildref *ref = (sdbuildref*)ss_bufat(&b->list, sizeof(sdbuildref), b->n); ref->m = ss_bufused(&b->m); ref->msize = 0; ref->v = ss_bufused(&b->v); ref->vsize = 0; ref->k = ss_bufused(&b->k); ref->ksize = 0; ref->c = ss_bufused(&b->c); ref->csize = 0; rc = ss_bufensure(&b->m, r->a, sizeof(sdpageheader)); if (ssunlikely(rc == -1)) return sr_oom(r->e); sdpageheader *h = sd_buildheader(b); memset(h, 0, sizeof(*h)); h->lsnmin = UINT64_MAX; h->lsnmindup = UINT64_MAX; memset(h->reserve, 0, sizeof(h->reserve)); ss_bufadvance(&b->list, sizeof(sdbuildref)); ss_bufadvance(&b->m, sizeof(sdpageheader)); return 0; }
int sd_indexadd(sdindex *i, sr *r, sdbuild *build, uint64_t offset) { int rc = ss_bufensure(&i->i, r->a, sizeof(sdindexpage)); if (ssunlikely(rc == -1)) return sr_oom(r->e); sdpageheader *ph = sd_buildheader(build); int size = ph->size + sizeof(sdpageheader); int sizeorigin = ph->sizeorigin + sizeof(sdpageheader); /* prepare page header */ sdindexpage *p = (sdindexpage*)i->i.p; p->offset = offset; p->offsetindex = ss_bufused(&i->v); p->lsnmin = ph->lsnmin; p->lsnmax = ph->lsnmax; p->size = size; p->sizeorigin = sizeorigin; p->sizemin = 0; p->sizemax = 0; /* copy keys */ if (ssunlikely(ph->count > 0)) { char *min; char *max; min = sd_buildminkey(build); min += ss_leb128skip(min); min += ss_leb128skip(min); max = sd_buildmaxkey(build); max += ss_leb128skip(max); max += ss_leb128skip(max); switch (r->fmt_storage) { case SF_SRAW: rc = sd_indexadd_raw(i, r, p, min, max); break; case SF_SKEYVALUE: rc = sd_indexadd_keyvalue(i, r, build, p, min, max); break; } if (ssunlikely(rc == -1)) return -1; } /* update index info */ sdindexheader *h = sd_indexheader(i); h->count++; h->size += sizeof(sdindexpage) + p->sizemin + p->sizemax; h->keys += ph->count; h->total += size; h->totalorigin += sizeorigin; if (build->vmax > h->sizevmax) h->sizevmax = build->vmax; if (ph->lsnmin < h->lsnmin) h->lsnmin = ph->lsnmin; if (ph->lsnmax > h->lsnmax) h->lsnmax = ph->lsnmax; h->dupkeys += ph->countdup; if (ph->lsnmindup < h->dupmin) h->dupmin = ph->lsnmindup; ss_bufadvance(&i->i, sizeof(sdindexpage)); return 0; }
int sd_indexadd(sdindex *i, sr *r, sdbuild *build) { int rc = sr_bufensure(&i->i, r->a, sizeof(sdindexpage)); if (srunlikely(rc == -1)) { sr_error(r->e, "%s", "memory allocation failed"); return -1; } sdpageheader *ph = sd_buildheader(build); int size = ph->size + sizeof(sdpageheader); int sizeorigin = ph->sizeorigin + sizeof(sdpageheader); /* prepare page header. * * offset is relative to index: * m->offset + (index_size) + page->offset */ sdindexpage *p = (sdindexpage*)i->i.p; p->offset = sd_buildoffset(build); p->offsetindex = sr_bufused(&i->v); p->size = size; p->sizeorigin = sizeorigin; if (srlikely(ph->count > 0)) { p->sizemin = sr_formatkey_total(r->cmp, sd_buildminkey(build)); p->sizemax = sr_formatkey_total(r->cmp, sd_buildmaxkey(build)); } else { p->sizemin = 0; p->sizemax = 0; } p->lsnmin = ph->lsnmin; p->lsnmax = ph->lsnmax; /* update index info */ sdindexheader *h = sd_indexheader(i); h->count++; h->size += sizeof(sdindexpage) + p->sizemin + p->sizemax; h->keys += ph->count; h->total += size; h->totalorigin += sizeorigin; if (ph->lsnmin < h->lsnmin) h->lsnmin = ph->lsnmin; if (ph->lsnmax > h->lsnmax) h->lsnmax = ph->lsnmax; h->dupkeys += ph->countdup; if (ph->lsnmindup < h->dupmin) h->dupmin = ph->lsnmindup; sr_bufadvance(&i->i, sizeof(sdindexpage)); if (srunlikely(ph->count == 0)) return 0; /* copy keys */ rc = sr_bufensure(&i->v, r->a, p->sizemin + p->sizemax); if (srunlikely(rc == -1)) { sr_error(r->e, "%s", "memory allocation failed"); return -1; } /* reformat key object to exclude value */ rc = sr_formatkey_copy(r->cmp, i->v.p, sd_buildminkey(build)); assert(rc == p->sizemin); (void)rc; sr_bufadvance(&i->v, p->sizemin); rc = sr_formatkey_copy(r->cmp, i->v.p, sd_buildmaxkey(build)); assert(rc == p->sizemax); (void)rc; sr_bufadvance(&i->v, p->sizemax); return 0; }
sd_indexinit(&index); t( sd_indexbegin(&index, &r, 0, 0) == 0 ); sdbuild b; sd_buildinit(&b); t( sd_buildbegin(&b, &r, 1, 0) == 0); int key = 7; addv(&b, &r, 3, SVSET, &key); key = 8; addv(&b, &r, 4, SVSET, &key); key = 9; addv(&b, &r, 5, SVSET, &key); sd_buildend(&b, &r); sdpageheader *h = sd_buildheader(&b); int rc; rc = sd_indexadd(&index, &r, sd_buildoffset(&b), h->size + sizeof(sdpageheader), h->sizeorigin + sizeof(sdpageheader), h->count, sd_buildminkey(&b), sd_buildmin(&b)->keysize, sd_buildmaxkey(&b), sd_buildmax(&b)->keysize, h->countdup, h->lsnmindup, h->lsnmin, h->lsnmax); t( rc == 0 );