tetengo 1.8.2
A multipurpose library set
Loading...
Searching...
No Matches
trie.hpp
Go to the documentation of this file.
1
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
27
28
29namespace tetengo::trie
30{
31 class double_array;
32 class storage;
33
34
38 class trie_impl : private boost::noncopyable
39 {
40 public:
41 // types
42
45 {
52 std::function<void(const std::string_view& serialized_key)> adding;
53
57 std::function<void()> done;
58 };
59
60
61 // static functions
62
69
75 [[nodiscard]] static std::size_t default_double_array_density_factor();
76
77
78 // constructors and destructor
79
84
93 std::vector<std::pair<std::string_view, std::any>> elements,
94 const building_observer_set_type& building_observer_set,
95 std::size_t double_array_density_factor);
96
105 std::vector<std::pair<std::string, std::any>> elements,
106 const building_observer_set_type& building_observer_set,
107 std::size_t double_array_density_factor);
108
114 explicit trie_impl(std::unique_ptr<storage>&& p_storage);
115
121 explicit trie_impl(std::unique_ptr<double_array>&& p_double_array);
122
128 trie_impl(trie_impl&& another) noexcept;
129
134
135
136 // functions
137
144 [[nodiscard]] bool empty() const;
145
151 [[nodiscard]] std::size_t size() const;
152
161 [[nodiscard]] bool contains(const std::string_view& key) const;
162
170 [[nodiscard]] const std::any* find(const std::string_view& key) const;
171
177 [[nodiscard]] trie_iterator_impl begin() const;
178
184 [[nodiscard]] trie_iterator_impl end() const;
185
194 [[nodiscard]] std::unique_ptr<trie_impl> subtrie(const std::string_view& key_prefix) const;
195
201 [[nodiscard]] const storage& get_storage() const;
202
203
204 private:
205 // types
206
207 class impl;
208
209
210 // variables
211
212 std::unique_ptr<impl> m_p_impl;
213 };
214
215
223 template <typename Key, typename Value, typename KeySerializer = default_serializer<Key>>
224 class trie : private boost::noncopyable
225 {
226 public:
227 // types
228
230 using key_type = Key;
231
233 using value_type = Value;
234
236 using key_serializer_type = KeySerializer;
237
240
243
244
245 // static functions
246
256
262 [[nodiscard]] static std::size_t default_double_array_density_factor()
263 {
265 }
266
267
268 // constructors and destructor
269
275 explicit trie(const key_serializer_type& key_serializer = default_serializer<key_type>{ true }) :
276 m_impl{},
277 m_key_serializer{ key_serializer }
278 {}
279
288 explicit trie(
289 std::initializer_list<std::pair<key_type, value_type>> elements,
290 const key_serializer_type& key_serializer = default_serializer<key_type>{ true },
291 const building_observer_set_type& building_observer_set = null_building_observer_set(),
292 std::size_t double_array_density_factor = default_double_array_density_factor()) :
293 m_impl{ serialize_key<true>(std::begin(elements), std::end(elements), key_serializer),
294 building_observer_set,
295 double_array_density_factor },
296 m_key_serializer{ key_serializer }
297 {}
298
310 template <typename InputIterator>
312 InputIterator first,
313 InputIterator last,
314 const key_serializer_type& key_serializer = default_serializer<key_type>{ true },
315 const building_observer_set_type& building_observer_set = null_building_observer_set(),
316 std::size_t double_array_density_factor = default_double_array_density_factor()) :
317 m_impl{ serialize_key<false>(first, last, key_serializer), building_observer_set, double_array_density_factor },
318 m_key_serializer{ key_serializer }
319 {}
320
332 template <typename InputIterator>
334 std::move_iterator<InputIterator> first,
335 std::move_iterator<InputIterator> last,
336 const key_serializer_type& key_serializer = default_serializer<key_type>{ true },
337 const building_observer_set_type& building_observer_set = null_building_observer_set(),
338 std::size_t double_array_density_factor = default_double_array_density_factor()) :
339 m_impl{ serialize_key<true>(first, last, key_serializer), building_observer_set, double_array_density_factor },
340 m_key_serializer{ key_serializer }
341 {}
342
349 explicit trie(
350 std::unique_ptr<storage>&& p_storage,
351 const key_serializer_type& key_serializer = default_serializer<key_type>{ true }) :
352 m_impl{ std::move(p_storage) },
353 m_key_serializer{ key_serializer }
354 {}
355
356
357 // functions
358
365 [[nodiscard]] bool empty() const
366 {
367 return std::empty(m_impl);
368 }
369
375 [[nodiscard]] std::size_t size() const
376 {
377 return std::size(m_impl);
378 }
379
388 [[nodiscard]] bool contains(const key_type& key) const
389 {
390 if constexpr (std::is_same_v<key_type, std::string_view> || std::is_same_v<key_type, std::string>)
391 {
392 return m_impl.contains(m_key_serializer(key));
393 }
394 else
395 {
396 const auto serialized_key = m_key_serializer(key);
397 return m_impl.contains(std::string_view{ std::data(serialized_key), std::size(serialized_key) });
398 }
399 }
400
408 [[nodiscard]] const value_type* find(const key_type& key) const
409 {
410 const auto* const p_found = [this, &key]() {
411 if constexpr (std::is_same_v<key_type, std::string_view> || std::is_same_v<key_type, std::string>)
412 {
413 return m_impl.find(m_key_serializer(key));
414 }
415 else
416 {
417 const auto serialized_key = m_key_serializer(key);
418 return m_impl.find(std::string_view{ std::data(serialized_key), std::size(serialized_key) });
419 }
420 }();
421 if (!p_found)
422 {
423 return nullptr;
424 }
425 return std::any_cast<value_type>(p_found);
426 }
427
433 [[nodiscard]] iterator begin() const
434 {
435 return iterator{ std::move(std::begin(m_impl)) };
436 }
437
443 [[nodiscard]] iterator end() const
444 {
445 return iterator{ std::move(std::end(m_impl)) };
446 }
447
456 [[nodiscard]] std::unique_ptr<trie> subtrie(const key_type& key_prefix) const
457 {
458 auto p_trie_impl = [this, &key_prefix]() {
459 if constexpr (std::is_same_v<key_type, std::string_view> || std::is_same_v<key_type, std::string>)
460 {
461 return m_impl.subtrie(m_key_serializer(key_prefix));
462 }
463 else
464 {
465 const auto serialized_key_prefix = m_key_serializer(key_prefix);
466 return m_impl.subtrie(
467 std::string_view{ std::data(serialized_key_prefix), std::size(serialized_key_prefix) });
468 }
469 }();
470 if (!p_trie_impl)
471 {
472 return nullptr;
473 }
474 std::unique_ptr<trie> p_trie{ new trie{ std::move(p_trie_impl), m_key_serializer } };
475 return p_trie;
476 }
477
483 [[nodiscard]] const storage& get_storage() const
484 {
485 return m_impl.get_storage();
486 }
487
488
489 private:
490 // types
491
492 using serialized_element_type = std::pair<
493 std::conditional_t<std::is_same_v<key_type, std::string_view>, std::string_view, std::string>,
494 std::any>;
495
496
497 // static functions
498
499 template <bool MoveValue, typename InputIterator>
500 static std::vector<serialized_element_type>
501 serialize_key(InputIterator first, InputIterator last, const key_serializer_type& key_serializer)
502 {
503 std::vector<serialized_element_type> serialized{};
504 if constexpr (std::is_convertible_v<
505 typename std::iterator_traits<InputIterator>::iterator_category,
506 std::forward_iterator_tag>)
507 {
508 serialized.reserve(std::distance(first, last));
509 }
510 std::transform(first, last, std::back_inserter(serialized), [&key_serializer](auto&& value) {
511 if constexpr (std::is_same_v<key_type, std::string_view> || std::is_same_v<key_type, std::string>)
512 {
513 if constexpr (MoveValue)
514 {
515 return serialized_element_type{ key_serializer(value.first), std::move(value.second) };
516 }
517 else
518 {
519 return serialized_element_type{ key_serializer(value.first), value.second };
520 }
521 }
522 else
523 {
524 const auto serialized_key_vector = key_serializer(value.first);
525 std::string serialized_key{ std::begin(serialized_key_vector), std::end(serialized_key_vector) };
526 if constexpr (MoveValue)
527 {
528 return serialized_element_type{ std::move(serialized_key), std::move(value.second) };
529 }
530 else
531 {
532 return serialized_element_type{ std::move(serialized_key), value.second };
533 }
534 }
535 });
536 return serialized;
537 }
538
539
540 // variables
541
542 const trie_impl m_impl;
543
544 const key_serializer_type m_key_serializer;
545
546
547 // constructors
548
549 explicit trie(std::unique_ptr<trie_impl>&& p_impl, const key_serializer_type& ker_serializer) :
550 m_impl{ std::move(*p_impl) },
551 m_key_serializer{ ker_serializer }
552 {}
553 };
554
555
556}
557
558
559#endif
A default serializer.
Definition default_serializer.hpp:36
A storage.
Definition storage.hpp:28
An implementation of trie.
Definition trie.hpp:39
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
A trie.
Definition trie.hpp:225
const storage & get_storage() const
Returns the storage.
Definition trie.hpp:483
trie_impl::building_observer_set_type building_observer_set_type
The building observer set type.
Definition trie.hpp:242
bool contains(const key_type &key) const
Returns true when the trie contains the given key.
Definition trie.hpp:388
std::size_t size() const
Returns the size of the trie.
Definition trie.hpp:375
bool empty() const
Returns true when the trie is empty.
Definition trie.hpp:365
trie(std::unique_ptr< storage > &&p_storage, const key_serializer_type &key_serializer=default_serializer< key_type >{ true })
Creates a trie.
Definition trie.hpp:349
iterator begin() const
Returns the first iterator.
Definition trie.hpp:433
trie(InputIterator first, InputIterator last, const key_serializer_type &key_serializer=default_serializer< key_type >{ 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:311
static const building_observer_set_type & null_building_observer_set()
Returns the null building observer set.
Definition trie.hpp:252
Value value_type
The value type.
Definition trie.hpp:233
const value_type * find(const key_type &key) const
Finds the value object correspoinding the given key.
Definition trie.hpp:408
trie(std::initializer_list< std::pair< key_type, value_type > > elements, const key_serializer_type &key_serializer=default_serializer< key_type >{ 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:288
iterator end() const
Returns the last iterator.
Definition trie.hpp:443
trie(std::move_iterator< InputIterator > first, std::move_iterator< InputIterator > last, const key_serializer_type &key_serializer=default_serializer< key_type >{ 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:333
static std::size_t default_double_array_density_factor()
Returns the default double array density factor.
Definition trie.hpp:262
KeySerializer key_serializer_type
The key serializer_type.
Definition trie.hpp:236
trie(const key_serializer_type &key_serializer=default_serializer< key_type >{ true })
Creates a trie.
Definition trie.hpp:275
Key key_type
The key type.
Definition trie.hpp:230
std::unique_ptr< trie > subtrie(const key_type &key_prefix) const
Returns a subtrie.
Definition trie.hpp:456
A default serializer.
A trie library.
The building observer set type.
Definition trie.hpp:45
std::function< void(const std::string_view &serialized_key)> adding
Called when a key is adding.
Definition trie.hpp:52
std::function< void()> done
Called when the building is done.
Definition trie.hpp:57
A trie iterator.