18 #include <sys/types.h>
33 const uint32_t FILE_ID_LENGTH = 3;
35 class CriticalSection {
37 CriticalSection() : lock_(NULL) {}
38 explicit CriticalSection(grn_critical_section *lock) : lock_(lock) {
39 CRITICAL_SECTION_ENTER(*lock_);
45 void enter(grn_critical_section *lock) {
51 CRITICAL_SECTION_LEAVE(*lock_);
57 grn_critical_section *lock_;
60 CriticalSection(
const CriticalSection &);
61 CriticalSection &operator=(
const CriticalSection &);
70 grn_dat_remove_file(
grn_ctx *ctx,
const char *path)
73 return !::stat(path, &stat) && !unlink(path);
115 CRITICAL_SECTION_INIT(dat->
lock);
121 CRITICAL_SECTION_FIN(dat->
lock);
137 grn_dat_generate_trie_path(
const char *base_path,
char *trie_path, uint32_t file_id)
139 if (!base_path || !base_path[0]) {
143 const size_t len = std::strlen(base_path);
144 std::memcpy(trie_path, base_path, len);
145 trie_path[len] =
'.';
146 grn_itoh(file_id % (1U << (4 * FILE_ID_LENGTH)),
147 trie_path + len + 1, FILE_ID_LENGTH);
148 trie_path[len + 1 + FILE_ID_LENGTH] =
'\0';
160 if (!file_id || (dat->
trie && (file_id <= dat->file_id))) {
168 CriticalSection critical_section(&dat->
lock);
170 if (dat->
trie && (file_id <= dat->file_id)) {
179 grn_dat_generate_trie_path(
grn_io_path(dat->
io), trie_path, file_id);
184 MERR(
"new grn::dat::Trie failed");
189 new_trie->
open(trie_path);
191 ERR(grn_dat_translate_error_code(ex.
code()),
192 "grn::dat::Trie::open failed");
198 dat->
trie = new_trie;
201 critical_section.leave();
205 grn_dat_generate_trie_path(
grn_io_path(dat->
io), trie_path, file_id - 2);
206 grn_dat_remove_file(ctx, trie_path);
214 MERR(
"new grn::dat::Trie failed");
221 grn_dat_generate_trie_path(
grn_io_path(dat->
io), trie_path, file_id + 1);
225 ERR(grn_dat_translate_error_code(ex.
code()),
226 "grn::dat::Trie::open failed");
233 dat->
trie = new_trie;
239 grn_dat_generate_trie_path(
grn_io_path(dat->
io), trie_path, file_id - 1);
240 grn_dat_remove_file(ctx, trie_path);
267 uint32_t, uint32_t flags)
270 if (path[0] ==
'\0') {
272 }
else if (std::strlen(path) >= (
PATH_MAX - (FILE_ID_LENGTH + 1))) {
282 grn_dat_init(ctx, dat);
295 grn_dat_remove_file(ctx, path);
324 if (path && (std::strlen(path) >= (
PATH_MAX - (FILE_ID_LENGTH + 1)))) {
334 grn_dat_init(ctx, dat);
365 grn_dat_fin(ctx, dat);
391 grn_dat_generate_trie_path(path, trie_path, file_id + 1);
392 grn_dat_remove_file(ctx, trie_path);
393 for (uint32_t
i = file_id;
i > 0; --
i) {
394 grn_dat_generate_trie_path(path, trie_path,
i);
395 if (!grn_dat_remove_file(ctx, trie_path)) {
408 unsigned int key_size,
void **)
410 if (!grn_dat_open_trie_if_needed(ctx, dat)) {
419 if (trie->
search(key, key_size, &key_pos)) {
423 ERR(grn_dat_translate_error_code(ex.
code()),
424 "grn::dat::Trie::search failed");
431 unsigned int key_size,
void **,
int *added)
435 }
else if (!grn_dat_open_trie_if_needed(ctx, dat)) {
441 grn_dat_generate_trie_path(
grn_io_path(dat->
io), trie_path, 1);
444 MERR(
"new grn::dat::Trie failed");
448 new_trie->
create(trie_path);
450 ERR(grn_dat_translate_error_code(ex.
code()),
451 "grn::dat::Trie::create failed");
455 dat->
trie = new_trie;
462 const bool res = trie->
insert(key, key_size, &key_pos);
464 *added = res ? 1 : 0;
468 if (!grn_dat_rebuild_trie(ctx, dat)) {
473 const bool res = new_trie->
insert(key, key_size, &key_pos);
475 *added = res ? 1 : 0;
479 ERR(grn_dat_translate_error_code(ex.
code()),
480 "grn::dat::Trie::insert failed");
488 if (!grn_dat_open_trie_if_needed(ctx, dat)) {
499 if (keybuf && (bufsize >= (
int)key.
length())) {
500 std::memcpy(keybuf, key.
ptr(), key.
length());
508 if (!grn_dat_open_trie_if_needed(ctx, dat)) {
520 bulk->
u.
b.head =
static_cast<char *
>(
const_cast<void *
>(key.
ptr()));
521 bulk->
u.
b.curr = bulk->
u.
b.head + key.
length();
532 if (!grn_dat_open_trie_if_needed(ctx, dat)) {
538 if (optarg && optarg->
func) {
542 }
else if (!optarg->
func(ctx, reinterpret_cast<grn_obj *>(dat),
id, optarg->
func_arg)) {
553 ERR(grn_dat_translate_error_code(ex.
code()),
554 "grn::dat::Trie::remove failed");
564 if (!grn_dat_open_trie_if_needed(ctx, dat)) {
566 }
else if (!dat->
trie || !key || !key_size) {
570 if (optarg && optarg->
func) {
574 if (!trie->
search(key, key_size, &key_pos)) {
576 }
else if (!optarg->
func(ctx, reinterpret_cast<grn_obj *>(dat),
581 ERR(grn_dat_translate_error_code(ex.
code()),
582 "grn::dat::Trie::search failed");
589 if (!trie->
remove(key, key_size)) {
593 ERR(grn_dat_translate_error_code(ex.
code()),
594 "grn::dat::Trie::remove failed");
602 const void *dest_key,
unsigned int dest_key_size)
604 if (!dest_key_size) {
606 }
else if (!grn_dat_open_trie_if_needed(ctx, dat)) {
608 }
else if (!dat->
trie) {
614 if (!trie->
update(src_key_id, dest_key, dest_key_size)) {
618 if (!grn_dat_rebuild_trie(ctx, dat)) {
622 if (!trie->
update(src_key_id, dest_key, dest_key_size)) {
627 ERR(grn_dat_translate_error_code(ex.
code()),
628 "grn::dat::Trie::update failed");
636 const void *src_key,
unsigned int src_key_size,
637 const void *dest_key,
unsigned int dest_key_size)
639 if (!dest_key_size) {
641 }
else if (!grn_dat_open_trie_if_needed(ctx, dat)) {
643 }
else if (!dat->
trie) {
649 if (!trie->
update(src_key, src_key_size, dest_key, dest_key_size)) {
653 if (!grn_dat_rebuild_trie(ctx, dat)) {
657 if (!trie->
update(src_key, src_key_size, dest_key, dest_key_size)) {
662 ERR(grn_dat_translate_error_code(ex.
code()),
663 "grn::dat::Trie::update failed");
672 unsigned int max_num_scan_hits,
const char **str_rest)
674 if (!grn_dat_open_trie_if_needed(ctx, dat) || !str ||
684 if (!max_num_scan_hits || !str_size) {
691 unsigned int num_scan_hits = 0;
698 if (!normalized_string) {
699 fprintf(stderr,
"error: grn_string_open() failed!\n");
704 unsigned int offset = 0;
708 if (trie->
lcp_search(str, str_size, &key_pos)) {
711 if ((key_length == str_size) || (checks[key_length])) {
712 unsigned int length = 0;
718 scan_hits[num_scan_hits].
id = key.
id();
719 scan_hits[num_scan_hits].
offset = offset;
720 scan_hits[num_scan_hits].
length = length;
723 str_size -= key_length;
724 checks += key_length;
725 if (++num_scan_hits >= max_num_scan_hits) {
745 const char *
const begin = str;
748 if (trie->
lcp_search(str, str_size, &key_pos)) {
750 scan_hits[num_scan_hits].
id = key.
id();
751 scan_hits[num_scan_hits].
offset = str - begin;
755 if (++num_scan_hits >= max_num_scan_hits) {
759 const int char_length =
grn_charlen(ctx, str, str + str_size);
762 str_size -= char_length;
774 ERR(grn_dat_translate_error_code(ex.
code()),
775 "grn::dat::lcp_search failed");
778 return static_cast<int>(num_scan_hits);
783 const void *key,
unsigned int key_size)
785 if (!grn_dat_open_trie_if_needed(ctx, dat) || !key ||
797 if (!trie->
lcp_search(key, key_size, &key_pos)) {
802 ERR(grn_dat_translate_error_code(ex.
code()),
803 "grn::dat::PrefixCursor::open failed");
811 if (!grn_dat_open_trie_if_needed(ctx, dat)) {
823 const void *min,
unsigned int min_size,
824 const void *max,
unsigned int max_size,
825 int offset,
int limit,
int flags)
827 if (!grn_dat_open_trie_if_needed(ctx, dat)) {
836 grn_dat_cursor_init(ctx, dc);
846 grn_dat_cursor_init(ctx, dc);
851 min, min_size, max, max_size, offset, limit,
857 if (max && max_size) {
860 NULL, min_size, max, max_size, offset, limit,
865 }
else if (min && min_size) {
870 min, min_size, NULL, 0, offset, limit,
878 min, min_size, max, max_size, offset, limit,
885 ERR(grn_dat_translate_error_code(ex.
code()),
886 "grn::dat::CursorFactory::open failed");
911 ERR(grn_dat_translate_error_code(ex.
code()),
912 "grn::dat::Cursor::next failed");
922 grn_dat_cursor_fin(ctx, c);
933 *key = key_ref.
ptr();
934 return (
int)key_ref.
length();
946 }
else if (!grn_dat_open_trie_if_needed(ctx, c->
dat)) {
958 ERR(grn_dat_translate_error_code(ex.
code()),
959 "grn::dat::Trie::remove failed");
968 if (!grn_dat_open_trie_if_needed(ctx, dat)) {
981 if (!grn_dat_open_trie_if_needed(ctx, dat)) {
994 const grn_rc error_code = grn_dat_translate_error_code(ex.
code());
995 ERR(error_code,
"grn::dat::Trie::create failed");
999 if (!grn_dat_open_trie_if_needed(ctx, dat)) {
1008 if (!grn_dat_open_trie_if_needed(ctx, dat)) {
1019 *key_size = key.
length();
1020 return static_cast<const char *
>(key.
ptr());
1026 if (!grn_dat_open_trie_if_needed(ctx, dat)) {
1033 while (id < trie->max_key_id()) {
1044 if (!grn_dat_open_trie_if_needed(ctx, dat)) {
1061 if (!grn_dat_open_trie_if_needed(ctx, dat)) {
1075 if (!grn_dat_open_trie_if_needed(ctx, dat)) {
1088 const grn_rc error_code = grn_dat_translate_error_code(ex.
code());
1089 ERR(error_code,
"grn::dat::Trie::create failed");
1093 if (!grn_dat_open_trie_if_needed(ctx, dat)) {