/* * * blockpairs store in disk as: * +------------------------------------------------------+ * | 'blkpairs' | * +----------+------+-----------+---------------+--------+ * | nid | off | real-size | skeleton-size | height | * +----------+------+-----------+---------------+--------+ * ... */ int _serialize_blockpairs_to_disk(int fd, struct block *b, struct hdr *hdr) { uint32_t i; int r = NESS_OK; uint32_t used_count = 0; DISKOFF address; struct buffer *wbuf; wbuf = buf_new(1 << 20); for (i = 0; i < b->pairs_used; i++) { if (!b->pairs[i].used) continue; used_count++; } __DEBUG(" block pairs count [%d], used count [%d]", b->pairs_used, used_count); buf_putnstr(wbuf, "blkpairs", 8); buf_putuint32(wbuf, used_count); for (i = 0; i < b->pairs_used; i++) { if (!b->pairs[i].used) continue; buf_putuint64(wbuf, b->pairs[i].nid); buf_putuint64(wbuf, b->pairs[i].offset); buf_putuint32(wbuf, b->pairs[i].real_size); buf_putuint32(wbuf, b->pairs[i].skeleton_size); buf_putuint32(wbuf, b->pairs[i].height); } uint32_t xsum; if (!buf_xsum(wbuf->buf, wbuf->NUL, &xsum)) { r = NESS_DO_XSUM_ERR; goto ERR; } buf_putuint32(wbuf, xsum); uint32_t real_size; uint32_t align_size; real_size = wbuf->NUL; hdr->blocksize = real_size; align_size = ALIGN(real_size); buf_putnull(wbuf, align_size - real_size); address = block_alloc_off(b, 0, real_size, 0, 0); if (ness_os_pwrite(fd, wbuf->buf, align_size, address) != 0) { r = NESS_WRITE_ERR; goto ERR; } hdr->blockoff = address; buf_free(wbuf); return NESS_OK; ERR: buf_free(wbuf); return r; }
CTEST(block_test, block_get) { struct status *status = status_new(); struct block *b = block_new(status); uint32_t height = 0; uint32_t skeleton_size = 0; uint64_t nid0 = 0; DISKOFF off0 = block_alloc_off(b, nid0, 513, skeleton_size, height); /* {1024 to 2048} */ ASSERT_EQUAL(1024, off0); uint64_t nid1 = 1; off0 = block_alloc_off(b, nid1, 513, skeleton_size, height); /* {2048 to 3072} */ ASSERT_EQUAL(2048, off0); uint64_t nid2 = 2; off0 = block_alloc_off(b, nid2, 512, skeleton_size, height); /* {3072 to 3584} */ ASSERT_EQUAL(3072, off0); uint64_t nid3 = 3; off0 = block_alloc_off(b, nid3, 511, skeleton_size, height); /* {3584 to 4096} */ ASSERT_EQUAL(3584, off0); /* realloc nid1 */ nid1 = 1; off0 = block_alloc_off(b, nid1, 513, skeleton_size, height); /* * {4096 to 5120} is used * {2048 to 3072} is unused */ ASSERT_EQUAL(4096, off0); /* realloc nid2 */ nid2 = 2; off0 = block_alloc_off(b, nid2, 512, skeleton_size, height); /* * {5120 to 5632} used * {3072 to 3584} is unused */ ASSERT_EQUAL(5120, off0); block_shrink(b); uint64_t nid4 = 4; off0 = block_alloc_off(b, nid4, 511, skeleton_size, height); ASSERT_EQUAL(2048, off0); uint64_t nid5 = 5; off0 = block_alloc_off(b, nid5, 511, skeleton_size, height); ASSERT_EQUAL(2560, off0); block_free(b); status_free(status); }