10 #ifdef MDDS_TRIE_MAP_DEBUG
14 #include "mdds/global.hpp"
15 #include "mdds/ref_pair.hpp"
17 namespace mdds {
namespace trie {
namespace detail {
19 enum class iterator_type
40 enum empty_iterator_type
45 template<
typename _TrieType,
typename _C>
48 template<
typename _TrieType>
51 using type =
typename _TrieType::const_node_stack_type;
54 template<
typename _TrieType>
57 using type =
typename _TrieType::node_stack_type;
60 template<
typename _TrieType>
63 template<
typename _TrieType,
bool IsConst>
67 using trie_type = _TrieType;
69 using _is_const = std::bool_constant<IsConst>;
75 using trie_node_type = mdds::detail::const_t<typename trie_type::trie_node, IsConst>;
77 typename std::remove_const<trie_node_type>::type::children_type, _is_const>::type;
79 using key_type =
typename trie_type::key_type;
87 using difference_type = std::ptrdiff_t;
88 using iterator_category = std::bidirectional_iterator_tag;
91 node_stack_type m_node_stack;
93 key_type m_current_key;
94 trie_value_type* m_current_value_ptr;
97 static trie_node_type* push_child_node_to_stack(
98 node_stack_type& node_stack, key_type& buf, trie_node_child_pos_type& child_pos)
100 trie_node_type* node = &child_pos->second;
101 buf.push_back(child_pos->first);
102 node_stack.emplace_back(node, node->children.begin());
113 trie_node_type* cur_node =
nullptr;
120 auto& si = node_stack.back();
123 buf.push_back(si.child_pos->first);
124 cur_node = &si.child_pos->second;
125 node_stack.emplace_back(cur_node, cur_node->children.end());
126 }
while (!cur_node->children.empty());
131 iterator_base(empty_iterator_type) : m_current_value_ptr(nullptr), m_type(iterator_type::empty)
135 iterator_base() : m_current_value_ptr(nullptr), m_type(iterator_type::normal)
138 iterator_base(node_stack_type&& node_stack, key_type&& buf, iterator_type type)
139 : m_node_stack(std::move(node_stack)), m_buffer(std::move(buf)), m_current_key(m_buffer),
140 m_current_value_ptr(&m_node_stack.back().node->value), m_type(type)
143 bool operator==(
const iterator_base& other)
const
145 if (m_type != other.m_type)
148 if (m_type == iterator_type::empty)
151 return m_node_stack.back() == other.m_node_stack.back();
154 bool operator!=(
const iterator_base& other)
const
156 return !operator==(other);
159 value_type operator*()
161 return value_type(m_current_key, *m_current_value_ptr);
164 value_type operator->()
166 return value_type(m_current_key, *m_current_value_ptr);
169 iterator_base& operator++()
171 trie_node_type* cur_node = m_node_stack.back().node;
175 if (cur_node->children.empty())
182 if (m_node_stack.size() == 1)
184 #ifdef MDDS_TRIE_MAP_DEBUG
185 if (m_type == iterator_type::end)
187 std::ostringstream os;
188 os <<
"iterator_base::operator++#" << __LINE__ <<
": moving past the end position!";
189 throw general_error(os.str());
193 m_type = iterator_type::end;
199 m_node_stack.pop_back();
200 auto& si = m_node_stack.back();
203 if (si.child_pos != si.node->children.end())
206 cur_node = push_child_node_to_stack(m_node_stack, m_buffer, si.child_pos);
214 auto child_pos = cur_node->children.begin();
215 cur_node = push_child_node_to_stack(m_node_stack, m_buffer, child_pos);
217 }
while (!cur_node->has_value);
219 m_current_key = m_buffer;
220 m_current_value_ptr = &cur_node->value;
224 iterator_base operator++(
int)
226 iterator_base tmp(*
this);
231 iterator_base& operator--()
233 trie_node_type* cur_node = m_node_stack.back().node;
235 if (m_type == iterator_type::end && cur_node->has_value)
237 assert(m_node_stack.size() == 1);
238 m_type = iterator_type::normal;
240 else if (m_node_stack.size() == 1)
244 auto& si = m_node_stack.back();
245 assert(si.child_pos == cur_node->children.end());
247 m_type = iterator_type::normal;
249 else if (cur_node->children.empty())
260 m_node_stack.pop_back();
261 auto& si = m_node_stack.back();
264 if (si.child_pos != cur_node->children.begin())
268 assert(cur_node->has_value);
270 }
while (!cur_node->has_value);
277 assert(cur_node->has_value);
278 assert(m_node_stack.back().child_pos == cur_node->children.begin());
284 m_node_stack.pop_back();
285 auto& si = m_node_stack.back();
288 if (m_node_stack.size() == 1)
292 assert(cur_node->has_value);
294 }
while (!cur_node->has_value);
297 assert(cur_node->has_value);
298 m_current_key = m_buffer;
299 m_current_value_ptr = &cur_node->value;
303 iterator_base operator--(
int)
305 iterator_base tmp(*
this);
311 template<
typename _TrieType>
314 template<
typename _TrieType>
317 using trie_type = _TrieType;
324 using node_stack_type =
typename base_type::node_stack_type;
325 using key_type =
typename base_type::key_type;
334 iterator(node_stack_type&& node_stack, key_type&& buf, iterator_type type)
335 :
base_type(std::move(node_stack), std::move(buf), type)
339 template<
typename _TrieType>
342 using trie_type = _TrieType;
348 using node_stack_type =
typename base_type::node_stack_type;
349 using key_type =
typename base_type::key_type;
351 using base_type::m_buffer;
352 using base_type::m_current_key;
353 using base_type::m_current_value_ptr;
354 using base_type::m_node_stack;
355 using base_type::m_type;
361 const_iterator() : base_type()
364 const_iterator(node_stack_type&& node_stack, key_type&& buf, iterator_type type)
365 : base_type(std::move(node_stack), std::move(buf), type)
368 const_iterator(
const iterator<_TrieType>& it) : base_type()
370 m_buffer = it.m_buffer;
371 m_current_key = it.m_current_key;
372 m_current_value_ptr = it.m_current_value_ptr;
375 for (
const auto& e : it.m_node_stack)
376 m_node_stack.emplace_back(e.node, e.child_pos);
380 template<
typename _TrieType>
381 bool operator==(
const iterator<_TrieType>& left,
const const_iterator<_TrieType>& right)
383 return const_iterator<_TrieType>(left) == right;
386 template<
typename _TrieType>
387 bool operator!=(
const iterator<_TrieType>& left,
const const_iterator<_TrieType>& right)
389 return const_iterator<_TrieType>(left) != right;
392 template<
typename _TrieType>
393 bool operator==(
const const_iterator<_TrieType>& left,
const iterator<_TrieType>& right)
395 return left == const_iterator<_TrieType>(right);
398 template<
typename _TrieType>
399 bool operator!=(
const const_iterator<_TrieType>& left,
const iterator<_TrieType>& right)
401 return left != const_iterator<_TrieType>(right);
404 template<
typename _TrieType>
407 using trie_type = _TrieType;
409 using node_stack_type =
typename trie_type::const_node_stack_type;
411 using trie_node =
typename trie_type::trie_node;
412 using key_type =
typename trie_type::key_type;
413 using key_unit_type =
typename key_type::value_type;
415 const trie_node* m_node;
417 node_stack_type m_node_stack;
419 search_results(
const trie_node* node, key_type&& buf) : m_node(node), m_buffer(buf)
423 using const_iterator =
typename trie_type::const_iterator;
425 const_iterator begin()
const
429 return const_iterator(empty_iterator);
432 key_type buf(m_buffer);
433 node_stack_type node_stack;
434 node_stack.emplace_back(m_node, m_node->children.begin());
436 while (!node_stack.back().node->has_value)
441 auto it = node_stack.back().child_pos;
442 const_iterator::push_child_node_to_stack(node_stack, buf, it);
445 return const_iterator(std::move(node_stack), std::move(buf), iterator_type::normal);
448 const_iterator end()
const
452 return const_iterator(empty_iterator);
454 node_stack_type node_stack;
455 node_stack.emplace_back(m_node, m_node->children.end());
456 return const_iterator(std::move(node_stack), key_type(m_buffer), iterator_type::end);
460 template<
typename _TrieType>
463 template<
typename TrieT>
466 using trie_type = TrieT;
470 using stack_item =
typename trie_type::stack_item;
471 using node_stack_type =
typename trie_type::node_stack_type;
473 using key_type =
typename trie_type::key_type;
474 using size_type =
typename trie_type::size_type;
475 using trie_value_type =
typename trie_type::value_type;
476 using value_store_type =
typename trie_type::value_store_type;
477 using pack_value_type =
typename trie_type::pack_value_type;
478 using key_unit_type =
typename key_type::value_type;
485 using difference_type = std::ptrdiff_t;
486 using iterator_category = std::bidirectional_iterator_tag;
489 const value_store_type* m_value_store =
nullptr;
490 node_stack_type m_node_stack;
492 pack_value_type m_current_value = trie_type::null_value;
493 iterator_type m_type;
499 static void push_child_node_to_stack(
500 const value_store_type* value_store, node_stack_type& node_stack, key_type& buf,
501 const pack_value_type* child_pos)
504 const auto* node_pos = node_stack.back().node_pos;
506 key_unit_type c =
static_cast<key_unit_type
>(*child_pos);
509 auto offset =
static_cast<size_type
>(*child_pos);
511 const auto* p = node_pos;
513 size_type index_size = *p;
516 const auto* child_end = child_pos + index_size;
519 node_stack.emplace_back(value_store, node_pos, child_pos, child_end);
522 static void descend_to_previous_leaf_node(node_stack_type& node_stack, key_type& buf)
524 const pack_value_type* node_pos =
nullptr;
525 size_t index_size = 0;
532 stack_item* si = &node_stack.back();
533 node_pos = si->node_pos;
535 size_t offset = *si->child_pos;
537 key_unit_type c = *si->child_pos;
541 const auto* p = node_pos;
545 const auto* child_pos = p;
546 const auto* child_end = child_pos + index_size;
547 node_stack.emplace_back(node_stack.back().value_store, node_pos, child_end, child_end);
548 }
while (index_size);
559 const value_store_type* value_store, node_stack_type&& node_stack, key_type&& buf, pack_value_type pos)
560 : m_value_store(value_store), m_node_stack(std::move(node_stack)), m_buffer(std::move(buf)),
561 m_current_value(pos), m_type(iterator_type::normal)
564 packed_iterator_base(
const value_store_type* value_store, node_stack_type&& node_stack, key_type&& buf)
565 : m_value_store(value_store), m_node_stack(std::move(node_stack)), m_buffer(std::move(buf)),
566 m_type(iterator_type::end)
571 if (m_type != other.m_type)
574 if (m_type == iterator_type::empty)
577 return m_node_stack.back() == other.m_node_stack.back();
582 return !operator==(other);
587 assert(m_value_store);
588 assert(m_current_value != trie_type::null_value);
589 return value_type(m_buffer, (*m_value_store)[m_current_value]);
594 assert(m_value_store);
595 assert(m_current_value != trie_type::null_value);
596 return value_type(m_buffer, (*m_value_store)[m_current_value]);
601 stack_item* si = &m_node_stack.back();
602 pack_value_type v = trie_type::null_value;
603 size_t index_size = *(si->node_pos + 1);
614 if (m_node_stack.size() == 1)
616 #ifdef MDDS_TRIE_MAP_DEBUG
617 if (m_type == iterator_type::end)
619 std::ostringstream os;
620 os <<
"packed_iterator_base::operator++#" << __LINE__ <<
": moving past the end position!";
625 m_type = iterator_type::end;
631 m_node_stack.pop_back();
632 si = &m_node_stack.back();
633 std::advance(si->child_pos, 2);
635 if (si->child_pos != si->child_end)
638 push_child_node_to_stack(m_value_store, m_node_stack, m_buffer, si->child_pos);
646 push_child_node_to_stack(m_value_store, m_node_stack, m_buffer, si->child_pos);
649 si = &m_node_stack.back();
651 index_size = *(si->node_pos + 1);
652 }
while (v == trie_type::null_value);
654 assert(v != trie_type::null_value);
669 stack_item* si = &m_node_stack.back();
670 pack_value_type v = *si->node_pos;
671 size_t index_size = *(si->node_pos + 1);
673 if (m_type == iterator_type::end && v != trie_type::null_value)
675 assert(m_node_stack.size() == 1);
676 m_type = iterator_type::normal;
678 else if (m_node_stack.size() == 1)
682 assert(si->child_pos == si->child_end);
683 descend_to_previous_leaf_node(m_node_stack, m_buffer);
684 si = &m_node_stack.back();
686 m_type = iterator_type::normal;
688 else if (!index_size)
699 m_node_stack.pop_back();
700 si = &m_node_stack.back();
701 const auto* p = si->node_pos;
706 const auto* first_child = p;
708 if (si->child_pos != first_child)
711 descend_to_previous_leaf_node(m_node_stack, m_buffer);
712 si = &m_node_stack.back();
715 assert(v != trie_type::null_value);
717 }
while (v == trie_type::null_value);
724 assert(*si->node_pos);
725 assert(si->child_pos == (si->node_pos + 2));
731 m_node_stack.pop_back();
732 si = &m_node_stack.back();
735 if (m_node_stack.size() == 1)
738 descend_to_previous_leaf_node(m_node_stack, m_buffer);
739 si = &m_node_stack.back();
741 assert(v != trie_type::null_value);
743 }
while (v == trie_type::null_value);
746 assert(v != trie_type::null_value);
760 template<
typename _TrieType>
763 using trie_type = _TrieType;
765 using node_stack_type =
typename trie_type::node_stack_type;
766 using value_store_type =
typename trie_type::value_store_type;
767 using pack_value_type =
typename trie_type::pack_value_type;
769 using key_type =
typename trie_type::key_type;
770 using key_unit_type =
typename key_type::value_type;
772 const value_store_type* m_value_store =
nullptr;
773 const pack_value_type* m_node =
nullptr;
776 packed_search_results(
const value_store_type* value_store,
const pack_value_type* node, key_type&& buf)
777 : m_value_store(value_store), m_node(node), m_buffer(std::move(buf))
779 assert(m_value_store);
782 node_stack_type get_root_node()
const
784 const auto* p = m_node;
786 size_t index_size = *p;
788 const auto* child_pos = p;
789 const auto* child_end = child_pos + index_size;
792 node_stack_type node_stack;
793 node_stack.emplace_back(m_value_store, m_node, child_pos, child_end);
797 void swap(packed_search_results& other)
799 std::swap(m_node, other.m_node);
800 std::swap(m_buffer, other.m_buffer);
804 using const_iterator = packed_iterator_base<trie_type>;
806 packed_search_results() : m_node(nullptr)
809 packed_search_results(
const packed_search_results& other) : m_node(other.m_node), m_buffer(other.m_buffer)
812 packed_search_results(packed_search_results&& other) : m_node(other.m_node), m_buffer(std::move(other.m_buffer))
814 other.m_node =
nullptr;
817 packed_search_results& operator=(packed_search_results other)
819 packed_search_results tmp(std::move(other));
824 const_iterator begin()
const
828 return const_iterator(empty_iterator);
831 key_type buf(m_buffer);
832 node_stack_type node_stack = get_root_node();
834 while (!node_stack.back().has_value())
839 const_iterator::push_child_node_to_stack(m_value_store, node_stack, buf, node_stack.back().child_pos);
842 return const_iterator(m_value_store, std::move(node_stack), std::move(buf), node_stack.back().get_value_pos());
845 const_iterator end()
const
849 return const_iterator(empty_iterator);
851 node_stack_type node_stack = get_root_node();
852 auto& si = node_stack.back();
853 si.child_pos = si.child_end;
854 return const_iterator(m_value_store, std::move(node_stack), key_type(m_buffer));
Definition: trie_map_itr.hpp:464
static trie_node_type * descend_to_previus_leaf_node(node_stack_type &node_stack, key_type &buf)
Definition: trie_map_itr.hpp:111
Definition: trie_map_itr.hpp:315
Definition: ref_pair.hpp:14
Definition: trie_map_itr.hpp:64
Definition: trie_map_itr.hpp:312
Definition: trie_map_itr.hpp:61
Definition: global.hpp:158
Definition: global.hpp:59
Definition: global.hpp:122
Definition: cref_wrapper.hpp:12
Definition: trie_map_itr.hpp:46
Definition: trie_map_itr.hpp:461