| 730 | } |
| 731 | |
| 732 | void TCompactTrieTest::TestFindTailsImpl(const TString& prefix) { |
| 733 | TCompactTrieBuilder<> builder; |
| 734 | |
| 735 | TMap<TString, ui64> input; |
| 736 | |
| 737 | for (auto& i : SampleData) { |
| 738 | TString temp = i; |
| 739 | ui64 val = temp.size() * 2; |
| 740 | builder.Add(temp.data(), temp.size(), val); |
| 741 | if (temp.StartsWith(prefix)) { |
| 742 | input[temp.substr(prefix.size())] = val; |
| 743 | } |
| 744 | } |
| 745 | |
| 746 | typedef TCompactTrie<> TTrie; |
| 747 | |
| 748 | TBufferStream stream; |
| 749 | size_t len = builder.Save(stream); |
| 750 | TTrie trie(stream.Buffer().Data(), len); |
| 751 | |
| 752 | TTrie subtrie = trie.FindTails(prefix.data(), prefix.size()); |
| 753 | |
| 754 | TMap<TString, ui64> output; |
| 755 | |
| 756 | for (TTrie::TConstIterator i = subtrie.Begin(), mi = subtrie.End(); i != mi; ++i) { |
| 757 | TTrie::TValueType val = *i; |
| 758 | output[TString(val.first.data(), val.first.size())] = val.second; |
| 759 | } |
| 760 | UNIT_ASSERT(input.size() == output.size()); |
| 761 | UNIT_ASSERT(input == output); |
| 762 | |
| 763 | TBufferStream buftmp; |
| 764 | CompactTrieMinimize<TTrie::TPacker>(buftmp, stream.Buffer().Data(), len, false); |
| 765 | TTrie trieMin(buftmp.Buffer().Data(), buftmp.Buffer().Size()); |
| 766 | |
| 767 | subtrie = trieMin.FindTails(prefix.data(), prefix.size()); |
| 768 | output.clear(); |
| 769 | |
| 770 | for (TTrie::TConstIterator i = subtrie.Begin(), mi = subtrie.End(); i != mi; ++i) { |
| 771 | TTrie::TValueType val = *i; |
| 772 | output[TString(val.first.data(), val.first.size())] = val.second; |
| 773 | } |
| 774 | UNIT_ASSERT(input.size() == output.size()); |
| 775 | UNIT_ASSERT(input == output); |
| 776 | } |
| 777 | |
| 778 | void TCompactTrieTest::TestPrefixGrouped() { |
| 779 | TBuffer b1b; |