tetengo 1.9.2
A multipurpose library set
Loading...
Searching...
No Matches
trie.hpp
Go to the documentation of this file.
1
6
7#if !defined(TETENGO_TRIE_TRIE_HPP)
8#define TETENGO_TRIE_TRIE_HPP
9
10#include <algorithm> // IWYU pragma: keep
11#include <any>
12#include <cstddef>
13#include <functional>
14#include <initializer_list>
15#include <iterator>
16#include <memory>
17#include <string>
18#include <string_view>
19#include <type_traits>
20#include <utility>
21#include <vector>
22
23#include <boost/core/noncopyable.hpp>
24
25#include <tetengo/trie/default_serializer.hpp> // IWYU pragma: keep
27
28
29namespace tetengo::trie
30{
31 template <typename Object, typename>
32 class default_serializer; // IWYU pragma: keep
33
34 class double_array;
35 class storage;
36
37
41 class trie_impl : private boost::noncopyable
42 {
43 public:
44 // types
45
48 {
55 std::function<void(const std::string_view& serialized_key)> adding;
56
60 std::function<void()> done;
61 };
62
63
64 // static functions
65
72
78 [[nodiscard]] static std::size_t default_double_array_density_factor();
79
80
81 // constructors and destructor
82
87
96 std::vector<std::pair<std::string_view, std::any>> elements,
97 const building_observer_set_type& building_observer_set,
98 std::size_t double_array_density_factor);
99
108 std::vector<std::pair<std::string, std::any>> elements,
109 const building_observer_set_type& building_observer_set,
110 std::size_t double_array_density_factor);
111
117 explicit trie_impl(std::unique_ptr<storage>&& p_storage);
118
124 explicit trie_impl(std::unique_ptr<double_array>&& p_double_array);
125
131 trie_impl(trie_impl&& another) noexcept;
132
137
138
139 // functions
140
147 [[nodiscard]] bool empty() const;
148
154 [[nodiscard]] std::size_t size() const;
155
164 [[nodiscard]] bool contains(const std::string_view& key) const;
165
173 [[nodiscard]] const std::any* find(const std::string_view& key) const;
174
180 [[nodiscard]] trie_iterator_impl begin() const;
181
187 [[nodiscard]] trie_iterator_impl end() const;
188
197 [[nodiscard]] std::unique_ptr<trie_impl> subtrie(const std::string_view& key_prefix) const;
198
204 [[nodiscard]] const storage& get_storage() const;
205
206
207 private:
208 // types
209
210 class impl;
211
212
213 // variables
214
215 std::unique_ptr<impl> m_p_impl;
216 };
217
218
226 template <typename Key, typename Value, typename KeySerializer = default_serializer<Key, void>>
227 class trie : private boost::noncopyable
228 {
229 public:
230 // types
231
233 using key_type = Key;
234
236 using value_type = Value;
237
239 using key_serializer_type = KeySerializer;
240
243
246
247
248 // static functions
249
259
265 [[nodiscard]] static std::size_t default_double_array_density_factor()
266 {
268 }
269
270
271 // constructors and destructor
272
278 explicit trie(const key_serializer_type& key_serializer = default_serializer<key_type, void>{ true }) :
279 m_impl{},
280 m_key_serializer{ key_serializer }
281 {}
282
291 explicit trie(
292 std::initializer_list<std::pair<key_type, value_type>> elements,
293 const key_serializer_type& key_serializer = default_serializer<key_type, void>{ true },
294 const building_observer_set_type& building_observer_set = null_building_observer_set(),
295 std::size_t double_array_density_factor = default_double_array_density_factor()) :
296 m_impl{ serialize_key<true>(std::begin(elements), std::end(elements), key_serializer),
297 building_observer_set,
298 double_array_density_factor },
299 m_key_serializer{ key_serializer }
300 {}
301
313 template <typename InputIterator>
315 InputIterator first,
316 InputIterator last,
317 const key_serializer_type& key_serializer = default_serializer<key_type, void>{ true },
318 const building_observer_set_type& building_observer_set = null_building_observer_set(),
319 std::size_t double_array_density_factor = default_double_array_density_factor()) :
320 m_impl{ serialize_key<false>(first, last, key_serializer), building_observer_set, double_array_density_factor },
321 m_key_serializer{ key_serializer }
322 {}
323
335 template <typename InputIterator>
337 std::move_iterator<InputIterator> first,
338 std::move_iterator<InputIterator> last,
339 const key_serializer_type& key_serializer = default_serializer<key_type, void>{ true },
340 const building_observer_set_type& building_observer_set = null_building_observer_set(),
341 std::size_t double_array_density_factor = default_double_array_density_factor()) :
342 m_impl{ serialize_key<true>(first, last, key_serializer), building_observer_set, double_array_density_factor },
343 m_key_serializer{ key_serializer }
344 {}
345
352 explicit trie(
353 std::unique_ptr<storage>&& p_storage,
354 const key_serializer_type& key_serializer = default_serializer<key_type, void>{ true }) :
355 m_impl{ std::move(p_storage) },
356 m_key_serializer{ key_serializer }
357 {}
358
359
360 // functions
361
368 [[nodiscard]] bool empty() const
369 {
370 return std::empty(m_impl);
371 }
372
378 [[nodiscard]] std::size_t size() const
379 {
380 return std::size(m_impl);
381 }
382
391 [[nodiscard]] bool contains(const key_type& key) const
392 {
393 if constexpr (std::is_same_v<key_type, std::string_view> || std::is_same_v<key_type, std::string>)
394 {
395 return m_impl.contains(m_key_serializer(key));
396 }
397 else
398 {
399 const auto serialized_key = m_key_serializer(key);
400 return m_impl.contains(std::string_view{ std::data(serialized_key), std::size(serialized_key) });
401 }
402 }
403
411 [[nodiscard]] const value_type* find(const key_type& key) const
412 {
413 const auto* const p_found = [this, &key]() {
414 if constexpr (std::is_same_v<key_type, std::string_view> || std::is_same_v<key_type, std::string>)
415 {
416 return m_impl.find(m_key_serializer(key));
417 }
418 else
419 {
420 const auto serialized_key = m_key_serializer(key);
421 return m_impl.find(std::string_view{ std::data(serialized_key), std::size(serialized_key) });
422 }
423 }();
424 if (!p_found)
425 {
426 return nullptr;
427 }
428 return std::any_cast<value_type>(p_found);
429 }
430
436 [[nodiscard]] iterator begin() const
437 {
438 return iterator{ std::move(std::begin(m_impl)) };
439 }
440
446 [[nodiscard]] iterator end() const
447 {
448 return iterator{ std::move(std::end(m_impl)) };
449 }
450
459 [[nodiscard]] std::unique_ptr<trie> subtrie(const key_type& key_prefix) const
460 {
461 auto p_trie_impl = [this, &key_prefix]() {
462 if constexpr (std::is_same_v<key_type, std::string_view> || std::is_same_v<key_type, std::string>)
463 {
464 return m_impl.subtrie(m_key_serializer(key_prefix));
465 }
466 else
467 {
468 const auto serialized_key_prefix = m_key_serializer(key_prefix);
469 return m_impl.subtrie(
470 std::string_view{ std::data(serialized_key_prefix), std::size(serialized_key_prefix) });
471 }
472 }();
473 if (!p_trie_impl)
474 {
475 return nullptr;
476 }
477 std::unique_ptr<trie> p_trie{ new trie{ std::move(p_trie_impl), m_key_serializer } };
478 return p_trie;
479 }
480
486 [[nodiscard]] const storage& get_storage() const
487 {
488 return m_impl.get_storage();
489 }
490
491
492 private:
493 // types
494
495 using serialized_element_type = std::pair<
496 std::conditional_t<std::is_same_v<key_type, std::string_view>, std::string_view, std::string>,
497 std::any>;
498
499
500 // static functions
501
502 template <bool MoveValue, typename InputIterator>
503 static std::vector<serialized_element_type>
504 serialize_key(InputIterator first, InputIterator last, const key_serializer_type& key_serializer)
505 {
506 std::vector<serialized_element_type> serialized{};
507 if constexpr (std::is_convertible_v<
508 typename std::iterator_traits<InputIterator>::iterator_category,
509 std::forward_iterator_tag>)
510 {
511 serialized.reserve(std::distance(first, last));
512 }
513 std::transform(first, last, std::back_inserter(serialized), [&key_serializer](auto&& value) {
514 if constexpr (std::is_same_v<key_type, std::string_view> || std::is_same_v<key_type, std::string>)
515 {
516 if constexpr (MoveValue)
517 {
518 return serialized_element_type{ key_serializer(value.first), std::move(value.second) };
519 }
520 else
521 {
522 return serialized_element_type{ key_serializer(value.first), value.second };
523 }
524 }
525 else
526 {
527 const auto serialized_key_vector = key_serializer(value.first);
528 std::string serialized_key{ std::begin(serialized_key_vector), std::end(serialized_key_vector) };
529 if constexpr (MoveValue)
530 {
531 return serialized_element_type{ std::move(serialized_key), std::move(value.second) };
532 }
533 else
534 {
535 return serialized_element_type{ std::move(serialized_key), value.second };
536 }
537 }
538 });
539 return serialized;
540 }
541
542
543 // variables
544
545 const trie_impl m_impl;
546
547 const key_serializer_type m_key_serializer;
548
549
550 // constructors
551
552 explicit trie(std::unique_ptr<trie_impl>&& p_impl, const key_serializer_type& ker_serializer) :
553 m_impl{ std::move(*p_impl) },
554 m_key_serializer{ ker_serializer }
555 {}
556 };
557
558
559}
560
561
562#endif
A default serializer.
Definition default_serializer.hpp:36
A double array.
Definition double_array.hpp:33
A storage.
Definition storage.hpp:28
std::unique_ptr< trie_impl > subtrie(const std::string_view &key_prefix) const
Returns a subtrie.
static const building_observer_set_type & null_building_observer_set()
Returns the null building observer set.
trie_impl()
Creates an implementation of trie.
bool contains(const std::string_view &key) const
Returns true when the trie contains the given key.
std::size_t size() const
Returns the size of the trie.
trie_iterator_impl end() const
Returns the last iterator.
trie_impl(std::vector< std::pair< std::string, std::any > > elements, const building_observer_set_type &building_observer_set, std::size_t double_array_density_factor)
Creates a trie.
const std::any * find(const std::string_view &key) const
Finds the value object correspoinding the given key.
bool empty() const
Returns true when the trie is empty.
trie_impl(trie_impl &&another) noexcept
Moves a trie.
trie_impl(std::unique_ptr< storage > &&p_storage)
Creates a trie.
const storage & get_storage() const
Returns the storage.
static std::size_t default_double_array_density_factor()
Returns the default double array density factor.
trie_impl(std::vector< std::pair< std::string_view, std::any > > elements, const building_observer_set_type &building_observer_set, std::size_t double_array_density_factor)
Creates a trie.
trie_impl(std::unique_ptr< double_array > &&p_double_array)
Creates a trie.
trie_iterator_impl begin() const
Returns the first iterator.
~trie_impl()
Destroys an implementation of trie.
An implementation of trie iterator.
Definition trie_iterator.hpp:28
A trie iterator.
Definition trie_iterator.hpp:102
const storage & get_storage() const
Returns the storage.
Definition trie.hpp:486
trie_impl::building_observer_set_type building_observer_set_type
The building observer set type.
Definition trie.hpp:245
bool contains(const key_type &key) const
Returns true when the trie contains the given key.
Definition trie.hpp:391
std::size_t size() const
Returns the size of the trie.
Definition trie.hpp:378
bool empty() const
Returns true when the trie is empty.
Definition trie.hpp:368
iterator begin() const
Returns the first iterator.
Definition trie.hpp:436
trie(const key_serializer_type &key_serializer=default_serializer< key_type, void >{ true })
Creates a trie.
Definition trie.hpp:278
static const building_observer_set_type & null_building_observer_set()
Returns the null building observer set.
Definition trie.hpp:255
trie(std::unique_ptr< storage > &&p_storage, const key_serializer_type &key_serializer=default_serializer< key_type, void >{ true })
Creates a trie.
Definition trie.hpp:352
trie(std::move_iterator< InputIterator > first, std::move_iterator< InputIterator > last, const key_serializer_type &key_serializer=default_serializer< key_type, void >{ true }, const building_observer_set_type &building_observer_set=null_building_observer_set(), std::size_t double_array_density_factor=default_double_array_density_factor())
Creates a trie.
Definition trie.hpp:336
trie(std::initializer_list< std::pair< key_type, value_type > > elements, const key_serializer_type &key_serializer=default_serializer< key_type, void >{ true }, const building_observer_set_type &building_observer_set=null_building_observer_set(), std::size_t double_array_density_factor=default_double_array_density_factor())
Creates a trie.
Definition trie.hpp:291
Value value_type
The value type.
Definition trie.hpp:236
const value_type * find(const key_type &key) const
Finds the value object correspoinding the given key.
Definition trie.hpp:411
iterator end() const
Returns the last iterator.
Definition trie.hpp:446
static std::size_t default_double_array_density_factor()
Returns the default double array density factor.
Definition trie.hpp:265
trie_iterator< value_type > iterator
The iterator type.
Definition trie.hpp:242
KeySerializer key_serializer_type
The key serializer_type.
Definition trie.hpp:239
trie(InputIterator first, InputIterator last, const key_serializer_type &key_serializer=default_serializer< key_type, void >{ true }, const building_observer_set_type &building_observer_set=null_building_observer_set(), std::size_t double_array_density_factor=default_double_array_density_factor())
Creates a trie.
Definition trie.hpp:314
Key key_type
The key type.
Definition trie.hpp:233
std::unique_ptr< trie > subtrie(const key_type &key_prefix) const
Returns a subtrie.
Definition trie.hpp:459
A default serializer.
A trie library.
The building observer set type.
Definition trie.hpp:48
std::function< void(const std::string_view &serialized_key)> adding
Called when a key is adding.
Definition trie.hpp:55
std::function< void()> done
Called when the building is done.
Definition trie.hpp:60
A trie iterator.