null+****@clear*****
null+****@clear*****
2012年 4月 2日 (月) 17:04:40 JST
Susumu Yata 2012-04-02 17:04:40 +0900 (Mon, 02 Apr 2012)
New Revision: 5463591560e6c4bc2d8396130b398e86ddd4cca7
Log:
Update functions for bitwise operations.
grn_tiny_array_bit_at() returns 1/0 on success, -1 on failure.
grn_io_array_*() are added.
Modified files:
lib/hash.c
Modified: lib/hash.c (+83 -21)
===================================================================
--- lib/hash.c 2012-04-02 16:12:20 +0900 (2d6b489)
+++ lib/hash.c 2012-04-02 17:04:40 +0900 (c8b9902)
@@ -82,17 +82,20 @@ grn_tiny_array_next(grn_tiny_array *array)
}
/*
- * grn_tiny_array_bit_at() returns the default value (0) when
- * grn_tiny_array_at_inline() returns NULL. So, it seems to work well.
+ * grn_tiny_array_bit_at() returns 1/0 on success, -1 on failure.
*/
-inline static grn_bool
+inline static int
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;
+ return ptr ? ((*ptr >> (offset & 7)) & 1) : -1;
}
+/*
+ * The following functions, grn_tiny_array_bit_*(), return a non-NULL pointer
+ * on success, a NULL pointer on failure.
+ */
inline static void *
grn_tiny_array_bit_on(grn_tiny_array *array, grn_id offset)
{
@@ -181,6 +184,69 @@ grn_tiny_array_id(grn_tiny_array *array, const void *element_address)
return GRN_ID_NIL;
}
+/* grn_io_array */
+
+inline void *
+grn_io_array_at_inline(grn_ctx *ctx, grn_io *io, uint32_t segment_id,
+ uint32_t offset, int flags)
+{
+ void *ptr;
+ GRN_IO_ARRAY_AT(io, segment_id, offset, &flags, ptr);
+ return ptr;
+}
+
+/*
+ * grn_io_array_bit_at() returns 1/0 on success, -1 on failure.
+ */
+inline static int
+grn_io_array_bit_at(grn_ctx *ctx, grn_io *io,
+ uint32_t segment_id, uint32_t offset)
+{
+ uint8_t * const ptr = (uint8_t *)grn_io_array_at_inline(
+ ctx, io, segment_id, (offset >> 3) + 1, 0);
+ return ptr ? ((*ptr >> (offset & 7)) & 1) : -1;
+}
+
+/*
+ * The following functions, grn_io_array_bit_*(), return a non-NULL pointer on
+ * success, a NULL pointer on failure.
+ */
+inline static void *
+grn_io_array_bit_on(grn_ctx *ctx, grn_io *io,
+ uint32_t segment_id, uint32_t offset)
+{
+ uint8_t * const ptr = (uint8_t *)grn_io_array_at_inline(
+ ctx, io, segment_id, (offset >> 3) + 1, GRN_TABLE_ADD);
+ if (ptr) {
+ *ptr |= 1 << (offset & 7);
+ }
+ return ptr;
+}
+
+inline static void *
+grn_io_array_bit_off(grn_ctx *ctx, grn_io *io,
+ uint32_t segment_id, uint32_t offset)
+{
+ uint8_t * const ptr = (uint8_t *)grn_io_array_at_inline(
+ ctx, io, segment_id, (offset >> 3) + 1, GRN_TABLE_ADD);
+ if (ptr) {
+ *ptr &= ~(1 << (offset & 7));
+ }
+ return ptr;
+}
+
+inline static void *
+grn_io_array_bit_flip(grn_ctx *ctx, grn_io *io,
+ uint32_t segment_id, uint32_t offset)
+{
+ uint8_t * const ptr = (uint8_t *)grn_io_array_at_inline(
+ ctx, io, segment_id, (offset >> 3) + 1, GRN_TABLE_ADD);
+ if (ptr) {
+ *ptr ^= 1 << (offset & 7);
+ }
+ return ptr;
+}
+
/* grn_array */
#define GRN_ARRAY_HEADER_SIZE 0x9000
@@ -230,11 +296,9 @@ inline static grn_bool
grn_array_bitmap_at(grn_ctx *ctx, grn_array *array, grn_id id)
{
if (grn_array_is_io_array(array)) {
- grn_bool value;
- GRN_IO_ARRAY_BIT_AT(array->io, GRN_ARRAY_BITMAP_SEGMENT, id, value);
- return value;
+ return grn_io_array_bit_at(ctx, array->io, GRN_ARRAY_BITMAP_SEGMENT, id) == 1;
} else {
- return grn_tiny_array_bit_at(&array->bitmap, id);
+ return grn_tiny_array_bit_at(&array->bitmap, id) == 1;
}
}
@@ -550,10 +614,10 @@ grn_array_delete_by_id(grn_ctx *ctx, grn_array *array, grn_id id,
(*array->n_entries)--;
(*array->n_garbages)++;
/*
- * The following GRN_IO_ARRAY_BIT_OFF() never fails because the above
+ * The following grn_io_array_bit_off() never fails because the above
* grn_array_bitmap_at() returned 1 for the same ID.
*/
- GRN_IO_ARRAY_BIT_OFF(array->io, GRN_ARRAY_BITMAP_SEGMENT, id);
+ grn_io_array_bit_off(ctx, array->io, GRN_ARRAY_BITMAP_SEGMENT, id);
}
} else {
if (array->value_size >= sizeof(grn_id)) {
@@ -767,15 +831,15 @@ grn_array_add_to_io_array(grn_ctx *ctx, grn_array *array, void **value)
header->garbages = *(grn_id *)entry;
memset(entry, 0, header->value_size);
(*array->n_garbages)--;
- /* FIXME: GRN_IO_ARRAY_BIT_ON() may fail and cause a critical problem. */
- GRN_IO_ARRAY_BIT_ON(array->io, GRN_ARRAY_BITMAP_SEGMENT, id);
+ /* FIXME: grn_io_array_bit_on() may fail and cause a critical problem. */
+ grn_io_array_bit_on(ctx, array->io, GRN_ARRAY_BITMAP_SEGMENT, id);
} else {
id = header->curr_rec + 1;
- /* FIXME: GRN_IO_ARRAY_BIT_ON() may fail and cause a critical problem. */
- GRN_IO_ARRAY_BIT_ON(array->io, GRN_ARRAY_BITMAP_SEGMENT, id);
+ /* FIXME: grn_io_array_bit_on() may fail and cause a critical problem. */
+ grn_io_array_bit_on(ctx, array->io, GRN_ARRAY_BITMAP_SEGMENT, id);
entry = grn_array_io_entry_at(ctx, array, id, GRN_TABLE_ADD);
if (!entry) {
- GRN_IO_ARRAY_BIT_OFF(array->io, GRN_ARRAY_BITMAP_SEGMENT, id);
+ grn_io_array_bit_off(ctx, array->io, GRN_ARRAY_BITMAP_SEGMENT, id);
return GRN_ID_NIL;
}
header->curr_rec = id;
@@ -900,11 +964,9 @@ inline static grn_bool
grn_hash_bitmap_at(grn_ctx *ctx, grn_hash *hash, grn_id id)
{
if (IO_HASHP(hash)) {
- grn_bool value;
- GRN_IO_ARRAY_BIT_AT(hash->io, segment_bitmap, id, value);
- return value;
+ return grn_io_array_bit_at(ctx, hash->io, segment_bitmap, id) == 1;
} else {
- return grn_tiny_array_bit_at(&hash->bitmap, id);
+ return grn_tiny_array_bit_at(&hash->bitmap, id) == 1;
}
}
@@ -1501,7 +1563,7 @@ entry_new(grn_ctx *ctx, grn_hash *hash, uint32_t size)
} else {
e = ++hh->curr_rec;
}
- GRN_IO_ARRAY_BIT_ON(hash->io, segment_bitmap, e);
+ grn_io_array_bit_on(ctx, hash->io, segment_bitmap, e);
} else {
if (hash->garbages) {
entry *ee;
@@ -1821,7 +1883,7 @@ grn_hash_set_value(grn_ctx *ctx, grn_hash *hash, grn_id id,
struct grn_hash_header *hh = hash->header;\
ee->key = hh->garbages[size];\
hh->garbages[size] = e;\
- GRN_IO_ARRAY_BIT_OFF(hash->io, segment_bitmap, e);\
+ grn_io_array_bit_off(ctx, hash->io, segment_bitmap, e);\
} else {\
ee->key = hash->garbages;\
hash->garbages = e;\