From 2f48f9fe8b43dcc0414934dc46a01795fb66d56c Mon Sep 17 00:00:00 2001 From: AmuroEita <1071307515@qq.com> Date: Tue, 20 Oct 2026 01:16:04 +0800 Subject: [PATCH] =?UTF-8?q?feat(shm):=20=E5=8D=87=E7=BA=A7=20slotsboxmallo?= =?UTF-8?q?c=20v0.1.7=20(v3)=20=E5=B9=B6=E9=80=82=E9=85=8D=E5=9C=A8?= =?UTF-8?q?=E7=BA=BF=E6=89=A9=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deps.json | 2 +- src/kvspace.c | 56 +++++++++++++++++++++++------------------ tests/test_shm_resize.c | 9 ++++--- 3 files changed, 38 insertions(+), 29 deletions(-) diff --git a/deps.json b/deps.json index d6e14ea..05cb228 100644 --- a/deps.json +++ b/deps.json @@ -1,4 +1,4 @@ { "blockmalloc": "v0.1.4", - "slotsboxmalloc": "v0.1.6" + "slotsboxmalloc": "v0.1.7" } diff --git a/src/kvspace.c b/src/kvspace.c index 98615c8..65b4823 100644 --- a/src/kvspace.c +++ b/src/kvspace.c @@ -7,6 +7,7 @@ * blockmalloc 必须先于 slotsboxmalloc(后者在其实现体里调用前者)。 */ #define BLOCKMALLOC_IMPLEMENTATION #include +#define SBO_MIN_SHARD_BYTES (1ULL << 40) #define SLOTSBOXMALLOC_IMPLEMENTATION #include "slotsboxmalloc/slotsboxobj.h" #include "kvspace_shm.h" @@ -109,17 +110,17 @@ _Static_assert( #define SBO_HEAD_FIXED \ (sizeof(sbo_meta_t) + sizeof(blocks_meta_t) + sizeof(sbo_lock_t)) static blocks_meta_t *sbo_pool(sbo_meta_t *m) { - return (blocks_meta_t *)(m + 1); + return sbo_pool_meta(m, 0); } static sbo_lock_t *sbo_plock(sbo_meta_t *m) { - return (sbo_lock_t *)(sbo_pool(m) + 1); + return sbo_pool_lock(m, 0); } static uint8_t *sbo_pmem(sbo_meta_t *m) { - return (uint8_t *)(sbo_plock(m) + 1); + return sbo_pool_mem(m, 0); } static sbo_box_t *sbo_box(sbo_meta_t *m, int32_t id) { return (sbo_box_t *)(sbo_pmem(m) + (size_t)id * m->block_stride + - m->sizeof_block_head); + m->box_off); } typedef struct { @@ -229,15 +230,15 @@ static int sbo_head_grow(kvspace_t *kv) { if (want > cap) want = cap; if (SBO_HEAD_FIXED + want > kv->r_head.reserve) - want = kv->r_head.reserve - SBO_HEAD_FIXED; + want = (kv->r_head.reserve - SBO_HEAD_FIXED) & ~(uint64_t)7; if (want <= cur || ftruncate(kv->r_head.fd, (off_t)(SBO_HEAD_FIXED + want)) != 0 || region_map(&kv->r_head, SBO_HEAD_FIXED + (size_t)want) != 0) return -1; p->total_size = want; m->per_slot_meta = want; - m->head_size = SBO_HEAD_FIXED + want; - kv->hdr->sbo_head_size = m->head_size; + m->max_blocks = (uint32_t)(want / m->block_stride); + kv->hdr->sbo_head_size = SBO_HEAD_FIXED + want; return 0; } @@ -259,25 +260,32 @@ static int sbo_data_grow(kvspace_t *kv) { sbo_box_t *root = sbo_box(m, 0), *b = sbo_box(m, (int32_t)nid); memcpy(b, root, sizeof *b); b->parent = 0; - for (int i = 0; i < SBO_N; i++) - if (root->slots[i].state == SBO_BOX) - sbo_box(m, root->children[i])->parent = (int32_t)nid; - uint8_t lvl = (uint8_t)(root->objlevel + 1); - root->objlevel = lvl; - root->box_boundary = 1; - root->obj_boundary = SBO_N - 1; - memset(root->free_bitmap, 0xFF, SBO_BITMAP_B); - root->free_bitmap[0] &= 0xFE; - for (int i = 0; i < SBO_N; i++) { - root->slots[i].state = SBO_FREE; - root->children[i] = -1; - } - root->slots[0].state = SBO_BOX; + b->parent_slot = 0; + b->self_id = (int32_t)nid; + uint64_t mm = root->child_mask; + while (mm) { + int i = __builtin_ctzll(mm); + mm &= mm - 1; + sbo_box(m, root->children[i])->parent = (int32_t)nid; + } + sbo_lock_t *lk = sbo_plock(m); + uint8_t old_lvl = b->objlevel; + if (old_lvl >= 1 && old_lvl <= 3 && lk->hot_id1[old_lvl - 1] == 1) + lk->hot_id1[old_lvl - 1] = (uint32_t)nid + 1; + uint8_t lvl = (uint8_t)(old_lvl + 1); + sbo_box_format(root, lvl, -1, 255, 0); + root->free_mask = ~1ULL; + root->child_mask = 1ULL; + root->states[0] = SBO_BOX; root->children[0] = (int32_t)nid; - root->max_obj_cap = SBO_N - 1; - root->child_max_cap = (sbo_usage_t){(uint8_t)(lvl + 1), 1}; + uint16_t b_comb = sbo_combined(b); + root->child_cap[0] = b_comb; + root->child_max_enc = b_comb; + root->child_max_count = 1; + root->max_obj_cap = SBO_MULT_MAX; + root->hint_child = 0; m->data_size = want; - m->slot_bytes = want; + m->slot_shift = (uint8_t)__builtin_ctzll(want); kv->hdr->sbo_data_size = want; return 0; } diff --git a/tests/test_shm_resize.c b/tests/test_shm_resize.c index fc38d1c..50fa430 100644 --- a/tests/test_shm_resize.c +++ b/tests/test_shm_resize.c @@ -309,16 +309,17 @@ static void t_bad_root_slots(const char *dir) { kvspace_t *kv = kvspaceShmOpen(db, DATA_2MB); REQUIRE(kv != NULL, "open failed"); kvspaceShmClose(kv); - /* sbo_meta_t: magic[16] head_size data_size slot_bytes per_slot_meta -> 48 */ + /* sbo_meta_t (v3): magic[16] data_size(8) per_slot_meta(8) next_shard(4) + block_stride(2) -> root_slots at byte 38 */ int fd = open(head, O_RDWR); REQUIRE(fd >= 0, "open head"); uint8_t one = 0; - REQUIRE(pread(fd, &one, 1, 48) == 1 && one == 1, "root_slots byte is %u", + REQUIRE(pread(fd, &one, 1, 38) == 1 && one == 1, "root_slots byte is %u", one); uint8_t two = 2; - CHECK(pwrite(fd, &two, 1, 48) == 1, "pwrite"); + CHECK(pwrite(fd, &two, 1, 38) == 1, "pwrite"); CHECK(kvspaceShmOpen(db, DATA_2MB) == NULL, "root_slots=2 accepted"); - CHECK(pwrite(fd, &one, 1, 48) == 1, "restore"); + CHECK(pwrite(fd, &one, 1, 38) == 1, "restore"); close(fd); kv = kvspaceShmOpen(db, DATA_2MB); CHECK(kv != NULL, "reopen after restore");