null+****@clear*****
null+****@clear*****
2012年 3月 27日 (火) 15:47:39 JST
Susumu Yata 2012-03-27 15:47:39 +0900 (Tue, 27 Mar 2012) New Revision: 21801275ea438cd1faa6c14e44bc50589fa6e760 Log: Replace GRN_TINY_ARRAY_* macros with functions. Modified files: lib/hash.c lib/hash.h Modified: lib/hash.c (+125 -34) =================================================================== --- lib/hash.c 2012-03-27 13:29:15 +0900 (48cca5d) +++ lib/hash.c 2012-03-27 15:47:39 +0900 (785efdd) @@ -16,7 +16,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "hash.h" -#include "pat.h" #include "output.h" #include <string.h> #include <limits.h> @@ -25,26 +24,122 @@ /* grn_tiny_array */ +inline static int +grn_tiny_array_get_block_id(grn_tiny_array *array, grn_id id) +{ + int most_significant_one_bit_offset; + GRN_BIT_SCAN_REV(id, most_significant_one_bit_offset); + return most_significant_one_bit_offset >> GRN_TINY_ARRAY_W; +} + +inline static void * +grn_tiny_array_at_inline(grn_tiny_array *array, grn_id id) +{ + int block_id; + void **block; + size_t offset; + if (!id) { + return NULL; + } + block_id = grn_tiny_array_get_block_id(array, id); + block = &array->elements[block_id]; + offset = GRN_TINY_ARRAY_R(block_id); + if (!*block) { + grn_ctx * const ctx = array->ctx; + if (array->flags & GRN_TINY_ARRAY_THREADSAFE) { + CRITICAL_SECTION_ENTER(array->lock); + } + if (!*block) { + const size_t block_size = + GRN_TINY_ARRAY_S * offset * array->element_size; + if (array->flags & GRN_TINY_ARRAY_USE_MALLOC) { + if (array->flags & GRN_TINY_ARRAY_CLEAR) { + *block = GRN_CALLOC(block_size); + } else { + *block = GRN_MALLOC(block_size); + } + } else { + *block = GRN_CTX_ALLOC(ctx, block_size); + } + } + if (array->flags & GRN_TINY_ARRAY_THREADSAFE) { + CRITICAL_SECTION_LEAVE(array->lock); + } + if (!*block) { + return NULL; + } + } + if (id > array->max) { + array->max = id; + } + return (byte *)*block + (id - offset) * array->element_size; +} + +inline static void * +grn_tiny_array_next(grn_tiny_array *array) +{ + return grn_tiny_array_at_inline(array, array->max + 1); +} + +inline static grn_bool +grn_tiny_array_bit_at(grn_tiny_array *array, grn_id offset) +{ + uint8_t * const ptr = + (uint8_t *)grn_tiny_array_at_inline(array, (offset >> 3) + 1); + return ptr ? ((*ptr >> (offset & 7)) & 1) : 0; +} + +inline static void +grn_tiny_array_bit_on(grn_tiny_array *array, grn_id offset) +{ + uint8_t * const ptr = + (uint8_t *)grn_tiny_array_at_inline(array, (offset >> 3) + 1); + if (ptr) { + *ptr |= 1 << (offset & 7); + } +} + +inline static void +grn_tiny_array_bit_off(grn_tiny_array *array, grn_id offset) +{ + uint8_t * const ptr = + (uint8_t *)grn_tiny_array_at_inline(array, (offset >> 3) + 1); + if (ptr) { + *ptr &= ~(1 << (offset & 7)); + } +} + +inline static void +grn_tiny_array_bit_flip(grn_tiny_array *array, grn_id offset) +{ + uint8_t * const ptr = + (uint8_t *)grn_tiny_array_at_inline(array, (offset >> 3) + 1); + if (ptr) { + *ptr ^= 1 << (offset & 7); + } +} + void -grn_tiny_array_init(grn_ctx *ctx, grn_tiny_array *a, uint16_t element_size, uint16_t flags) +grn_tiny_array_init(grn_ctx *ctx, grn_tiny_array *array, + uint16_t element_size, uint16_t flags) { - a->ctx = ctx; - a->element_size = element_size; - a->flags = flags; - a->max = 0; - if (flags & GRN_TINY_ARRAY_THREADSAFE) { CRITICAL_SECTION_INIT(a->lock); } - memset(a->elements, 0, sizeof(a->elements)); + array->ctx = ctx; + array->element_size = element_size; + array->flags = flags; + array->max = 0; + if (flags & GRN_TINY_ARRAY_THREADSAFE) { CRITICAL_SECTION_INIT(array->lock); } + memset(array->elements, 0, sizeof(array->elements)); } void -grn_tiny_array_fin(grn_tiny_array *a) +grn_tiny_array_fin(grn_tiny_array *array) { int i; - grn_ctx *ctx = a->ctx; + grn_ctx *ctx = array->ctx; for (i = 0; i < GRN_TINY_ARRAY_N; i++) { - void **e = &a->elements[i]; + void **e = &array->elements[i]; if (*e) { - if (a->flags & GRN_TINY_ARRAY_USE_MALLOC) { + if (array->flags & GRN_TINY_ARRAY_USE_MALLOC) { GRN_FREE(*e); } else { GRN_CTX_FREE(ctx, *e); @@ -55,23 +150,21 @@ grn_tiny_array_fin(grn_tiny_array *a) } void * -grn_tiny_array_at(grn_tiny_array *a, grn_id id) +grn_tiny_array_at(grn_tiny_array *array, grn_id id) { - void *e; - GRN_TINY_ARRAY_AT(a, id, e); - return e; + return grn_tiny_array_at_inline(array, id); } grn_id -grn_tiny_array_id(grn_tiny_array *a, void *p) +grn_tiny_array_id(grn_tiny_array *array, void *p) { uint32_t i, s, n; uintptr_t o, p_ = (uintptr_t) p; for (i = 0, s = 0; i < GRN_TINY_ARRAY_N; i++, s += n) { n = GRN_TINY_ARRAY_S * GRN_TINY_ARRAY_R(i); - o = (uintptr_t) a->elements[i]; - if (o <= p_ && p_ < o + n * a->element_size) { - return s + ((p_ - o) / a->element_size); + o = (uintptr_t) array->elements[i]; + if (o <= p_ && p_ < o + n * array->element_size) { + return s + ((p_ - o) / array->element_size); } } return GRN_ID_NIL; @@ -109,7 +202,7 @@ enum { if (IO_ARRAYP(array)) {\ ARRAY_ENTRY_AT_(array, id, value, addp);\ } else {\ - GRN_TINY_ARRAY_AT(&array->a, id, value);\ + (value) = grn_tiny_array_at_inline(&array->a, id);\ }\ } while (0) @@ -117,7 +210,7 @@ enum { if (IO_ARRAYP(array)) {\ GRN_IO_ARRAY_BIT_AT((array)->io, array_seg_bitmap, (id), (value));\ } else {\ - GRN_TINY_ARRAY_BIT_AT(&(array)->bitmap, (id), (value));\ + (value) = grn_tiny_array_bit_at(&(array)->bitmap, (id));\ }\ } while (0) @@ -411,15 +504,14 @@ grn_array_delete_by_id(grn_ctx *ctx, grn_array *array, grn_id id, GRN_IO_ARRAY_BIT_OFF(array->io, array_seg_bitmap, id); } else { if (array->value_size >= sizeof(grn_id)) { - void *ee; - GRN_TINY_ARRAY_AT(&array->a, id, ee); + void *ee = grn_tiny_array_at_inline(&array->a, id); if (!ee) { rc = GRN_INVALID_ARGUMENT; goto exit; } *((grn_id *)ee) = array->garbages; array->garbages = id; } (*array->n_entries)--; (*array->n_garbages)++; - GRN_TINY_ARRAY_BIT_OFF(&array->bitmap, id); + grn_tiny_array_bit_off(&array->bitmap, id); } exit : /* unlock */ @@ -588,15 +680,14 @@ array_entry_new(grn_ctx *ctx, grn_array *array) GRN_IO_ARRAY_BIT_ON(array->io, array_seg_bitmap, e); } else { if ((e = array->garbages)) { - void *ee; - GRN_TINY_ARRAY_AT(&array->a, e, ee); + void *ee = grn_tiny_array_at_inline(&array->a, e); array->garbages = *((grn_id *)ee); memset(ee, 0, array->value_size); (*array->n_garbages)--; } else { e = ++array->a.max; } - GRN_TINY_ARRAY_BIT_ON(&array->bitmap, e); + grn_tiny_array_bit_on(&array->bitmap, e); } return e; } @@ -663,7 +754,7 @@ enum { if (IO_HASHP(hash)) {\ ENTRY_AT_(hash, id, ee, addp);\ } else {\ - GRN_TINY_ARRAY_AT(&hash->a, id, ee);\ + (ee) = grn_tiny_array_at_inline(&hash->a, id);\ }\ } while (0) @@ -671,7 +762,7 @@ enum { if (IO_HASHP(hash)) {\ GRN_IO_ARRAY_BIT_AT((hash)->io, segment_bitmap, (id), (value));\ } else {\ - GRN_TINY_ARRAY_BIT_AT(&(hash)->bitmap, (id), (value));\ + (value) = grn_tiny_array_bit_at(&(hash)->bitmap, (id));\ }\ } while (0) @@ -1004,7 +1095,7 @@ tiny_hash_fin(grn_ctx *ctx, grn_hash *hash) entry_astr *n; e = *sp; if (!e || (e == GARBAGE)) { continue; } - GRN_TINY_ARRAY_AT(&hash->a, e, n); + n = grn_tiny_array_at_inline(&hash->a, e); GRN_ASSERT(n); i--; if (!n || (n->flag & HASH_IMMEDIATE)) { continue; } @@ -1172,13 +1263,13 @@ entry_new(grn_ctx *ctx, grn_hash *hash, uint32_t size) if (hash->garbages) { entry *ee; e = hash->garbages; - GRN_TINY_ARRAY_AT(&hash->a, e, ee); + ee = grn_tiny_array_at_inline(&hash->a, e); hash->garbages = ee->key; memset(ee, 0, hash->entry_size); } else { e = hash->a.max + 1; } - GRN_TINY_ARRAY_BIT_ON(&hash->bitmap, e); + grn_tiny_array_bit_on(&hash->bitmap, e); } return e; } @@ -1512,7 +1603,7 @@ grn_hash_set_value(grn_ctx *ctx, grn_hash *hash, grn_id id, grn_ctx *ctx = hash->ctx;\ GRN_CTX_FREE(ctx, ((entry_astr *)ee)->str);\ }\ - GRN_TINY_ARRAY_BIT_OFF(&hash->bitmap, e);\ + grn_tiny_array_bit_off(&hash->bitmap, e);\ }\ (*hash->n_entries)--;\ (*hash->n_garbages)++;\ Modified: lib/hash.h (+5 -63) =================================================================== --- lib/hash.h 2012-03-27 13:29:15 +0900 (9fc8466) +++ lib/hash.h 2012-03-27 15:47:39 +0900 (7ebce64) @@ -65,69 +65,11 @@ struct _grn_tiny_array { }\ } while (0) -#define GRN_TINY_ARRAY_AT(a,id,e) do {\ - grn_id id_ = (id);\ - byte **e_;\ - size_t o_;\ - {\ - int l_, i_;\ - if (!id_) { e = NULL; break; }\ - GRN_BIT_SCAN_REV(id_, l_);\ - i_ = l_ >> GRN_TINY_ARRAY_W;\ - o_ = GRN_TINY_ARRAY_R(i_);\ - e_ = (byte **)&(a)->elements[i_];\ - }\ - if (!*e_) {\ - grn_ctx *ctx = (a)->ctx;\ - if ((a)->flags & GRN_TINY_ARRAY_THREADSAFE) { CRITICAL_SECTION_ENTER((a)->lock); }\ - if (!*e_) {\ - if ((a)->flags & GRN_TINY_ARRAY_USE_MALLOC) {\ - if ((a)->flags & GRN_TINY_ARRAY_CLEAR) {\ - *e_ = GRN_CALLOC(GRN_TINY_ARRAY_S * o_ * (a)->element_size);\ - } else {\ - *e_ = GRN_MALLOC(GRN_TINY_ARRAY_S * o_ * (a)->element_size);\ - }\ - } else {\ - *e_ = GRN_CTX_ALLOC(ctx, GRN_TINY_ARRAY_S * o_ * (a)->element_size);\ - }\ - }\ - if ((a)->flags & GRN_TINY_ARRAY_THREADSAFE) { CRITICAL_SECTION_LEAVE((a)->lock); }\ - if (!*e_) { e = NULL; break; }\ - }\ - if (id_ > (a)->max) { (a)->max = id_; }\ - (e) = (void *)(*e_ + (id_ - o_) * (a)->element_size);\ -} while (0) - -#define GRN_TINY_ARRAY_NEXT(a,e) GRN_TINY_ARRAY_AT((a), (a)->max + 1, e) - -#define GRN_TINY_ARRAY_BIT_AT(array,offset,res) do {\ - uint8_t *ptr_;\ - GRN_TINY_ARRAY_AT((array), ((offset) >> 3) + 1, ptr_);\ - res = ptr_ ? ((*ptr_ >> ((offset) & 7)) & 1) : 0;\ -} while (0) - -#define GRN_TINY_ARRAY_BIT_ON(array,offset) do {\ - uint8_t *ptr_;\ - GRN_TINY_ARRAY_AT((array), ((offset) >> 3) + 1, ptr_);\ - if (ptr_) { *ptr_ |= (1 << ((offset) & 7)); }\ -} while (0) - -#define GRN_TINY_ARRAY_BIT_OFF(array,offset) do {\ - uint8_t *ptr_;\ - GRN_TINY_ARRAY_AT((array), ((offset) >> 3) + 1, ptr_);\ - if (ptr_) { *ptr_ &= ~(1 << ((offset) & 7)); }\ -} while (0) - -#define GRN_TINY_ARRAY_BIT_FLIP(array,offset) do {\ - uint8_t *ptr_;\ - GRN_TINY_ARRAY_AT((array), ((offset) >> 3) + 1, ptr_);\ - if (ptr_) { *ptr_ ^= (1 << ((offset) & 7)); }\ -} while (0) - -void grn_tiny_array_init(grn_ctx *ctx, grn_tiny_array *a, uint16_t element_size, uint16_t flags); -void grn_tiny_array_fin(grn_tiny_array *a); -void *grn_tiny_array_at(grn_tiny_array *a, grn_id id); -grn_id grn_tiny_array_id(grn_tiny_array *a, void *p); +void grn_tiny_array_init(grn_ctx *ctx, grn_tiny_array *array, + uint16_t element_size, uint16_t flags); +void grn_tiny_array_fin(grn_tiny_array *array); +void *grn_tiny_array_at(grn_tiny_array *array, grn_id id); +grn_id grn_tiny_array_id(grn_tiny_array *array, void *p); /**** grn_array ****/