first_symbol_iterator.h 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. #pragma once
  2. #include "opaque_trie_iterator.h"
  3. #include <util/generic/ptr.h>
  4. namespace NCompactTrie {
  5. // Iterates over possible first symbols in a trie.
  6. // Allows one to get the symbol and the subtrie starting from it.
  7. template <class TTrie>
  8. class TFirstSymbolIterator {
  9. public:
  10. using TSymbol = typename TTrie::TSymbol;
  11. using TData = typename TTrie::TData;
  12. void SetTrie(const TTrie& trie, const ILeafSkipper& skipper) {
  13. Trie = trie;
  14. Impl.Reset(new TOpaqueTrieIterator(
  15. TOpaqueTrie(Trie.Data().AsCharPtr(), Trie.Data().Size(), skipper),
  16. nullptr,
  17. false,
  18. sizeof(TSymbol)));
  19. if (Impl->MeasureKey<TSymbol>() == 0) {
  20. MakeStep();
  21. }
  22. }
  23. const TTrie& GetTrie() const {
  24. return Trie;
  25. }
  26. bool AtEnd() const {
  27. return *Impl == TOpaqueTrieIterator(Impl->GetTrie(), nullptr, true, sizeof(TSymbol));
  28. }
  29. TSymbol GetKey() const {
  30. return Impl->GetKey<TSymbol>()[0];
  31. }
  32. TTrie GetTails() const {
  33. const TNode& node = Impl->GetNode();
  34. const size_t forwardOffset = node.GetForwardOffset();
  35. const char* emptyValue = node.IsFinal() ? Trie.Data().AsCharPtr() + node.GetLeafOffset() : nullptr;
  36. if (forwardOffset) {
  37. const char* start = Trie.Data().AsCharPtr() + forwardOffset;
  38. TBlob body = TBlob::NoCopy(start, Trie.Data().Size() - forwardOffset);
  39. return TTrie(body, emptyValue, Trie.GetPacker());
  40. } else {
  41. return TTrie(emptyValue);
  42. }
  43. }
  44. void MakeStep() {
  45. Impl->Forward();
  46. }
  47. private:
  48. TTrie Trie;
  49. TCopyPtr<TOpaqueTrieIterator> Impl;
  50. };
  51. }