1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424
|
/*
Copyright (C) 2009-2018 Brazil
Copyright (C) 2018-2022 Sutou Kouhei <kou@clear-code.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#include "grn.h"
#include "grn_ii_select_cursor.h"
#include "grn_io.h"
#include "grn_table_module.h"
#ifdef __cplusplus
extern "C" {
#endif
/**** grn_tiny_array ****/
/*
* grn_tiny_array_init() accepts a logical OR of the following flags.
* Note that other flags, such as (1 << 30), will be ignored.
*
* - GRN_TINY_ARRAY_CLEAR specifies to initialize a new block with zeros.
* It is valid only iff specified with GRN_TINY_ARRAY_USE_MALLOC.
* - GRN_TINY_ARRAY_THREADSAFE specifies to create a critical section when
* allocating memory.
* - GRN_TINY_ARRAY_USE_MALLOC specifies to use GRN_MALLOC/CALLOC/FREE instead
* of GRN_CTX_ALLOC/FREE.
*/
#define GRN_TINY_ARRAY_CLEAR (1 << 0)
#define GRN_TINY_ARRAY_THREADSAFE (1 << 1)
#define GRN_TINY_ARRAY_USE_MALLOC (1 << 2)
/*
* - GRN_TINY_ARRAY_FACTOR is the global parameter of grn_tiny_array.
* - GRN_TINY_ARRAY_GET_OFFSET() returns the offset of a specified block.
* - GRN_TINY_ARRAY_BASE_BLOCK_SIZE is the number of elements in the first
* block.
* - GRN_TINY_ARRAY_GET_BLOCK_SIZE() returns the number of elements in a
* specified block.
* - GRN_TINY_ARRAY_NUM_BLOCKS is the maximum number of blocks.
*/
#define GRN_TINY_ARRAY_FACTOR 0
#define GRN_TINY_ARRAY_GET_OFFSET(block_id) \
(1 << ((block_id) << GRN_TINY_ARRAY_FACTOR))
#define GRN_TINY_ARRAY_BASE_BLOCK_SIZE \
(GRN_TINY_ARRAY_GET_OFFSET(1) - GRN_TINY_ARRAY_GET_OFFSET(0))
#define GRN_TINY_ARRAY_GET_BLOCK_SIZE(block_id) \
(GRN_TINY_ARRAY_BASE_BLOCK_SIZE * GRN_TINY_ARRAY_GET_OFFSET(block_id))
#define GRN_TINY_ARRAY_NUM_BLOCKS (32 >> GRN_TINY_ARRAY_FACTOR)
/*
* grn_tiny_array uses several blocks to emulate an array.
* The k-th block, blocks[k - 1], consists of 2^(k-1) elements.
*/
typedef struct _grn_tiny_array grn_tiny_array;
struct _grn_tiny_array {
grn_ctx *ctx;
grn_id max;
uint16_t element_size;
uint16_t flags;
void *blocks[GRN_TINY_ARRAY_NUM_BLOCKS];
grn_critical_section lock;
};
#define GRN_TINY_ARRAY_EACH(array, head, tail, key, value, block) do { \
int _block_id; \
const grn_id _head = (head); \
const grn_id _tail = (tail); \
for (_block_id = 0, (key) = (_head); \
_block_id < GRN_TINY_ARRAY_NUM_BLOCKS && (key) <= (_tail); \
_block_id++) { \
int _id = GRN_TINY_ARRAY_GET_BLOCK_SIZE(_block_id); \
(value) = (array)->blocks[_block_id]; \
if (value) { \
while (_id-- && (key) <= (_tail)) { \
{ \
block \
} \
(key)++; \
(value) = (void *)((byte *)(value) + (array)->element_size); \
} \
} else { \
(key) += _id; \
} \
} \
} while (0)
#define GRN_TINY_ARRAY_EACH_BEGIN(array, head, tail, value) do { \
int _block_id; \
const grn_id _head = (head); \
const grn_id _tail = (tail); \
grn_id _current = _head; \
for (_block_id = 0; \
_block_id < GRN_TINY_ARRAY_NUM_BLOCKS && _current <= _tail; \
_block_id++) { \
int _n_elements = GRN_TINY_ARRAY_GET_BLOCK_SIZE(_block_id); \
uint8_t *_block = (array)->blocks[_block_id]; \
if (_block) { \
int _i; \
for (_i = 0; \
_i < _n_elements && _current <= _tail; \
_i++, _current++) { \
void *value = _block + (array)->element_size * _i; \
#define GRN_TINY_ARRAY_EACH_END() \
} \
} else { \
_current += _n_elements; \
} \
} \
} while (0)
GRN_API void grn_tiny_array_init(grn_ctx *ctx, grn_tiny_array *array,
uint16_t element_size, uint16_t flags);
GRN_API void grn_tiny_array_fin(grn_tiny_array *array);
GRN_API void *grn_tiny_array_at(grn_tiny_array *array, grn_id id);
GRN_API grn_id grn_tiny_array_id(grn_tiny_array *array,
const void *element_address);
/**** grn_tiny_bitmap ****/
typedef struct _grn_tiny_bitmap grn_tiny_bitmap;
struct _grn_tiny_bitmap {
grn_ctx *ctx;
void *blocks[GRN_TINY_ARRAY_NUM_BLOCKS];
};
/**** grn_array ****/
#define GRN_ARRAY_TINY (0x01<<6)
/*
* grn_array uses grn_io or grn_tiny_array to represent an array.
*
* To create a grn_tiny_array-based grn_array, specify the GRN_ARRAY_TINY flag
* to grn_array_create(). Note that a grn_tiny_array-based grn_array is not
* backed by a file.
*/
struct _grn_array {
grn_db_obj obj;
grn_ctx *ctx;
uint32_t value_size;
size_t n_keys;
grn_table_sort_key *keys;
uint32_t *n_garbages;
uint32_t *n_entries;
/* For grn_io_array. */
grn_io *io;
struct grn_array_header *header;
uint32_t *lock;
bool wal_touched;
/* For grn_tiny_array. */
uint32_t n_garbages_buf;
uint32_t n_entries_buf;
grn_id garbages;
grn_tiny_array array;
grn_tiny_bitmap bitmap;
};
struct _grn_array_cursor {
grn_db_obj obj;
grn_array *array;
grn_ctx *ctx;
grn_id curr_rec;
grn_id tail;
unsigned int rest;
int dir;
};
/*
* grn_array_size() returns the number of entries in an array.
* If the array was truncated by another process but `array` still refers to
* the old one, this function returns 0.
*/
uint32_t grn_array_size(grn_ctx *ctx, grn_array *array);
uint32_t grn_array_get_flags(grn_ctx *ctx, grn_array *array);
grn_rc grn_array_truncate(grn_ctx *ctx, grn_array *array);
grn_rc grn_array_copy_sort_key(grn_ctx *ctx, grn_array *array,
grn_table_sort_key *keys, size_t n_keys);
grn_rc grn_array_wal_recover(grn_ctx *ctx, grn_array *array);
grn_rc grn_array_warm(grn_ctx *ctx, grn_array *array);
/**** grn_hash ****/
#define GRN_HASH_MAX_KEY_SIZE_NORMAL GRN_TABLE_MAX_KEY_SIZE
#define GRN_HASH_MAX_KEY_SIZE_LARGE (0xffff)
#define GRN_HASH_IS_LARGE_KEY(hash)\
((hash)->key_size > GRN_HASH_MAX_KEY_SIZE_NORMAL)
typedef struct _grn_hash_header_common grn_hash_header_common;
typedef struct _grn_hash_header_normal grn_hash_header_normal;
typedef struct _grn_hash_header_large grn_hash_header_large;
typedef struct _grn_hash_wal_add_entry_data grn_hash_wal_add_entry_data;
struct _grn_hash {
grn_db_obj obj;
grn_ctx *ctx;
uint32_t key_size;
grn_encoding encoding;
uint32_t value_size;
uint32_t entry_size;
uint32_t *n_garbages;
uint32_t *n_entries;
uint32_t *max_offset;
grn_table_module tokenizer;
grn_obj normalizers;
grn_obj token_filters;
/* For backward compatibility */
grn_obj token_filter_procs;
/* For grn_io_hash. */
grn_io *io;
union {
grn_hash_header_common *common;
grn_hash_header_normal *normal;
grn_hash_header_large *large;
} header;
uint32_t *lock;
// uint32_t nref;
// unsigned int max_n_subrecs;
// unsigned int record_size;
// unsigned int subrec_size;
// grn_rec_unit record_unit;
// grn_rec_unit subrec_unit;
// uint8_t arrayp;
// grn_recordh *curr_rec;
// grn_set_cursor *cursor;
// int limit;
// void *userdata;
// grn_id subrec_id;
/* For grn_tiny_hash. */
uint32_t max_offset_;
uint32_t n_garbages_;
uint32_t n_entries_;
grn_id *index;
grn_id garbages;
grn_tiny_array a;
grn_tiny_bitmap bitmap;
grn_hash_wal_add_entry_data *wal_data;
};
#define GRN_HASH_HEADER_COMMON_FIELDS\
uint32_t flags;\
grn_encoding encoding;\
uint32_t key_size;\
uint32_t value_size;\
grn_id tokenizer;\
uint32_t curr_rec;\
uint32_t curr_key_normal;\
uint32_t idx_offset;\
uint32_t entry_size;\
uint32_t max_offset;\
uint32_t n_entries;\
uint32_t n_garbages;\
uint32_t lock;\
grn_id normalizer;\
uint32_t truncated;\
uint64_t curr_key_large;\
uint64_t wal_id;\
uint32_t reserved[10]
struct _grn_hash_header_common {
GRN_HASH_HEADER_COMMON_FIELDS;
};
struct _grn_hash_header_normal {
GRN_HASH_HEADER_COMMON_FIELDS;
grn_id garbages[GRN_HASH_MAX_KEY_SIZE_NORMAL];
};
struct _grn_hash_header_large {
GRN_HASH_HEADER_COMMON_FIELDS;
grn_id garbages[GRN_HASH_MAX_KEY_SIZE_LARGE];
};
struct _grn_hash_cursor {
grn_db_obj obj;
grn_hash *hash;
grn_ctx *ctx;
grn_id curr_rec;
grn_id tail;
unsigned int rest;
int dir;
};
/* deprecated */
#define GRN_TABLE_SORT_BY_KEY 0
#define GRN_TABLE_SORT_BY_ID (1L<<1)
#define GRN_TABLE_SORT_BY_VALUE (1L<<2)
#define GRN_TABLE_SORT_RES_ID 0
#define GRN_TABLE_SORT_RES_KEY (1L<<3)
#define GRN_TABLE_SORT_AS_BIN 0
#define GRN_TABLE_SORT_AS_NUMBER (1L<<4)
#define GRN_TABLE_SORT_AS_SIGNED 0
#define GRN_TABLE_SORT_AS_UNSIGNED (1L<<5)
#define GRN_TABLE_SORT_AS_INT32 0
#define GRN_TABLE_SORT_AS_INT64 (1L<<6)
#define GRN_TABLE_SORT_NO_PROC 0
#define GRN_TABLE_SORT_WITH_PROC (1L<<7)
typedef struct _grn_table_sort_optarg grn_table_sort_optarg;
struct _grn_table_sort_optarg {
grn_table_sort_flags flags;
int (*compar)(grn_ctx *ctx,
grn_obj *table1, void *target1, unsigned int target1_size,
grn_obj *table2, void *target2, unsigned int target2_size,
void *compare_arg);
void *compar_arg;
grn_obj *proc;
int offset;
};
void grn_hash_init_from_env(void);
GRN_API int grn_hash_sort(grn_ctx *ctx, grn_hash *hash, int limit,
grn_array *result, grn_table_sort_optarg *optarg);
grn_rc grn_hash_lock(grn_ctx *ctx, grn_hash *hash, int timeout);
grn_rc grn_hash_unlock(grn_ctx *ctx, grn_hash *hash);
grn_rc grn_hash_clear_lock(grn_ctx *ctx, grn_hash *hash);
#define GRN_HASH_SIZE(hash) (*((hash)->n_entries))
/* private */
typedef enum {
GRN_REC_DOCUMENT = 0,
GRN_REC_SECTION,
GRN_REC_POSITION,
GRN_REC_USERDEF,
GRN_REC_NONE
} grn_rec_unit;
GRN_API grn_rc grn_hash_truncate(grn_ctx *ctx, grn_hash *hash);
int grn_rec_unit_size(grn_rec_unit unit, int rec_size);
const char * _grn_hash_key(grn_ctx *ctx, grn_hash *hash, grn_id id, uint32_t *key_size);
grn_rc
grn_hash_add_table_cursor(grn_ctx *ctx,
grn_hash *hash,
grn_table_cursor *cursor,
double score,
grn_operator op);
grn_rc
grn_hash_add_index_cursor(grn_ctx *ctx,
grn_hash *hash,
grn_obj *cursor,
double additional_score,
double weight,
grn_operator op);
grn_rc
grn_hash_add_ii_cursor(grn_ctx *ctx,
grn_hash *hash,
grn_ii_cursor *cursor,
double additional_score,
double weight,
grn_operator op);
grn_rc
grn_hash_add_ii_select_cursor(grn_ctx *ctx,
grn_hash *hash,
grn_ii_select_cursor *cursor,
grn_operator op);
int grn_hash_get_key_value(grn_ctx *ctx, grn_hash *hash, grn_id id,
void *keybuf, int bufsize, void *valuebuf);
int _grn_hash_get_key_value(grn_ctx *ctx, grn_hash *hash, grn_id id,
void **key, void **value);
grn_id grn_hash_next(grn_ctx *ctx, grn_hash *hash, grn_id id);
/* only valid for hash tables, GRN_OBJ_KEY_VAR_SIZE && GRN_HASH_TINY */
const char *_grn_hash_strkey_by_val(void *v, uint16_t *size);
const char *grn_hash_get_value_(grn_ctx *ctx, grn_hash *hash, grn_id id, uint32_t *size);
grn_rc grn_hash_remove(grn_ctx *ctx, const char *path);
grn_rc grn_array_remove(grn_ctx *ctx, const char *path);
grn_id grn_hash_at(grn_ctx *ctx, grn_hash *hash, grn_id id);
grn_id grn_array_at(grn_ctx *ctx, grn_array *array, grn_id id);
void grn_hash_check(grn_ctx *ctx, grn_hash *hash);
bool grn_hash_is_large_total_key_size(grn_ctx *ctx, grn_hash *hash);
uint64_t grn_hash_total_key_size(grn_ctx *ctx, grn_hash *hash);
uint64_t grn_hash_max_total_key_size(grn_ctx *ctx, grn_hash *hash);
grn_rc grn_hash_wal_recover(grn_ctx *ctx, grn_hash *hash);
grn_rc grn_hash_warm(grn_ctx *ctx, grn_hash *hash);
#ifdef __cplusplus
}
#endif
|