8#define DARTS_VERSION "0.32"
15#define DARTS_INT_TO_STR(value) #value
16#define DARTS_LINE_TO_STR(line) DARTS_INT_TO_STR(line)
17#define DARTS_LINE_STR DARTS_LINE_TO_STR(__LINE__)
18#define DARTS_THROW(msg) throw Darts::Details::Exception( \
19 __FILE__ ":" DARTS_LINE_STR ": exception: " msg)
57 return ((unit_ >> 8) & 1) == 1;
62 return static_cast<value_type>(unit_ & ((1U << 31) - 1));
69 return unit_ & ((1U << 31) | 0xFF);
73 return (unit_ >> 10) << ((unit_ & (1U << 9)) >> 6);
89 explicit Exception(
const char *msg = NULL)
throw() : msg_(msg) {}
94 virtual const char *
what()
const throw() {
95 return (msg_ != NULL) ? msg_ :
"";
116template <
typename,
typename,
typename T,
typename>
160 result->value = value;
161 result->length = length;
173 array_ =
static_cast<const unit_type *
>(ptr);
196 return sizeof(unit_type);
231 const std::size_t *lengths = NULL,
const value_type *values = NULL,
242 int open(
const char *file_name,
const char *mode =
"rb",
243 std::size_t offset = 0, std::size_t
size = 0);
248 int save(
const char *file_name,
const char *mode =
"wb",
249 std::size_t offset = 0)
const;
264 std::size_t length = 0, std::size_t node_pos = 0)
const {
271 std::size_t node_pos = 0)
const;
283 std::size_t max_num_results, std::size_t length = 0,
284 std::size_t node_pos = 0)
const;
298 std::size_t &key_pos, std::size_t length = 0)
const;
306 const unit_type *array_;
326template <
typename A,
typename B,
typename T,
typename C>
328 const char *mode, std::size_t offset, std::size_t
size) {
331 if (::fopen_s(&file, file_name, mode) != 0) {
335 std::FILE *file = std::fopen(file_name, mode);
342 if (std::fseek(file, 0, SEEK_END) != 0) {
346 size = std::ftell(file) - offset;
349 if (std::fseek(file, offset, SEEK_SET) != 0) {
357 buf =
new unit_type[
size];
358 }
catch (
const std::bad_alloc &) {
360 DARTS_THROW(
"failed to open double-array: std::bad_alloc");
378template <
typename A,
typename B,
typename T,
typename C>
380 const char *mode, std::size_t)
const {
387 if (::fopen_s(&file, file_name, mode) != 0) {
391 std::FILE *file = std::fopen(file_name, mode);
405template <
typename A,
typename B,
typename T,
typename C>
408 std::size_t length, std::size_t node_pos)
const {
412 unit_type unit = array_[node_pos];
414 for (std::size_t i = 0; i < length; ++i) {
415 node_pos ^= unit.
offset() ^
static_cast<uchar_type
>(key[i]);
416 unit = array_[node_pos];
417 if (unit.
label() !=
static_cast<uchar_type
>(key[i])) {
422 for ( ; key[length] !=
'\0'; ++length) {
423 node_pos ^= unit.
offset() ^
static_cast<uchar_type
>(key[length]);
424 unit = array_[node_pos];
425 if (unit.
label() !=
static_cast<uchar_type
>(key[length])) {
434 unit = array_[node_pos ^ unit.
offset()];
439template <
typename A,
typename B,
typename T,
typename C>
442 const key_type *key, U *results, std::size_t max_num_results,
443 std::size_t length, std::size_t node_pos)
const {
444 std::size_t num_results = 0;
446 unit_type unit = array_[node_pos];
447 node_pos ^= unit.
offset();
449 for (std::size_t i = 0; i < length; ++i) {
450 node_pos ^=
static_cast<uchar_type
>(key[i]);
451 unit = array_[node_pos];
452 if (unit.
label() !=
static_cast<uchar_type
>(key[i])) {
456 node_pos ^= unit.
offset();
458 if (num_results < max_num_results) {
460 array_[node_pos].value()), i + 1);
466 for ( ; key[length] !=
'\0'; ++length) {
467 node_pos ^=
static_cast<uchar_type
>(key[length]);
468 unit = array_[node_pos];
469 if (unit.
label() !=
static_cast<uchar_type
>(key[length])) {
473 node_pos ^= unit.
offset();
475 if (num_results < max_num_results) {
477 array_[node_pos].value()), length + 1);
487template <
typename A,
typename B,
typename T,
typename C>
490 std::size_t &node_pos, std::size_t &key_pos, std::size_t length)
const {
491 id_type
id =
static_cast<id_type
>(node_pos);
492 unit_type unit = array_[id];
495 for ( ; key_pos < length; ++key_pos) {
496 id ^= unit.
offset() ^
static_cast<uchar_type
>(key[key_pos]);
498 if (unit.
label() !=
static_cast<uchar_type
>(key[key_pos])) {
504 for ( ; key[key_pos] !=
'\0'; ++key_pos) {
505 id ^= unit.
offset() ^
static_cast<uchar_type
>(key[key_pos]);
507 if (unit.
label() !=
static_cast<uchar_type
>(key[key_pos])) {
517 unit = array_[
id ^ unit.
offset()];
543 return array_ == NULL;
547 if (array_ != NULL) {
554 array_ = array->array_;
555 array->array_ = temp;
580 return *(
reinterpret_cast<const T *
>(&buf_[0]) + id);
583 return *(
reinterpret_cast<T *
>(&buf_[0]) + id);
604 (*this)[--size_].~T();
608 if (size_ == capacity_)
609 resize_buf(size_ + 1);
610 new(&(*this)[size_++]) T;
613 if (size_ == capacity_)
614 resize_buf(size_ + 1);
615 new(&(*this)[size_++]) T(value);
619 while (size_ >
size) {
620 (*this)[--size_].~T();
622 if (
size > capacity_) {
625 while (size_ <
size) {
626 new(&(*this)[size_++]) T;
630 while (size_ >
size) {
631 (*this)[--size_].~T();
633 if (
size > capacity_) {
636 while (size_ <
size) {
637 new(&(*this)[size_++]) T(value);
642 if (
size > capacity_) {
650 std::size_t capacity_;
656 void resize_buf(std::size_t
size);
660void AutoPool<T>::resize_buf(std::size_t size) {
661 std::size_t capacity;
662 if (size >= capacity_ * 2) {
666 while (capacity < size) {
673 buf.reset(
new char[
sizeof(T) * capacity]);
674 }
catch (
const std::bad_alloc &) {
675 DARTS_THROW(
"failed to resize pool: std::bad_alloc");
679 T *src =
reinterpret_cast<T *
>(&buf_[0]);
680 T *dest =
reinterpret_cast<T *
>(&buf[0]);
681 for (std::size_t i = 0; i < size_; ++i) {
682 new(&dest[i]) T(src[i]);
688 capacity_ = capacity;
704 return pool_[
size() - 1];
707 return pool_[
size() - 1];
711 return pool_.empty();
718 pool_.push_back(value);
742 BitVector() : units_(), ranks_(), num_ones_(0), size_(0) {}
748 return (units_[
id / UNIT_SIZE] >> (
id % UNIT_SIZE) & 1) == 1;
752 std::size_t unit_id =
id / UNIT_SIZE;
753 return ranks_[unit_id] + pop_count(units_[unit_id]
754 & (~0U >> (UNIT_SIZE - (
id % UNIT_SIZE) - 1)));
757 void set(std::size_t
id,
bool bit) {
759 units_[
id / UNIT_SIZE] |= 1U << (
id % UNIT_SIZE);
761 units_[
id / UNIT_SIZE] &= ~(1U << (
id % UNIT_SIZE));
766 return units_.empty();
776 if ((size_ % UNIT_SIZE) == 0) {
789 enum { UNIT_SIZE =
sizeof(
id_type) * 8 };
791 AutoPool<id_type> units_;
792 AutoArray<id_type> ranks_;
793 std::size_t num_ones_;
801 unit = ((unit & 0xAAAAAAAA) >> 1) + (unit & 0x55555555);
802 unit = ((unit & 0xCCCCCCCC) >> 2) + (unit & 0x33333333);
803 unit = ((unit >> 4) + unit) & 0x0F0F0F0F;
812 ranks_.reset(
new id_type[units_.size()]);
813 }
catch (
const std::bad_alloc &) {
814 DARTS_THROW(
"failed to build rank index: std::bad_alloc");
818 for (std::size_t i = 0; i < units_.size(); ++i) {
819 ranks_[i] = num_ones_;
820 num_ones_ += pop_count(units_[i]);
844 return keys_[key_id][char_id];
848 return lengths_ != NULL;
854 std::size_t length = 0;
855 while (keys_[
id][length] !=
'\0') {
862 return values_ != NULL;
872 std::size_t num_keys_;
874 const std::size_t *lengths_;
889 is_state_(false), has_sibling_(false) {}
930 if (label_ ==
'\0') {
931 return (child_ << 1) | (has_sibling_ ? 1 : 0);
933 return (child_ << 2) | (is_state_ ? 2 : 0) | (has_sibling_ ? 1 : 0);
968 return (unit_ & 1) == 1;
974 return (unit_ & 2) == 2;
989 DawgBuilder() : nodes_(), units_(), labels_(), is_intersections_(),
990 table_(), node_stack_(), recycle_bin_(), num_states_(0) {}
1000 return units_[id].child();
1003 return units_[id].has_sibling() ? (
id + 1) : 0;
1006 return units_[id].value();
1010 return label(
id) ==
'\0';
1017 return is_intersections_[id];
1020 return is_intersections_.rank(
id) - 1;
1024 return is_intersections_.num_ones();
1028 return units_.size();
1039 enum { INITIAL_TABLE_SIZE = 1 << 10 };
1041 AutoPool<DawgNode> nodes_;
1042 AutoPool<DawgUnit> units_;
1043 AutoPool<uchar_type> labels_;
1044 BitVector is_intersections_;
1045 AutoPool<id_type> table_;
1046 AutoStack<id_type> node_stack_;
1047 AutoStack<id_type> recycle_bin_;
1048 std::size_t num_states_;
1056 void expand_table();
1070 recycle_bin_.push(
id);
1074 key = ~key + (key << 15);
1075 key = key ^ (key >> 12);
1076 key = key + (key << 2);
1077 key = key ^ (key >> 4);
1079 key = key ^ (key >> 16);
1085 table_.resize(INITIAL_TABLE_SIZE, 0);
1092 nodes_[0].set_label(0xFF);
1093 node_stack_.push(0);
1099 units_[0] = nodes_[0].unit();
1100 labels_[0] = nodes_[0].label();
1104 node_stack_.clear();
1105 recycle_bin_.clear();
1107 is_intersections_.build();
1113 DARTS_THROW(
"failed to insert key: negative value");
1114 }
else if (length == 0) {
1115 DARTS_THROW(
"failed to insert key: zero-length key");
1119 std::size_t key_pos = 0;
1121 for ( ; key_pos <= length; ++key_pos) {
1122 id_type child_id = nodes_[id].child();
1123 if (child_id == 0) {
1128 if (key_pos < length && key_label ==
'\0') {
1129 DARTS_THROW(
"failed to insert key: invalid null character");
1132 uchar_type unit_label = nodes_[child_id].label();
1133 if (key_label < unit_label) {
1134 DARTS_THROW(
"failed to insert key: wrong key order");
1135 }
else if (key_label > unit_label) {
1136 nodes_[child_id].set_has_sibling(
true);
1143 if (key_pos > length) {
1147 for ( ; key_pos <= length; ++key_pos) {
1149 (key_pos < length) ? key[key_pos] :
'\0');
1150 id_type child_id = append_node();
1152 if (nodes_[
id].
child() == 0) {
1153 nodes_[child_id].set_is_state(
true);
1155 nodes_[child_id].set_sibling(nodes_[
id].
child());
1156 nodes_[child_id].set_label(key_label);
1157 nodes_[id].set_child(child_id);
1158 node_stack_.push(child_id);
1162 nodes_[id].set_value(
value);
1169 is_intersections_.clear();
1171 node_stack_.clear();
1172 recycle_bin_.clear();
1176inline void DawgBuilder::flush(
id_type id) {
1177 while (node_stack_.top() !=
id) {
1178 id_type node_id = node_stack_.top();
1181 if (num_states_ >= table_.size() - (table_.size() >> 2)) {
1186 for (
id_type i = node_id; i != 0; i = nodes_[i].sibling()) {
1191 id_type match_id = find_node(node_id, &hash_id);
1192 if (match_id != 0) {
1193 is_intersections_.set(match_id,
true);
1196 for (
id_type i = 0; i < num_siblings; ++i) {
1197 unit_id = append_unit();
1199 for (
id_type i = node_id; i != 0; i = nodes_[i].sibling()) {
1200 units_[unit_id] = nodes_[i].unit();
1201 labels_[unit_id] = nodes_[i].label();
1204 match_id = unit_id + 1;
1205 table_[hash_id] = match_id;
1209 for (
id_type i = node_id, next; i != 0; i =
next) {
1210 next = nodes_[i].sibling();
1214 nodes_[node_stack_.top()].set_child(match_id);
1219inline void DawgBuilder::expand_table() {
1220 std::size_t table_size = table_.size() << 1;
1222 table_.resize(table_size, 0);
1224 for (std::size_t i = 1; i < units_.size(); ++i) {
1226 if (labels_[
id] ==
'\0' || units_[
id].is_state()) {
1228 find_unit(
id, &hash_id);
1229 table_[hash_id] = id;
1235 *hash_id = hash_unit(
id) % table_.size();
1236 for ( ; ; *hash_id = (*hash_id + 1) % table_.size()) {
1237 id_type unit_id = table_[*hash_id];
1249 *hash_id = hash_node(node_id) % table_.size();
1250 for ( ; ; *hash_id = (*hash_id + 1) % table_.size()) {
1251 id_type unit_id = table_[*hash_id];
1256 if (are_equal(node_id, unit_id)) {
1263inline bool DawgBuilder::are_equal(
id_type node_id,
id_type unit_id)
const {
1265 i = nodes_[i].sibling()) {
1266 if (units_[unit_id].has_sibling() ==
false) {
1271 if (units_[unit_id].has_sibling() ==
true) {
1275 for (
id_type i = node_id; i != 0; i = nodes_[i].sibling(), --unit_id) {
1276 if (nodes_[i].unit() != units_[unit_id].unit() ||
1277 nodes_[i].
label() != labels_[unit_id]) {
1286 for ( ;
id != 0; ++id) {
1287 id_type unit = units_[id].unit();
1289 hash_value ^= hash((
label << 24) ^ unit);
1291 if (units_[
id].has_sibling() ==
false) {
1300 for ( ;
id != 0;
id = nodes_[id].sibling()) {
1301 id_type unit = nodes_[id].unit();
1303 hash_value ^= hash((
label << 24) ^ unit);
1308inline id_type DawgBuilder::append_unit() {
1309 is_intersections_.append();
1313 return static_cast<id_type>(is_intersections_.size() - 1);
1316inline id_type DawgBuilder::append_node() {
1318 if (recycle_bin_.empty()) {
1319 id =
static_cast<id_type>(nodes_.size());
1322 id = recycle_bin_.top();
1341 unit_ &= ~(1U << 8);
1345 unit_ = value | (1U << 31);
1348 unit_ = (unit_ & ~0xFFU) | label;
1351 if (offset >= 1U << 29) {
1352 DARTS_THROW(
"failed to modify unit: too large offset");
1354 unit_ &= (1U << 31) | (1U << 8) | 0xFF;
1355 if (offset < 1U << 21) {
1356 unit_ |= (offset << 10);
1358 unit_ |= (offset << 2) | (1U << 9);
1375 is_fixed_(false), is_used_(false) {}
1419 : progress_func_(progress_func), units_(), extras_(), labels_(),
1420 table_(), extras_head_(0) {}
1425 template <
typename T>
1432 enum { BLOCK_SIZE = 256 };
1433 enum { NUM_EXTRA_BLOCKS = 16 };
1434 enum { NUM_EXTRAS = BLOCK_SIZE * NUM_EXTRA_BLOCKS };
1436 enum { UPPER_MASK = 0xFF << 21 };
1437 enum { LOWER_MASK = 0xFF };
1439 typedef DoubleArrayBuilderUnit unit_type;
1440 typedef DoubleArrayBuilderExtraUnit extra_type;
1443 AutoPool<unit_type> units_;
1444 AutoArray<extra_type> extras_;
1445 AutoPool<uchar_type> labels_;
1446 AutoArray<id_type> table_;
1453 std::size_t num_blocks()
const {
1454 return units_.size() / BLOCK_SIZE;
1457 const extra_type &extras(
id_type id)
const {
1458 return extras_[
id % NUM_EXTRAS];
1460 extra_type &extras(
id_type id) {
1461 return extras_[
id % NUM_EXTRAS];
1464 template <
typename T>
1465 void build_dawg(
const Keyset<T> &keyset, DawgBuilder *dawg_builder);
1466 void build_from_dawg(
const DawgBuilder &dawg);
1467 void build_from_dawg(
const DawgBuilder &dawg,
1469 id_type arrange_from_dawg(
const DawgBuilder &dawg,
1472 template <
typename T>
1473 void build_from_keyset(
const Keyset<T> &keyset);
1474 template <
typename T>
1475 void build_from_keyset(
const Keyset<T> &keyset, std::size_t begin,
1476 std::size_t end, std::size_t depth,
id_type dic_id);
1477 template <
typename T>
1478 id_type arrange_from_keyset(
const Keyset<T> &keyset, std::size_t begin,
1479 std::size_t end, std::size_t depth,
id_type dic_id);
1485 void expand_units();
1487 void fix_all_blocks();
1488 void fix_block(
id_type block_id);
1491template <
typename T>
1495 build_dawg(keyset, &dawg_builder);
1496 build_from_dawg(dawg_builder);
1497 dawg_builder.
clear();
1499 build_from_keyset(keyset);
1505 if (size_ptr != NULL) {
1506 *size_ptr = units_.size();
1508 if (buf_ptr != NULL) {
1510 unit_type *units =
reinterpret_cast<unit_type *
>(*buf_ptr);
1511 for (std::size_t i = 0; i < units_.size(); ++i) {
1512 units[i] = units_[i];
1525template <
typename T>
1526void DoubleArrayBuilder::build_dawg(
const Keyset<T> &keyset,
1528 dawg_builder->
init();
1529 for (std::size_t i = 0; i < keyset.
num_keys(); ++i) {
1531 if (progress_func_ != NULL) {
1532 progress_func_(i + 1, keyset.
num_keys() + 1);
1538inline void DoubleArrayBuilder::build_from_dawg(
const DawgBuilder &dawg) {
1539 std::size_t num_units = 1;
1540 while (num_units < dawg.size()) {
1543 units_.reserve(num_units);
1545 table_.reset(
new id_type[dawg.num_intersections()]);
1546 for (std::size_t i = 0; i < dawg.num_intersections(); ++i) {
1550 extras_.reset(
new extra_type[NUM_EXTRAS]);
1553 extras(0).set_is_used(
true);
1554 units_[0].set_offset(1);
1555 units_[0].set_label(
'\0');
1557 if (dawg.child(dawg.root()) != 0) {
1558 build_from_dawg(dawg, dawg.root(), 0);
1568inline void DoubleArrayBuilder::build_from_dawg(
const DawgBuilder &dawg,
1570 id_type dawg_child_id = dawg.child(dawg_id);
1571 if (dawg.is_intersection(dawg_child_id)) {
1572 id_type intersection_id = dawg.intersection_id(dawg_child_id);
1573 id_type offset = table_[intersection_id];
1576 if (!(offset & UPPER_MASK) || !(offset & LOWER_MASK)) {
1577 if (dawg.is_leaf(dawg_child_id)) {
1578 units_[dic_id].set_has_leaf(
true);
1580 units_[dic_id].set_offset(offset);
1586 id_type offset = arrange_from_dawg(dawg, dawg_id, dic_id);
1587 if (dawg.is_intersection(dawg_child_id)) {
1588 table_[dawg.intersection_id(dawg_child_id)] = offset;
1592 uchar_type child_label = dawg.label(dawg_child_id);
1593 id_type dic_child_id = offset ^ child_label;
1594 if (child_label !=
'\0') {
1595 build_from_dawg(dawg, dawg_child_id, dic_child_id);
1597 dawg_child_id = dawg.sibling(dawg_child_id);
1598 }
while (dawg_child_id != 0);
1605 id_type dawg_child_id = dawg.child(dawg_id);
1606 while (dawg_child_id != 0) {
1607 labels_.append(dawg.label(dawg_child_id));
1608 dawg_child_id = dawg.sibling(dawg_child_id);
1611 id_type offset = find_valid_offset(dic_id);
1612 units_[dic_id].set_offset(dic_id ^ offset);
1614 dawg_child_id = dawg.child(dawg_id);
1615 for (std::size_t i = 0; i < labels_.size(); ++i) {
1616 id_type dic_child_id = offset ^ labels_[i];
1617 reserve_id(dic_child_id);
1619 if (dawg.is_leaf(dawg_child_id)) {
1620 units_[dic_id].set_has_leaf(
true);
1621 units_[dic_child_id].set_value(dawg.value(dawg_child_id));
1623 units_[dic_child_id].set_label(labels_[i]);
1626 dawg_child_id = dawg.sibling(dawg_child_id);
1628 extras(offset).set_is_used(
true);
1633template <
typename T>
1634void DoubleArrayBuilder::build_from_keyset(
const Keyset<T> &keyset) {
1635 std::size_t num_units = 1;
1636 while (num_units < keyset.num_keys()) {
1639 units_.reserve(num_units);
1641 extras_.reset(
new extra_type[NUM_EXTRAS]);
1644 extras(0).set_is_used(
true);
1645 units_[0].set_offset(1);
1646 units_[0].set_label(
'\0');
1648 if (keyset.num_keys() > 0) {
1649 build_from_keyset(keyset, 0, keyset.num_keys(), 0, 0);
1658template <
typename T>
1659void DoubleArrayBuilder::build_from_keyset(
const Keyset<T> &keyset,
1660 std::size_t begin, std::size_t end, std::size_t depth,
id_type dic_id) {
1661 id_type offset = arrange_from_keyset(keyset, begin, end, depth, dic_id);
1663 while (begin < end) {
1664 if (keyset.keys(begin, depth) !=
'\0') {
1673 std::size_t last_begin = begin;
1674 uchar_type last_label = keyset.keys(begin, depth);
1675 while (++begin < end) {
1676 uchar_type label = keyset.keys(begin, depth);
1677 if (label != last_label) {
1678 build_from_keyset(keyset, last_begin, begin,
1679 depth + 1, offset ^ last_label);
1681 last_label = keyset.keys(begin, depth);
1684 build_from_keyset(keyset, last_begin, end, depth + 1, offset ^ last_label);
1687template <
typename T>
1689 std::size_t begin, std::size_t end, std::size_t depth,
id_type dic_id) {
1693 for (std::size_t i = begin; i < end; ++i) {
1695 if (label ==
'\0') {
1696 if (keyset.has_lengths() && depth < keyset.lengths(i)) {
1698 "invalid null character");
1699 }
else if (keyset.values(i) < 0) {
1700 DARTS_THROW(
"failed to build double-array: negative value");
1704 value = keyset.values(i);
1706 if (progress_func_ != NULL) {
1707 progress_func_(i + 1, keyset.num_keys() + 1);
1711 if (labels_.empty()) {
1712 labels_.append(label);
1713 }
else if (label != labels_[labels_.size() - 1]) {
1714 if (label < labels_[labels_.size() - 1]) {
1715 DARTS_THROW(
"failed to build double-array: wrong key order");
1717 labels_.append(label);
1721 id_type offset = find_valid_offset(dic_id);
1722 units_[dic_id].set_offset(dic_id ^ offset);
1724 for (std::size_t i = 0; i < labels_.size(); ++i) {
1725 id_type dic_child_id = offset ^ labels_[i];
1726 reserve_id(dic_child_id);
1727 if (labels_[i] ==
'\0') {
1728 units_[dic_id].set_has_leaf(
true);
1729 units_[dic_child_id].set_value(value);
1731 units_[dic_child_id].set_label(labels_[i]);
1734 extras(offset).set_is_used(
true);
1739inline id_type DoubleArrayBuilder::find_valid_offset(
id_type id)
const {
1740 if (extras_head_ >= units_.size()) {
1741 return units_.size() | (
id & LOWER_MASK);
1744 id_type unfixed_id = extras_head_;
1746 id_type offset = unfixed_id ^ labels_[0];
1747 if (is_valid_offset(
id, offset)) {
1750 unfixed_id = extras(unfixed_id).next();
1751 }
while (unfixed_id != extras_head_);
1753 return units_.size() | (
id & LOWER_MASK);
1756inline bool DoubleArrayBuilder::is_valid_offset(
id_type id,
1758 if (extras(offset).is_used()) {
1762 id_type rel_offset =
id ^ offset;
1763 if ((rel_offset & LOWER_MASK) && (rel_offset & UPPER_MASK)) {
1767 for (std::size_t i = 1; i < labels_.size(); ++i) {
1768 if (extras(offset ^ labels_[i]).is_fixed()) {
1776inline void DoubleArrayBuilder::reserve_id(
id_type id) {
1777 if (
id >= units_.size()) {
1781 if (
id == extras_head_) {
1782 extras_head_ = extras(
id).next();
1783 if (extras_head_ ==
id) {
1784 extras_head_ = units_.size();
1787 extras(extras(
id).prev()).set_next(extras(
id).
next());
1788 extras(extras(
id).
next()).set_prev(extras(
id).prev());
1789 extras(
id).set_is_fixed(
true);
1792inline void DoubleArrayBuilder::expand_units() {
1793 id_type src_num_units = units_.size();
1794 id_type src_num_blocks = num_blocks();
1796 id_type dest_num_units = src_num_units + BLOCK_SIZE;
1797 id_type dest_num_blocks = src_num_blocks + 1;
1799 if (dest_num_blocks > NUM_EXTRA_BLOCKS) {
1800 fix_block(src_num_blocks - NUM_EXTRA_BLOCKS);
1803 units_.resize(dest_num_units);
1805 if (dest_num_blocks > NUM_EXTRA_BLOCKS) {
1806 for (std::size_t
id = src_num_units;
id < dest_num_units; ++id) {
1807 extras(
id).set_is_used(
false);
1808 extras(
id).set_is_fixed(
false);
1812 for (
id_type i = src_num_units + 1; i < dest_num_units; ++i) {
1813 extras(i - 1).set_next(i);
1814 extras(i).set_prev(i - 1);
1817 extras(src_num_units).set_prev(dest_num_units - 1);
1818 extras(dest_num_units - 1).set_next(src_num_units);
1820 extras(src_num_units).set_prev(extras(extras_head_).prev());
1821 extras(dest_num_units - 1).set_next(extras_head_);
1823 extras(extras(extras_head_).prev()).set_next(src_num_units);
1824 extras(extras_head_).set_prev(dest_num_units - 1);
1827inline void DoubleArrayBuilder::fix_all_blocks() {
1829 if (num_blocks() > NUM_EXTRA_BLOCKS) {
1830 begin = num_blocks() - NUM_EXTRA_BLOCKS;
1834 for (
id_type block_id = begin; block_id != end; ++block_id) {
1835 fix_block(block_id);
1839inline void DoubleArrayBuilder::fix_block(
id_type block_id) {
1840 id_type begin = block_id * BLOCK_SIZE;
1841 id_type end = begin + BLOCK_SIZE;
1844 for (
id_type offset = begin; offset != end; ++offset) {
1845 if (!extras(offset).is_used()) {
1846 unused_offset = offset;
1851 for (
id_type id = begin;
id != end; ++id) {
1852 if (!extras(
id).is_fixed()) {
1854 units_[id].set_label(
static_cast<uchar_type>(
id ^ unused_offset));
1865template <
typename A,
typename B,
typename T,
typename C>
1867 const key_type *
const *keys,
const std::size_t *lengths,
1872 builder.
build(keyset);
1874 std::size_t
size = 0;
1875 unit_type *buf = NULL;
1884 if (progress_func != NULL) {
1885 progress_func(num_keys + 1, num_keys + 1);
1893#undef DARTS_INT_TO_STR
1894#undef DARTS_LINE_TO_STR
1895#undef DARTS_LINE_STR
#define DARTS_THROW(msg)
Definition darts.h:18
DoubleArrayImpl< void, void, int, void > DoubleArray
Definition darts.h:316
char char_type
Definition darts.h:33
unsigned int id_type
Definition darts.h:39
unsigned char uchar_type
Definition darts.h:34
int value_type
Definition darts.h:35
int(*) progress_func_type(std::size_t, std::size_t)
Definition darts.h:46
uint32_t next(octet_iterator &it, octet_iterator end)
Definition checked.h:123
value_type value() const
Definition darts.h:61
id_type label() const
Definition darts.h:68
DoubleArrayUnit()
Definition darts.h:52
id_type offset() const
Definition darts.h:72
bool has_leaf() const
Definition darts.h:56
virtual const char * what() const
Definition darts.h:94
virtual ~Exception()
Definition darts.h:91
Exception(const Exception &rhs)
Definition darts.h:90
Exception(const char *msg=NULL)
Definition darts.h:89
Details::char_type key_type
Definition darts.h:125
std::size_t total_size() const
Definition darts.h:204
virtual ~DoubleArrayImpl()
Definition darts.h:141
value_type result_type
Definition darts.h:128
void set_result(value_type *result, value_type value, std::size_t) const
Definition darts.h:154
int build(std::size_t num_keys, const key_type *const *keys, const std::size_t *lengths=NULL, const value_type *values=NULL, Details::progress_func_type progress_func=NULL)
Definition darts.h:1866
value_type traverse(const key_type *key, std::size_t &node_pos, std::size_t &key_pos, std::size_t length=0) const
Definition darts.h:489
DoubleArrayImpl()
Definition darts.h:138
std::size_t unit_size() const
Definition darts.h:195
U exactMatchSearch(const key_type *key, std::size_t length=0, std::size_t node_pos=0) const
Definition darts.h:407
std::size_t nonzero_size() const
Definition darts.h:209
const void * array() const
Definition darts.h:177
int open(const char *file_name, const char *mode="rb", std::size_t offset=0, std::size_t size=0)
Definition darts.h:327
int save(const char *file_name, const char *mode="wb", std::size_t offset=0) const
Definition darts.h:379
std::size_t size() const
Definition darts.h:199
std::size_t commonPrefixSearch(const key_type *key, U *results, std::size_t max_num_results, std::size_t length=0, std::size_t node_pos=0) const
Definition darts.h:441
T value_type
Definition darts.h:122
void set_array(const void *ptr, std::size_t size=0)
Definition darts.h:171
void exactMatchSearch(const key_type *key, U &result, std::size_t length=0, std::size_t node_pos=0) const
Definition darts.h:263
void set_result(result_pair_type *result, value_type value, std::size_t length) const
Definition darts.h:158
void clear()
Definition darts.h:185
value_type value
Definition darts.h:133
std::size_t length
Definition darts.h:134
bool empty() const
Definition darts.h:542
~AutoArray()
Definition darts.h:531
AutoArray(T *array=NULL)
Definition darts.h:530
const T & operator[](std::size_t id) const
Definition darts.h:535
void swap(AutoArray *array)
Definition darts.h:552
void reset(T *array=NULL)
Definition darts.h:557
T & operator[](std::size_t id)
Definition darts.h:538
void clear()
Definition darts.h:546
std::size_t size() const
Definition darts.h:589
void reserve(std::size_t size)
Definition darts.h:641
void pop_back()
Definition darts.h:603
AutoPool()
Definition darts.h:576
void append(const T &value)
Definition darts.h:612
void resize(std::size_t size, const T &value)
Definition darts.h:629
T & operator[](std::size_t id)
Definition darts.h:582
bool empty() const
Definition darts.h:586
const T & operator[](std::size_t id) const
Definition darts.h:579
~AutoPool()
Definition darts.h:577
void append()
Definition darts.h:607
void resize(std::size_t size)
Definition darts.h:618
void clear()
Definition darts.h:593
void push_back(const T &value)
Definition darts.h:600
void push(const T &value)
Definition darts.h:717
T & top()
Definition darts.h:706
bool empty() const
Definition darts.h:710
void pop()
Definition darts.h:720
~AutoStack()
Definition darts.h:699
std::size_t size() const
Definition darts.h:713
void clear()
Definition darts.h:724
const T & top() const
Definition darts.h:703
AutoStack()
Definition darts.h:698
~BitVector()
Definition darts.h:743
void clear()
Definition darts.h:783
bool operator[](std::size_t id) const
Definition darts.h:747
void build()
Definition darts.h:810
void set(std::size_t id, bool bit)
Definition darts.h:757
bool empty() const
Definition darts.h:765
std::size_t num_ones() const
Definition darts.h:768
id_type rank(std::size_t id) const
Definition darts.h:751
void append()
Definition darts.h:775
std::size_t size() const
Definition darts.h:771
BitVector()
Definition darts.h:742
const char_type * keys(std::size_t id) const
Definition darts.h:838
bool has_lengths() const
Definition darts.h:847
std::size_t lengths(std::size_t id) const
Definition darts.h:850
uchar_type keys(std::size_t key_id, std::size_t char_id) const
Definition darts.h:841
bool has_values() const
Definition darts.h:861
Keyset(std::size_t num_keys, const char_type *const *keys, const std::size_t *lengths, const T *values)
Definition darts.h:831
const value_type values(std::size_t id) const
Definition darts.h:864
std::size_t num_keys() const
Definition darts.h:835
id_type child() const
Definition darts.h:910
void set_is_state(bool is_state)
Definition darts.h:903
void set_label(uchar_type label)
Definition darts.h:900
bool is_state() const
Definition darts.h:922
id_type sibling() const
Definition darts.h:913
DawgNode()
Definition darts.h:888
id_type unit() const
Definition darts.h:929
void set_value(value_type value)
Definition darts.h:897
uchar_type label() const
Definition darts.h:919
void set_child(id_type child)
Definition darts.h:891
value_type value() const
Definition darts.h:916
void set_has_sibling(bool has_sibling)
Definition darts.h:906
bool has_sibling() const
Definition darts.h:925
void set_sibling(id_type sibling)
Definition darts.h:894
id_type unit() const
Definition darts.h:960
bool is_state() const
Definition darts.h:973
value_type value() const
Definition darts.h:970
DawgUnit(const DawgUnit &unit)
Definition darts.h:953
DawgUnit(id_type unit=0)
Definition darts.h:952
id_type child() const
Definition darts.h:964
bool has_sibling() const
Definition darts.h:967
DawgUnit & operator=(id_type unit)
Definition darts.h:955
std::size_t num_intersections() const
Definition darts.h:1023
id_type child(id_type id) const
Definition darts.h:999
void clear()
Definition darts.h:1165
void finish()
Definition darts.h:1096
~DawgBuilder()
Definition darts.h:991
void insert(const char *key, std::size_t length, value_type value)
Definition darts.h:1110
id_type intersection_id(id_type id) const
Definition darts.h:1019
id_type sibling(id_type id) const
Definition darts.h:1002
int value(id_type id) const
Definition darts.h:1005
uchar_type label(id_type id) const
Definition darts.h:1012
bool is_leaf(id_type id) const
Definition darts.h:1009
std::size_t size() const
Definition darts.h:1027
void init()
Definition darts.h:1084
id_type root() const
Definition darts.h:995
bool is_intersection(id_type id) const
Definition darts.h:1016
DawgBuilder()
Definition darts.h:989
void set_label(uchar_type label)
Definition darts.h:1347
void set_has_leaf(bool has_leaf)
Definition darts.h:1337
void set_value(value_type value)
Definition darts.h:1344
DoubleArrayBuilderUnit()
Definition darts.h:1335
void set_offset(id_type offset)
Definition darts.h:1350
void set_is_fixed(bool is_fixed)
Definition darts.h:1383
DoubleArrayBuilderExtraUnit()
Definition darts.h:1374
void set_is_used(bool is_used)
Definition darts.h:1386
void set_prev(id_type prev)
Definition darts.h:1377
bool is_fixed() const
Definition darts.h:1396
id_type prev() const
Definition darts.h:1390
void set_next(id_type next)
Definition darts.h:1380
bool is_used() const
Definition darts.h:1399
id_type next() const
Definition darts.h:1393
void build(const Keyset< T > &keyset)
Definition darts.h:1492
~DoubleArrayBuilder()
Definition darts.h:1421
DoubleArrayBuilder(progress_func_type progress_func)
Definition darts.h:1418
void clear()
Definition darts.h:1517
void copy(std::size_t *size_ptr, DoubleArrayUnit **buf_ptr) const
Definition darts.h:1503