diff options
author | sereglond <sereglond@yandex-team.ru> | 2022-02-10 16:47:47 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:47:47 +0300 |
commit | 73bb02f2495181e0719a800f979df508924f4b71 (patch) | |
tree | c0748b5dcbade83af788c0abfa89c0383d6b779c /library/cpp/containers | |
parent | eb3d925534734c808602b31b38b953677f0a279f (diff) | |
download | ydb-73bb02f2495181e0719a800f979df508924f4b71.tar.gz |
Restoring authorship annotation for <sereglond@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'library/cpp/containers')
17 files changed, 557 insertions, 557 deletions
diff --git a/library/cpp/containers/comptrie/comptrie_builder.h b/library/cpp/containers/comptrie/comptrie_builder.h index e8e55302ce..cf7d2e39a3 100644 --- a/library/cpp/containers/comptrie/comptrie_builder.h +++ b/library/cpp/containers/comptrie/comptrie_builder.h @@ -6,12 +6,12 @@ #include <util/stream/file.h> -// -------------------------------------------------------------------------------------- -// Data Builder -// To build the data buffer, we first create an automaton in memory. The automaton +// -------------------------------------------------------------------------------------- +// Data Builder +// To build the data buffer, we first create an automaton in memory. The automaton // is created incrementally. It actually helps a lot to have the input data prefix-grouped -// by key; otherwise, memory consumption becomes a tough issue. -// NOTE: building and serializing the automaton may be lengthy, and takes lots of memory. +// by key; otherwise, memory consumption becomes a tough issue. +// NOTE: building and serializing the automaton may be lengthy, and takes lots of memory. // PREFIX_GROUPED means that if we, while constructing a trie, add to the builder two keys with the same prefix, // then all the keys that we add between these two also have the same prefix. @@ -38,11 +38,11 @@ template <typename T> class TArrayWithSizeHolder; template <class T = char, class D = ui64, class S = TCompactTriePacker<D>> -class TCompactTrieBuilder { -public: - typedef T TSymbol; - typedef D TData; - typedef S TPacker; +class TCompactTrieBuilder { +public: + typedef T TSymbol; + typedef D TData; + typedef S TPacker; typedef typename TCompactTrieKeySelector<TSymbol>::TKey TKey; typedef typename TCompactTrieKeySelector<TSymbol>::TKeyBuf TKeyBuf; @@ -71,7 +71,7 @@ public: return AddSubtreeInBuffer(key.data(), key.size(), std::move(buffer)); } - bool Find(const TSymbol* key, size_t keylen, TData* value) const; + bool Find(const TSymbol* key, size_t keylen, TData* value) const; bool Find(const TKeyBuf& key, TData* value = nullptr) const { return Find(key.data(), key.size(), value); } @@ -90,8 +90,8 @@ public: void Clear(); // Returns all memory to the system and resets the builder state. - size_t GetEntryCount() const; - size_t GetNodeCount() const; + size_t GetEntryCount() const; + size_t GetNodeCount() const; // Exact output file size in bytes. size_t MeasureByteSize() const { @@ -99,8 +99,8 @@ public: } protected: - class TCompactTrieBuilderImpl; - THolder<TCompactTrieBuilderImpl> Impl; + class TCompactTrieBuilderImpl; + THolder<TCompactTrieBuilderImpl> Impl; }; //---------------------------------------------------------------------------------------------------------------------- @@ -117,7 +117,7 @@ protected: // as you expect it to, and can destroy the trie in the making. // If you want both minimization and fast layout, do the minimization first. -template <class TPacker> +template <class TPacker> size_t CompactTrieMinimize(IOutputStream& os, const char* data, size_t datalength, bool verbose = false, const TPacker& packer = TPacker(), NCompactTrie::EMinimizeMode mode = NCompactTrie::MM_DEFAULT); template <class TTrieBuilder> diff --git a/library/cpp/containers/comptrie/comptrie_builder.inl b/library/cpp/containers/comptrie/comptrie_builder.inl index ef3078a4ad..f273fa6571 100644 --- a/library/cpp/containers/comptrie/comptrie_builder.inl +++ b/library/cpp/containers/comptrie/comptrie_builder.inl @@ -22,22 +22,22 @@ #define CONSTEXPR_MAX2(a, b) (a) > (b) ? (a) : (b) #define CONSTEXPR_MAX3(a, b, c) CONSTEXPR_MAX2(CONSTEXPR_MAX2(a, b), c) -// TCompactTrieBuilder::TCompactTrieBuilderImpl - -template <class T, class D, class S> -class TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl { +// TCompactTrieBuilder::TCompactTrieBuilderImpl + +template <class T, class D, class S> +class TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl { protected: TMemoryPool Pool; size_t PayloadSize; THolder<TFixedSizeAllocator> NodeAllocator; - class TNode; + class TNode; class TArc; - TNode* Root; + TNode* Root; TCompactTrieBuilderFlags Flags; - size_t EntryCount; - size_t NodeCount; + size_t EntryCount; + size_t NodeCount; TPacker Packer; - + enum EPayload { DATA_ABSENT, DATA_INSIDE, @@ -66,10 +66,10 @@ protected: ui64 ArcSave(const TArc* thiz, IOutputStream& os) const; ui64 ArcSaveAndDestroy(const TArc* thiz, IOutputStream& os); -public: +public: TCompactTrieBuilderImpl(TCompactTrieBuilderFlags flags, TPacker packer, IAllocator* alloc); virtual ~TCompactTrieBuilderImpl(); - + void DestroyNode(TNode* node); void NodeReleasePayload(TNode* thiz); @@ -80,40 +80,40 @@ public: bool AddEntryPtr(const TSymbol* key, size_t keylen, const char* value); bool AddSubtreeInFile(const TSymbol* key, size_t keylen, const TString& fileName); bool AddSubtreeInBuffer(const TSymbol* key, size_t keylen, TArrayWithSizeHolder<char>&& buffer); - bool FindEntry(const TSymbol* key, size_t keylen, TData* value) const; + bool FindEntry(const TSymbol* key, size_t keylen, TData* value) const; bool FindLongestPrefix(const TSymbol* key, size_t keylen, size_t* prefixlen, TData* value) const; - + size_t Save(IOutputStream& os) const; size_t SaveAndDestroy(IOutputStream& os); - void Clear(); - + void Clear(); + // lies if some key was added at least twice - size_t GetEntryCount() const; - size_t GetNodeCount() const; + size_t GetEntryCount() const; + size_t GetNodeCount() const; size_t MeasureByteSize() const { return NodeMeasureSubtree(Root); } -}; - -template <class T, class D, class S> +}; + +template <class T, class D, class S> class TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::TArc { -public: +public: TBlob Label; TNode* Node; mutable size_t LeftOffset; mutable size_t RightOffset; - + TArc(const TBlob& lbl, TNode* nd); }; - + template <class T, class D, class S> class TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::TNode { public: typedef typename TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl TBuilderImpl; typedef typename TBuilderImpl::TArc TArc; - + struct ISubtree { virtual ~ISubtree() = default; virtual bool IsLast() const = 0; @@ -130,10 +130,10 @@ public: }; class TArcSet: public ISubtree, public TCompactVector<TArc> { - public: + public: typedef typename TCompactVector<TArc>::iterator iterator; typedef typename TCompactVector<TArc>::const_iterator const_iterator; - + TArcSet() { Y_ASSERT(reinterpret_cast<ISubtree*>(this) == static_cast<void*>(this)); // This assumption is used in TNode::Subtree() } @@ -212,8 +212,8 @@ public: Y_ASSERT(this->empty()); } - }; - + }; + struct TBufferedSubtree: public ISubtree { TArrayWithSizeHolder<char> Buffer; @@ -350,7 +350,7 @@ public: } EPayload PayloadType; - + inline const char* PayloadPtr() const { return ((const char*) this) + sizeof(TNode); } @@ -409,28 +409,28 @@ public: { new (Subtree()) TArcSet; } - + ~TNode() { Subtree()->~ISubtree(); Y_ASSERT(PayloadType == DATA_ABSENT); } -}; - -// TCompactTrieBuilder - -template <class T, class D, class S> +}; + +// TCompactTrieBuilder + +template <class T, class D, class S> TCompactTrieBuilder<T, D, S>::TCompactTrieBuilder(TCompactTrieBuilderFlags flags, TPacker packer, IAllocator* alloc) : Impl(new TCompactTrieBuilderImpl(flags, packer, alloc)) { } - -template <class T, class D, class S> + +template <class T, class D, class S> bool TCompactTrieBuilder<T, D, S>::Add(const TSymbol* key, size_t keylen, const TData& value) { return Impl->AddEntry(key, keylen, value); -} - -template <class T, class D, class S> +} + +template <class T, class D, class S> bool TCompactTrieBuilder<T, D, S>::AddPtr(const TSymbol* key, size_t keylen, const char* value) { return Impl->AddEntryPtr(key, keylen, value); } @@ -446,11 +446,11 @@ bool TCompactTrieBuilder<T, D, S>::AddSubtreeInBuffer(const TSymbol* key, size_t } template <class T, class D, class S> -bool TCompactTrieBuilder<T, D, S>::Find(const TSymbol* key, size_t keylen, TData* value) const { - return Impl->FindEntry(key, keylen, value); -} - -template <class T, class D, class S> +bool TCompactTrieBuilder<T, D, S>::Find(const TSymbol* key, size_t keylen, TData* value) const { + return Impl->FindEntry(key, keylen, value); +} + +template <class T, class D, class S> bool TCompactTrieBuilder<T, D, S>::FindLongestPrefix( const TSymbol* key, size_t keylen, size_t* prefixlen, TData* value) const { return Impl->FindLongestPrefix(key, keylen, prefixlen, value); @@ -458,50 +458,50 @@ bool TCompactTrieBuilder<T, D, S>::FindLongestPrefix( template <class T, class D, class S> size_t TCompactTrieBuilder<T, D, S>::Save(IOutputStream& os) const { - return Impl->Save(os); -} - -template <class T, class D, class S> + return Impl->Save(os); +} + +template <class T, class D, class S> size_t TCompactTrieBuilder<T, D, S>::SaveAndDestroy(IOutputStream& os) { return Impl->SaveAndDestroy(os); } template <class T, class D, class S> -void TCompactTrieBuilder<T, D, S>::Clear() { - Impl->Clear(); -} - -template <class T, class D, class S> -size_t TCompactTrieBuilder<T, D, S>::GetEntryCount() const { - return Impl->GetEntryCount(); -} - -template <class T, class D, class S> -size_t TCompactTrieBuilder<T, D, S>::GetNodeCount() const { - return Impl->GetNodeCount(); -} - -// TCompactTrieBuilder::TCompactTrieBuilderImpl - -template <class T, class D, class S> +void TCompactTrieBuilder<T, D, S>::Clear() { + Impl->Clear(); +} + +template <class T, class D, class S> +size_t TCompactTrieBuilder<T, D, S>::GetEntryCount() const { + return Impl->GetEntryCount(); +} + +template <class T, class D, class S> +size_t TCompactTrieBuilder<T, D, S>::GetNodeCount() const { + return Impl->GetNodeCount(); +} + +// TCompactTrieBuilder::TCompactTrieBuilderImpl + +template <class T, class D, class S> TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::TCompactTrieBuilderImpl(TCompactTrieBuilderFlags flags, TPacker packer, IAllocator* alloc) : Pool(1000000, TMemoryPool::TLinearGrow::Instance(), alloc) , PayloadSize(sizeof(void*)) // XXX: find better value , NodeAllocator(new TFixedSizeAllocator(sizeof(TNode) + PayloadSize, alloc)) , Flags(flags) - , EntryCount(0) - , NodeCount(1) + , EntryCount(0) + , NodeCount(1) , Packer(packer) -{ +{ Root = new (*NodeAllocator) TNode; -} - -template <class T, class D, class S> -TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::~TCompactTrieBuilderImpl() { +} + +template <class T, class D, class S> +TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::~TCompactTrieBuilderImpl() { DestroyNode(Root); -} - -template <class T, class D, class S> +} + +template <class T, class D, class S> void TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::ConvertSymbolArrayToChar( const TSymbol* key, size_t keylen, TTempBuf& buf, size_t buflen) const { char* ckeyptr = buf.Data(); @@ -600,16 +600,16 @@ template <class T, class D, class S> typename TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::TNode* TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::AddEntryForSomething( const TSymbol* key, size_t keylen, bool& isNewAddition) { - using namespace NCompactTrie; - - EntryCount++; - + using namespace NCompactTrie; + + EntryCount++; + if (Flags & CTBF_VERBOSE) - ShowProgress(EntryCount); - - TNode* current = Root; + ShowProgress(EntryCount); + + TNode* current = Root; size_t passed; - + // Special case of empty key: replace it by 1-byte "\0" key. size_t ckeylen = keylen ? keylen * sizeof(TSymbol) : 1; TTempBuf ckeybuf(ckeylen); @@ -620,13 +620,13 @@ typename TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::TNode* } char* ckey = ckeybuf.Data(); - + TNode* next; while ((ckeylen > 0) && (next = NodeForwardAdd(current, ckey, ckeylen, passed, &NodeCount)) != nullptr) { current = next; ckeylen -= passed; ckey += passed; - } + } if (ckeylen != 0) { //new leaf @@ -640,7 +640,7 @@ typename TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::TNode* ythrow yexception() << "Duplicate key"; return current; } - + template <class T, class D, class S> char* TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::AddEntryForData(const TSymbol* key, size_t keylen, size_t datalen, bool& isNewAddition) { @@ -656,12 +656,12 @@ char* TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::AddEntryForData(con current->PayloadAsPtr() = (char*) Pool.Allocate(datalen); // XXX: allocate unaligned } return current->GetPayload(); -} - -template <class T, class D, class S> -bool TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::FindEntry(const TSymbol* key, size_t keylen, TData* value) const { - using namespace NCompactTrie; - +} + +template <class T, class D, class S> +bool TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::FindEntry(const TSymbol* key, size_t keylen, TData* value) const { + using namespace NCompactTrie; + if (!keylen) { const char zero = '\0'; return FindEntryImpl(&zero, 1, value); @@ -670,20 +670,20 @@ bool TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::FindEntry(const TSym TTempBuf ckeybuf(ckeylen); ConvertSymbolArrayToChar(key, keylen, ckeybuf, ckeylen); return FindEntryImpl(ckeybuf.Data(), ckeylen, value); - } + } } - + template <class T, class D, class S> bool TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::FindEntryImpl(const char* keyptr, size_t keylen, TData* value) const { const TNode* node = Root; bool result = false; TStringBuf key(keyptr, keylen); while (key && (node = node->Subtree()->Find(key, value, result, Packer))) { - } + } return result; -} - -template <class T, class D, class S> +} + +template <class T, class D, class S> bool TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::FindLongestPrefix( const TSymbol* key, size_t keylen, size_t* prefixlen, TData* value) const { using namespace NCompactTrie; @@ -740,25 +740,25 @@ bool TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::FindLongestPrefixImp } template <class T, class D, class S> -void TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::Clear() { +void TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::Clear() { DestroyNode(Root); Pool.Clear(); NodeAllocator.Reset(new TFixedSizeAllocator(sizeof(TNode) + PayloadSize, TDefaultAllocator::Instance())); Root = new (*NodeAllocator) TNode; EntryCount = 0; NodeCount = 1; -} - -template <class T, class D, class S> +} + +template <class T, class D, class S> size_t TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::Save(IOutputStream& os) const { const size_t len = NodeMeasureSubtree(Root); if (len != NodeSaveSubtree(Root, os)) ythrow yexception() << "something wrong"; - - return len; -} - -template <class T, class D, class S> + + return len; +} + +template <class T, class D, class S> size_t TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::SaveAndDestroy(IOutputStream& os) { const size_t len = NodeMeasureSubtree(Root); if (len != NodeSaveSubtreeAndDestroy(Root, os)) @@ -768,16 +768,16 @@ size_t TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::SaveAndDestroy(IOu } template <class T, class D, class S> -size_t TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::GetEntryCount() const { - return EntryCount; -} - -template <class T, class D, class S> -size_t TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::GetNodeCount() const { - return NodeCount; -} - -template <class T, class D, class S> +size_t TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::GetEntryCount() const { + return EntryCount; +} + +template <class T, class D, class S> +size_t TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::GetNodeCount() const { + return NodeCount; +} + +template <class T, class D, class S> typename TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::TNode* TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::NodeForwardAdd( TNode* thiz, const char* label, size_t len, size_t& passed, size_t* nodeCount) { @@ -815,25 +815,25 @@ void TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::NodeLinkTo(TNode* th typename TNode::TArcSet* arcSet = dynamic_cast<typename TNode::TArcSet*>(thiz->Subtree()); if (!arcSet) ythrow yexception() << "Bad input order - expected input strings to be prefix-grouped."; - - // Buffer the node at the last arc + + // Buffer the node at the last arc if ((Flags & CTBF_PREFIX_GROUPED) && !arcSet->empty()) NodeBufferSubtree(arcSet->back().Node); - + arcSet->Add(label, node); -} - -template <class T, class D, class S> +} + +template <class T, class D, class S> size_t TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::NodeMeasureSubtree(TNode* thiz) const { return (size_t)thiz->Subtree()->Measure(this); -} - -template <class T, class D, class S> +} + +template <class T, class D, class S> ui64 TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::NodeSaveSubtree(TNode* thiz, IOutputStream& os) const { return thiz->Subtree()->Save(this, os); -} - -template <class T, class D, class S> +} + +template <class T, class D, class S> ui64 TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::NodeSaveSubtreeAndDestroy(TNode* thiz, IOutputStream& os) { return thiz->Subtree()->SaveAndDestroy(this, os); } @@ -844,12 +844,12 @@ void TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::NodeBufferSubtree(TN TArcSet* arcSet = dynamic_cast<TArcSet*>(thiz->Subtree()); if (!arcSet) - return; - + return; + size_t bufferLength = (size_t)arcSet->Measure(this); TArrayWithSizeHolder<char> buffer; buffer.Resize(bufferLength); - + TMemoryOutput bufout(buffer.Get(), buffer.Size()); ui64 written = arcSet->Save(this, bufout); @@ -857,100 +857,100 @@ void TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::NodeBufferSubtree(TN arcSet->Destroy(this); arcSet->~TArcSet(); - + typename TNode::TBufferedSubtree* bufferedArcSet = new (thiz->Subtree()) typename TNode::TBufferedSubtree; bufferedArcSet->Buffer.Swap(buffer); -} - -template <class T, class D, class S> +} + +template <class T, class D, class S> size_t TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::NodeMeasureLeafValue(TNode* thiz) const { if (!thiz->IsFinal()) - return 0; - + return 0; + return Packer.SkipLeaf(thiz->GetPayload()); -} - -template <class T, class D, class S> +} + +template <class T, class D, class S> ui64 TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::NodeSaveLeafValue(TNode* thiz, IOutputStream& os) const { if (!thiz->IsFinal()) return 0; - + size_t len = Packer.SkipLeaf(thiz->GetPayload()); os.Write(thiz->GetPayload(), len); return len; -} - -// TCompactTrieBuilder::TCompactTrieBuilderImpl::TNode::TArc - -template <class T, class D, class S> +} + +// TCompactTrieBuilder::TCompactTrieBuilderImpl::TNode::TArc + +template <class T, class D, class S> TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::TArc::TArc(const TBlob& lbl, TNode* nd) - : Label(lbl) - , Node(nd) - , LeftOffset(0) - , RightOffset(0) + : Label(lbl) + , Node(nd) + , LeftOffset(0) + , RightOffset(0) {} - -template <class T, class D, class S> + +template <class T, class D, class S> ui64 TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::ArcMeasure( const TArc* thiz, size_t leftsize, size_t rightsize) const { - using namespace NCompactTrie; - + using namespace NCompactTrie; + size_t coresize = 2 + NodeMeasureLeafValue(thiz->Node); // 2 == (char + flags) size_t treesize = NodeMeasureSubtree(thiz->Node); - + if (thiz->Label.Length() > 0) treesize += 2 * (thiz->Label.Length() - 1); - // Triple measurements are needed because the space needed to store the offset - // shall be added to the offset itself. Hence three iterations. - size_t leftoffsetsize = leftsize ? MeasureOffset(coresize + treesize) : 0; - size_t rightoffsetsize = rightsize ? MeasureOffset(coresize + treesize + leftsize) : 0; - leftoffsetsize = leftsize ? MeasureOffset(coresize + treesize + leftoffsetsize + rightoffsetsize) : 0; + // Triple measurements are needed because the space needed to store the offset + // shall be added to the offset itself. Hence three iterations. + size_t leftoffsetsize = leftsize ? MeasureOffset(coresize + treesize) : 0; + size_t rightoffsetsize = rightsize ? MeasureOffset(coresize + treesize + leftsize) : 0; + leftoffsetsize = leftsize ? MeasureOffset(coresize + treesize + leftoffsetsize + rightoffsetsize) : 0; rightoffsetsize = rightsize ? MeasureOffset(coresize + treesize + leftsize + leftoffsetsize + rightoffsetsize) : 0; - leftoffsetsize = leftsize ? MeasureOffset(coresize + treesize + leftoffsetsize + rightoffsetsize) : 0; + leftoffsetsize = leftsize ? MeasureOffset(coresize + treesize + leftoffsetsize + rightoffsetsize) : 0; rightoffsetsize = rightsize ? MeasureOffset(coresize + treesize + leftsize + leftoffsetsize + rightoffsetsize) : 0; - - coresize += leftoffsetsize + rightoffsetsize; + + coresize += leftoffsetsize + rightoffsetsize; thiz->LeftOffset = leftsize ? coresize + treesize : 0; thiz->RightOffset = rightsize ? coresize + treesize + leftsize : 0; - - return coresize + treesize + leftsize + rightsize; -} - -template <class T, class D, class S> + + return coresize + treesize + leftsize + rightsize; +} + +template <class T, class D, class S> ui64 TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::ArcSaveSelf(const TArc* thiz, IOutputStream& os) const { - using namespace NCompactTrie; - + using namespace NCompactTrie; + ui64 written = 0; size_t leftoffsetsize = MeasureOffset(thiz->LeftOffset); size_t rightoffsetsize = MeasureOffset(thiz->RightOffset); - + size_t labelLen = thiz->Label.Length(); - + for (size_t i = 0; i < labelLen; ++i) { char flags = 0; - + if (i == 0) { flags |= (leftoffsetsize << MT_LEFTSHIFT); flags |= (rightoffsetsize << MT_RIGHTSHIFT); } - + if (i == labelLen-1) { if (thiz->Node->IsFinal()) flags |= MT_FINAL; - + if (!thiz->Node->IsLast()) flags |= MT_NEXT; } else { flags |= MT_NEXT; } - + os.Write(&flags, 1); os.Write(&thiz->Label.AsCharPtr()[i], 1); written += 2; - + if (i == 0) { written += ArcSaveOffset(thiz->LeftOffset, os); written += ArcSaveOffset(thiz->RightOffset, os); @@ -966,8 +966,8 @@ ui64 TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::ArcSave(const TArc* ui64 written = ArcSaveSelf(thiz, os); written += NodeSaveSubtree(thiz->Node, os); return written; -} - +} + template <class T, class D, class S> ui64 TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::ArcSaveAndDestroy(const TArc* thiz, IOutputStream& os) { ui64 written = ArcSaveSelf(thiz, os); @@ -975,9 +975,9 @@ ui64 TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::ArcSaveAndDestroy(co return written; } -// TCompactTrieBuilder::TCompactTrieBuilderImpl::TNode::TArcSet - -template <class T, class D, class S> +// TCompactTrieBuilder::TCompactTrieBuilderImpl::TNode::TArcSet + +template <class T, class D, class S> typename TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::TNode::TArcSet::iterator TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::TNode::TArcSet::Find(char ch) { using namespace NCompTriePrivate; @@ -985,12 +985,12 @@ typename TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::TNode::TArcSet:: if (it != this->end() && it->Label[0] == (unsigned char)ch) { return it; - } - - return this->end(); -} - -template <class T, class D, class S> + } + + return this->end(); +} + +template <class T, class D, class S> typename TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::TNode::TArcSet::const_iterator TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::TNode::TArcSet::Find(char ch) const { using namespace NCompTriePrivate; @@ -1007,8 +1007,8 @@ template <class T, class D, class S> void TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::TNode::TArcSet::Add(const TBlob& s, TNode* node) { using namespace NCompTriePrivate; this->insert(LowerBound(this->begin(), this->end(), s[0], TCmp()), TArc(s, node)); -} - +} + template <class T, class D, class S> const typename TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::TNode* TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::TNode::TArcSet::Find( @@ -1045,8 +1045,8 @@ const typename TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::TNode* return nullptr; } -// Different - +// Different + //---------------------------------------------------------------------------------------------------------------------- // Minimize the trie. The result is equivalent to the original // trie, except that it takes less space (and has marginally lower @@ -1060,11 +1060,11 @@ const typename TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::TNode* // Because of non-local structure and epsilon links, it won't work // as you expect it to, and can destroy the trie in the making. -template <class TPacker> +template <class TPacker> size_t CompactTrieMinimize(IOutputStream& os, const char* data, size_t datalength, bool verbose /*= false*/, const TPacker& packer /*= TPacker()*/, NCompactTrie::EMinimizeMode mode) { - using namespace NCompactTrie; + using namespace NCompactTrie; return CompactTrieMinimizeImpl(os, data, datalength, verbose, &packer, mode); -} +} template <class TTrieBuilder> size_t CompactTrieMinimize(IOutputStream& os, const TTrieBuilder& builder, bool verbose /*=false*/) { diff --git a/library/cpp/containers/comptrie/comptrie_impl.cpp b/library/cpp/containers/comptrie/comptrie_impl.cpp index f3b9d03fd1..a116ab6d1e 100644 --- a/library/cpp/containers/comptrie/comptrie_impl.cpp +++ b/library/cpp/containers/comptrie/comptrie_impl.cpp @@ -2,10 +2,10 @@ #include <util/system/rusage.h> #include <util/stream/output.h> - -// Unpack the leaf value. The algorithm can store up to 8 full bytes in leafs. - -namespace NCompactTrie { + +// Unpack the leaf value. The algorithm can store up to 8 full bytes in leafs. + +namespace NCompactTrie { size_t MeasureOffset(size_t offset) { int n = 0; diff --git a/library/cpp/containers/comptrie/comptrie_impl.h b/library/cpp/containers/comptrie/comptrie_impl.h index 894297158b..f41c38311a 100644 --- a/library/cpp/containers/comptrie/comptrie_impl.h +++ b/library/cpp/containers/comptrie/comptrie_impl.h @@ -6,9 +6,9 @@ #define COMPTRIE_DATA_CHECK 1 #endif -// NCompactTrie - -namespace NCompactTrie { +// NCompactTrie + +namespace NCompactTrie { const char MT_FINAL = '\x80'; const char MT_NEXT = '\x40'; const char MT_SIZEMASK = '\x07'; @@ -16,16 +16,16 @@ namespace NCompactTrie { const size_t MT_RIGHTSHIFT = 0; Y_FORCE_INLINE size_t UnpackOffset(const char* p, size_t len); - size_t MeasureOffset(size_t offset); - size_t PackOffset(char* buffer, size_t offset); + size_t MeasureOffset(size_t offset); + size_t PackOffset(char* buffer, size_t offset); static inline ui64 ArcSaveOffset(size_t offset, IOutputStream& os); Y_FORCE_INLINE char LeapByte(const char*& datapos, const char* dataend, char label); - - template <class T> - inline static size_t ExtraBits() { - return (sizeof(T) - 1) * 8; - } - + + template <class T> + inline static size_t ExtraBits() { + return (sizeof(T) - 1) * 8; + } + static inline bool IsEpsilonLink(const char flags) { return !(flags & (MT_FINAL | MT_NEXT)); } @@ -49,9 +49,9 @@ namespace NCompactTrie { return flags & MT_SIZEMASK; } - void ShowProgress(size_t n); // just print dots -} - + void ShowProgress(size_t n); // just print dots +} + namespace NCompTriePrivate { template <typename TChar> struct TStringForChar { diff --git a/library/cpp/containers/comptrie/comptrie_trie.h b/library/cpp/containers/comptrie/comptrie_trie.h index 2b1a42aa0a..40ec1e52b3 100644 --- a/library/cpp/containers/comptrie/comptrie_trie.h +++ b/library/cpp/containers/comptrie/comptrie_trie.h @@ -33,8 +33,8 @@ template <class T = char, class D = ui64, class S = TCompactTriePacker<D>> class TCompactTrie { public: typedef T TSymbol; - typedef D TData; - typedef S TPacker; + typedef D TData; + typedef S TPacker; typedef typename TCompactTrieKeySelector<TSymbol>::TKey TKey; typedef typename TCompactTrieKeySelector<TSymbol>::TKeyBuf TKeyBuf; @@ -42,7 +42,7 @@ public: typedef std::pair<TKey, TData> TValueType; typedef std::pair<size_t, TData> TPhraseMatch; typedef TVector<TPhraseMatch> TPhraseMatchVector; - + typedef TCompactTrieBuilder<T, D, S> TBuilder; protected: @@ -77,8 +77,8 @@ public: void Init(const char* d, size_t len, TPacker packer = TPacker()); void Init(const TBlob& data, TPacker packer = TPacker()); - bool IsInitialized() const; - bool IsEmpty() const; + bool IsInitialized() const; + bool IsEmpty() const; bool Find(const TSymbol* key, size_t keylen, TData* value = nullptr) const; bool Find(const TKeyBuf& key, TData* value = nullptr) const { @@ -118,7 +118,7 @@ public: return Skipper.GetPacker() == &Packer; } - void FindPhrases(const TSymbol* key, size_t keylen, TPhraseMatchVector& matches, TSymbol separator = TSymbol(' ')) const; + void FindPhrases(const TSymbol* key, size_t keylen, TPhraseMatchVector& matches, TSymbol separator = TSymbol(' ')) const; void FindPhrases(const TKeyBuf& key, TPhraseMatchVector& matches, TSymbol separator = TSymbol(' ')) const { return FindPhrases(key.data(), key.size(), matches, separator); } @@ -141,14 +141,14 @@ public: // return false, if no arc with @label exists inline bool FindTails(TSymbol label, TCompactTrie<T, D, S>& res) const; - class TConstIterator { + class TConstIterator { private: typedef NCompactTrie::TOpaqueTrieIterator TOpaqueTrieIterator; typedef NCompactTrie::TOpaqueTrie TOpaqueTrie; friend class TCompactTrie; TConstIterator(const TOpaqueTrie& trie, const char* emptyValue, bool atend, TPacker packer); // only usable from Begin() and End() methods TConstIterator(const TOpaqueTrie& trie, const char* emptyValue, const TKeyBuf& key, TPacker packer); // only usable from UpperBound() method - + public: TConstIterator() = default; bool IsEmpty() const { @@ -157,11 +157,11 @@ public: bool operator==(const TConstIterator& other) const; bool operator!=(const TConstIterator& other) const; - TConstIterator& operator++(); - TConstIterator operator++(int /*unused*/); + TConstIterator& operator++(); + TConstIterator operator++(int /*unused*/); TConstIterator& operator--(); TConstIterator operator--(int /*unused*/); - TValueType operator*(); + TValueType operator*(); TKey GetKey() const; size_t GetKeySize() const; @@ -169,14 +169,14 @@ public: void GetValue(TData& data) const; const char* GetValuePtr() const; - private: + private: TPacker Packer; TCopyPtr<TOpaqueTrieIterator> Impl; }; - TConstIterator Begin() const; + TConstIterator Begin() const; TConstIterator begin() const; - TConstIterator End() const; + TConstIterator End() const; TConstIterator end() const; // Returns an iterator pointing to the smallest key in the trie >= the argument. @@ -194,9 +194,9 @@ public: friend class TPrefixIterator<TCompactTrie>; protected: - explicit TCompactTrie(const char* emptyValue); + explicit TCompactTrie(const char* emptyValue); TCompactTrie(const TBlob& data, const char* emptyValue, TPacker packer = TPacker()); - + bool LookupLongestPrefix(const TSymbol* key, size_t keylen, size_t& prefixLen, const char*& valuepos, bool& hasNext) const; bool LookupLongestPrefix(const TSymbol* key, size_t keylen, size_t& prefixLen, const char*& valuepos) const { bool hasNext; @@ -207,49 +207,49 @@ protected: template <class T = char, class D = ui64, class S = TCompactTriePacker<D>> class TCompactTrieHolder: public TCompactTrie<T, D, S>, NNonCopyable::TNonCopyable { -private: +private: typedef TCompactTrie<T, D, S> TBase; TArrayHolder<char> Storage; -public: +public: TCompactTrieHolder(IInputStream& is, size_t len); -}; +}; + +//------------------------// +// Implementation section // +//------------------------// -//------------------------// -// Implementation section // -//------------------------// +// TCompactTrie -// TCompactTrie - template <class T, class D, class S> TCompactTrie<T, D, S>::TCompactTrie(const TBlob& data, TPacker packer) - : DataHolder(data) + : DataHolder(data) , Packer(packer) -{ - Init(data, packer); -} - +{ + Init(data, packer); +} + template <class T, class D, class S> TCompactTrie<T, D, S>::TCompactTrie(const char* d, size_t len, TPacker packer) : Packer(packer) -{ +{ Init(d, len, packer); -} - +} + template <class T, class D, class S> TCompactTrie<T, D, S>::TCompactTrie(const char* emptyValue) - : EmptyValue(emptyValue) + : EmptyValue(emptyValue) { } - + template <class T, class D, class S> TCompactTrie<T, D, S>::TCompactTrie(const TBlob& data, const char* emptyValue, TPacker packer) - : DataHolder(data) - , EmptyValue(emptyValue) + : DataHolder(data) + , EmptyValue(emptyValue) , Packer(packer) { } - + template <class T, class D, class S> TCompactTrie<T, D, S>::TCompactTrie(const TCompactTrie& other) : DataHolder(other.DataHolder) @@ -289,43 +289,43 @@ TCompactTrie<T, D, S>& TCompactTrie<T, D, S>::operator=(TCompactTrie&& other) no template <class T, class D, class S> void TCompactTrie<T, D, S>::Init(const char* d, size_t len, TPacker packer) { Init(TBlob::NoCopy(d, len), packer); -} - +} + template <class T, class D, class S> void TCompactTrie<T, D, S>::Init(const TBlob& data, TPacker packer) { - using namespace NCompactTrie; - - DataHolder = data; + using namespace NCompactTrie; + + DataHolder = data; Packer = packer; - + const char* datapos = DataHolder.AsCharPtr(); size_t len = DataHolder.Length(); - if (!len) - return; - - const char* const dataend = datapos + len; - - const char* emptypos = datapos; - char flags = LeapByte(emptypos, dataend, 0); - if (emptypos && (flags & MT_FINAL)) { + if (!len) + return; + + const char* const dataend = datapos + len; + + const char* emptypos = datapos; + char flags = LeapByte(emptypos, dataend, 0); + if (emptypos && (flags & MT_FINAL)) { Y_ASSERT(emptypos <= dataend); - EmptyValue = emptypos; - } -} - + EmptyValue = emptypos; + } +} + template <class T, class D, class S> bool TCompactTrie<T, D, S>::IsInitialized() const { return DataHolder.Data() != nullptr; -} - +} + template <class T, class D, class S> bool TCompactTrie<T, D, S>::IsEmpty() const { return DataHolder.Size() == 0 && EmptyValue == nullptr; -} - +} + template <class T, class D, class S> bool TCompactTrie<T, D, S>::Find(const TSymbol* key, size_t keylen, TData* value) const { - size_t prefixLen = 0; + size_t prefixLen = 0; const char* valuepos = nullptr; bool hasNext; if (!LookupLongestPrefix(key, keylen, prefixLen, valuepos, hasNext) || prefixLen != keylen) @@ -333,13 +333,13 @@ bool TCompactTrie<T, D, S>::Find(const TSymbol* key, size_t keylen, TData* value if (value) Packer.UnpackLeaf(valuepos, *value); return true; -} - +} + template <class T, class D, class S> void TCompactTrie<T, D, S>::FindPhrases(const TSymbol* key, size_t keylen, TPhraseMatchVector& matches, TSymbol separator) const { LookupPhrases(DataHolder.AsCharPtr(), DataHolder.Length(), key, keylen, matches, separator); -} - +} + template <class T, class D, class S> inline TCompactTrie<T, D, S> TCompactTrie<T, D, S>::FindTails(const TSymbol* key, size_t keylen) const { TCompactTrie<T, D, S> ret; @@ -349,46 +349,46 @@ inline TCompactTrie<T, D, S> TCompactTrie<T, D, S>::FindTails(const TSymbol* key template <class T, class D, class S> bool TCompactTrie<T, D, S>::FindTails(const TSymbol* key, size_t keylen, TCompactTrie<T, D, S>& res) const { - using namespace NCompactTrie; - - size_t len = DataHolder.Length(); - - if (!key || !len) + using namespace NCompactTrie; + + size_t len = DataHolder.Length(); + + if (!key || !len) return false; - - if (!keylen) { + + if (!keylen) { res = *this; return true; - } - + } + const char* datastart = DataHolder.AsCharPtr(); const char* datapos = datastart; const char* const dataend = datapos + len; - const TSymbol* keyend = key + keylen; + const TSymbol* keyend = key + keylen; const char* value = nullptr; - while (key != keyend) { - T label = *(key++); + while (key != keyend) { + T label = *(key++); if (!NCompactTrie::Advance(datapos, dataend, value, label, Packer)) return false; - + if (key == keyend) { if (datapos) { Y_ASSERT(datapos >= datastart); res = TCompactTrie<T, D, S>(TBlob::NoCopy(datapos, dataend - datapos), value); } else { res = TCompactTrie<T, D, S>(value); - } + } return true; } else if (!datapos) { return false; // No further way - } - } - + } + } + return false; -} - +} + template <class T, class D, class S> inline bool TCompactTrie<T, D, S>::FindTails(TSymbol label, TCompactTrie<T, D, S>& res) const { using namespace NCompactTrie; @@ -419,8 +419,8 @@ template <class T, class D, class S> typename TCompactTrie<T, D, S>::TConstIterator TCompactTrie<T, D, S>::Begin() const { NCompactTrie::TOpaqueTrie self(DataHolder.AsCharPtr(), DataHolder.Length(), Skipper); return TConstIterator(self, EmptyValue, false, Packer); -} - +} + template <class T, class D, class S> typename TCompactTrie<T, D, S>::TConstIterator TCompactTrie<T, D, S>::begin() const { return Begin(); @@ -430,8 +430,8 @@ template <class T, class D, class S> typename TCompactTrie<T, D, S>::TConstIterator TCompactTrie<T, D, S>::End() const { NCompactTrie::TOpaqueTrie self(DataHolder.AsCharPtr(), DataHolder.Length(), Skipper); return TConstIterator(self, EmptyValue, true, Packer); -} - +} + template <class T, class D, class S> typename TCompactTrie<T, D, S>::TConstIterator TCompactTrie<T, D, S>::end() const { return End(); @@ -462,11 +462,11 @@ void TCompactTrie<T, D, S>::Print(IOutputStream& os) { template <class T, class D, class S> bool TCompactTrie<T, D, S>::FindLongestPrefix(const TSymbol* key, size_t keylen, size_t* prefixLen, TData* value, bool* hasNext) const { const char* valuepos = nullptr; - size_t tempPrefixLen = 0; + size_t tempPrefixLen = 0; bool tempHasNext; bool found = LookupLongestPrefix(key, keylen, tempPrefixLen, valuepos, tempHasNext); - if (prefixLen) - *prefixLen = tempPrefixLen; + if (prefixLen) + *prefixLen = tempPrefixLen; if (found && value) Packer.UnpackLeaf(valuepos, *value); if (hasNext) @@ -476,38 +476,38 @@ bool TCompactTrie<T, D, S>::FindLongestPrefix(const TSymbol* key, size_t keylen, template <class T, class D, class S> bool TCompactTrie<T, D, S>::LookupLongestPrefix(const TSymbol* key, size_t keylen, size_t& prefixLen, const char*& valuepos, bool& hasNext) const { - using namespace NCompactTrie; - + using namespace NCompactTrie; + const char* datapos = DataHolder.AsCharPtr(); size_t len = DataHolder.Length(); - prefixLen = 0; + prefixLen = 0; hasNext = false; bool found = false; - if (EmptyValue) { - valuepos = EmptyValue; - found = true; - } - - if (!key || !len) + if (EmptyValue) { + valuepos = EmptyValue; + found = true; + } + + if (!key || !len) return found; - - const char* const dataend = datapos + len; - + + const char* const dataend = datapos + len; + const T* keyend = key + keylen; - while (key != keyend) { - T label = *(key++); + while (key != keyend) { + T label = *(key++); for (i64 i = (i64)ExtraBits<TSymbol>(); i >= 0; i -= 8) { const char flags = LeapByte(datapos, dataend, (char)(label >> i)); if (!datapos) { return found; // no such arc } - + Y_ASSERT(datapos <= dataend); if ((flags & MT_FINAL)) { prefixLen = keylen - (keyend - key) - (i ? 1 : 0); - valuepos = datapos; + valuepos = datapos; hasNext = flags & MT_NEXT; found = true; @@ -516,67 +516,67 @@ bool TCompactTrie<T, D, S>::LookupLongestPrefix(const TSymbol* key, size_t keyle } datapos += Packer.SkipLeaf(datapos); // skip intermediate leaf nodes } - + if (!(flags & MT_NEXT)) { return found; // no further way - } - } - } - + } + } + } + return found; -} - +} + template <class T, class D, class S> void TCompactTrie<T, D, S>::LookupPhrases( - const char* datapos, size_t len, const TSymbol* key, size_t keylen, + const char* datapos, size_t len, const TSymbol* key, size_t keylen, TVector<TPhraseMatch>& matches, TSymbol separator) const { - using namespace NCompactTrie; - - matches.clear(); - - if (!key || !len) - return; - - const T* const keystart = key; - const T* const keyend = key + keylen; - const char* const dataend = datapos + len; + using namespace NCompactTrie; + + matches.clear(); + + if (!key || !len) + return; + + const T* const keystart = key; + const T* const keyend = key + keylen; + const char* const dataend = datapos + len; while (datapos && key != keyend) { - T label = *(key++); + T label = *(key++); const char* value = nullptr; if (!Advance(datapos, dataend, value, label, Packer)) { return; - } + } if (value && (key == keyend || *key == separator)) { size_t matchlength = (size_t)(key - keystart); D data; Packer.UnpackLeaf(value, data); matches.push_back(TPhraseMatch(matchlength, data)); } - } -} - -// TCompactTrieHolder - -template <class T, class D, class S> + } +} + +// TCompactTrieHolder + +template <class T, class D, class S> TCompactTrieHolder<T, D, S>::TCompactTrieHolder(IInputStream& is, size_t len) - : Storage(new char[len]) -{ - if (is.Load(Storage.Get(), len) != len) { + : Storage(new char[len]) +{ + if (is.Load(Storage.Get(), len) != len) { ythrow yexception() << "bad data load"; - } - TBase::Init(Storage.Get(), len); -} - + } + TBase::Init(Storage.Get(), len); +} + //---------------------------------------------------------------------------------------------------------------- -// TCompactTrie::TConstIterator - +// TCompactTrie::TConstIterator + template <class T, class D, class S> TCompactTrie<T, D, S>::TConstIterator::TConstIterator(const TOpaqueTrie& trie, const char* emptyValue, bool atend, TPacker packer) : Packer(packer) , Impl(new TOpaqueTrieIterator(trie, emptyValue, atend)) { } - + template <class T, class D, class S> TCompactTrie<T, D, S>::TConstIterator::TConstIterator(const TOpaqueTrie& trie, const char* emptyValue, const TKeyBuf& key, TPacker packer) : Packer(packer) @@ -591,27 +591,27 @@ bool TCompactTrie<T, D, S>::TConstIterator::operator==(const TConstIterator& oth return !other.Impl; if (!other.Impl) return false; - return *Impl == *other.Impl; -} - + return *Impl == *other.Impl; +} + template <class T, class D, class S> bool TCompactTrie<T, D, S>::TConstIterator::operator!=(const TConstIterator& other) const { return !operator==(other); -} - +} + template <class T, class D, class S> typename TCompactTrie<T, D, S>::TConstIterator& TCompactTrie<T, D, S>::TConstIterator::operator++() { - Impl->Forward(); - return *this; -} - + Impl->Forward(); + return *this; +} + template <class T, class D, class S> typename TCompactTrie<T, D, S>::TConstIterator TCompactTrie<T, D, S>::TConstIterator::operator++(int /*unused*/) { - TConstIterator copy(*this); - Impl->Forward(); - return copy; -} - + TConstIterator copy(*this); + Impl->Forward(); + return copy; +} + template <class T, class D, class S> typename TCompactTrie<T, D, S>::TConstIterator& TCompactTrie<T, D, S>::TConstIterator::operator--() { Impl->Backward(); @@ -627,14 +627,14 @@ typename TCompactTrie<T, D, S>::TConstIterator TCompactTrie<T, D, S>::TConstIter template <class T, class D, class S> typename TCompactTrie<T, D, S>::TValueType TCompactTrie<T, D, S>::TConstIterator::operator*() { - return TValueType(GetKey(), GetValue()); -} - + return TValueType(GetKey(), GetValue()); +} + template <class T, class D, class S> typename TCompactTrie<T, D, S>::TKey TCompactTrie<T, D, S>::TConstIterator::GetKey() const { return Impl->GetKey<TSymbol>(); -} - +} + template <class T, class D, class S> size_t TCompactTrie<T, D, S>::TConstIterator::GetKeySize() const { return Impl->MeasureKey<TSymbol>(); diff --git a/library/cpp/containers/comptrie/comptrie_ut.cpp b/library/cpp/containers/comptrie/comptrie_ut.cpp index 9600631f28..74bee09b5d 100644 --- a/library/cpp/containers/comptrie/comptrie_ut.cpp +++ b/library/cpp/containers/comptrie/comptrie_ut.cpp @@ -8,9 +8,9 @@ #include <util/generic/algorithm.h> #include <util/generic/buffer.h> #include <util/generic/map.h> -#include <util/generic/vector.h> -#include <util/generic/ptr.h> -#include <util/generic/ylimits.h> +#include <util/generic/vector.h> +#include <util/generic/ptr.h> +#include <util/generic/ylimits.h> #include <util/folder/dirut.h> @@ -135,11 +135,11 @@ private: template <class T> void TestTrieIterator(bool minimize); - template <class T, bool minimize> - void TestRandom(const size_t n, const size_t maxKeySize); - + template <class T, bool minimize> + void TestRandom(const size_t n, const size_t maxKeySize); + void TestFindTailsImpl(const TString& prefix); - + void TestUniqueImpl(bool isPrefixGrouped); TVector<TUtf16String> GetSampleKeys(size_t nKeys) const; @@ -161,14 +161,14 @@ private: template <typename TSymbol> void TestFirstSymbolIterator(); - template <class T> - class TIntPacker; - template <class T> - class TDummyPacker; - class TStrokaPacker; - + template <class T> + class TIntPacker; + template <class T> + class TDummyPacker; + class TStrokaPacker; + public: - void TestPackers(); + void TestPackers(); void TestTrie8(); void TestTrie16(); @@ -199,7 +199,7 @@ public: void TestEmpty(); void TestUninitializedNonEmpty(); void TestRandom(); - void TestFindTails(); + void TestFindTails(); void TestPrefixGrouped(); void CrashTestPrefixGrouped(); void TestMergeFromFile(); @@ -274,7 +274,7 @@ const char* TCompactTrieTest::SampleData[] = { "fba", "fbb", "fbc", "fbd", "fbbaa", "c\x85\xA4\xBF" // Just something outside ASCII. -}; +}; template <class T> typename TCompactTrie<T>::TKey MakeWideKey(const char* str, size_t len) { @@ -613,17 +613,17 @@ void TCompactTrieTest::TestEmpty() { UNIT_ASSERT(!trie.FindLongestPrefix("abc", 3, &prefixLen, &dummy)); UNIT_ASSERT(!trie.FindLongestPrefix("", 0, &prefixLen, &dummy)); UNIT_ASSERT_EQUAL(12345, dummy); - - UNIT_ASSERT(trie.Begin() == trie.End()); - - TCompactTrie<> trieNull; - - UNIT_ASSERT(!trieNull.Find(" ", 1)); - - TCompactTrie<>::TPhraseMatchVector matches; - trieNull.FindPhrases(" ", 1, matches); // just to be sure it doesn't crash - - UNIT_ASSERT(trieNull.Begin() == trieNull.End()); + + UNIT_ASSERT(trie.Begin() == trie.End()); + + TCompactTrie<> trieNull; + + UNIT_ASSERT(!trieNull.Find(" ", 1)); + + TCompactTrie<>::TPhraseMatchVector matches; + trieNull.FindPhrases(" ", 1, matches); // just to be sure it doesn't crash + + UNIT_ASSERT(trieNull.Begin() == trieNull.End()); } void TCompactTrieTest::TestUninitializedNonEmpty() { @@ -658,46 +658,46 @@ static TString RandStr(const size_t max) { return key; } -template <class T, bool minimize> -void TCompactTrieTest::TestRandom(const size_t n, const size_t maxKeySize) { +template <class T, bool minimize> +void TCompactTrieTest::TestRandom(const size_t n, const size_t maxKeySize) { const TStringBuf EMPTY_KEY = TStringBuf("", 1); - TCompactTrieBuilder<char, typename T::TData, T> builder; + TCompactTrieBuilder<char, typename T::TData, T> builder; typedef TMap<TString, typename T::TData> TKeys; - TKeys keys; + TKeys keys; - typename T::TData dummy; - for (size_t i = 0; i < n; ++i) { + typename T::TData dummy; + for (size_t i = 0; i < n; ++i) { const TString key = RandStr(maxKeySize); if (key != EMPTY_KEY && keys.find(key) == keys.end()) { - const typename T::TData val = T::Data(key); - keys[key] = val; + const typename T::TData val = T::Data(key); + keys[key] = val; UNIT_ASSERT_C(!builder.Find(key.data(), key.size(), &dummy), "key = " << HexEncode(TString(key))); builder.Add(key.data(), key.size(), val); UNIT_ASSERT_C(builder.Find(key.data(), key.size(), &dummy), "key = " << HexEncode(TString(key))); - UNIT_ASSERT(dummy == val); - } + UNIT_ASSERT(dummy == val); + } } TBufferStream stream; size_t len = builder.Save(stream); - TCompactTrie<char, typename T::TData, T> trie(stream.Buffer().Data(), len); + TCompactTrie<char, typename T::TData, T> trie(stream.Buffer().Data(), len); - TBufferStream buftmp; - if (minimize) { - CompactTrieMinimize<T>(buftmp, stream.Buffer().Data(), len, false); + TBufferStream buftmp; + if (minimize) { + CompactTrieMinimize<T>(buftmp, stream.Buffer().Data(), len, false); } - TCompactTrie<char, typename T::TData, T> trieMin(buftmp.Buffer().Data(), buftmp.Buffer().Size()); - + TCompactTrie<char, typename T::TData, T> trieMin(buftmp.Buffer().Data(), buftmp.Buffer().Size()); + TCompactTrieBuilder<char, typename T::TData, T> prefixGroupedBuilder(CTBF_PREFIX_GROUPED); - for (typename TKeys::const_iterator i = keys.begin(), mi = keys.end(); i != mi; ++i) { + for (typename TKeys::const_iterator i = keys.begin(), mi = keys.end(); i != mi; ++i) { UNIT_ASSERT(!prefixGroupedBuilder.Find(i->first.c_str(), i->first.size(), &dummy)); - UNIT_ASSERT(trie.Find(i->first.c_str(), i->first.size(), &dummy)); - UNIT_ASSERT(dummy == i->second); - if (minimize) { - UNIT_ASSERT(trieMin.Find(i->first.c_str(), i->first.size(), &dummy)); - UNIT_ASSERT(dummy == i->second); - } + UNIT_ASSERT(trie.Find(i->first.c_str(), i->first.size(), &dummy)); + UNIT_ASSERT(dummy == i->second); + if (minimize) { + UNIT_ASSERT(trieMin.Find(i->first.c_str(), i->first.size(), &dummy)); + UNIT_ASSERT(dummy == i->second); + } prefixGroupedBuilder.Add(i->first.c_str(), i->first.size(), dummy); UNIT_ASSERT(prefixGroupedBuilder.Find(i->first.c_str(), i->first.size(), &dummy)); @@ -711,7 +711,7 @@ void TCompactTrieTest::TestRandom(const size_t n, const size_t maxKeySize) { UNIT_ASSERT(!prefixGroupedBuilder.Find(j->first.c_str(), j->first.size(), &valFound)); } } - } + } TBufferStream prefixGroupedBuffer; prefixGroupedBuilder.Save(prefixGroupedBuffer); @@ -719,62 +719,62 @@ void TCompactTrieTest::TestRandom(const size_t n, const size_t maxKeySize) { UNIT_ASSERT_VALUES_EQUAL(stream.Buffer().Size(), prefixGroupedBuffer.Buffer().Size()); UNIT_ASSERT(0 == memcmp(stream.Buffer().Data(), prefixGroupedBuffer.Buffer().Data(), stream.Buffer().Size())); } - -void TCompactTrieTest::TestRandom() { + +void TCompactTrieTest::TestRandom() { TestRandom<TIntPacker<ui64>, true>(1000, 1000); TestRandom<TIntPacker<int>, true>(100, 100); TestRandom<TDummyPacker<ui64>, true>(0, 0); TestRandom<TDummyPacker<ui64>, true>(100, 3); TestRandom<TDummyPacker<ui64>, true>(100, 100); TestRandom<TStrokaPacker, true>(100, 100); -} - +} + void TCompactTrieTest::TestFindTailsImpl(const TString& prefix) { TCompactTrieBuilder<> builder; - + TMap<TString, ui64> input; - + for (auto& i : SampleData) { TString temp = i; - ui64 val = temp.size() * 2; + ui64 val = temp.size() * 2; builder.Add(temp.data(), temp.size(), val); if (temp.StartsWith(prefix)) { - input[temp.substr(prefix.size())] = val; - } - } - - typedef TCompactTrie<> TTrie; - - TBufferStream stream; - size_t len = builder.Save(stream); - TTrie trie(stream.Buffer().Data(), len); - + input[temp.substr(prefix.size())] = val; + } + } + + typedef TCompactTrie<> TTrie; + + TBufferStream stream; + size_t len = builder.Save(stream); + TTrie trie(stream.Buffer().Data(), len); + TTrie subtrie = trie.FindTails(prefix.data(), prefix.size()); - + TMap<TString, ui64> output; - - for (TTrie::TConstIterator i = subtrie.Begin(), mi = subtrie.End(); i != mi; ++i) { - TTrie::TValueType val = *i; + + for (TTrie::TConstIterator i = subtrie.Begin(), mi = subtrie.End(); i != mi; ++i) { + TTrie::TValueType val = *i; output[TString(val.first.data(), val.first.size())] = val.second; - } - UNIT_ASSERT(input.size() == output.size()); - UNIT_ASSERT(input == output); - - TBufferStream buftmp; - CompactTrieMinimize<TTrie::TPacker>(buftmp, stream.Buffer().Data(), len, false); - TTrie trieMin(buftmp.Buffer().Data(), buftmp.Buffer().Size()); - + } + UNIT_ASSERT(input.size() == output.size()); + UNIT_ASSERT(input == output); + + TBufferStream buftmp; + CompactTrieMinimize<TTrie::TPacker>(buftmp, stream.Buffer().Data(), len, false); + TTrie trieMin(buftmp.Buffer().Data(), buftmp.Buffer().Size()); + subtrie = trieMin.FindTails(prefix.data(), prefix.size()); - output.clear(); - - for (TTrie::TConstIterator i = subtrie.Begin(), mi = subtrie.End(); i != mi; ++i) { - TTrie::TValueType val = *i; + output.clear(); + + for (TTrie::TConstIterator i = subtrie.Begin(), mi = subtrie.End(); i != mi; ++i) { + TTrie::TValueType val = *i; output[TString(val.first.data(), val.first.size())] = val.second; - } - UNIT_ASSERT(input.size() == output.size()); - UNIT_ASSERT(input == output); -} - + } + UNIT_ASSERT(input.size() == output.size()); + UNIT_ASSERT(input == output); +} + void TCompactTrieTest::TestPrefixGrouped() { TBuffer b1b; TCompactTrieBuilder<char, ui32> b1(CTBF_PREFIX_GROUPED); @@ -1004,44 +1004,44 @@ void TCompactTrieTest::TestClear() { UNIT_ASSERT(builder.GetNodeCount() == 1); } -void TCompactTrieTest::TestFindTails() { - TestFindTailsImpl("aa"); - TestFindTailsImpl("bb"); - TestFindTailsImpl("fb"); +void TCompactTrieTest::TestFindTails() { + TestFindTailsImpl("aa"); + TestFindTailsImpl("bb"); + TestFindTailsImpl("fb"); TestFindTailsImpl("fbc"); TestFindTailsImpl("fbbaa"); -} - -template <class T> +} + +template <class T> class TCompactTrieTest::TDummyPacker: public TNullPacker<T> { -public: +public: static T Data(const TString&) { T data; TNullPacker<T>().UnpackLeaf(nullptr, data); return data; - } - - typedef T TData; -}; - + } + + typedef T TData; +}; + class TCompactTrieTest::TStrokaPacker: public TCompactTriePacker<TString> { -public: +public: typedef TString TData; - + static TString Data(const TString& str) { - return str; - } -}; - -template <class T> + return str; + } +}; + +template <class T> class TCompactTrieTest::TIntPacker: public TCompactTriePacker<T> { -public: - typedef T TData; - +public: + typedef T TData; + static TData Data(const TString&) { return RandomNumber<std::make_unsigned_t<T>>(); - } -}; + } +}; void TCompactTrieTest::TestIterateEmptyKey() { TBuffer trieBuffer; diff --git a/library/cpp/containers/comptrie/leaf_skipper.h b/library/cpp/containers/comptrie/leaf_skipper.h index 7622ba3742..3959258948 100644 --- a/library/cpp/containers/comptrie/leaf_skipper.h +++ b/library/cpp/containers/comptrie/leaf_skipper.h @@ -2,7 +2,7 @@ #include <cstddef> -namespace NCompactTrie { +namespace NCompactTrie { class ILeafSkipper { public: virtual size_t SkipLeaf(const char* p) const = 0; @@ -53,4 +53,4 @@ namespace NCompactTrie { return !(*this == other); } }; -} +} diff --git a/library/cpp/containers/comptrie/make_fast_layout.cpp b/library/cpp/containers/comptrie/make_fast_layout.cpp index 3dd81c6543..ade78d7899 100644 --- a/library/cpp/containers/comptrie/make_fast_layout.cpp +++ b/library/cpp/containers/comptrie/make_fast_layout.cpp @@ -6,7 +6,7 @@ #include <util/generic/hash.h> #include <util/generic/utility.h> - + // Lay the trie in memory in such a way that there are less cache misses when jumping from root to leaf. // The trie becomes about 2% larger, but the access became about 25% faster in our experiments. // Can be called on minimized and non-minimized tries, in the first case in requires half a trie more memory. @@ -183,7 +183,7 @@ namespace NCompactTrie { size_t GetDepth() const { return Depth; } - + size_t GetNodeCount() const { return NodeCount; } diff --git a/library/cpp/containers/comptrie/make_fast_layout.h b/library/cpp/containers/comptrie/make_fast_layout.h index 33a378426b..b8fab5d65b 100644 --- a/library/cpp/containers/comptrie/make_fast_layout.h +++ b/library/cpp/containers/comptrie/make_fast_layout.h @@ -5,10 +5,10 @@ class IOutputStream; -namespace NCompactTrie { +namespace NCompactTrie { // Return value: size of the resulting trie. size_t RawCompactTrieFastLayoutImpl(IOutputStream& os, const NCompactTrie::TOpaqueTrie& trie, bool verbose); - + // Return value: size of the resulting trie. template <class TPacker> size_t CompactTrieMakeFastLayoutImpl(IOutputStream& os, const char* data, size_t datalength, bool verbose, const TPacker* packer) { @@ -17,4 +17,4 @@ namespace NCompactTrie { return RawCompactTrieFastLayoutImpl(os, trie, verbose); } -} +} diff --git a/library/cpp/containers/comptrie/minimize.cpp b/library/cpp/containers/comptrie/minimize.cpp index 39299d69dd..80d0b25217 100644 --- a/library/cpp/containers/comptrie/minimize.cpp +++ b/library/cpp/containers/comptrie/minimize.cpp @@ -6,8 +6,8 @@ #include <util/generic/hash.h> #include <util/generic/algorithm.h> - -namespace NCompactTrie { + +namespace NCompactTrie { // Minimize the trie. The result is equivalent to the original // trie, except that it takes less space (and has marginally lower // performance, because of eventual epsilon links). @@ -169,7 +169,7 @@ namespace NCompactTrie { bool IsFinal() const { return Node.IsFinal(); } - + // NextNode returns child nodes, starting from the last node: Right, then Left, then Forward size_t NextNode(const TOffsetMap& mergedNodes) { while (Selector < 3) { diff --git a/library/cpp/containers/comptrie/minimize.h b/library/cpp/containers/comptrie/minimize.h index b36fa5d01f..baaa431d04 100644 --- a/library/cpp/containers/comptrie/minimize.h +++ b/library/cpp/containers/comptrie/minimize.h @@ -5,7 +5,7 @@ class IOutputStream; -namespace NCompactTrie { +namespace NCompactTrie { size_t MeasureOffset(size_t offset); enum EMinimizeMode { @@ -13,7 +13,7 @@ namespace NCompactTrie { MM_NOALLOC, // minimize tree in the same buffer MM_INPLACE // do not write tree to the stream, but move to the buffer beginning }; - + // Return value: size of the minimized trie. size_t RawCompactTrieMinimizeImpl(IOutputStream& os, TOpaqueTrie& trie, bool verbose, size_t minMergeSize, EMinimizeMode mode); @@ -25,5 +25,5 @@ namespace NCompactTrie { TOpaqueTrie trie(data, datalength, skipper); return RawCompactTrieMinimizeImpl(os, trie, verbose, minmerge, mode); } - -} + +} diff --git a/library/cpp/containers/comptrie/node.cpp b/library/cpp/containers/comptrie/node.cpp index a888023bd2..5fd22f15ec 100644 --- a/library/cpp/containers/comptrie/node.cpp +++ b/library/cpp/containers/comptrie/node.cpp @@ -4,8 +4,8 @@ #include <util/system/yassert.h> #include <util/generic/yexception.h> - -namespace NCompactTrie { + +namespace NCompactTrie { TNode::TNode() : Offset(0) , LeafLength(0) diff --git a/library/cpp/containers/comptrie/node.h b/library/cpp/containers/comptrie/node.h index d397b37427..d6f4317db0 100644 --- a/library/cpp/containers/comptrie/node.h +++ b/library/cpp/containers/comptrie/node.h @@ -1,8 +1,8 @@ #pragma once #include <cstddef> - -namespace NCompactTrie { + +namespace NCompactTrie { class ILeafSkipper; enum TDirection { diff --git a/library/cpp/containers/comptrie/opaque_trie_iterator.cpp b/library/cpp/containers/comptrie/opaque_trie_iterator.cpp index 7434e3dbc5..5fd3914be6 100644 --- a/library/cpp/containers/comptrie/opaque_trie_iterator.cpp +++ b/library/cpp/containers/comptrie/opaque_trie_iterator.cpp @@ -21,11 +21,11 @@ namespace NCompactTrie { AtEmptyValue == rhs.AtEmptyValue && MaxKeyLength == rhs.MaxKeyLength); } - + bool TOpaqueTrieIterator::HasMaxKeyLength() const { return MaxKeyLength != size_t(-1) && MeasureNarrowKey() == MaxKeyLength; } - + bool TOpaqueTrieIterator::Forward() { if (AtEmptyValue) { AtEmptyValue = false; @@ -34,11 +34,11 @@ namespace NCompactTrie { return res; // there was not "\0" key } // otherwise we are skipping "\0" key - } - + } + if (!Trie.Length) return false; - + if (Forks.Empty()) { TFork fork(Trie.Data, 0, Trie.Length, Trie.SkipFunction); Forks.Push(fork); @@ -53,7 +53,7 @@ namespace NCompactTrie { topFork = &Forks.Top(); } } - + Y_ASSERT(!Forks.Empty()); while (Forks.Top().CurrentDirection != D_FINAL && !HasMaxKeyLength()) { TFork nextFork = Forks.Top().NextFork(Trie.SkipFunction); @@ -65,8 +65,8 @@ namespace NCompactTrie { top.NextDirection(); } return true; - } - + } + bool TOpaqueTrieIterator::Backward() { if (AtEmptyValue) return false; @@ -141,14 +141,14 @@ namespace NCompactTrie { if (HasEmptyKey()) { return TString(); } - + TString result(Key); if (TopHasLabelInKey()) { result.append(Top().GetLabel()); } return result; } - + bool TForkStack::HasEmptyKey() const { // Special case: if we get a single zero label, treat it as an empty key // TODO delete this after format change @@ -165,8 +165,8 @@ namespace NCompactTrie { return 0; } return result; - } - + } + //------------------------------------------------------------------------- TFork::TFork(const char* data, size_t offset, size_t limit, const ILeafSkipper& skipper) @@ -183,20 +183,20 @@ namespace NCompactTrie { ++CurrentDirection; } } - + bool TFork::operator==(const TFork& rhs) const { return (Data == rhs.Data && Node.GetOffset() == rhs.Node.GetOffset() && CurrentDirection == rhs.CurrentDirection); } - + inline bool TFork::NextDirection() { do { ++CurrentDirection; } while (CurrentDirection < D_MAX && !HasDirection(CurrentDirection)); return CurrentDirection < D_MAX; } - + inline bool TFork::PrevDirection() { if (CurrentDirection == TDirection(0)) { return false; diff --git a/library/cpp/containers/comptrie/opaque_trie_iterator.h b/library/cpp/containers/comptrie/opaque_trie_iterator.h index a5c3cc1358..195da3c191 100644 --- a/library/cpp/containers/comptrie/opaque_trie_iterator.h +++ b/library/cpp/containers/comptrie/opaque_trie_iterator.h @@ -20,13 +20,13 @@ namespace NCompactTrie { public: TFork(const char* data, size_t offset, size_t limit, const ILeafSkipper& skipper); - + bool operator==(const TFork& rhs) const; - + bool HasLabelInKey() const { return CurrentDirection == D_NEXT || CurrentDirection == D_FINAL; } - + bool NextDirection(); bool PrevDirection(); void LastDirection(); @@ -39,7 +39,7 @@ namespace NCompactTrie { // Otherwise returns true. bool SetDirection(TDirection direction); TFork NextFork(const ILeafSkipper& skipper) const; - + char GetLabel() const; size_t GetValueOffset() const; }; @@ -59,7 +59,7 @@ namespace NCompactTrie { } Forks.push_back(fork); } - + void Pop() { Forks.pop_back(); if (TopHasLabelInKey()) { @@ -73,7 +73,7 @@ namespace NCompactTrie { const TFork& Top() const { return Forks.back(); } - + bool Empty() const { return Forks.empty(); } @@ -160,24 +160,24 @@ namespace NCompactTrie { template <class TSymbol> bool UpperBound(const typename TCompactTrieKeySelector<TSymbol>::TKeyBuf& key); // True if matched exactly. - + template <class TSymbol> typename TCompactTrieKeySelector<TSymbol>::TKey GetKey() const { return TConvertRawKey<TSymbol>::Get(GetNarrowKey()); } - + template <class TSymbol> size_t MeasureKey() const { return TConvertRawKey<TSymbol>::Size(MeasureNarrowKey()); } - + TString GetNarrowKey() const { return Forks.GetKey(); } size_t MeasureNarrowKey() const { return Forks.MeasureKey(); } - + const char* GetValuePtr() const; // 0 if none const TNode& GetNode() const { // Could be called for non-empty key and not AtEnd. return Forks.Top().Node; @@ -199,7 +199,7 @@ namespace NCompactTrie { template <class TSymbol> int LongestPrefix(const typename TCompactTrieKeySelector<TSymbol>::TKeyBuf& key); // Used in UpperBound. }; - + template <class TSymbol> int TOpaqueTrieIterator::LongestPrefix(const typename TCompactTrieKeySelector<TSymbol>::TKeyBuf& key) { Forks.Clear(); diff --git a/library/cpp/containers/comptrie/write_trie_backwards.cpp b/library/cpp/containers/comptrie/write_trie_backwards.cpp index 9b124310dc..fd8c28b0ed 100644 --- a/library/cpp/containers/comptrie/write_trie_backwards.cpp +++ b/library/cpp/containers/comptrie/write_trie_backwards.cpp @@ -6,7 +6,7 @@ #include <util/generic/buffer.h> #include <util/generic/vector.h> -namespace NCompactTrie { +namespace NCompactTrie { size_t WriteTrieBackwards(IOutputStream& os, TReverseNodeEnumerator& enumerator, bool verbose) { if (verbose) { Cerr << "Writing down the trie..." << Endl; @@ -37,7 +37,7 @@ namespace NCompactTrie { Y_ASSERT(nodelength <= bufferLength); resultLength += nodelength; - + if (chunkLength + nodelength <= chunksize) { chunkLength += nodelength; memcpy(chunkend - chunkLength, buffer, nodelength); @@ -55,11 +55,11 @@ namespace NCompactTrie { resultData.push_back(new char[chunksize]); chunkend = resultData.back() + chunksize; } - + memcpy(chunkend - chunkLength, buffer, chunkLength); - } + } } - + if (verbose) Cerr << counter << Endl; @@ -79,7 +79,7 @@ namespace NCompactTrie { char* data = const_cast<char*>(trie.Data); char* end = data + trie.Length; char* pos = end; - + TVector<char> buf(64); while (enumerator.Move()) { size_t nodeLength = enumerator.RecreateNode(nullptr, end - pos); diff --git a/library/cpp/containers/comptrie/writeable_node.cpp b/library/cpp/containers/comptrie/writeable_node.cpp index 2028e1eb1a..404003dbbd 100644 --- a/library/cpp/containers/comptrie/writeable_node.cpp +++ b/library/cpp/containers/comptrie/writeable_node.cpp @@ -2,7 +2,7 @@ #include "node.h" #include "comptrie_impl.h" -namespace NCompactTrie { +namespace NCompactTrie { TWriteableNode::TWriteableNode() : LeafPos(nullptr) , LeafLength(0) |