mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
khash: add kh_init_data and kh_destroy_data functions
Add core data initialization functions that handle only the internal data allocation/deallocation without managing the khash struct itself. Changes: - Add kh_init_data_##name() for initializing khash internal data - Add kh_destroy_data_##name() for cleaning up khash internal data - Refactor kh_init_##name##_size() to use kh_init_data internally - Refactor kh_destroy_##name() to use kh_destroy_data internally - Add corresponding kh_init_data() and kh_destroy_data() macros Benefits: - Eliminates code duplication between init/destroy and embed functions - Provides clear separation: data functions handle internals, regular functions handle struct lifecycle - Enables embedding khash in other structures (e.g., mruby-set's RSet) - Centralizes complex initialization logic in single implementation Architecture: - kh_init_data/kh_destroy_data: core implementation with small table optimization - kh_init_size/kh_destroy: convenience wrappers that add struct allocation - Same functionality preserved, all tests pass This prepares khash for mruby-set integration while improving code organization and maintainability. Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
+33
-20
@@ -99,7 +99,9 @@ static const uint8_t __m_either[] = {0x03, 0x0c, 0x30, 0xc0};
|
||||
khint_t kh_put_##name(mrb_state *mrb, kh_##name##_t *h, khkey_t key, int *ret); \
|
||||
void kh_resize_##name(mrb_state *mrb, kh_##name##_t *h, khint_t new_n_buckets); \
|
||||
void kh_del_##name(mrb_state *mrb, kh_##name##_t *h, khint_t x); \
|
||||
kh_##name##_t *kh_copy_##name(mrb_state *mrb, kh_##name##_t *h);
|
||||
kh_##name##_t *kh_copy_##name(mrb_state *mrb, kh_##name##_t *h); \
|
||||
void kh_init_data_##name(mrb_state *mrb, kh_##name##_t *h, khint_t size); \
|
||||
void kh_destroy_data_##name(mrb_state *mrb, kh_##name##_t *h);
|
||||
|
||||
/* define kh_xxx_funcs
|
||||
|
||||
@@ -187,24 +189,7 @@ static const uint8_t __m_either[] = {0x03, 0x0c, 0x30, 0xc0};
|
||||
} \
|
||||
kh_##name##_t *kh_init_##name##_size(mrb_state *mrb, khint_t size) { \
|
||||
kh_##name##_t *h = (kh_##name##_t*)mrb_calloc(mrb, 1, sizeof(kh_##name##_t)); \
|
||||
if (size <= KHASH_SMALL_THRESHOLD) { \
|
||||
/* Start as small table */ \
|
||||
h->n_buckets = 0; /* Small table marker */ \
|
||||
if (kh_alloc_small_##name(mrb, h)) { \
|
||||
mrb_free(mrb, h); \
|
||||
mrb_raise_nomemory(mrb); \
|
||||
} \
|
||||
} else { \
|
||||
/* Start as regular hash table */ \
|
||||
if (size < KHASH_MIN_SIZE) \
|
||||
size = KHASH_MIN_SIZE; \
|
||||
khash_power2(size); \
|
||||
h->n_buckets = size; \
|
||||
if (kh_alloc_simple_##name(mrb, h)) { \
|
||||
mrb_free(mrb, h); \
|
||||
mrb_raise_nomemory(mrb); \
|
||||
} \
|
||||
} \
|
||||
kh_init_data_##name(mrb, h, size); \
|
||||
return h; \
|
||||
} \
|
||||
kh_##name##_t *kh_init_##name(mrb_state *mrb) { \
|
||||
@@ -213,7 +198,7 @@ static const uint8_t __m_either[] = {0x03, 0x0c, 0x30, 0xc0};
|
||||
void kh_destroy_##name(mrb_state *mrb, kh_##name##_t *h) \
|
||||
{ \
|
||||
if (h) { \
|
||||
mrb_free(mrb, h->data); /* Free single data allocation */ \
|
||||
kh_destroy_data_##name(mrb, h); \
|
||||
mrb_free(mrb, h); \
|
||||
} \
|
||||
} \
|
||||
@@ -345,6 +330,32 @@ static const uint8_t __m_either[] = {0x03, 0x0c, 0x30, 0xc0};
|
||||
} \
|
||||
} \
|
||||
return h2; \
|
||||
} \
|
||||
void kh_init_data_##name(mrb_state *mrb, kh_##name##_t *h, khint_t size) { \
|
||||
if (size <= KHASH_SMALL_THRESHOLD) { \
|
||||
/* Start as small table */ \
|
||||
h->n_buckets = 0; /* Small table marker */ \
|
||||
if (kh_alloc_small_##name(mrb, h)) { \
|
||||
mrb_raise_nomemory(mrb); \
|
||||
} \
|
||||
} \
|
||||
else { \
|
||||
/* Start as regular hash table */ \
|
||||
if (size < KHASH_MIN_SIZE) \
|
||||
size = KHASH_MIN_SIZE; \
|
||||
khash_power2(size); \
|
||||
h->n_buckets = size; \
|
||||
if (kh_alloc_simple_##name(mrb, h)) { \
|
||||
mrb_raise_nomemory(mrb); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
void kh_destroy_data_##name(mrb_state *mrb, kh_##name##_t *h) \
|
||||
{ \
|
||||
if (h && h->data) { \
|
||||
mrb_free(mrb, h->data); /* Free only the data allocation */ \
|
||||
h->data = NULL; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
@@ -360,6 +371,8 @@ static const uint8_t __m_either[] = {0x03, 0x0c, 0x30, 0xc0};
|
||||
#define kh_get(name, mrb, h, k) kh_get_##name(mrb, h, k)
|
||||
#define kh_del(name, mrb, h, k) kh_del_##name(mrb, h, k)
|
||||
#define kh_copy(name, mrb, h) kh_copy_##name(mrb, h)
|
||||
#define kh_init_data(name, mrb, h, size) kh_init_data_##name(mrb, h, size)
|
||||
#define kh_destroy_data(name, mrb, h) kh_destroy_data_##name(mrb, h)
|
||||
|
||||
/* BREAKING CHANGE: Field access macros now require type name as first parameter
|
||||
* The macros keep their familiar names but now need the hash type name.
|
||||
|
||||
Reference in New Issue
Block a user