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) {