Groonga 3.0.9 Source Code Document
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
trie.cpp
Go to the documentation of this file.
1 /* -*- c-basic-offset: 2 -*- */
2 /* Copyright(C) 2011 Brazil
3 
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Lesser General Public
6  License version 2.1 as published by the Free Software Foundation.
7 
8  This library is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  Lesser General Public License for more details.
12 
13  You should have received a copy of the GNU Lesser General Public
14  License along with this library; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 #include "trie.hpp"
19 
20 #include <algorithm>
21 #include <cstring>
22 
23 #include "vector.hpp"
24 
25 namespace grn {
26 namespace dat {
27 namespace {
28 
29 class StatusFlagManager {
30  public:
31  StatusFlagManager(Header *header, UInt32 status_flag)
32  : header_(header), status_flag_(status_flag) {
33  header_->set_status_flags(header_->status_flags() | status_flag_);
34  }
35  ~StatusFlagManager() {
36  header_->set_status_flags(header_->status_flags() & ~status_flag_);
37  }
38 
39  private:
40  Header *header_;
42 
43  // Disallows copy and assignment.
44  StatusFlagManager(const StatusFlagManager &);
45  StatusFlagManager &operator=(const StatusFlagManager &);
46 };
47 
48 } // namespace
49 
51  : file_(),
52  header_(NULL),
53  nodes_(),
54  blocks_(),
55  entries_(),
56  key_buf_() {}
57 
59 
60 void Trie::create(const char *file_name,
61  UInt64 file_size,
62  UInt32 max_num_keys,
63  double num_nodes_per_key,
64  double average_key_length) {
65  GRN_DAT_THROW_IF(PARAM_ERROR, (file_size != 0) && (max_num_keys != 0));
66 
67  if (num_nodes_per_key < 1.0) {
68  num_nodes_per_key = DEFAULT_NUM_NODES_PER_KEY;
69  }
70  GRN_DAT_THROW_IF(PARAM_ERROR, num_nodes_per_key < 1.0);
71 
72  if (average_key_length < 1.0) {
73  average_key_length = DEFAULT_AVERAGE_KEY_LENGTH;
74  }
75  GRN_DAT_THROW_IF(PARAM_ERROR, average_key_length < 1.0);
76  GRN_DAT_THROW_IF(PARAM_ERROR, average_key_length > MAX_KEY_LENGTH);
77 
78  if (max_num_keys == 0) {
79  if (file_size == 0) {
80  file_size = DEFAULT_FILE_SIZE;
81  } else {
84  }
85  } else {
86  GRN_DAT_THROW_IF(PARAM_ERROR, max_num_keys > MAX_NUM_KEYS);
87  }
88 
89  Trie new_trie;
90  new_trie.create_file(file_name, file_size, max_num_keys,
91  num_nodes_per_key, average_key_length);
92  new_trie.swap(this);
93 }
94 
95 void Trie::create(const Trie &trie,
96  const char *file_name,
97  UInt64 file_size,
98  UInt32 max_num_keys,
99  double num_nodes_per_key,
100  double average_key_length) {
101  GRN_DAT_THROW_IF(PARAM_ERROR, (file_size != 0) && (max_num_keys != 0));
102 
103  if (num_nodes_per_key < 1.0) {
104  if (trie.num_keys() == 0) {
105  num_nodes_per_key = DEFAULT_NUM_NODES_PER_KEY;
106  } else {
107  num_nodes_per_key = 1.0 * trie.num_nodes() / trie.num_keys();
108  }
109  }
110  GRN_DAT_THROW_IF(PARAM_ERROR, num_nodes_per_key < 1.0);
111 
112  if (average_key_length < 1.0) {
113  if (trie.num_keys() == 0) {
114  average_key_length = DEFAULT_AVERAGE_KEY_LENGTH;
115  } else {
116  average_key_length = 1.0 * trie.total_key_length() / trie.num_keys();
117  }
118  }
119  GRN_DAT_THROW_IF(PARAM_ERROR, average_key_length < 1.0);
120  GRN_DAT_THROW_IF(PARAM_ERROR, average_key_length > MAX_KEY_LENGTH);
121 
122  if (max_num_keys == 0) {
123  if (file_size == 0) {
124  file_size = trie.file_size();
125  }
128  GRN_DAT_THROW_IF(PARAM_ERROR, file_size < trie.virtual_size());
129  } else {
130  GRN_DAT_THROW_IF(PARAM_ERROR, max_num_keys < trie.num_keys());
131  GRN_DAT_THROW_IF(PARAM_ERROR, max_num_keys < trie.max_key_id());
132  GRN_DAT_THROW_IF(PARAM_ERROR, max_num_keys > MAX_NUM_KEYS);
133  }
134 
135  Trie new_trie;
136  new_trie.create_file(file_name, file_size, max_num_keys,
137  num_nodes_per_key, average_key_length);
138  new_trie.build_from_trie(trie);
139  new_trie.swap(this);
140 }
141 
142 void Trie::repair(const Trie &trie, const char *file_name) {
143  Trie new_trie;
144  new_trie.create_file(file_name, trie.file_size(), trie.max_num_keys(),
145  trie.max_num_blocks(), trie.key_buf_size());
146  new_trie.repair_trie(trie);
147  new_trie.swap(this);
148 }
149 
150 void Trie::open(const char *file_name) {
151  GRN_DAT_THROW_IF(PARAM_ERROR, file_name == NULL);
152 
153  Trie new_trie;
154  new_trie.open_file(file_name);
155  new_trie.swap(this);
156 }
157 
158 void Trie::close() {
159  Trie().swap(this);
160 }
161 
162 void Trie::swap(Trie *trie) {
163  file_.swap(&trie->file_);
164  std::swap(header_, trie->header_);
165  nodes_.swap(&trie->nodes_);
166  blocks_.swap(&trie->blocks_);
167  entries_.swap(&trie->entries_);
168  key_buf_.swap(&trie->key_buf_);
169 }
170 
171 void Trie::create_file(const char *file_name,
172  UInt64 file_size,
173  UInt32 max_num_keys,
174  double num_nodes_per_key,
175  double average_key_length) {
176  GRN_DAT_THROW_IF(PARAM_ERROR, (file_size == 0) && (max_num_keys == 0));
177  GRN_DAT_THROW_IF(PARAM_ERROR, (file_size != 0) && (max_num_keys != 0));
178  if (max_num_keys == 0) {
179  const UInt64 avail = file_size - sizeof(Header);
180  const double num_bytes_per_key = (sizeof(Node) * num_nodes_per_key)
181  + (1.0 * sizeof(Block) / BLOCK_SIZE * num_nodes_per_key)
182  + sizeof(Entry)
183  + sizeof(UInt32) + sizeof(UInt8) + average_key_length + 1.5;
184  if ((avail / num_bytes_per_key) > MAX_NUM_KEYS) {
185  max_num_keys = MAX_NUM_KEYS;
186  } else {
187  max_num_keys = (UInt32)(avail / num_bytes_per_key);
188  }
189  GRN_DAT_THROW_IF(PARAM_ERROR, max_num_keys == 0);
190  }
191 
193  {
194  const double max_num_nodes = num_nodes_per_key * max_num_keys;
195  GRN_DAT_THROW_IF(PARAM_ERROR, (max_num_nodes - 1.0) >= MAX_NUM_NODES);
196  max_num_blocks = ((UInt32)max_num_nodes + BLOCK_SIZE - 1) / BLOCK_SIZE;
197  GRN_DAT_THROW_IF(PARAM_ERROR, max_num_blocks == 0);
198  GRN_DAT_THROW_IF(PARAM_ERROR, max_num_blocks > MAX_NUM_BLOCKS);
199  }
200 
202  if (file_size == 0) {
203  const double total_key_length = average_key_length * max_num_keys;
205  (total_key_length - 1.0) >= MAX_TOTAL_KEY_LENGTH);
206 
207  // The last term is the estimated number of bytes that will be used for
208  // 32-bit alignment.
209  const UInt64 total_num_bytes = (UInt64)(total_key_length)
210  + (UInt64)(sizeof(UInt32) + sizeof(UInt8)) * max_num_keys
211  + (UInt32)(max_num_keys * 1.5);
213  (total_num_bytes / sizeof(UInt32)) >= MAX_KEY_BUF_SIZE);
214  key_buf_size = (UInt32)(total_num_bytes / sizeof(UInt32));
215 
216  file_size = sizeof(Header)
217  + (sizeof(Block) * max_num_blocks)
218  + (sizeof(Node) * BLOCK_SIZE * max_num_blocks)
219  + (sizeof(Entry) * max_num_keys)
220  + (sizeof(UInt32) * key_buf_size);
221  } else {
222  const UInt64 avail = file_size - sizeof(Header)
223  - (sizeof(Block) * max_num_blocks)
224  - (sizeof(Node) * BLOCK_SIZE * max_num_blocks)
225  - (sizeof(Entry) * max_num_keys);
226  GRN_DAT_THROW_IF(PARAM_ERROR, (avail / sizeof(UInt32)) > MAX_KEY_BUF_SIZE);
227  key_buf_size = (UInt32)(avail / sizeof(UInt32));
228  }
229 
230  create_file(file_name, file_size, max_num_keys,
231  max_num_blocks, key_buf_size);
232 }
233 
234 void Trie::create_file(const char *file_name,
235  UInt64 file_size,
236  UInt32 max_num_keys,
237  UInt32 max_num_blocks,
238  UInt32 key_buf_size) {
239  GRN_DAT_THROW_IF(PARAM_ERROR, file_size < (sizeof(Header)
240  + (sizeof(Block) * max_num_blocks)
241  + (sizeof(Node) * BLOCK_SIZE * max_num_blocks)
242  + (sizeof(Entry) * max_num_keys)
243  + (sizeof(UInt32) * key_buf_size)));
244 
245  file_.create(file_name, file_size);
246 
247  Header * const header = static_cast<Header *>(file_.ptr());
248  *header = Header();
249  header->set_file_size(file_size);
250  header->set_max_num_keys(max_num_keys);
251  header->set_max_num_blocks(max_num_blocks);
252  header->set_key_buf_size(key_buf_size);
253 
254  map_address(file_.ptr());
255 
256  reserve_node(ROOT_NODE_ID);
258 }
259 
260 void Trie::open_file(const char *file_name) {
261  GRN_DAT_THROW_IF(PARAM_ERROR, file_name == NULL);
262 
263  file_.open(file_name);
264  map_address(file_.ptr());
266 }
267 
268 void Trie::map_address(void *address) {
269  GRN_DAT_THROW_IF(PARAM_ERROR, address == NULL);
270 
271  header_ = static_cast<Header *>(address);
272  nodes_.assign(header_ + 1, max_num_nodes());
273  blocks_.assign(nodes_.end(), max_num_blocks());
274  entries_.assign(reinterpret_cast<Entry *>(blocks_.end()) - 1,
275  max_num_keys() + 1);
276  key_buf_.assign(entries_.end(), key_buf_size());
277 
278  GRN_DAT_THROW_IF(UNEXPECTED_ERROR, static_cast<void *>(key_buf_.end())
279  > static_cast<void *>(static_cast<char *>(address) + file_size()));
280 }
281 
282 void Trie::build_from_trie(const Trie &trie) {
283  GRN_DAT_THROW_IF(SIZE_ERROR, max_num_keys() < trie.num_keys());
284  GRN_DAT_THROW_IF(SIZE_ERROR, max_num_keys() < trie.max_key_id());
285 
286  header_->set_total_key_length(trie.total_key_length());
287  header_->set_num_keys(trie.num_keys());
288  header_->set_max_key_id(trie.max_key_id());
289  header_->set_next_key_id(trie.next_key_id());
290  for (UInt32 i = min_key_id(); i <= max_key_id(); ++i) {
291  ith_entry(i) = trie.ith_entry(i);
292  }
293  build_from_trie(trie, ROOT_NODE_ID, ROOT_NODE_ID);
294 }
295 
296 void Trie::build_from_trie(const Trie &trie, UInt32 src, UInt32 dest) {
297  // Keys are sorted in lexicographic order.
298  if (trie.ith_node(src).is_linker()) {
299  const Key &key = trie.get_key(trie.ith_node(src).key_pos());
300  Key::create(key_buf_.ptr() + next_key_pos(),
301  key.id(), key.ptr(), key.length());
303  ith_entry(key.id()).set_key_pos(next_key_pos());
304  header_->set_next_key_pos(
305  next_key_pos() + Key::estimate_size(key.length()));
306  return;
307  }
308 
309  const UInt32 src_offset = trie.ith_node(src).offset();
310  UInt32 dest_offset;
311  {
312  UInt16 labels[MAX_LABEL + 1];
313  UInt32 num_labels = 0;
314 
315  UInt32 label = trie.ith_node(src).child();
316  while (label != INVALID_LABEL) {
318  const UInt32 child = src_offset ^ label;
319  if (trie.ith_node(child).is_linker() ||
320  (trie.ith_node(child).child() != INVALID_LABEL)) {
321  labels[num_labels++] = label;
322  }
323  label = trie.ith_node(child).sibling();
324  }
325  if (num_labels == 0) {
326  return;
327  }
328 
329  dest_offset = find_offset(labels, num_labels);
330  for (UInt32 i = 0; i < num_labels; ++i) {
331  const UInt32 child = dest_offset ^ labels[i];
332  reserve_node(child);
333  ith_node(child).set_label(labels[i]);
334  if ((i + 1) < num_labels) {
335  ith_node(child).set_sibling(labels[i + 1]);
336  }
337  }
338 
339  GRN_DAT_DEBUG_THROW_IF(ith_node(dest_offset).is_offset());
340  ith_node(dest_offset).set_is_offset(true);
341  ith_node(dest).set_offset(dest_offset);
342  ith_node(dest).set_child(labels[0]);
343  }
344 
345  UInt32 label = ith_node(dest).child();
346  while (label != INVALID_LABEL) {
347  build_from_trie(trie, src_offset ^ label, dest_offset ^ label);
348  label = ith_node(dest_offset ^ label).sibling();
349  }
350 }
351 
352 void Trie::repair_trie(const Trie &trie) {
353  Vector<UInt32> valid_ids;
354  header_->set_max_key_id(trie.max_key_id());
355  header_->set_next_key_id(trie.max_key_id() + 1);
356  UInt32 prev_invalid_key_id = INVALID_KEY_ID;
357  for (UInt32 i = min_key_id(); i <= max_key_id(); ++i) {
358  const Entry &entry = trie.ith_entry(i);
359  if (entry.is_valid()) {
360  valid_ids.push_back(i);
361  ith_entry(i) = entry;
362  const Key &key = trie.get_key(entry.key_pos());
363  Key::create(key_buf_.ptr() + next_key_pos(),
364  key.id(), key.ptr(), key.length());
366  header_->set_next_key_pos(
367  next_key_pos() + Key::estimate_size(key.length()));
368  header_->set_total_key_length(
369  total_key_length() + key.length());
370  header_->set_num_keys(num_keys() + 1);
371  } else {
372  if (prev_invalid_key_id == INVALID_KEY_ID) {
373  header_->set_next_key_id(i);
374  } else {
375  ith_entry(prev_invalid_key_id).set_next(i);
376  }
377  prev_invalid_key_id = i;
378  }
379  }
380  if (prev_invalid_key_id != INVALID_KEY_ID) {
381  ith_entry(prev_invalid_key_id).set_next(max_key_id() + 1);
382  }
383  mkq_sort(valid_ids.begin(), valid_ids.end(), 0);
384  build_from_keys(valid_ids.begin(), valid_ids.end(), 0, ROOT_NODE_ID);
385 }
386 
387 void Trie::build_from_keys(const UInt32 *begin, const UInt32 *end,
388  UInt32 depth, UInt32 node_id) {
389  if ((end - begin) == 1) {
390  ith_node(node_id).set_key_pos(ith_entry(*begin).key_pos());
391  return;
392  }
393 
394  UInt32 offset;
395  {
396  UInt16 labels[MAX_LABEL + 2];
397  UInt32 num_labels = 0;
398 
399  const UInt32 *it = begin;
400  if (ith_key(*it).length() == depth) {
401  labels[num_labels++] = TERMINAL_LABEL;
402  ++it;
403  }
404 
405  labels[num_labels++] = (UInt8)ith_key(*it)[depth];
406  for (++it; it < end; ++it) {
407  const Key &key = ith_key(*it);
408  if ((UInt8)key[depth] != labels[num_labels - 1]) {
409  labels[num_labels++] = (UInt8)key[depth];
410  }
411  }
412  labels[num_labels] = INVALID_LABEL;
413 
414  offset = find_offset(labels, num_labels);
415  ith_node(node_id).set_child(labels[0]);
416  for (UInt32 i = 0; i < num_labels; ++i) {
417  const UInt32 next = offset ^ labels[i];
418  reserve_node(next);
419  ith_node(next).set_label(labels[i]);
420  ith_node(next).set_sibling(labels[i + 1]);
421  }
422 
423  if (offset >= num_nodes()) {
424  reserve_block(num_blocks());
425  }
426  ith_node(offset).set_is_offset(true);
427  ith_node(node_id).set_offset(offset);
428  }
429 
430  if (ith_key(*begin).length() == depth) {
431  build_from_keys(begin, begin + 1, depth + 1, offset ^ TERMINAL_LABEL);
432  ++begin;
433  }
434 
435  UInt16 label = ith_key(*begin)[depth];
436  for (const UInt32 *it = begin + 1; it < end; ++it) {
437  const Key &key = ith_key(*it);
438  if ((UInt8)key[depth] != label) {
439  build_from_keys(begin, it, depth + 1, offset ^ label);
440  label = (UInt8)key[depth];
441  begin = it;
442  }
443  }
444  build_from_keys(begin, end, depth + 1, offset ^ label);
445 }
446 
447 void Trie::mkq_sort(UInt32 *l, UInt32 *r, UInt32 depth) {
448  while ((r - l) >= MKQ_SORT_THRESHOLD) {
449  UInt32 *pl = l;
450  UInt32 *pr = r;
451  UInt32 *pivot_l = l;
452  UInt32 *pivot_r = r;
453 
454  const int pivot = get_median(*l, *(l + (r - l) / 2), *(r - 1), depth);
455  for ( ; ; ) {
456  while (pl < pr) {
457  const int label = get_label(*pl, depth);
458  if (label > pivot) {
459  break;
460  } else if (label == pivot) {
461  swap_ids(pl, pivot_l);
462  ++pivot_l;
463  }
464  ++pl;
465  }
466  while (pl < pr) {
467  const int label = get_label(*--pr, depth);
468  if (label < pivot) {
469  break;
470  } else if (label == pivot) {
471  swap_ids(pr, --pivot_r);
472  }
473  }
474  if (pl >= pr) {
475  break;
476  }
477  swap_ids(pl, pr);
478  ++pl;
479  }
480  while (pivot_l > l) {
481  swap_ids(--pivot_l, --pl);
482  }
483  while (pivot_r < r) {
484  swap_ids(pivot_r, pr);
485  ++pivot_r;
486  ++pr;
487  }
488 
489  if (((pl - l) > (pr - pl)) || ((r - pr) > (pr - pl))) {
490  if ((pr - pl) > 1) {
491  mkq_sort(pl, pr, depth + 1);
492  }
493 
494  if ((pl - l) < (r - pr)) {
495  if ((pl - l) > 1) {
496  mkq_sort(l, pl, depth);
497  }
498  l = pr;
499  } else {
500  if ((r - pr) > 1) {
501  mkq_sort(pr, r, depth);
502  }
503  r = pl;
504  }
505  } else {
506  if ((pl - l) > 1) {
507  mkq_sort(l, pl, depth);
508  }
509 
510  if ((r - pr) > 1) {
511  mkq_sort(pr, r, depth);
512  }
513 
514  l = pl, r = pr;
515  if ((pr - pl) > 1) {
516  ++depth;
517  }
518  }
519  }
520 
521  if ((r - l) > 1) {
522  insertion_sort(l, r, depth);
523  }
524 }
525 
526 void Trie::insertion_sort(UInt32 *l, UInt32 *r, UInt32 depth) {
527  for (UInt32 *i = l + 1; i < r; ++i) {
528  for (UInt32 *j = i; j > l; --j) {
529  if (less_than(*(j - 1), *j, depth)) {
530  break;
531  }
532  swap_ids(j - 1, j);
533  }
534  }
535 }
536 
537 int Trie::get_median(UInt32 a, UInt32 b, UInt32 c, UInt32 depth) const {
538  const int x = get_label(a, depth);
539  const int y = get_label(b, depth);
540  const int z = get_label(c, depth);
541  if (x < y) {
542  if (y < z) {
543  return y;
544  } else if (x < z) {
545  return z;
546  }
547  return x;
548  } else if (x < z) {
549  return x;
550  } else if (y < z) {
551  return z;
552  }
553  return y;
554 }
555 
556 int Trie::get_label(UInt32 key_id, UInt32 depth) const {
557  const Key &key = ith_key(key_id);
558  if (depth == key.length()) {
559  return -1;
560  } else {
561  return (UInt8)key[depth];
562  }
563 }
564 
565 bool Trie::less_than(UInt32 lhs, UInt32 rhs, UInt32 depth) const {
566  const Key &lhs_key = ith_key(lhs);
567  const Key &rhs_key = ith_key(rhs);
568  const UInt32 length = (lhs_key.length() < rhs_key.length()) ?
569  lhs_key.length() : rhs_key.length();
570  for (UInt32 i = depth; i < length; ++i) {
571  if (lhs_key[i] != rhs_key[i]) {
572  return (UInt8)lhs_key[i] < (UInt8)rhs_key[i];
573  }
574  }
575  return lhs_key.length() < rhs_key.length();
576 }
577 
578 void Trie::swap_ids(UInt32 *lhs, UInt32 *rhs) {
579  UInt32 temp = *lhs;
580  *lhs = *rhs;
581  *rhs = temp;
582 }
583 
584 bool Trie::search_key(const UInt8 *ptr, UInt32 length, UInt32 *key_pos) const {
585  GRN_DAT_DEBUG_THROW_IF((ptr == NULL) && (length != 0));
586 
587  UInt32 node_id = ROOT_NODE_ID;
588  UInt32 query_pos = 0;
589  if (!search_linker(ptr, length, node_id, query_pos)) {
590  return false;
591  }
592 
593  const Base base = ith_node(node_id).base();
594  if (!base.is_linker()) {
595  return false;
596  }
597 
598  if (get_key(base.key_pos()).equals_to(ptr, length, query_pos)) {
599  if (key_pos != NULL) {
600  *key_pos = base.key_pos();
601  }
602  return true;
603  }
604  return false;
605 }
606 
607 bool Trie::search_linker(const UInt8 *ptr, UInt32 length,
608  UInt32 &node_id, UInt32 &query_pos) const {
609  GRN_DAT_DEBUG_THROW_IF((ptr == NULL) && (length != 0));
610 
611  for ( ; query_pos < length; ++query_pos) {
612  const Base base = ith_node(node_id).base();
613  if (base.is_linker()) {
614  return true;
615  }
616 
617  const UInt32 next = base.offset() ^ ptr[query_pos];
618  if (ith_node(next).label() != ptr[query_pos]) {
619  return false;
620  }
621  node_id = next;
622  }
623 
624  const Base base = ith_node(node_id).base();
625  if (base.is_linker()) {
626  return true;
627  }
628 
629  const UInt32 next = base.offset() ^ TERMINAL_LABEL;
630  if (ith_node(next).label() != TERMINAL_LABEL) {
631  return false;
632  }
633  node_id = next;
634  return ith_node(next).is_linker();
635 }
636 
637 bool Trie::lcp_search_key(const UInt8 *ptr, UInt32 length,
638  UInt32 *key_pos) const {
639  GRN_DAT_DEBUG_THROW_IF((ptr == NULL) && (length != 0));
640 
641  bool found = false;
642  UInt32 node_id = ROOT_NODE_ID;
643  UInt32 query_pos = 0;
644 
645  for ( ; query_pos < length; ++query_pos) {
646  const Base base = ith_node(node_id).base();
647  if (base.is_linker()) {
648  const Key &key = get_key(base.key_pos());
649  if ((key.length() <= length) &&
650  key.equals_to(ptr, key.length(), query_pos)) {
651  if (key_pos != NULL) {
652  *key_pos = base.key_pos();
653  }
654  found = true;
655  }
656  return found;
657  }
658 
659  if (ith_node(node_id).child() == TERMINAL_LABEL) {
660  const Base linker_base =
661  ith_node(base.offset() ^ TERMINAL_LABEL).base();
662  if (linker_base.is_linker()) {
663  if (key_pos != NULL) {
664  *key_pos = linker_base.key_pos();
665  }
666  found = true;
667  }
668  }
669 
670  node_id = base.offset() ^ ptr[query_pos];
671  if (ith_node(node_id).label() != ptr[query_pos]) {
672  return found;
673  }
674  }
675 
676  const Base base = ith_node(node_id).base();
677  if (base.is_linker()) {
678  const Key &key = get_key(base.key_pos());
679  if (key.length() <= length) {
680  if (key_pos != NULL) {
681  *key_pos = base.key_pos();
682  }
683  found = true;
684  }
685  } else if (ith_node(node_id).child() == TERMINAL_LABEL) {
686  const Base linker_base = ith_node(base.offset() ^ TERMINAL_LABEL).base();
687  if (linker_base.is_linker()) {
688  if (key_pos != NULL) {
689  *key_pos = linker_base.key_pos();
690  }
691  found = true;
692  }
693  }
694  return found;
695 }
696 
697 bool Trie::remove_key(const UInt8 *ptr, UInt32 length) {
699  StatusFlagManager status_flag_manager(header_, REMOVING_FLAG);
700 
701  GRN_DAT_DEBUG_THROW_IF((ptr == NULL) && (length != 0));
702 
703  UInt32 node_id = ROOT_NODE_ID;
704  UInt32 query_pos = 0;
705  if (!search_linker(ptr, length, node_id, query_pos)) {
706  return false;
707  }
708 
709  const UInt32 key_pos = ith_node(node_id).key_pos();
710  if (!get_key(key_pos).equals_to(ptr, length, query_pos)) {
711  return false;
712  }
713 
714  const UInt32 key_id = get_key(key_pos).id();
716  ith_entry(key_id).set_next(next_key_id());
717 
718  header_->set_next_key_id(key_id);
719  header_->set_total_key_length(total_key_length() - length);
720  header_->set_num_keys(num_keys() - 1);
721  return true;
722 }
723 
724 bool Trie::insert_key(const UInt8 *ptr, UInt32 length, UInt32 *key_pos) {
726  StatusFlagManager status_flag_manager(header_, INSERTING_FLAG);
727 
728  GRN_DAT_DEBUG_THROW_IF((ptr == NULL) && (length != 0));
729 
730  UInt32 node_id = ROOT_NODE_ID;
731  UInt32 query_pos = 0;
732 
733  search_linker(ptr, length, node_id, query_pos);
734  if (!insert_linker(ptr, length, node_id, query_pos)) {
735  if (key_pos != NULL) {
736  *key_pos = ith_node(node_id).key_pos();
737  }
738  return false;
739  }
740 
741  const UInt32 new_key_id = next_key_id();
742  const UInt32 new_key_pos = append_key(ptr, length, new_key_id);
743 
744  header_->set_total_key_length(total_key_length() + length);
745  header_->set_num_keys(num_keys() + 1);
746  if (new_key_id > max_key_id()) {
747  header_->set_max_key_id(new_key_id);
748  header_->set_next_key_id(new_key_id + 1);
749  } else {
750  header_->set_next_key_id(ith_entry(new_key_id).next());
751  }
752 
753  ith_entry(new_key_id).set_key_pos(new_key_pos);
754  ith_node(node_id).set_key_pos(new_key_pos);
755  if (key_pos != NULL) {
756  *key_pos = new_key_pos;
757  }
758  return true;
759 }
760 
761 bool Trie::insert_linker(const UInt8 *ptr, UInt32 length,
762  UInt32 &node_id, UInt32 query_pos) {
763  if (ith_node(node_id).is_linker()) {
764  const Key &key = get_key(ith_node(node_id).key_pos());
765  UInt32 i = query_pos;
766  while ((i < length) && (i < key.length())) {
767  if (ptr[i] != key[i]) {
768  break;
769  }
770  ++i;
771  }
772  if ((i == length) && (i == key.length())) {
773  return false;
774  }
777 
778  for (UInt32 j = query_pos; j < i; ++j) {
779  node_id = insert_node(node_id, ptr[j]);
780  }
781  node_id = separate(ptr, length, node_id, i);
782  return true;
783  } else if (ith_node(node_id).label() == TERMINAL_LABEL) {
784  return true;
785  } else {
787  const UInt16 label = (query_pos < length) ?
788  (UInt16)ptr[query_pos] : (UInt16)TERMINAL_LABEL;
789  const Base base = ith_node(node_id).base();
790  if ((base.offset() == INVALID_OFFSET) ||
791  !ith_node(base.offset() ^ label).is_phantom()) {
792  resolve(node_id, label);
793  }
794  node_id = insert_node(node_id, label);
795  return true;
796  }
797 }
798 
799 bool Trie::update_key(const Key &key, const UInt8 *ptr, UInt32 length,
800  UInt32 *key_pos) {
802  StatusFlagManager status_flag_manager(header_, UPDATING_FLAG);
803 
804  GRN_DAT_DEBUG_THROW_IF((ptr == NULL) && (length != 0));
805 
806  if (!key.is_valid()) {
807  return false;
808  }
809 
810  UInt32 node_id = ROOT_NODE_ID;
811  UInt32 query_pos = 0;
812 
813  search_linker(ptr, length, node_id, query_pos);
814  if (!insert_linker(ptr, length, node_id, query_pos)) {
815  if (key_pos != NULL) {
816  *key_pos = ith_node(node_id).key_pos();
817  }
818  return false;
819  }
820 
821  const UInt32 new_key_pos = append_key(ptr, length, key.id());
822  header_->set_total_key_length(total_key_length() + length - key.length());
823  ith_entry(key.id()).set_key_pos(new_key_pos);
824  ith_node(node_id).set_key_pos(new_key_pos);
825  if (key_pos != NULL) {
826  *key_pos = new_key_pos;
827  }
828 
829  node_id = ROOT_NODE_ID;
830  query_pos = 0;
832  !search_linker(static_cast<const UInt8 *>(key.ptr()), key.length(),
833  node_id, query_pos));
835  return true;
836 }
837 
838 UInt32 Trie::insert_node(UInt32 node_id, UInt16 label) {
839  GRN_DAT_DEBUG_THROW_IF(node_id >= num_nodes());
841 
842  const Base base = ith_node(node_id).base();
843  UInt32 offset;
844  if (base.is_linker() || (base.offset() == INVALID_OFFSET)) {
845  offset = find_offset(&label, 1);
846  } else {
847  offset = base.offset();
848  }
849 
850  const UInt32 next = offset ^ label;
851  reserve_node(next);
852 
853  ith_node(next).set_label(label);
854  if (base.is_linker()) {
855  GRN_DAT_DEBUG_THROW_IF(ith_node(offset).is_offset());
856  ith_node(offset).set_is_offset(true);
857  ith_node(next).set_key_pos(base.key_pos());
858  } else if (base.offset() == INVALID_OFFSET) {
859  GRN_DAT_DEBUG_THROW_IF(ith_node(offset).is_offset());
860  ith_node(offset).set_is_offset(true);
861  } else {
862  GRN_DAT_DEBUG_THROW_IF(!ith_node(offset).is_offset());
863  }
864  ith_node(node_id).set_offset(offset);
865 
866  const UInt32 child_label = ith_node(node_id).child();
867  GRN_DAT_DEBUG_THROW_IF(child_label == label);
868  if (child_label == INVALID_LABEL) {
869  ith_node(node_id).set_child(label);
870  } else if ((label == TERMINAL_LABEL) ||
871  ((child_label != TERMINAL_LABEL) && (label < child_label))) {
872  GRN_DAT_DEBUG_THROW_IF(ith_node(offset ^ child_label).is_phantom());
873  GRN_DAT_DEBUG_THROW_IF(ith_node(offset ^ child_label).label() != child_label);
874  ith_node(next).set_sibling(child_label);
875  ith_node(node_id).set_child(label);
876  } else {
877  UInt32 prev = offset ^ child_label;
878  GRN_DAT_DEBUG_THROW_IF(ith_node(prev).label() != child_label);
879  UInt32 sibling_label = ith_node(prev).sibling();
880  while (label > sibling_label) {
881  prev = offset ^ sibling_label;
882  GRN_DAT_DEBUG_THROW_IF(ith_node(prev).label() != sibling_label);
883  sibling_label = ith_node(prev).sibling();
884  }
885  GRN_DAT_DEBUG_THROW_IF(label == sibling_label);
886  ith_node(next).set_sibling(ith_node(prev).sibling());
887  ith_node(prev).set_sibling(label);
888  }
889  return next;
890 }
891 
892 UInt32 Trie::append_key(const UInt8 *ptr, UInt32 length, UInt32 key_id) {
894 
895  const UInt32 key_pos = next_key_pos();
896  const UInt32 key_size = Key::estimate_size(length);
897 
898  GRN_DAT_THROW_IF(SIZE_ERROR, key_size > (key_buf_size() - key_pos));
899  Key::create(key_buf_.ptr() + key_pos, key_id, ptr, length);
900 
901  header_->set_next_key_pos(key_pos + key_size);
902  return key_pos;
903 }
904 
905 UInt32 Trie::separate(const UInt8 *ptr, UInt32 length,
906  UInt32 node_id, UInt32 i) {
907  GRN_DAT_DEBUG_THROW_IF(node_id >= num_nodes());
908  GRN_DAT_DEBUG_THROW_IF(!ith_node(node_id).is_linker());
909  GRN_DAT_DEBUG_THROW_IF(i > length);
910 
911  const UInt32 key_pos = ith_node(node_id).key_pos();
912  const Key &key = get_key(key_pos);
913 
914  UInt16 labels[2];
915  labels[0] = (i < key.length()) ? (UInt16)key[i] : (UInt16)TERMINAL_LABEL;
916  labels[1] = (i < length) ? (UInt16)ptr[i] : (UInt16)TERMINAL_LABEL;
917  GRN_DAT_DEBUG_THROW_IF(labels[0] == labels[1]);
918 
919  const UInt32 offset = find_offset(labels, 2);
920 
921  UInt32 next = offset ^ labels[0];
922  reserve_node(next);
923  GRN_DAT_DEBUG_THROW_IF(ith_node(offset).is_offset());
924 
925  ith_node(next).set_label(labels[0]);
926  ith_node(next).set_key_pos(key_pos);
927 
928  next = offset ^ labels[1];
929  reserve_node(next);
930 
931  ith_node(next).set_label(labels[1]);
932 
933  ith_node(offset).set_is_offset(true);
934  ith_node(node_id).set_offset(offset);
935 
936  if ((labels[0] == TERMINAL_LABEL) ||
937  ((labels[1] != TERMINAL_LABEL) && (labels[0] < labels[1]))) {
938  ith_node(node_id).set_child(labels[0]);
939  ith_node(offset ^ labels[0]).set_sibling(labels[1]);
940  } else {
941  ith_node(node_id).set_child(labels[1]);
942  ith_node(offset ^ labels[1]).set_sibling(labels[0]);
943  }
944  return next;
945 }
946 
947 void Trie::resolve(UInt32 node_id, UInt16 label) {
948  GRN_DAT_DEBUG_THROW_IF(node_id >= num_nodes());
949  GRN_DAT_DEBUG_THROW_IF(ith_node(node_id).is_linker());
951 
952  UInt32 offset = ith_node(node_id).offset();
953  if (offset != INVALID_OFFSET) {
954  UInt16 labels[MAX_LABEL + 1];
955  UInt32 num_labels = 0;
956 
957  UInt32 next_label = ith_node(node_id).child();
958  GRN_DAT_DEBUG_THROW_IF(next_label == INVALID_LABEL);
959  while (next_label != INVALID_LABEL) {
960  GRN_DAT_DEBUG_THROW_IF(next_label > MAX_LABEL);
961  labels[num_labels++] = next_label;
962  next_label = ith_node(offset ^ next_label).sibling();
963  }
964  GRN_DAT_DEBUG_THROW_IF(num_labels == 0);
965 
966  labels[num_labels] = label;
967  offset = find_offset(labels, num_labels + 1);
968  migrate_nodes(node_id, offset, labels, num_labels);
969  } else {
970  offset = find_offset(&label, 1);
971  if (offset >= num_nodes()) {
973  reserve_block(num_blocks());
974  }
975  ith_node(offset).set_is_offset(true);
976  ith_node(node_id).set_offset(offset);
977  }
978 }
979 
980 void Trie::migrate_nodes(UInt32 node_id, UInt32 dest_offset,
981  const UInt16 *labels, UInt32 num_labels) {
982  GRN_DAT_DEBUG_THROW_IF(node_id >= num_nodes());
983  GRN_DAT_DEBUG_THROW_IF(ith_node(node_id).is_linker());
984  GRN_DAT_DEBUG_THROW_IF(labels == NULL);
985  GRN_DAT_DEBUG_THROW_IF(num_labels == 0);
986  GRN_DAT_DEBUG_THROW_IF(num_labels > (MAX_LABEL + 1));
987 
988  const UInt32 src_offset = ith_node(node_id).offset();
989  GRN_DAT_DEBUG_THROW_IF(src_offset == INVALID_OFFSET);
990  GRN_DAT_DEBUG_THROW_IF(!ith_node(src_offset).is_offset());
991 
992  for (UInt32 i = 0; i < num_labels; ++i) {
993  const UInt32 src_node_id = src_offset ^ labels[i];
994  const UInt32 dest_node_id = dest_offset ^ labels[i];
995  GRN_DAT_DEBUG_THROW_IF(ith_node(src_node_id).is_phantom());
996  GRN_DAT_DEBUG_THROW_IF(ith_node(src_node_id).label() != labels[i]);
997 
998  reserve_node(dest_node_id);
999  ith_node(dest_node_id).set_except_is_offset(
1000  ith_node(src_node_id).except_is_offset());
1001  ith_node(dest_node_id).set_base(ith_node(src_node_id).base());
1002  }
1003  header_->set_num_zombies(num_zombies() + num_labels);
1004 
1005  GRN_DAT_DEBUG_THROW_IF(ith_node(dest_offset).is_offset());
1006  ith_node(dest_offset).set_is_offset(true);
1007  ith_node(node_id).set_offset(dest_offset);
1008 }
1009 
1010 UInt32 Trie::find_offset(const UInt16 *labels, UInt32 num_labels) {
1011  GRN_DAT_DEBUG_THROW_IF(labels == NULL);
1012  GRN_DAT_DEBUG_THROW_IF(num_labels == 0);
1013  GRN_DAT_DEBUG_THROW_IF(num_labels > (MAX_LABEL + 1));
1014 
1015  // Blocks are tested in descending order of level. Basically, a lower level
1016  // block contains more phantom nodes.
1017  UInt32 level = 1;
1018  while (num_labels >= (1U << level)) {
1019  ++level;
1020  }
1021  level = (level < MAX_BLOCK_LEVEL) ? (MAX_BLOCK_LEVEL - level) : 0;
1022 
1023  UInt32 block_count = 0;
1024  do {
1025  UInt32 leader = header_->ith_leader(level);
1026  if (leader == INVALID_LEADER) {
1027  // This level has no blocks and it is thus skipped.
1028  continue;
1029  }
1030 
1031  UInt32 block_id = leader;
1032  do {
1033  const Block &block = ith_block(block_id);
1034  GRN_DAT_DEBUG_THROW_IF(block.level() != level);
1035 
1036  const UInt32 first = (block_id * BLOCK_SIZE) | block.first_phantom();
1037  UInt32 node_id = first;
1038  do {
1039  GRN_DAT_DEBUG_THROW_IF(!ith_node(node_id).is_phantom());
1040  const UInt32 offset = node_id ^ labels[0];
1041  if (!ith_node(offset).is_offset()) {
1042  UInt32 i = 1;
1043  for ( ; i < num_labels; ++i) {
1044  if (!ith_node(offset ^ labels[i]).is_phantom()) {
1045  break;
1046  }
1047  }
1048  if (i >= num_labels) {
1049  return offset;
1050  }
1051  }
1052  node_id = (block_id * BLOCK_SIZE) | ith_node(node_id).next();
1053  } while (node_id != first);
1054 
1055  const UInt32 prev = block_id;
1056  const UInt32 next = block.next();
1057  block_id = next;
1058  ith_block(prev).set_failure_count(ith_block(prev).failure_count() + 1);
1059 
1060  // The level of a block is updated when this function fails many times,
1061  // actually MAX_FAILURE_COUNT times, in that block.
1062  if (ith_block(prev).failure_count() == MAX_FAILURE_COUNT) {
1063  update_block_level(prev, level + 1);
1064  if (next == leader) {
1065  break;
1066  } else {
1067  // Note that the leader might be updated in the level update.
1068  leader = header_->ith_leader(level);
1069  continue;
1070  }
1071  }
1072  } while ((++block_count < MAX_BLOCK_COUNT) && (block_id != leader));
1073  } while ((block_count < MAX_BLOCK_COUNT) && (level-- != 0));
1074 
1075  return num_nodes() ^ labels[0];
1076 }
1077 
1078 void Trie::reserve_node(UInt32 node_id) {
1079  GRN_DAT_DEBUG_THROW_IF(node_id > num_nodes());
1080  if (node_id >= num_nodes()) {
1081  reserve_block(node_id / BLOCK_SIZE);
1082  }
1083 
1084  Node &node = ith_node(node_id);
1085  GRN_DAT_DEBUG_THROW_IF(!node.is_phantom());
1086 
1087  const UInt32 block_id = node_id / BLOCK_SIZE;
1088  Block &block = ith_block(block_id);
1089  GRN_DAT_DEBUG_THROW_IF(block.num_phantoms() == 0);
1090 
1091  const UInt32 next = (block_id * BLOCK_SIZE) | node.next();
1092  const UInt32 prev = (block_id * BLOCK_SIZE) | node.prev();
1093  GRN_DAT_DEBUG_THROW_IF(next >= num_nodes());
1094  GRN_DAT_DEBUG_THROW_IF(prev >= num_nodes());
1095 
1096  if ((node_id & BLOCK_MASK) == block.first_phantom()) {
1097  // The first phantom node is removed from the block and the second phantom
1098  // node comes first.
1099  block.set_first_phantom(next & BLOCK_MASK);
1100  }
1101 
1102  ith_node(next).set_prev(prev & BLOCK_MASK);
1103  ith_node(prev).set_next(next & BLOCK_MASK);
1104 
1105  if (block.level() != MAX_BLOCK_LEVEL) {
1106  const UInt32 threshold = 1U << ((MAX_BLOCK_LEVEL - block.level() - 1) * 2);
1107  if (block.num_phantoms() == threshold) {
1108  update_block_level(block_id, block.level() + 1);
1109  }
1110  }
1111  block.set_num_phantoms(block.num_phantoms() - 1);
1112 
1113  node.set_is_phantom(false);
1114 
1115  GRN_DAT_DEBUG_THROW_IF(node.offset() != INVALID_OFFSET);
1116  GRN_DAT_DEBUG_THROW_IF(node.label() != INVALID_LABEL);
1117 
1118  header_->set_num_phantoms(num_phantoms() - 1);
1119 }
1120 
1121 void Trie::reserve_block(UInt32 block_id) {
1122  GRN_DAT_DEBUG_THROW_IF(block_id != num_blocks());
1123  GRN_DAT_THROW_IF(SIZE_ERROR, block_id >= max_num_blocks());
1124 
1125  header_->set_num_blocks(block_id + 1);
1126  ith_block(block_id).set_failure_count(0);
1127  ith_block(block_id).set_first_phantom(0);
1129 
1130  const UInt32 begin = block_id * BLOCK_SIZE;
1131  const UInt32 end = begin + BLOCK_SIZE;
1133 
1134  Base base;
1135  base.set_offset(INVALID_OFFSET);
1136 
1137  Check check;
1138  check.set_is_phantom(true);
1139 
1140  for (UInt32 i = begin; i < end; ++i) {
1141  check.set_prev((i - 1) & BLOCK_MASK);
1142  check.set_next((i + 1) & BLOCK_MASK);
1143  ith_node(i).set_base(base);
1144  ith_node(i).set_check(check);
1145  }
1146 
1147  // The level of the new block is 0.
1148  set_block_level(block_id, 0);
1149  header_->set_num_phantoms(num_phantoms() + BLOCK_SIZE);
1150 }
1151 
1152 void Trie::update_block_level(UInt32 block_id, UInt32 level) {
1153  GRN_DAT_DEBUG_THROW_IF(block_id >= num_blocks());
1155 
1156  unset_block_level(block_id);
1157  set_block_level(block_id, level);
1158 }
1159 
1160 void Trie::set_block_level(UInt32 block_id, UInt32 level) {
1161  GRN_DAT_DEBUG_THROW_IF(block_id >= num_blocks());
1163 
1164  const UInt32 leader = header_->ith_leader(level);
1165  if (leader == INVALID_LEADER) {
1166  // The new block becomes the only one block of the linked list.
1167  ith_block(block_id).set_next(block_id);
1168  ith_block(block_id).set_prev(block_id);
1169  header_->set_ith_leader(level, block_id);
1170  } else {
1171  // The new block is added to the end of the list.
1172  const UInt32 next = leader;
1173  const UInt32 prev = ith_block(leader).prev();
1176  ith_block(block_id).set_next(next);
1177  ith_block(block_id).set_prev(prev);
1178  ith_block(next).set_prev(block_id);
1179  ith_block(prev).set_next(block_id);
1180  }
1181  ith_block(block_id).set_level(level);
1182  ith_block(block_id).set_failure_count(0);
1183 }
1184 
1185 void Trie::unset_block_level(UInt32 block_id) {
1186  GRN_DAT_DEBUG_THROW_IF(block_id >= num_blocks());
1187 
1188  const UInt32 level = ith_block(block_id).level();
1190 
1191  const UInt32 leader = header_->ith_leader(level);
1193 
1194  const UInt32 next = ith_block(block_id).next();
1195  const UInt32 prev = ith_block(block_id).prev();
1198 
1199  if (next == block_id) {
1200  // The linked list becomes empty.
1201  header_->set_ith_leader(level, INVALID_LEADER);
1202  } else {
1203  ith_block(next).set_prev(prev);
1204  ith_block(prev).set_next(next);
1205  if (block_id == leader) {
1206  // The second block becomes the leader of the linked list.
1207  header_->set_ith_leader(level, next);
1208  }
1209  }
1210 }
1211 
1212 } // namespace dat
1213 } // namespace grn