30 grn_tiny_array_get_block_id(
grn_id id)
32 int most_significant_one_bit_offset;
40 const int block_id = grn_tiny_array_get_block_id(
id);
41 uint8_t *
const block = (uint8_t *)array->
blocks[block_id];
52 const int block_id = grn_tiny_array_get_block_id(
id);
53 void **
const block = &array->
blocks[block_id];
58 CRITICAL_SECTION_ENTER(array->
lock);
61 const size_t block_size =
74 CRITICAL_SECTION_LEAVE(array->
lock);
80 if (
id > array->
max) {
83 return (uint8_t *)*block + (
id - offset) * array->
element_size;
89 return id ? grn_tiny_array_put(array,
id) : NULL;
95 return grn_tiny_array_put(array, array->
max + 1);
100 uint16_t element_size, uint16_t flags)
105 array->
flags = flags;
108 CRITICAL_SECTION_INIT(array->
lock);
118 if (array->
blocks[block_id]) {
124 array->
blocks[block_id] = NULL;
132 return grn_tiny_array_at_inline(array,
id);
138 const uint8_t *
const ptr = (
const uint8_t *)element_address;
139 uint32_t block_id, offset = 1;
142 const uint8_t *
const block = (
const uint8_t *)array->
blocks[block_id];
144 if (block <= ptr && ptr < (block + block_size * array->
element_size)) {
148 offset += block_size;
168 if (bitmap->
blocks[block_id]) {
170 bitmap->
blocks[block_id] = NULL;
176 inline static uint8_t *
178 const uint32_t byte_id = (bit_id >> 3) + 1;
179 const int block_id = grn_tiny_array_get_block_id(byte_id);
180 uint8_t *
const block = (uint8_t *)bitmap->
blocks[block_id];
183 return block + byte_id - offset;
189 inline static uint8_t *
191 const uint32_t byte_id = (bit_id >> 3) + 1;
192 const int block_id = grn_tiny_array_get_block_id(byte_id);
193 void **
const block = &bitmap->
blocks[block_id];
202 return (uint8_t *)*block + byte_id - offset;
210 uint8_t *
const ptr = grn_tiny_bitmap_get_byte(bitmap, bit_id);
211 return ptr ? ((*ptr >> (bit_id & 7)) & 1) : -1;
220 uint8_t *
const ptr = grn_tiny_bitmap_put_byte(bitmap, bit_id);
221 return ptr ? ((*ptr >> (bit_id & 7)) & 1) : -1;
225 inline static uint8_t *
229 uint8_t *
const ptr = grn_tiny_bitmap_get_byte(bitmap, bit_id);
233 *ptr |= 1 << (bit_id & 7);
235 *ptr &= ~(1 << (bit_id & 7));
243 inline static uint8_t *
247 uint8_t *
const ptr = grn_tiny_bitmap_put_byte(bitmap, bit_id);
251 *ptr |= 1 << (bit_id & 7);
253 *ptr &= ~(1 << (bit_id & 7));
261 #define GRN_ARRAY_MAX (GRN_ID_MAX - 8)
264 grn_io_array_at_inline(
grn_ctx *ctx,
grn_io *io, uint32_t segment_id,
265 uint32_t offset,
int flags)
277 uint32_t segment_id, uint32_t offset)
279 uint8_t *
const ptr = (uint8_t *)grn_io_array_at_inline(
280 ctx, io, segment_id, (offset >> 3) + 1, 0);
281 return ptr ? ((*ptr >> (offset & 7)) & 1) : -1;
290 uint32_t segment_id, uint32_t offset)
292 uint8_t *
const ptr = (uint8_t *)grn_io_array_at_inline(
295 *ptr |= 1 << (offset & 7);
302 uint32_t segment_id, uint32_t offset)
304 uint8_t *
const ptr = (uint8_t *)grn_io_array_at_inline(
307 *ptr &= ~(1 << (offset & 7));
314 uint32_t segment_id, uint32_t offset)
316 uint8_t *
const ptr = (uint8_t *)grn_io_array_at_inline(
319 *ptr ^= 1 << (offset & 7);
340 grn_table_queue_lock_init(ctx, queue);
354 if (queue->
head == 2 * queue->
cap) {
364 if (queue->
tail == 2 * queue->
cap) {
374 return queue->
head > queue->
cap
382 return queue->
tail > queue->
cap
389 #define GRN_ARRAY_SEGMENT_SIZE 0x400000
417 return array->
io != NULL;
429 if (grn_array_is_io_array(array)) {
430 return grn_array_io_entry_at(ctx, array,
id, flags);
432 return grn_tiny_array_at_inline(&array->
array,
id);
440 if (grn_array_is_io_array(array)) {
443 return grn_tiny_bitmap_put(&array->
bitmap,
id);
449 uint32_t value_size, uint32_t flags)
467 grn_tiny_bitmap_init(ctx, &array->
bitmap);
472 grn_array_create_io_array(
grn_ctx *ctx,
const char *path, uint32_t value_size)
474 uint32_t w_of_element = 0;
477 while ((1U << w_of_element) < value_size) {
483 1U << (30 - (22 - w_of_element));
493 uint32_t value_size, uint32_t flags)
498 io = grn_array_create_io_array(ctx, path, value_size);
512 grn_table_queue_init(ctx, &header->
queue);
531 grn_table_queue_lock_init(ctx, &header->
queue);
537 if (grn_array_is_io_array(array)) {
540 return &header->
queue;
548 const char *path, uint32_t value_size, uint32_t flags)
551 return grn_array_init_tiny_array(ctx, array, path, value_size, flags);
553 return grn_array_init_io_array(ctx, array, path, value_size, flags);
564 if (!grn_array_init(ctx, array, path, value_size, flags)) {
616 if (grn_array_is_io_array(array)) {
621 grn_tiny_bitmap_fin(&array->
bitmap);
642 if (grn_array_is_io_array(array)) {
644 if (io_path && *io_path) {
655 if (grn_array_is_io_array(array)) {
665 rc = grn_array_init(ctx, array, path, value_size, flags);
680 if (!ctx || !array) {
688 if (grn_array_bitmap_at(ctx, array,
id) != 1) {
691 }
else if (
id == 0 ||
id > grn_array_get_max_id(array)) {
694 return grn_array_entry_at(ctx, array,
id, 0);
700 void *
const value = grn_array_get_value_inline(ctx, array,
id);
713 return grn_array_get_value_inline(ctx, array,
id);
718 const void *value,
int flags)
720 void *
const entry = grn_array_entry_at(ctx, array,
id, 0);
731 case sizeof(int32_t) :
732 *((int32_t *)entry) += *((int32_t *)value);
734 case sizeof(int64_t) :
735 *((int64_t *)entry) += *((int64_t *)value);
743 case sizeof(int32_t) :
744 *((int32_t *)entry) -= *((int32_t *)value);
746 case sizeof(int64_t) :
747 *((int64_t *)entry) -= *((int64_t *)value);
761 const void *value,
int flags)
763 if (!ctx || !array || !value) {
771 if (grn_array_bitmap_at(ctx, array,
id) != 1) {
774 }
else if (
id == 0 ||
id > grn_array_get_max_id(array)) {
777 return grn_array_set_value_inline(ctx, array,
id, value, flags);
784 if (!ctx || !array) {
787 if (grn_array_bitmap_at(ctx, array,
id) != 1) {
794 if (grn_array_is_io_array(array)) {
797 void *
const entry = grn_array_io_entry_at(ctx, array,
id, 0);
817 void *
const entry = grn_tiny_array_get(&array->
array,
id);
833 grn_tiny_bitmap_get_and_set(&array->
bitmap,
id, 0);
849 if (grn_array_bitmap_at(ctx, array,
id) != 1) {
852 }
else if (
id > grn_array_get_max_id(array)) {
880 int offset,
int limit,
int flags)
883 if (!array || !ctx) {
return NULL; }
886 if (!cursor) {
return NULL; }
889 cursor->
array = array;
900 cursor->
curr_rec = grn_array_get_max_id(array) + 1;
921 cursor->
tail = grn_array_get_max_id(array);
929 if (grn_array_bitmap_at(ctx, cursor->
array, cursor->
curr_rec) == 1) {
943 if (cursor && cursor->
rest) {
947 if (grn_array_bitmap_at(ctx, cursor->
array, cursor->
curr_rec) != 1) {
961 const grn_id max_id = grn_array_get_max_id(array);
962 while (++
id <= max_id) {
964 grn_array_bitmap_at(ctx, array,
id) == 1) {
974 if (cursor && value) {
975 void *
const entry = grn_array_entry_at(ctx, cursor->
array, cursor->
curr_rec, 0);
986 const void *value,
int flags)
988 return grn_array_set_value_inline(ctx, cursor->
array, cursor->
curr_rec,
1006 entry = grn_tiny_array_get(&array->
array,
id);
1013 if (!grn_tiny_bitmap_get_and_set(&array->
bitmap,
id, 1)) {
1022 if (!grn_tiny_bitmap_put_and_set(&array->
bitmap,
id, 1)) {
1025 entry = grn_tiny_array_put(&array->
array,
id);
1027 grn_tiny_bitmap_get_and_set(&array->
bitmap,
id, 0);
1033 if (value) { *value = entry; }
1045 entry = grn_array_io_entry_at(ctx, array,
id,
GRN_TABLE_ADD);
1065 entry = grn_array_io_entry_at(ctx, array,
id,
GRN_TABLE_ADD);
1073 if (value) { *value = entry; }
1088 if (grn_array_is_io_array(array)) {
1089 return grn_array_add_to_io_array(ctx, array, value);
1091 return grn_array_add_to_tiny_array(ctx, array, value);
1105 MUTEX_LOCK(queue->
mutex);
1111 func(ctx, array,
id, func_arg);
1118 MUTEX_UNLOCK(queue->
mutex);
1133 MUTEX_LOCK(queue->
mutex);
1137 MUTEX_UNLOCK(queue->
mutex);
1146 func(ctx, array,
id, func_arg);
1148 MUTEX_UNLOCK(queue->
mutex);
1164 COND_BROADCAST(queue->
cond);
1169 #define GRN_HASH_MAX_SEGMENT 0x400
1170 #define GRN_HASH_HEADER_SIZE 0x9000
1171 #define GRN_HASH_SEGMENT_SIZE 0x400000
1172 #define W_OF_KEY_IN_A_SEGMENT 22
1173 #define IDX_MASK_IN_A_SEGMENT 0xfffff
1182 uint8_t key_and_value[1];
1190 uint8_t buf[
sizeof(uint32_t)];
1201 uint8_t buf[
sizeof(
void *)];
1248 #define LOGICAL_MAX_SEGMENT ((GRN_HASH_MAX_SEGMENT) * 4)
1258 grn_hash_is_io_hash(
grn_hash *hash)
1260 return hash->
io != NULL;
1263 inline static void *
1270 inline static void *
1273 if (grn_hash_is_io_hash(hash)) {
1274 return grn_io_hash_entry_at(ctx, hash,
id, flags);
1276 return grn_tiny_array_at_inline(&hash->
a,
id);
1283 if (grn_hash_is_io_hash(hash)) {
1286 return grn_tiny_bitmap_put(&hash->
bitmap,
id) == 1;
1300 if (grn_hash_is_io_hash(hash)) {
1302 return grn_io_hash_idx_at(ctx, hash,
id);
1308 inline static void *
1315 #define HASH_IMMEDIATE 1
1317 #define MAX_INDEX_SIZE ((GRN_HASH_MAX_SEGMENT * (IDX_MASK_IN_A_SEGMENT + 1)) >> 1)
1319 inline static uint16_t
1329 inline static char *
1333 if (grn_hash_is_io_hash(hash)) {
1347 if (hash->
key_size ==
sizeof(uint32_t)) {
1355 inline static void *
1359 if (grn_hash_is_io_hash(hash)) {
1365 if (hash->
key_size ==
sizeof(uint32_t)) {
1376 const void *key,
unsigned int key_size)
1378 uint32_t key_offset;
1382 uint32_t segment_id;
1396 void *
const key_ptr = grn_io_hash_key_at(ctx, hash, key_offset);
1400 memcpy(key_ptr, key, key_size);
1408 const void *key,
unsigned int key_size)
1411 if (grn_hash_is_io_hash(hash)) {
1443 if (hash->
key_size ==
sizeof(uint32_t)) {
1460 const void *key,
unsigned int key_size)
1467 if (grn_hash_is_io_hash(hash)) {
1471 const void *
const entry_key_ptr =
1473 return !memcmp(key, entry_key_ptr, key_size);
1486 if (key_size ==
sizeof(uint32_t)) {
1494 inline static char *
1500 inline static void *
1508 const char *key,
unsigned int len)
1510 return grn_hash_entry_put_key(ctx, hash, (
grn_hash_entry *)n, h, key, len);
1515 const char *key,
unsigned int len)
1517 return grn_hash_entry_compare_key(ctx, hash, (
grn_hash_entry *)ee,
1521 #define GARBAGE (0xffffffff)
1523 inline static uint32_t
1524 grn_io_hash_calculate_entry_size(uint32_t key_size, uint32_t value_size,
1530 if (key_size ==
sizeof(uint32_t)) {
1534 + key_size + value_size;
1540 grn_io_hash_create_io(
grn_ctx *ctx,
const char *path, uint32_t entry_size)
1542 uint32_t w_of_element = 0;
1545 while ((1U << w_of_element) < entry_size) {
1553 1U << (30 - (22 - w_of_element));
1565 uint32_t key_size, uint32_t value_size, uint32_t flags,
1572 entry_size = grn_io_hash_calculate_entry_size(key_size, value_size, flags);
1574 io = grn_io_hash_create_io(ctx, path, entry_size);
1581 while (max_offset < init_size * 2) {
1612 grn_table_queue_init(ctx, &header->
queue);
1630 #define INITIAL_INDEX_SIZE 256U
1633 grn_tiny_hash_calculate_entry_size(uint32_t key_size, uint32_t value_size,
1640 if (key_size ==
sizeof(uint32_t)) {
1644 + key_size + value_size;
1647 if (entry_size !=
sizeof(uint32_t)) {
1648 entry_size +=
sizeof(uintptr_t) - 1;
1649 entry_size &= ~(
sizeof(uintptr_t) - 1);
1656 uint32_t key_size, uint32_t value_size, uint32_t flags,
1669 entry_size = grn_tiny_hash_calculate_entry_size(key_size, value_size, flags);
1687 grn_tiny_bitmap_init(ctx, &hash->
bitmap);
1693 uint32_t key_size, uint32_t value_size, uint32_t flags)
1696 return grn_tiny_hash_init(ctx, hash, path, key_size, value_size,
1699 return grn_io_hash_init(ctx, hash, path, key_size, value_size,
1720 if (grn_hash_init(ctx, hash, path, key_size, value_size, flags)) {
1762 "invalid hash flag. (%x)", header->
flags);
1783 uint32_t num_remaining_entries = *hash->
n_entries;
1785 for (hash_ptr = hash->
index; num_remaining_entries; hash_ptr++) {
1786 const grn_id id = *hash_ptr;
1791 num_remaining_entries--;
1799 grn_tiny_bitmap_fin(&hash->
bitmap);
1809 if (grn_hash_is_io_hash(hash)) {
1813 rc = grn_tiny_hash_fin(ctx, hash);
1833 if (!ctx || !hash) {
1837 if (grn_hash_is_io_hash(hash)) {
1839 if (io_path && *io_path) {
1851 if (grn_hash_is_io_hash(hash)) {
1861 rc = grn_hash_init(ctx, hash, path, key_size, value_size, flags);
1869 inline static uint32_t
1870 grn_hash_calculate_hash_value(
const void *ptr, uint32_t size)
1873 uint32_t hash_value = 0;
1874 for (i = 0; i < size; i++) {
1875 hash_value = (hash_value * 1021) + ((
const uint8_t *)ptr)[i];
1880 inline static uint32_t
1881 grn_hash_calculate_step(uint32_t hash_value)
1883 return (hash_value >> 2) | 0x1010101;
1887 grn_hash_reset(
grn_ctx *ctx,
grn_hash *hash, uint32_t expected_n_entries)
1889 grn_id *new_index = NULL;
1891 grn_id *src_ptr = NULL, *dest_ptr = NULL;
1892 uint32_t src_offset = 0, dest_offset = 0;
1894 const uint32_t max_offset = *hash->
max_offset;
1896 if (!expected_n_entries) {
1897 expected_n_entries = n_entries * 2;
1899 if (expected_n_entries > INT_MAX) {
1902 while (new_index_size <= expected_n_entries) {
1903 new_index_size *= 2;
1906 if (grn_hash_is_io_hash(hash)) {
1916 dest_ptr = grn_io_hash_idx_at(ctx, hash, i + dest_offset);
1928 src_ptr = hash->
index;
1932 uint32_t src_pos, count;
1933 const uint32_t new_max_offset = new_index_size - 1;
1934 for (count = 0, src_pos = 0; count < n_entries && src_pos <=
max_offset;
1935 src_pos++, src_ptr++) {
1940 src_ptr = grn_io_hash_idx_at(ctx, hash, src_pos + src_offset);
1945 entry_id = *src_ptr;
1946 if (!entry_id || (entry_id ==
GARBAGE)) {
1949 entry = grn_hash_entry_at(ctx, hash, entry_id,
GRN_TABLE_ADD);
1953 step = grn_hash_calculate_step(entry->
hash_value);
1955 i &= new_max_offset;
1956 if (grn_hash_is_io_hash(hash)) {
1957 dest_ptr = grn_io_hash_idx_at(ctx, hash, i + dest_offset);
1962 dest_ptr = new_index +
i;
1968 *dest_ptr = entry_id;
1975 if (grn_hash_is_io_hash(hash)) {
1979 hash->
index = new_index;
1989 static int _ncalls = 0, _ncolls = 0;
1992 for (count = 0;; count++) {
1994 GRN_ATOMIC_ADD_EX(hash->
lock, 1, lock);
1996 GRN_ATOMIC_ADD_EX(hash->
lock, -1, lock);
1997 if (!timeout || (timeout > 0 && timeout == count)) {
break; }
1998 if (!(++_ncolls % 1000000) && (_ncolls > _ncalls)) {
1999 if (_ncolls < 0 || _ncalls < 0) {
2000 _ncolls = 0; _ncalls = 0;
2018 GRN_ATOMIC_ADD_EX(hash->
lock, -1, lock);
2031 const void *key,
unsigned int key_size,
void **value)
2037 entry_id = header->
garbages[key_size - 1];
2039 entry = grn_io_hash_entry_at(ctx, hash, entry_id,
GRN_TABLE_ADD);
2052 entry = grn_hash_entry_at(ctx, hash, entry_id,
GRN_TABLE_ADD);
2063 if (grn_hash_entry_put_key(ctx, hash, entry, hash_value, key, key_size)) {
2068 *value = grn_hash_entry_get_value(hash, entry);
2075 const void *key,
unsigned int key_size,
void **value)
2085 entry_id = hash->
a.
max + 1;
2092 if (!grn_tiny_bitmap_put_and_set(&hash->
bitmap, entry_id, 1)) {
2096 if (grn_hash_entry_put_key(ctx, hash, entry, hash_value, key, key_size)) {
2101 *value = grn_hash_entry_get_value(hash, entry);
2108 unsigned int key_size,
void **value,
int *added)
2110 uint32_t hash_value;
2111 if (!key || !key_size) {
2119 hash_value = grn_hash_calculate_hash_value(key, key_size);
2125 if (key_size ==
sizeof(uint32_t)) {
2126 hash_value = *((uint32_t *)key);
2128 hash_value = grn_hash_calculate_hash_value(key, key_size);
2134 const uint32_t step = grn_hash_calculate_step(hash_value);
2140 grn_hash_reset(ctx, hash, 0);
2143 for (i = hash_value; ; i += step) {
2144 index = grn_hash_idx_at(ctx, hash, i);
2153 if (!garbage_index) {
2154 garbage_index =
index;
2163 if (grn_hash_entry_compare_key(ctx, hash, entry, hash_value,
2166 *value = grn_hash_entry_get_value(hash, entry);
2175 if (grn_hash_is_io_hash(hash)) {
2176 id = grn_io_hash_add(ctx, hash, hash_value, key, key_size, value);
2178 id = grn_tiny_hash_add(ctx, hash, hash_value, key, key_size, value);
2183 if (garbage_index) {
2185 index = garbage_index;
2200 unsigned int key_size,
void **value)
2202 uint32_t hash_value;
2207 hash_value = grn_hash_calculate_hash_value(key, key_size);
2212 if (key_size ==
sizeof(uint32_t)) {
2213 hash_value = *((uint32_t *)key);
2215 hash_value = grn_hash_calculate_hash_value(key, key_size);
2221 const uint32_t step = grn_hash_calculate_step(hash_value);
2222 for (i = hash_value; ; i += step) {
2224 grn_id *
const index = grn_hash_idx_at(ctx, hash, i);
2233 grn_hash_entry *
const entry = grn_hash_entry_at(ctx, hash,
id, 0);
2235 if (grn_hash_entry_compare_key(ctx, hash, entry, hash_value,
2238 *value = grn_hash_entry_get_value(hash, entry);
2251 if (!grn_hash_bitmap_at(ctx, hash,
id)) {
2254 return grn_hash_entry_at(ctx, hash,
id, 0);
2260 grn_hash_entry *
const entry = grn_hash_get_entry(ctx, hash,
id);
2265 *key_size = grn_hash_entry_get_key_size(hash, entry);
2266 return grn_hash_entry_get_key(ctx, hash, entry);
2273 grn_hash_entry *
const entry = grn_hash_get_entry(ctx, hash,
id);
2277 key_size = grn_hash_entry_get_key_size(hash, entry);
2278 if (bufsize >= key_size) {
2279 memcpy(keybuf, grn_hash_entry_get_key(ctx, hash, entry), key_size);
2289 grn_hash_entry *
const entry = grn_hash_get_entry(ctx, hash,
id);
2293 key_size = grn_hash_entry_get_key_size(hash, entry);
2294 key = grn_hash_entry_get_key(ctx, hash, entry);
2296 bulk->
u.
b.head = key;
2308 grn_hash_entry *
const entry = grn_hash_get_entry(ctx, hash,
id);
2312 value = grn_hash_entry_get_value(hash, entry);
2326 grn_hash_entry *
const entry = grn_hash_get_entry(ctx, hash,
id);
2330 value = grn_hash_entry_get_value(hash, entry);
2335 return (
const char *)value;
2340 void *keybuf,
int bufsize,
void *valuebuf)
2344 grn_hash_entry *
const entry = grn_hash_get_entry(ctx, hash,
id);
2348 key_size = grn_hash_entry_get_key_size(hash, entry);
2349 if (bufsize >= key_size) {
2350 memcpy(keybuf, grn_hash_entry_get_key(ctx, hash, entry), key_size);
2352 value = grn_hash_entry_get_value(hash, entry);
2364 void **key,
void **value)
2367 grn_hash_entry *
const entry = grn_hash_get_entry(ctx, hash,
id);
2371 key_size = grn_hash_entry_get_key_size(hash, entry);
2372 *key = grn_hash_entry_get_key(ctx, hash, entry);
2373 *value = grn_hash_entry_get_value(hash, entry);
2374 return *value ? key_size : 0;
2379 const void *value,
int flags)
2386 entry = grn_hash_get_entry(ctx, hash,
id);
2390 entry_value = grn_hash_entry_get_value(hash, entry);
2395 switch (flags & GRN_OBJ_SET_MASK) {
2397 memcpy(entry_value, value, hash->
value_size);
2401 case sizeof(int32_t) :
2402 *((int32_t *)entry_value) += *((int32_t *)value);
2404 case sizeof(int64_t) :
2405 *((int64_t *)entry_value) += *((int64_t *)value);
2413 case sizeof(int32_t) :
2414 *((int32_t *)entry_value) -= *((int32_t *)value);
2416 case sizeof(int64_t) :
2417 *((int64_t *)entry_value) -= *((int64_t *)value);
2429 #define DELETE_IT do {\
2431 if (grn_hash_is_io_hash(hash)) {\
2432 uint32_t size = key_size - 1;\
2433 struct grn_hash_header *hh = hash->header;\
2434 ee->key = hh->garbages[size];\
2435 hh->garbages[size] = e;\
2436 grn_io_array_bit_off(ctx, hash->io, GRN_HASH_BITMAP_SEGMENT, e);\
2438 ee->key = hash->garbages;\
2439 hash->garbages = e;\
2440 if ((hash->obj.header.flags & GRN_OBJ_KEY_VAR_SIZE) && !(ee->flag & HASH_IMMEDIATE)) {\
2441 grn_ctx *ctx = hash->ctx;\
2442 GRN_CTX_FREE(ctx, ((entry_astr *)ee)->str);\
2444 grn_tiny_bitmap_get_and_set(&hash->bitmap, e, 0);\
2446 (*hash->n_entries)--;\
2447 (*hash->n_garbages)++;\
2457 if (!hash || !
id) {
return rc; }
2459 ee = grn_hash_entry_at(ctx, hash,
id, 0);
2462 uint32_t
i,
key_size, h = ee->
key, s = grn_hash_calculate_step(h);
2464 for (i = h; ; i += s) {
2466 if (!(e = *ep)) {
break; }
2481 uint32_t h,
i, m, s;
2485 h = grn_hash_calculate_hash_value(key, key_size);
2488 if (key_size ==
sizeof(uint32_t)) {
2489 h = *((uint32_t *)key);
2491 h = grn_hash_calculate_hash_value(key, key_size);
2494 s = grn_hash_calculate_step(h);
2499 for (i = h; ; i += s) {
2501 if (!(e = *ep)) {
break; }
2502 if (e ==
GARBAGE) {
continue; }
2504 entry_str *
const ee = grn_hash_entry_at(ctx, hash, e, 0);
2505 if (ee && match_key(ctx, hash, ee, h, key, key_size)) {
2533 #define HASH_CURR_MAX(hash) \
2534 ((grn_hash_is_io_hash(hash)) ? (hash)->header->curr_rec : (hash)->a.max)
2538 const void *min, uint32_t min_size,
2539 const void *max, uint32_t max_size,
2540 int offset,
int limit,
int flags)
2543 if (!hash || !ctx) {
return NULL; }
2596 if (grn_hash_bitmap_at(ctx, c->
hash, c->
curr_rec)) { offset--; }
2613 if (!grn_hash_bitmap_at(ctx, c->
hash, c->
curr_rec)) {
continue; }
2626 while (++
id <= max) {
2627 if (grn_hash_bitmap_at(ctx, hash,
id)) {
return id; }
2635 return grn_hash_bitmap_at(ctx, hash,
id) ?
id :
GRN_ID_NIL;
2643 if (!c) {
return 0; }
2645 if (!ee) {
return 0; }
2647 *key = get_key(ctx, c->
hash, ee);
2656 if (!c) {
return 0; }
2658 if (ee && (v = get_value(c->
hash, ee))) {
2667 void **key, uint32_t *key_size,
void **value)
2676 if (key) { *key = get_key(ctx, c->
hash, ee); }
2677 if (value) { *value = get_value(c->
hash, ee); }
2683 const void *value,
int flags)
2699 #define PREPARE_VAL(e,ep,es) do {\
2700 if ((arg->flags & GRN_TABLE_SORT_BY_VALUE)) {\
2701 ep = ((const uint8_t *)(get_value(hash, (entry_str *)(e))));\
2702 es = hash->value_size;\
2704 ep = ((const uint8_t *)(get_key(ctx, hash, (entry_str *)(e))));\
2705 es = ((hash->obj.header.flags & GRN_OBJ_KEY_VAR_SIZE)\
2706 ? ((entry_str *)(e))->size : hash->key_size); \
2712 #define COMPARE_VAL_(ap,as,bp,bs)\
2715 (grn_obj *)hash, (void *)(ap), as,\
2716 (grn_obj *)hash, (void *)(bp), bs, arg->compar_arg)\
2717 : ((arg->flags & GRN_TABLE_SORT_AS_NUMBER)\
2718 ? ((arg->flags & GRN_TABLE_SORT_AS_UNSIGNED)\
2719 ? ((arg->flags & GRN_TABLE_SORT_AS_INT64)\
2720 ? *((uint64_t *)(ap)) > *((uint64_t *)(bp))\
2721 : *((uint32_t *)(ap)) > *((uint32_t *)(bp)))\
2722 : ((arg->flags & GRN_TABLE_SORT_AS_INT64)\
2723 ? *((int64_t *)(ap)) > *((int64_t *)(bp))\
2724 : *((int32_t *)(ap)) > *((int32_t *)(bp))))\
2725 : grn_str_greater(ap, as, bp, bs)))
2727 #define COMPARE_VAL(ap,as,bp,bs)\
2728 ((dir) ? COMPARE_VAL_((bp),(bs),(ap),(as)) : COMPARE_VAL_((ap),(as),(bp),(bs)))
2730 inline static entry **
2735 const uint8_t *cp, *ep;
2736 entry **head, **tail, *e, *c;
2738 for (
id = m >> 1;;
id = (
id == m) ? 1 :
id + 1) {
2739 if (grn_hash_bitmap_at(ctx, hash,
id)) {
break; }
2741 c = grn_hash_entry_at(ctx, hash,
id, 0);
2742 if (!c) {
return NULL; }
2749 id = (
id == m) ? 1 :
id + 1;
2750 }
while (!grn_hash_bitmap_at(ctx, hash,
id));
2751 e = grn_hash_entry_at(ctx, hash,
id, 0);
2752 if (!e) {
return NULL; }
2761 return *hash->
n_entries > 2 ? head : NULL;
2765 swap(entry **a, entry **
b)
2772 #define SWAP(a,ap,as,b,bp,bs) do {\
2773 const uint8_t *cp_ = ap;\
2780 inline static entry **
2784 const uint8_t *bp, *cp, *ep;
2785 uint32_t bs, cs, es;
2790 SWAP(b, bp, bs, e, ep, es);
2792 if (d < 2) {
return NULL; }
2796 SWAP(b, bp, bs, c, cp, cs);
2799 SWAP(c, cp, cs, e, ep, es);
2802 if (d < 3) {
return NULL; }
2816 if (b >= e) {
break; }
2817 SWAP(b, bp, bs, e, ep, es);
2819 SWAP(c, cp, cs, e, ep, es);
2824 _sort(
grn_ctx *ctx, entry **head, entry **tail,
int limit,
2828 if (head < tail && (c = part(ctx, head, tail, arg, hash, dir))) {
2829 intptr_t rest = limit - 1 - (c - head);
2830 _sort(ctx, head, c - 1, limit, arg, hash, dir);
2831 if (rest > 0) { _sort(ctx, c + 1, tail, (
int)rest, arg, hash, dir); }
2839 entry **c = pack(ctx, hash, res, arg, dir);
2841 intptr_t rest = limit - 1 - (c - res);
2842 _sort(ctx, res, c - 1, limit, arg, hash, dir);
2844 _sort(ctx, c + 1, res + *hash->
n_entries - 1, (
int)rest, arg, hash, dir);
2854 #define PREPARE_VAL32(id,e,ep) do {\
2856 (ep)->v = (arg->flags & GRN_TABLE_SORT_BY_ID)\
2858 : (*((int32_t *)((byte *)((arg->flags & GRN_TABLE_SORT_BY_VALUE)\
2859 ? get_value(hash, (e))\
2860 : get_key(ctx, hash, (e))) + arg->offset)));\
2863 #define COMPARE_VAL32_(ap,bp) \
2866 (grn_obj *)hash, (void *)&(ap)->v, sizeof(uint32_t),\
2867 (grn_obj *)hash, (void *)&(bp)->v, sizeof(uint32_t),\
2869 : ((arg->flags & GRN_TABLE_SORT_AS_NUMBER)\
2870 ? ((arg->flags & GRN_TABLE_SORT_AS_UNSIGNED)\
2871 ? *((uint32_t *)&(ap)->v) > *((uint32_t *)&(bp)->v)\
2872 : *((int32_t *)&(ap)->v) > *((int32_t *)&(bp)->v))\
2873 : memcmp(&(ap)->v, &(bp)->v, sizeof(uint32_t)) > 0))
2875 #define COMPARE_VAL32(ap,bp)\
2876 ((dir) ? COMPARE_VAL32_((bp),(ap)) : COMPARE_VAL32_((ap),(bp)))
2878 inline static val32 *
2883 val32 *head, *tail, cr, er;
2885 for (
id = m >> 1;;
id = (
id == m) ? 1 :
id + 1) {
2886 if (grn_hash_bitmap_at(ctx, hash,
id)) {
break; }
2888 c = grn_hash_entry_at(ctx, hash,
id, 0);
2889 if (!c) {
return NULL; }
2896 id = (
id == m) ? 1 :
id + 1;
2897 }
while (!grn_hash_bitmap_at(ctx, hash,
id));
2898 e = grn_hash_entry_at(ctx, hash,
id, 0);
2899 if (!e) {
return NULL; }
2908 return *hash->
n_entries > 2 ? head : NULL;
2911 #define SWAP_VAL32(ap,bp) do {\
2917 inline static val32 *
2924 if (d < 2) {
return NULL; }
2931 if (d < 3) {
return NULL; }
2938 if (b >= e) {
break; }
2950 if (head < tail && (c = part_val32(ctx, head, tail, arg, hash, dir))) {
2951 intptr_t rest = limit - 1 - (c - head);
2952 _sort_val32(ctx, head, c - 1, limit, arg, hash, dir);
2953 if (rest > 0) { _sort_val32(ctx, c + 1, tail, (
int)rest, arg, hash, dir); }
2961 val32 *c = pack_val32(ctx, hash, res, arg, dir);
2963 intptr_t rest = limit - 1 - (c - res);
2964 _sort_val32(ctx, res, c - 1, limit, arg, hash, dir);
2966 _sort_val32(ctx, c + 1, res + *hash->
n_entries - 1, (
int)rest, arg, hash, dir);
2976 uint32_t
i, h = e->
key, s = grn_hash_calculate_step(h);
2977 for (i = h; ; i += s) {
2978 if (!(ep = grn_hash_idx_at(ctx, hash, i))) {
return GRN_ID_NIL; }
2979 if (!(
id = *ep)) {
break; }
2981 e2 = grn_hash_entry_at(ctx, hash,
id, 0);
2983 if (e2 == e) {
break; }
2994 if (!result || !*hash->
n_entries) {
return 0; }
3014 && hash->
key_size ==
sizeof(uint32_t))) {
3015 if (
sizeof(entry *) !=
sizeof(
val32)) {
3022 sort_val32(ctx, hash, (
val32 *)res, limit, optarg, dir);
3027 for (i = 0; i < limit; i++, rp++) {
3029 if (!(*v = rp->
id)) {
break; }
3035 sort(ctx, hash, res, limit, optarg, dir);
3039 sort(ctx, hash, res, limit, &opt, 0);
3045 for (i = 0; i < limit; i++, rp++) {
3047 if (!(*v = entry2id(ctx, hash, *rp))) {
break; }
3094 #ifdef USE_GRN_INDEX2
3100 grn_rec_unit subrec_unit,
int subrec_size,
unsigned int max_n_subrecs)
3106 subrec_size -= record_size;
3111 rc = grn_tiny_hash_init(ctx, hash, NULL, record_size,
3115 rc = grn_io_hash_init(ctx, hash, NULL, record_size,
3119 if (rc) {
return rc; }
3120 hash->record_unit = record_unit;
3121 hash->subrec_unit = subrec_unit;
3122 hash->subrec_size = subrec_size;
3123 hash->max_n_subrecs = max_n_subrecs;
3131 if (grn_hash_is_io_hash(hash)) {
3135 rc = grn_tiny_hash_fin(ctx, hash);
3141 subrecs_push(
byte *subrecs,
int size,
int n_subrecs,
int score,
void *body,
int dir)
3145 int n = n_subrecs - 1, n2;
3154 *((
int *)v) = score;
3159 subrecs_replace_min(
byte *subrecs,
int size,
int n_subrecs,
int score,
void *body,
int dir)
3162 int n = 0, n1, n2, *c1, *c2;
3195 int limit = s->max_n_subrecs;
3199 int ssize = s->subrec_size;
3201 if (limit < n_subrecs) {
3203 subrecs_replace_min(ri->
subrecs, ssize, limit, score, body, dir);
3206 subrecs_push(ri->
subrecs, ssize, n_subrecs, score, body, dir);
3212 grn_rhash_group(
grn_hash *s,
int limit, grn_group_optarg *optarg)
3220 byte *key, *ekey, *gkey = NULL;
3223 if (!s || !s->
index) {
return NULL; }
3226 rsize = optarg->key_size;
3227 funcp = optarg->func ? 1 : 0;
3228 dir = (optarg->mode == grn_sort_ascending) ? -1 : 1;
3242 if (s->
key_size <= rsize) {
return NULL; }
3252 if (grn_rhash_init(ctx, g, unit, rsize, s->record_unit, s->
key_size, limit)) {
3261 if (optarg->func((grn_records *)s,
3262 (grn_recordh *)(intptr_t)rh, gkey, optarg->func_arg)) {
continue; }
3270 if (
grn_hash_add(ctx, g, gkey, rsize, (
void **)&gri, NULL)) {
3271 grn_rhash_add_subrec(g, gri, ri->
score, ekey, dir);
3276 grn_rhash_fin(s->
ctx, s);
3283 grn_id *rid,
int *section,
int *pos,
int *score,
void **subrec)
3293 ee = grn_hash_entry_at(ctx, s, rh, 0);
3296 ri = get_value(s, ee);
3300 p = (
int *)(ri->
subrecs + index * unit_size);
3301 if (score) { *score = p[0]; }
3302 if (subrec) { *subrec = &p[1]; }
3303 switch (s->record_unit) {
3305 if (rid) { *rid = pi->
rid; }
3306 if (section) { *section = (s->subrec_unit !=
grn_rec_userdef) ? p[1] : 0; }
3310 if (rid) { *rid = pi->
rid; }
3311 if (section) { *section = pi->
sid; }
3316 switch (s->subrec_unit) {
3318 if (rid) { *rid = pi->
rid; }
3319 if (section) { *section = 0; }
3320 if (pos) { *pos = 0; }
3323 if (rid) { *rid = pi->
rid; }
3324 if (section) { *section = pi->
sid; }
3325 if (pos) { *pos = 0; }
3328 if (rid) { *rid = pi->
rid; }
3329 if (section) { *section = pi->
sid; }
3330 if (pos) { *pos = pi->
pos; }
3333 if (rid) { *rid = 0; }
3334 if (section) { *section = 0; }
3335 if (pos) { *pos = 0; }