null+****@clear*****
null+****@clear*****
2012年 4月 2日 (月) 12:56:29 JST
Susumu Yata 2012-04-02 12:56:29 +0900 (Mon, 02 Apr 2012)
New Revision: d49d58a748d227dd2eb626337783cf93db218218
Log:
Add new entry types to make grn_hash easier to understand.
Modified files:
lib/hash.c
Modified: lib/hash.c (+98 -13)
===================================================================
--- lib/hash.c 2012-04-02 15:08:46 +0900 (ba9aaef)
+++ lib/hash.c 2012-04-02 12:56:29 +0900 (25efd2f)
@@ -807,6 +807,45 @@ grn_array_add(grn_ctx *ctx, grn_array *array, void **value)
#define IDX_MASK_IN_A_SEGMENT 0xfffff
typedef struct {
+ uint8_t key[4];
+ uint8_t value[1];
+} grn_hash_plain_entry;
+
+typedef struct {
+ uint32_t hash_value;
+ uint8_t key_and_value[1];
+} grn_hash_rich_entry;
+
+typedef struct {
+ uint32_t hash_value;
+ uint16_t flag;
+ uint16_t key_size;
+ union {
+ uint8_t buf[sizeof(uint32_t)];
+ uint32_t offset;
+ } key;
+ uint8_t value[1];
+} grn_io_hash_entry;
+
+typedef struct {
+ uint32_t hash_value;
+ uint16_t flag;
+ uint16_t key_size;
+ union {
+ uint8_t buf[sizeof(void *)];
+ void *ptr;
+ } key;
+ uint8_t value[1];
+} grn_tiny_hash_entry;
+
+typedef union {
+ grn_hash_plain_entry plain_entry;
+ grn_hash_rich_entry rich_entry;
+ grn_io_hash_entry io_entry;
+ grn_tiny_hash_entry tiny_entry;
+} grn_hash_entry;
+
+typedef struct {
uint32_t key;
uint8_t dummy[1];
} entry;
@@ -903,45 +942,91 @@ grn_io_hash_key_at(grn_ctx *ctx, grn_hash *hash, uint32_t pos)
#define MAX_INDEX_SIZE ((GRN_HASH_MAX_SEGMENT * (IDX_MASK_IN_A_SEGMENT + 1)) >> 1)
inline static char *
-get_key(grn_ctx *ctx, grn_hash *hash, entry_str *n)
+grn_hash_entry_get_key(grn_ctx *ctx, grn_hash *hash, grn_hash_entry *entry)
{
if (hash->obj.header.flags & GRN_OBJ_KEY_VAR_SIZE) {
- if (n->flag & HASH_IMMEDIATE) {
- return (char *)&n->str;
+ if (IO_HASHP(hash)) {
+ if (entry->io_entry.flag & HASH_IMMEDIATE) {
+ return entry->io_entry.key.buf;
+ } else {
+ return (char *)grn_io_hash_key_at(ctx, hash, entry->io_entry.key.offset);
+ }
} else {
- if (IO_HASHP(hash)) {
- return (char *)grn_io_hash_key_at(ctx, hash, n->str);
+ if (entry->tiny_entry.flag & HASH_IMMEDIATE) {
+ return entry->tiny_entry.key.buf;
} else {
- return ((entry_astr *)n)->str;
+ return entry->tiny_entry.key.ptr;
}
}
} else {
if (hash->key_size == sizeof(uint32_t)) {
- return (char *)(&((entry *)n)->key);
+ return entry->plain_entry.key;
} else {
- return (char *)(((entry *)n)->dummy);
+ return entry->rich_entry.key_and_value;
}
}
}
inline static void *
-get_value(grn_hash *hash, entry_str *n)
+grn_hash_entry_get_value(grn_hash *hash, grn_hash_entry *entry)
{
if (hash->obj.header.flags & GRN_OBJ_KEY_VAR_SIZE) {
if (IO_HASHP(hash)) {
- return ((entry_str *)n)->dummy;
+ return entry->io_entry.value;
} else {
- return ((entry_astr *)n)->dummy;
+ return entry->tiny_entry.value;
}
} else {
if (hash->key_size == sizeof(uint32_t)) {
- return ((entry *)n)->dummy;
+ return entry->plain_entry.value;
} else {
- return &((entry *)n)->dummy[hash->key_size];
+ return entry->rich_entry.key_and_value + hash->key_size;
}
}
}
+inline static char *
+get_key(grn_ctx *ctx, grn_hash *hash, entry_str *n)
+{
+ return grn_hash_entry_get_key(ctx, hash, (grn_hash_entry *)n);
+/* if (hash->obj.header.flags & GRN_OBJ_KEY_VAR_SIZE) {*/
+/* if (n->flag & HASH_IMMEDIATE) {*/
+/* return (char *)&n->str;*/
+/* } else {*/
+/* if (IO_HASHP(hash)) {*/
+/* return (char *)grn_io_hash_key_at(ctx, hash, n->str);*/
+/* } else {*/
+/* return ((entry_astr *)n)->str;*/
+/* }*/
+/* }*/
+/* } else {*/
+/* if (hash->key_size == sizeof(uint32_t)) {*/
+/* return ((grn_hash_plain_entry *)n)->key;*/
+/* } else {*/
+/* return ((grn_hash_rich_entry *)n)->key_and_value;*/
+/* }*/
+/* }*/
+}
+
+inline static void *
+get_value(grn_hash *hash, entry_str *n)
+{
+ return grn_hash_entry_get_value(hash, (grn_hash_entry *)n);
+/* if (hash->obj.header.flags & GRN_OBJ_KEY_VAR_SIZE) {*/
+/* if (IO_HASHP(hash)) {*/
+/* return ((entry_str *)n)->dummy;*/
+/* } else {*/
+/* return ((entry_astr *)n)->dummy;*/
+/* }*/
+/* } else {*/
+/* if (hash->key_size == sizeof(uint32_t)) {*/
+/* return ((entry *)n)->dummy;*/
+/* } else {*/
+/* return &((entry *)n)->dummy[hash->key_size];*/
+/* }*/
+/* }*/
+}
+
inline static void
put_key_(grn_ctx *ctx, grn_hash *hash, entry_str *n, const char *key, int len)
{