diff options
| author | Anton Samokhvalov <[email protected]> | 2022-02-10 16:45:17 +0300 | 
|---|---|---|
| committer | Daniil Cherednik <[email protected]> | 2022-02-10 16:45:17 +0300 | 
| commit | d3a398281c6fd1d3672036cb2d63f842d2cb28c5 (patch) | |
| tree | dd4bd3ca0f36b817e96812825ffaf10d645803f2 /library/cpp/containers | |
| parent | 72cb13b4aff9bc9cf22e49251bc8fd143f82538f (diff) | |
Restoring authorship annotation for Anton Samokhvalov <[email protected]>. Commit 2 of 2.
Diffstat (limited to 'library/cpp/containers')
73 files changed, 4850 insertions, 4850 deletions
diff --git a/library/cpp/containers/2d_array/2d_array.h b/library/cpp/containers/2d_array/2d_array.h index d57f6e4b2f4..9e246506370 100644 --- a/library/cpp/containers/2d_array/2d_array.h +++ b/library/cpp/containers/2d_array/2d_array.h @@ -1,5 +1,5 @@  #pragma once -  +  #include <util/system/yassert.h>  #include <util/generic/algorithm.h> @@ -27,9 +27,9 @@ private:      T** PData;      size_t XSize;      size_t YSize; -  +  private: -    void Copy(const TArray2D& a) {  +    void Copy(const TArray2D& a) {          XSize = a.XSize;          YSize = a.YSize;          Create(); @@ -46,17 +46,17 @@ private:          for (size_t i = 0; i < YSize; i++)              PData[i] = Data + i * XSize;      } -  +  public:      TArray2D(size_t xsize = 1, size_t ysize = 1) {          XSize = xsize;          YSize = ysize;          Create();      } -    TArray2D(const TArray2D& a) {  +    TArray2D(const TArray2D& a) {          Copy(a);      } -    TArray2D& operator=(const TArray2D& a) {  +    TArray2D& operator=(const TArray2D& a) {          Destroy();          Copy(a);          return *this; @@ -73,7 +73,7 @@ public:          Create();      }      void Clear() { -        SetSizes(1, 1);  +        SetSizes(1, 1);      }  #ifdef _DEBUG      TBoundCheck<T> operator[](size_t i) const { @@ -107,8 +107,8 @@ public:      }  }; -template <class T>  -inline bool operator==(const TArray2D<T>& a, const TArray2D<T>& b) {  +template <class T> +inline bool operator==(const TArray2D<T>& a, const TArray2D<T>& b) {      if (a.GetXSize() != b.GetXSize() || a.GetYSize() != b.GetYSize())          return false;      for (size_t y = 0; y < a.GetYSize(); ++y) { @@ -119,7 +119,7 @@ inline bool operator==(const TArray2D<T>& a, const TArray2D<T>& b) {      return true;  } -template <class T>  -inline bool operator!=(const TArray2D<T>& a, const TArray2D<T>& b) {  +template <class T> +inline bool operator!=(const TArray2D<T>& a, const TArray2D<T>& b) {      return !(a == b);  } diff --git a/library/cpp/containers/2d_array/ya.make b/library/cpp/containers/2d_array/ya.make index c542a46070f..71d56b902f3 100644 --- a/library/cpp/containers/2d_array/ya.make +++ b/library/cpp/containers/2d_array/ya.make @@ -1,6 +1,6 @@  LIBRARY() -OWNER(kirillovs)  +OWNER(kirillovs)  SRCS(      2d_array.cpp diff --git a/library/cpp/containers/atomizer/atomizer.cpp b/library/cpp/containers/atomizer/atomizer.cpp index 90d526adb4b..7a5f781d992 100644 --- a/library/cpp/containers/atomizer/atomizer.cpp +++ b/library/cpp/containers/atomizer/atomizer.cpp @@ -1 +1 @@ -#include "atomizer.h"  +#include "atomizer.h" diff --git a/library/cpp/containers/atomizer/atomizer.h b/library/cpp/containers/atomizer/atomizer.h index 8f9e5c50016..5e40f47ab93 100644 --- a/library/cpp/containers/atomizer/atomizer.h +++ b/library/cpp/containers/atomizer/atomizer.h @@ -1,24 +1,24 @@  #pragma once  #include <library/cpp/containers/str_map/str_map.h> -  +  #include <util/generic/vector.h>  #include <util/generic/utility.h> -  +  #include <utility> -#include <cstdio>  -  -template <class HashFcn = THash<const char*>, class EqualTo = TEqualTo<const char*>>  -class atomizer;  -  -template <class T, class HashFcn = THash<const char*>, class EqualTo = TEqualTo<const char*>>  -class super_atomizer;  -  +#include <cstdio> + +template <class HashFcn = THash<const char*>, class EqualTo = TEqualTo<const char*>> +class atomizer; + +template <class T, class HashFcn = THash<const char*>, class EqualTo = TEqualTo<const char*>> +class super_atomizer; +  template <class HashFcn, class EqualTo> -class atomizer: public string_hash<ui32, HashFcn, EqualTo> {  +class atomizer: public string_hash<ui32, HashFcn, EqualTo> {  private:      TVector<const char*> order; -  +  public:      using iterator = typename string_hash<ui32, HashFcn, EqualTo>::iterator;      using const_iterator = typename string_hash<ui32, HashFcn, EqualTo>::const_iterator; @@ -33,84 +33,84 @@ public:      using string_hash<ui32, HashFcn, EqualTo>::insert_copy;      using string_hash<ui32, HashFcn, EqualTo>::clear_hash; -    atomizer() {  +    atomizer() {          order.reserve(HASH_SIZE_DEFAULT);      }      atomizer(size_type hash_size, pool_size_type pool_size) -        : string_hash<ui32, HashFcn, EqualTo>(hash_size, pool_size)  +        : string_hash<ui32, HashFcn, EqualTo>(hash_size, pool_size)      {          order.reserve(hash_size);      }      ~atomizer() = default; -    ui32 string_to_atom(const char* key) {  -        const char* old_begin = pool.Begin();  -        const char* old_end = pool.End();  +    ui32 string_to_atom(const char* key) { +        const char* old_begin = pool.Begin(); +        const char* old_end = pool.End();          std::pair<iterator, bool> ins = insert_copy(key, ui32(size() + 1)); -        if (ins.second) {                  // new?  -            if (pool.Begin() != old_begin) // repoint?  +        if (ins.second) {                  // new? +            if (pool.Begin() != old_begin) // repoint?                  for (TVector<const char*>::iterator ptr = order.begin(); ptr != order.end(); ++ptr)                      if (old_begin <= *ptr && *ptr < old_end) // from old pool? -                        *ptr += pool.Begin() - old_begin;  +                        *ptr += pool.Begin() - old_begin;              order.push_back((*ins.first).first); // copy of 'key'          }          return (ui32)(*ins.first).second;      } -    ui32 perm_string_to_atom(const char* key) {  -        value_type val(key, ui32(size() + 1));  +    ui32 perm_string_to_atom(const char* key) { +        value_type val(key, ui32(size() + 1));          std::pair<iterator, bool> ins = this->insert(val);          if (ins.second)              order.push_back((*ins.first).first); // == copy of 'key' -        return (ui32)(*ins.first).second;        // == size()+1  +        return (ui32)(*ins.first).second;        // == size()+1      } -    ui32 find_atom(const char* key) const {  +    ui32 find_atom(const char* key) const {          const_iterator it = find(key);          if (it == end())              return 0; // INVALID_ATOM          else              return (ui32)(*it).second;      } -    const char* get_atom_name(ui32 atom) const {  +    const char* get_atom_name(ui32 atom) const {          if (atom && atom <= size()) -            return order[atom - 1];  +            return order[atom - 1];          return nullptr;      } -    void clear_atomizer() {  +    void clear_atomizer() {          clear_hash();          order.clear();      } -    void SaveC2N(FILE* f) const { // we write sorted file  +    void SaveC2N(FILE* f) const { // we write sorted file          for (ui32 i = 0; i < order.size(); i++)              if (order[i]) -                fprintf(f, "%d\t%s\n", i + 1, order[i]);  +                fprintf(f, "%d\t%s\n", i + 1, order[i]);      } -    void LoadC2N(FILE* f) { // but can read unsorted one  +    void LoadC2N(FILE* f) { // but can read unsorted one          long k, km = 0;          char buf[1000]; -        char* s;  +        char* s;          while (fgets(buf, 1000, f)) {              k = strtol(buf, &s, 10); -            char* endl = strchr(s, '\n');  +            char* endl = strchr(s, '\n');              if (endl)                  *endl = 0;              if (k > 0 && k != LONG_MAX) { -                km = Max(km, k);  +                km = Max(km, k);                  insert_copy(++s, ui32(k));              }          }          order.resize(km); -        memset(&order[0], 0, order.size()); // if some atoms are absent  +        memset(&order[0], 0, order.size()); // if some atoms are absent          for (const_iterator I = this->begin(); I != end(); ++I)              order[(*I).second - 1] = (*I).first;      }  };  template <class T, class HashFcn, class EqualTo> -class super_atomizer: public string_hash<ui32, HashFcn, EqualTo> {  +class super_atomizer: public string_hash<ui32, HashFcn, EqualTo> {  private:      using TOrder = TVector<std::pair<const char*, T>>;      TOrder order; -  +  public:      using iterator = typename string_hash<ui32, HashFcn, EqualTo>::iterator;      using const_iterator = typename string_hash<ui32, HashFcn, EqualTo>::const_iterator; @@ -129,56 +129,56 @@ public:      using string_hash<ui32, HashFcn, EqualTo>::insert_copy;      using string_hash<ui32, HashFcn, EqualTo>::clear_hash; -    super_atomizer() {  +    super_atomizer() {          order.reserve(HASH_SIZE_DEFAULT);      }      super_atomizer(size_type hash_size, pool_size_type pool_size) -        : string_hash<ui32, HashFcn, EqualTo>(hash_size, pool_size)  +        : string_hash<ui32, HashFcn, EqualTo>(hash_size, pool_size)      {          order.reserve(hash_size);      }      ~super_atomizer() = default; -    ui32 string_to_atom(const char* key, const T* atom_data = NULL) {  -        const char* old_begin = pool.Begin();  -        const char* old_end = pool.End();  +    ui32 string_to_atom(const char* key, const T* atom_data = NULL) { +        const char* old_begin = pool.Begin(); +        const char* old_end = pool.End();          std::pair<iterator, bool> ins = insert_copy(key, ui32(size() + 1)); -        if (ins.second) {                  // new?  -            if (pool.Begin() != old_begin) // repoint?  +        if (ins.second) {                  // new? +            if (pool.Begin() != old_begin) // repoint?                  for (typename TOrder::iterator ptr = order.begin(); ptr != order.end(); ++ptr)                      if (old_begin <= (*ptr).first && (*ptr).first < old_end) // from old pool? -                        (*ptr).first += pool.Begin() - old_begin;  +                        (*ptr).first += pool.Begin() - old_begin;              order.push_back(std::pair<const char*, T>((*ins.first).first, atom_data ? *atom_data : T()));          }          return (*ins.first).second;      } -    ui32 perm_string_to_atom(const char* key, const T* atom_data = NULL) {  -        value_type val(key, ui32(size() + 1));  +    ui32 perm_string_to_atom(const char* key, const T* atom_data = NULL) { +        value_type val(key, ui32(size() + 1));          std::pair<iterator, bool> ins = this->insert(val);          if (ins.second)              order.push_back(std::pair<const char*, T>((*ins.first).first, atom_data ? *atom_data : T()));          return (*ins.first).second; // == size()+1      } -    ui32 find_atom(const char* key) const {  +    ui32 find_atom(const char* key) const {          const_iterator it = find(key);          if (it == end())              return 0; // INVALID_ATOM          else              return (*it).second;      } -    const char* get_atom_name(ui32 atom) const {  +    const char* get_atom_name(ui32 atom) const {          if (atom && atom <= size()) -            return order[atom - 1].first;  +            return order[atom - 1].first;          return nullptr;      }      const T* get_atom_data(ui32 atom) const {          if (atom && atom <= size()) -            return &order[atom - 1].second;  +            return &order[atom - 1].second;          return NULL;      }      T* get_atom_data(ui32 atom) {          if (atom && atom <= size()) -            return &order[atom - 1].second;  +            return &order[atom - 1].second;          return NULL;      }      o_iterator o_begin() { @@ -193,7 +193,7 @@ public:      o_const_iterator o_end() const {          return order.end();      } -    void clear_atomizer() {  +    void clear_atomizer() {          clear_hash();          order.clear();      } diff --git a/library/cpp/containers/atomizer/ya.make b/library/cpp/containers/atomizer/ya.make index c3ad49fff2e..55165a3b672 100644 --- a/library/cpp/containers/atomizer/ya.make +++ b/library/cpp/containers/atomizer/ya.make @@ -1,13 +1,13 @@ -LIBRARY()  -  +LIBRARY() +  OWNER(g:util) -  -PEERDIR(  + +PEERDIR(      library/cpp/containers/str_map -)  -  -SRCS(  -    atomizer.cpp  -)  -  -END()  +) + +SRCS( +    atomizer.cpp +) + +END() diff --git a/library/cpp/containers/bitseq/bititerator.h b/library/cpp/containers/bitseq/bititerator.h index 6eeaec40739..52dadd37982 100644 --- a/library/cpp/containers/bitseq/bititerator.h +++ b/library/cpp/containers/bitseq/bititerator.h @@ -3,7 +3,7 @@  #include "traits.h"  #include <library/cpp/pop_count/popcount.h> -  +  template <typename T>  class TBitIterator {  public: @@ -15,8 +15,8 @@ public:          : Current(0)          , Mask(0)          , Data(data) -    {  -    }  +    { +    }      /// Get the word next to the one we are currenlty iterating over.      const TWord* NextWord() const { @@ -49,7 +49,7 @@ public:          if (!Mask)              return *Data & TTraits::ElemMask(count); -        auto usedBits = (size_t)PopCount(Mask - 1);  +        auto usedBits = (size_t)PopCount(Mask - 1);          TWord result = Current >> usedBits;          auto leftInCurrent = TTraits::NumBits - usedBits;          if (count <= leftInCurrent) @@ -72,7 +72,7 @@ public:              return Current & TTraits::ElemMask(count);          } -        auto usedBits = (size_t)PopCount(Mask - 1);  +        auto usedBits = (size_t)PopCount(Mask - 1);          TWord result = Current >> usedBits;          auto leftInCurrent = TTraits::NumBits - usedBits;          if (count < leftInCurrent) { @@ -97,7 +97,7 @@ public:          if (!count)              return; -        int leftInCurrent = (size_t)PopCount(~(Mask - 1));  +        int leftInCurrent = (size_t)PopCount(~(Mask - 1));          if (count < leftInCurrent) {              Mask <<= count;              return; diff --git a/library/cpp/containers/bitseq/bititerator_ut.cpp b/library/cpp/containers/bitseq/bititerator_ut.cpp index e5aa5a91842..ed0925866f6 100644 --- a/library/cpp/containers/bitseq/bititerator_ut.cpp +++ b/library/cpp/containers/bitseq/bititerator_ut.cpp @@ -12,7 +12,7 @@ Y_UNIT_TEST_SUITE(TBitIteratorTest) {      }      template <typename TWord> -    void AssertPeekRead(TBitIterator<TWord> & iter, ui8 count, TWord expected) {  +    void AssertPeekRead(TBitIterator<TWord> & iter, ui8 count, TWord expected) {          auto peek = iter.Peek(count);          auto read = iter.Read(count);          UNIT_ASSERT_EQUAL(peek, read); diff --git a/library/cpp/containers/bitseq/bitvector.cpp b/library/cpp/containers/bitseq/bitvector.cpp index 895baeb99b3..05cb3a881df 100644 --- a/library/cpp/containers/bitseq/bitvector.cpp +++ b/library/cpp/containers/bitseq/bitvector.cpp @@ -1 +1 @@ -#include "bitvector.h"  +#include "bitvector.h" diff --git a/library/cpp/containers/bitseq/bitvector.h b/library/cpp/containers/bitseq/bitvector.h index e5d171a203c..3f8fd81ee57 100644 --- a/library/cpp/containers/bitseq/bitvector.h +++ b/library/cpp/containers/bitseq/bitvector.h @@ -3,7 +3,7 @@  #include "traits.h"  #include <library/cpp/pop_count/popcount.h> -  +  #include <util/generic/vector.h>  #include <util/ysaveload.h> @@ -78,8 +78,8 @@ public:      }      void Set(ui64 pos, TWord value, ui8 width, TWord mask) { -        if (!width)  -            return;  +        if (!width) +            return;          Y_ASSERT((pos + width) <= Size_);          size_t word = pos >> TTraits::DivShift;          TWord shift1 = pos & TTraits::ModMask; @@ -87,8 +87,8 @@ public:          Data_[word] &= ~(mask << shift1);          Data_[word] |= (value & mask) << shift1;          if (shift2 < width) { -            Data_[word + 1] &= ~(mask >> shift2);  -            Data_[word + 1] |= (value & mask) >> shift2;  +            Data_[word + 1] &= ~(mask >> shift2); +            Data_[word + 1] |= (value & mask) >> shift2;          }      } @@ -97,8 +97,8 @@ public:      }      void Append(TWord value, ui8 width, TWord mask) { -        if (!width)  -            return;  +        if (!width) +            return;          if (Data_.size() * TTraits::NumBits < Size_ + width) {              Data_.push_back(0);          } @@ -113,7 +113,7 @@ public:      size_t Count() const {          size_t count = 0;          for (size_t i = 0; i < Data_.size(); ++i) { -            count += (size_t)PopCount(Data_[i]);  +            count += (size_t)PopCount(Data_[i]);          }          return count;      } @@ -142,7 +142,7 @@ public:      ui64 Space() const {          return CHAR_BIT * (sizeof(Size_) + -                           Data_.size() * sizeof(TWord));  +                           Data_.size() * sizeof(TWord));      }      void Print(IOutputStream& out, size_t truncate = 128) { diff --git a/library/cpp/containers/bitseq/readonly_bitvector.h b/library/cpp/containers/bitseq/readonly_bitvector.h index 419e49811e9..8612739c3f7 100644 --- a/library/cpp/containers/bitseq/readonly_bitvector.h +++ b/library/cpp/containers/bitseq/readonly_bitvector.h @@ -16,8 +16,8 @@ public:      TReadonlyBitVector()          : Size_()          , Data_() -    {  -    }  +    { +    }      explicit TReadonlyBitVector(const TBitVector<T>& vector)          : Size_(vector.Size_) diff --git a/library/cpp/containers/bitseq/ya.make b/library/cpp/containers/bitseq/ya.make index 758e2bec775..7090956c557 100644 --- a/library/cpp/containers/bitseq/ya.make +++ b/library/cpp/containers/bitseq/ya.make @@ -2,14 +2,14 @@ LIBRARY()  OWNER(g:util) -PEERDIR(  -    util/draft  +PEERDIR( +    util/draft      library/cpp/pop_count -)  -  -SRCS(  -    bitvector.cpp  +) + +SRCS( +    bitvector.cpp      readonly_bitvector.cpp -)  -  +) +  END() diff --git a/library/cpp/containers/compact_vector/compact_vector.h b/library/cpp/containers/compact_vector/compact_vector.h index 9e379385464..dbe7473f0cc 100644 --- a/library/cpp/containers/compact_vector/compact_vector.h +++ b/library/cpp/containers/compact_vector/compact_vector.h @@ -24,11 +24,11 @@ private:      T* Ptr;      THeader* Header() { -        return ((THeader*)Ptr) - 1;  +        return ((THeader*)Ptr) - 1;      }      const THeader* Header() const { -        return ((THeader*)Ptr) - 1;  +        return ((THeader*)Ptr) - 1;      }  public: @@ -40,8 +40,8 @@ public:      TCompactVector()          : Ptr(nullptr) -    {  -    }  +    { +    }      TCompactVector(const TThis& that)          : Ptr(nullptr) @@ -105,7 +105,7 @@ public:              void* mem = ::malloc(sizeof(THeader) + newCapacity * sizeof(T));              if (mem == nullptr)                  ythrow yexception() << "out of memory"; -            Ptr = (T*)(((THeader*)mem) + 1);  +            Ptr = (T*)(((THeader*)mem) + 1);              Header()->Size = 0;              Header()->Capacity = newCapacity;          } else { @@ -197,12 +197,12 @@ public:          Clear();      } -    T& operator[](size_t index) {  +    T& operator[](size_t index) {          Y_ASSERT(index < Size());          return Ptr[index];      } -    const T& operator[](size_t index) const {  +    const T& operator[](size_t index) const {          Y_ASSERT(index < Size());          return Ptr[index];      } diff --git a/library/cpp/containers/comptrie/array_with_size.h b/library/cpp/containers/comptrie/array_with_size.h index 148200fe6ae..36e61c74103 100644 --- a/library/cpp/containers/comptrie/array_with_size.h +++ b/library/cpp/containers/comptrie/array_with_size.h @@ -3,19 +3,19 @@  #include <util/generic/ptr.h>  #include <util/generic/noncopyable.h>  #include <util/generic/utility.h> -#include <util/system/sys_alloc.h>  +#include <util/system/sys_alloc.h>  template <typename T> -class TArrayWithSizeHolder : TNonCopyable {  +class TArrayWithSizeHolder : TNonCopyable {      typedef TArrayWithSizeHolder<T> TThis;      T* Data;  public: -    TArrayWithSizeHolder()  -        : Data(nullptr)  -    {  -    }  +    TArrayWithSizeHolder() +        : Data(nullptr) +    { +    }      ~TArrayWithSizeHolder() {          if (!Data) @@ -26,7 +26,7 @@ public:              } catch (...) {              }          } -        y_deallocate(((size_t*)Data) - 1);  +        y_deallocate(((size_t*)Data) - 1);      }      void Swap(TThis& copy) { @@ -37,7 +37,7 @@ public:          if (newSize == Size())              return;          TThis copy; -        copy.Data = (T*)(((size_t*)y_allocate(sizeof(size_t) + sizeof(T) * newSize)) + 1);  +        copy.Data = (T*)(((size_t*)y_allocate(sizeof(size_t) + sizeof(T) * newSize)) + 1);          // does not handle constructor exceptions properly          for (size_t i = 0; i < Min(Size(), newSize); ++i) {              new (copy.Data + i) T(Data[i]); @@ -45,12 +45,12 @@ public:          for (size_t i = Min(Size(), newSize); i < newSize; ++i) {              new (copy.Data + i) T;          } -        ((size_t*)copy.Data)[-1] = newSize;  +        ((size_t*)copy.Data)[-1] = newSize;          Swap(copy);      }      size_t Size() const { -        return Data ? ((size_t*)Data)[-1] : 0;  +        return Data ? ((size_t*)Data)[-1] : 0;      }      bool Empty() const { diff --git a/library/cpp/containers/comptrie/chunked_helpers_trie.h b/library/cpp/containers/comptrie/chunked_helpers_trie.h index 6efe55b5f0e..cfa35f5ba2a 100644 --- a/library/cpp/containers/comptrie/chunked_helpers_trie.h +++ b/library/cpp/containers/comptrie/chunked_helpers_trie.h @@ -13,7 +13,7 @@ public:          : Trie(blob)      {      } -  +      bool Has(const char* key) const {          return Trie.Find(key, strlen(key));      } @@ -23,7 +23,7 @@ public:      }  }; -template <bool sorted = false>  +template <bool sorted = false>  class TTrieSetWriter {  private:      TCompactTrieBuilder<char> Builder; @@ -57,24 +57,24 @@ public:      }  }; -template <bool isWriter, bool sorted = false>  +template <bool isWriter, bool sorted = false>  struct TTrieSetG; -template <bool sorted>  +template <bool sorted>  struct TTrieSetG<false, sorted> {      typedef TTrieSet T;  }; -template <bool sorted>  +template <bool sorted>  struct TTrieSetG<true, sorted> {      typedef TTrieSetWriter<sorted> T;  }; -template <typename T>  +template <typename T>  class TTrieMap {  private:      TCompactTrie<char> Trie; -    static_assert(sizeof(T) <= sizeof(ui64), "expect sizeof(T) <= sizeof(ui64)");  +    static_assert(sizeof(T) <= sizeof(ui64), "expect sizeof(T) <= sizeof(ui64)");  public:      TTrieMap(const TBlob& blob) @@ -101,17 +101,17 @@ public:          }      } -    const TCompactTrie<char>& GetTrie() const {  +    const TCompactTrie<char>& GetTrie() const {          return Trie;      }  }; -template <typename T, bool sorted = false>  +template <typename T, bool sorted = false>  class TTrieMapWriter {  private:      typedef TCompactTrieBuilder<char> TBuilder;      TBuilder Builder; -    static_assert(sizeof(T) <= sizeof(ui64), "expect sizeof(T) <= sizeof(ui64)");  +    static_assert(sizeof(T) <= sizeof(ui64), "expect sizeof(T) <= sizeof(ui64)");  #ifndef NDEBUG      bool IsSorted;  #endif @@ -130,12 +130,12 @@ public:          memcpy(&intValue, &value, sizeof(T));          Builder.Add(key, strlen(key), intValue);  #ifndef NDEBUG -        /*  +        /*          if (!IsSorted) {              T test;              assert(Get(key, &test) && value == test);          } -        */  +        */  #endif      } @@ -177,7 +177,7 @@ public:      }  }; -template <typename T>  +template <typename T>  class TTrieSortedMapWriter {  private:      typedef std::pair<TString, T> TValue; @@ -204,15 +204,15 @@ public:      }  }; -template <typename X, bool isWriter, bool sorted = false>  +template <typename X, bool isWriter, bool sorted = false>  struct TTrieMapG; -template <typename X, bool sorted>  +template <typename X, bool sorted>  struct TTrieMapG<X, false, sorted> {      typedef TTrieMap<X> T;  }; -template <typename X, bool sorted>  +template <typename X, bool sorted>  struct TTrieMapG<X, true, sorted> {      typedef TTrieMapWriter<X, sorted> T;  }; diff --git a/library/cpp/containers/comptrie/comptrie.cpp b/library/cpp/containers/comptrie/comptrie.cpp index 86a006a231f..4556e5b5719 100644 --- a/library/cpp/containers/comptrie/comptrie.cpp +++ b/library/cpp/containers/comptrie/comptrie.cpp @@ -1,8 +1,8 @@ -#include "comptrie_impl.h"  -#include "comptrie.h"  -#include "array_with_size.h"  -#include "comptrie_trie.h"  -#include "comptrie_builder.h"  -#include "protopacker.h"  -#include "set.h"  -#include "chunked_helpers_trie.h"  +#include "comptrie_impl.h" +#include "comptrie.h" +#include "array_with_size.h" +#include "comptrie_trie.h" +#include "comptrie_builder.h" +#include "protopacker.h" +#include "set.h" +#include "chunked_helpers_trie.h" diff --git a/library/cpp/containers/comptrie/comptrie_builder.h b/library/cpp/containers/comptrie/comptrie_builder.h index e0364eef9f7..cf7d2e39a34 100644 --- a/library/cpp/containers/comptrie/comptrie_builder.h +++ b/library/cpp/containers/comptrie/comptrie_builder.h @@ -26,18 +26,18 @@ enum ECompactTrieBuilderFlags {  using TCompactTrieBuilderFlags = ECompactTrieBuilderFlags; -inline TCompactTrieBuilderFlags operator|(TCompactTrieBuilderFlags first, TCompactTrieBuilderFlags second) {  +inline TCompactTrieBuilderFlags operator|(TCompactTrieBuilderFlags first, TCompactTrieBuilderFlags second) {      return static_cast<TCompactTrieBuilderFlags>(static_cast<int>(first) | second);  } -inline TCompactTrieBuilderFlags& operator|=(TCompactTrieBuilderFlags& first, TCompactTrieBuilderFlags second) {  +inline TCompactTrieBuilderFlags& operator|=(TCompactTrieBuilderFlags& first, TCompactTrieBuilderFlags second) {      return first = first | second;  }  template <typename T>  class TArrayWithSizeHolder; -template <class T = char, class D = ui64, class S = TCompactTriePacker<D>>  +template <class T = char, class D = ui64, class S = TCompactTriePacker<D>>  class TCompactTrieBuilder {  public:      typedef T TSymbol; @@ -92,12 +92,12 @@ public:      size_t GetEntryCount() const;      size_t GetNodeCount() const; -  +      // Exact output file size in bytes.      size_t MeasureByteSize() const {          return Impl->MeasureByteSize();      } -  +  protected:      class TCompactTrieBuilderImpl;      THolder<TCompactTrieBuilderImpl> Impl; diff --git a/library/cpp/containers/comptrie/comptrie_builder.inl b/library/cpp/containers/comptrie/comptrie_builder.inl index e19f005d7c4..f273fa65710 100644 --- a/library/cpp/containers/comptrie/comptrie_builder.inl +++ b/library/cpp/containers/comptrie/comptrie_builder.inl @@ -27,7 +27,7 @@  template <class T, class D, class S>  class TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl {  protected: -    TMemoryPool Pool;  +    TMemoryPool Pool;      size_t PayloadSize;      THolder<TFixedSizeAllocator> NodeAllocator;      class TNode; @@ -138,7 +138,7 @@ public:              Y_ASSERT(reinterpret_cast<ISubtree*>(this) == static_cast<void*>(this)); // This assumption is used in TNode::Subtree()          } -        iterator Find(char ch);  +        iterator Find(char ch);          const_iterator Find(char ch) const;          void Add(const TBlob& s, TNode* node); @@ -422,8 +422,8 @@ public:  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>  bool TCompactTrieBuilder<T, D, S>::Add(const TSymbol* key, size_t keylen, const TData& value) { @@ -742,7 +742,7 @@ bool TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::FindLongestPrefixImp  template <class T, class D, class S>  void TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::Clear() {      DestroyNode(Root); -    Pool.Clear();  +    Pool.Clear();      NodeAllocator.Reset(new TFixedSizeAllocator(sizeof(TNode) + PayloadSize, TDefaultAllocator::Instance()));      Root = new (*NodeAllocator) TNode;      EntryCount = 0; @@ -980,11 +980,11 @@ ui64 TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::ArcSaveAndDestroy(co  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;  -    iterator it = LowerBound(this->begin(), this->end(), ch, TCmp());  -  +    using namespace NCompTriePrivate; +    iterator it = LowerBound(this->begin(), this->end(), ch, TCmp()); +      if (it != this->end() && it->Label[0] == (unsigned char)ch) { -        return it;  +        return it;      }      return this->end(); @@ -1005,7 +1005,7 @@ typename TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::TNode::TArcSet::  template <class T, class D, class S>  void TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::TNode::TArcSet::Add(const TBlob& s, TNode* node) { -    using namespace NCompTriePrivate;  +    using namespace NCompTriePrivate;      this->insert(LowerBound(this->begin(), this->end(), s[0], TCmp()), TArc(s, node));  } diff --git a/library/cpp/containers/comptrie/comptrie_impl.cpp b/library/cpp/containers/comptrie/comptrie_impl.cpp index a293b45d1c5..a116ab6d1ef 100644 --- a/library/cpp/containers/comptrie/comptrie_impl.cpp +++ b/library/cpp/containers/comptrie/comptrie_impl.cpp @@ -6,34 +6,34 @@  // 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;  - -        while (offset) {  -            offset >>= 8;  -            ++n;  -        }  -  -        return n;  +    size_t MeasureOffset(size_t offset) { +        int n = 0; + +        while (offset) { +            offset >>= 8; +            ++n; +        } + +        return n;      } -  -    size_t PackOffset(char* buffer, size_t offset) {  -        size_t len = MeasureOffset(offset);  -        size_t i = len;  - -        while (i--) {  -            buffer[i] = (char)(offset & 0xFF);  -            offset >>= 8;  -        }  -  -        return len;  + +    size_t PackOffset(char* buffer, size_t offset) { +        size_t len = MeasureOffset(offset); +        size_t i = len; + +        while (i--) { +            buffer[i] = (char)(offset & 0xFF); +            offset >>= 8; +        } + +        return len;      } -  -    void ShowProgress(size_t n) {  -        if (n % 1000000 == 0)  + +    void ShowProgress(size_t n) { +        if (n % 1000000 == 0)              Cerr << n << ", RSS=" << (TRusage::Get().MaxRss >> 20) << "mb" << Endl; -        else if (n % 20000 == 0)  -            Cerr << ".";  -    }  +        else if (n % 20000 == 0) +            Cerr << "."; +    }  } diff --git a/library/cpp/containers/comptrie/comptrie_impl.h b/library/cpp/containers/comptrie/comptrie_impl.h index f4b0bf072ec..f41c38311a4 100644 --- a/library/cpp/containers/comptrie/comptrie_impl.h +++ b/library/cpp/containers/comptrie/comptrie_impl.h @@ -9,10 +9,10 @@  // NCompactTrie  namespace NCompactTrie { -    const char MT_FINAL = '\x80';  -    const char MT_NEXT = '\x40';  +    const char MT_FINAL = '\x80'; +    const char MT_NEXT = '\x40';      const char MT_SIZEMASK = '\x07'; -    const size_t MT_LEFTSHIFT = 3;  +    const size_t MT_LEFTSHIFT = 3;      const size_t MT_RIGHTSHIFT = 0;      Y_FORCE_INLINE size_t UnpackOffset(const char* p, size_t len); @@ -72,22 +72,22 @@ namespace NCompTriePrivate {          typedef TUtf32String TResult;      }; -}  +} -namespace NCompTriePrivate {  -    struct TCmp {  -        template <class T>  -        inline bool operator()(const T& l, const T& r) {  +namespace NCompTriePrivate { +    struct TCmp { +        template <class T> +        inline bool operator()(const T& l, const T& r) {              return (unsigned char)(l.Label[0]) < (unsigned char)(r.Label[0]); -        }  -  -        template <class T>  -        inline bool operator()(const T& l, char r) {  +        } + +        template <class T> +        inline bool operator()(const T& l, char r) {              return (unsigned char)(l.Label[0]) < (unsigned char)r; -        }  -    };  -}  -  +        } +    }; +} +  namespace NCompactTrie {      static inline ui64 ArcSaveOffset(size_t offset, IOutputStream& os) {          using namespace NCompactTrie; @@ -184,7 +184,7 @@ namespace NCompactTrie {      // Returns true if the symbol was succesfully found in the trie, false otherwise.      template <typename TSymbol, class TPacker>      Y_FORCE_INLINE bool Advance(const char*& datapos, const char* const dataend, const char*& value, -                                TSymbol label, TPacker packer) {  +                                TSymbol label, TPacker packer) {          Y_ASSERT(datapos < dataend);          char flags = MT_NEXT;          for (int i = (int)ExtraBits<TSymbol>(); i >= 0; i -= 8) { diff --git a/library/cpp/containers/comptrie/comptrie_trie.h b/library/cpp/containers/comptrie/comptrie_trie.h index 1fa8794897c..40ec1e52b32 100644 --- a/library/cpp/containers/comptrie/comptrie_trie.h +++ b/library/cpp/containers/comptrie/comptrie_trie.h @@ -29,7 +29,7 @@ template <class TTrie>  class TPrefixIterator;  // in case of <char> specialization cannot distinguish between "" and "\0" keys -template <class T = char, class D = ui64, class S = TCompactTriePacker<D>>  +template <class T = char, class D = ui64, class S = TCompactTriePacker<D>>  class TCompactTrie {  public:      typedef T TSymbol; @@ -56,12 +56,12 @@ public:      TCompactTrie(const char* d, size_t len, TPacker packer);      TCompactTrie(const char* d, size_t len) -        : TCompactTrie{d, len, TPacker{}} {  +        : TCompactTrie{d, len, TPacker{}} {      }      TCompactTrie(const TBlob& data, TPacker packer);      explicit TCompactTrie(const TBlob& data) -        : TCompactTrie{data, TPacker{}} {  +        : TCompactTrie{data, TPacker{}} {      }      // Skipper should be initialized with &Packer, not with &other.Packer, so you have to redefine these. @@ -126,7 +126,7 @@ public:      bool FindLongestPrefix(const TKeyBuf& key, size_t* prefixLen, TData* value = nullptr, bool* hasNext = nullptr) const {          return FindLongestPrefix(key.data(), key.size(), prefixLen, value, hasNext);      } -  +      // Return trie, containing all tails for the given key      inline TCompactTrie<T, D, S> FindTails(const TSymbol* key, size_t keylen) const;      TCompactTrie<T, D, S> FindTails(const TKeyBuf& key) const { @@ -146,17 +146,17 @@ public:          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, 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 {  -            return !Impl;  -        } // Almost no other method can be called.  +        bool IsEmpty() const { +            return !Impl; +        } // Almost no other method can be called. -        bool operator==(const TConstIterator& other) const;  -        bool operator!=(const TConstIterator& other) const;  +        bool operator==(const TConstIterator& other) const; +        bool operator!=(const TConstIterator& other) const;          TConstIterator& operator++();          TConstIterator operator++(int /*unused*/);          TConstIterator& operator--(); @@ -205,8 +205,8 @@ protected:      void LookupPhrases(const char* datapos, size_t len, const TSymbol* key, size_t keylen, TVector<TPhraseMatch>& matches, TSymbol separator) const;  }; -template <class T = char, class D = ui64, class S = TCompactTriePacker<D>>  -class TCompactTrieHolder: public TCompactTrie<T, D, S>, NNonCopyable::TNonCopyable {  +template <class T = char, class D = ui64, class S = TCompactTriePacker<D>> +class TCompactTrieHolder: public TCompactTrie<T, D, S>, NNonCopyable::TNonCopyable {  private:      typedef TCompactTrie<T, D, S> TBase;      TArrayHolder<char> Storage; @@ -239,35 +239,35 @@ TCompactTrie<T, D, S>::TCompactTrie(const char* d, size_t len, TPacker packer)  template <class T, class D, class S>  TCompactTrie<T, D, S>::TCompactTrie(const char* 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)      , Packer(packer) -{  -}  +{ +}  template <class T, class D, class S>  TCompactTrie<T, D, S>::TCompactTrie(const TCompactTrie& other) -    : DataHolder(other.DataHolder)  -    , EmptyValue(other.EmptyValue)  -    , Packer(other.Packer)  -{  -}  +    : DataHolder(other.DataHolder) +    , EmptyValue(other.EmptyValue) +    , Packer(other.Packer) +{ +}  template <class T, class D, class S>  TCompactTrie<T, D, S>::TCompactTrie(TCompactTrie&& other) noexcept -    : DataHolder(std::move(other.DataHolder))  -    , EmptyValue(std::move(other.EmptyValue))  -    , Packer(std::move(other.Packer))  -{  -}  +    : DataHolder(std::move(other.DataHolder)) +    , EmptyValue(std::move(other.EmptyValue)) +    , Packer(std::move(other.Packer)) +{ +}  template <class T, class D, class S> -TCompactTrie<T, D, S>& TCompactTrie<T, D, S>::operator=(const TCompactTrie& other) {  +TCompactTrie<T, D, S>& TCompactTrie<T, D, S>::operator=(const TCompactTrie& other) {      if (this != &other) {          DataHolder = other.DataHolder;          EmptyValue = other.EmptyValue; @@ -529,7 +529,7 @@ bool TCompactTrie<T, D, S>::LookupLongestPrefix(const TSymbol* key, size_t keyle  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, -    TVector<TPhraseMatch>& matches, TSymbol separator) const {  +    TVector<TPhraseMatch>& matches, TSymbol separator) const {      using namespace NCompactTrie;      matches.clear(); @@ -572,10 +572,10 @@ TCompactTrieHolder<T, D, S>::TCompactTrieHolder(IInputStream& is, size_t len)  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))  -{  -}  +    : 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) @@ -586,7 +586,7 @@ TCompactTrie<T, D, S>::TConstIterator::TConstIterator(const TOpaqueTrie& trie, c  }  template <class T, class D, class S> -bool TCompactTrie<T, D, S>::TConstIterator::operator==(const TConstIterator& other) const {  +bool TCompactTrie<T, D, S>::TConstIterator::operator==(const TConstIterator& other) const {      if (!Impl)          return !other.Impl;      if (!other.Impl) @@ -595,8 +595,8 @@ bool TCompactTrie<T, D, S>::TConstIterator::operator==(const TConstIterator& oth  }  template <class T, class D, class S> -bool TCompactTrie<T, D, S>::TConstIterator::operator!=(const TConstIterator& other) const {  -    return !operator==(other);  +bool TCompactTrie<T, D, S>::TConstIterator::operator!=(const TConstIterator& other) const { +    return !operator==(other);  }  template <class T, class D, class S> diff --git a/library/cpp/containers/comptrie/comptrie_ut.cpp b/library/cpp/containers/comptrie/comptrie_ut.cpp index b4f84b3e4b8..74bee09b5d6 100644 --- a/library/cpp/containers/comptrie/comptrie_ut.cpp +++ b/library/cpp/containers/comptrie/comptrie_ut.cpp @@ -1,12 +1,12 @@ -#include <util/random/shuffle.h>  +#include <util/random/shuffle.h>  #include <library/cpp/testing/unittest/registar.h> -  +  #include <util/stream/output.h>  #include <utility> -  -#include <util/charset/wide.h>  + +#include <util/charset/wide.h>  #include <util/generic/algorithm.h> -#include <util/generic/buffer.h>  +#include <util/generic/buffer.h>  #include <util/generic/map.h>  #include <util/generic/vector.h>  #include <util/generic/ptr.h> @@ -14,100 +14,100 @@  #include <util/folder/dirut.h> -#include <util/random/random.h>  +#include <util/random/random.h>  #include <util/random/fast.h> -  +  #include <util/string/hex.h>  #include <util/string/cast.h> -#include "comptrie.h"  +#include "comptrie.h"  #include "set.h"  #include "first_symbol_iterator.h"  #include "search_iterator.h"  #include "pattern_searcher.h" -  +  #include <array>  #include <iterator> -class TCompactTrieTest: public TTestBase {  +class TCompactTrieTest: public TTestBase {  private:      UNIT_TEST_SUITE(TCompactTrieTest); -    UNIT_TEST(TestTrie8);  -    UNIT_TEST(TestTrie16);  -    UNIT_TEST(TestTrie32);  - -    UNIT_TEST(TestFastTrie8);  -    UNIT_TEST(TestFastTrie16);  -    UNIT_TEST(TestFastTrie32);  - -    UNIT_TEST(TestMinimizedTrie8);  -    UNIT_TEST(TestMinimizedTrie16);  -    UNIT_TEST(TestMinimizedTrie32);  - -    UNIT_TEST(TestFastMinimizedTrie8);  -    UNIT_TEST(TestFastMinimizedTrie16);  -    UNIT_TEST(TestFastMinimizedTrie32);  - -    UNIT_TEST(TestTrieIterator8);  -    UNIT_TEST(TestTrieIterator16);  -    UNIT_TEST(TestTrieIterator32);  - -    UNIT_TEST(TestMinimizedTrieIterator8);  -    UNIT_TEST(TestMinimizedTrieIterator16);  -    UNIT_TEST(TestMinimizedTrieIterator32);  - -    UNIT_TEST(TestPhraseSearch);  -    UNIT_TEST(TestAddGet);  -    UNIT_TEST(TestEmpty);  -    UNIT_TEST(TestUninitializedNonEmpty);  -    UNIT_TEST(TestRandom);  -    UNIT_TEST(TestFindTails);  -    UNIT_TEST(TestPrefixGrouped);  -    UNIT_TEST(CrashTestPrefixGrouped);  +    UNIT_TEST(TestTrie8); +    UNIT_TEST(TestTrie16); +    UNIT_TEST(TestTrie32); + +    UNIT_TEST(TestFastTrie8); +    UNIT_TEST(TestFastTrie16); +    UNIT_TEST(TestFastTrie32); + +    UNIT_TEST(TestMinimizedTrie8); +    UNIT_TEST(TestMinimizedTrie16); +    UNIT_TEST(TestMinimizedTrie32); + +    UNIT_TEST(TestFastMinimizedTrie8); +    UNIT_TEST(TestFastMinimizedTrie16); +    UNIT_TEST(TestFastMinimizedTrie32); + +    UNIT_TEST(TestTrieIterator8); +    UNIT_TEST(TestTrieIterator16); +    UNIT_TEST(TestTrieIterator32); + +    UNIT_TEST(TestMinimizedTrieIterator8); +    UNIT_TEST(TestMinimizedTrieIterator16); +    UNIT_TEST(TestMinimizedTrieIterator32); + +    UNIT_TEST(TestPhraseSearch); +    UNIT_TEST(TestAddGet); +    UNIT_TEST(TestEmpty); +    UNIT_TEST(TestUninitializedNonEmpty); +    UNIT_TEST(TestRandom); +    UNIT_TEST(TestFindTails); +    UNIT_TEST(TestPrefixGrouped); +    UNIT_TEST(CrashTestPrefixGrouped);      UNIT_TEST(TestMergeFromFile);      UNIT_TEST(TestMergeFromBuffer); -    UNIT_TEST(TestUnique);  -    UNIT_TEST(TestAddRetValue);  -    UNIT_TEST(TestClear);  +    UNIT_TEST(TestUnique); +    UNIT_TEST(TestAddRetValue); +    UNIT_TEST(TestClear); -    UNIT_TEST(TestIterateEmptyKey);  +    UNIT_TEST(TestIterateEmptyKey); -    UNIT_TEST(TestTrieSet);  +    UNIT_TEST(TestTrieSet); -    UNIT_TEST(TestTrieForVectorInt64);  -    UNIT_TEST(TestTrieForListInt64);  -    UNIT_TEST(TestTrieForSetInt64);  +    UNIT_TEST(TestTrieForVectorInt64); +    UNIT_TEST(TestTrieForListInt64); +    UNIT_TEST(TestTrieForSetInt64); -    UNIT_TEST(TestTrieForVectorStroka);  -    UNIT_TEST(TestTrieForListStroka);  -    UNIT_TEST(TestTrieForSetStroka);  +    UNIT_TEST(TestTrieForVectorStroka); +    UNIT_TEST(TestTrieForListStroka); +    UNIT_TEST(TestTrieForSetStroka); -    UNIT_TEST(TestTrieForVectorWtroka);  -    UNIT_TEST(TestTrieForVectorFloat);  -    UNIT_TEST(TestTrieForVectorDouble);  +    UNIT_TEST(TestTrieForVectorWtroka); +    UNIT_TEST(TestTrieForVectorFloat); +    UNIT_TEST(TestTrieForVectorDouble); -    UNIT_TEST(TestTrieForListVectorInt64);  -    UNIT_TEST(TestTrieForPairWtrokaVectorInt64);  +    UNIT_TEST(TestTrieForListVectorInt64); +    UNIT_TEST(TestTrieForPairWtrokaVectorInt64); -    UNIT_TEST(TestEmptyValueOutOfOrder);  -    UNIT_TEST(TestFindLongestPrefixWithEmptyValue);  +    UNIT_TEST(TestEmptyValueOutOfOrder); +    UNIT_TEST(TestFindLongestPrefixWithEmptyValue); -    UNIT_TEST(TestSearchIterChar);  -    UNIT_TEST(TestSearchIterWchar);  +    UNIT_TEST(TestSearchIterChar); +    UNIT_TEST(TestSearchIterWchar);      UNIT_TEST(TestSearchIterWchar32) -    UNIT_TEST(TestCopyAndAssignment);  +    UNIT_TEST(TestCopyAndAssignment); -    UNIT_TEST(TestFirstSymbolIterator8);  -    UNIT_TEST(TestFirstSymbolIterator16);  -    UNIT_TEST(TestFirstSymbolIterator32);  +    UNIT_TEST(TestFirstSymbolIterator8); +    UNIT_TEST(TestFirstSymbolIterator16); +    UNIT_TEST(TestFirstSymbolIterator32);      UNIT_TEST(TestFirstSymbolIteratorChar32); -    UNIT_TEST(TestArrayPacker);  +    UNIT_TEST(TestArrayPacker); -    UNIT_TEST(TestBuilderFindLongestPrefix);  -    UNIT_TEST(TestBuilderFindLongestPrefixWithEmptyValue);  +    UNIT_TEST(TestBuilderFindLongestPrefix); +    UNIT_TEST(TestBuilderFindLongestPrefixWithEmptyValue);      UNIT_TEST(TestPatternSearcherEmpty);      UNIT_TEST(TestPatternSearcherSimple); @@ -147,7 +147,7 @@ private:      TVector<TContainer> GetSampleVectorData(size_t nValues);      template <class TContainer>      TVector<TContainer> GetSampleTextVectorData(size_t nValues); -    template <class T>  +    template <class T>      void CheckEquality(const T& value1, const T& value2) const;      template <class TContainer>      void TestTrieWithContainers(const TVector<TUtf16String>& keys, const TVector<TContainer>& sampleData, TString methodName); @@ -265,38 +265,38 @@ public:  UNIT_TEST_SUITE_REGISTRATION(TCompactTrieTest); -const char* TCompactTrieTest::SampleData[] = {  -    "",  -    "a", "b", "c", "d",  -    "aa", "ab", "ac", "ad",  -    "aaa", "aab", "aac", "aad",  -    "aba", "abb", "abc", "abd",  -    "fba", "fbb", "fbc", "fbd",  -    "fbbaa",  -    "c\x85\xA4\xBF" // Just something outside ASCII.  +const char* TCompactTrieTest::SampleData[] = { +    "", +    "a", "b", "c", "d", +    "aa", "ab", "ac", "ad", +    "aaa", "aab", "aac", "aad", +    "aba", "abb", "abc", "abd", +    "fba", "fbb", "fbc", "fbd", +    "fbbaa", +    "c\x85\xA4\xBF" // Just something outside ASCII.  }; -template <class T>  +template <class T>  typename TCompactTrie<T>::TKey MakeWideKey(const char* str, size_t len) {      typename TCompactTrie<T>::TKey buffer;      for (size_t i = 0; i < len; i++) {          unsigned int ch = (str[i] & 0xFF); -        buffer.push_back((T)(ch | ch << 8 | ch << 16 | ch << 24));  +        buffer.push_back((T)(ch | ch << 8 | ch << 16 | ch << 24));      }      return buffer;  } -template <class T>  +template <class T>  typename TCompactTrie<T>::TKey MakeWideKey(const TString& str) {      return MakeWideKey<T>(str.c_str(), str.length());  } -template <class T>  +template <class T>  typename TCompactTrie<T>::TKey MakeWideKey(const TStringBuf& buf) {      return MakeWideKey<T>(buf.data(), buf.length());  } -template <class T>  +template <class T>  void TCompactTrieTest::CreateTrie(IOutputStream& out, bool minimize, bool useFastLayout) {      TCompactTrieBuilder<T> builder; @@ -305,18 +305,18 @@ void TCompactTrieTest::CreateTrie(IOutputStream& out, bool minimize, bool useFas          builder.Add(MakeWideKey<T>(i, len), len * 2);      } -  +      TBufferOutput tmp2;      IOutputStream& currentOutput = useFastLayout ? tmp2 : out;      if (minimize) {          TBufferOutput buftmp;          builder.Save(buftmp); -        CompactTrieMinimize<TCompactTriePacker<ui64>>(currentOutput, buftmp.Buffer().Data(), buftmp.Buffer().Size(), false);  +        CompactTrieMinimize<TCompactTriePacker<ui64>>(currentOutput, buftmp.Buffer().Data(), buftmp.Buffer().Size(), false);      } else {          builder.Save(currentOutput);      }      if (useFastLayout) { -        CompactTrieMakeFastLayout<TCompactTriePacker<T>>(out, tmp2.Buffer().Data(), tmp2.Buffer().Size(), false);  +        CompactTrieMakeFastLayout<TCompactTriePacker<T>>(out, tmp2.Buffer().Data(), tmp2.Buffer().Size(), false);      }  } @@ -337,7 +337,7 @@ static bool LexicographicStep(TString& s) {      return true;  } -template <class T>  +template <class T>  void TCompactTrieTest::CheckUpperBound(const char* data, size_t datalen) {      TCompactTrie<T> trie(data, datalen);      typedef typename TCompactTrie<T>::TKey TKey; @@ -357,7 +357,7 @@ void TCompactTrieTest::CheckUpperBound(const char* data, size_t datalen) {      } while (LexicographicStep(key));  } -template <class T>  +template <class T>  void TCompactTrieTest::CheckData(const char* data, size_t datalen) {      TCompactTrie<T> trie(data, datalen); @@ -413,13 +413,13 @@ void TCompactTrieTest::CheckData(const char* data, size_t datalen) {      UNIT_ASSERT(trie.FindLongestPrefix(key, &prefixLen, &value));      UNIT_ASSERT_EQUAL(prefixLen, 3);      UNIT_ASSERT_EQUAL(6, value); -  +      value = 12345678;      UNIT_ASSERT(!trie.Find(key, &value)); -    UNIT_ASSERT_EQUAL(12345678, value); //Failed Find() should not change value  +    UNIT_ASSERT_EQUAL(12345678, value); //Failed Find() should not change value  } -template <class T>  +template <class T>  void TCompactTrieTest::CheckIterator(const char* data, size_t datalen) {      typedef typename TCompactTrie<T>::TKey TKey;      typedef typename TCompactTrie<T>::TValueType TValue; @@ -441,10 +441,10 @@ void TCompactTrieTest::CheckIterator(const char* data, size_t datalen) {          received.insert(*it);          items.push_back(*it);          entry_count++; -        it++;  +        it++;      }      TMap<TKey, ui64> received2; -    for (std::pair<TKey, ui64> x : trie) {  +    for (std::pair<TKey, ui64> x : trie) {          received2.insert(x);      }      UNIT_ASSERT(entry_count == stored.size()); @@ -485,7 +485,7 @@ void TCompactTrieTest::CheckIterator(const char* data, size_t datalen) {      UNIT_ASSERT(revIt != trie.End());  } -template <class T>  +template <class T>  void TCompactTrieTest::TestTrie(bool minimize, bool useFastLayout) {      TBufferOutput bufout;      CreateTrie<T>(bufout, minimize, useFastLayout); @@ -493,75 +493,75 @@ void TCompactTrieTest::TestTrie(bool minimize, bool useFastLayout) {      CheckUpperBound<T>(bufout.Buffer().Data(), bufout.Buffer().Size());  } -template <class T>  +template <class T>  void TCompactTrieTest::TestTrieIterator(bool minimize) {      TBufferOutput bufout;      CreateTrie<T>(bufout, minimize, false);      CheckIterator<T>(bufout.Buffer().Data(), bufout.Buffer().Size());  } -void TCompactTrieTest::TestTrie8() {  -    TestTrie<char>(false, false);  -}  -void TCompactTrieTest::TestTrie16() {  -    TestTrie<wchar16>(false, false);  -}  -void TCompactTrieTest::TestTrie32() {  -    TestTrie<wchar32>(false, false);  -}  - -void TCompactTrieTest::TestFastTrie8() {  -    TestTrie<char>(false, true);  -}  -void TCompactTrieTest::TestFastTrie16() {  -    TestTrie<wchar16>(false, true);  -}  -void TCompactTrieTest::TestFastTrie32() {  -    TestTrie<wchar32>(false, true);  -}  - -void TCompactTrieTest::TestMinimizedTrie8() {  -    TestTrie<char>(true, false);  -}  -void TCompactTrieTest::TestMinimizedTrie16() {  -    TestTrie<wchar16>(true, false);  -}  -void TCompactTrieTest::TestMinimizedTrie32() {  -    TestTrie<wchar32>(true, false);  -}  - -void TCompactTrieTest::TestFastMinimizedTrie8() {  -    TestTrie<char>(true, true);  -}  -void TCompactTrieTest::TestFastMinimizedTrie16() {  -    TestTrie<wchar16>(true, true);  -}  -void TCompactTrieTest::TestFastMinimizedTrie32() {  -    TestTrie<wchar32>(true, true);  -}  - -void TCompactTrieTest::TestTrieIterator8() {  -    TestTrieIterator<char>(false);  -}  -void TCompactTrieTest::TestTrieIterator16() {  -    TestTrieIterator<wchar16>(false);  -}  -void TCompactTrieTest::TestTrieIterator32() {  -    TestTrieIterator<wchar32>(false);  -}  - -void TCompactTrieTest::TestMinimizedTrieIterator8() {  -    TestTrieIterator<char>(true);  -}  -void TCompactTrieTest::TestMinimizedTrieIterator16() {  -    TestTrieIterator<wchar16>(true);  -}  -void TCompactTrieTest::TestMinimizedTrieIterator32() {  -    TestTrieIterator<wchar32>(true);  -}  +void TCompactTrieTest::TestTrie8() { +    TestTrie<char>(false, false); +} +void TCompactTrieTest::TestTrie16() { +    TestTrie<wchar16>(false, false); +} +void TCompactTrieTest::TestTrie32() { +    TestTrie<wchar32>(false, false); +} + +void TCompactTrieTest::TestFastTrie8() { +    TestTrie<char>(false, true); +} +void TCompactTrieTest::TestFastTrie16() { +    TestTrie<wchar16>(false, true); +} +void TCompactTrieTest::TestFastTrie32() { +    TestTrie<wchar32>(false, true); +} + +void TCompactTrieTest::TestMinimizedTrie8() { +    TestTrie<char>(true, false); +} +void TCompactTrieTest::TestMinimizedTrie16() { +    TestTrie<wchar16>(true, false); +} +void TCompactTrieTest::TestMinimizedTrie32() { +    TestTrie<wchar32>(true, false); +} + +void TCompactTrieTest::TestFastMinimizedTrie8() { +    TestTrie<char>(true, true); +} +void TCompactTrieTest::TestFastMinimizedTrie16() { +    TestTrie<wchar16>(true, true); +} +void TCompactTrieTest::TestFastMinimizedTrie32() { +    TestTrie<wchar32>(true, true); +} + +void TCompactTrieTest::TestTrieIterator8() { +    TestTrieIterator<char>(false); +} +void TCompactTrieTest::TestTrieIterator16() { +    TestTrieIterator<wchar16>(false); +} +void TCompactTrieTest::TestTrieIterator32() { +    TestTrieIterator<wchar32>(false); +} + +void TCompactTrieTest::TestMinimizedTrieIterator8() { +    TestTrieIterator<char>(true); +} +void TCompactTrieTest::TestMinimizedTrieIterator16() { +    TestTrieIterator<wchar16>(true); +} +void TCompactTrieTest::TestMinimizedTrieIterator32() { +    TestTrieIterator<wchar32>(true); +}  void TCompactTrieTest::TestPhraseSearch() { -    static const char* phrases[] = {"ab", "ab cd", "ab cd ef"};  +    static const char* phrases[] = {"ab", "ab cd", "ab cd ef"};      static const char* const goodphrase = "ab cd ef gh";      static const char* const badphrase = "cd ef gh ab";      TBufferOutput bufout; @@ -651,7 +651,7 @@ static char RandChar() {  }  static TString RandStr(const size_t max) { -    size_t len = RandomNumber<size_t>() % max;  +    size_t len = RandomNumber<size_t>() % max;      TString key;      for (size_t j = 0; j < len; ++j)          key += RandChar(); @@ -664,7 +664,7 @@ void TCompactTrieTest::TestRandom(const size_t n, const size_t maxKeySize) {      TCompactTrieBuilder<char, typename T::TData, T> builder;      typedef TMap<TString, typename T::TData> TKeys;      TKeys keys; -  +      typename T::TData dummy;      for (size_t i = 0; i < n; ++i) {          const TString key = RandStr(maxKeySize); @@ -677,7 +677,7 @@ void TCompactTrieTest::TestRandom(const size_t n, const size_t maxKeySize) {              UNIT_ASSERT(dummy == val);          }      } -  +      TBufferStream stream;      size_t len = builder.Save(stream);      TCompactTrie<char, typename T::TData, T> trie(stream.Buffer().Data(), len); @@ -721,12 +721,12 @@ void TCompactTrieTest::TestRandom(const size_t n, const size_t maxKeySize) {  }  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);  +    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) { @@ -779,14 +779,14 @@ void TCompactTrieTest::TestPrefixGrouped() {      TBuffer b1b;      TCompactTrieBuilder<char, ui32> b1(CTBF_PREFIX_GROUPED);      const char* data[] = { -        "Kazan",  -        "Moscow",  -        "Monino",  -        "Murmansk",  -        "Fryanovo",  -        "Fryazino",  -        "Fryazevo",  -        "Tumen",  +        "Kazan", +        "Moscow", +        "Monino", +        "Murmansk", +        "Fryanovo", +        "Fryazino", +        "Fryazevo", +        "Tumen",      };      for (size_t i = 0; i < Y_ARRAY_SIZE(data); ++i) { @@ -937,15 +937,15 @@ void TCompactTrieTest::TestUnique() {  void TCompactTrieTest::TestUniqueImpl(bool isPrefixGrouped) {      TCompactTrieBuilder<char, ui32> builder(CTBF_UNIQUE | (isPrefixGrouped ? CTBF_PREFIX_GROUPED : CTBF_NONE));      const char* data[] = { -        "Kazan",  -        "Moscow",  -        "Monino",  -        "Murmansk",  -        "Fryanovo",  -        "Fryazino",  -        "Fryazevo",  -        "Fry",  -        "Tumen",  +        "Kazan", +        "Moscow", +        "Monino", +        "Murmansk", +        "Fryanovo", +        "Fryazino", +        "Fryazevo", +        "Fry", +        "Tumen",      };      for (size_t i = 0; i < Y_ARRAY_SIZE(data); ++i) {          UNIT_ASSERT_C(builder.Add(data[i], strlen(data[i]), i + 1), i); @@ -963,15 +963,15 @@ void TCompactTrieTest::TestUniqueImpl(bool isPrefixGrouped) {  void TCompactTrieTest::TestAddRetValue() {      TCompactTrieBuilder<char, ui32> builder;      const char* data[] = { -        "Kazan",  -        "Moscow",  -        "Monino",  -        "Murmansk",  -        "Fryanovo",  -        "Fryazino",  -        "Fryazevo",  -        "Fry",  -        "Tumen",  +        "Kazan", +        "Moscow", +        "Monino", +        "Murmansk", +        "Fryanovo", +        "Fryazino", +        "Fryazevo", +        "Fry", +        "Tumen",      };      for (size_t i = 0; i < Y_ARRAY_SIZE(data); ++i) {          UNIT_ASSERT(builder.Add(data[i], strlen(data[i]), i + 1)); @@ -982,7 +982,7 @@ void TCompactTrieTest::TestAddRetValue() {      }  } -void TCompactTrieTest::TestClear() {  +void TCompactTrieTest::TestClear() {      TCompactTrieBuilder<char, ui32> builder;      const char* data[] = {          "Kazan", @@ -1008,14 +1008,14 @@ void TCompactTrieTest::TestFindTails() {      TestFindTailsImpl("aa");      TestFindTailsImpl("bb");      TestFindTailsImpl("fb"); -    TestFindTailsImpl("fbc");  -    TestFindTailsImpl("fbbaa");  +    TestFindTailsImpl("fbc"); +    TestFindTailsImpl("fbbaa");  }  template <class T> -class TCompactTrieTest::TDummyPacker: public TNullPacker<T> {  +class TCompactTrieTest::TDummyPacker: public TNullPacker<T> {  public: -    static T Data(const TString&) {  +    static T Data(const TString&) {          T data;          TNullPacker<T>().UnpackLeaf(nullptr, data);          return data; @@ -1024,21 +1024,21 @@ public:      typedef T TData;  }; -class TCompactTrieTest::TStrokaPacker: public TCompactTriePacker<TString> {  +class TCompactTrieTest::TStrokaPacker: public TCompactTriePacker<TString> {  public:      typedef TString TData; -    static TString Data(const TString& str) {  +    static TString Data(const TString& str) {          return str;      }  };  template <class T> -class TCompactTrieTest::TIntPacker: public TCompactTriePacker<T> {  +class TCompactTrieTest::TIntPacker: public TCompactTriePacker<T> {  public:      typedef T TData; -    static TData Data(const TString&) {  +    static TData Data(const TString&) {          return RandomNumber<std::make_unsigned_t<T>>();      }  }; @@ -1099,7 +1099,7 @@ void TCompactTrieTest::TestTrieSet() {      UNIT_ASSERT(!empty.Has("d"));      UNIT_ASSERT(!empty.Has("d")); -    UNIT_ASSERT(empty.Has("")); // contains only empty string  +    UNIT_ASSERT(empty.Has("")); // contains only empty string  }  // Tests for trie with vector (list, set) values @@ -1119,7 +1119,7 @@ TVector<TContainer> TCompactTrieTest::GetSampleVectorData(size_t nValues) {      for (size_t i = 0; i < nValues; i++) {          data.push_back(TContainer());          for (size_t j = 0; j < i; j++) -            data[i].insert(data[i].end(), (typename TContainer::value_type)((j == 3) ? 0 : (1 << (j * 5))));  +            data[i].insert(data[i].end(), (typename TContainer::value_type)((j == 3) ? 0 : (1 << (j * 5))));      }      return data;  } @@ -1135,16 +1135,16 @@ TVector<TContainer> TCompactTrieTest::GetSampleTextVectorData(size_t nValues) {      return data;  } -template <class T>  +template <class T>  void TCompactTrieTest::CheckEquality(const T& value1, const T& value2) const {      UNIT_ASSERT_VALUES_EQUAL(value1, value2);  } -template <>  -void TCompactTrieTest::CheckEquality<TVector<i64>>(const TVector<i64>& value1, const TVector<i64>& value2) const {  -    UNIT_ASSERT_VALUES_EQUAL(value1.size(), value2.size());  -    for (size_t i = 0; i < value1.size(); i++)  -        UNIT_ASSERT_VALUES_EQUAL(value1[i], value2[i]);  +template <> +void TCompactTrieTest::CheckEquality<TVector<i64>>(const TVector<i64>& value1, const TVector<i64>& value2) const { +    UNIT_ASSERT_VALUES_EQUAL(value1.size(), value2.size()); +    for (size_t i = 0; i < value1.size(); i++) +        UNIT_ASSERT_VALUES_EQUAL(value1[i], value2[i]);  }  template <class TContainer> @@ -1171,9 +1171,9 @@ void TCompactTrieTest::TestTrieWithContainers(const TVector<TUtf16String>& keys,      unlink(fileName.data());  } -template <>  -void TCompactTrieTest::TestTrieWithContainers<std::pair<TUtf16String, TVector<i64>>>(const TVector<TUtf16String>& keys, const TVector<std::pair<TUtf16String, TVector<i64>>>& sampleData, TString methodName) {  -    typedef std::pair<TUtf16String, TVector<i64>> TContainer;  +template <> +void TCompactTrieTest::TestTrieWithContainers<std::pair<TUtf16String, TVector<i64>>>(const TVector<TUtf16String>& keys, const TVector<std::pair<TUtf16String, TVector<i64>>>& sampleData, TString methodName) { +    typedef std::pair<TUtf16String, TVector<i64>> TContainer;      TString fileName = GetSystemTempDir() + "/TCompactTrieTest-TestTrieWithContainers-" + methodName;      TCompactTrieBuilder<wchar16, TContainer> b; @@ -1194,63 +1194,63 @@ void TCompactTrieTest::TestTrieWithContainers<std::pair<TUtf16String, TVector<i6  }  void TCompactTrieTest::TestTrieForVectorInt64() { -    TestTrieWithContainers<TVector<i64>>(GetSampleKeys(10), GetSampleVectorData<TVector<i64>>(10), "v-i64");  +    TestTrieWithContainers<TVector<i64>>(GetSampleKeys(10), GetSampleVectorData<TVector<i64>>(10), "v-i64");  }  void TCompactTrieTest::TestTrieForListInt64() { -    TestTrieWithContainers<TList<i64>>(GetSampleKeys(10), GetSampleVectorData<TList<i64>>(10), "l-i64");  +    TestTrieWithContainers<TList<i64>>(GetSampleKeys(10), GetSampleVectorData<TList<i64>>(10), "l-i64");  }  void TCompactTrieTest::TestTrieForSetInt64() { -    TestTrieWithContainers<TSet<i64>>(GetSampleKeys(10), GetSampleVectorData<TSet<i64>>(10), "s-i64");  +    TestTrieWithContainers<TSet<i64>>(GetSampleKeys(10), GetSampleVectorData<TSet<i64>>(10), "s-i64");  }  void TCompactTrieTest::TestTrieForVectorStroka() { -    TestTrieWithContainers<TVector<TString>>(GetSampleKeys(10), GetSampleTextVectorData<TVector<TString>>(10), "v-str");  +    TestTrieWithContainers<TVector<TString>>(GetSampleKeys(10), GetSampleTextVectorData<TVector<TString>>(10), "v-str");  }  void TCompactTrieTest::TestTrieForListStroka() { -    TestTrieWithContainers<TList<TString>>(GetSampleKeys(10), GetSampleTextVectorData<TList<TString>>(10), "l-str");  +    TestTrieWithContainers<TList<TString>>(GetSampleKeys(10), GetSampleTextVectorData<TList<TString>>(10), "l-str");  }  void TCompactTrieTest::TestTrieForSetStroka() { -    TestTrieWithContainers<TSet<TString>>(GetSampleKeys(10), GetSampleTextVectorData<TSet<TString>>(10), "s-str");  +    TestTrieWithContainers<TSet<TString>>(GetSampleKeys(10), GetSampleTextVectorData<TSet<TString>>(10), "s-str");  }  void TCompactTrieTest::TestTrieForVectorWtroka() { -    TVector<TVector<TString>> data = GetSampleTextVectorData<TVector<TString>>(10);  -    TVector<TVector<TUtf16String>> wData;  +    TVector<TVector<TString>> data = GetSampleTextVectorData<TVector<TString>>(10); +    TVector<TVector<TUtf16String>> wData;      for (size_t i = 0; i < data.size(); i++) {          wData.push_back(TVector<TUtf16String>());          for (size_t j = 0; j < data[i].size(); j++) -            wData[i].push_back(UTF8ToWide(data[i][j]));  +            wData[i].push_back(UTF8ToWide(data[i][j]));      } -    TestTrieWithContainers<TVector<TUtf16String>>(GetSampleKeys(10), wData, "v-wtr");  +    TestTrieWithContainers<TVector<TUtf16String>>(GetSampleKeys(10), wData, "v-wtr");  }  void TCompactTrieTest::TestTrieForVectorFloat() { -    TestTrieWithContainers<TVector<float>>(GetSampleKeys(10), GetSampleVectorData<TVector<float>>(10), "v-float");  +    TestTrieWithContainers<TVector<float>>(GetSampleKeys(10), GetSampleVectorData<TVector<float>>(10), "v-float");  }  void TCompactTrieTest::TestTrieForVectorDouble() { -    TestTrieWithContainers<TVector<double>>(GetSampleKeys(10), GetSampleVectorData<TVector<double>>(10), "v-double");  +    TestTrieWithContainers<TVector<double>>(GetSampleKeys(10), GetSampleVectorData<TVector<double>>(10), "v-double");  }  void TCompactTrieTest::TestTrieForListVectorInt64() {      TVector<i64> tmp; -    tmp.push_back(0);  -    TList<TVector<i64>> dataElement(5, tmp);  -    TVector<TList<TVector<i64>>> data(10, dataElement);  -    TestTrieWithContainers<TList<TVector<i64>>>(GetSampleKeys(10), data, "l-v-i64");  +    tmp.push_back(0); +    TList<TVector<i64>> dataElement(5, tmp); +    TVector<TList<TVector<i64>>> data(10, dataElement); +    TestTrieWithContainers<TList<TVector<i64>>>(GetSampleKeys(10), data, "l-v-i64");  }  void TCompactTrieTest::TestTrieForPairWtrokaVectorInt64() {      TVector<TUtf16String> keys = GetSampleKeys(10); -    TVector<TVector<i64>> values = GetSampleVectorData<TVector<i64>>(10);  -    TVector<std::pair<TUtf16String, TVector<i64>>> data;  +    TVector<TVector<i64>> values = GetSampleVectorData<TVector<i64>>(10); +    TVector<std::pair<TUtf16String, TVector<i64>>> data;      for (size_t i = 0; i < 10; i++)          data.push_back(std::pair<TUtf16String, TVector<i64>>(keys[i] + u"_v", values[i])); -    TestTrieWithContainers<std::pair<TUtf16String, TVector<i64>>>(keys, data, "pair-str-v-i64");  +    TestTrieWithContainers<std::pair<TUtf16String, TVector<i64>>>(keys, data, "pair-str-v-i64");  }  void TCompactTrieTest::TestEmptyValueOutOfOrder() { @@ -1468,7 +1468,7 @@ void TCompactTrieTest::TestArrayPacker() {  void TCompactTrieTest::TestBuilderFindLongestPrefix() {      const size_t sizes[] = {10, 100}; -    const double branchProbabilities[] = {0.01, 0.1, 0.5, 0.9, 0.99};  +    const double branchProbabilities[] = {0.01, 0.1, 0.5, 0.9, 0.99};      for (size_t size : sizes) {          for (double branchProbability : branchProbabilities) {              TestBuilderFindLongestPrefix(size, branchProbability, false, false); @@ -1498,7 +1498,7 @@ void TCompactTrieTest::TestBuilderFindLongestPrefix(size_t keysCount, double bra      if (isPrefixGrouped)          Sort(keys.begin(), keys.end());      else -        Shuffle(keys.begin(), keys.end());  +        Shuffle(keys.begin(), keys.end());      TCompactTrieBuilder<char, TString> builder(isPrefixGrouped ? CTBF_PREFIX_GROUPED : CTBF_NONE);      const TString EMPTY_VALUE = "empty"; diff --git a/library/cpp/containers/comptrie/first_symbol_iterator.h b/library/cpp/containers/comptrie/first_symbol_iterator.h index d3c521e7e64..d06135f06f2 100644 --- a/library/cpp/containers/comptrie/first_symbol_iterator.h +++ b/library/cpp/containers/comptrie/first_symbol_iterator.h @@ -6,7 +6,7 @@  namespace NCompactTrie {      // Iterates over possible first symbols in a trie.      // Allows one to get the symbol and the subtrie starting from it. -    template <class TTrie>  +    template <class TTrie>      class TFirstSymbolIterator {      public:          using TSymbol = typename TTrie::TSymbol; @@ -58,4 +58,4 @@ namespace NCompactTrie {          TCopyPtr<TOpaqueTrieIterator> Impl;      }; -}  +} diff --git a/library/cpp/containers/comptrie/key_selector.h b/library/cpp/containers/comptrie/key_selector.h index 80191df744b..60466cef715 100644 --- a/library/cpp/containers/comptrie/key_selector.h +++ b/library/cpp/containers/comptrie/key_selector.h @@ -4,24 +4,24 @@  #include <util/generic/string.h>  #include <util/generic/strbuf.h> -template <class T>  +template <class T>  struct TCompactTrieKeySelector {      typedef TVector<T> TKey;      typedef TVector<T> TKeyBuf;  }; -template <class TChar>  +template <class TChar>  struct TCompactTrieCharKeySelector {      typedef TBasicString<TChar> TKey;      typedef TBasicStringBuf<TChar> TKeyBuf;  }; -template <>  -struct TCompactTrieKeySelector<char>: public TCompactTrieCharKeySelector<char> {  +template <> +struct TCompactTrieKeySelector<char>: public TCompactTrieCharKeySelector<char> {  }; -template <>  -struct TCompactTrieKeySelector<wchar16>: public TCompactTrieCharKeySelector<wchar16> {  +template <> +struct TCompactTrieKeySelector<wchar16>: public TCompactTrieCharKeySelector<wchar16> {  };  template <> diff --git a/library/cpp/containers/comptrie/leaf_skipper.h b/library/cpp/containers/comptrie/leaf_skipper.h index 0bdfa11d63e..39592589487 100644 --- a/library/cpp/containers/comptrie/leaf_skipper.h +++ b/library/cpp/containers/comptrie/leaf_skipper.h @@ -9,11 +9,11 @@ namespace NCompactTrie {          virtual ~ILeafSkipper() = default;      }; -    template <class TPacker>  -    class TPackerLeafSkipper: public ILeafSkipper {  +    template <class TPacker> +    class TPackerLeafSkipper: public ILeafSkipper {      private:          const TPacker* Packer; -  +      public:          TPackerLeafSkipper(const TPacker* packer)              : Packer(packer) @@ -25,9 +25,9 @@ namespace NCompactTrie {          }          // For test purposes. -        const TPacker* GetPacker() const {  -            return Packer;  -        }  +        const TPacker* GetPacker() const { +            return Packer; +        }      };      // The data you need to traverse the trie without unpacking the values. @@ -40,13 +40,13 @@ namespace NCompactTrie {              : Data(data)              , Length(dataLength)              , SkipFunction(skipFunction) -        {  -        }  +        { +        }          bool operator==(const TOpaqueTrie& other) const {              return Data == other.Data && -                   Length == other.Length &&  -                   &SkipFunction == &other.SkipFunction;  +                   Length == other.Length && +                   &SkipFunction == &other.SkipFunction;          }          bool operator!=(const TOpaqueTrie& other) const { diff --git a/library/cpp/containers/comptrie/loader/loader.h b/library/cpp/containers/comptrie/loader/loader.h index d172efa5411..ee10e9b451e 100644 --- a/library/cpp/containers/comptrie/loader/loader.h +++ b/library/cpp/containers/comptrie/loader/loader.h @@ -9,7 +9,7 @@  template <class TrieType, size_t N>  TrieType LoadTrieFromArchive(const TString& key,                               const unsigned char (&data)[N], -                             bool ignoreErrors = false) {  +                             bool ignoreErrors = false) {      TArchiveReader archive(TBlob::NoCopy(data, sizeof(data)));      if (archive.Has(key)) {          TAutoPtr<IInputStream> trie = archive.ObjectByKey(key); diff --git a/library/cpp/containers/comptrie/loader/loader_ut.cpp b/library/cpp/containers/comptrie/loader/loader_ut.cpp index 2e771357fe0..345063a31e4 100644 --- a/library/cpp/containers/comptrie/loader/loader_ut.cpp +++ b/library/cpp/containers/comptrie/loader/loader_ut.cpp @@ -6,25 +6,25 @@ using TDummyTrie = TCompactTrie<char, i32>;  namespace {      const unsigned char DATA[] = { -#include "data.inc"  +#include "data.inc"      }; -}  +}  Y_UNIT_TEST_SUITE(ArchiveLoaderTests) {      Y_UNIT_TEST(BaseTest) { -        TDummyTrie trie = LoadTrieFromArchive<TDummyTrie>("/dummy.trie", DATA, true);  -        UNIT_ASSERT_EQUAL(trie.Size(), 3);  +        TDummyTrie trie = LoadTrieFromArchive<TDummyTrie>("/dummy.trie", DATA, true); +        UNIT_ASSERT_EQUAL(trie.Size(), 3); -        const TString TrieKyes[3] = {  -            "zero", "one", "two"};  -        i32 val = -1;  -        for (i32 i = 0; i < 3; ++i) {  +        const TString TrieKyes[3] = { +            "zero", "one", "two"}; +        i32 val = -1; +        for (i32 i = 0; i < 3; ++i) {              UNIT_ASSERT(trie.Find(TrieKyes[i].data(), TrieKyes[i].size(), &val)); -            UNIT_ASSERT_EQUAL(i, val);  -        }  +            UNIT_ASSERT_EQUAL(i, val); +        } -        UNIT_CHECK_GENERATED_EXCEPTION(  -            LoadTrieFromArchive<TDummyTrie>("/noname.trie", DATA),  -            yexception);  +        UNIT_CHECK_GENERATED_EXCEPTION( +            LoadTrieFromArchive<TDummyTrie>("/noname.trie", DATA), +            yexception);      }  } diff --git a/library/cpp/containers/comptrie/make_fast_layout.cpp b/library/cpp/containers/comptrie/make_fast_layout.cpp index 693384ee7f6..ade78d78994 100644 --- a/library/cpp/containers/comptrie/make_fast_layout.cpp +++ b/library/cpp/containers/comptrie/make_fast_layout.cpp @@ -24,444 +24,444 @@  // (there is not much difference between these papers, actually).  //  namespace NCompactTrie { -    static size_t FindSupportingPowerOf2(size_t n) {  -        size_t result = 1ull << (8 * sizeof(size_t) - 1);  -        while (result > n) {  -            result >>= 1;  -        }  -        return result;  +    static size_t FindSupportingPowerOf2(size_t n) { +        size_t result = 1ull << (8 * sizeof(size_t) - 1); +        while (result > n) { +            result >>= 1; +        } +        return result;      } -    namespace {  -        class TTrieNodeSet {  -        public:  +    namespace { +        class TTrieNodeSet { +        public:              TTrieNodeSet() = default; -            explicit TTrieNodeSet(const TOpaqueTrie& trie)  -                : Body(trie.Length / (8 * MinNodeSize) + 1, 0)  -            {  -            }  - -            bool Has(size_t offset) const {  -                const size_t reducedOffset = ReducedOffset(offset);  -                return OffsetCell(reducedOffset) & OffsetMask(reducedOffset);  -            }  - -            void Add(size_t offset) {  -                const size_t reducedOffset = ReducedOffset(offset);  -                OffsetCell(reducedOffset) |= OffsetMask(reducedOffset);  -            }  - -            void Remove(size_t offset) {  -                const size_t reducedOffset = ReducedOffset(offset);  -                OffsetCell(reducedOffset) &= ~OffsetMask(reducedOffset);  -            }  - -            void Swap(TTrieNodeSet& other) {  -                Body.swap(other.Body);  -            }  - -        private:  -            static const size_t MinNodeSize = 2;  -            TVector<ui8> Body;  - -            static size_t ReducedOffset(size_t offset) {  -                return offset / MinNodeSize;  -            }  -            static ui8 OffsetMask(size_t reducedOffset) {  -                return 1 << (reducedOffset % 8);  -            }  -            ui8& OffsetCell(size_t reducedOffset) {  -                return Body.at(reducedOffset / 8);  -            }  -            const ui8& OffsetCell(size_t reducedOffset) const {  -                return Body.at(reducedOffset / 8);  -            }  -        };  - -        //---------------------------------------------------------------------  - -        class TTrieNodeCounts {  -        public:  +            explicit TTrieNodeSet(const TOpaqueTrie& trie) +                : Body(trie.Length / (8 * MinNodeSize) + 1, 0) +            { +            } + +            bool Has(size_t offset) const { +                const size_t reducedOffset = ReducedOffset(offset); +                return OffsetCell(reducedOffset) & OffsetMask(reducedOffset); +            } + +            void Add(size_t offset) { +                const size_t reducedOffset = ReducedOffset(offset); +                OffsetCell(reducedOffset) |= OffsetMask(reducedOffset); +            } + +            void Remove(size_t offset) { +                const size_t reducedOffset = ReducedOffset(offset); +                OffsetCell(reducedOffset) &= ~OffsetMask(reducedOffset); +            } + +            void Swap(TTrieNodeSet& other) { +                Body.swap(other.Body); +            } + +        private: +            static const size_t MinNodeSize = 2; +            TVector<ui8> Body; + +            static size_t ReducedOffset(size_t offset) { +                return offset / MinNodeSize; +            } +            static ui8 OffsetMask(size_t reducedOffset) { +                return 1 << (reducedOffset % 8); +            } +            ui8& OffsetCell(size_t reducedOffset) { +                return Body.at(reducedOffset / 8); +            } +            const ui8& OffsetCell(size_t reducedOffset) const { +                return Body.at(reducedOffset / 8); +            } +        }; + +        //--------------------------------------------------------------------- + +        class TTrieNodeCounts { +        public:              TTrieNodeCounts() = default; -            explicit TTrieNodeCounts(const TOpaqueTrie& trie)  -                : Body(trie.Length / MinNodeSize, 0)  -                , IsTree(false)  -            {  -            }  - -            size_t Get(size_t offset) const {  -                return IsTree ? 1 : Body.at(offset / MinNodeSize);  -            }  - -            void Inc(size_t offset) {  -                if (IsTree) {  -                    return;  -                }  -                ui8& count = Body.at(offset / MinNodeSize);  -                if (count != MaxCount) {  -                    ++count;  -                }  -            }  - -            size_t Dec(size_t offset) {  -                if (IsTree) {  -                    return 0;  -                }  -                ui8& count = Body.at(offset / MinNodeSize);  -                Y_ASSERT(count > 0);  -                if (count != MaxCount) {  -                    --count;  -                }  -                return count;  -            }  - -            void Swap(TTrieNodeCounts& other) {  -                Body.swap(other.Body);  -                ::DoSwap(IsTree, other.IsTree);  -            }  - -            void SetTreeMode() {  -                IsTree = true;  -                Body = TVector<ui8>();  -            }  - -        private:  -            static const size_t MinNodeSize = 2;  -            static const ui8 MaxCount = 255;  - -            TVector<ui8> Body;  -            bool IsTree = false;  -        };  - -        //----------------------------------------------------------  - -        class TOffsetIndex {  -        public:  -            // In all methods:  -            // Key --- offset from the beginning of the old trie.  -            // Value --- offset from the end of the new trie.  - -            explicit TOffsetIndex(TTrieNodeCounts& counts) {  -                ParentCounts.Swap(counts);  -            }  - -            void Add(size_t key, size_t value) {  -                Data[key] = value;  -            }  - -            size_t Size() const {  -                return Data.size();  -            }  - -            size_t Get(size_t key) {  -                auto pos = Data.find(key);  -                if (pos == Data.end()) {  -                    ythrow yexception() << "Bad node walking order: trying to get node offset too early or too many times!";  -                }  -                size_t result = pos->second;  -                if (ParentCounts.Dec(key) == 0) {  -                    // We don't need this offset any more.  -                    Data.erase(pos);  -                }  -                return result;  -            }  - -        private:  -            TTrieNodeCounts ParentCounts;  -            THashMap<size_t, size_t> Data;  -        };  - -        //---------------------------------------------------------------------------------------  - -        class TTrieMeasurer {  -        public:  -            TTrieMeasurer(const TOpaqueTrie& trie, bool verbose);  -            void Measure();  - -            size_t GetDepth() const {  -                return Depth;  -            }  - -            size_t GetNodeCount() const {  -                return NodeCount;  -            }  - -            size_t GetUnminimizedNodeCount() const {  -                return UnminimizedNodeCount;  -            }  - -            bool IsTree() const {  -                return NodeCount == UnminimizedNodeCount;  -            }  - -            TTrieNodeCounts& GetParentCounts() {  -                return ParentCounts;  -            }  - -            const TOpaqueTrie& GetTrie() const {  -                return Trie;  -            }  - -        private:  -            const TOpaqueTrie& Trie;  -            size_t Depth;  -            TTrieNodeCounts ParentCounts;  -            size_t NodeCount;  -            size_t UnminimizedNodeCount;  -            const bool Verbose;  - -            // returns depth, increments NodeCount.  -            size_t MeasureSubtrie(size_t rootOffset, bool isNewPath);  -        };  - -        TTrieMeasurer::TTrieMeasurer(const TOpaqueTrie& trie, bool verbose)  -            : Trie(trie)  -            , Depth(0)  -            , ParentCounts(trie)  -            , NodeCount(0)  -            , UnminimizedNodeCount(0)  -            , Verbose(verbose)  -        {  -            Y_ASSERT(Trie.Data);  -        }  - -        void TTrieMeasurer::Measure() {  -            if (Verbose) {  -                Cerr << "Measuring the trie..." << Endl;  -            }  -            NodeCount = 0;  -            UnminimizedNodeCount = 0;  -            Depth = MeasureSubtrie(0, true);  -            if (IsTree()) {  -                ParentCounts.SetTreeMode();  -            }  -            if (Verbose) {  -                Cerr << "Unminimized node count: " << UnminimizedNodeCount << Endl;  -                Cerr << "Trie depth: " << Depth << Endl;  -                Cerr << "Node count: " << NodeCount << Endl;  -            }  -        }  - -        // A chain of nodes linked by forward links  -        // is considered one node with many left and right children  -        // for depth measuring here and in  -        // TVanEmdeBoasReverseNodeEnumerator::FindDescendants.  -        size_t TTrieMeasurer::MeasureSubtrie(size_t rootOffset, bool isNewPath) {  -            Y_ASSERT(rootOffset < Trie.Length);  -            TNode node(Trie.Data, rootOffset, Trie.SkipFunction);  -            size_t depth = 0;  -            for (;;) {  -                ++UnminimizedNodeCount;  -                if (Verbose) {  -                    ShowProgress(UnminimizedNodeCount);  -                }  -                if (isNewPath) {  -                    if (ParentCounts.Get(node.GetOffset()) > 0) {  -                        isNewPath = false;  -                    } else {  -                        ++NodeCount;  -                    }  -                    ParentCounts.Inc(node.GetOffset());  -                }  -                if (node.GetLeftOffset()) {  -                    depth = Max(depth, 1 + MeasureSubtrie(node.GetLeftOffset(), isNewPath));  -                }  -                if (node.GetRightOffset()) {  -                    depth = Max(depth, 1 + MeasureSubtrie(node.GetRightOffset(), isNewPath));  -                }  -                if (node.GetForwardOffset()) {  -                    node = TNode(Trie.Data, node.GetForwardOffset(), Trie.SkipFunction);  -                } else {  -                    break;  -                }  -            } -            return depth;  +            explicit TTrieNodeCounts(const TOpaqueTrie& trie) +                : Body(trie.Length / MinNodeSize, 0) +                , IsTree(false) +            { +            } + +            size_t Get(size_t offset) const { +                return IsTree ? 1 : Body.at(offset / MinNodeSize); +            } + +            void Inc(size_t offset) { +                if (IsTree) { +                    return; +                } +                ui8& count = Body.at(offset / MinNodeSize); +                if (count != MaxCount) { +                    ++count; +                } +            } + +            size_t Dec(size_t offset) { +                if (IsTree) { +                    return 0; +                } +                ui8& count = Body.at(offset / MinNodeSize); +                Y_ASSERT(count > 0); +                if (count != MaxCount) { +                    --count; +                } +                return count; +            } + +            void Swap(TTrieNodeCounts& other) { +                Body.swap(other.Body); +                ::DoSwap(IsTree, other.IsTree); +            } + +            void SetTreeMode() { +                IsTree = true; +                Body = TVector<ui8>(); +            } + +        private: +            static const size_t MinNodeSize = 2; +            static const ui8 MaxCount = 255; + +            TVector<ui8> Body; +            bool IsTree = false; +        }; + +        //---------------------------------------------------------- + +        class TOffsetIndex { +        public: +            // In all methods: +            // Key --- offset from the beginning of the old trie. +            // Value --- offset from the end of the new trie. + +            explicit TOffsetIndex(TTrieNodeCounts& counts) { +                ParentCounts.Swap(counts); +            } + +            void Add(size_t key, size_t value) { +                Data[key] = value; +            } + +            size_t Size() const { +                return Data.size(); +            } + +            size_t Get(size_t key) { +                auto pos = Data.find(key); +                if (pos == Data.end()) { +                    ythrow yexception() << "Bad node walking order: trying to get node offset too early or too many times!"; +                } +                size_t result = pos->second; +                if (ParentCounts.Dec(key) == 0) { +                    // We don't need this offset any more. +                    Data.erase(pos); +                } +                return result; +            } + +        private: +            TTrieNodeCounts ParentCounts; +            THashMap<size_t, size_t> Data; +        }; + +        //--------------------------------------------------------------------------------------- + +        class TTrieMeasurer { +        public: +            TTrieMeasurer(const TOpaqueTrie& trie, bool verbose); +            void Measure(); + +            size_t GetDepth() const { +                return Depth; +            } + +            size_t GetNodeCount() const { +                return NodeCount; +            } + +            size_t GetUnminimizedNodeCount() const { +                return UnminimizedNodeCount; +            } + +            bool IsTree() const { +                return NodeCount == UnminimizedNodeCount; +            } + +            TTrieNodeCounts& GetParentCounts() { +                return ParentCounts; +            } + +            const TOpaqueTrie& GetTrie() const { +                return Trie; +            } + +        private: +            const TOpaqueTrie& Trie; +            size_t Depth; +            TTrieNodeCounts ParentCounts; +            size_t NodeCount; +            size_t UnminimizedNodeCount; +            const bool Verbose; + +            // returns depth, increments NodeCount. +            size_t MeasureSubtrie(size_t rootOffset, bool isNewPath); +        }; + +        TTrieMeasurer::TTrieMeasurer(const TOpaqueTrie& trie, bool verbose) +            : Trie(trie) +            , Depth(0) +            , ParentCounts(trie) +            , NodeCount(0) +            , UnminimizedNodeCount(0) +            , Verbose(verbose) +        { +            Y_ASSERT(Trie.Data);          } -  -        //--------------------------------------------------------------------------------------  - -        using TLevelNodes = TVector<size_t>;  - -        struct TLevel {  -            size_t Depth;  -            TLevelNodes Nodes;  -  -            explicit TLevel(size_t depth)  -                : Depth(depth)  -            {  -            }  -        };  -  -        //----------------------------------------------------------------------------------------  - -        class TVanEmdeBoasReverseNodeEnumerator: public TReverseNodeEnumerator {  -        public:  -            TVanEmdeBoasReverseNodeEnumerator(TTrieMeasurer& measurer, bool verbose)  -                : Fresh(true)  -                , Trie(measurer.GetTrie())  -                , Depth(measurer.GetDepth())  -                , MaxIndexSize(0)  -                , BackIndex(measurer.GetParentCounts())  -                , ProcessedNodes(measurer.GetTrie())  -                , Verbose(verbose)  -            {  -            }  - -            bool Move() override {  -                if (!Fresh) {  -                    CentralWord.pop_back();  -                }  -                if (CentralWord.empty()) {  -                    return MoveCentralWordStart();  -                }  -                return true;  -            }  - -            const TNode& Get() const {  -                return CentralWord.back();  -            }  - -            size_t GetLeafLength() const override {  -                return Get().GetLeafLength();  -            }  - -            // Returns recalculated offset from the end of the current node.  -            size_t PrepareOffset(size_t absoffset, size_t resultLength) {  -                if (!absoffset)  -                    return NPOS;  -                return resultLength - BackIndex.Get(absoffset);  -            }  - -            size_t RecreateNode(char* buffer, size_t resultLength) override {  -                TWriteableNode newNode(Get(), Trie.Data);  -                newNode.ForwardOffset = PrepareOffset(Get().GetForwardOffset(), resultLength);  -                newNode.LeftOffset = PrepareOffset(Get().GetLeftOffset(), resultLength);  -                newNode.RightOffset = PrepareOffset(Get().GetRightOffset(), resultLength);  -  -                const size_t len = newNode.Pack(buffer);  -                ProcessedNodes.Add(Get().GetOffset());  -                BackIndex.Add(Get().GetOffset(), resultLength + len);  -                MaxIndexSize = Max(MaxIndexSize, BackIndex.Size());  -                return len;  -            }  - -        private:  -            bool Fresh;  -            TOpaqueTrie Trie;  -            size_t Depth;  -            size_t MaxIndexSize;  - -            TVector<TLevel> Trace;  -            TOffsetIndex BackIndex;  -            TVector<TNode> CentralWord;  -            TTrieNodeSet ProcessedNodes;  - -            const bool Verbose;  - -        private:  -            bool IsVisited(size_t offset) const {  -                return ProcessedNodes.Has(offset);  -            }  - -            void AddCascade(size_t step) {  -                Y_ASSERT(!(step & (step - 1))); // Should be a power of 2.  -                while (step > 0) {  -                    size_t root = Trace.back().Nodes.back();  -                    TLevel level(Trace.back().Depth + step);  -                    Trace.push_back(level);  -                    size_t actualStep = FindSupportingPowerOf2(FindDescendants(root, step, Trace.back().Nodes));  -                    if (actualStep != step) {  -                        // Retry with a smaller step.  -                        Y_ASSERT(actualStep < step);  -                        step = actualStep;  -                        Trace.pop_back();  -                    } else {  -                        step /= 2;  -                    }  -                }  -            } - -            void FillCentralWord() {  -                CentralWord.clear();  -                CentralWord.push_back(TNode(Trie.Data, Trace.back().Nodes.back(), Trie.SkipFunction));  -                // Do not check for epsilon links, as the traversal order now is different.  -                while (CentralWord.back().GetForwardOffset() && !IsVisited(CentralWord.back().GetForwardOffset())) {  -                    CentralWord.push_back(TNode(Trie.Data, CentralWord.back().GetForwardOffset(), Trie.SkipFunction));  -                }  -            }  - -            bool MoveCentralWordStart() {  -                do {  -                    if (Fresh) {  -                        TLevel root(0);  -                        Trace.push_back(root);  -                        Trace.back().Nodes.push_back(0);  -                        const size_t sectionDepth = FindSupportingPowerOf2(Depth);  -                        AddCascade(sectionDepth);  -                        Fresh = false;  -                    } else {  -                        Trace.back().Nodes.pop_back();  -                        if (Trace.back().Nodes.empty() && Trace.size() == 1) {  -                            if (Verbose) {  -                                Cerr << "Max index size: " << MaxIndexSize << Endl;  -                                Cerr << "Current index size: " << BackIndex.Size() << Endl;  -                            }  -                            // We just popped the root.  -                            return false;  -                        }  -                        size_t lastStep = Trace.back().Depth - Trace[Trace.size() - 2].Depth;  -                        if (Trace.back().Nodes.empty()) {  -                            Trace.pop_back();  -                        }  -                        AddCascade(lastStep / 2);  -                    }  -                } while (IsVisited(Trace.back().Nodes.back()));  -                FillCentralWord();  -                return true;  -            } -  -            // Returns the maximal depth it has reached while searching.  -            // This is a method because it needs OffsetIndex to skip processed nodes.  -            size_t FindDescendants(size_t rootOffset, size_t depth, TLevelNodes& result) const {  -                if (depth == 0) {  -                    result.push_back(rootOffset);  -                    return 0;  -                }  -                size_t actualDepth = 0;  -                TNode node(Trie.Data, rootOffset, Trie.SkipFunction);  -                for (;;) {  -                    if (node.GetLeftOffset() && !IsVisited(node.GetLeftOffset())) {  -                        actualDepth = Max(actualDepth,  -                                          1 + FindDescendants(node.GetLeftOffset(), depth - 1, result));  + +        void TTrieMeasurer::Measure() { +            if (Verbose) { +                Cerr << "Measuring the trie..." << Endl; +            } +            NodeCount = 0; +            UnminimizedNodeCount = 0; +            Depth = MeasureSubtrie(0, true); +            if (IsTree()) { +                ParentCounts.SetTreeMode(); +            } +            if (Verbose) { +                Cerr << "Unminimized node count: " << UnminimizedNodeCount << Endl; +                Cerr << "Trie depth: " << Depth << Endl; +                Cerr << "Node count: " << NodeCount << Endl; +            } +        } + +        // A chain of nodes linked by forward links +        // is considered one node with many left and right children +        // for depth measuring here and in +        // TVanEmdeBoasReverseNodeEnumerator::FindDescendants. +        size_t TTrieMeasurer::MeasureSubtrie(size_t rootOffset, bool isNewPath) { +            Y_ASSERT(rootOffset < Trie.Length); +            TNode node(Trie.Data, rootOffset, Trie.SkipFunction); +            size_t depth = 0; +            for (;;) { +                ++UnminimizedNodeCount; +                if (Verbose) { +                    ShowProgress(UnminimizedNodeCount); +                } +                if (isNewPath) { +                    if (ParentCounts.Get(node.GetOffset()) > 0) { +                        isNewPath = false; +                    } else { +                        ++NodeCount; +                    } +                    ParentCounts.Inc(node.GetOffset()); +                } +                if (node.GetLeftOffset()) { +                    depth = Max(depth, 1 + MeasureSubtrie(node.GetLeftOffset(), isNewPath)); +                } +                if (node.GetRightOffset()) { +                    depth = Max(depth, 1 + MeasureSubtrie(node.GetRightOffset(), isNewPath)); +                } +                if (node.GetForwardOffset()) { +                    node = TNode(Trie.Data, node.GetForwardOffset(), Trie.SkipFunction); +                } else { +                    break; +                } +            } +            return depth; +        } + +        //-------------------------------------------------------------------------------------- + +        using TLevelNodes = TVector<size_t>; + +        struct TLevel { +            size_t Depth; +            TLevelNodes Nodes; + +            explicit TLevel(size_t depth) +                : Depth(depth) +            { +            } +        }; + +        //---------------------------------------------------------------------------------------- + +        class TVanEmdeBoasReverseNodeEnumerator: public TReverseNodeEnumerator { +        public: +            TVanEmdeBoasReverseNodeEnumerator(TTrieMeasurer& measurer, bool verbose) +                : Fresh(true) +                , Trie(measurer.GetTrie()) +                , Depth(measurer.GetDepth()) +                , MaxIndexSize(0) +                , BackIndex(measurer.GetParentCounts()) +                , ProcessedNodes(measurer.GetTrie()) +                , Verbose(verbose) +            { +            } + +            bool Move() override { +                if (!Fresh) { +                    CentralWord.pop_back(); +                } +                if (CentralWord.empty()) { +                    return MoveCentralWordStart(); +                } +                return true; +            } + +            const TNode& Get() const { +                return CentralWord.back(); +            } + +            size_t GetLeafLength() const override { +                return Get().GetLeafLength(); +            } + +            // Returns recalculated offset from the end of the current node. +            size_t PrepareOffset(size_t absoffset, size_t resultLength) { +                if (!absoffset) +                    return NPOS; +                return resultLength - BackIndex.Get(absoffset); +            } + +            size_t RecreateNode(char* buffer, size_t resultLength) override { +                TWriteableNode newNode(Get(), Trie.Data); +                newNode.ForwardOffset = PrepareOffset(Get().GetForwardOffset(), resultLength); +                newNode.LeftOffset = PrepareOffset(Get().GetLeftOffset(), resultLength); +                newNode.RightOffset = PrepareOffset(Get().GetRightOffset(), resultLength); + +                const size_t len = newNode.Pack(buffer); +                ProcessedNodes.Add(Get().GetOffset()); +                BackIndex.Add(Get().GetOffset(), resultLength + len); +                MaxIndexSize = Max(MaxIndexSize, BackIndex.Size()); +                return len; +            } + +        private: +            bool Fresh; +            TOpaqueTrie Trie; +            size_t Depth; +            size_t MaxIndexSize; + +            TVector<TLevel> Trace; +            TOffsetIndex BackIndex; +            TVector<TNode> CentralWord; +            TTrieNodeSet ProcessedNodes; + +            const bool Verbose; + +        private: +            bool IsVisited(size_t offset) const { +                return ProcessedNodes.Has(offset); +            } + +            void AddCascade(size_t step) { +                Y_ASSERT(!(step & (step - 1))); // Should be a power of 2. +                while (step > 0) { +                    size_t root = Trace.back().Nodes.back(); +                    TLevel level(Trace.back().Depth + step); +                    Trace.push_back(level); +                    size_t actualStep = FindSupportingPowerOf2(FindDescendants(root, step, Trace.back().Nodes)); +                    if (actualStep != step) { +                        // Retry with a smaller step. +                        Y_ASSERT(actualStep < step); +                        step = actualStep; +                        Trace.pop_back(); +                    } else { +                        step /= 2;                      } -                    if (node.GetRightOffset() && !IsVisited(node.GetRightOffset())) {  -                        actualDepth = Max(actualDepth,  -                                          1 + FindDescendants(node.GetRightOffset(), depth - 1, result));  -                    }  -                    if (node.GetForwardOffset() && !IsVisited(node.GetForwardOffset())) {  -                        node = TNode(Trie.Data, node.GetForwardOffset(), Trie.SkipFunction);  -                    } else {  -                        break;  -                    }                   } -                return actualDepth;               } -        };  -    } // Anonymous namespace.  -  -    //-----------------------------------------------------------------------------------  -  -    size_t RawCompactTrieFastLayoutImpl(IOutputStream& os, const TOpaqueTrie& trie, bool verbose) {  -        if (!trie.Data || !trie.Length) {  +            void FillCentralWord() { +                CentralWord.clear(); +                CentralWord.push_back(TNode(Trie.Data, Trace.back().Nodes.back(), Trie.SkipFunction)); +                // Do not check for epsilon links, as the traversal order now is different. +                while (CentralWord.back().GetForwardOffset() && !IsVisited(CentralWord.back().GetForwardOffset())) { +                    CentralWord.push_back(TNode(Trie.Data, CentralWord.back().GetForwardOffset(), Trie.SkipFunction)); +                } +            } + +            bool MoveCentralWordStart() { +                do { +                    if (Fresh) { +                        TLevel root(0); +                        Trace.push_back(root); +                        Trace.back().Nodes.push_back(0); +                        const size_t sectionDepth = FindSupportingPowerOf2(Depth); +                        AddCascade(sectionDepth); +                        Fresh = false; +                    } else { +                        Trace.back().Nodes.pop_back(); +                        if (Trace.back().Nodes.empty() && Trace.size() == 1) { +                            if (Verbose) { +                                Cerr << "Max index size: " << MaxIndexSize << Endl; +                                Cerr << "Current index size: " << BackIndex.Size() << Endl; +                            } +                            // We just popped the root. +                            return false; +                        } +                        size_t lastStep = Trace.back().Depth - Trace[Trace.size() - 2].Depth; +                        if (Trace.back().Nodes.empty()) { +                            Trace.pop_back(); +                        } +                        AddCascade(lastStep / 2); +                    } +                } while (IsVisited(Trace.back().Nodes.back())); +                FillCentralWord(); +                return true; +            } + +            // Returns the maximal depth it has reached while searching. +            // This is a method because it needs OffsetIndex to skip processed nodes. +            size_t FindDescendants(size_t rootOffset, size_t depth, TLevelNodes& result) const { +                if (depth == 0) { +                    result.push_back(rootOffset); +                    return 0; +                } +                size_t actualDepth = 0; +                TNode node(Trie.Data, rootOffset, Trie.SkipFunction); +                for (;;) { +                    if (node.GetLeftOffset() && !IsVisited(node.GetLeftOffset())) { +                        actualDepth = Max(actualDepth, +                                          1 + FindDescendants(node.GetLeftOffset(), depth - 1, result)); +                    } +                    if (node.GetRightOffset() && !IsVisited(node.GetRightOffset())) { +                        actualDepth = Max(actualDepth, +                                          1 + FindDescendants(node.GetRightOffset(), depth - 1, result)); +                    } +                    if (node.GetForwardOffset() && !IsVisited(node.GetForwardOffset())) { +                        node = TNode(Trie.Data, node.GetForwardOffset(), Trie.SkipFunction); +                    } else { +                        break; +                    } +                } +                return actualDepth; +            } +        }; + +    } // Anonymous namespace. + +    //----------------------------------------------------------------------------------- + +    size_t RawCompactTrieFastLayoutImpl(IOutputStream& os, const TOpaqueTrie& trie, bool verbose) { +        if (!trie.Data || !trie.Length) {              return 0;          } -        TTrieMeasurer mes(trie, verbose);  -        mes.Measure();  -        TVanEmdeBoasReverseNodeEnumerator enumerator(mes, verbose);  -        return WriteTrieBackwards(os, enumerator, verbose);  +        TTrieMeasurer mes(trie, verbose); +        mes.Measure(); +        TVanEmdeBoasReverseNodeEnumerator enumerator(mes, verbose); +        return WriteTrieBackwards(os, enumerator, verbose);      } -  +  } diff --git a/library/cpp/containers/comptrie/make_fast_layout.h b/library/cpp/containers/comptrie/make_fast_layout.h index cb488ffaa5b..b8fab5d65b8 100644 --- a/library/cpp/containers/comptrie/make_fast_layout.h +++ b/library/cpp/containers/comptrie/make_fast_layout.h @@ -6,15 +6,15 @@  class IOutputStream;  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. +    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) { +        TPackerLeafSkipper<TPacker> skipper(packer); +        TOpaqueTrie trie(data, datalength, skipper); +        return RawCompactTrieFastLayoutImpl(os, trie, 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) {  -        TPackerLeafSkipper<TPacker> skipper(packer);  -        TOpaqueTrie trie(data, datalength, skipper);  -        return RawCompactTrieFastLayoutImpl(os, trie, verbose);  -    }  -   } diff --git a/library/cpp/containers/comptrie/minimize.cpp b/library/cpp/containers/comptrie/minimize.cpp index f53511428f4..80d0b25217d 100644 --- a/library/cpp/containers/comptrie/minimize.cpp +++ b/library/cpp/containers/comptrie/minimize.cpp @@ -8,352 +8,352 @@  #include <util/generic/algorithm.h>  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).  -    // The algorithm is as follows: starting from the largest pieces, we find  -    // nodes that have identical continuations  (Daciuk's right language),  -    // and repack the trie. Repacking is done in-place, so memory is less  -    // of an issue; however, it may take considerable time.  - -    // IMPORTANT: never try to reminimize an already minimized trie or a trie with fast layout.  -    // 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.  -  -    namespace {  -        using TOffsetList = TVector<size_t>;  -        using TPieceIndex = THashMap<size_t, TOffsetList>;  - -        using TSizePair = std::pair<size_t, size_t>;  -        using TSizePairVector = TVector<TSizePair>;  -        using TSizePairVectorVector = TVector<TSizePairVector>;  - -        class TOffsetMap {  -        protected:  -            TSizePairVectorVector Data;  -  -        public:  -            TOffsetMap() {  -                Data.reserve(0x10000);  -            }  - -            void Add(size_t key, size_t value) {  -                size_t hikey = key & 0xFFFF;  - -                if (Data.size() <= hikey)  -                    Data.resize(hikey + 1);  - -                TSizePairVector& sublist = Data[hikey];  - -                for (auto& it : sublist) {  -                    if (it.first == key) {  -                        it.second = value;  - -                        return;  -                    }  -                }  - -                sublist.push_back(TSizePair(key, value));  -            }  -  -            bool Contains(size_t key) const {  -                return (Get(key) != 0);  +    // 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). +    // The algorithm is as follows: starting from the largest pieces, we find +    // nodes that have identical continuations  (Daciuk's right language), +    // and repack the trie. Repacking is done in-place, so memory is less +    // of an issue; however, it may take considerable time. + +    // IMPORTANT: never try to reminimize an already minimized trie or a trie with fast layout. +    // 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. + +    namespace { +        using TOffsetList = TVector<size_t>; +        using TPieceIndex = THashMap<size_t, TOffsetList>; + +        using TSizePair = std::pair<size_t, size_t>; +        using TSizePairVector = TVector<TSizePair>; +        using TSizePairVectorVector = TVector<TSizePairVector>; + +        class TOffsetMap { +        protected: +            TSizePairVectorVector Data; + +        public: +            TOffsetMap() { +                Data.reserve(0x10000);              } -  -            size_t Get(size_t key) const {  -                size_t hikey = key & 0xFFFF;  - -                if (Data.size() <= hikey)  -                    return 0;  - -                const TSizePairVector& sublist = Data[hikey];  - -                for (const auto& it : sublist) {  -                    if (it.first == key)  -                        return it.second;  -                }  -  -                return 0;  -            }  -        };  - -        class TOffsetDeltas {  -        protected:  -            TSizePairVector Data;  -  -        public:  -            void Add(size_t key, size_t value) {  -                if (Data.empty()) {  -                    if (key == value)  -                        return; // no offset  -                } else {  -                    TSizePair last = Data.back();  - -                    if (key <= last.first) {  -                        Cerr << "Trouble: elements to offset delta list added in wrong order" << Endl;  - -                        return;  -                    }  -  -                    if (last.first + value == last.second + key)  -                        return; // same  offset  -                }  -  -                Data.push_back(TSizePair(key, value));  + +            void Add(size_t key, size_t value) { +                size_t hikey = key & 0xFFFF; + +                if (Data.size() <= hikey) +                    Data.resize(hikey + 1); + +                TSizePairVector& sublist = Data[hikey]; + +                for (auto& it : sublist) { +                    if (it.first == key) { +                        it.second = value; + +                        return; +                    } +                } + +                sublist.push_back(TSizePair(key, value)); +            } + +            bool Contains(size_t key) const { +                return (Get(key) != 0); +            } + +            size_t Get(size_t key) const { +                size_t hikey = key & 0xFFFF; + +                if (Data.size() <= hikey) +                    return 0; + +                const TSizePairVector& sublist = Data[hikey]; + +                for (const auto& it : sublist) { +                    if (it.first == key) +                        return it.second; +                } + +                return 0; +            } +        }; + +        class TOffsetDeltas { +        protected: +            TSizePairVector Data; + +        public: +            void Add(size_t key, size_t value) { +                if (Data.empty()) { +                    if (key == value) +                        return; // no offset +                } else { +                    TSizePair last = Data.back(); + +                    if (key <= last.first) { +                        Cerr << "Trouble: elements to offset delta list added in wrong order" << Endl; + +                        return; +                    } + +                    if (last.first + value == last.second + key) +                        return; // same  offset +                } + +                Data.push_back(TSizePair(key, value)); +            } + +            size_t Get(size_t key) const { +                if (Data.empty()) +                    return key; // difference is zero; + +                if (key < Data.front().first) +                    return key; + +                // Binary search for the highest entry in the list that does not exceed the key +                size_t from = 0; +                size_t to = Data.size() - 1; + +                while (from < to) { +                    size_t midpoint = (from + to + 1) / 2; + +                    if (key < Data[midpoint].first) +                        to = midpoint - 1; +                    else +                        from = midpoint; +                } + +                TSizePair entry = Data[from]; + +                return key - entry.first + entry.second; +            } +        }; + +        class TPieceComparer { +        private: +            const char* Data; +            const size_t Length; + +        public: +            TPieceComparer(const char* buf, size_t len) +                : Data(buf) +                , Length(len) +            {              } -  -            size_t Get(size_t key) const {  -                if (Data.empty())  -                    return key; // difference is zero;  - -                if (key < Data.front().first)  -                    return key;  - -                // Binary search for the highest entry in the list that does not exceed the key  -                size_t from = 0;  -                size_t to = Data.size() - 1;  - -                while (from < to) {  -                    size_t midpoint = (from + to + 1) / 2;  -  -                    if (key < Data[midpoint].first)  -                        to = midpoint - 1;  -                    else  -                        from = midpoint;  -                }  - -                TSizePair entry = Data[from];  -  -                return key - entry.first + entry.second;  -            }  -        };  -  -        class TPieceComparer {  -        private:  -            const char* Data;  -            const size_t Length;  -  -        public:  -            TPieceComparer(const char* buf, size_t len)  -                : Data(buf)  -                , Length(len)  -            {  -            }  - -            bool operator()(size_t p1, const size_t p2) {  -                int res = memcmp(Data + p1, Data + p2, Length);  -  -                if (res)  -                    return (res > 0);  -  -                return (p1 > p2); // the pieces are sorted in the reverse order of appearance  -            }  -        };  -  -        struct TBranchPoint {  -            TNode Node;  -            int Selector;  -  -        public:  -            TBranchPoint()  -                : Selector(0)  -            {  -            }  - -            TBranchPoint(const char* data, size_t offset, const ILeafSkipper& skipFunction)  -                : Node(data, offset, skipFunction)  -                , Selector(0)  -            {  -            }  - -            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) {  -                    size_t nextOffset = 0;  - -                    switch (++Selector) {  -                        case 1:  -                            if (Node.GetRightOffset())  -                                nextOffset = Node.GetRightOffset();  -                            break;  - -                        case 2:  -                            if (Node.GetLeftOffset())  -                                nextOffset = Node.GetLeftOffset();  -                            break;  -  -                        case 3:  -                            if (Node.GetForwardOffset())  -                                nextOffset = Node.GetForwardOffset();  -                            break;  -  -                        default:  -                            break;  -                    }  -  -                    if (nextOffset && !mergedNodes.Contains(nextOffset))  -                        return nextOffset;  -                }  -                return 0;  + +            bool operator()(size_t p1, const size_t p2) { +                int res = memcmp(Data + p1, Data + p2, Length); + +                if (res) +                    return (res > 0); + +                return (p1 > p2); // the pieces are sorted in the reverse order of appearance +            } +        }; + +        struct TBranchPoint { +            TNode Node; +            int Selector; + +        public: +            TBranchPoint() +                : Selector(0) +            {              } -        };  -  -        class TMergingReverseNodeEnumerator: public TReverseNodeEnumerator {  -        private:  -            bool Fresh;  -            TOpaqueTrie Trie;  -            const TOffsetMap& MergeMap;  -            TVector<TBranchPoint> Trace;  -            TOffsetDeltas OffsetIndex;  - -        public:  -            TMergingReverseNodeEnumerator(const TOpaqueTrie& trie, const TOffsetMap& mergers)  -                : Fresh(true)  -                , Trie(trie)  -                , MergeMap(mergers)  -            {  -            }  - -            bool Move() override {  -                if (Fresh) {  -                    Trace.push_back(TBranchPoint(Trie.Data, 0, Trie.SkipFunction));  -                    Fresh = false;  -                } else {  -                    if (Trace.empty())  -                        return false;  - -                    Trace.pop_back();  -  -                    if (Trace.empty())  -                        return false;  -                }  -  -                size_t nextnode = Trace.back().NextNode(MergeMap);  - -                while (nextnode) {  -                    Trace.push_back(TBranchPoint(Trie.Data, nextnode, Trie.SkipFunction));  -                    nextnode = Trace.back().NextNode(MergeMap);  -                }  -  -                return (!Trace.empty());  -            }  - -            const TNode& Get() const {  -                return Trace.back().Node;  -            }  -            size_t GetLeafLength() const override {  -                return Get().GetLeafLength();  -            }  - -            // Returns recalculated offset from the end of the current node  -            size_t PrepareOffset(size_t absoffset, size_t minilength) {  -                if (!absoffset)  -                    return NPOS;  - -                if (MergeMap.Contains(absoffset))  -                    absoffset = MergeMap.Get(absoffset);  -                return minilength - OffsetIndex.Get(Trie.Length - absoffset);  -            }  - -            size_t RecreateNode(char* buffer, size_t resultLength) override {  -                TWriteableNode newNode(Get(), Trie.Data);  -                newNode.ForwardOffset = PrepareOffset(Get().GetForwardOffset(), resultLength);  -                newNode.LeftOffset = PrepareOffset(Get().GetLeftOffset(), resultLength);  -                newNode.RightOffset = PrepareOffset(Get().GetRightOffset(), resultLength);  - -                if (!buffer)  -                    return newNode.Measure();  -  -                const size_t len = newNode.Pack(buffer);  -                OffsetIndex.Add(Trie.Length - Get().GetOffset(), resultLength + len);  - -                return len;  -            }  -        };  -  + +            TBranchPoint(const char* data, size_t offset, const ILeafSkipper& skipFunction) +                : Node(data, offset, skipFunction) +                , Selector(0) +            { +            } + +            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) { +                    size_t nextOffset = 0; + +                    switch (++Selector) { +                        case 1: +                            if (Node.GetRightOffset()) +                                nextOffset = Node.GetRightOffset(); +                            break; + +                        case 2: +                            if (Node.GetLeftOffset()) +                                nextOffset = Node.GetLeftOffset(); +                            break; + +                        case 3: +                            if (Node.GetForwardOffset()) +                                nextOffset = Node.GetForwardOffset(); +                            break; + +                        default: +                            break; +                    } + +                    if (nextOffset && !mergedNodes.Contains(nextOffset)) +                        return nextOffset; +                } +                return 0; +            } +        }; + +        class TMergingReverseNodeEnumerator: public TReverseNodeEnumerator { +        private: +            bool Fresh; +            TOpaqueTrie Trie; +            const TOffsetMap& MergeMap; +            TVector<TBranchPoint> Trace; +            TOffsetDeltas OffsetIndex; + +        public: +            TMergingReverseNodeEnumerator(const TOpaqueTrie& trie, const TOffsetMap& mergers) +                : Fresh(true) +                , Trie(trie) +                , MergeMap(mergers) +            { +            } + +            bool Move() override { +                if (Fresh) { +                    Trace.push_back(TBranchPoint(Trie.Data, 0, Trie.SkipFunction)); +                    Fresh = false; +                } else { +                    if (Trace.empty()) +                        return false; + +                    Trace.pop_back(); + +                    if (Trace.empty()) +                        return false; +                } + +                size_t nextnode = Trace.back().NextNode(MergeMap); + +                while (nextnode) { +                    Trace.push_back(TBranchPoint(Trie.Data, nextnode, Trie.SkipFunction)); +                    nextnode = Trace.back().NextNode(MergeMap); +                } + +                return (!Trace.empty()); +            } + +            const TNode& Get() const { +                return Trace.back().Node; +            } +            size_t GetLeafLength() const override { +                return Get().GetLeafLength(); +            } + +            // Returns recalculated offset from the end of the current node +            size_t PrepareOffset(size_t absoffset, size_t minilength) { +                if (!absoffset) +                    return NPOS; + +                if (MergeMap.Contains(absoffset)) +                    absoffset = MergeMap.Get(absoffset); +                return minilength - OffsetIndex.Get(Trie.Length - absoffset); +            } + +            size_t RecreateNode(char* buffer, size_t resultLength) override { +                TWriteableNode newNode(Get(), Trie.Data); +                newNode.ForwardOffset = PrepareOffset(Get().GetForwardOffset(), resultLength); +                newNode.LeftOffset = PrepareOffset(Get().GetLeftOffset(), resultLength); +                newNode.RightOffset = PrepareOffset(Get().GetRightOffset(), resultLength); + +                if (!buffer) +                    return newNode.Measure(); + +                const size_t len = newNode.Pack(buffer); +                OffsetIndex.Add(Trie.Length - Get().GetOffset(), resultLength + len); + +                return len; +            } +        }; +      } -    static void AddPiece(TPieceIndex& index, size_t offset, size_t len) {  -        index[len].push_back(offset);  -    }  - -    static TOffsetMap FindEquivalentSubtries(const TOpaqueTrie& trie, bool verbose, size_t minMergeSize) {  -        // Tree nodes, arranged by span length.  -        // When all nodes of a given size are considered, they pop off the queue.  -        TPieceIndex subtries;  -        TOffsetMap merger;  -        // Start walking the trie from head.  -        AddPiece(subtries, 0, trie.Length);  - -        size_t counter = 0;  -        // Now consider all nodes with sizeable continuations  -        for (size_t curlen = trie.Length; curlen >= minMergeSize && !subtries.empty(); curlen--) {  -            TPieceIndex::iterator iit = subtries.find(curlen);  - -            if (iit == subtries.end())  -                continue; // fast forward to the next available length value  - -            TOffsetList& batch = iit->second;  -            TPieceComparer comparer(trie.Data, curlen);  -            Sort(batch.begin(), batch.end(), comparer);  - -            TOffsetList::iterator it = batch.begin();  -            while (it != batch.end()) {  -                if (verbose)  -                    ShowProgress(++counter);  - -                size_t offset = *it;  -  -                // Fill the array with the subnodes of the element  -                TNode node(trie.Data, offset, trie.SkipFunction);  -                size_t end = offset + curlen;  -                if (size_t rightOffset = node.GetRightOffset()) {  -                    AddPiece(subtries, rightOffset, end - rightOffset);  -                    end = rightOffset;  -                }  -                if (size_t leftOffset = node.GetLeftOffset()) {  -                    AddPiece(subtries, leftOffset, end - leftOffset);  -                    end = leftOffset;  -                }  -                if (size_t forwardOffset = node.GetForwardOffset()) {  -                    AddPiece(subtries, forwardOffset, end - forwardOffset);  -                }  - -                while (++it != batch.end()) {  -                    // Find next different; until then, just add the offsets to the list of merged nodes.  -                    size_t nextoffset = *it;  - -                    if (memcmp(trie.Data + offset, trie.Data + nextoffset, curlen))  -                        break;  -  -                    merger.Add(nextoffset, offset);  -                }  -            }  -  -            subtries.erase(curlen);  +    static void AddPiece(TPieceIndex& index, size_t offset, size_t len) { +        index[len].push_back(offset); +    } + +    static TOffsetMap FindEquivalentSubtries(const TOpaqueTrie& trie, bool verbose, size_t minMergeSize) { +        // Tree nodes, arranged by span length. +        // When all nodes of a given size are considered, they pop off the queue. +        TPieceIndex subtries; +        TOffsetMap merger; +        // Start walking the trie from head. +        AddPiece(subtries, 0, trie.Length); + +        size_t counter = 0; +        // Now consider all nodes with sizeable continuations +        for (size_t curlen = trie.Length; curlen >= minMergeSize && !subtries.empty(); curlen--) { +            TPieceIndex::iterator iit = subtries.find(curlen); + +            if (iit == subtries.end()) +                continue; // fast forward to the next available length value + +            TOffsetList& batch = iit->second; +            TPieceComparer comparer(trie.Data, curlen); +            Sort(batch.begin(), batch.end(), comparer); + +            TOffsetList::iterator it = batch.begin(); +            while (it != batch.end()) { +                if (verbose) +                    ShowProgress(++counter); + +                size_t offset = *it; + +                // Fill the array with the subnodes of the element +                TNode node(trie.Data, offset, trie.SkipFunction); +                size_t end = offset + curlen; +                if (size_t rightOffset = node.GetRightOffset()) { +                    AddPiece(subtries, rightOffset, end - rightOffset); +                    end = rightOffset; +                } +                if (size_t leftOffset = node.GetLeftOffset()) { +                    AddPiece(subtries, leftOffset, end - leftOffset); +                    end = leftOffset; +                } +                if (size_t forwardOffset = node.GetForwardOffset()) { +                    AddPiece(subtries, forwardOffset, end - forwardOffset); +                } + +                while (++it != batch.end()) { +                    // Find next different; until then, just add the offsets to the list of merged nodes. +                    size_t nextoffset = *it; + +                    if (memcmp(trie.Data + offset, trie.Data + nextoffset, curlen)) +                        break; + +                    merger.Add(nextoffset, offset); +                } +            } + +            subtries.erase(curlen); +        } +        if (verbose) { +            Cerr << counter << Endl;          } -        if (verbose) {  -            Cerr << counter << Endl;  -        }  -        return merger;  +        return merger;      } -  -    size_t RawCompactTrieMinimizeImpl(IOutputStream& os, TOpaqueTrie& trie, bool verbose, size_t minMergeSize, EMinimizeMode mode) {  -        if (!trie.Data || !trie.Length) {  -            return 0;  -        }  -  -        TOffsetMap merger = FindEquivalentSubtries(trie, verbose, minMergeSize);  -        TMergingReverseNodeEnumerator enumerator(trie, merger);  -  -        if (mode == MM_DEFAULT)  -            return WriteTrieBackwards(os, enumerator, verbose);  -        else  -            return WriteTrieBackwardsNoAlloc(os, enumerator, trie, mode);  + +    size_t RawCompactTrieMinimizeImpl(IOutputStream& os, TOpaqueTrie& trie, bool verbose, size_t minMergeSize, EMinimizeMode mode) { +        if (!trie.Data || !trie.Length) { +            return 0; +        } + +        TOffsetMap merger = FindEquivalentSubtries(trie, verbose, minMergeSize); +        TMergingReverseNodeEnumerator enumerator(trie, merger); + +        if (mode == MM_DEFAULT) +            return WriteTrieBackwards(os, enumerator, verbose); +        else +            return WriteTrieBackwardsNoAlloc(os, enumerator, trie, mode);      }  } diff --git a/library/cpp/containers/comptrie/minimize.h b/library/cpp/containers/comptrie/minimize.h index 24645714370..baaa431d044 100644 --- a/library/cpp/containers/comptrie/minimize.h +++ b/library/cpp/containers/comptrie/minimize.h @@ -6,24 +6,24 @@  class IOutputStream;  namespace NCompactTrie { -    size_t MeasureOffset(size_t offset);  +    size_t MeasureOffset(size_t offset); -    enum EMinimizeMode {  -        MM_DEFAULT, // alollocate new memory for minimized tree  -        MM_NOALLOC, // minimize tree in the same buffer  -        MM_INPLACE  // do not write tree to the stream, but move to the buffer beginning  -    };  +    enum EMinimizeMode { +        MM_DEFAULT, // alollocate new memory for minimized tree +        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);  +    // Return value: size of the minimized trie. +    size_t RawCompactTrieMinimizeImpl(IOutputStream& os, TOpaqueTrie& trie, bool verbose, size_t minMergeSize, EMinimizeMode mode); -    // Return value: size of the minimized trie.  -    template <class TPacker>  -    size_t CompactTrieMinimizeImpl(IOutputStream& os, const char* data, size_t datalength, bool verbose, const TPacker* packer, EMinimizeMode mode) {  -        TPackerLeafSkipper<TPacker> skipper(packer);  -        size_t minmerge = MeasureOffset(datalength);  -        TOpaqueTrie trie(data, datalength, skipper);  -        return RawCompactTrieMinimizeImpl(os, trie, verbose, minmerge, mode);  -    }  +    // Return value: size of the minimized trie. +    template <class TPacker> +    size_t CompactTrieMinimizeImpl(IOutputStream& os, const char* data, size_t datalength, bool verbose, const TPacker* packer, EMinimizeMode mode) { +        TPackerLeafSkipper<TPacker> skipper(packer); +        size_t minmerge = MeasureOffset(datalength); +        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 cd98e6b4d66..5fd22f15ec3 100644 --- a/library/cpp/containers/comptrie/node.cpp +++ b/library/cpp/containers/comptrie/node.cpp @@ -6,74 +6,74 @@  #include <util/generic/yexception.h>  namespace NCompactTrie { -    TNode::TNode()  -        : Offset(0)  -        , LeafLength(0)  -        , CoreLength(0)  -        , Label(0)  -    {  -        for (auto& offset : Offsets) {  -            offset = 0;  -        }  +    TNode::TNode() +        : Offset(0) +        , LeafLength(0) +        , CoreLength(0) +        , Label(0) +    { +        for (auto& offset : Offsets) { +            offset = 0; +        }      } -    // We believe that epsilon links are found only on the forward-position and that afer jumping an epsilon link you come to an ordinary node.  -  -    TNode::TNode(const char* data, size_t offset, const ILeafSkipper& skipFunction)  -        : Offset(offset)  -        , LeafLength(0)  -        , CoreLength(0)  -        , Label(0)  -    {  -        for (auto& anOffset : Offsets) {  -            anOffset = 0;  -        }  -        if (!data)  -            return; // empty constructor  -  -        const char* datapos = data + offset;  -        char flags = *(datapos++);  -        Y_ASSERT(!IsEpsilonLink(flags));  -        Label = *(datapos++);  +    // We believe that epsilon links are found only on the forward-position and that afer jumping an epsilon link you come to an ordinary node. -        size_t leftsize = LeftOffsetLen(flags);  -        size_t& leftOffset = Offsets[D_LEFT];  -        leftOffset = UnpackOffset(datapos, leftsize);  -        if (leftOffset) {  -            leftOffset += Offset;  -        }  -        datapos += leftsize;  +    TNode::TNode(const char* data, size_t offset, const ILeafSkipper& skipFunction) +        : Offset(offset) +        , LeafLength(0) +        , CoreLength(0) +        , Label(0) +    { +        for (auto& anOffset : Offsets) { +            anOffset = 0; +        } +        if (!data) +            return; // empty constructor -        size_t rightsize = RightOffsetLen(flags);  -        size_t& rightOffset = Offsets[D_RIGHT];  -        rightOffset = UnpackOffset(datapos, rightsize);  -        if (rightOffset) {  -            rightOffset += Offset;  -        }  -        datapos += rightsize;  -  -        if (flags & MT_FINAL) {  -            Offsets[D_FINAL] = datapos - data;  -            LeafLength = skipFunction.SkipLeaf(datapos);  -        }  +        const char* datapos = data + offset; +        char flags = *(datapos++); +        Y_ASSERT(!IsEpsilonLink(flags)); +        Label = *(datapos++); -        CoreLength = 2 + leftsize + rightsize + LeafLength;  -        if (flags & MT_NEXT) {  -            size_t& forwardOffset = Offsets[D_NEXT];  -            forwardOffset = Offset + CoreLength;  -            // There might be an epsilon link at the forward position.  -            // If so, set the ForwardOffset to the value that points to the link's end.  -            const char* forwardPos = data + forwardOffset;  -            const char forwardFlags = *forwardPos;  -            if (IsEpsilonLink(forwardFlags)) {  -                // Jump through the epsilon link.  -                size_t epsilonOffset = UnpackOffset(forwardPos + 1, forwardFlags & MT_SIZEMASK);  -                if (!epsilonOffset) {  -                    ythrow yexception() << "Corrupted epsilon link";  -                }  -                forwardOffset += epsilonOffset;  +        size_t leftsize = LeftOffsetLen(flags); +        size_t& leftOffset = Offsets[D_LEFT]; +        leftOffset = UnpackOffset(datapos, leftsize); +        if (leftOffset) { +            leftOffset += Offset; +        } +        datapos += leftsize; + +        size_t rightsize = RightOffsetLen(flags); +        size_t& rightOffset = Offsets[D_RIGHT]; +        rightOffset = UnpackOffset(datapos, rightsize); +        if (rightOffset) { +            rightOffset += Offset; +        } +        datapos += rightsize; + +        if (flags & MT_FINAL) { +            Offsets[D_FINAL] = datapos - data; +            LeafLength = skipFunction.SkipLeaf(datapos); +        } + +        CoreLength = 2 + leftsize + rightsize + LeafLength; +        if (flags & MT_NEXT) { +            size_t& forwardOffset = Offsets[D_NEXT]; +            forwardOffset = Offset + CoreLength; +            // There might be an epsilon link at the forward position. +            // If so, set the ForwardOffset to the value that points to the link's end. +            const char* forwardPos = data + forwardOffset; +            const char forwardFlags = *forwardPos; +            if (IsEpsilonLink(forwardFlags)) { +                // Jump through the epsilon link. +                size_t epsilonOffset = UnpackOffset(forwardPos + 1, forwardFlags & MT_SIZEMASK); +                if (!epsilonOffset) { +                    ythrow yexception() << "Corrupted epsilon link"; +                } +                forwardOffset += epsilonOffset;              }          }      } -  +  } diff --git a/library/cpp/containers/comptrie/node.h b/library/cpp/containers/comptrie/node.h index 9a936998b59..d6f4317db09 100644 --- a/library/cpp/containers/comptrie/node.h +++ b/library/cpp/containers/comptrie/node.h @@ -3,78 +3,78 @@  #include <cstddef>  namespace NCompactTrie { -    class ILeafSkipper;  +    class ILeafSkipper; -    enum TDirection {  -        D_LEFT,  -        D_FINAL,  -        D_NEXT,  -        D_RIGHT,  -        D_MAX  -    };  -  -    inline TDirection& operator++(TDirection& direction) {  -        direction = static_cast<TDirection>(direction + 1);  -        return direction;  -    }  +    enum TDirection { +        D_LEFT, +        D_FINAL, +        D_NEXT, +        D_RIGHT, +        D_MAX +    }; -    inline TDirection& operator--(TDirection& direction) {  -        direction = static_cast<TDirection>(direction - 1);  -        return direction;  -    }  +    inline TDirection& operator++(TDirection& direction) { +        direction = static_cast<TDirection>(direction + 1); +        return direction; +    } -    class TNode {  -    public:  -        TNode();  -        // Processes epsilon links and sets ForwardOffset to correct value. Assumes an epsilon link doesn't point to an epsilon link.  -        TNode(const char* data, size_t offset, const ILeafSkipper& skipFunction);  +    inline TDirection& operator--(TDirection& direction) { +        direction = static_cast<TDirection>(direction - 1); +        return direction; +    } -        size_t GetOffset() const {  -            return Offset;  -        }  +    class TNode { +    public: +        TNode(); +        // Processes epsilon links and sets ForwardOffset to correct value. Assumes an epsilon link doesn't point to an epsilon link. +        TNode(const char* data, size_t offset, const ILeafSkipper& skipFunction); -        size_t GetLeafOffset() const {  -            return Offsets[D_FINAL];  -        }  -        size_t GetLeafLength() const {  -            return LeafLength;  -        }  -        size_t GetCoreLength() const {  -            return CoreLength;  -        }  +        size_t GetOffset() const { +            return Offset; +        } -        size_t GetOffsetByDirection(TDirection direction) const {  -            return Offsets[direction];  -        }  +        size_t GetLeafOffset() const { +            return Offsets[D_FINAL]; +        } +        size_t GetLeafLength() const { +            return LeafLength; +        } +        size_t GetCoreLength() const { +            return CoreLength; +        } -        size_t GetForwardOffset() const {  -            return Offsets[D_NEXT];  -        }  -        size_t GetLeftOffset() const {  -            return Offsets[D_LEFT];  -        }  -        size_t GetRightOffset() const {  -            return Offsets[D_RIGHT];  -        }  -        char GetLabel() const {  -            return Label;  -        }  +        size_t GetOffsetByDirection(TDirection direction) const { +            return Offsets[direction]; +        } -        bool IsFinal() const {  -            return GetLeafOffset() != 0;  -        }  +        size_t GetForwardOffset() const { +            return Offsets[D_NEXT]; +        } +        size_t GetLeftOffset() const { +            return Offsets[D_LEFT]; +        } +        size_t GetRightOffset() const { +            return Offsets[D_RIGHT]; +        } +        char GetLabel() const { +            return Label; +        } -        bool HasEpsilonLinkForward() const {  -            return GetForwardOffset() > Offset + CoreLength;  -        }  -  -    private:  -        size_t Offsets[D_MAX];  -        size_t Offset;  -        size_t LeafLength;  -        size_t CoreLength;  +        bool IsFinal() const { +            return GetLeafOffset() != 0; +        } -        char Label;  -    };  +        bool HasEpsilonLinkForward() const { +            return GetForwardOffset() > Offset + CoreLength; +        } -}  +    private: +        size_t Offsets[D_MAX]; +        size_t Offset; +        size_t LeafLength; +        size_t CoreLength; + +        char Label; +    }; + +} diff --git a/library/cpp/containers/comptrie/opaque_trie_iterator.cpp b/library/cpp/containers/comptrie/opaque_trie_iterator.cpp index d1916358aab..5fd3914be6e 100644 --- a/library/cpp/containers/comptrie/opaque_trie_iterator.cpp +++ b/library/cpp/containers/comptrie/opaque_trie_iterator.cpp @@ -3,229 +3,229 @@  #include "node.h"  namespace NCompactTrie { -    TOpaqueTrieIterator::TOpaqueTrieIterator(const TOpaqueTrie& trie, const char* emptyValue, bool atend,  -                                             size_t maxKeyLength)  -        : Trie(trie)  -        , EmptyValue(emptyValue)  -        , AtEmptyValue(emptyValue && !atend)  -        , MaxKeyLength(maxKeyLength)  -    {  -        if (!AtEmptyValue && !atend)  -            Forward();  -    }  - -    bool TOpaqueTrieIterator::operator==(const TOpaqueTrieIterator& rhs) const {  -        return (Trie == rhs.Trie &&  -                Forks == rhs.Forks &&  -                EmptyValue == rhs.EmptyValue &&  -                AtEmptyValue == rhs.AtEmptyValue &&  -                MaxKeyLength == rhs.MaxKeyLength);  -    }  - -    bool TOpaqueTrieIterator::HasMaxKeyLength() const {  -        return MaxKeyLength != size_t(-1) && MeasureNarrowKey() == MaxKeyLength;  -    }  - -    bool TOpaqueTrieIterator::Forward() {  -        if (AtEmptyValue) {  -            AtEmptyValue = false;  -            bool res = Forward(); // TODO delete this after format change  -            if (res && MeasureNarrowKey() != 0) {  -                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);  -        } else {  -            TFork* topFork = &Forks.Top();  -            while (!topFork->NextDirection()) {  -                if (topFork->Node.GetOffset() >= Trie.Length)  -                    return false;  -                Forks.Pop();  -                if (Forks.Empty())  -                    return false;  -                topFork = &Forks.Top();  -            }  -        } - -        Y_ASSERT(!Forks.Empty());  -        while (Forks.Top().CurrentDirection != D_FINAL && !HasMaxKeyLength()) {  -            TFork nextFork = Forks.Top().NextFork(Trie.SkipFunction);  -            Forks.Push(nextFork);  -        }  -        TFork& top = Forks.Top();  -        static_assert(D_FINAL < D_NEXT, "relative order of NEXT and FINAL directions has changed");  -        if (HasMaxKeyLength() && top.CurrentDirection == D_FINAL && top.HasDirection(D_NEXT)) {  -            top.NextDirection();  -        }  -        return true;  -    } - -    bool TOpaqueTrieIterator::Backward() {  -        if (AtEmptyValue)  +    TOpaqueTrieIterator::TOpaqueTrieIterator(const TOpaqueTrie& trie, const char* emptyValue, bool atend, +                                             size_t maxKeyLength) +        : Trie(trie) +        , EmptyValue(emptyValue) +        , AtEmptyValue(emptyValue && !atend) +        , MaxKeyLength(maxKeyLength) +    { +        if (!AtEmptyValue && !atend) +            Forward(); +    } + +    bool TOpaqueTrieIterator::operator==(const TOpaqueTrieIterator& rhs) const { +        return (Trie == rhs.Trie && +                Forks == rhs.Forks && +                EmptyValue == rhs.EmptyValue && +                AtEmptyValue == rhs.AtEmptyValue && +                MaxKeyLength == rhs.MaxKeyLength); +    } + +    bool TOpaqueTrieIterator::HasMaxKeyLength() const { +        return MaxKeyLength != size_t(-1) && MeasureNarrowKey() == MaxKeyLength; +    } + +    bool TOpaqueTrieIterator::Forward() { +        if (AtEmptyValue) { +            AtEmptyValue = false; +            bool res = Forward(); // TODO delete this after format change +            if (res && MeasureNarrowKey() != 0) { +                return res; // there was not "\0" key +            } +            // otherwise we are skipping "\0" key +        } + +        if (!Trie.Length)              return false; -        if (!Trie.Length) {  -            if (EmptyValue) {  -                // A trie that has only the empty value;  -                // we are not at the empty value, so move to it.  +        if (Forks.Empty()) { +            TFork fork(Trie.Data, 0, Trie.Length, Trie.SkipFunction); +            Forks.Push(fork); +        } else { +            TFork* topFork = &Forks.Top(); +            while (!topFork->NextDirection()) { +                if (topFork->Node.GetOffset() >= Trie.Length) +                    return false; +                Forks.Pop(); +                if (Forks.Empty()) +                    return false; +                topFork = &Forks.Top(); +            } +        } + +        Y_ASSERT(!Forks.Empty()); +        while (Forks.Top().CurrentDirection != D_FINAL && !HasMaxKeyLength()) { +            TFork nextFork = Forks.Top().NextFork(Trie.SkipFunction); +            Forks.Push(nextFork); +        } +        TFork& top = Forks.Top(); +        static_assert(D_FINAL < D_NEXT, "relative order of NEXT and FINAL directions has changed"); +        if (HasMaxKeyLength() && top.CurrentDirection == D_FINAL && top.HasDirection(D_NEXT)) { +            top.NextDirection(); +        } +        return true; +    } + +    bool TOpaqueTrieIterator::Backward() { +        if (AtEmptyValue) +            return false; + +        if (!Trie.Length) { +            if (EmptyValue) { +                // A trie that has only the empty value; +                // we are not at the empty value, so move to it.                  AtEmptyValue = true;                  return true; -            } else {  -                // Empty trie.  -                return false;  +            } else { +                // Empty trie. +                return false; +            } +        } + +        if (Forks.Empty()) { +            TFork fork(Trie.Data, 0, Trie.Length, Trie.SkipFunction); +            fork.LastDirection(); +            Forks.Push(fork); +        } else { +            TFork* topFork = &Forks.Top(); +            while (!topFork->PrevDirection()) { +                if (topFork->Node.GetOffset() >= Trie.Length) +                    return false; +                Forks.Pop(); +                if (!Forks.Empty()) { +                    topFork = &Forks.Top(); +                } else { +                    // When there are no more forks, +                    // we have to iterate over the empty value. +                    if (!EmptyValue) +                        return false; +                    AtEmptyValue = true; +                    return true; +                }              }          } -        if (Forks.Empty()) {  -            TFork fork(Trie.Data, 0, Trie.Length, Trie.SkipFunction);  -            fork.LastDirection();  -            Forks.Push(fork);  -        } else {  -            TFork* topFork = &Forks.Top();  -            while (!topFork->PrevDirection()) {  -                if (topFork->Node.GetOffset() >= Trie.Length)  -                    return false;  -                Forks.Pop();  -                if (!Forks.Empty()) {  -                    topFork = &Forks.Top();  -                } else {  -                    // When there are no more forks,  -                    // we have to iterate over the empty value.  -                    if (!EmptyValue)  -                        return false;  -                    AtEmptyValue = true;  -                    return true;  -                }  -            }  -        }  -  -        Y_ASSERT(!Forks.Empty());  -        while (Forks.Top().CurrentDirection != D_FINAL && !HasMaxKeyLength()) {  -            TFork nextFork = Forks.Top().NextFork(Trie.SkipFunction);  -            nextFork.LastDirection();  -            Forks.Push(nextFork);  -        }  -        TFork& top = Forks.Top();  -        static_assert(D_FINAL < D_NEXT, "relative order of NEXT and FINAL directions has changed");  -        if (HasMaxKeyLength() && top.CurrentDirection == D_NEXT && top.HasDirection(D_FINAL)) {  -            top.PrevDirection();  -        }  -        if (MeasureNarrowKey() == 0) {  -            // This is the '\0' key, skip it and get to the EmptyValue.  -            AtEmptyValue = true;  -            Forks.Clear();  -        }  -        return true;  -    } - -    const char* TOpaqueTrieIterator::GetValuePtr() const {  -        if (!Forks.Empty()) {  -            const TFork& lastFork = Forks.Top();  -            Y_ASSERT(lastFork.Node.IsFinal() && lastFork.CurrentDirection == D_FINAL);  -            return Trie.Data + lastFork.GetValueOffset();  -        }  -        Y_ASSERT(AtEmptyValue);  -        return EmptyValue;  -    } - -    //-------------------------------------------------------------------------  - -    TString TForkStack::GetKey() const {  -        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  -        if (TopHasLabelInKey()) {  -            return Key.size() == 0 && Top().GetLabel() == '\0';  -        } else {  -            return Key.size() == 1 && Key[0] == '\0';  -        }  -    } - -    size_t TForkStack::MeasureKey() const {  -        size_t result = Key.size() + (TopHasLabelInKey() ? 1 : 0);  -        if (result == 1 && HasEmptyKey()) {  -            return 0;  -        }  -        return result;  -    } - -    //-------------------------------------------------------------------------  - -    TFork::TFork(const char* data, size_t offset, size_t limit, const ILeafSkipper& skipper)  -        : Node(data, offset, skipper)  -        , Data(data)  -        , Limit(limit)  -        , CurrentDirection(TDirection(0))  -    {  +        Y_ASSERT(!Forks.Empty()); +        while (Forks.Top().CurrentDirection != D_FINAL && !HasMaxKeyLength()) { +            TFork nextFork = Forks.Top().NextFork(Trie.SkipFunction); +            nextFork.LastDirection(); +            Forks.Push(nextFork); +        } +        TFork& top = Forks.Top(); +        static_assert(D_FINAL < D_NEXT, "relative order of NEXT and FINAL directions has changed"); +        if (HasMaxKeyLength() && top.CurrentDirection == D_NEXT && top.HasDirection(D_FINAL)) { +            top.PrevDirection(); +        } +        if (MeasureNarrowKey() == 0) { +            // This is the '\0' key, skip it and get to the EmptyValue. +            AtEmptyValue = true; +            Forks.Clear(); +        } +        return true; +    } + +    const char* TOpaqueTrieIterator::GetValuePtr() const { +        if (!Forks.Empty()) { +            const TFork& lastFork = Forks.Top(); +            Y_ASSERT(lastFork.Node.IsFinal() && lastFork.CurrentDirection == D_FINAL); +            return Trie.Data + lastFork.GetValueOffset(); +        } +        Y_ASSERT(AtEmptyValue); +        return EmptyValue; +    } + +    //------------------------------------------------------------------------- + +    TString TForkStack::GetKey() const { +        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 +        if (TopHasLabelInKey()) { +            return Key.size() == 0 && Top().GetLabel() == '\0'; +        } else { +            return Key.size() == 1 && Key[0] == '\0'; +        } +    } + +    size_t TForkStack::MeasureKey() const { +        size_t result = Key.size() + (TopHasLabelInKey() ? 1 : 0); +        if (result == 1 && HasEmptyKey()) { +            return 0; +        } +        return result; +    } + +    //------------------------------------------------------------------------- + +    TFork::TFork(const char* data, size_t offset, size_t limit, const ILeafSkipper& skipper) +        : Node(data, offset, skipper) +        , Data(data) +        , Limit(limit) +        , CurrentDirection(TDirection(0)) +    {  #if COMPTRIE_DATA_CHECK -        if (Node.GetOffset() >= Limit - 1)  -            ythrow yexception() << "gone beyond the limit, data is corrupted";  +        if (Node.GetOffset() >= Limit - 1) +            ythrow yexception() << "gone beyond the limit, data is corrupted";  #endif -        while (CurrentDirection < D_MAX && !HasDirection(CurrentDirection)) {  -            ++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;  -        }  -        do {  -            --CurrentDirection;  -        } while (CurrentDirection > 0 && !HasDirection(CurrentDirection));  -        return HasDirection(CurrentDirection);  -    }  - -    void TFork::LastDirection() {  -        CurrentDirection = D_MAX;  -        PrevDirection();  -    } - -    bool TFork::SetDirection(TDirection direction) {  -        if (!HasDirection(direction)) {  -            return false;  -        }  -        CurrentDirection = direction;  -        return true;  -    }  - -    char TFork::GetLabel() const {  -        return Node.GetLabel();  -    }  - -    size_t TFork::GetValueOffset() const {  -        return Node.GetLeafOffset();  +        while (CurrentDirection < D_MAX && !HasDirection(CurrentDirection)) { +            ++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; +        } +        do { +            --CurrentDirection; +        } while (CurrentDirection > 0 && !HasDirection(CurrentDirection)); +        return HasDirection(CurrentDirection); +    } + +    void TFork::LastDirection() { +        CurrentDirection = D_MAX; +        PrevDirection(); +    } + +    bool TFork::SetDirection(TDirection direction) { +        if (!HasDirection(direction)) { +            return false; +        } +        CurrentDirection = direction; +        return true; +    } + +    char TFork::GetLabel() const { +        return Node.GetLabel(); +    } + +    size_t TFork::GetValueOffset() const { +        return Node.GetLeafOffset();      }  } diff --git a/library/cpp/containers/comptrie/opaque_trie_iterator.h b/library/cpp/containers/comptrie/opaque_trie_iterator.h index 8e615d7e707..195da3c1918 100644 --- a/library/cpp/containers/comptrie/opaque_trie_iterator.h +++ b/library/cpp/containers/comptrie/opaque_trie_iterator.h @@ -9,258 +9,258 @@  #include <util/generic/yexception.h>  namespace NCompactTrie { -    class ILeafSkipper;  - -    class TFork { // Auxiliary class for a branching point in the iterator  -    public:  -        TNode Node;  -        const char* Data;  -        size_t Limit; // valid data is in range [Data + Node.GetOffset(), Data + Limit)  -        TDirection CurrentDirection;  - -    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();  - -        bool HasDirection(TDirection direction) const {  -            return Node.GetOffsetByDirection(direction);  -        }  -        // If the fork doesn't have the specified direction,  -        // leaves the direction intact and returns false.  -        // Otherwise returns true.  -        bool SetDirection(TDirection direction);  -        TFork NextFork(const ILeafSkipper& skipper) const;  - -        char GetLabel() const;  -        size_t GetValueOffset() const;  -    };  -  -    inline TFork TFork::NextFork(const ILeafSkipper& skipper) const {  -        Y_ASSERT(CurrentDirection != D_FINAL);  -        size_t offset = Node.GetOffsetByDirection(CurrentDirection);  -        return TFork(Data, offset, Limit, skipper);  +    class ILeafSkipper; + +    class TFork { // Auxiliary class for a branching point in the iterator +    public: +        TNode Node; +        const char* Data; +        size_t Limit; // valid data is in range [Data + Node.GetOffset(), Data + Limit) +        TDirection CurrentDirection; + +    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(); + +        bool HasDirection(TDirection direction) const { +            return Node.GetOffsetByDirection(direction); +        } +        // If the fork doesn't have the specified direction, +        // leaves the direction intact and returns false. +        // Otherwise returns true. +        bool SetDirection(TDirection direction); +        TFork NextFork(const ILeafSkipper& skipper) const; + +        char GetLabel() const; +        size_t GetValueOffset() const; +    }; + +    inline TFork TFork::NextFork(const ILeafSkipper& skipper) const { +        Y_ASSERT(CurrentDirection != D_FINAL); +        size_t offset = Node.GetOffsetByDirection(CurrentDirection); +        return TFork(Data, offset, Limit, skipper);      } -    //------------------------------------------------------------------------------------------------  -    class TForkStack {  -    public:  -        void Push(const TFork& fork) {  -            if (TopHasLabelInKey()) {  -                Key.push_back(Top().GetLabel());  -            }  -            Forks.push_back(fork);  -        }  - -        void Pop() {  -            Forks.pop_back();  -            if (TopHasLabelInKey()) {  -                Key.pop_back();  -            }  -        }  - -        TFork& Top() {  -            return Forks.back();  +    //------------------------------------------------------------------------------------------------ +    class TForkStack { +    public: +        void Push(const TFork& fork) { +            if (TopHasLabelInKey()) { +                Key.push_back(Top().GetLabel()); +            } +            Forks.push_back(fork); +        } + +        void Pop() { +            Forks.pop_back(); +            if (TopHasLabelInKey()) { +                Key.pop_back(); +            } +        } + +        TFork& Top() { +            return Forks.back(); +        } +        const TFork& Top() const { +            return Forks.back(); +        } + +        bool Empty() const { +            return Forks.empty(); +        } + +        void Clear() { +            Forks.clear(); +            Key.clear(); +        } + +        bool operator==(const TForkStack& other) const { +            return Forks == other.Forks; +        } +        bool operator!=(const TForkStack& other) const { +            return !(*this == other); +        } + +        TString GetKey() const; +        size_t MeasureKey() const; + +    private: +        TVector<TFork> Forks; +        TString Key; + +    private: +        bool TopHasLabelInKey() const { +            return !Empty() && Top().HasLabelInKey(); +        } +        bool HasEmptyKey() const; +    }; + +    //------------------------------------------------------------------------------------------------ + +    template <class TSymbol> +    struct TConvertRawKey { +        typedef typename TCompactTrieKeySelector<TSymbol>::TKey TKey; +        static TKey Get(const TString& rawkey) { +            TKey result; +            const size_t sz = rawkey.size(); +            result.reserve(sz / sizeof(TSymbol)); +            for (size_t i = 0; i < sz; i += sizeof(TSymbol)) { +                TSymbol sym = 0; +                for (size_t j = 0; j < sizeof(TSymbol); j++) { +                    if (sizeof(TSymbol) <= 1) +                        sym = 0; +                    else +                        sym <<= 8; +                    if (i + j < sz) +                        sym |= TSymbol(0x00FF & rawkey[i + j]); +                } +                result.push_back(sym); +            } +            return result; +        } + +        static size_t Size(size_t rawsize) { +            return rawsize / sizeof(TSymbol); +        } +    }; + +    template <> +    struct TConvertRawKey<char> { +        static TString Get(const TString& rawkey) { +            return rawkey;          } -        const TFork& Top() const {  -            return Forks.back();  -        }  -        bool Empty() const {  -            return Forks.empty();  -        }  +        static size_t Size(size_t rawsize) { +            return rawsize; +        } +    }; + +    //------------------------------------------------------------------------------------------------ +    class TOpaqueTrieIterator { // Iterator stuff. Stores a stack of visited forks. +    public: +        TOpaqueTrieIterator(const TOpaqueTrie& trie, const char* emptyValue, bool atend, +                            size_t maxKeyLength = size_t(-1)); + +        bool operator==(const TOpaqueTrieIterator& rhs) const; +        bool operator!=(const TOpaqueTrieIterator& rhs) const { +            return !(*this == rhs); +        } + +        bool Forward(); +        bool Backward(); + +        template <class TSymbol> +        bool UpperBound(const typename TCompactTrieKeySelector<TSymbol>::TKeyBuf& key); // True if matched exactly. -        void Clear() {  -            Forks.clear();  -            Key.clear();  +        template <class TSymbol> +        typename TCompactTrieKeySelector<TSymbol>::TKey GetKey() const { +            return TConvertRawKey<TSymbol>::Get(GetNarrowKey());          } -        bool operator==(const TForkStack& other) const {  -            return Forks == other.Forks;  -        }  -        bool operator!=(const TForkStack& other) const {  -            return !(*this == other);  -        }  - -        TString GetKey() const;  -        size_t MeasureKey() const;  - -    private:  -        TVector<TFork> Forks;  -        TString Key;  - -    private:  -        bool TopHasLabelInKey() const {  -            return !Empty() && Top().HasLabelInKey();  -        }  -        bool HasEmptyKey() const;  -    };  - -    //------------------------------------------------------------------------------------------------  - -    template <class TSymbol>  -    struct TConvertRawKey {  -        typedef typename TCompactTrieKeySelector<TSymbol>::TKey TKey;  -        static TKey Get(const TString& rawkey) {  -            TKey result;  -            const size_t sz = rawkey.size();  -            result.reserve(sz / sizeof(TSymbol));  -            for (size_t i = 0; i < sz; i += sizeof(TSymbol)) {  -                TSymbol sym = 0;  -                for (size_t j = 0; j < sizeof(TSymbol); j++) {  -                    if (sizeof(TSymbol) <= 1)  -                        sym = 0;  -                    else  -                        sym <<= 8;  -                    if (i + j < sz)  -                        sym |= TSymbol(0x00FF & rawkey[i + j]);  -                }  -                result.push_back(sym);  -            }  -            return result;  -        }  - -        static size_t Size(size_t rawsize) {  -            return rawsize / sizeof(TSymbol);  -        }  -    };  - -    template <>  -    struct TConvertRawKey<char> {  -        static TString Get(const TString& rawkey) {  -            return rawkey;  -        }  - -        static size_t Size(size_t rawsize) {  -            return rawsize;  +        template <class TSymbol> +        size_t MeasureKey() const { +            return TConvertRawKey<TSymbol>::Size(MeasureNarrowKey());          } -    };  - -    //------------------------------------------------------------------------------------------------  -    class TOpaqueTrieIterator { // Iterator stuff. Stores a stack of visited forks.  -    public:  -        TOpaqueTrieIterator(const TOpaqueTrie& trie, const char* emptyValue, bool atend,  -                            size_t maxKeyLength = size_t(-1));  - -        bool operator==(const TOpaqueTrieIterator& rhs) const;  -        bool operator!=(const TOpaqueTrieIterator& rhs) const {  -            return !(*this == rhs);  -        }  - -        bool Forward();  -        bool Backward();  - -        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;  -        }  -        const TOpaqueTrie& GetTrie() const {  -            return Trie;  -        }  - -    private:  -        TOpaqueTrie Trie;  -        TForkStack Forks;  -        const char* const EmptyValue;  -        bool AtEmptyValue;  -        const size_t MaxKeyLength;  - -    private:  -        bool HasMaxKeyLength() const;  - -        template <class TSymbol>  -        int LongestPrefix(const typename TCompactTrieKeySelector<TSymbol>::TKeyBuf& key); // Used in UpperBound.  -    };  + +        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; +        } +        const TOpaqueTrie& GetTrie() const { +            return Trie; +        } + +    private: +        TOpaqueTrie Trie; +        TForkStack Forks; +        const char* const EmptyValue; +        bool AtEmptyValue; +        const size_t MaxKeyLength; + +    private: +        bool HasMaxKeyLength() const; + +        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();  -        TFork next(Trie.Data, 0, Trie.Length, Trie.SkipFunction);  -        for (size_t i = 0; i < key.size(); i++) {  -            TSymbol symbol = key[i];  -            const bool isLastSymbol = (i + 1 == key.size());  -            for (i64 shift = (i64)NCompactTrie::ExtraBits<TSymbol>(); shift >= 0; shift -= 8) {  -                const unsigned char label = (unsigned char)(symbol >> shift);  -                const bool isLastByte = (isLastSymbol && shift == 0);  -                do {  -                    Forks.Push(next);  -                    TFork& top = Forks.Top();  -                    if (label < (unsigned char)top.GetLabel()) {  -                        if (!top.SetDirection(D_LEFT))  -                            return 1;  -                    } else if (label > (unsigned char)top.GetLabel()) {  -                        if (!top.SetDirection(D_RIGHT)) {  -                            Forks.Pop(); // We don't pass this fork on the way to the upper bound.  -                            return -1;  -                        }  -                    } else if (isLastByte) { // Here and below label == top.GetLabel().  -                        if (top.SetDirection(D_FINAL)) {  -                            return 0; // Skip the NextFork() call at the end of the cycle.  -                        } else {  -                            top.SetDirection(D_NEXT);  -                            return 1;  -                        }  -                    } else if (!top.SetDirection(D_NEXT)) {  -                        top.SetDirection(D_FINAL);  +    int TOpaqueTrieIterator::LongestPrefix(const typename TCompactTrieKeySelector<TSymbol>::TKeyBuf& key) { +        Forks.Clear(); +        TFork next(Trie.Data, 0, Trie.Length, Trie.SkipFunction); +        for (size_t i = 0; i < key.size(); i++) { +            TSymbol symbol = key[i]; +            const bool isLastSymbol = (i + 1 == key.size()); +            for (i64 shift = (i64)NCompactTrie::ExtraBits<TSymbol>(); shift >= 0; shift -= 8) { +                const unsigned char label = (unsigned char)(symbol >> shift); +                const bool isLastByte = (isLastSymbol && shift == 0); +                do { +                    Forks.Push(next); +                    TFork& top = Forks.Top(); +                    if (label < (unsigned char)top.GetLabel()) { +                        if (!top.SetDirection(D_LEFT)) +                            return 1; +                    } else if (label > (unsigned char)top.GetLabel()) { +                        if (!top.SetDirection(D_RIGHT)) { +                            Forks.Pop(); // We don't pass this fork on the way to the upper bound. +                            return -1; +                        } +                    } else if (isLastByte) { // Here and below label == top.GetLabel(). +                        if (top.SetDirection(D_FINAL)) { +                            return 0; // Skip the NextFork() call at the end of the cycle. +                        } else { +                            top.SetDirection(D_NEXT); +                            return 1; +                        } +                    } else if (!top.SetDirection(D_NEXT)) { +                        top.SetDirection(D_FINAL);                          return -1;                      } -                    next = top.NextFork(Trie.SkipFunction);  -                } while (Forks.Top().CurrentDirection != D_NEXT); // Proceed to the next byte.  -            }  +                    next = top.NextFork(Trie.SkipFunction); +                } while (Forks.Top().CurrentDirection != D_NEXT); // Proceed to the next byte. +            }          } -        // We get here only if the key was empty.  -        Forks.Push(next);  -        return 1;  +        // We get here only if the key was empty. +        Forks.Push(next); +        return 1;      } -    template <class TSymbol>  -    bool TOpaqueTrieIterator::UpperBound(const typename TCompactTrieKeySelector<TSymbol>::TKeyBuf& key) {  -        Forks.Clear();  -        if (key.empty() && EmptyValue) {  -            AtEmptyValue = true;  -            return true;  -        } else {  -            AtEmptyValue = false;  +    template <class TSymbol> +    bool TOpaqueTrieIterator::UpperBound(const typename TCompactTrieKeySelector<TSymbol>::TKeyBuf& key) { +        Forks.Clear(); +        if (key.empty() && EmptyValue) { +            AtEmptyValue = true; +            return true; +        } else { +            AtEmptyValue = false; +        } +        const int defect = LongestPrefix<TSymbol>(key); +        if (defect > 0) { +            // Continue the constructed forks with the smallest key possible. +            while (Forks.Top().CurrentDirection != D_FINAL) { +                TFork next = Forks.Top().NextFork(Trie.SkipFunction); +                Forks.Push(next); +            } +        } else if (defect < 0) { +            Forward();          } -        const int defect = LongestPrefix<TSymbol>(key);  -        if (defect > 0) {  -            // Continue the constructed forks with the smallest key possible.  -            while (Forks.Top().CurrentDirection != D_FINAL) {  -                TFork next = Forks.Top().NextFork(Trie.SkipFunction);  -                Forks.Push(next);  -            }  -        } else if (defect < 0) {  -            Forward();  -        }  -        return defect == 0;  +        return defect == 0;      } -  +  } diff --git a/library/cpp/containers/comptrie/prefix_iterator.h b/library/cpp/containers/comptrie/prefix_iterator.h index eb2b2d6878b..b369bb4f425 100644 --- a/library/cpp/containers/comptrie/prefix_iterator.h +++ b/library/cpp/containers/comptrie/prefix_iterator.h @@ -1,5 +1,5 @@  #pragma once -  +  #include "comptrie_trie.h"  // Iterates over all prefixes of the given key in the trie. @@ -39,11 +39,11 @@ public:          result = Next();      } -    operator bool() const {  +    operator bool() const {          return result;      } -    TPrefixIterator& operator++() {  +    TPrefixIterator& operator++() {          result = Next();          return *this;      } diff --git a/library/cpp/containers/comptrie/protopacker.h b/library/cpp/containers/comptrie/protopacker.h index 5bedde270d2..3e15866dc54 100644 --- a/library/cpp/containers/comptrie/protopacker.h +++ b/library/cpp/containers/comptrie/protopacker.h @@ -3,7 +3,7 @@  #include <util/stream/mem.h>  #include <util/ysaveload.h> -template <class Proto>  +template <class Proto>  class TProtoPacker {  public:      TProtoPacker() = default; diff --git a/library/cpp/containers/comptrie/search_iterator.h b/library/cpp/containers/comptrie/search_iterator.h index ad6bcfdf60e..247f7e59363 100644 --- a/library/cpp/containers/comptrie/search_iterator.h +++ b/library/cpp/containers/comptrie/search_iterator.h @@ -1,5 +1,5 @@  #pragma once -  +  #include "comptrie_trie.h"  #include "first_symbol_iterator.h" @@ -74,7 +74,7 @@ private:      const char* ValuePos = nullptr;  }; -template <class TTrie>  +template <class TTrie>  inline TSearchIterator<TTrie> MakeSearchIterator(const TTrie& trie) {      return TSearchIterator<TTrie>(trie);  } diff --git a/library/cpp/containers/comptrie/set.h b/library/cpp/containers/comptrie/set.h index ffea92485c6..acd43338f0a 100644 --- a/library/cpp/containers/comptrie/set.h +++ b/library/cpp/containers/comptrie/set.h @@ -1,16 +1,16 @@ -#pragma once  -  +#pragma once +  #include "comptrie_trie.h"  template <typename T = char> -class TCompactTrieSet: public TCompactTrie<T, ui8, TNullPacker<ui8>> {  +class TCompactTrieSet: public TCompactTrie<T, ui8, TNullPacker<ui8>> {  public: -    typedef TCompactTrie<T, ui8, TNullPacker<ui8>> TBase;  +    typedef TCompactTrie<T, ui8, TNullPacker<ui8>> TBase; -    using typename TBase::TBuilder;  +    using typename TBase::TBuilder;      using typename TBase::TKey;      using typename TBase::TKeyBuf; -    using typename TBase::TSymbol;  +    using typename TBase::TSymbol;      TCompactTrieSet() = default; @@ -20,8 +20,8 @@ public:      }      template <typename D> -    explicit TCompactTrieSet(const TCompactTrie<T, D, TNullPacker<D>>& trie)  -        : TBase(trie.Data()) // should be binary compatible for any D  +    explicit TCompactTrieSet(const TCompactTrie<T, D, TNullPacker<D>>& trie) +        : TBase(trie.Data()) // should be binary compatible for any D      {      } diff --git a/library/cpp/containers/comptrie/write_trie_backwards.cpp b/library/cpp/containers/comptrie/write_trie_backwards.cpp index f7459b1c497..fd8c28b0ed9 100644 --- a/library/cpp/containers/comptrie/write_trie_backwards.cpp +++ b/library/cpp/containers/comptrie/write_trie_backwards.cpp @@ -7,104 +7,104 @@  #include <util/generic/vector.h>  namespace NCompactTrie { -    size_t WriteTrieBackwards(IOutputStream& os, TReverseNodeEnumerator& enumerator, bool verbose) {  -        if (verbose) {  -            Cerr << "Writing down the trie..." << Endl;  -        }  - -        // Rewrite everything from the back, removing unused pieces.  -        const size_t chunksize = 0x10000;  -        TVector<char*> resultData;  - -        resultData.push_back(new char[chunksize]);  -        char* chunkend = resultData.back() + chunksize;  - -        size_t resultLength = 0;  -        size_t chunkLength = 0;  - -        size_t counter = 0;  -        TBuffer bufferHolder;  -        while (enumerator.Move()) {  -            if (verbose)  -                ShowProgress(++counter);  - -            size_t bufferLength = 64 + enumerator.GetLeafLength(); // never know how big leaf data can be  -            bufferHolder.Clear();  -            bufferHolder.Resize(bufferLength);  -            char* buffer = bufferHolder.Data();  -  -            size_t nodelength = enumerator.RecreateNode(buffer, resultLength);  -            Y_ASSERT(nodelength <= bufferLength);  - -            resultLength += nodelength;  - -            if (chunkLength + nodelength <= chunksize) {  -                chunkLength += nodelength;  -                memcpy(chunkend - chunkLength, buffer, nodelength);  -            } else { // allocate a new chunk  -                memcpy(chunkend - chunksize, buffer + nodelength - (chunksize - chunkLength), chunksize - chunkLength);  -                chunkLength = chunkLength + nodelength - chunksize;  - -                resultData.push_back(new char[chunksize]);  -                chunkend = resultData.back() + chunksize;  - -                while (chunkLength > chunksize) { // allocate a new chunks  -                    chunkLength -= chunksize;  -                    memcpy(chunkend - chunksize, buffer + chunkLength, chunksize);  - -                    resultData.push_back(new char[chunksize]);  -                    chunkend = resultData.back() + chunksize;  -                }  - -                memcpy(chunkend - chunkLength, buffer, chunkLength);  +    size_t WriteTrieBackwards(IOutputStream& os, TReverseNodeEnumerator& enumerator, bool verbose) { +        if (verbose) { +            Cerr << "Writing down the trie..." << Endl; +        } + +        // Rewrite everything from the back, removing unused pieces. +        const size_t chunksize = 0x10000; +        TVector<char*> resultData; + +        resultData.push_back(new char[chunksize]); +        char* chunkend = resultData.back() + chunksize; + +        size_t resultLength = 0; +        size_t chunkLength = 0; + +        size_t counter = 0; +        TBuffer bufferHolder; +        while (enumerator.Move()) { +            if (verbose) +                ShowProgress(++counter); + +            size_t bufferLength = 64 + enumerator.GetLeafLength(); // never know how big leaf data can be +            bufferHolder.Clear(); +            bufferHolder.Resize(bufferLength); +            char* buffer = bufferHolder.Data(); + +            size_t nodelength = enumerator.RecreateNode(buffer, resultLength); +            Y_ASSERT(nodelength <= bufferLength); + +            resultLength += nodelength; + +            if (chunkLength + nodelength <= chunksize) { +                chunkLength += nodelength; +                memcpy(chunkend - chunkLength, buffer, nodelength); +            } else { // allocate a new chunk +                memcpy(chunkend - chunksize, buffer + nodelength - (chunksize - chunkLength), chunksize - chunkLength); +                chunkLength = chunkLength + nodelength - chunksize; + +                resultData.push_back(new char[chunksize]); +                chunkend = resultData.back() + chunksize; + +                while (chunkLength > chunksize) { // allocate a new chunks +                    chunkLength -= chunksize; +                    memcpy(chunkend - chunksize, buffer + chunkLength, chunksize); + +                    resultData.push_back(new char[chunksize]); +                    chunkend = resultData.back() + chunksize; +                } + +                memcpy(chunkend - chunkLength, buffer, chunkLength);              } -        }  - -        if (verbose)  -            Cerr << counter << Endl;  -  -        // Write the whole thing down  -        while (!resultData.empty()) {  -            char* chunk = resultData.back();  -            os.Write(chunk + chunksize - chunkLength, chunkLength);  -            chunkLength = chunksize;  -            delete[] chunk;  -            resultData.pop_back();           } -  -        return resultLength;  + +        if (verbose) +            Cerr << counter << Endl; + +        // Write the whole thing down +        while (!resultData.empty()) { +            char* chunk = resultData.back(); +            os.Write(chunk + chunksize - chunkLength, chunkLength); +            chunkLength = chunksize; +            delete[] chunk; +            resultData.pop_back(); +        } + +        return resultLength;      } -    size_t WriteTrieBackwardsNoAlloc(IOutputStream& os, TReverseNodeEnumerator& enumerator, TOpaqueTrie& trie, EMinimizeMode mode) {  -        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);  -            if (nodeLength > buf.size())  -                buf.resize(nodeLength);  - -            size_t realLength = enumerator.RecreateNode(buf.data(), end - pos);  -            Y_ASSERT(realLength == nodeLength);  - -            pos -= nodeLength;  -            memcpy(pos, buf.data(), nodeLength);  -        }  - -        switch (mode) {  -            case MM_NOALLOC:  -                os.Write(pos, end - pos);  -                break;  -            case MM_INPLACE:  -                memmove(data, pos, end - pos);  -                break;  -            default:  -                Y_VERIFY(false);  -        }  - -        return end - pos;  +    size_t WriteTrieBackwardsNoAlloc(IOutputStream& os, TReverseNodeEnumerator& enumerator, TOpaqueTrie& trie, EMinimizeMode mode) { +        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); +            if (nodeLength > buf.size()) +                buf.resize(nodeLength); + +            size_t realLength = enumerator.RecreateNode(buf.data(), end - pos); +            Y_ASSERT(realLength == nodeLength); + +            pos -= nodeLength; +            memcpy(pos, buf.data(), nodeLength); +        } + +        switch (mode) { +            case MM_NOALLOC: +                os.Write(pos, end - pos); +                break; +            case MM_INPLACE: +                memmove(data, pos, end - pos); +                break; +            default: +                Y_VERIFY(false); +        } + +        return end - pos;      }  } diff --git a/library/cpp/containers/comptrie/writeable_node.cpp b/library/cpp/containers/comptrie/writeable_node.cpp index d0e986f99a0..404003dbbd2 100644 --- a/library/cpp/containers/comptrie/writeable_node.cpp +++ b/library/cpp/containers/comptrie/writeable_node.cpp @@ -3,94 +3,94 @@  #include "comptrie_impl.h"  namespace NCompactTrie { -    TWriteableNode::TWriteableNode()  -        : LeafPos(nullptr)  -        , LeafLength(0)  -        , ForwardOffset(NPOS)  -        , LeftOffset(NPOS)  -        , RightOffset(NPOS)  -        , Label(0)  -    {  -    }  +    TWriteableNode::TWriteableNode() +        : LeafPos(nullptr) +        , LeafLength(0) +        , ForwardOffset(NPOS) +        , LeftOffset(NPOS) +        , RightOffset(NPOS) +        , Label(0) +    { +    } + +    static size_t GetOffsetFromEnd(const TNode& node, size_t absOffset) { +        return absOffset ? absOffset - node.GetOffset() - node.GetCoreLength() : NPOS; +    } -    static size_t GetOffsetFromEnd(const TNode& node, size_t absOffset) {  -        return absOffset ? absOffset - node.GetOffset() - node.GetCoreLength() : NPOS;  -    }  -  -    TWriteableNode::TWriteableNode(const TNode& node, const char* data)  -        : LeafPos(node.IsFinal() ? data + node.GetLeafOffset() : nullptr)  -        , LeafLength(node.GetLeafLength())  -        , ForwardOffset(GetOffsetFromEnd(node, node.GetForwardOffset()))  -        , LeftOffset(GetOffsetFromEnd(node, node.GetLeftOffset()))  -        , RightOffset(GetOffsetFromEnd(node, node.GetRightOffset()))  -        , Label(node.GetLabel())  -    {  -    }  +    TWriteableNode::TWriteableNode(const TNode& node, const char* data) +        : LeafPos(node.IsFinal() ? data + node.GetLeafOffset() : nullptr) +        , LeafLength(node.GetLeafLength()) +        , ForwardOffset(GetOffsetFromEnd(node, node.GetForwardOffset())) +        , LeftOffset(GetOffsetFromEnd(node, node.GetLeftOffset())) +        , RightOffset(GetOffsetFromEnd(node, node.GetRightOffset())) +        , Label(node.GetLabel()) +    { +    } -    size_t TWriteableNode::Measure() const {  -        size_t len = 2 + LeafLength;  -        size_t fwdLen = 0;  -        size_t lastLen = 0;  -        size_t lastFwdLen = 0;  -        // Now, increase all the offsets by the length and recalculate everything, until it converges  -        do {  -            lastLen = len;  -            lastFwdLen = fwdLen;  +    size_t TWriteableNode::Measure() const { +        size_t len = 2 + LeafLength; +        size_t fwdLen = 0; +        size_t lastLen = 0; +        size_t lastFwdLen = 0; +        // Now, increase all the offsets by the length and recalculate everything, until it converges +        do { +            lastLen = len; +            lastFwdLen = fwdLen; -            len = 2 + LeafLength;  -            len += MeasureOffset(LeftOffset != NPOS ? LeftOffset + lastLen : 0);  -            len += MeasureOffset(RightOffset != NPOS ? RightOffset + lastLen : 0);  -  -            // Relative forward offset of 0 means we don't need extra length for an epsilon link.  -            // But an epsilon link means we need an extra 1 for the flags and the forward offset is measured  -            // from the start of the epsilon link, not from the start of our node.  -            if (ForwardOffset != NPOS && ForwardOffset != 0) {  -                fwdLen = MeasureOffset(ForwardOffset + lastFwdLen) + 1;  -                len += fwdLen;  -            }  +            len = 2 + LeafLength; +            len += MeasureOffset(LeftOffset != NPOS ? LeftOffset + lastLen : 0); +            len += MeasureOffset(RightOffset != NPOS ? RightOffset + lastLen : 0); -        } while (lastLen != len || lastFwdLen != fwdLen);  +            // Relative forward offset of 0 means we don't need extra length for an epsilon link. +            // But an epsilon link means we need an extra 1 for the flags and the forward offset is measured +            // from the start of the epsilon link, not from the start of our node. +            if (ForwardOffset != NPOS && ForwardOffset != 0) { +                fwdLen = MeasureOffset(ForwardOffset + lastFwdLen) + 1; +                len += fwdLen; +            } + +        } while (lastLen != len || lastFwdLen != fwdLen); + +        return len; +    } -        return len;  -    }  +    size_t TWriteableNode::Pack(char* buffer) const { +        const size_t length = Measure(); -    size_t TWriteableNode::Pack(char* buffer) const {  -        const size_t length = Measure();  +        char flags = 0; +        if (LeafPos) { +            flags |= MT_FINAL; +        } +        if (ForwardOffset != NPOS) { +            flags |= MT_NEXT; +        } -        char flags = 0;  -        if (LeafPos) {  -            flags |= MT_FINAL;  -        }  -        if (ForwardOffset != NPOS) {  -            flags |= MT_NEXT;  -        }  +        const size_t leftOffset = LeftOffset != NPOS ? LeftOffset + length : 0; +        const size_t rightOffset = RightOffset != NPOS ? RightOffset + length : 0; +        const size_t leftOffsetSize = MeasureOffset(leftOffset); +        const size_t rightOffsetSize = MeasureOffset(rightOffset); +        flags |= (leftOffsetSize << MT_LEFTSHIFT); +        flags |= (rightOffsetSize << MT_RIGHTSHIFT); -        const size_t leftOffset = LeftOffset != NPOS ? LeftOffset + length : 0;  -        const size_t rightOffset = RightOffset != NPOS ? RightOffset + length : 0;  -        const size_t leftOffsetSize = MeasureOffset(leftOffset);  -        const size_t rightOffsetSize = MeasureOffset(rightOffset);  -        flags |= (leftOffsetSize << MT_LEFTSHIFT);  -        flags |= (rightOffsetSize << MT_RIGHTSHIFT);  +        buffer[0] = flags; +        buffer[1] = Label; +        size_t usedLen = 2; +        usedLen += PackOffset(buffer + usedLen, leftOffset); +        usedLen += PackOffset(buffer + usedLen, rightOffset); -        buffer[0] = flags;  -        buffer[1] = Label;  -        size_t usedLen = 2;  -        usedLen += PackOffset(buffer + usedLen, leftOffset);  -        usedLen += PackOffset(buffer + usedLen, rightOffset);  +        if (LeafPos && LeafLength) { +            memcpy(buffer + usedLen, LeafPos, LeafLength); +            usedLen += LeafLength; +        } -        if (LeafPos && LeafLength) {  -            memcpy(buffer + usedLen, LeafPos, LeafLength);  -            usedLen += LeafLength;  -        }  -  -        if (ForwardOffset != NPOS && ForwardOffset != 0) {  -            const size_t fwdOffset = ForwardOffset + length - usedLen;  -            size_t fwdOffsetSize = MeasureOffset(fwdOffset);  -            buffer[usedLen++] = (char)(fwdOffsetSize & MT_SIZEMASK);  -            usedLen += PackOffset(buffer + usedLen, fwdOffset);  -        }  -        Y_ASSERT(usedLen == length);  -        return usedLen;  +        if (ForwardOffset != NPOS && ForwardOffset != 0) { +            const size_t fwdOffset = ForwardOffset + length - usedLen; +            size_t fwdOffsetSize = MeasureOffset(fwdOffset); +            buffer[usedLen++] = (char)(fwdOffsetSize & MT_SIZEMASK); +            usedLen += PackOffset(buffer + usedLen, fwdOffset); +        } +        Y_ASSERT(usedLen == length); +        return usedLen;      }  } diff --git a/library/cpp/containers/comptrie/writeable_node.h b/library/cpp/containers/comptrie/writeable_node.h index 585ef0a5e4c..5454e579ef0 100644 --- a/library/cpp/containers/comptrie/writeable_node.h +++ b/library/cpp/containers/comptrie/writeable_node.h @@ -3,24 +3,24 @@  #include <cstddef>  namespace NCompactTrie { -    class TNode;  +    class TNode; -    class TWriteableNode {  -    public:  -        const char* LeafPos;  -        size_t LeafLength;  +    class TWriteableNode { +    public: +        const char* LeafPos; +        size_t LeafLength; -        size_t ForwardOffset;  -        size_t LeftOffset;  -        size_t RightOffset;  -        char Label;  +        size_t ForwardOffset; +        size_t LeftOffset; +        size_t RightOffset; +        char Label; -        TWriteableNode();  -        TWriteableNode(const TNode& node, const char* data);  +        TWriteableNode(); +        TWriteableNode(const TNode& node, const char* data); -        // When you call this, the offsets should be relative to the end of the node. Use NPOS to indicate an absent offset.  -        size_t Pack(char* buffer) const;  -        size_t Measure() const;  -    };  +        // When you call this, the offsets should be relative to the end of the node. Use NPOS to indicate an absent offset. +        size_t Pack(char* buffer) const; +        size_t Measure() const; +    };  } diff --git a/library/cpp/containers/comptrie/ya.make b/library/cpp/containers/comptrie/ya.make index 43d6534634d..81352da4b25 100644 --- a/library/cpp/containers/comptrie/ya.make +++ b/library/cpp/containers/comptrie/ya.make @@ -1,4 +1,4 @@ -LIBRARY()  +LIBRARY()  OWNER(velavokr) @@ -12,9 +12,9 @@ SRCS(      key_selector.h      leaf_skipper.h      set.h -    comptrie.cpp  +    comptrie.cpp      comptrie_builder.cpp -    comptrie_impl.cpp  +    comptrie_impl.cpp      make_fast_layout.cpp      minimize.cpp      node.cpp diff --git a/library/cpp/containers/intrusive_avl_tree/avltree.cpp b/library/cpp/containers/intrusive_avl_tree/avltree.cpp index 05cbea330c6..dd27c7df419 100644 --- a/library/cpp/containers/intrusive_avl_tree/avltree.cpp +++ b/library/cpp/containers/intrusive_avl_tree/avltree.cpp @@ -1 +1 @@ -#include "avltree.h"  +#include "avltree.h" diff --git a/library/cpp/containers/intrusive_avl_tree/avltree.h b/library/cpp/containers/intrusive_avl_tree/avltree.h index 596917a0e27..a58c63b07c5 100644 --- a/library/cpp/containers/intrusive_avl_tree/avltree.h +++ b/library/cpp/containers/intrusive_avl_tree/avltree.h @@ -1,158 +1,158 @@  #pragma once -  -#include <util/generic/noncopyable.h>  -  -template <class T, class C>  -struct TAvlTreeItem;  -  -template <class T, class C>  -class TAvlTree: public TNonCopyable {  + +#include <util/generic/noncopyable.h> + +template <class T, class C> +struct TAvlTreeItem; + +template <class T, class C> +class TAvlTree: public TNonCopyable {      using TTreeItem = TAvlTreeItem<T, C>; -    friend struct TAvlTreeItem<T, C>;  -  +    friend struct TAvlTreeItem<T, C>; +      static inline const T* AsT(const TTreeItem* item) noexcept {          return (const T*)item;      }      static inline T* AsT(TTreeItem* item) noexcept { -        return (T*)item;  -    }  -  +        return (T*)item; +    } +      template <class TTreeItem, class TValue>      class TIteratorBase { -    public:  +    public:          inline TIteratorBase(TTreeItem* p, const TAvlTree* t) noexcept -            : Ptr_(p)  -            , Tree_(t)  -        {  -        }  -  +            : Ptr_(p) +            , Tree_(t) +        { +        } +          inline bool IsEnd() const noexcept {              return Ptr_ == nullptr; -        }  -  +        } +          inline bool IsBegin() const noexcept {              return Ptr_ == nullptr; -        }  -  +        } +          inline bool IsFirst() const noexcept { -            return Ptr_ && Ptr_ == Tree_->Head_;  -        }  -  +            return Ptr_ && Ptr_ == Tree_->Head_; +        } +          inline bool IsLast() const noexcept { -            return Ptr_ && Ptr_ == Tree_->Tail_;  -        }  -  +            return Ptr_ && Ptr_ == Tree_->Tail_; +        } +          inline TValue& operator*() const noexcept { -            return *AsT(Ptr_);  -        }  -  +            return *AsT(Ptr_); +        } +          inline TValue* operator->() const noexcept { -            return AsT(Ptr_);  -        }  -  +            return AsT(Ptr_); +        } +          inline TTreeItem* Inc() noexcept { -            return Ptr_ = FindNext(Ptr_);  -        }  -  +            return Ptr_ = FindNext(Ptr_); +        } +          inline TTreeItem* Dec() noexcept { -            return Ptr_ = FindPrev(Ptr_);  -        }  -  +            return Ptr_ = FindPrev(Ptr_); +        } +          inline TIteratorBase& operator++() noexcept { -            Inc();  -            return *this;  -        }  -  +            Inc(); +            return *this; +        } +          inline TIteratorBase operator++(int) noexcept {              TIteratorBase ret(*this); -            Inc();  -            return ret;  -        }  -  +            Inc(); +            return ret; +        } +          inline TIteratorBase& operator--() noexcept { -            Dec();  -            return *this;  -        }  -  +            Dec(); +            return *this; +        } +          inline TIteratorBase operator--(int) noexcept {              TIteratorBase ret(*this); -            Dec();  -            return ret;  -        }  -  +            Dec(); +            return ret; +        } +          inline TIteratorBase Next() const noexcept { -            return ConstructNext(*this);  -        }  -  +            return ConstructNext(*this); +        } +          inline TIteratorBase Prev() const noexcept { -            return ConstructPrev(*this);  -        }  -  +            return ConstructPrev(*this); +        } +          inline bool operator==(const TIteratorBase& r) const noexcept { -            return Ptr_ == r.Ptr_;  -        }  -  +            return Ptr_ == r.Ptr_; +        } +          inline bool operator!=(const TIteratorBase& r) const noexcept { -            return Ptr_ != r.Ptr_;  -        }  -  -    private:  +            return Ptr_ != r.Ptr_; +        } + +    private:          inline static TIteratorBase ConstructNext(const TIteratorBase& i) noexcept { -            return TIterator(FindNext(i.Ptr_), i.Tree_);  -        }  -  +            return TIterator(FindNext(i.Ptr_), i.Tree_); +        } +          inline static TIteratorBase ConstructPrev(const TIteratorBase& i) noexcept { -            return TIterator(FindPrev(i.Ptr_), i.Tree_);  -        }  -  +            return TIterator(FindPrev(i.Ptr_), i.Tree_); +        } +          inline static TIteratorBase FindPrev(TTreeItem* el) noexcept {              if (el->Left_ != nullptr) { -                el = el->Left_;  -  +                el = el->Left_; +                  while (el->Right_ != nullptr) { -                    el = el->Right_;  -                }  -            } else {  -                while (true) {  -                    TTreeItem* last = el;  -                    el = el->Parent_;  -  +                    el = el->Right_; +                } +            } else { +                while (true) { +                    TTreeItem* last = el; +                    el = el->Parent_; +                      if (el == nullptr || el->Right_ == last) { -                        break;  -                    }  -                }  -            }  -  -            return el;  -        }  -  -        static TTreeItem* FindNext(TTreeItem* el) {  +                        break; +                    } +                } +            } + +            return el; +        } + +        static TTreeItem* FindNext(TTreeItem* el) {              if (el->Right_ != nullptr) { -                el = el->Right_;  -  -                while (el->Left_) {  -                    el = el->Left_;  -                }  -            } else {  -                while (true) {  -                    TTreeItem* last = el;  -                    el = el->Parent_;  -  +                el = el->Right_; + +                while (el->Left_) { +                    el = el->Left_; +                } +            } else { +                while (true) { +                    TTreeItem* last = el; +                    el = el->Parent_; +                      if (el == nullptr || el->Left_ == last) { -                        break;  -                    }  -                }  -            }  -  -            return el;  -        }  -  -    private:  -        TTreeItem* Ptr_;  -        const TAvlTree* Tree_;  -    };  -  +                        break; +                    } +                } +            } + +            return el; +        } + +    private: +        TTreeItem* Ptr_; +        const TAvlTree* Tree_; +    }; +      using TConstIterator = TIteratorBase<const TTreeItem, const T>;      using TIterator = TIteratorBase<TTreeItem, T>; @@ -161,222 +161,222 @@ class TAvlTree: public TNonCopyable {      }      static inline TIterator ConstructFirst(const TAvlTree* t) noexcept { -        return TIterator(t->Head_, t);  -    }  -  +        return TIterator(t->Head_, t); +    } +      static inline TConstIterator ConstructLastConst(const TAvlTree* t) noexcept {          return TConstIterator(t->Tail_, t);      }      static inline TIterator ConstructLast(const TAvlTree* t) noexcept { -        return TIterator(t->Tail_, t);  -    }  -  -    static inline bool Compare(const TTreeItem& l, const TTreeItem& r) {  -        return C::Compare(*AsT(&l), *AsT(&r));  -    }  -  -public:  +        return TIterator(t->Tail_, t); +    } + +    static inline bool Compare(const TTreeItem& l, const TTreeItem& r) { +        return C::Compare(*AsT(&l), *AsT(&r)); +    } + +public:      using const_iterator = TConstIterator;      using iterator = TIterator; -  +      inline TAvlTree() noexcept -        : Root_(nullptr)  -        , Head_(nullptr)  -        , Tail_(nullptr)  -    {  -    }  -  +        : Root_(nullptr) +        , Head_(nullptr) +        , Tail_(nullptr) +    { +    } +      inline ~TAvlTree() noexcept {          Clear();      }      inline void Clear() noexcept { -        for (iterator it = Begin(); it != End();) {  -            (it++)->TTreeItem::Unlink();  -        }  -    }  -  +        for (iterator it = Begin(); it != End();) { +            (it++)->TTreeItem::Unlink(); +        } +    } +      inline T* Insert(TTreeItem* el, TTreeItem** lastFound = nullptr) noexcept { -        el->Unlink();  -        el->Tree_ = this;  -  -        TTreeItem* curEl = Root_;  +        el->Unlink(); +        el->Tree_ = this; + +        TTreeItem* curEl = Root_;          TTreeItem* parentEl = nullptr;          TTreeItem* lastLess = nullptr; -  -        while (true) {  + +        while (true) {              if (curEl == nullptr) { -                AttachRebal(el, parentEl, lastLess);  -  +                AttachRebal(el, parentEl, lastLess); +                  if (lastFound != nullptr) { -                    *lastFound = el;  -                }  -  -                return AsT(el);  -            }  -  -            if (Compare(*el, *curEl)) {  -                parentEl = lastLess = curEl;  -                curEl = curEl->Left_;  -            } else if (Compare(*curEl, *el)) {  -                parentEl = curEl;  -                curEl = curEl->Right_;  -            } else {  +                    *lastFound = el; +                } + +                return AsT(el); +            } + +            if (Compare(*el, *curEl)) { +                parentEl = lastLess = curEl; +                curEl = curEl->Left_; +            } else if (Compare(*curEl, *el)) { +                parentEl = curEl; +                curEl = curEl->Right_; +            } else {                  if (lastFound != nullptr) { -                    *lastFound = curEl;  -                }  -  +                    *lastFound = curEl; +                } +                  return nullptr; -            }  -        }  -    }  -  +            } +        } +    } +      inline T* Find(const TTreeItem* el) const noexcept { -        TTreeItem* curEl = Root_;  -  -        while (curEl) {  -            if (Compare(*el, *curEl)) {  -                curEl = curEl->Left_;  -            } else if (Compare(*curEl, *el)) {  -                curEl = curEl->Right_;  -            } else {  -                return AsT(curEl);  -            }  -        }  -  +        TTreeItem* curEl = Root_; + +        while (curEl) { +            if (Compare(*el, *curEl)) { +                curEl = curEl->Left_; +            } else if (Compare(*curEl, *el)) { +                curEl = curEl->Right_; +            } else { +                return AsT(curEl); +            } +        } +          return nullptr; -    }  +    }      inline T* LowerBound(const TTreeItem* el) const noexcept { -        TTreeItem* curEl = Root_;  +        TTreeItem* curEl = Root_;          TTreeItem* lowerBound = nullptr; -  -        while (curEl) {  -            if (Compare(*el, *curEl)) {  -                lowerBound = curEl;  -                curEl = curEl->Left_;  -            } else if (Compare(*curEl, *el)) {  -                curEl = curEl->Right_;  -            } else {  -                return AsT(curEl);  + +        while (curEl) { +            if (Compare(*el, *curEl)) { +                lowerBound = curEl; +                curEl = curEl->Left_; +            } else if (Compare(*curEl, *el)) { +                curEl = curEl->Right_; +            } else { +                return AsT(curEl);              }          } -        return AsT(lowerBound);  -    }  -  +        return AsT(lowerBound); +    } +      inline T* Erase(TTreeItem* el) noexcept { -        if (el->Tree_ == this) {  -            return this->EraseImpl(el);  -        }  -  +        if (el->Tree_ == this) { +            return this->EraseImpl(el); +        } +          return nullptr; -    }  -  +    } +      inline T* EraseImpl(TTreeItem* el) noexcept {          el->Tree_ = nullptr; -  -        TTreeItem* replacement;  -        TTreeItem* fixfrom;  -        long lheight, rheight;  -  -        if (el->Right_) {  -            replacement = el->Right_;  -  -            while (replacement->Left_) {  -                replacement = replacement->Left_;  -            }  -  -            if (replacement->Parent_ == el) {  -                fixfrom = replacement;  -            } else {  -                fixfrom = replacement->Parent_;  -            }  -  -            if (el == Head_) {  -                Head_ = replacement;  -            }  -  -            RemoveEl(replacement, replacement->Right_);  -            ReplaceEl(el, replacement);  -        } else if (el->Left_) {  -            replacement = el->Left_;  -  -            while (replacement->Right_) {  -                replacement = replacement->Right_;  -            }  -  -            if (replacement->Parent_ == el) {  -                fixfrom = replacement;  -            } else {  -                fixfrom = replacement->Parent_;  -            }  -  -            if (el == Tail_) {  -                Tail_ = replacement;  -            }  -  -            RemoveEl(replacement, replacement->Left_);  -            ReplaceEl(el, replacement);  -        } else {  -            fixfrom = el->Parent_;  -  -            if (el == Head_) {  -                Head_ = el->Parent_;  -            }  -  -            if (el == Tail_) {  -                Tail_ = el->Parent_;  -            }  -  + +        TTreeItem* replacement; +        TTreeItem* fixfrom; +        long lheight, rheight; + +        if (el->Right_) { +            replacement = el->Right_; + +            while (replacement->Left_) { +                replacement = replacement->Left_; +            } + +            if (replacement->Parent_ == el) { +                fixfrom = replacement; +            } else { +                fixfrom = replacement->Parent_; +            } + +            if (el == Head_) { +                Head_ = replacement; +            } + +            RemoveEl(replacement, replacement->Right_); +            ReplaceEl(el, replacement); +        } else if (el->Left_) { +            replacement = el->Left_; + +            while (replacement->Right_) { +                replacement = replacement->Right_; +            } + +            if (replacement->Parent_ == el) { +                fixfrom = replacement; +            } else { +                fixfrom = replacement->Parent_; +            } + +            if (el == Tail_) { +                Tail_ = replacement; +            } + +            RemoveEl(replacement, replacement->Left_); +            ReplaceEl(el, replacement); +        } else { +            fixfrom = el->Parent_; + +            if (el == Head_) { +                Head_ = el->Parent_; +            } + +            if (el == Tail_) { +                Tail_ = el->Parent_; +            } +              RemoveEl(el, nullptr); -        }  -  +        } +          if (fixfrom == nullptr) { -            return AsT(el);  -        }  -  -        RecalcHeights(fixfrom);  -  -        TTreeItem* ub = FindFirstUnbalEl(fixfrom);  -  -        while (ub) {  -            lheight = ub->Left_ ? ub->Left_->Height_ : 0;  -            rheight = ub->Right_ ? ub->Right_->Height_ : 0;  -  -            if (rheight > lheight) {  -                ub = ub->Right_;  -                lheight = ub->Left_ ? ub->Left_->Height_ : 0;  -                rheight = ub->Right_ ? ub->Right_->Height_ : 0;  -  -                if (rheight > lheight) {  -                    ub = ub->Right_;  -                } else if (rheight < lheight) {  -                    ub = ub->Left_;  -                } else {  -                    ub = ub->Right_;  -                }  -            } else {  -                ub = ub->Left_;  -                lheight = ub->Left_ ? ub->Left_->Height_ : 0;  -                rheight = ub->Right_ ? ub->Right_->Height_ : 0;  -                if (rheight > lheight) {  -                    ub = ub->Right_;  -                } else if (rheight < lheight) {  -                    ub = ub->Left_;  -                } else {  -                    ub = ub->Left_;  -                }  -            }  -  -            fixfrom = Rebalance(ub);  -            ub = FindFirstUnbalEl(fixfrom);  -        }  -  -        return AsT(el);  -    }  -  +            return AsT(el); +        } + +        RecalcHeights(fixfrom); + +        TTreeItem* ub = FindFirstUnbalEl(fixfrom); + +        while (ub) { +            lheight = ub->Left_ ? ub->Left_->Height_ : 0; +            rheight = ub->Right_ ? ub->Right_->Height_ : 0; + +            if (rheight > lheight) { +                ub = ub->Right_; +                lheight = ub->Left_ ? ub->Left_->Height_ : 0; +                rheight = ub->Right_ ? ub->Right_->Height_ : 0; + +                if (rheight > lheight) { +                    ub = ub->Right_; +                } else if (rheight < lheight) { +                    ub = ub->Left_; +                } else { +                    ub = ub->Right_; +                } +            } else { +                ub = ub->Left_; +                lheight = ub->Left_ ? ub->Left_->Height_ : 0; +                rheight = ub->Right_ ? ub->Right_->Height_ : 0; +                if (rheight > lheight) { +                    ub = ub->Right_; +                } else if (rheight < lheight) { +                    ub = ub->Left_; +                } else { +                    ub = ub->Left_; +                } +            } + +            fixfrom = Rebalance(ub); +            ub = FindFirstUnbalEl(fixfrom); +        } + +        return AsT(el); +    } +      inline const_iterator First() const noexcept {          return ConstructFirstConst(this);      } @@ -410,21 +410,21 @@ public:      }      inline iterator First() noexcept { -        return ConstructFirst(this);  -    }  -  +        return ConstructFirst(this); +    } +      inline iterator Last() noexcept { -        return ConstructLast(this);  -    }  -  +        return ConstructLast(this); +    } +      inline iterator Begin() noexcept { -        return First();  -    }  -  +        return First(); +    } +      inline iterator End() noexcept {          return iterator(nullptr, this); -    }  -  +    } +      inline iterator begin() noexcept {          return Begin();      } @@ -434,321 +434,321 @@ public:      }      inline bool Empty() const noexcept { -        return const_cast<TAvlTree*>(this)->Begin() == const_cast<TAvlTree*>(this)->End();  -    }  -  +        return const_cast<TAvlTree*>(this)->Begin() == const_cast<TAvlTree*>(this)->End(); +    } +      inline explicit operator bool() const noexcept { -        return !this->Empty();  -    }  -  -    template <class Functor>  -    inline void ForEach(Functor& f) {  -        iterator it = Begin();  -  -        while (!it.IsEnd()) {  -            iterator next = it;  -            ++next;  -            f(*it);  -            it = next;  -        }  -    }  -  -private:  +        return !this->Empty(); +    } + +    template <class Functor> +    inline void ForEach(Functor& f) { +        iterator it = Begin(); + +        while (!it.IsEnd()) { +            iterator next = it; +            ++next; +            f(*it); +            it = next; +        } +    } + +private:      inline TTreeItem* Rebalance(TTreeItem* n) noexcept { -        long lheight, rheight;  -  -        TTreeItem* a;  -        TTreeItem* b;  -        TTreeItem* c;  -        TTreeItem* t1;  -        TTreeItem* t2;  -        TTreeItem* t3;  -        TTreeItem* t4;  -  -        TTreeItem* p = n->Parent_;  -        TTreeItem* gp = p->Parent_;  -        TTreeItem* ggp = gp->Parent_;  -  -        if (gp->Right_ == p) {  -            if (p->Right_ == n) {  -                a = gp;  -                b = p;  -                c = n;  -                t1 = gp->Left_;  -                t2 = p->Left_;  -                t3 = n->Left_;  -                t4 = n->Right_;  -            } else {  -                a = gp;  -                b = n;  -                c = p;  -                t1 = gp->Left_;  -                t2 = n->Left_;  -                t3 = n->Right_;  -                t4 = p->Right_;  -            }  -        } else {  -            if (p->Right_ == n) {  -                a = p;  -                b = n;  -                c = gp;  -                t1 = p->Left_;  -                t2 = n->Left_;  -                t3 = n->Right_;  -                t4 = gp->Right_;  -            } else {  -                a = n;  -                b = p;  -                c = gp;  -                t1 = n->Left_;  -                t2 = n->Right_;  -                t3 = p->Right_;  -                t4 = gp->Right_;  -            }  -        }  -  +        long lheight, rheight; + +        TTreeItem* a; +        TTreeItem* b; +        TTreeItem* c; +        TTreeItem* t1; +        TTreeItem* t2; +        TTreeItem* t3; +        TTreeItem* t4; + +        TTreeItem* p = n->Parent_; +        TTreeItem* gp = p->Parent_; +        TTreeItem* ggp = gp->Parent_; + +        if (gp->Right_ == p) { +            if (p->Right_ == n) { +                a = gp; +                b = p; +                c = n; +                t1 = gp->Left_; +                t2 = p->Left_; +                t3 = n->Left_; +                t4 = n->Right_; +            } else { +                a = gp; +                b = n; +                c = p; +                t1 = gp->Left_; +                t2 = n->Left_; +                t3 = n->Right_; +                t4 = p->Right_; +            } +        } else { +            if (p->Right_ == n) { +                a = p; +                b = n; +                c = gp; +                t1 = p->Left_; +                t2 = n->Left_; +                t3 = n->Right_; +                t4 = gp->Right_; +            } else { +                a = n; +                b = p; +                c = gp; +                t1 = n->Left_; +                t2 = n->Right_; +                t3 = p->Right_; +                t4 = gp->Right_; +            } +        } +          if (ggp == nullptr) { -            Root_ = b;  -        } else if (ggp->Left_ == gp) {  -            ggp->Left_ = b;  -        } else {  -            ggp->Right_ = b;  -        }  -  -        b->Parent_ = ggp;  -        b->Left_ = a;  -        a->Parent_ = b;  -        b->Right_ = c;  -        c->Parent_ = b;  -        a->Left_ = t1;  -  +            Root_ = b; +        } else if (ggp->Left_ == gp) { +            ggp->Left_ = b; +        } else { +            ggp->Right_ = b; +        } + +        b->Parent_ = ggp; +        b->Left_ = a; +        a->Parent_ = b; +        b->Right_ = c; +        c->Parent_ = b; +        a->Left_ = t1; +          if (t1 != nullptr) { -            t1->Parent_ = a;  -        }  -  -        a->Right_ = t2;  -  +            t1->Parent_ = a; +        } + +        a->Right_ = t2; +          if (t2 != nullptr) { -            t2->Parent_ = a;  -        }  -  -        c->Left_ = t3;  -  +            t2->Parent_ = a; +        } + +        c->Left_ = t3; +          if (t3 != nullptr) { -            t3->Parent_ = c;  -        }  -  -        c->Right_ = t4;  -  +            t3->Parent_ = c; +        } + +        c->Right_ = t4; +          if (t4 != nullptr) { -            t4->Parent_ = c;  -        }  -  -        lheight = a->Left_ ? a->Left_->Height_ : 0;  -        rheight = a->Right_ ? a->Right_->Height_ : 0;  -        a->Height_ = (lheight > rheight ? lheight : rheight) + 1;  -  -        lheight = c->Left_ ? c->Left_->Height_ : 0;  -        rheight = c->Right_ ? c->Right_->Height_ : 0;  -        c->Height_ = (lheight > rheight ? lheight : rheight) + 1;  -  -        lheight = a->Height_;  -        rheight = c->Height_;  -        b->Height_ = (lheight > rheight ? lheight : rheight) + 1;  -  -        RecalcHeights(ggp);  -  -        return ggp;  -    }  -  +            t4->Parent_ = c; +        } + +        lheight = a->Left_ ? a->Left_->Height_ : 0; +        rheight = a->Right_ ? a->Right_->Height_ : 0; +        a->Height_ = (lheight > rheight ? lheight : rheight) + 1; + +        lheight = c->Left_ ? c->Left_->Height_ : 0; +        rheight = c->Right_ ? c->Right_->Height_ : 0; +        c->Height_ = (lheight > rheight ? lheight : rheight) + 1; + +        lheight = a->Height_; +        rheight = c->Height_; +        b->Height_ = (lheight > rheight ? lheight : rheight) + 1; + +        RecalcHeights(ggp); + +        return ggp; +    } +      inline void RecalcHeights(TTreeItem* el) noexcept { -        long lheight, rheight, new_height;  -  -        while (el) {  -            lheight = el->Left_ ? el->Left_->Height_ : 0;  -            rheight = el->Right_ ? el->Right_->Height_ : 0;  -  -            new_height = (lheight > rheight ? lheight : rheight) + 1;  -  -            if (new_height == el->Height_) {  -                return;  -            } else {  -                el->Height_ = new_height;  -            }  -  -            el = el->Parent_;  -        }  -    }  -  +        long lheight, rheight, new_height; + +        while (el) { +            lheight = el->Left_ ? el->Left_->Height_ : 0; +            rheight = el->Right_ ? el->Right_->Height_ : 0; + +            new_height = (lheight > rheight ? lheight : rheight) + 1; + +            if (new_height == el->Height_) { +                return; +            } else { +                el->Height_ = new_height; +            } + +            el = el->Parent_; +        } +    } +      inline TTreeItem* FindFirstUnbalGP(TTreeItem* el) noexcept { -        long lheight, rheight, balanceProp;  -        TTreeItem* gp;  -  +        long lheight, rheight, balanceProp; +        TTreeItem* gp; +          if (el == nullptr || el->Parent_ == nullptr || el->Parent_->Parent_ == nullptr) {              return nullptr; -        }  -  -        gp = el->Parent_->Parent_;  -  +        } + +        gp = el->Parent_->Parent_; +          while (gp != nullptr) { -            lheight = gp->Left_ ? gp->Left_->Height_ : 0;  -            rheight = gp->Right_ ? gp->Right_->Height_ : 0;  -            balanceProp = lheight - rheight;  -  -            if (balanceProp < -1 || balanceProp > 1) {  -                return el;  -            }  -  -            el = el->Parent_;  -            gp = gp->Parent_;  -        }  -  +            lheight = gp->Left_ ? gp->Left_->Height_ : 0; +            rheight = gp->Right_ ? gp->Right_->Height_ : 0; +            balanceProp = lheight - rheight; + +            if (balanceProp < -1 || balanceProp > 1) { +                return el; +            } + +            el = el->Parent_; +            gp = gp->Parent_; +        } +          return nullptr; -    }  -  +    } +      inline TTreeItem* FindFirstUnbalEl(TTreeItem* el) noexcept {          if (el == nullptr) {              return nullptr; -        }  -  -        while (el) {  -            const long lheight = el->Left_ ? el->Left_->Height_ : 0;  -            const long rheight = el->Right_ ? el->Right_->Height_ : 0;  -            const long balanceProp = lheight - rheight;  -  -            if (balanceProp < -1 || balanceProp > 1) {  -                return el;  -            }  -  -            el = el->Parent_;  -        }  -  +        } + +        while (el) { +            const long lheight = el->Left_ ? el->Left_->Height_ : 0; +            const long rheight = el->Right_ ? el->Right_->Height_ : 0; +            const long balanceProp = lheight - rheight; + +            if (balanceProp < -1 || balanceProp > 1) { +                return el; +            } + +            el = el->Parent_; +        } +          return nullptr; -    }  -  +    } +      inline void ReplaceEl(TTreeItem* el, TTreeItem* replacement) noexcept { -        TTreeItem* parent = el->Parent_;  -        TTreeItem* left = el->Left_;  -        TTreeItem* right = el->Right_;  -  -        replacement->Left_ = left;  -  -        if (left) {  -            left->Parent_ = replacement;  -        }  -  -        replacement->Right_ = right;  -  -        if (right) {  -            right->Parent_ = replacement;  -        }  -  -        replacement->Parent_ = parent;  -  -        if (parent) {  -            if (parent->Left_ == el) {  -                parent->Left_ = replacement;  -            } else {  -                parent->Right_ = replacement;  -            }  -        } else {  -            Root_ = replacement;  -        }  -  -        replacement->Height_ = el->Height_;  -    }  -  +        TTreeItem* parent = el->Parent_; +        TTreeItem* left = el->Left_; +        TTreeItem* right = el->Right_; + +        replacement->Left_ = left; + +        if (left) { +            left->Parent_ = replacement; +        } + +        replacement->Right_ = right; + +        if (right) { +            right->Parent_ = replacement; +        } + +        replacement->Parent_ = parent; + +        if (parent) { +            if (parent->Left_ == el) { +                parent->Left_ = replacement; +            } else { +                parent->Right_ = replacement; +            } +        } else { +            Root_ = replacement; +        } + +        replacement->Height_ = el->Height_; +    } +      inline void RemoveEl(TTreeItem* el, TTreeItem* filler) noexcept { -        TTreeItem* parent = el->Parent_;  -  -        if (parent) {  -            if (parent->Left_ == el) {  -                parent->Left_ = filler;  -            } else {  -                parent->Right_ = filler;  -            }  -        } else {  -            Root_ = filler;  -        }  -  -        if (filler) {  -            filler->Parent_ = parent;  -        }  -  -        return;  -    }  -  -    inline void AttachRebal(TTreeItem* el, TTreeItem* parentEl, TTreeItem* lastLess) {  -        el->Parent_ = parentEl;  +        TTreeItem* parent = el->Parent_; + +        if (parent) { +            if (parent->Left_ == el) { +                parent->Left_ = filler; +            } else { +                parent->Right_ = filler; +            } +        } else { +            Root_ = filler; +        } + +        if (filler) { +            filler->Parent_ = parent; +        } + +        return; +    } + +    inline void AttachRebal(TTreeItem* el, TTreeItem* parentEl, TTreeItem* lastLess) { +        el->Parent_ = parentEl;          el->Left_ = nullptr;          el->Right_ = nullptr; -        el->Height_ = 1;  -  +        el->Height_ = 1; +          if (parentEl != nullptr) { -            if (lastLess == parentEl) {  -                parentEl->Left_ = el;  -            } else {  -                parentEl->Right_ = el;  -            }  -  -            if (Head_->Left_ == el) {  -                Head_ = el;  -            }  -  -            if (Tail_->Right_ == el) {  -                Tail_ = el;  -            }  -        } else {  -            Root_ = el;  -            Head_ = Tail_ = el;  -        }  -  -        RecalcHeights(parentEl);  -  -        TTreeItem* ub = FindFirstUnbalGP(el);  -  +            if (lastLess == parentEl) { +                parentEl->Left_ = el; +            } else { +                parentEl->Right_ = el; +            } + +            if (Head_->Left_ == el) { +                Head_ = el; +            } + +            if (Tail_->Right_ == el) { +                Tail_ = el; +            } +        } else { +            Root_ = el; +            Head_ = Tail_ = el; +        } + +        RecalcHeights(parentEl); + +        TTreeItem* ub = FindFirstUnbalGP(el); +          if (ub != nullptr) { -            Rebalance(ub);  -        }  -    }  -  -private:  -    TTreeItem* Root_;  -    TTreeItem* Head_;  -    TTreeItem* Tail_;  -};  -  -template <class T, class C>  -struct TAvlTreeItem: public TNonCopyable {  -public:  +            Rebalance(ub); +        } +    } + +private: +    TTreeItem* Root_; +    TTreeItem* Head_; +    TTreeItem* Tail_; +}; + +template <class T, class C> +struct TAvlTreeItem: public TNonCopyable { +public:      using TTree = TAvlTree<T, C>; -    friend class TAvlTree<T, C>;  +    friend class TAvlTree<T, C>;      friend typename TAvlTree<T, C>::TConstIterator;      friend typename TAvlTree<T, C>::TIterator; -  +      inline TAvlTreeItem() noexcept -        : Left_(nullptr)  -        , Right_(nullptr)  -        , Parent_(nullptr)  -        , Height_(0)  -        , Tree_(nullptr)  -    {  -    }  -  +        : Left_(nullptr) +        , Right_(nullptr) +        , Parent_(nullptr) +        , Height_(0) +        , Tree_(nullptr) +    { +    } +      inline ~TAvlTreeItem() noexcept { -        Unlink();  -    }  -  +        Unlink(); +    } +      inline void Unlink() noexcept { -        if (Tree_) {  -            Tree_->EraseImpl(this);  -        }  -    }  -  -private:  -    TAvlTreeItem* Left_;  -    TAvlTreeItem* Right_;  -    TAvlTreeItem* Parent_;  -    long Height_;  -    TTree* Tree_;  -};  +        if (Tree_) { +            Tree_->EraseImpl(this); +        } +    } + +private: +    TAvlTreeItem* Left_; +    TAvlTreeItem* Right_; +    TAvlTreeItem* Parent_; +    long Height_; +    TTree* Tree_; +}; diff --git a/library/cpp/containers/intrusive_avl_tree/ut/avltree_ut.cpp b/library/cpp/containers/intrusive_avl_tree/ut/avltree_ut.cpp index 256738c50a6..cab2365ccec 100644 --- a/library/cpp/containers/intrusive_avl_tree/ut/avltree_ut.cpp +++ b/library/cpp/containers/intrusive_avl_tree/ut/avltree_ut.cpp @@ -3,29 +3,29 @@  #include <library/cpp/containers/intrusive_avl_tree/avltree.h>  class TAvlTreeTest: public TTestBase { -    UNIT_TEST_SUITE(TAvlTreeTest);  -    UNIT_TEST(TestLowerBound);  +    UNIT_TEST_SUITE(TAvlTreeTest); +    UNIT_TEST(TestLowerBound);      UNIT_TEST(TestIterator); -    UNIT_TEST_SUITE_END();  +    UNIT_TEST_SUITE_END(); -private:  -    void TestLowerBound();  +private: +    void TestLowerBound();      void TestIterator(); -    class TIt;  -    struct TItCompare {  +    class TIt; +    struct TItCompare {          static inline bool Compare(const TIt& l, const TIt& r) noexcept; -    };  +    }; -    class TIt: public TAvlTreeItem<TIt, TItCompare> {  -    public:  -        TIt(int val = 0)  -            : Val(val)  -        {  -        }  +    class TIt: public TAvlTreeItem<TIt, TItCompare> { +    public: +        TIt(int val = 0) +            : Val(val) +        { +        } -        int Val;  -    };  +        int Val; +    };      using TIts = TAvlTree<TIt, TItCompare>;  }; diff --git a/library/cpp/containers/intrusive_avl_tree/ut/ya.make b/library/cpp/containers/intrusive_avl_tree/ut/ya.make index ef8fb95b6e6..87920306d78 100644 --- a/library/cpp/containers/intrusive_avl_tree/ut/ya.make +++ b/library/cpp/containers/intrusive_avl_tree/ut/ya.make @@ -1,12 +1,12 @@  UNITTEST_FOR(library/cpp/containers/intrusive_avl_tree) -  +  OWNER(      pg      g:util  ) -  -SRCS(  -    avltree_ut.cpp  -)  -  -END()  + +SRCS( +    avltree_ut.cpp +) + +END() diff --git a/library/cpp/containers/intrusive_avl_tree/ya.make b/library/cpp/containers/intrusive_avl_tree/ya.make index a8e3211340c..6b061f27609 100644 --- a/library/cpp/containers/intrusive_avl_tree/ya.make +++ b/library/cpp/containers/intrusive_avl_tree/ya.make @@ -1,12 +1,12 @@ -LIBRARY()  -  +LIBRARY() +  OWNER(      pg      g:util  ) -  -SRCS(  -    avltree.cpp  -)  -  -END()  + +SRCS( +    avltree.cpp +) + +END() diff --git a/library/cpp/containers/intrusive_rb_tree/fuzz/rb_tree_fuzzing.cpp b/library/cpp/containers/intrusive_rb_tree/fuzz/rb_tree_fuzzing.cpp index 3bf84258c11..92370760b59 100644 --- a/library/cpp/containers/intrusive_rb_tree/fuzz/rb_tree_fuzzing.cpp +++ b/library/cpp/containers/intrusive_rb_tree/fuzz/rb_tree_fuzzing.cpp @@ -11,31 +11,31 @@ struct TCmp {      }      template <class T> -    static inline bool Compare(const T& l, ui8 r) {  +    static inline bool Compare(const T& l, ui8 r) {          return l.N < r;      }      template <class T> -    static inline bool Compare(ui8 l, const T& r) {  +    static inline bool Compare(ui8 l, const T& r) {          return l < r.N;      }  };  class TNode: public TRbTreeItem<TNode, TCmp> {  public: -    inline TNode(ui8 n) noexcept  +    inline TNode(ui8 n) noexcept          : N(n)      {      } -    ui8 N;  +    ui8 N;  };  using TTree = TRbTree<TNode, TCmp>; -extern "C" int LLVMFuzzerTestOneInput(const ui8* data, size_t size) {  +extern "C" int LLVMFuzzerTestOneInput(const ui8* data, size_t size) {      TDeque<TNode> records; -    const ui8 half = 128u;  +    const ui8 half = 128u;      TTree tree;      for (size_t i = 0; i < size; ++i) {          if (data[i] / half == 0) { diff --git a/library/cpp/containers/intrusive_rb_tree/rb_tree.cpp b/library/cpp/containers/intrusive_rb_tree/rb_tree.cpp index 85b35e26343..535b536c41f 100644 --- a/library/cpp/containers/intrusive_rb_tree/rb_tree.cpp +++ b/library/cpp/containers/intrusive_rb_tree/rb_tree.cpp @@ -1 +1 @@ -#include "rb_tree.h"  +#include "rb_tree.h" diff --git a/library/cpp/containers/intrusive_rb_tree/rb_tree.h b/library/cpp/containers/intrusive_rb_tree/rb_tree.h index ed94b1794d3..0259452a145 100644 --- a/library/cpp/containers/intrusive_rb_tree/rb_tree.h +++ b/library/cpp/containers/intrusive_rb_tree/rb_tree.h @@ -1,48 +1,48 @@  #pragma once -  -#include <util/generic/utility.h>  -#include <util/generic/yexception.h>  -  + +#include <util/generic/utility.h> +#include <util/generic/yexception.h> +  using TRbTreeColorType = bool; -  -#define RBTreeRed false  -#define RBTreeBlack true  -  -struct TRbTreeNodeBase {  + +#define RBTreeRed false +#define RBTreeBlack true + +struct TRbTreeNodeBase {      using TColorType = TRbTreeColorType;      using TBasePtr = TRbTreeNodeBase*; -  -    TColorType Color_;  -    TBasePtr Parent_;  -    TBasePtr Left_;  -    TBasePtr Right_;  + +    TColorType Color_; +    TBasePtr Parent_; +    TBasePtr Left_; +    TBasePtr Right_;      size_t Children_; -  +      inline TRbTreeNodeBase() noexcept { -        ReInitNode();  -    }  -  +        ReInitNode(); +    } +      inline void ReInitNode() noexcept { -        Color_ = RBTreeBlack;  +        Color_ = RBTreeBlack;          Parent_ = nullptr;          Left_ = nullptr;          Right_ = nullptr;          Children_ = 1; -    }  -  -    static TBasePtr MinimumNode(TBasePtr x) {  +    } + +    static TBasePtr MinimumNode(TBasePtr x) {          while (x->Left_ != nullptr) -            x = x->Left_;  -  -        return x;  -    }  -  -    static TBasePtr MaximumNode(TBasePtr x) {  +            x = x->Left_; + +        return x; +    } + +    static TBasePtr MaximumNode(TBasePtr x) {          while (x->Right_ != nullptr) -            x = x->Right_;  -  -        return x;  -    }  +            x = x->Right_; + +        return x; +    }      static TBasePtr ByIndex(TBasePtr x, size_t index) {          if (x->Left_ != nullptr) { @@ -56,300 +56,300 @@ struct TRbTreeNodeBase {              ythrow yexception() << "index not found";          return ByIndex(x->Right_, index - 1);      } -};  -  -struct TRbTreeBaseIterator;  -  -template <class TDummy>  -class TRbGlobal {  -public:  +}; + +struct TRbTreeBaseIterator; + +template <class TDummy> +class TRbGlobal { +public:      using TBasePtr = TRbTreeNodeBase*; -  -    static void Rebalance(TBasePtr x, TBasePtr& root);  -    static TBasePtr RebalanceForErase(TBasePtr z, TBasePtr& root, TBasePtr& leftmost, TBasePtr& rightmost);  + +    static void Rebalance(TBasePtr x, TBasePtr& root); +    static TBasePtr RebalanceForErase(TBasePtr z, TBasePtr& root, TBasePtr& leftmost, TBasePtr& rightmost);      static void DecrementChildrenUntilRoot(TBasePtr x, TBasePtr root);      static void RecalcChildren(TBasePtr x); -  -    static TBasePtr IncrementNode(TBasePtr);  -    static TBasePtr DecrementNode(TBasePtr);  -    static void RotateLeft(TBasePtr x, TBasePtr& root);  -    static void RotateRight(TBasePtr x, TBasePtr& root);  -};  -  + +    static TBasePtr IncrementNode(TBasePtr); +    static TBasePtr DecrementNode(TBasePtr); +    static void RotateLeft(TBasePtr x, TBasePtr& root); +    static void RotateRight(TBasePtr x, TBasePtr& root); +}; +  using TRbGlobalInst = TRbGlobal<bool>; -  -struct TRbTreeBaseIterator {  + +struct TRbTreeBaseIterator {      using TBasePtr = TRbTreeNodeBase*; -    TBasePtr Node_;  -  +    TBasePtr Node_; +      inline TRbTreeBaseIterator(TBasePtr x = nullptr) noexcept -        : Node_(x)  -    {  -    }  -};  -  -template <class TValue, class TTraits>  -struct TRbTreeIterator: public TRbTreeBaseIterator {  +        : Node_(x) +    { +    } +}; + +template <class TValue, class TTraits> +struct TRbTreeIterator: public TRbTreeBaseIterator {      using TReference = typename TTraits::TReference;      using TPointer = typename TTraits::TPointer;      using TSelf = TRbTreeIterator<TValue, TTraits>;      using TBasePtr = TRbTreeNodeBase*; -  +      inline TRbTreeIterator() noexcept = default; -  -    template <class T1>  + +    template <class T1>      inline TRbTreeIterator(const T1& x) noexcept -        : TRbTreeBaseIterator(x)  -    {  -    }  -  +        : TRbTreeBaseIterator(x) +    { +    } +      inline TReference operator*() const noexcept { -        return *static_cast<TValue*>(Node_);  -    }  -  +        return *static_cast<TValue*>(Node_); +    } +      inline TPointer operator->() const noexcept { -        return static_cast<TValue*>(Node_);  -    }  -  +        return static_cast<TValue*>(Node_); +    } +      inline TSelf& operator++() noexcept { -        Node_ = TRbGlobalInst::IncrementNode(Node_);  -        return *this;  -    }  -  +        Node_ = TRbGlobalInst::IncrementNode(Node_); +        return *this; +    } +      inline TSelf operator++(int) noexcept { -        TSelf tmp = *this;  -        ++(*this);  -        return tmp;  -    }  -  +        TSelf tmp = *this; +        ++(*this); +        return tmp; +    } +      inline TSelf& operator--() noexcept { -        Node_ = TRbGlobalInst::DecrementNode(Node_);  -        return *this;  -    }  -  +        Node_ = TRbGlobalInst::DecrementNode(Node_); +        return *this; +    } +      inline TSelf operator--(int) noexcept { -        TSelf tmp = *this;  -        --(*this);  -        return tmp;  -    }  -  -    template <class T1>  +        TSelf tmp = *this; +        --(*this); +        return tmp; +    } + +    template <class T1>      inline bool operator==(const T1& rhs) const noexcept { -        return Node_ == rhs.Node_;  -    }  -  -    template <class T1>  +        return Node_ == rhs.Node_; +    } + +    template <class T1>      inline bool operator!=(const T1& rhs) const noexcept { -        return Node_ != rhs.Node_;  -    }  -};  -  -template <class TValue, class TCmp>  -class TRbTree {  -    struct TCmpAdaptor: public TCmp {  +        return Node_ != rhs.Node_; +    } +}; + +template <class TValue, class TCmp> +class TRbTree { +    struct TCmpAdaptor: public TCmp {          inline TCmpAdaptor() noexcept = default; -  +          inline TCmpAdaptor(const TCmp& cmp) noexcept -            : TCmp(cmp)  -        {  -        }  -  -        template <class T1, class T2>  -        inline bool operator()(const T1& l, const T2& r) const {  -            return TCmp::Compare(l, r);  -        }  -    };  -  -    struct TNonConstTraits {  +            : TCmp(cmp) +        { +        } + +        template <class T1, class T2> +        inline bool operator()(const T1& l, const T2& r) const { +            return TCmp::Compare(l, r); +        } +    }; + +    struct TNonConstTraits {          using TReference = TValue&;          using TPointer = TValue*; -    };  -  -    struct TConstTraits {  +    }; + +    struct TConstTraits {          using TReference = const TValue&;          using TPointer = const TValue*; -    };  -  +    }; +      using TNodeBase = TRbTreeNodeBase;      using TBasePtr = TRbTreeNodeBase*;      using TColorType = TRbTreeColorType; -  -public:  -    class TRealNode: public TNodeBase {  -    public:  -        inline TRealNode()  + +public: +    class TRealNode: public TNodeBase { +    public: +        inline TRealNode()              : Tree_(nullptr) -        {  -        }  -  +        { +        } +          inline ~TRealNode() { -            UnLink();  -        }  -  +            UnLink(); +        } +          inline void UnLink() noexcept { -            if (Tree_) {  -                Tree_->EraseImpl(this);  -                ReInitNode();  +            if (Tree_) { +                Tree_->EraseImpl(this); +                ReInitNode();                  Tree_ = nullptr; -            }  -        }  -  +            } +        } +          inline void SetRbTreeParent(TRbTree* parent) noexcept { -            Tree_ = parent;  -        }  -  +            Tree_ = parent; +        } +          inline TRbTree* ParentTree() const noexcept { -            return Tree_;  -        }  -  -    private:  -        TRbTree* Tree_;  -    };  -  +            return Tree_; +        } + +    private: +        TRbTree* Tree_; +    }; +      using TIterator = TRbTreeIterator<TValue, TNonConstTraits>;      using TConstIterator = TRbTreeIterator<TValue, TConstTraits>; -  +      inline TRbTree() noexcept { -        Init();  -    }  -  +        Init(); +    } +      inline TRbTree(const TCmp& cmp) noexcept -        : KeyCompare_(cmp)  -    {  -        Init();  -    }  -  +        : KeyCompare_(cmp) +    { +        Init(); +    } +      inline void Init() noexcept { -        Data_.Color_ = RBTreeRed;  +        Data_.Color_ = RBTreeRed;          Data_.Parent_ = nullptr; -        Data_.Left_ = &Data_;  -        Data_.Right_ = &Data_;  -        Data_.Children_ = 0;  -    }  -  -    struct TDestroy {  +        Data_.Left_ = &Data_; +        Data_.Right_ = &Data_; +        Data_.Children_ = 0; +    } + +    struct TDestroy {          inline void operator()(TValue& v) const noexcept {              v.SetRbTreeParent(nullptr); -            v.ReInitNode();  -        }  -    };  -  +            v.ReInitNode(); +        } +    }; +      inline ~TRbTree() { -        ForEachNoOrder(TDestroy());  -    }  -  +        ForEachNoOrder(TDestroy()); +    } +      inline void Clear() noexcept { -        ForEachNoOrder(TDestroy());  -        Init();  -    }  -  -    template <class F>  -    inline void ForEachNoOrder(const F& f) {  -        ForEachNoOrder(Root(), f);  -    }  -  -    template <class F>  -    inline void ForEachNoOrder(TNodeBase* n, const F& f) {  -        if (n && n != &Data_) {  -            ForEachNoOrder(n->Left_, f);  -            ForEachNoOrder(n->Right_, f);  -            f(ValueNode(n));  -        }  -    }  -  +        ForEachNoOrder(TDestroy()); +        Init(); +    } + +    template <class F> +    inline void ForEachNoOrder(const F& f) { +        ForEachNoOrder(Root(), f); +    } + +    template <class F> +    inline void ForEachNoOrder(TNodeBase* n, const F& f) { +        if (n && n != &Data_) { +            ForEachNoOrder(n->Left_, f); +            ForEachNoOrder(n->Right_, f); +            f(ValueNode(n)); +        } +    } +      inline TIterator Begin() noexcept { -        return LeftMost();  -    }  -  +        return LeftMost(); +    } +      inline TConstIterator Begin() const noexcept { -        return LeftMost();  -    }  -  +        return LeftMost(); +    } +      inline TIterator End() noexcept { -        return &this->Data_;  -    }  -  +        return &this->Data_; +    } +      inline TConstIterator End() const noexcept { -        return const_cast<TBasePtr>(&this->Data_);  -    }  -  +        return const_cast<TBasePtr>(&this->Data_); +    } +      inline bool Empty() const noexcept { -        return this->Begin() == this->End();  -    }  -  +        return this->Begin() == this->End(); +    } +      inline explicit operator bool() const noexcept { -        return !this->Empty();  -    }  -  -    inline TIterator Insert(TValue* val) {  -        return Insert(*val);  -    }  -  -    inline TIterator Insert(TValue& val) {  -        val.UnLink();  -  -        TBasePtr y = &this->Data_;  -        TBasePtr x = Root();  -  +        return !this->Empty(); +    } + +    inline TIterator Insert(TValue* val) { +        return Insert(*val); +    } + +    inline TIterator Insert(TValue& val) { +        val.UnLink(); + +        TBasePtr y = &this->Data_; +        TBasePtr x = Root(); +          while (x != nullptr) { -            ++(x->Children_);  -            y = x;  -  -            if (KeyCompare_(ValueNode(&val), ValueNode(x))) {  -                x = LeftNode(x);  -            } else {  -                x = RightNode(x);  -            }  -        }  -  -        return InsertImpl(y, &val, x);  -    }  -  -    template <class F>  -    inline void ForEach(F& f) {  -        TIterator it = Begin();  -  -        while (it != End()) {  -            f(*it++);  -        }  -    }  -  +            ++(x->Children_); +            y = x; + +            if (KeyCompare_(ValueNode(&val), ValueNode(x))) { +                x = LeftNode(x); +            } else { +                x = RightNode(x); +            } +        } + +        return InsertImpl(y, &val, x); +    } + +    template <class F> +    inline void ForEach(F& f) { +        TIterator it = Begin(); + +        while (it != End()) { +            f(*it++); +        } +    } +      inline void Erase(TValue& val) noexcept { -        val.UnLink();  -    }  -  +        val.UnLink(); +    } +      inline void Erase(TValue* val) noexcept { -        Erase(*val);  -    }  -  +        Erase(*val); +    } +      inline void Erase(TIterator pos) noexcept { -        Erase(*pos);  -    }  -  +        Erase(*pos); +    } +      inline void EraseImpl(TNodeBase* val) noexcept { -        TRbGlobalInst::RebalanceForErase(val, this->Data_.Parent_, this->Data_.Left_, this->Data_.Right_);  -    }  -  -    template <class T1>  -    inline TValue* Find(const T1& k) const {  +        TRbGlobalInst::RebalanceForErase(val, this->Data_.Parent_, this->Data_.Left_, this->Data_.Right_); +    } + +    template <class T1> +    inline TValue* Find(const T1& k) const {          TBasePtr y = nullptr; -        TBasePtr x = Root(); // Current node.  -  +        TBasePtr x = Root(); // Current node. +          while (x != nullptr) -            if (!KeyCompare_(ValueNode(x), k))  -                y = x, x = LeftNode(x);  -            else  -                x = RightNode(x);  -  -        if (y) {  -            if (KeyCompare_(k, ValueNode(y))) {  +            if (!KeyCompare_(ValueNode(x), k)) +                y = x, x = LeftNode(x); +            else +                x = RightNode(x); + +        if (y) { +            if (KeyCompare_(k, ValueNode(y))) {                  y = nullptr; -            }  -        }  -  -        return static_cast<TValue*>(y);  -    }  -  +            } +        } + +        return static_cast<TValue*>(y); +    } +      size_t GetIndex(TBasePtr x) const {          size_t index = 0; @@ -370,33 +370,33 @@ public:          return index;      } -    template <class T1>  -    inline TBasePtr LowerBound(const T1& k) const {  -        TBasePtr y = const_cast<TBasePtr>(&this->Data_); /* Last node which is not less than k. */  -        TBasePtr x = Root();                             /* Current node. */  -  +    template <class T1> +    inline TBasePtr LowerBound(const T1& k) const { +        TBasePtr y = const_cast<TBasePtr>(&this->Data_); /* Last node which is not less than k. */ +        TBasePtr x = Root();                             /* Current node. */ +          while (x != nullptr) -            if (!KeyCompare_(ValueNode(x), k))  -                y = x, x = LeftNode(x);  -            else  -                x = RightNode(x);  -  -        return y;  -    }  -  -    template <class T1>  -    inline TBasePtr UpperBound(const T1& k) const {  -        TBasePtr y = const_cast<TBasePtr>(&this->Data_); /* Last node which is greater than k. */  -        TBasePtr x = Root();                             /* Current node. */  -  +            if (!KeyCompare_(ValueNode(x), k)) +                y = x, x = LeftNode(x); +            else +                x = RightNode(x); + +        return y; +    } + +    template <class T1> +    inline TBasePtr UpperBound(const T1& k) const { +        TBasePtr y = const_cast<TBasePtr>(&this->Data_); /* Last node which is greater than k. */ +        TBasePtr x = Root();                             /* Current node. */ +          while (x != nullptr) -            if (KeyCompare_(k, ValueNode(x)))  -                y = x, x = LeftNode(x);  -            else  -                x = RightNode(x);  -  -        return y;  -    }  +            if (KeyCompare_(k, ValueNode(x))) +                y = x, x = LeftNode(x); +            else +                x = RightNode(x); + +        return y; +    }      template <class T1>      inline size_t LessCount(const T1& k) const { @@ -432,184 +432,184 @@ public:          return Root()->Children_ - GreaterCount<T1>(k);      } -    TValue* ByIndex(size_t index) {  -        return static_cast<TValue*>(TRbTreeNodeBase::ByIndex(Root(), index));  -    }  -  -private:  -    // CRP 7/10/00 inserted argument on_right, which is another hint (meant to  -    // act like on_left and ignore a portion of the if conditions -- specify  +    TValue* ByIndex(size_t index) { +        return static_cast<TValue*>(TRbTreeNodeBase::ByIndex(Root(), index)); +    } + +private: +    // CRP 7/10/00 inserted argument on_right, which is another hint (meant to +    // act like on_left and ignore a portion of the if conditions -- specify      // on_right != nullptr to bypass comparison as false or on_left != nullptr to bypass -    // comparison as true)  +    // comparison as true)      TIterator InsertImpl(TRbTreeNodeBase* parent, TRbTreeNodeBase* val, TRbTreeNodeBase* on_left = nullptr, TRbTreeNodeBase* on_right = nullptr) { -        ValueNode(val).SetRbTreeParent(this);  -        TBasePtr new_node = val;  -  -        if (parent == &this->Data_) {  -            LeftNode(parent) = new_node;  -            // also makes LeftMost() = new_node  -            Root() = new_node;  -            RightMost() = new_node;  +        ValueNode(val).SetRbTreeParent(this); +        TBasePtr new_node = val; + +        if (parent == &this->Data_) { +            LeftNode(parent) = new_node; +            // also makes LeftMost() = new_node +            Root() = new_node; +            RightMost() = new_node;          } else if (on_right == nullptr &&                     // If on_right != nullptr, the remainder fails to false                     (on_left != nullptr ||                      // If on_left != nullptr, the remainder succeeds to true -                    KeyCompare_(ValueNode(val), ValueNode(parent))))  - {  -            LeftNode(parent) = new_node;  -            if (parent == LeftMost())  -                // maintain LeftMost() pointing to min node  -                LeftMost() = new_node;  -        } else {  -            RightNode(parent) = new_node;  -            if (parent == RightMost())  -                // maintain RightMost() pointing to max node  -                RightMost() = new_node;  -        }  -        ParentNode(new_node) = parent;  -        TRbGlobalInst::Rebalance(new_node, this->Data_.Parent_);  -        return new_node;  -    }  -  -    TBasePtr Root() const {  -        return this->Data_.Parent_;  -    }  -  -    TBasePtr LeftMost() const {  -        return this->Data_.Left_;  -    }  -  -    TBasePtr RightMost() const {  -        return this->Data_.Right_;  -    }  -  -    TBasePtr& Root() {  -        return this->Data_.Parent_;  -    }  -  -    TBasePtr& LeftMost() {  -        return this->Data_.Left_;  -    }  -  -    TBasePtr& RightMost() {  -        return this->Data_.Right_;  -    }  -  -    static TBasePtr& LeftNode(TBasePtr x) {  -        return x->Left_;  -    }  -  -    static TBasePtr& RightNode(TBasePtr x) {  -        return x->Right_;  -    }  -  -    static TBasePtr& ParentNode(TBasePtr x) {  -        return x->Parent_;  -    }  -  -    static TValue& ValueNode(TBasePtr x) {  -        return *static_cast<TValue*>(x);  -    }  -  -    static TBasePtr MinimumNode(TBasePtr x) {  -        return TRbTreeNodeBase::MinimumNode(x);  -    }  -  -    static TBasePtr MaximumNode(TBasePtr x) {  -        return TRbTreeNodeBase::MaximumNode(x);  -    }  -  -private:  -    TCmpAdaptor KeyCompare_;  -    TNodeBase Data_;  -};  -  -template <class TValue, class TCmp>  -class TRbTreeItem: public TRbTree<TValue, TCmp>::TRealNode {  -};  -  -template <class TDummy>  -void TRbGlobal<TDummy>::RotateLeft(TRbTreeNodeBase* x, TRbTreeNodeBase*& root) {  -    TRbTreeNodeBase* y = x->Right_;  -    x->Right_ = y->Left_;  +                    KeyCompare_(ValueNode(val), ValueNode(parent)))) + { +            LeftNode(parent) = new_node; +            if (parent == LeftMost()) +                // maintain LeftMost() pointing to min node +                LeftMost() = new_node; +        } else { +            RightNode(parent) = new_node; +            if (parent == RightMost()) +                // maintain RightMost() pointing to max node +                RightMost() = new_node; +        } +        ParentNode(new_node) = parent; +        TRbGlobalInst::Rebalance(new_node, this->Data_.Parent_); +        return new_node; +    } + +    TBasePtr Root() const { +        return this->Data_.Parent_; +    } + +    TBasePtr LeftMost() const { +        return this->Data_.Left_; +    } + +    TBasePtr RightMost() const { +        return this->Data_.Right_; +    } + +    TBasePtr& Root() { +        return this->Data_.Parent_; +    } + +    TBasePtr& LeftMost() { +        return this->Data_.Left_; +    } + +    TBasePtr& RightMost() { +        return this->Data_.Right_; +    } + +    static TBasePtr& LeftNode(TBasePtr x) { +        return x->Left_; +    } + +    static TBasePtr& RightNode(TBasePtr x) { +        return x->Right_; +    } + +    static TBasePtr& ParentNode(TBasePtr x) { +        return x->Parent_; +    } + +    static TValue& ValueNode(TBasePtr x) { +        return *static_cast<TValue*>(x); +    } + +    static TBasePtr MinimumNode(TBasePtr x) { +        return TRbTreeNodeBase::MinimumNode(x); +    } + +    static TBasePtr MaximumNode(TBasePtr x) { +        return TRbTreeNodeBase::MaximumNode(x); +    } + +private: +    TCmpAdaptor KeyCompare_; +    TNodeBase Data_; +}; + +template <class TValue, class TCmp> +class TRbTreeItem: public TRbTree<TValue, TCmp>::TRealNode { +}; + +template <class TDummy> +void TRbGlobal<TDummy>::RotateLeft(TRbTreeNodeBase* x, TRbTreeNodeBase*& root) { +    TRbTreeNodeBase* y = x->Right_; +    x->Right_ = y->Left_;      if (y->Left_ != nullptr) -        y->Left_->Parent_ = x;  -    y->Parent_ = x->Parent_;  -  -    if (x == root)  -        root = y;  -    else if (x == x->Parent_->Left_)  -        x->Parent_->Left_ = y;  -    else  -        x->Parent_->Right_ = y;  -    y->Left_ = x;  -    x->Parent_ = y;  +        y->Left_->Parent_ = x; +    y->Parent_ = x->Parent_; + +    if (x == root) +        root = y; +    else if (x == x->Parent_->Left_) +        x->Parent_->Left_ = y; +    else +        x->Parent_->Right_ = y; +    y->Left_ = x; +    x->Parent_ = y;      y->Children_ = x->Children_;      x->Children_ = ((x->Left_) ? x->Left_->Children_ : 0) + ((x->Right_) ? x->Right_->Children_ : 0) + 1; -}  -  -template <class TDummy>  -void TRbGlobal<TDummy>::RotateRight(TRbTreeNodeBase* x, TRbTreeNodeBase*& root) {  -    TRbTreeNodeBase* y = x->Left_;  -    x->Left_ = y->Right_;  +} + +template <class TDummy> +void TRbGlobal<TDummy>::RotateRight(TRbTreeNodeBase* x, TRbTreeNodeBase*& root) { +    TRbTreeNodeBase* y = x->Left_; +    x->Left_ = y->Right_;      if (y->Right_ != nullptr) -        y->Right_->Parent_ = x;  -    y->Parent_ = x->Parent_;  -  -    if (x == root)  -        root = y;  -    else if (x == x->Parent_->Right_)  -        x->Parent_->Right_ = y;  -    else  -        x->Parent_->Left_ = y;  -    y->Right_ = x;  -    x->Parent_ = y;  +        y->Right_->Parent_ = x; +    y->Parent_ = x->Parent_; + +    if (x == root) +        root = y; +    else if (x == x->Parent_->Right_) +        x->Parent_->Right_ = y; +    else +        x->Parent_->Left_ = y; +    y->Right_ = x; +    x->Parent_ = y;      y->Children_ = x->Children_;      x->Children_ = ((x->Left_) ? x->Left_->Children_ : 0) + ((x->Right_) ? x->Right_->Children_ : 0) + 1; -}  -  -template <class TDummy>  -void TRbGlobal<TDummy>::Rebalance(TRbTreeNodeBase* x, TRbTreeNodeBase*& root) {  -    x->Color_ = RBTreeRed;  -    while (x != root && x->Parent_->Color_ == RBTreeRed) {  -        if (x->Parent_ == x->Parent_->Parent_->Left_) {  -            TRbTreeNodeBase* y = x->Parent_->Parent_->Right_;  -            if (y && y->Color_ == RBTreeRed) {  -                x->Parent_->Color_ = RBTreeBlack;  -                y->Color_ = RBTreeBlack;  -                x->Parent_->Parent_->Color_ = RBTreeRed;  -                x = x->Parent_->Parent_;  -            } else {  -                if (x == x->Parent_->Right_) {  -                    x = x->Parent_;  -                    RotateLeft(x, root);  -                }  -                x->Parent_->Color_ = RBTreeBlack;  -                x->Parent_->Parent_->Color_ = RBTreeRed;  -                RotateRight(x->Parent_->Parent_, root);  -            }  -        } else {  -            TRbTreeNodeBase* y = x->Parent_->Parent_->Left_;  -            if (y && y->Color_ == RBTreeRed) {  -                x->Parent_->Color_ = RBTreeBlack;  -                y->Color_ = RBTreeBlack;  -                x->Parent_->Parent_->Color_ = RBTreeRed;  -                x = x->Parent_->Parent_;  -            } else {  -                if (x == x->Parent_->Left_) {  -                    x = x->Parent_;  -                    RotateRight(x, root);  -                }  -                x->Parent_->Color_ = RBTreeBlack;  -                x->Parent_->Parent_->Color_ = RBTreeRed;  -                RotateLeft(x->Parent_->Parent_, root);  -            }  -        }  -    }  -    root->Color_ = RBTreeBlack;  -}  -  -template <class TDummy>  +} + +template <class TDummy> +void TRbGlobal<TDummy>::Rebalance(TRbTreeNodeBase* x, TRbTreeNodeBase*& root) { +    x->Color_ = RBTreeRed; +    while (x != root && x->Parent_->Color_ == RBTreeRed) { +        if (x->Parent_ == x->Parent_->Parent_->Left_) { +            TRbTreeNodeBase* y = x->Parent_->Parent_->Right_; +            if (y && y->Color_ == RBTreeRed) { +                x->Parent_->Color_ = RBTreeBlack; +                y->Color_ = RBTreeBlack; +                x->Parent_->Parent_->Color_ = RBTreeRed; +                x = x->Parent_->Parent_; +            } else { +                if (x == x->Parent_->Right_) { +                    x = x->Parent_; +                    RotateLeft(x, root); +                } +                x->Parent_->Color_ = RBTreeBlack; +                x->Parent_->Parent_->Color_ = RBTreeRed; +                RotateRight(x->Parent_->Parent_, root); +            } +        } else { +            TRbTreeNodeBase* y = x->Parent_->Parent_->Left_; +            if (y && y->Color_ == RBTreeRed) { +                x->Parent_->Color_ = RBTreeBlack; +                y->Color_ = RBTreeBlack; +                x->Parent_->Parent_->Color_ = RBTreeRed; +                x = x->Parent_->Parent_; +            } else { +                if (x == x->Parent_->Left_) { +                    x = x->Parent_; +                    RotateRight(x, root); +                } +                x->Parent_->Color_ = RBTreeBlack; +                x->Parent_->Parent_->Color_ = RBTreeRed; +                RotateLeft(x->Parent_->Parent_, root); +            } +        } +    } +    root->Color_ = RBTreeBlack; +} + +template <class TDummy>  void TRbGlobal<TDummy>::RecalcChildren(TRbTreeNodeBase* x) {      x->Children_ = ((x->Left_) ? x->Left_->Children_ : 0) + ((x->Right_) ? x->Right_->Children_ : 0) + 1;  } @@ -625,46 +625,46 @@ void TRbGlobal<TDummy>::DecrementChildrenUntilRoot(TRbTreeNodeBase* x, TRbTreeNo  }  template <class TDummy> -TRbTreeNodeBase* TRbGlobal<TDummy>::RebalanceForErase(TRbTreeNodeBase* z,  -                                                      TRbTreeNodeBase*& root,  -                                                      TRbTreeNodeBase*& leftmost,  -                                                      TRbTreeNodeBase*& rightmost) {  -    TRbTreeNodeBase* y = z;  -    TRbTreeNodeBase* x;  -    TRbTreeNodeBase* x_parent;  -  +TRbTreeNodeBase* TRbGlobal<TDummy>::RebalanceForErase(TRbTreeNodeBase* z, +                                                      TRbTreeNodeBase*& root, +                                                      TRbTreeNodeBase*& leftmost, +                                                      TRbTreeNodeBase*& rightmost) { +    TRbTreeNodeBase* y = z; +    TRbTreeNodeBase* x; +    TRbTreeNodeBase* x_parent; +      if (y->Left_ == nullptr) // z has at most one non-null child. y == z. -        x = y->Right_;       // x might be null.  -    else {  -        if (y->Right_ == nullptr)                        // z has exactly one non-null child. y == z.  -            x = y->Left_;                                // x is not null.  -        else {                                           // z has two non-null children.  Set y to  -            y = TRbTreeNodeBase::MinimumNode(y->Right_); //   z's successor.  x might be null.  -            x = y->Right_;  -        }  -    }  -  -    if (y != z) {  -        // relink y in place of z.  y is z's successor  -        z->Left_->Parent_ = y;  -        y->Left_ = z->Left_;  -        if (y != z->Right_) {  -            x_parent = y->Parent_;  -            if (x)  -                x->Parent_ = y->Parent_;  -            y->Parent_->Left_ = x; // y must be a child of mLeft  -            y->Right_ = z->Right_;  -            z->Right_->Parent_ = y;  -        } else  -            x_parent = y;  -        if (root == z)  -            root = y;  -        else if (z->Parent_->Left_ == z)  -            z->Parent_->Left_ = y;  -        else  -            z->Parent_->Right_ = y;  -        y->Parent_ = z->Parent_;  -        DoSwap(y->Color_, z->Color_);  +        x = y->Right_;       // x might be null. +    else { +        if (y->Right_ == nullptr)                        // z has exactly one non-null child. y == z. +            x = y->Left_;                                // x is not null. +        else {                                           // z has two non-null children.  Set y to +            y = TRbTreeNodeBase::MinimumNode(y->Right_); //   z's successor.  x might be null. +            x = y->Right_; +        } +    } + +    if (y != z) { +        // relink y in place of z.  y is z's successor +        z->Left_->Parent_ = y; +        y->Left_ = z->Left_; +        if (y != z->Right_) { +            x_parent = y->Parent_; +            if (x) +                x->Parent_ = y->Parent_; +            y->Parent_->Left_ = x; // y must be a child of mLeft +            y->Right_ = z->Right_; +            z->Right_->Parent_ = y; +        } else +            x_parent = y; +        if (root == z) +            root = y; +        else if (z->Parent_->Left_ == z) +            z->Parent_->Left_ = y; +        else +            z->Parent_->Right_ = y; +        y->Parent_ = z->Parent_; +        DoSwap(y->Color_, z->Color_);          RecalcChildren(y);          if (x_parent != y) { @@ -673,146 +673,146 @@ TRbTreeNodeBase* TRbGlobal<TDummy>::RebalanceForErase(TRbTreeNodeBase* z,          if (x_parent != root) {              DecrementChildrenUntilRoot(x_parent->Parent_, root);          } -        y = z;  -        // y now points to node to be actually deleted  -    } else {  -        // y == z  -        x_parent = y->Parent_;  -        if (x)  -            x->Parent_ = y->Parent_;  -        if (root == z)  -            root = x;  -        else {  -            if (z->Parent_->Left_ == z)  -                z->Parent_->Left_ = x;  -            else  -                z->Parent_->Right_ = x;  -            DecrementChildrenUntilRoot(z->Parent_, root); // we lost y  -        }  -  -        if (leftmost == z) {  +        y = z; +        // y now points to node to be actually deleted +    } else { +        // y == z +        x_parent = y->Parent_; +        if (x) +            x->Parent_ = y->Parent_; +        if (root == z) +            root = x; +        else { +            if (z->Parent_->Left_ == z) +                z->Parent_->Left_ = x; +            else +                z->Parent_->Right_ = x; +            DecrementChildrenUntilRoot(z->Parent_, root); // we lost y +        } + +        if (leftmost == z) {              if (z->Right_ == nullptr) // z->mLeft must be null also -                leftmost = z->Parent_;  -            // makes leftmost == _M_header if z == root  -            else  -                leftmost = TRbTreeNodeBase::MinimumNode(x);  -        }  -        if (rightmost == z) {  +                leftmost = z->Parent_; +            // makes leftmost == _M_header if z == root +            else +                leftmost = TRbTreeNodeBase::MinimumNode(x); +        } +        if (rightmost == z) {              if (z->Left_ == nullptr) // z->mRight must be null also -                rightmost = z->Parent_;  -            // makes rightmost == _M_header if z == root  -            else // x == z->mLeft  -                rightmost = TRbTreeNodeBase::MaximumNode(x);  -        }  -    }  -  -    if (y->Color_ != RBTreeRed) {  +                rightmost = z->Parent_; +            // makes rightmost == _M_header if z == root +            else // x == z->mLeft +                rightmost = TRbTreeNodeBase::MaximumNode(x); +        } +    } + +    if (y->Color_ != RBTreeRed) {          while (x != root && (x == nullptr || x->Color_ == RBTreeBlack)) -            if (x == x_parent->Left_) {  -                TRbTreeNodeBase* w = x_parent->Right_;  -                if (w->Color_ == RBTreeRed) {  -                    w->Color_ = RBTreeBlack;  -                    x_parent->Color_ = RBTreeRed;  -                    RotateLeft(x_parent, root);  -                    w = x_parent->Right_;  -                }  +            if (x == x_parent->Left_) { +                TRbTreeNodeBase* w = x_parent->Right_; +                if (w->Color_ == RBTreeRed) { +                    w->Color_ = RBTreeBlack; +                    x_parent->Color_ = RBTreeRed; +                    RotateLeft(x_parent, root); +                    w = x_parent->Right_; +                }                  if ((w->Left_ == nullptr || -                     w->Left_->Color_ == RBTreeBlack) &&  +                     w->Left_->Color_ == RBTreeBlack) &&                      (w->Right_ == nullptr || -                     w->Right_->Color_ == RBTreeBlack))  -                {  -                    w->Color_ = RBTreeRed;  -                    x = x_parent;  -                    x_parent = x_parent->Parent_;  -                } else {  -                    if (w->Right_ == nullptr || w->Right_->Color_ == RBTreeBlack) {  -                        if (w->Left_)  -                            w->Left_->Color_ = RBTreeBlack;  -                        w->Color_ = RBTreeRed;  -                        RotateRight(w, root);  -                        w = x_parent->Right_;  -                    }  -                    w->Color_ = x_parent->Color_;  -                    x_parent->Color_ = RBTreeBlack;  -                    if (w->Right_)  -                        w->Right_->Color_ = RBTreeBlack;  -                    RotateLeft(x_parent, root);  -                    break;  -                }  -            } else {  -                // same as above, with mRight <-> mLeft.  -                TRbTreeNodeBase* w = x_parent->Left_;  -                if (w->Color_ == RBTreeRed) {  -                    w->Color_ = RBTreeBlack;  -                    x_parent->Color_ = RBTreeRed;  -                    RotateRight(x_parent, root);  -                    w = x_parent->Left_;  -                }  +                     w->Right_->Color_ == RBTreeBlack)) +                { +                    w->Color_ = RBTreeRed; +                    x = x_parent; +                    x_parent = x_parent->Parent_; +                } else { +                    if (w->Right_ == nullptr || w->Right_->Color_ == RBTreeBlack) { +                        if (w->Left_) +                            w->Left_->Color_ = RBTreeBlack; +                        w->Color_ = RBTreeRed; +                        RotateRight(w, root); +                        w = x_parent->Right_; +                    } +                    w->Color_ = x_parent->Color_; +                    x_parent->Color_ = RBTreeBlack; +                    if (w->Right_) +                        w->Right_->Color_ = RBTreeBlack; +                    RotateLeft(x_parent, root); +                    break; +                } +            } else { +                // same as above, with mRight <-> mLeft. +                TRbTreeNodeBase* w = x_parent->Left_; +                if (w->Color_ == RBTreeRed) { +                    w->Color_ = RBTreeBlack; +                    x_parent->Color_ = RBTreeRed; +                    RotateRight(x_parent, root); +                    w = x_parent->Left_; +                }                  if ((w->Right_ == nullptr || -                     w->Right_->Color_ == RBTreeBlack) &&  +                     w->Right_->Color_ == RBTreeBlack) &&                      (w->Left_ == nullptr || -                     w->Left_->Color_ == RBTreeBlack))  -                {  -                    w->Color_ = RBTreeRed;  -                    x = x_parent;  -                    x_parent = x_parent->Parent_;  -                } else {  -                    if (w->Left_ == nullptr || w->Left_->Color_ == RBTreeBlack) {  -                        if (w->Right_)  -                            w->Right_->Color_ = RBTreeBlack;  -                        w->Color_ = RBTreeRed;  -                        RotateLeft(w, root);  -                        w = x_parent->Left_;  -                    }  -                    w->Color_ = x_parent->Color_;  -                    x_parent->Color_ = RBTreeBlack;  -                    if (w->Left_)  -                        w->Left_->Color_ = RBTreeBlack;  -                    RotateRight(x_parent, root);  -                    break;  -                }  -            }  -        if (x)  -            x->Color_ = RBTreeBlack;  -    }  -    return y;  -}  -  -template <class TDummy>  -TRbTreeNodeBase* TRbGlobal<TDummy>::DecrementNode(TRbTreeNodeBase* Node_) {  -    if (Node_->Color_ == RBTreeRed && Node_->Parent_->Parent_ == Node_)  -        Node_ = Node_->Right_;  +                     w->Left_->Color_ == RBTreeBlack)) +                { +                    w->Color_ = RBTreeRed; +                    x = x_parent; +                    x_parent = x_parent->Parent_; +                } else { +                    if (w->Left_ == nullptr || w->Left_->Color_ == RBTreeBlack) { +                        if (w->Right_) +                            w->Right_->Color_ = RBTreeBlack; +                        w->Color_ = RBTreeRed; +                        RotateLeft(w, root); +                        w = x_parent->Left_; +                    } +                    w->Color_ = x_parent->Color_; +                    x_parent->Color_ = RBTreeBlack; +                    if (w->Left_) +                        w->Left_->Color_ = RBTreeBlack; +                    RotateRight(x_parent, root); +                    break; +                } +            } +        if (x) +            x->Color_ = RBTreeBlack; +    } +    return y; +} + +template <class TDummy> +TRbTreeNodeBase* TRbGlobal<TDummy>::DecrementNode(TRbTreeNodeBase* Node_) { +    if (Node_->Color_ == RBTreeRed && Node_->Parent_->Parent_ == Node_) +        Node_ = Node_->Right_;      else if (Node_->Left_ != nullptr) { -        Node_ = TRbTreeNodeBase::MaximumNode(Node_->Left_);  -    } else {  -        TBasePtr y = Node_->Parent_;  -        while (Node_ == y->Left_) {  -            Node_ = y;  -            y = y->Parent_;  -        }  -        Node_ = y;  -    }  -    return Node_;  -}  -  -template <class TDummy>  -TRbTreeNodeBase* TRbGlobal<TDummy>::IncrementNode(TRbTreeNodeBase* Node_) {  +        Node_ = TRbTreeNodeBase::MaximumNode(Node_->Left_); +    } else { +        TBasePtr y = Node_->Parent_; +        while (Node_ == y->Left_) { +            Node_ = y; +            y = y->Parent_; +        } +        Node_ = y; +    } +    return Node_; +} + +template <class TDummy> +TRbTreeNodeBase* TRbGlobal<TDummy>::IncrementNode(TRbTreeNodeBase* Node_) {      if (Node_->Right_ != nullptr) { -        Node_ = TRbTreeNodeBase::MinimumNode(Node_->Right_);  -    } else {  -        TBasePtr y = Node_->Parent_;  -        while (Node_ == y->Right_) {  -            Node_ = y;  -            y = y->Parent_;  -        }  -        // check special case: This is necessary if mNode is the  -        // _M_head and the tree contains only a single node y. In  -        // that case parent, left and right all point to y!  -        if (Node_->Right_ != y)  -            Node_ = y;  -    }  -    return Node_;  -}  -  -#undef RBTreeRed  -#undef RBTreeBlack  +        Node_ = TRbTreeNodeBase::MinimumNode(Node_->Right_); +    } else { +        TBasePtr y = Node_->Parent_; +        while (Node_ == y->Right_) { +            Node_ = y; +            y = y->Parent_; +        } +        // check special case: This is necessary if mNode is the +        // _M_head and the tree contains only a single node y. In +        // that case parent, left and right all point to y! +        if (Node_->Right_ != y) +            Node_ = y; +    } +    return Node_; +} + +#undef RBTreeRed +#undef RBTreeBlack diff --git a/library/cpp/containers/intrusive_rb_tree/rb_tree_ut.cpp b/library/cpp/containers/intrusive_rb_tree/rb_tree_ut.cpp index cea3ab44218..c34ed1fd9b4 100644 --- a/library/cpp/containers/intrusive_rb_tree/rb_tree_ut.cpp +++ b/library/cpp/containers/intrusive_rb_tree/rb_tree_ut.cpp @@ -1,82 +1,82 @@ -#include "rb_tree.h"  -  +#include "rb_tree.h" +  #include <library/cpp/testing/unittest/registar.h> -  -#include <util/random/fast.h>  -#include <util/random/easy.h>  + +#include <util/random/fast.h> +#include <util/random/easy.h>  #include <util/random/shuffle.h> -  -class TRedBlackTreeTest: public TTestBase {  -    struct TCmp {  -        template <class T>  -        static inline bool Compare(const T& l, const T& r) {  -            return l.N < r.N;  -        }  -  -        template <class T>  -        static inline bool Compare(const T& l, int r) {  -            return l.N < r;  -        }  -  -        template <class T>  -        static inline bool Compare(int l, const T& r) {  -            return l < r.N;  -        }  -    };  -  -    class TNode: public TRbTreeItem<TNode, TCmp> {  -    public:  + +class TRedBlackTreeTest: public TTestBase { +    struct TCmp { +        template <class T> +        static inline bool Compare(const T& l, const T& r) { +            return l.N < r.N; +        } + +        template <class T> +        static inline bool Compare(const T& l, int r) { +            return l.N < r; +        } + +        template <class T> +        static inline bool Compare(int l, const T& r) { +            return l < r.N; +        } +    }; + +    class TNode: public TRbTreeItem<TNode, TCmp> { +    public:          inline TNode(int n) noexcept -            : N(n)  -        {  -        }  -  -        int N;  -    };  -  +            : N(n) +        { +        } + +        int N; +    }; +      using TTree = TRbTree<TNode, TCmp>; -  -    UNIT_TEST_SUITE(TRedBlackTreeTest);  -    UNIT_TEST(TestEmpty)  -    UNIT_TEST(TestInsert)  -    UNIT_TEST(TestErase)  -    UNIT_TEST(TestFind)  -    UNIT_TEST(TestStress)  + +    UNIT_TEST_SUITE(TRedBlackTreeTest); +    UNIT_TEST(TestEmpty) +    UNIT_TEST(TestInsert) +    UNIT_TEST(TestErase) +    UNIT_TEST(TestFind) +    UNIT_TEST(TestStress)      UNIT_TEST(TestGettingIndexWithDifferentValues)      UNIT_TEST(TestCheckChildrenAfterErase)      UNIT_TEST(TestGettingIndexWithDifferentValuesAfterErase)      UNIT_TEST(TestGettingIndexWithEqualValues)      UNIT_TEST(TestLessCountOnEmptyTree) -    UNIT_TEST_SUITE_END();  -  -private:  -    inline void TestStress() {  +    UNIT_TEST_SUITE_END(); + +private: +    inline void TestStress() {          TVector<TSimpleSharedPtr<TNode>> nodes; -  -        for (int i = 0; i < 1000; ++i) {  -            nodes.push_back(new TNode(i));  -        }  -  -        TTree tree;  -        TReallyFastRng32 rnd(Random());  -  -        for (size_t i = 0; i < 1000000; ++i) {  -            tree.Insert(nodes[rnd.Uniform(nodes.size())].Get());  -        }  -  -        for (TTree::TConstIterator it = tree.Begin(); it != tree.End();) {  -            const int v1 = it->N;  -  -            if (++it == tree.End()) {  -                break;  -            }  -  -            const int v2 = it->N;  -  -            UNIT_ASSERT(v1 < v2);  -        }  -    }  -  + +        for (int i = 0; i < 1000; ++i) { +            nodes.push_back(new TNode(i)); +        } + +        TTree tree; +        TReallyFastRng32 rnd(Random()); + +        for (size_t i = 0; i < 1000000; ++i) { +            tree.Insert(nodes[rnd.Uniform(nodes.size())].Get()); +        } + +        for (TTree::TConstIterator it = tree.Begin(); it != tree.End();) { +            const int v1 = it->N; + +            if (++it == tree.End()) { +                break; +            } + +            const int v2 = it->N; + +            UNIT_ASSERT(v1 < v2); +        } +    } +      inline void TestGettingIndexWithDifferentValues() {          TVector<TSimpleSharedPtr<TNode>> nodes;          size_t N = 1000; @@ -202,97 +202,97 @@ private:          }      } -    inline void TestFind() {  -        TTree tree;  -  -        {  -            TNode n1(1);  -            TNode n2(2);  -            TNode n3(3);  -  -            tree.Insert(n1);  -            tree.Insert(n2);  -            tree.Insert(n3);  -  -            UNIT_ASSERT_EQUAL(tree.Find(1)->N, 1);  -            UNIT_ASSERT_EQUAL(tree.Find(2)->N, 2);  -            UNIT_ASSERT_EQUAL(tree.Find(3)->N, 3);  -  -            UNIT_ASSERT(!tree.Find(0));  -            UNIT_ASSERT(!tree.Find(4));  -            UNIT_ASSERT(!tree.Find(1234567));  -        }  -  -        UNIT_ASSERT(tree.Empty());  -    }  -  -    inline void TestEmpty() {  -        TTree tree;  -  -        UNIT_ASSERT(tree.Empty());  -        UNIT_ASSERT_EQUAL(tree.Begin(), tree.End());  -    }  -  -    inline void TestInsert() {  -        TTree tree;  -  -        {  -            TNode n1(1);  -            TNode n2(2);  -            TNode n3(3);  -  -            tree.Insert(n1);  -            tree.Insert(n2);  -            tree.Insert(n3);  -  -            TTree::TConstIterator it = tree.Begin();  -  -            UNIT_ASSERT_EQUAL((it++)->N, 1);  -            UNIT_ASSERT_EQUAL((it++)->N, 2);  -            UNIT_ASSERT_EQUAL((it++)->N, 3);  -            UNIT_ASSERT_EQUAL(it, tree.End());  -        }  -  -        UNIT_ASSERT(tree.Empty());  -    }  -  -    inline void TestErase() {  -        TTree tree;  -  -        {  -            TNode n1(1);  -            TNode n2(2);  -            TNode n3(3);  -  -            tree.Insert(n1);  -            tree.Insert(n2);  -            tree.Insert(n3);  -  -            TTree::TIterator it = tree.Begin();  -  -            tree.Erase(it++);  -  -            UNIT_ASSERT_EQUAL(it, tree.Begin());  -            UNIT_ASSERT_EQUAL(it->N, 2);  -  -            tree.Erase(it++);  -  -            UNIT_ASSERT_EQUAL(it, tree.Begin());  -            UNIT_ASSERT_EQUAL(it->N, 3);  -  -            tree.Erase(it++);  -  -            UNIT_ASSERT_EQUAL(it, tree.Begin());  -            UNIT_ASSERT_EQUAL(it, tree.End());  -        }  -  -        UNIT_ASSERT(tree.Empty());  -    }  +    inline void TestFind() { +        TTree tree; + +        { +            TNode n1(1); +            TNode n2(2); +            TNode n3(3); + +            tree.Insert(n1); +            tree.Insert(n2); +            tree.Insert(n3); + +            UNIT_ASSERT_EQUAL(tree.Find(1)->N, 1); +            UNIT_ASSERT_EQUAL(tree.Find(2)->N, 2); +            UNIT_ASSERT_EQUAL(tree.Find(3)->N, 3); + +            UNIT_ASSERT(!tree.Find(0)); +            UNIT_ASSERT(!tree.Find(4)); +            UNIT_ASSERT(!tree.Find(1234567)); +        } + +        UNIT_ASSERT(tree.Empty()); +    } + +    inline void TestEmpty() { +        TTree tree; + +        UNIT_ASSERT(tree.Empty()); +        UNIT_ASSERT_EQUAL(tree.Begin(), tree.End()); +    } + +    inline void TestInsert() { +        TTree tree; + +        { +            TNode n1(1); +            TNode n2(2); +            TNode n3(3); + +            tree.Insert(n1); +            tree.Insert(n2); +            tree.Insert(n3); + +            TTree::TConstIterator it = tree.Begin(); + +            UNIT_ASSERT_EQUAL((it++)->N, 1); +            UNIT_ASSERT_EQUAL((it++)->N, 2); +            UNIT_ASSERT_EQUAL((it++)->N, 3); +            UNIT_ASSERT_EQUAL(it, tree.End()); +        } + +        UNIT_ASSERT(tree.Empty()); +    } + +    inline void TestErase() { +        TTree tree; + +        { +            TNode n1(1); +            TNode n2(2); +            TNode n3(3); + +            tree.Insert(n1); +            tree.Insert(n2); +            tree.Insert(n3); + +            TTree::TIterator it = tree.Begin(); + +            tree.Erase(it++); + +            UNIT_ASSERT_EQUAL(it, tree.Begin()); +            UNIT_ASSERT_EQUAL(it->N, 2); + +            tree.Erase(it++); + +            UNIT_ASSERT_EQUAL(it, tree.Begin()); +            UNIT_ASSERT_EQUAL(it->N, 3); + +            tree.Erase(it++); + +            UNIT_ASSERT_EQUAL(it, tree.Begin()); +            UNIT_ASSERT_EQUAL(it, tree.End()); +        } + +        UNIT_ASSERT(tree.Empty()); +    }      inline void TestLessCountOnEmptyTree() {          TTree tree;          UNIT_ASSERT_VALUES_EQUAL(0, tree.LessCount(TNode(1)));      } -};  -  -UNIT_TEST_SUITE_REGISTRATION(TRedBlackTreeTest);  +}; + +UNIT_TEST_SUITE_REGISTRATION(TRedBlackTreeTest); diff --git a/library/cpp/containers/intrusive_rb_tree/ut/ya.make b/library/cpp/containers/intrusive_rb_tree/ut/ya.make index 15c74020dc7..6f1e3b38ee0 100644 --- a/library/cpp/containers/intrusive_rb_tree/ut/ya.make +++ b/library/cpp/containers/intrusive_rb_tree/ut/ya.make @@ -1,12 +1,12 @@  UNITTEST_FOR(library/cpp/containers/intrusive_rb_tree) -  +  OWNER(      pg      g:util  ) -  -SRCS(  -    rb_tree_ut.cpp  -)  -  -END()  + +SRCS( +    rb_tree_ut.cpp +) + +END() diff --git a/library/cpp/containers/intrusive_rb_tree/ya.make b/library/cpp/containers/intrusive_rb_tree/ya.make index ff2c0b5adfa..2e5eddcfbe8 100644 --- a/library/cpp/containers/intrusive_rb_tree/ya.make +++ b/library/cpp/containers/intrusive_rb_tree/ya.make @@ -1,12 +1,12 @@ -LIBRARY()  -  +LIBRARY() +  OWNER(      pg      g:util  ) -  -SRCS(  -    rb_tree.cpp  -)  -  -END()  + +SRCS( +    rb_tree.cpp +) + +END() diff --git a/library/cpp/containers/paged_vector/paged_vector.cpp b/library/cpp/containers/paged_vector/paged_vector.cpp index 52f91880bf7..e354caf09d4 100644 --- a/library/cpp/containers/paged_vector/paged_vector.cpp +++ b/library/cpp/containers/paged_vector/paged_vector.cpp @@ -1 +1 @@ -#include "paged_vector.h"  +#include "paged_vector.h" diff --git a/library/cpp/containers/paged_vector/paged_vector.h b/library/cpp/containers/paged_vector/paged_vector.h index dbd1486a719..6a3657d3ea5 100644 --- a/library/cpp/containers/paged_vector/paged_vector.h +++ b/library/cpp/containers/paged_vector/paged_vector.h @@ -4,429 +4,429 @@  #include <util/generic/vector.h>  #include <util/generic/yexception.h> -#include <iterator>  -  +#include <iterator> +  namespace NPagedVector { -    template <class T, ui32 PageSize = 1u << 20, class A = std::allocator<T>>  -    class TPagedVector;  - -    namespace NPrivate {  -        template <class T, class TT, ui32 PageSize, class A>  -        struct TPagedVectorIterator {  -        private:  -            friend class TPagedVector<TT, PageSize, A>;  -            typedef TPagedVector<TT, PageSize, A> TVec;  -            typedef TPagedVectorIterator<T, TT, PageSize, A> TSelf;  -            size_t Offset;  -            TVec* Vector;  - -            template <class T1, class TT1, ui32 PageSize1, class A1>  -            friend struct TPagedVectorIterator;  - -        public:  -            TPagedVectorIterator()  -                : Offset()  -                , Vector()  -            {  -            }  - -            TPagedVectorIterator(TVec* vector, size_t offset)  -                : Offset(offset)  -                , Vector(vector)  -            {  -            }  - -            template <class T1, class TT1, ui32 PageSize1, class A1>  -            TPagedVectorIterator(const TPagedVectorIterator<T1, TT1, PageSize1, A1>& it)  -                : Offset(it.Offset)  -                , Vector(it.Vector)  -            {  -            }  - -            T& operator*() const {  -                return (*Vector)[Offset];  -            }  - -            T* operator->() const {  -                return &(**this);  -            }  - -            template <class T1, class TT1, ui32 PageSize1, class A1>  -            bool operator==(const TPagedVectorIterator<T1, TT1, PageSize1, A1>& it) const {  -                return Offset == it.Offset;  -            }  - -            template <class T1, class TT1, ui32 PageSize1, class A1>  -            bool operator!=(const TPagedVectorIterator<T1, TT1, PageSize1, A1>& it) const {  -                return !(*this == it);  -            }  - -            template <class T1, class TT1, ui32 PageSize1, class A1>  -            bool operator<(const TPagedVectorIterator<T1, TT1, PageSize1, A1>& it) const {  -                return Offset < it.Offset;  -            }  - -            template <class T1, class TT1, ui32 PageSize1, class A1>  -            bool operator<=(const TPagedVectorIterator<T1, TT1, PageSize1, A1>& it) const {  -                return Offset <= it.Offset;  -            }  - -            template <class T1, class TT1, ui32 PageSize1, class A1>  -            bool operator>(const TPagedVectorIterator<T1, TT1, PageSize1, A1>& it) const {  -                return !(*this <= it);  -            }  - -            template <class T1, class TT1, ui32 PageSize1, class A1>  -            bool operator>=(const TPagedVectorIterator<T1, TT1, PageSize1, A1>& it) const {  -                return !(*this < it);  -            }  - -            template <class T1, class TT1, ui32 PageSize1, class A1>  -            ptrdiff_t operator-(const TPagedVectorIterator<T1, TT1, PageSize1, A1>& it) const {  -                return Offset - it.Offset;  -            }  - -            TSelf& operator+=(ptrdiff_t off) {  -                Offset += off;  -                return *this;  -            }  - -            TSelf& operator-=(ptrdiff_t off) {  -                return this->operator+=(-off);  -            }  - -            TSelf& operator++() {  -                return this->operator+=(1);  -            }  - -            TSelf& operator--() {  -                return this->operator+=(-1);  -            }  - -            TSelf operator++(int) {  -                TSelf it = *this;  -                this->operator+=(1);  -                return it;  -            }  - -            TSelf operator--(int) {  -                TSelf it = *this;  -                this->operator+=(-1);  -                return it;  -            }  - -            TSelf operator+(ptrdiff_t off) {  -                TSelf res = *this;  -                res += off;  -                return res;  -            }  - -            TSelf operator-(ptrdiff_t off) {  -                return this->operator+(-off);  -            }  - -            size_t GetOffset() {  -                return Offset;  -            }  -        };  +    template <class T, ui32 PageSize = 1u << 20, class A = std::allocator<T>> +    class TPagedVector; + +    namespace NPrivate { +        template <class T, class TT, ui32 PageSize, class A> +        struct TPagedVectorIterator { +        private: +            friend class TPagedVector<TT, PageSize, A>; +            typedef TPagedVector<TT, PageSize, A> TVec; +            typedef TPagedVectorIterator<T, TT, PageSize, A> TSelf; +            size_t Offset; +            TVec* Vector; + +            template <class T1, class TT1, ui32 PageSize1, class A1> +            friend struct TPagedVectorIterator; + +        public: +            TPagedVectorIterator() +                : Offset() +                , Vector() +            { +            } + +            TPagedVectorIterator(TVec* vector, size_t offset) +                : Offset(offset) +                , Vector(vector) +            { +            } + +            template <class T1, class TT1, ui32 PageSize1, class A1> +            TPagedVectorIterator(const TPagedVectorIterator<T1, TT1, PageSize1, A1>& it) +                : Offset(it.Offset) +                , Vector(it.Vector) +            { +            } + +            T& operator*() const { +                return (*Vector)[Offset]; +            } + +            T* operator->() const { +                return &(**this); +            } + +            template <class T1, class TT1, ui32 PageSize1, class A1> +            bool operator==(const TPagedVectorIterator<T1, TT1, PageSize1, A1>& it) const { +                return Offset == it.Offset; +            } + +            template <class T1, class TT1, ui32 PageSize1, class A1> +            bool operator!=(const TPagedVectorIterator<T1, TT1, PageSize1, A1>& it) const { +                return !(*this == it); +            } + +            template <class T1, class TT1, ui32 PageSize1, class A1> +            bool operator<(const TPagedVectorIterator<T1, TT1, PageSize1, A1>& it) const { +                return Offset < it.Offset; +            } + +            template <class T1, class TT1, ui32 PageSize1, class A1> +            bool operator<=(const TPagedVectorIterator<T1, TT1, PageSize1, A1>& it) const { +                return Offset <= it.Offset; +            } + +            template <class T1, class TT1, ui32 PageSize1, class A1> +            bool operator>(const TPagedVectorIterator<T1, TT1, PageSize1, A1>& it) const { +                return !(*this <= it); +            } + +            template <class T1, class TT1, ui32 PageSize1, class A1> +            bool operator>=(const TPagedVectorIterator<T1, TT1, PageSize1, A1>& it) const { +                return !(*this < it); +            } + +            template <class T1, class TT1, ui32 PageSize1, class A1> +            ptrdiff_t operator-(const TPagedVectorIterator<T1, TT1, PageSize1, A1>& it) const { +                return Offset - it.Offset; +            } + +            TSelf& operator+=(ptrdiff_t off) { +                Offset += off; +                return *this; +            } + +            TSelf& operator-=(ptrdiff_t off) { +                return this->operator+=(-off); +            } + +            TSelf& operator++() { +                return this->operator+=(1); +            } + +            TSelf& operator--() { +                return this->operator+=(-1); +            } + +            TSelf operator++(int) { +                TSelf it = *this; +                this->operator+=(1); +                return it; +            } + +            TSelf operator--(int) { +                TSelf it = *this; +                this->operator+=(-1); +                return it; +            } + +            TSelf operator+(ptrdiff_t off) { +                TSelf res = *this; +                res += off; +                return res; +            } + +            TSelf operator-(ptrdiff_t off) { +                return this->operator+(-off); +            } + +            size_t GetOffset() { +                return Offset; +            } +        };      }  } -namespace std {  -    template <class T, class TT, ui32 PageSize, class A>  -    struct iterator_traits<NPagedVector::NPrivate::TPagedVectorIterator<T, TT, PageSize, A>> {  -        typedef ptrdiff_t difference_type;  -        typedef T value_type;  -        typedef T* pointer;  -        typedef T& reference;  -        typedef random_access_iterator_tag iterator_category;  -    };  +namespace std { +    template <class T, class TT, ui32 PageSize, class A> +    struct iterator_traits<NPagedVector::NPrivate::TPagedVectorIterator<T, TT, PageSize, A>> { +        typedef ptrdiff_t difference_type; +        typedef T value_type; +        typedef T* pointer; +        typedef T& reference; +        typedef random_access_iterator_tag iterator_category; +    };  }  namespace NPagedVector { -    //2-level radix tree  -    template <class T, ui32 PageSize, class A>  -    class TPagedVector: private TVector<TSimpleSharedPtr<TVector<T, A>>, A> {  -        static_assert(PageSize, "expect PageSize");  - -        typedef TVector<T, A> TPage;  -        typedef TVector<TSimpleSharedPtr<TPage>, A> TPages;  -        typedef TPagedVector<T, PageSize, A> TSelf;  - -    public:  -        typedef NPrivate::TPagedVectorIterator<T, T, PageSize, A> iterator;  -        typedef NPrivate::TPagedVectorIterator<const T, T, PageSize, A> const_iterator;  -        typedef std::reverse_iterator<iterator> reverse_iterator;  -        typedef std::reverse_iterator<const_iterator> const_reverse_iterator;  -        typedef T value_type;  -        typedef value_type& reference;  -        typedef const value_type& const_reference;  - -        TPagedVector() = default;  - -        template <typename TIter>  -        TPagedVector(TIter b, TIter e) {  -            append(b, e);  -        }  - -        iterator begin() {  -            return iterator(this, 0);  -        }  - -        const_iterator begin() const {  -            return const_iterator((TSelf*)this, 0);  -        }  - -        iterator end() {  -            return iterator(this, size());  -        }  - -        const_iterator end() const {  -            return const_iterator((TSelf*)this, size());  -        }  - -        reverse_iterator rbegin() {  -            return reverse_iterator(end());  -        }  - -        const_reverse_iterator rbegin() const {  -            return const_reverse_iterator(end());  -        }  - -        reverse_iterator rend() {  -            return reverse_iterator(begin());  -        }  - -        const_reverse_iterator rend() const {  -            return const_reverse_iterator(begin());  -        }  - -        void swap(TSelf& v) {  -            TPages::swap((TPages&)v);  -        }  - -    private:  -        static size_t PageNumber(size_t idx) {  -            return idx / PageSize;  -        }  - -        static size_t InPageIndex(size_t idx) {  -            return idx % PageSize;  -        }  - -        static size_t Index(size_t pnum, size_t poff) {  -            return pnum * PageSize + poff;  -        }  - -        TPage& PageAt(size_t pnum) const {  -            return *TPages::at(pnum);  -        }  - -        TPage& CurrentPage() const {  -            return *TPages::back();  -        }  - -        size_t CurrentPageSize() const {  -            return TPages::empty() ? 0 : CurrentPage().size();  -        }  - -        size_t NPages() const {  -            return TPages::size();  -        }  - -        void AllocateNewPage() {  -            TPages::push_back(new TPage());  -            CurrentPage().reserve(PageSize);  -        }  - -        void MakeNewPage() {  +    //2-level radix tree +    template <class T, ui32 PageSize, class A> +    class TPagedVector: private TVector<TSimpleSharedPtr<TVector<T, A>>, A> { +        static_assert(PageSize, "expect PageSize"); + +        typedef TVector<T, A> TPage; +        typedef TVector<TSimpleSharedPtr<TPage>, A> TPages; +        typedef TPagedVector<T, PageSize, A> TSelf; + +    public: +        typedef NPrivate::TPagedVectorIterator<T, T, PageSize, A> iterator; +        typedef NPrivate::TPagedVectorIterator<const T, T, PageSize, A> const_iterator; +        typedef std::reverse_iterator<iterator> reverse_iterator; +        typedef std::reverse_iterator<const_iterator> const_reverse_iterator; +        typedef T value_type; +        typedef value_type& reference; +        typedef const value_type& const_reference; + +        TPagedVector() = default; + +        template <typename TIter> +        TPagedVector(TIter b, TIter e) { +            append(b, e); +        } + +        iterator begin() { +            return iterator(this, 0); +        } + +        const_iterator begin() const { +            return const_iterator((TSelf*)this, 0); +        } + +        iterator end() { +            return iterator(this, size()); +        } + +        const_iterator end() const { +            return const_iterator((TSelf*)this, size()); +        } + +        reverse_iterator rbegin() { +            return reverse_iterator(end()); +        } + +        const_reverse_iterator rbegin() const { +            return const_reverse_iterator(end()); +        } + +        reverse_iterator rend() { +            return reverse_iterator(begin()); +        } + +        const_reverse_iterator rend() const { +            return const_reverse_iterator(begin()); +        } + +        void swap(TSelf& v) { +            TPages::swap((TPages&)v); +        } + +    private: +        static size_t PageNumber(size_t idx) { +            return idx / PageSize; +        } + +        static size_t InPageIndex(size_t idx) { +            return idx % PageSize; +        } + +        static size_t Index(size_t pnum, size_t poff) { +            return pnum * PageSize + poff; +        } + +        TPage& PageAt(size_t pnum) const { +            return *TPages::at(pnum); +        } + +        TPage& CurrentPage() const { +            return *TPages::back(); +        } + +        size_t CurrentPageSize() const { +            return TPages::empty() ? 0 : CurrentPage().size(); +        } + +        size_t NPages() const { +            return TPages::size(); +        } + +        void AllocateNewPage() { +            TPages::push_back(new TPage()); +            CurrentPage().reserve(PageSize); +        } + +        void MakeNewPage() {              AllocateNewPage(); -            CurrentPage().resize(PageSize);  -        }  - -        void PrepareAppend() {  -            if (TPages::empty() || CurrentPage().size() + 1 > PageSize)  -                AllocateNewPage();  -        }  - -    public:  -        size_t size() const {  -            return empty() ? 0 : (NPages() - 1) * PageSize + CurrentPage().size();  -        }  - -        bool empty() const {  -            return TPages::empty() || 1 == NPages() && CurrentPage().empty();  -        }  -  -        explicit operator bool() const noexcept {  -            return !empty();  -        }  - -        void emplace_back() {  -            PrepareAppend();  -            CurrentPage().emplace_back();  -        }  - -        void push_back(const_reference t) {  +            CurrentPage().resize(PageSize); +        } + +        void PrepareAppend() { +            if (TPages::empty() || CurrentPage().size() + 1 > PageSize) +                AllocateNewPage(); +        } + +    public: +        size_t size() const { +            return empty() ? 0 : (NPages() - 1) * PageSize + CurrentPage().size(); +        } + +        bool empty() const { +            return TPages::empty() || 1 == NPages() && CurrentPage().empty(); +        } + +        explicit operator bool() const noexcept { +            return !empty(); +        } + +        void emplace_back() { +            PrepareAppend(); +            CurrentPage().emplace_back(); +        } + +        void push_back(const_reference t) { +            PrepareAppend(); +            CurrentPage().push_back(t); +        } + +        void pop_back() { +            if (CurrentPage().empty()) +                TPages::pop_back(); +            CurrentPage().pop_back(); +        } + +        template <typename TIter> +        void append(TIter b, TIter e) { +            size_t sz = e - b; +            size_t sz1 = Min<size_t>(sz, PageSize - CurrentPageSize()); +            size_t sz2 = (sz - sz1) / PageSize; +            size_t sz3 = (sz - sz1) % PageSize; + +            if (sz1) { +                PrepareAppend(); +                TPage& p = CurrentPage(); +                p.insert(p.end(), b, b + sz1); +            } + +            for (size_t i = 0; i < sz2; ++i) { +                AllocateNewPage(); +                TPage& p = CurrentPage(); +                p.insert(p.end(), b + sz1 + i * PageSize, b + sz1 + (i + 1) * PageSize); +            } + +            if (sz3) { +                AllocateNewPage(); +                TPage& p = CurrentPage(); +                p.insert(p.end(), b + sz1 + sz2 * PageSize, e); +            } +        } + +        iterator erase(iterator it) { +            size_t pnum = PageNumber(it.Offset); +            size_t pidx = InPageIndex(it.Offset); + +            if (CurrentPage().empty()) +                TPages::pop_back(); + +            for (size_t p = NPages() - 1; p > pnum; --p) { +                PageAt(p - 1).push_back(PageAt(p).front()); +                PageAt(p).erase(PageAt(p).begin()); +            } + +            PageAt(pnum).erase(PageAt(pnum).begin() + pidx); +            return it; +        } + +        iterator erase(iterator b, iterator e) { +            // todo : suboptimal! +            while (b != e) { +                b = erase(b); +                --e; +            } + +            return b; +        } + +        iterator insert(iterator it, const value_type& v) { +            size_t pnum = PageNumber(it.Offset); +            size_t pidx = InPageIndex(it.Offset); +              PrepareAppend(); -            CurrentPage().push_back(t);  -        } - -        void pop_back() {  -            if (CurrentPage().empty())  -                TPages::pop_back();  -            CurrentPage().pop_back();  -        } - -        template <typename TIter>  -        void append(TIter b, TIter e) {  -            size_t sz = e - b;  -            size_t sz1 = Min<size_t>(sz, PageSize - CurrentPageSize());  -            size_t sz2 = (sz - sz1) / PageSize;  -            size_t sz3 = (sz - sz1) % PageSize;  -  -            if (sz1) {  -                PrepareAppend();  -                TPage& p = CurrentPage();  -                p.insert(p.end(), b, b + sz1);  -            }  -  -            for (size_t i = 0; i < sz2; ++i) {  -                AllocateNewPage();  -                TPage& p = CurrentPage();  -                p.insert(p.end(), b + sz1 + i * PageSize, b + sz1 + (i + 1) * PageSize);  -            }  -  -            if (sz3) {  -                AllocateNewPage();  -                TPage& p = CurrentPage();  -                p.insert(p.end(), b + sz1 + sz2 * PageSize, e);  -            }  -        } - -        iterator erase(iterator it) {  -            size_t pnum = PageNumber(it.Offset);  -            size_t pidx = InPageIndex(it.Offset);  - -            if (CurrentPage().empty())  -                TPages::pop_back();  - -            for (size_t p = NPages() - 1; p > pnum; --p) {  -                PageAt(p - 1).push_back(PageAt(p).front());  -                PageAt(p).erase(PageAt(p).begin());  -            }  -  -            PageAt(pnum).erase(PageAt(pnum).begin() + pidx);  -            return it;  -        } - -        iterator erase(iterator b, iterator e) {  -            // todo : suboptimal!  -            while (b != e) {  -                b = erase(b);  -                --e;  -            }  - -            return b;  -        } - -        iterator insert(iterator it, const value_type& v) {  -            size_t pnum = PageNumber(it.Offset);  -            size_t pidx = InPageIndex(it.Offset);  - -            PrepareAppend();  - -            for (size_t p = NPages() - 1; p > pnum; --p) {  -                PageAt(p).insert(PageAt(p).begin(), PageAt(p - 1).back());  -                PageAt(p - 1).pop_back();  -            }  - -            PageAt(pnum).insert(PageAt(pnum).begin() + pidx, v);  -            return it;  -        } - -        template <typename TIter>  -        void insert(iterator it, TIter b, TIter e) {  -            // todo : suboptimal!  -            for (; b != e; ++b, ++it)  -                it = insert(it, *b);  -        }  - -        reference front() {  -            return TPages::front()->front();  -        }  - -        const_reference front() const {  -            return TPages::front()->front();  -        }  - -        reference back() {  -            return CurrentPage().back();  -        }  - -        const_reference back() const {  -            return CurrentPage().back();  -        }  - -        void clear() {  -            TPages::clear();  -        }  - -        void resize(size_t sz) {  -            if (sz == size())  -                return;  - -            const size_t npages = NPages();  -            const size_t newwholepages = sz / PageSize;  -            const size_t pagepart = sz % PageSize;  -            const size_t newpages = newwholepages + bool(pagepart);  - -            if (npages && newwholepages >= npages)  -                CurrentPage().resize(PageSize);  - -            if (newpages < npages)  -                TPages::resize(newpages);  -            else  -                for (size_t i = npages; i < newpages; ++i)  -                    MakeNewPage();  - -            if (pagepart)  -                CurrentPage().resize(pagepart);  - -            Y_VERIFY(sz == size(), "%" PRIu64 " %" PRIu64, (ui64)sz, (ui64)size());  -        }  -        reference at(size_t idx) {  -            return TPages::at(PageNumber(idx))->at(InPageIndex(idx));  -        }  +            for (size_t p = NPages() - 1; p > pnum; --p) { +                PageAt(p).insert(PageAt(p).begin(), PageAt(p - 1).back()); +                PageAt(p - 1).pop_back(); +            } -        const_reference at(size_t idx) const {  -            return TPages::at(PageNumber(idx))->at(InPageIndex(idx));  -        }  +            PageAt(pnum).insert(PageAt(pnum).begin() + pidx, v); +            return it; +        } -        reference operator[](size_t idx) {  -            return TPages::operator[](PageNumber(idx))->operator[](InPageIndex(idx));  -        }  +        template <typename TIter> +        void insert(iterator it, TIter b, TIter e) { +            // todo : suboptimal! +            for (; b != e; ++b, ++it) +                it = insert(it, *b); +        } -        const_reference operator[](size_t idx) const {  -            return TPages::operator[](PageNumber(idx))->operator[](InPageIndex(idx));  -        }  +        reference front() { +            return TPages::front()->front(); +        } -        friend bool operator==(const TSelf& a, const TSelf& b) {  -            return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin());  -        }  +        const_reference front() const { +            return TPages::front()->front(); +        } -        friend bool operator<(const TSelf& a, const TSelf& b) {  -            return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end());  -        }  -    };  +        reference back() { +            return CurrentPage().back(); +        } + +        const_reference back() const { +            return CurrentPage().back(); +        } + +        void clear() { +            TPages::clear(); +        } + +        void resize(size_t sz) { +            if (sz == size()) +                return; + +            const size_t npages = NPages(); +            const size_t newwholepages = sz / PageSize; +            const size_t pagepart = sz % PageSize; +            const size_t newpages = newwholepages + bool(pagepart); + +            if (npages && newwholepages >= npages) +                CurrentPage().resize(PageSize); + +            if (newpages < npages) +                TPages::resize(newpages); +            else +                for (size_t i = npages; i < newpages; ++i) +                    MakeNewPage(); + +            if (pagepart) +                CurrentPage().resize(pagepart); + +            Y_VERIFY(sz == size(), "%" PRIu64 " %" PRIu64, (ui64)sz, (ui64)size()); +        } + +        reference at(size_t idx) { +            return TPages::at(PageNumber(idx))->at(InPageIndex(idx)); +        } + +        const_reference at(size_t idx) const { +            return TPages::at(PageNumber(idx))->at(InPageIndex(idx)); +        } + +        reference operator[](size_t idx) { +            return TPages::operator[](PageNumber(idx))->operator[](InPageIndex(idx)); +        } + +        const_reference operator[](size_t idx) const { +            return TPages::operator[](PageNumber(idx))->operator[](InPageIndex(idx)); +        } + +        friend bool operator==(const TSelf& a, const TSelf& b) { +            return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin()); +        } + +        friend bool operator<(const TSelf& a, const TSelf& b) { +            return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end()); +        } +    }; -    namespace NPrivate {  -        typedef std::is_same<std::random_access_iterator_tag, std::iterator_traits<  -                                                                  TPagedVector<ui32>::iterator>::iterator_category>  -            TIteratorCheck;  -        static_assert(TIteratorCheck::value, "expect TIteratorCheck::Result");  +    namespace NPrivate { +        typedef std::is_same<std::random_access_iterator_tag, std::iterator_traits< +                                                                  TPagedVector<ui32>::iterator>::iterator_category> +            TIteratorCheck; +        static_assert(TIteratorCheck::value, "expect TIteratorCheck::Result");      }  } diff --git a/library/cpp/containers/paged_vector/ut/paged_vector_ut.cpp b/library/cpp/containers/paged_vector/ut/paged_vector_ut.cpp index 2904a1d05e5..e867808ee41 100644 --- a/library/cpp/containers/paged_vector/ut/paged_vector_ut.cpp +++ b/library/cpp/containers/paged_vector/ut/paged_vector_ut.cpp @@ -1,378 +1,378 @@  #include <library/cpp/containers/paged_vector/paged_vector.h>  #include <library/cpp/testing/unittest/registar.h> -  -#include <stdexcept>  + +#include <stdexcept>  class TPagedVectorTest: public TTestBase { -    UNIT_TEST_SUITE(TPagedVectorTest);  -    UNIT_TEST(Test0)  -    UNIT_TEST(Test1)  -    UNIT_TEST(Test2)  -    UNIT_TEST(Test3)  -    UNIT_TEST(Test4)  -    UNIT_TEST(Test5)  -    UNIT_TEST(Test6)  -    UNIT_TEST(Test7)  -    UNIT_TEST(TestAt)  -    UNIT_TEST(TestAutoRef)  -    UNIT_TEST(TestIterators)  -    //UNIT_TEST(TestEbo)  -    UNIT_TEST_SUITE_END();  - -private:  -    // Copy-paste of STLPort tests  -    void Test0() {  -        using NPagedVector::TPagedVector;  -        TPagedVector<int, 16> v1; // Empty vector of integers.  -  -        UNIT_ASSERT(v1.empty() == true);  -        UNIT_ASSERT(v1.size() == 0);  - -        for (size_t i = 0; i < 256; ++i) {  -            v1.resize(i + 1);  -            UNIT_ASSERT_VALUES_EQUAL(v1.size(), i + 1);  -        }  - -        for (size_t i = 256; i-- > 0;) {  -            v1.resize(i);  -            UNIT_ASSERT_VALUES_EQUAL(v1.size(), i);  +    UNIT_TEST_SUITE(TPagedVectorTest); +    UNIT_TEST(Test0) +    UNIT_TEST(Test1) +    UNIT_TEST(Test2) +    UNIT_TEST(Test3) +    UNIT_TEST(Test4) +    UNIT_TEST(Test5) +    UNIT_TEST(Test6) +    UNIT_TEST(Test7) +    UNIT_TEST(TestAt) +    UNIT_TEST(TestAutoRef) +    UNIT_TEST(TestIterators) +    //UNIT_TEST(TestEbo) +    UNIT_TEST_SUITE_END(); + +private: +    // Copy-paste of STLPort tests +    void Test0() { +        using NPagedVector::TPagedVector; +        TPagedVector<int, 16> v1; // Empty vector of integers. + +        UNIT_ASSERT(v1.empty() == true); +        UNIT_ASSERT(v1.size() == 0); + +        for (size_t i = 0; i < 256; ++i) { +            v1.resize(i + 1); +            UNIT_ASSERT_VALUES_EQUAL(v1.size(), i + 1); +        } + +        for (size_t i = 256; i-- > 0;) { +            v1.resize(i); +            UNIT_ASSERT_VALUES_EQUAL(v1.size(), i);          } -    }  +    } -    void Test1() {  -        using NPagedVector::TPagedVector;  -        TPagedVector<int, 3> v1; // Empty vector of integers.  +    void Test1() { +        using NPagedVector::TPagedVector; +        TPagedVector<int, 3> v1; // Empty vector of integers. -        UNIT_ASSERT(v1.empty() == true);  -        UNIT_ASSERT(v1.size() == 0);  +        UNIT_ASSERT(v1.empty() == true); +        UNIT_ASSERT(v1.size() == 0); -        // UNIT_ASSERT(v1.max_size() == INT_MAX / sizeof(int));  -        // cout << "max_size = " << v1.max_size() << endl;  -        v1.push_back(42); // Add an integer to the vector.  +        // UNIT_ASSERT(v1.max_size() == INT_MAX / sizeof(int)); +        // cout << "max_size = " << v1.max_size() << endl; +        v1.push_back(42); // Add an integer to the vector. -        UNIT_ASSERT(v1.size() == 1);  +        UNIT_ASSERT(v1.size() == 1); -        UNIT_ASSERT(v1[0] == 42);  +        UNIT_ASSERT(v1[0] == 42); -        {  -            TPagedVector<TPagedVector<int, 3>, 3> vect;  -            vect.resize(10);  -            UNIT_ASSERT(vect.size() == 10);  -            TPagedVector<TPagedVector<int, 3>, 3>::iterator it(vect.begin()), end(vect.end());  -            for (; it != end; ++it) {  -                UNIT_ASSERT((*it).empty());  -                UNIT_ASSERT((*it).size() == 0);  -                UNIT_ASSERT((*it).begin() == (*it).end());  +        { +            TPagedVector<TPagedVector<int, 3>, 3> vect; +            vect.resize(10); +            UNIT_ASSERT(vect.size() == 10); +            TPagedVector<TPagedVector<int, 3>, 3>::iterator it(vect.begin()), end(vect.end()); +            for (; it != end; ++it) { +                UNIT_ASSERT((*it).empty()); +                UNIT_ASSERT((*it).size() == 0); +                UNIT_ASSERT((*it).begin() == (*it).end());              }          } -    }  +    } -    void Test2() {  -        using NPagedVector::TPagedVector;  -        TPagedVector<double, 3> v1; // Empty vector of doubles.  -        v1.push_back(32.1);  -        v1.push_back(40.5);  -        v1.push_back(45.5);  -        v1.push_back(33.4);  -        TPagedVector<double, 3> v2; // Another empty vector of doubles.  -        v2.push_back(3.56);  +    void Test2() { +        using NPagedVector::TPagedVector; +        TPagedVector<double, 3> v1; // Empty vector of doubles. +        v1.push_back(32.1); +        v1.push_back(40.5); +        v1.push_back(45.5); +        v1.push_back(33.4); +        TPagedVector<double, 3> v2; // Another empty vector of doubles. +        v2.push_back(3.56); -        UNIT_ASSERT(v1.size() == 4);  -        UNIT_ASSERT(v1[0] == 32.1);  -        UNIT_ASSERT(v1[1] == 40.5);  -        UNIT_ASSERT(v1[2] == 45.5);  -        UNIT_ASSERT(v1[3] == 33.4);  +        UNIT_ASSERT(v1.size() == 4); +        UNIT_ASSERT(v1[0] == 32.1); +        UNIT_ASSERT(v1[1] == 40.5); +        UNIT_ASSERT(v1[2] == 45.5); +        UNIT_ASSERT(v1[3] == 33.4); -        UNIT_ASSERT(v2.size() == 1);  -        UNIT_ASSERT(v2[0] == 3.56);  -        v1.swap(v2); // Swap the vector's contents.  +        UNIT_ASSERT(v2.size() == 1); +        UNIT_ASSERT(v2[0] == 3.56); +        v1.swap(v2); // Swap the vector's contents. -        UNIT_ASSERT(v1.size() == 1);  -        UNIT_ASSERT(v1[0] == 3.56);  +        UNIT_ASSERT(v1.size() == 1); +        UNIT_ASSERT(v1[0] == 3.56); -        UNIT_ASSERT(v2.size() == 4);  -        UNIT_ASSERT(v2[0] == 32.1);  -        UNIT_ASSERT(v2[1] == 40.5);  -        UNIT_ASSERT(v2[2] == 45.5);  -        UNIT_ASSERT(v2[3] == 33.4);  +        UNIT_ASSERT(v2.size() == 4); +        UNIT_ASSERT(v2[0] == 32.1); +        UNIT_ASSERT(v2[1] == 40.5); +        UNIT_ASSERT(v2[2] == 45.5); +        UNIT_ASSERT(v2[3] == 33.4); -        v2 = v1; // Assign one vector to another.  +        v2 = v1; // Assign one vector to another. -        UNIT_ASSERT(v2.size() == 1);  -        UNIT_ASSERT(v2[0] == 3.56);  +        UNIT_ASSERT(v2.size() == 1); +        UNIT_ASSERT(v2[0] == 3.56); -        v2.pop_back();  -        UNIT_ASSERT(v2.size() == 0);  -        UNIT_ASSERT(v2.empty());  -    }  +        v2.pop_back(); +        UNIT_ASSERT(v2.size() == 0); +        UNIT_ASSERT(v2.empty()); +    } -    void Test3() {  -        using NPagedVector::TPagedVector;  -        TPagedVector<char, 1> v1;  +    void Test3() { +        using NPagedVector::TPagedVector; +        TPagedVector<char, 1> v1; -        v1.push_back('h');  -        v1.push_back('i');  +        v1.push_back('h'); +        v1.push_back('i'); -        UNIT_ASSERT(v1.size() == 2);  -        UNIT_ASSERT(v1[0] == 'h');  -        UNIT_ASSERT(v1[1] == 'i');  +        UNIT_ASSERT(v1.size() == 2); +        UNIT_ASSERT(v1[0] == 'h'); +        UNIT_ASSERT(v1[1] == 'i'); -        TPagedVector<char, 1> v2;  -        v2.resize(v1.size());  +        TPagedVector<char, 1> v2; +        v2.resize(v1.size()); -        for (size_t i = 0; i < v1.size(); ++i)  -            v2[i] = v1[i];  +        for (size_t i = 0; i < v1.size(); ++i) +            v2[i] = v1[i]; -        v2[1] = 'o'; // Replace second character.  +        v2[1] = 'o'; // Replace second character. -        UNIT_ASSERT(v2.size() == 2);  -        UNIT_ASSERT(v2[0] == 'h');  -        UNIT_ASSERT(v2[1] == 'o');  +        UNIT_ASSERT(v2.size() == 2); +        UNIT_ASSERT(v2[0] == 'h'); +        UNIT_ASSERT(v2[1] == 'o'); -        UNIT_ASSERT((v1 == v2) == false);  +        UNIT_ASSERT((v1 == v2) == false); -        UNIT_ASSERT((v1 < v2) == true);  -    }  +        UNIT_ASSERT((v1 < v2) == true); +    } -    void Test4() {  -        using NPagedVector::TPagedVector;  -        TPagedVector<int, 3> v;  -        v.resize(4);  +    void Test4() { +        using NPagedVector::TPagedVector; +        TPagedVector<int, 3> v; +        v.resize(4); -        v[0] = 1;  -        v[1] = 4;  -        v[2] = 9;  -        v[3] = 16;  +        v[0] = 1; +        v[1] = 4; +        v[2] = 9; +        v[3] = 16; -        UNIT_ASSERT(v.front() == 1);  -        UNIT_ASSERT(v.back() == 16);  +        UNIT_ASSERT(v.front() == 1); +        UNIT_ASSERT(v.back() == 16); -        v.push_back(25);  +        v.push_back(25); -        UNIT_ASSERT(v.back() == 25);  -        UNIT_ASSERT(v.size() == 5);  +        UNIT_ASSERT(v.back() == 25); +        UNIT_ASSERT(v.size() == 5); -        v.pop_back();  +        v.pop_back(); -        UNIT_ASSERT(v.back() == 16);  -        UNIT_ASSERT(v.size() == 4);  -    }  +        UNIT_ASSERT(v.back() == 16); +        UNIT_ASSERT(v.size() == 4); +    } -    void Test5() {  -        int array[] = {1, 4, 9, 16};  +    void Test5() { +        int array[] = {1, 4, 9, 16}; -        typedef NPagedVector::TPagedVector<int, 3> TVectorType;  -        TVectorType v(array, array + 4);  +        typedef NPagedVector::TPagedVector<int, 3> TVectorType; +        TVectorType v(array, array + 4); -        UNIT_ASSERT(v.size() == 4);  - -        UNIT_ASSERT(v[0] == 1);  -        UNIT_ASSERT(v[1] == 4);  -        UNIT_ASSERT(v[2] == 9);  -        UNIT_ASSERT(v[3] == 16);  -    }  - -    void Test6() {  -        int array[] = {1, 4, 9, 16, 25, 36};  +        UNIT_ASSERT(v.size() == 4); + +        UNIT_ASSERT(v[0] == 1); +        UNIT_ASSERT(v[1] == 4); +        UNIT_ASSERT(v[2] == 9); +        UNIT_ASSERT(v[3] == 16); +    } + +    void Test6() { +        int array[] = {1, 4, 9, 16, 25, 36}; -        typedef NPagedVector::TPagedVector<int, 3> TVectorType;  -        TVectorType v(array, array + 6);  -        TVectorType::iterator vit;  +        typedef NPagedVector::TPagedVector<int, 3> TVectorType; +        TVectorType v(array, array + 6); +        TVectorType::iterator vit; -        UNIT_ASSERT_VALUES_EQUAL(v.size(), 6u);  -        UNIT_ASSERT(v[0] == 1);  -        UNIT_ASSERT(v[1] == 4);  -        UNIT_ASSERT(v[2] == 9);  -        UNIT_ASSERT(v[3] == 16);  -        UNIT_ASSERT(v[4] == 25);  -        UNIT_ASSERT(v[5] == 36);  +        UNIT_ASSERT_VALUES_EQUAL(v.size(), 6u); +        UNIT_ASSERT(v[0] == 1); +        UNIT_ASSERT(v[1] == 4); +        UNIT_ASSERT(v[2] == 9); +        UNIT_ASSERT(v[3] == 16); +        UNIT_ASSERT(v[4] == 25); +        UNIT_ASSERT(v[5] == 36); -        vit = v.erase(v.begin()); // Erase first element.  -        UNIT_ASSERT(*vit == 4);  +        vit = v.erase(v.begin()); // Erase first element. +        UNIT_ASSERT(*vit == 4); -        UNIT_ASSERT(v.size() == 5);  -        UNIT_ASSERT(v[0] == 4);  -        UNIT_ASSERT(v[1] == 9);  -        UNIT_ASSERT(v[2] == 16);  -        UNIT_ASSERT(v[3] == 25);  -        UNIT_ASSERT(v[4] == 36);  +        UNIT_ASSERT(v.size() == 5); +        UNIT_ASSERT(v[0] == 4); +        UNIT_ASSERT(v[1] == 9); +        UNIT_ASSERT(v[2] == 16); +        UNIT_ASSERT(v[3] == 25); +        UNIT_ASSERT(v[4] == 36); -        vit = v.erase(v.end() - 1); // Erase last element.  -        UNIT_ASSERT(vit == v.end());  +        vit = v.erase(v.end() - 1); // Erase last element. +        UNIT_ASSERT(vit == v.end()); -        UNIT_ASSERT(v.size() == 4);  -        UNIT_ASSERT(v[0] == 4);  -        UNIT_ASSERT(v[1] == 9);  -        UNIT_ASSERT(v[2] == 16);  -        UNIT_ASSERT(v[3] == 25);  +        UNIT_ASSERT(v.size() == 4); +        UNIT_ASSERT(v[0] == 4); +        UNIT_ASSERT(v[1] == 9); +        UNIT_ASSERT(v[2] == 16); +        UNIT_ASSERT(v[3] == 25); -        v.erase(v.begin() + 1, v.end() - 1); // Erase all but first and last.  +        v.erase(v.begin() + 1, v.end() - 1); // Erase all but first and last. -        UNIT_ASSERT(v.size() == 2);  -        UNIT_ASSERT(v[0] == 4);  -        UNIT_ASSERT(v[1] == 25);  -    }  +        UNIT_ASSERT(v.size() == 2); +        UNIT_ASSERT(v[0] == 4); +        UNIT_ASSERT(v[1] == 25); +    } -    void Test7() {  -        int array1[] = {1, 4, 25};  -        int array2[] = {9, 16};  +    void Test7() { +        int array1[] = {1, 4, 25}; +        int array2[] = {9, 16}; -        typedef NPagedVector::TPagedVector<int, 3> TVectorType;  +        typedef NPagedVector::TPagedVector<int, 3> TVectorType; -        TVectorType v(array1, array1 + 3);  -        TVectorType::iterator vit;  -        vit = v.insert(v.begin(), 0); // Insert before first element.  -        UNIT_ASSERT_VALUES_EQUAL(*vit, 0);  - -        vit = v.insert(v.end(), 36); // Insert after last element.  -        UNIT_ASSERT(*vit == 36);  - -        UNIT_ASSERT(v.size() == 5);  -        UNIT_ASSERT(v[0] == 0);  -        UNIT_ASSERT(v[1] == 1);  -        UNIT_ASSERT(v[2] == 4);  -        UNIT_ASSERT(v[3] == 25);  -        UNIT_ASSERT(v[4] == 36);  - -        // Insert contents of array2 before fourth element.  -        v.insert(v.begin() + 3, array2, array2 + 2);  - -        UNIT_ASSERT(v.size() == 7);  - -        UNIT_ASSERT(v[0] == 0);  -        UNIT_ASSERT(v[1] == 1);  -        UNIT_ASSERT(v[2] == 4);  -        UNIT_ASSERT(v[3] == 9);  -        UNIT_ASSERT(v[4] == 16);  -        UNIT_ASSERT(v[5] == 25);  -        UNIT_ASSERT(v[6] == 36);  - -        v.clear();  -        UNIT_ASSERT(v.empty());  -    }  - -    void TestAt() {  -        using NPagedVector::TPagedVector;  -        TPagedVector<int, 3> v;  -        TPagedVector<int, 3> const& cv = v;  - -        v.push_back(10);  -        UNIT_ASSERT(v.at(0) == 10);  -        v.at(0) = 20;  -        UNIT_ASSERT(cv.at(0) == 20);  - -        for (;;) {  -            try {  -                v.at(1) = 20;  -                UNIT_ASSERT(false);  -            } catch (std::out_of_range const&) {  -                return;  -            } catch (...) {  -                UNIT_ASSERT(false);  +        TVectorType v(array1, array1 + 3); +        TVectorType::iterator vit; +        vit = v.insert(v.begin(), 0); // Insert before first element. +        UNIT_ASSERT_VALUES_EQUAL(*vit, 0); + +        vit = v.insert(v.end(), 36); // Insert after last element. +        UNIT_ASSERT(*vit == 36); + +        UNIT_ASSERT(v.size() == 5); +        UNIT_ASSERT(v[0] == 0); +        UNIT_ASSERT(v[1] == 1); +        UNIT_ASSERT(v[2] == 4); +        UNIT_ASSERT(v[3] == 25); +        UNIT_ASSERT(v[4] == 36); + +        // Insert contents of array2 before fourth element. +        v.insert(v.begin() + 3, array2, array2 + 2); + +        UNIT_ASSERT(v.size() == 7); + +        UNIT_ASSERT(v[0] == 0); +        UNIT_ASSERT(v[1] == 1); +        UNIT_ASSERT(v[2] == 4); +        UNIT_ASSERT(v[3] == 9); +        UNIT_ASSERT(v[4] == 16); +        UNIT_ASSERT(v[5] == 25); +        UNIT_ASSERT(v[6] == 36); + +        v.clear(); +        UNIT_ASSERT(v.empty()); +    } + +    void TestAt() { +        using NPagedVector::TPagedVector; +        TPagedVector<int, 3> v; +        TPagedVector<int, 3> const& cv = v; + +        v.push_back(10); +        UNIT_ASSERT(v.at(0) == 10); +        v.at(0) = 20; +        UNIT_ASSERT(cv.at(0) == 20); + +        for (;;) { +            try { +                v.at(1) = 20; +                UNIT_ASSERT(false); +            } catch (std::out_of_range const&) { +                return; +            } catch (...) { +                UNIT_ASSERT(false);              }          } -    }  - -    void TestAutoRef() {  -        using NPagedVector::TPagedVector;  -        typedef TPagedVector<int, 3> TVec;  -        TVec ref;  -        for (int i = 0; i < 5; ++i) {  -            ref.push_back(i);  -        }  - -        TPagedVector<TVec, 3> v_v_int;  -        v_v_int.push_back(ref);  -        v_v_int.push_back(v_v_int[0]);  -        v_v_int.push_back(ref);  -        v_v_int.push_back(v_v_int[0]);  -        v_v_int.push_back(v_v_int[0]);  -        v_v_int.push_back(ref);  - -        TPagedVector<TVec, 3>::iterator vvit(v_v_int.begin()), vvitEnd(v_v_int.end());  -        for (; vvit != vvitEnd; ++vvit) {  -            UNIT_ASSERT(*vvit == ref);  +    } + +    void TestAutoRef() { +        using NPagedVector::TPagedVector; +        typedef TPagedVector<int, 3> TVec; +        TVec ref; +        for (int i = 0; i < 5; ++i) { +            ref.push_back(i); +        } + +        TPagedVector<TVec, 3> v_v_int; +        v_v_int.push_back(ref); +        v_v_int.push_back(v_v_int[0]); +        v_v_int.push_back(ref); +        v_v_int.push_back(v_v_int[0]); +        v_v_int.push_back(v_v_int[0]); +        v_v_int.push_back(ref); + +        TPagedVector<TVec, 3>::iterator vvit(v_v_int.begin()), vvitEnd(v_v_int.end()); +        for (; vvit != vvitEnd; ++vvit) { +            UNIT_ASSERT(*vvit == ref); +        } +    } + +    struct Point { +        int x, y; +    }; + +    struct PointEx: public Point { +        PointEx() +            : builtFromBase(false) +        {          } -    }  - -    struct Point {  -        int x, y;  -    };  - -    struct PointEx: public Point {  -        PointEx()  -            : builtFromBase(false)  -        {  -        }  -        PointEx(const Point&)  -            : builtFromBase(true)  -        {  -        }  - -        bool builtFromBase;  -    };  - -    void TestIterators() {  -        using NPagedVector::TPagedVector;  -        TPagedVector<int, 3> vint;  -        vint.resize(10);  -        TPagedVector<int, 3> const& crvint = vint;  - -        UNIT_ASSERT(vint.begin() == vint.begin());  -        UNIT_ASSERT(crvint.begin() == vint.begin());  -        UNIT_ASSERT(vint.begin() == crvint.begin());  -        UNIT_ASSERT(crvint.begin() == crvint.begin());  - -        UNIT_ASSERT(vint.begin() != vint.end());  -        UNIT_ASSERT(crvint.begin() != vint.end());  -        UNIT_ASSERT(vint.begin() != crvint.end());  -        UNIT_ASSERT(crvint.begin() != crvint.end());  - -        UNIT_ASSERT(vint.rbegin() == vint.rbegin());  -        // Not Standard:  -        //UNIT_ASSERT(vint.rbegin() == crvint.rbegin());  -        //UNIT_ASSERT(crvint.rbegin() == vint.rbegin());  -        UNIT_ASSERT(crvint.rbegin() == crvint.rbegin());  - -        UNIT_ASSERT(vint.rbegin() != vint.rend());  -        // Not Standard:  -        //UNIT_ASSERT(vint.rbegin() != crvint.rend());  -        //UNIT_ASSERT(crvint.rbegin() != vint.rend());  -        UNIT_ASSERT(crvint.rbegin() != crvint.rend());  -    }  - -    /* This test check a potential issue with empty base class  +        PointEx(const Point&) +            : builtFromBase(true) +        { +        } + +        bool builtFromBase; +    }; + +    void TestIterators() { +        using NPagedVector::TPagedVector; +        TPagedVector<int, 3> vint; +        vint.resize(10); +        TPagedVector<int, 3> const& crvint = vint; + +        UNIT_ASSERT(vint.begin() == vint.begin()); +        UNIT_ASSERT(crvint.begin() == vint.begin()); +        UNIT_ASSERT(vint.begin() == crvint.begin()); +        UNIT_ASSERT(crvint.begin() == crvint.begin()); + +        UNIT_ASSERT(vint.begin() != vint.end()); +        UNIT_ASSERT(crvint.begin() != vint.end()); +        UNIT_ASSERT(vint.begin() != crvint.end()); +        UNIT_ASSERT(crvint.begin() != crvint.end()); + +        UNIT_ASSERT(vint.rbegin() == vint.rbegin()); +        // Not Standard: +        //UNIT_ASSERT(vint.rbegin() == crvint.rbegin()); +        //UNIT_ASSERT(crvint.rbegin() == vint.rbegin()); +        UNIT_ASSERT(crvint.rbegin() == crvint.rbegin()); + +        UNIT_ASSERT(vint.rbegin() != vint.rend()); +        // Not Standard: +        //UNIT_ASSERT(vint.rbegin() != crvint.rend()); +        //UNIT_ASSERT(crvint.rbegin() != vint.rend()); +        UNIT_ASSERT(crvint.rbegin() != crvint.rend()); +    } + +    /* This test check a potential issue with empty base class           * optimization. Some compilers (VC6) do not implement it           * correctly resulting ina wrong behavior. */ -    void TestEbo() {  -        using NPagedVector::TPagedVector;  -        // We use heap memory as test failure can corrupt vector internal  -        // representation making executable crash on vector destructor invocation.  -        // We prefer a simple memory leak, internal corruption should be reveal  -        // by size or capacity checks.  -        typedef TPagedVector<int, 3> V;  -        V* pv1 = new V;  +    void TestEbo() { +        using NPagedVector::TPagedVector; +        // We use heap memory as test failure can corrupt vector internal +        // representation making executable crash on vector destructor invocation. +        // We prefer a simple memory leak, internal corruption should be reveal +        // by size or capacity checks. +        typedef TPagedVector<int, 3> V; +        V* pv1 = new V; -        pv1->resize(1);  -        pv1->at(0) = 1;  +        pv1->resize(1); +        pv1->at(0) = 1; -        V* pv2 = new V;  +        V* pv2 = new V; -        pv2->resize(10);  -        for (int i = 0; i < 10; ++i)  -            pv2->at(i) = 2;  +        pv2->resize(10); +        for (int i = 0; i < 10; ++i) +            pv2->at(i) = 2; -        pv1->swap(*pv2);  +        pv1->swap(*pv2); -        UNIT_ASSERT(pv1->size() == 10);  -        UNIT_ASSERT((*pv1)[5] == 2);  +        UNIT_ASSERT(pv1->size() == 10); +        UNIT_ASSERT((*pv1)[5] == 2); -        UNIT_ASSERT(pv2->size() == 1);  -        UNIT_ASSERT((*pv2)[0] == 1);  +        UNIT_ASSERT(pv2->size() == 1); +        UNIT_ASSERT((*pv2)[0] == 1); -        delete pv2;  -        delete pv1;  -    }  +        delete pv2; +        delete pv1; +    }  };  UNIT_TEST_SUITE_REGISTRATION(TPagedVectorTest); diff --git a/library/cpp/containers/paged_vector/ut/ya.make b/library/cpp/containers/paged_vector/ut/ya.make index 69054531b1f..74cfe5fb4ad 100644 --- a/library/cpp/containers/paged_vector/ut/ya.make +++ b/library/cpp/containers/paged_vector/ut/ya.make @@ -1,13 +1,13 @@ -UNITTEST()  -  -OWNER(velavokr)  -  -PEERDIR(  +UNITTEST() + +OWNER(velavokr) + +PEERDIR(      library/cpp/containers/paged_vector -)  -  -SRCS(  -    paged_vector_ut.cpp  -)  -  -END()  +) + +SRCS( +    paged_vector_ut.cpp +) + +END() diff --git a/library/cpp/containers/sorted_vector/sorted_vector.cpp b/library/cpp/containers/sorted_vector/sorted_vector.cpp index 806efe371aa..56aaf69ddef 100644 --- a/library/cpp/containers/sorted_vector/sorted_vector.cpp +++ b/library/cpp/containers/sorted_vector/sorted_vector.cpp @@ -1 +1 @@ -#include "sorted_vector.h"  +#include "sorted_vector.h" diff --git a/library/cpp/containers/sorted_vector/sorted_vector.h b/library/cpp/containers/sorted_vector/sorted_vector.h index 17a1fddcc5c..123539af9e2 100644 --- a/library/cpp/containers/sorted_vector/sorted_vector.h +++ b/library/cpp/containers/sorted_vector/sorted_vector.h @@ -1,85 +1,85 @@ -#pragma once  -  -#include <util/system/defaults.h>  -#include <util/generic/hash.h>  -#include <util/generic/vector.h>  -#include <util/generic/algorithm.h>  +#pragma once + +#include <util/system/defaults.h> +#include <util/generic/hash.h> +#include <util/generic/vector.h> +#include <util/generic/algorithm.h>  #include <util/generic/mapfindptr.h> -#include <util/ysaveload.h>  +#include <util/ysaveload.h>  #include <utility> -  +  #include <initializer_list> -namespace NSorted {  -    namespace NPrivate {  +namespace NSorted { +    namespace NPrivate {          template <class TPredicate>          struct TEqual {              template<typename TValueType1, typename TValueType2>              inline bool operator()(const TValueType1& l, const TValueType2& r) const { -                TPredicate comp;  -                return comp(l, r) == comp(r, l);  -            }  -        };  -  +                TPredicate comp; +                return comp(l, r) == comp(r, l); +            } +        }; +          template <typename TValueType, class TPredicate, class TKeyExtractor>          struct TKeyCompare { -            inline bool operator()(const TValueType& l, const TValueType& r) const {  -                TKeyExtractor extractKey;  -                return TPredicate()(extractKey(l), extractKey(r));  -            }  +            inline bool operator()(const TValueType& l, const TValueType& r) const { +                TKeyExtractor extractKey; +                return TPredicate()(extractKey(l), extractKey(r)); +            }              template<typename TKeyType> -            inline bool operator()(const TKeyType& l, const TValueType& r) const {  -                return TPredicate()(l, TKeyExtractor()(r));  -            }  +            inline bool operator()(const TKeyType& l, const TValueType& r) const { +                return TPredicate()(l, TKeyExtractor()(r)); +            }              template<typename TKeyType> -            inline bool operator()(const TValueType& l, const TKeyType& r) const {  -                return TPredicate()(TKeyExtractor()(l), r);  -            }  -        };  -  -        template <typename TValueType, class TPredicate>  +            inline bool operator()(const TValueType& l, const TKeyType& r) const { +                return TPredicate()(TKeyExtractor()(l), r); +            } +        }; + +        template <typename TValueType, class TPredicate>          struct TKeyCompare<TValueType, TPredicate, TIdentity> {              template <typename TValueType1, typename TValueType2>              inline bool operator()(const TValueType1& l, const TValueType2& r) const { -                return TPredicate()(l, r);  -            }  -        };  -  -    }  -  -    // Sorted vector, which is order by the key. The key is extracted from the value by the provided key-extractor  -    template <typename TValueType, typename TKeyType = TValueType, class TKeyExtractor = TIdentity,  +                return TPredicate()(l, r); +            } +        }; + +    } + +    // Sorted vector, which is order by the key. The key is extracted from the value by the provided key-extractor +    template <typename TValueType, typename TKeyType = TValueType, class TKeyExtractor = TIdentity,                class TPredicate = TLess<TKeyType>, class A = std::allocator<TValueType>>      class TSortedVector: public TVector<TValueType, A> { -    private:  +    private:          typedef TVector<TValueType, A> TBase;          typedef NPrivate::TKeyCompare<TValueType, TPredicate, TKeyExtractor> TKeyCompare;          typedef NPrivate::TEqual<TKeyCompare> TValueEqual;          typedef NPrivate::TEqual<TPredicate> TKeyEqual; -  -    public:  -        typedef TValueType value_type;  -        typedef TKeyType key_type;  -        typedef typename TBase::iterator iterator;  -        typedef typename TBase::const_iterator const_iterator;  -        typedef typename TBase::size_type size_type;  -  -    public:  -        inline TSortedVector()  -            : TBase()  -        {  -        }  -  -        inline explicit TSortedVector(size_type count)  -            : TBase(count)  -        {  -        }  -  -        inline TSortedVector(size_type count, const value_type& val)  -            : TBase(count, val)  -        {  -        }  -  + +    public: +        typedef TValueType value_type; +        typedef TKeyType key_type; +        typedef typename TBase::iterator iterator; +        typedef typename TBase::const_iterator const_iterator; +        typedef typename TBase::size_type size_type; + +    public: +        inline TSortedVector() +            : TBase() +        { +        } + +        inline explicit TSortedVector(size_type count) +            : TBase(count) +        { +        } + +        inline TSortedVector(size_type count, const value_type& val) +            : TBase(count, val) +        { +        } +          inline TSortedVector(std::initializer_list<value_type> il)              : TBase(il)          { @@ -92,293 +92,293 @@ namespace NSorted {              Sort();          } -        template <class TIter>  -        inline TSortedVector(TIter first, TIter last)  -            : TBase(first, last)  -        {  -            Sort();  -        }  -  -        // Inserts non-unique value in the proper position according to the key-sort order.  -        // Returns iterator, which points to the inserted value  -        inline iterator Insert(const value_type& value) {  -            return TBase::insert(LowerBound(TKeyExtractor()(value)), value);  -        }  -  -        // STL-compatible synonym  +        template <class TIter> +        inline TSortedVector(TIter first, TIter last) +            : TBase(first, last) +        { +            Sort(); +        } + +        // Inserts non-unique value in the proper position according to the key-sort order. +        // Returns iterator, which points to the inserted value +        inline iterator Insert(const value_type& value) { +            return TBase::insert(LowerBound(TKeyExtractor()(value)), value); +        } + +        // STL-compatible synonym          Y_FORCE_INLINE iterator insert(const value_type& value) { -            return this->Insert(value);  -        }  -  -        // Inserts non-unique value range in the proper position according to the key-sort order.  -        template <class TIter>  -        inline void Insert(TIter first, TIter last) {  -            TBase::insert(TBase::end(), first, last);  -            Sort();  -        }  -  -        // STL-compatible synonym  -        template <class TIter>  +            return this->Insert(value); +        } + +        // Inserts non-unique value range in the proper position according to the key-sort order. +        template <class TIter> +        inline void Insert(TIter first, TIter last) { +            TBase::insert(TBase::end(), first, last); +            Sort(); +        } + +        // STL-compatible synonym +        template <class TIter>          Y_FORCE_INLINE void insert(TIter first, TIter last) { -            this->Insert(first, last);  -        }  -  -        // Inserts unique value in the proper position according to the key-sort order,  -        // if the value with the same key doesn't exist. Returns <iterator, bool> pair,  -        // where the first member is the pointer to the inserted/existing value, and the  -        // second member indicates either the value is inserted or not.  +            this->Insert(first, last); +        } + +        // Inserts unique value in the proper position according to the key-sort order, +        // if the value with the same key doesn't exist. Returns <iterator, bool> pair, +        // where the first member is the pointer to the inserted/existing value, and the +        // second member indicates either the value is inserted or not.          inline std::pair<iterator, bool> InsertUnique(const value_type& value) { -            iterator i = LowerBound(TKeyExtractor()(value));  -            if (i == TBase::end() || !TValueEqual()(*i, value))  +            iterator i = LowerBound(TKeyExtractor()(value)); +            if (i == TBase::end() || !TValueEqual()(*i, value))                  return std::pair<iterator, bool>(TBase::insert(i, value), true); -            else  +            else                  return std::pair<iterator, bool>(i, false); -        }  -  -        // STL-compatible synonym  +        } + +        // STL-compatible synonym          Y_FORCE_INLINE std::pair<iterator, bool> insert_unique(const value_type& value) { -            return this->InsertUnique(value);  -        }  -  -        // Inserts unique value range in the proper position according to the key-sort order.  -        template <class TIter>  -        inline void InsertUnique(TIter first, TIter last) {  -            TBase::insert(TBase::end(), first, last);  -            Sort();  -            MakeUnique();  -        }  -  -        // STL-compatible synonym  -        template <class TIter>  +            return this->InsertUnique(value); +        } + +        // Inserts unique value range in the proper position according to the key-sort order. +        template <class TIter> +        inline void InsertUnique(TIter first, TIter last) { +            TBase::insert(TBase::end(), first, last); +            Sort(); +            MakeUnique(); +        } + +        // STL-compatible synonym +        template <class TIter>          Y_FORCE_INLINE void insert_unique(TIter first, TIter last) { -            this->InsertUnique(first, last);  -        }  -  -        // Inserts unique value in the proper position according to the key-sort order.  -        // If the value with the same key already exists, then it is replaced with the new one.  -        // Returns iterator, which points to the inserted value  -        inline iterator InsertOrReplace(const value_type& value) {  -            iterator i = ::LowerBound(TBase::begin(), TBase::end(), value, TKeyCompare());  -            if (i == TBase::end() || !TValueEqual()(*i, value))  -                return TBase::insert(i, value);  -            else  -                return TBase::insert(TBase::erase(i), value);  -        }  -  -        // STL-compatible synonym  +            this->InsertUnique(first, last); +        } + +        // Inserts unique value in the proper position according to the key-sort order. +        // If the value with the same key already exists, then it is replaced with the new one. +        // Returns iterator, which points to the inserted value +        inline iterator InsertOrReplace(const value_type& value) { +            iterator i = ::LowerBound(TBase::begin(), TBase::end(), value, TKeyCompare()); +            if (i == TBase::end() || !TValueEqual()(*i, value)) +                return TBase::insert(i, value); +            else +                return TBase::insert(TBase::erase(i), value); +        } + +        // STL-compatible synonym          Y_FORCE_INLINE iterator insert_or_replace(const value_type& value) { -            return this->InsertOrReplace(value);  -        }  -  +            return this->InsertOrReplace(value); +        } +          Y_FORCE_INLINE void Sort() { -            ::Sort(TBase::begin(), TBase::end(), TKeyCompare());  -        }  -  -        // STL-compatible synonym  +            ::Sort(TBase::begin(), TBase::end(), TKeyCompare()); +        } + +        // STL-compatible synonym          Y_FORCE_INLINE void sort() { -            this->Sort();  -        }  -  +            this->Sort(); +        } +          Y_FORCE_INLINE void Sort(iterator from, iterator to) { -            ::Sort(from, to, TKeyCompare());  -        }  -  -        // STL-compatible synonym  +            ::Sort(from, to, TKeyCompare()); +        } + +        // STL-compatible synonym          Y_FORCE_INLINE void sort(iterator from, iterator to) { -            this->Sort(from, to);  -        }  -  -        inline void MakeUnique() {  -            TBase::erase(::Unique(TBase::begin(), TBase::end(), TValueEqual()), TBase::end());  -        }  -  -        // STL-compatible synonym  +            this->Sort(from, to); +        } + +        inline void MakeUnique() { +            TBase::erase(::Unique(TBase::begin(), TBase::end(), TValueEqual()), TBase::end()); +        } + +        // STL-compatible synonym          Y_FORCE_INLINE void make_unique() { -            this->MakeUnique();  -        }  -  +            this->MakeUnique(); +        } +          template<class K>          inline const_iterator Find(const K& key) const { -            const_iterator i = LowerBound(key);  -            if (i == TBase::end() || !TKeyEqual()(TKeyExtractor()(*i), key))  -                return TBase::end();  -            else  -                return i;  -        }  -  -        // STL-compatible synonym  +            const_iterator i = LowerBound(key); +            if (i == TBase::end() || !TKeyEqual()(TKeyExtractor()(*i), key)) +                return TBase::end(); +            else +                return i; +        } + +        // STL-compatible synonym          template<class K>          Y_FORCE_INLINE const_iterator find(const K& key) const { -            return this->Find(key);  -        }  -  +            return this->Find(key); +        } +          template<class K>          inline iterator Find(const K& key) { -            iterator i = LowerBound(key);  -            if (i == TBase::end() || !TKeyEqual()(TKeyExtractor()(*i), key))  -                return TBase::end();  -            else  -                return i;  -        }  -  -        // STL-compatible synonym  +            iterator i = LowerBound(key); +            if (i == TBase::end() || !TKeyEqual()(TKeyExtractor()(*i), key)) +                return TBase::end(); +            else +                return i; +        } + +        // STL-compatible synonym          template<class K>          Y_FORCE_INLINE iterator find(const K& key) { -            return this->Find(key);  -        }  -  +            return this->Find(key); +        } +          template<class K>          Y_FORCE_INLINE bool Has(const K& key) const { -            return this->find(key) != TBase::end();  -        }  -  +            return this->find(key) != TBase::end(); +        } +          template<class K>          Y_FORCE_INLINE bool has(const K& key) const { -            return this->Has(key);  -        }  -  +            return this->Has(key); +        } +          template<class K>          Y_FORCE_INLINE iterator LowerBound(const K& key) { -            return ::LowerBound(TBase::begin(), TBase::end(), key, TKeyCompare());  -        }  -  -        // STL-compatible synonym  +            return ::LowerBound(TBase::begin(), TBase::end(), key, TKeyCompare()); +        } + +        // STL-compatible synonym          template<class K>          Y_FORCE_INLINE iterator lower_bound(const K& key) { -            return this->LowerBound(key);  -        }  -  +            return this->LowerBound(key); +        } +          template<class K>          Y_FORCE_INLINE const_iterator LowerBound(const K& key) const { -            return ::LowerBound(TBase::begin(), TBase::end(), key, TKeyCompare());  -        }  -  -        // STL-compatible synonym  +            return ::LowerBound(TBase::begin(), TBase::end(), key, TKeyCompare()); +        } + +        // STL-compatible synonym          template<class K>          Y_FORCE_INLINE const_iterator lower_bound(const K& key) const { -            return this->LowerBound(key);  -        }  -  +            return this->LowerBound(key); +        } +          template<class K>          Y_FORCE_INLINE iterator UpperBound(const K& key) { -            return ::UpperBound(TBase::begin(), TBase::end(), key, TKeyCompare());  -        }  -  -        // STL-compatible synonym  +            return ::UpperBound(TBase::begin(), TBase::end(), key, TKeyCompare()); +        } + +        // STL-compatible synonym          template<class K>          Y_FORCE_INLINE iterator upper_bound(const K& key) { -            return this->UpperBound(key);  -        }  -  +            return this->UpperBound(key); +        } +          template<class K>          Y_FORCE_INLINE const_iterator UpperBound(const K& key) const { -            return ::UpperBound(TBase::begin(), TBase::end(), key, TKeyCompare());  -        }  -  -        // STL-compatible synonym  +            return ::UpperBound(TBase::begin(), TBase::end(), key, TKeyCompare()); +        } + +        // STL-compatible synonym          template<class K>          Y_FORCE_INLINE const_iterator upper_bound(const K& key) const { -            return this->UpperBound(key);  -        }  -  +            return this->UpperBound(key); +        } +          template<class K>          Y_FORCE_INLINE std::pair<iterator, iterator> EqualRange(const K& key) { -            return std::equal_range(TBase::begin(), TBase::end(), key, TKeyCompare());  -        }  -  -        // STL-compatible synonym  +            return std::equal_range(TBase::begin(), TBase::end(), key, TKeyCompare()); +        } + +        // STL-compatible synonym          template<class K>          Y_FORCE_INLINE std::pair<iterator, iterator> equal_range(const K& key) { -            return this->EqualRange(key);  -        }  -  +            return this->EqualRange(key); +        } +          template<class K>          Y_FORCE_INLINE std::pair<const_iterator, const_iterator> EqualRange(const K& key) const { -            return std::equal_range(TBase::begin(), TBase::end(), key, TKeyCompare());  -        }  -  -        // STL-compatible synonym  +            return std::equal_range(TBase::begin(), TBase::end(), key, TKeyCompare()); +        } + +        // STL-compatible synonym          template<class K>          Y_FORCE_INLINE std::pair<const_iterator, const_iterator> equal_range(const K& key) const { -            return this->EqualRange(key);  -        }  -  +            return this->EqualRange(key); +        } +          template<class K>          inline void Erase(const K& key) {              std::pair<iterator, iterator> res = EqualRange(key); -            TBase::erase(res.first, res.second);  -        }  -  -        // STL-compatible synonym  +            TBase::erase(res.first, res.second); +        } + +        // STL-compatible synonym          Y_FORCE_INLINE void erase(const key_type& key) { -            this->Erase(key);  -        }  -  +            this->Erase(key); +        } +          template<class K>          inline size_t count(const K& key) const {              const std::pair<const_iterator, const_iterator> range = this->EqualRange(key); -            return std::distance(range.first, range.second);  -        }  -  -        using TBase::erase;  -    };  -  +            return std::distance(range.first, range.second); +        } + +        using TBase::erase; +    }; +      // The simplified map (a.k.a TFlatMap, flat_map), which is implemented by the sorted-vector. -    // This structure has the side-effect: if you keep a reference to an existing element  -    // and then inserts a new one, the existing reference can be broken (due to reallocation).  -    // Please keep this in mind when using this structure.  +    // This structure has the side-effect: if you keep a reference to an existing element +    // and then inserts a new one, the existing reference can be broken (due to reallocation). +    // Please keep this in mind when using this structure.      template <typename TKeyType, typename TValueType, class TPredicate = TLess<TKeyType>, class A = std::allocator<TValueType>>      class TSimpleMap:          public TSortedVector<std::pair<TKeyType, TValueType>, TKeyType, TSelect1st, TPredicate, A>,          public TMapOps<TSimpleMap<TKeyType, TValueType, TPredicate, A>>      { -    private:  +    private:          typedef TSortedVector<std::pair<TKeyType, TValueType>, TKeyType, TSelect1st, TPredicate, A> TBase; -  -    public:  -        typedef typename TBase::value_type value_type;  -        typedef typename TBase::key_type key_type;  -        typedef typename TBase::iterator iterator;  -        typedef typename TBase::const_iterator const_iterator;  -        typedef typename TBase::size_type size_type;  -  -    public:  -        inline TSimpleMap()  -            : TBase()  -        {  -        }  -  -        template <class TIter>  -        inline TSimpleMap(TIter first, TIter last)  -            : TBase(first, last)  -        {  -            TBase::MakeUnique();  -        }  -  + +    public: +        typedef typename TBase::value_type value_type; +        typedef typename TBase::key_type key_type; +        typedef typename TBase::iterator iterator; +        typedef typename TBase::const_iterator const_iterator; +        typedef typename TBase::size_type size_type; + +    public: +        inline TSimpleMap() +            : TBase() +        { +        } + +        template <class TIter> +        inline TSimpleMap(TIter first, TIter last) +            : TBase(first, last) +        { +            TBase::MakeUnique(); +        } +          inline TSimpleMap(std::initializer_list<value_type> il)              : TBase(il)          {              TBase::MakeUnique();          } -        inline TValueType& Get(const TKeyType& key) {  -            typename TBase::iterator i = TBase::LowerBound(key);  -            if (i == TBase::end() || key != i->first)  +        inline TValueType& Get(const TKeyType& key) { +            typename TBase::iterator i = TBase::LowerBound(key); +            if (i == TBase::end() || key != i->first)                  return TVector<std::pair<TKeyType, TValueType>, A>::insert(i, std::make_pair(key, TValueType()))->second; -            else  -                return i->second;  -        }  -  +            else +                return i->second; +        } +          template<class K>          inline const TValueType& Get(const K& key, const TValueType& def) const { -            typename TBase::const_iterator i = TBase::Find(key);  -            return i != TBase::end() ? i->second : def;  -        }  -  +            typename TBase::const_iterator i = TBase::Find(key); +            return i != TBase::end() ? i->second : def; +        } +          template<class K>          Y_FORCE_INLINE TValueType& operator[](const K& key) { -            return Get(key);  -        }  +            return Get(key); +        }          template<class K>          const TValueType& at(const K& key) const { @@ -395,98 +395,98 @@ namespace NSorted {              return const_cast<TValueType&>(                      const_cast<const TSimpleMap<TKeyType, TValueType, TPredicate, A>*>(this)->at(key));          } -    };  -  +    }; +      // The simplified set (a.k.a TFlatSet, flat_set), which is implemented by the sorted-vector. -    // This structure has the same side-effect as TSimpleMap.  -    // The value type must have TValueType(TKeyType) constructor in order to use [] operator  -    template <typename TValueType, typename TKeyType = TValueType, class TKeyExtractor = TIdentity,  +    // This structure has the same side-effect as TSimpleMap. +    // The value type must have TValueType(TKeyType) constructor in order to use [] operator +    template <typename TValueType, typename TKeyType = TValueType, class TKeyExtractor = TIdentity,                class TPredicate = TLess<TKeyType>, class A = std::allocator<TValueType>> -    class TSimpleSet: public TSortedVector<TValueType, TKeyType, TKeyExtractor, TPredicate, A> {  -    private:  -        typedef TSortedVector<TValueType, TKeyType, TKeyExtractor, TPredicate, A> TBase;  -  -    public:  -        typedef typename TBase::value_type value_type;  -        typedef typename TBase::key_type key_type;  -        typedef typename TBase::iterator iterator;  -        typedef typename TBase::const_iterator const_iterator;  -        typedef typename TBase::size_type size_type;  +    class TSimpleSet: public TSortedVector<TValueType, TKeyType, TKeyExtractor, TPredicate, A> { +    private: +        typedef TSortedVector<TValueType, TKeyType, TKeyExtractor, TPredicate, A> TBase; + +    public: +        typedef typename TBase::value_type value_type; +        typedef typename TBase::key_type key_type; +        typedef typename TBase::iterator iterator; +        typedef typename TBase::const_iterator const_iterator; +        typedef typename TBase::size_type size_type;          typedef NPrivate::TEqual<TPredicate> TKeyEqual; -  -    public:  -        inline TSimpleSet()  -            : TBase()  -        {  -        }  -  -        template <class TIter>  -        inline TSimpleSet(TIter first, TIter last)  -            : TBase(first, last)  -        {  -            TBase::MakeUnique();  -        }  -  + +    public: +        inline TSimpleSet() +            : TBase() +        { +        } + +        template <class TIter> +        inline TSimpleSet(TIter first, TIter last) +            : TBase(first, last) +        { +            TBase::MakeUnique(); +        } +          inline TSimpleSet(std::initializer_list<value_type> il)              : TBase(il)          {              TBase::MakeUnique();          } -        // The method expects that there is a TValueType(TKeyType) constructor available  -        inline TValueType& Get(const TKeyType& key) {  -            typename TBase::iterator i = TBase::LowerBound(key);  -            if (i == TBase::end() || !TKeyEqual()(TKeyExtractor()(*i), key))  +        // The method expects that there is a TValueType(TKeyType) constructor available +        inline TValueType& Get(const TKeyType& key) { +            typename TBase::iterator i = TBase::LowerBound(key); +            if (i == TBase::end() || !TKeyEqual()(TKeyExtractor()(*i), key))                  i = TVector<TValueType, A>::insert(i, TValueType(key)); -            return *i;  -        }  -  +            return *i; +        } +          template<class K>          inline const TValueType& Get(const K& key, const TValueType& def) const { -            typename TBase::const_iterator i = TBase::Find(key);  -            return i != TBase::end() ? *i : def;  -        }  -  +            typename TBase::const_iterator i = TBase::Find(key); +            return i != TBase::end() ? *i : def; +        } +          template<class K>          Y_FORCE_INLINE TValueType& operator[](const K& key) { -            return Get(key);  -        }  -  -        // Inserts value with unique key. Returns <iterator, bool> pair,  -        // where the first member is the pointer to the inserted/existing value, and the  -        // second member indicates either the value is inserted or not.  +            return Get(key); +        } + +        // Inserts value with unique key. Returns <iterator, bool> pair, +        // where the first member is the pointer to the inserted/existing value, and the +        // second member indicates either the value is inserted or not.          Y_FORCE_INLINE std::pair<iterator, bool> Insert(const TValueType& value) { -            return TBase::InsertUnique(value);  -        }  -  -        // STL-compatible synonym  +            return TBase::InsertUnique(value); +        } + +        // STL-compatible synonym          Y_FORCE_INLINE std::pair<iterator, bool> insert(const TValueType& value) { -            return TBase::InsertUnique(value);  -        }  -  -        // Inserts value range with unique keys.  -        template <class TIter>  +            return TBase::InsertUnique(value); +        } + +        // Inserts value range with unique keys. +        template <class TIter>          Y_FORCE_INLINE void Insert(TIter first, TIter last) { -            TBase::InsertUnique(first, last);  -        }  -  -        // STL-compatible synonym  -        template <class TIter>  +            TBase::InsertUnique(first, last); +        } + +        // STL-compatible synonym +        template <class TIter>          Y_FORCE_INLINE void insert(TIter first, TIter last) { -            TBase::InsertUnique(first, last);  -        }  -    };  -  -}  -  -template <typename V, typename K, class E, class P, class A>  -class TSerializer<NSorted::TSortedVector<V, K, E, P, A>>: public TVectorSerializer<NSorted::TSortedVector<V, K, E, P, A>> {  -};  -  -template <typename K, typename V, class P, class A>  -class TSerializer<NSorted::TSimpleMap<K, V, P, A>>: public TVectorSerializer<NSorted::TSimpleMap<K, V, P, A>> {  -};  -  -template <typename V, typename K, class E, class P, class A>  -class TSerializer<NSorted::TSimpleSet<V, K, E, P, A>>: public TVectorSerializer<NSorted::TSimpleSet<V, K, E, P, A>> {  -};  +            TBase::InsertUnique(first, last); +        } +    }; + +} + +template <typename V, typename K, class E, class P, class A> +class TSerializer<NSorted::TSortedVector<V, K, E, P, A>>: public TVectorSerializer<NSorted::TSortedVector<V, K, E, P, A>> { +}; + +template <typename K, typename V, class P, class A> +class TSerializer<NSorted::TSimpleMap<K, V, P, A>>: public TVectorSerializer<NSorted::TSimpleMap<K, V, P, A>> { +}; + +template <typename V, typename K, class E, class P, class A> +class TSerializer<NSorted::TSimpleSet<V, K, E, P, A>>: public TVectorSerializer<NSorted::TSimpleSet<V, K, E, P, A>> { +}; diff --git a/library/cpp/containers/sorted_vector/ya.make b/library/cpp/containers/sorted_vector/ya.make index 78f1c1494e5..1975c5dc908 100644 --- a/library/cpp/containers/sorted_vector/ya.make +++ b/library/cpp/containers/sorted_vector/ya.make @@ -1,11 +1,11 @@ -LIBRARY()  -  -OWNER(udovichenko-r)  -  -SRCS(  -    sorted_vector.cpp  -)  -  -END()  +LIBRARY() + +OWNER(udovichenko-r) + +SRCS( +    sorted_vector.cpp +) + +END()  RECURSE_FOR_TESTS(ut) diff --git a/library/cpp/containers/stack_array/range_ops.cpp b/library/cpp/containers/stack_array/range_ops.cpp index ea47fe67777..f1b5e3af0de 100644 --- a/library/cpp/containers/stack_array/range_ops.cpp +++ b/library/cpp/containers/stack_array/range_ops.cpp @@ -1 +1 @@ -#include "range_ops.h"  +#include "range_ops.h" diff --git a/library/cpp/containers/stack_array/range_ops.h b/library/cpp/containers/stack_array/range_ops.h index dfb95ab4010..1d40341aa19 100644 --- a/library/cpp/containers/stack_array/range_ops.h +++ b/library/cpp/containers/stack_array/range_ops.h @@ -1,52 +1,52 @@ -#pragma once  -  -#include <util/generic/typetraits.h>  -  -#include <new>  -  -namespace NRangeOps {  -    template <class T, bool isTrivial>  -    struct TRangeOpsBase {  +#pragma once + +#include <util/generic/typetraits.h> + +#include <new> + +namespace NRangeOps { +    template <class T, bool isTrivial> +    struct TRangeOpsBase {          static inline void DestroyRange(T* b, T* e) noexcept { -            while (e > b) {  -                (--e)->~T();  -            }  -        }  -  -        static inline void InitializeRange(T* b, T* e) {  -            T* c = b;  -  -            try {  -                for (; c < e; ++c) {  -                    new (c) T();  -                }  -            } catch (...) {  -                DestroyRange(b, c);  -  -                throw;  -            }  -        }  -    };  -  -    template <class T>  -    struct TRangeOpsBase<T, true> {  +            while (e > b) { +                (--e)->~T(); +            } +        } + +        static inline void InitializeRange(T* b, T* e) { +            T* c = b; + +            try { +                for (; c < e; ++c) { +                    new (c) T(); +                } +            } catch (...) { +                DestroyRange(b, c); + +                throw; +            } +        } +    }; + +    template <class T> +    struct TRangeOpsBase<T, true> {          static inline void DestroyRange(T*, T*) noexcept { -        }  -  +        } +          static inline void InitializeRange(T*, T*) noexcept { -        }  -    };  -  -    template <class T>  -    using TRangeOps = TRangeOpsBase<T, TTypeTraits<T>::IsPod>;  -  -    template <class T>  +        } +    }; + +    template <class T> +    using TRangeOps = TRangeOpsBase<T, TTypeTraits<T>::IsPod>; + +    template <class T>      static inline void DestroyRange(T* b, T* e) noexcept { -        TRangeOps<T>::DestroyRange(b, e);  -    }  -  -    template <class T>  -    static inline void InitializeRange(T* b, T* e) {  -        TRangeOps<T>::InitializeRange(b, e);  -    }  -}  +        TRangeOps<T>::DestroyRange(b, e); +    } + +    template <class T> +    static inline void InitializeRange(T* b, T* e) { +        TRangeOps<T>::InitializeRange(b, e); +    } +} diff --git a/library/cpp/containers/stack_array/stack_array.cpp b/library/cpp/containers/stack_array/stack_array.cpp index d5793281280..68e8b097baa 100644 --- a/library/cpp/containers/stack_array/stack_array.cpp +++ b/library/cpp/containers/stack_array/stack_array.cpp @@ -1 +1 @@ -#include "stack_array.h"  +#include "stack_array.h" diff --git a/library/cpp/containers/stack_array/stack_array.h b/library/cpp/containers/stack_array/stack_array.h index 105189de060..28e49bfc3c2 100644 --- a/library/cpp/containers/stack_array/stack_array.h +++ b/library/cpp/containers/stack_array/stack_array.h @@ -1,11 +1,11 @@ -#pragma once  -  -#include "range_ops.h"  -  +#pragma once + +#include "range_ops.h" +  #include <util/generic/array_ref.h>  #include <util/system/defaults.h> /* For alloca. */ -  -namespace NStackArray {  + +namespace NStackArray {      /**       * A stack-allocated array. Should be used instead of � variable length       * arrays that are not part of C++ standard. @@ -21,20 +21,20 @@ namespace NStackArray {       *       * Note that it is generally a *VERY BAD* idea to use this in inline methods       * as those might be called from a loop, and then stack overflow is in the cards. -     */  -    template <class T>  +     */ +    template <class T>      class TStackArray: public TArrayRef<T> { -    public:  -        inline TStackArray(void* data, size_t len)  +    public: +        inline TStackArray(void* data, size_t len)              : TArrayRef<T>((T*)data, len) -        {  +        {              NRangeOps::InitializeRange(this->begin(), this->end()); -        }  -  +        } +          inline ~TStackArray() {              NRangeOps::DestroyRange(this->begin(), this->end()); -        }  -    };  -}  -  -#define ALLOC_ON_STACK(type, n) alloca(sizeof(type) * (n)), (n)  +        } +    }; +} + +#define ALLOC_ON_STACK(type, n) alloca(sizeof(type) * (n)), (n) diff --git a/library/cpp/containers/stack_array/ut/tests_ut.cpp b/library/cpp/containers/stack_array/ut/tests_ut.cpp index d0c4bfe8c00..3e96384f0e7 100644 --- a/library/cpp/containers/stack_array/ut/tests_ut.cpp +++ b/library/cpp/containers/stack_array/ut/tests_ut.cpp @@ -1,94 +1,94 @@  #include <library/cpp/containers/stack_array/stack_array.h>  #include <library/cpp/testing/unittest/registar.h> -  +  Y_UNIT_TEST_SUITE(TestStackArray) { -    using namespace NStackArray;  -  -    static inline void* FillWithTrash(void* d, size_t l) {  -        memset(d, 0xCC, l);  -  -        return d;  -    }  -  -#define ALLOC(type, len) FillWithTrash(alloca(sizeof(type) * len), sizeof(type) * len), len  -  +    using namespace NStackArray; + +    static inline void* FillWithTrash(void* d, size_t l) { +        memset(d, 0xCC, l); + +        return d; +    } + +#define ALLOC(type, len) FillWithTrash(alloca(sizeof(type) * len), sizeof(type) * len), len +      Y_UNIT_TEST(Test1) { -        TStackArray<ui32> s(ALLOC(ui32, 10));  -  +        TStackArray<ui32> s(ALLOC(ui32, 10)); +          UNIT_ASSERT_VALUES_EQUAL(s.size(), 10); -  +          for (size_t i = 0; i < s.size(); ++i) { -            UNIT_ASSERT_VALUES_EQUAL(s[i], 0xCCCCCCCC);  -        }  -  -        for (auto&& x : s) {  -            UNIT_ASSERT_VALUES_EQUAL(x, 0xCCCCCCCC);  -        }  -  +            UNIT_ASSERT_VALUES_EQUAL(s[i], 0xCCCCCCCC); +        } + +        for (auto&& x : s) { +            UNIT_ASSERT_VALUES_EQUAL(x, 0xCCCCCCCC); +        } +          for (size_t i = 0; i < s.size(); ++i) { -            s[i] = i;  -        }  -  -        size_t ss = 0;  -  -        for (auto&& x : s) {  -            ss += x;  -        }  -  -        UNIT_ASSERT_VALUES_EQUAL(ss, 45);  -    }  -  -    static int N1 = 0;  -  -    struct TX1 {  -        inline TX1() {  -            ++N1;  -        }  -  -        inline ~TX1() {  -            --N1;  -        }  -    };  -  +            s[i] = i; +        } + +        size_t ss = 0; + +        for (auto&& x : s) { +            ss += x; +        } + +        UNIT_ASSERT_VALUES_EQUAL(ss, 45); +    } + +    static int N1 = 0; + +    struct TX1 { +        inline TX1() { +            ++N1; +        } + +        inline ~TX1() { +            --N1; +        } +    }; +      Y_UNIT_TEST(Test2) { -        {  -            TStackArray<TX1> s(ALLOC(TX1, 10));  -  -            UNIT_ASSERT_VALUES_EQUAL(N1, 10);  -        }  -  -        UNIT_ASSERT_VALUES_EQUAL(N1, 0);  -    }  -  -    static int N2 = 0;  -    static int N3 = 0;  -  -    struct TX2 {  -        inline TX2() {  -            if (N2 >= 5) {  -                ythrow yexception() << "ups";  -            }  -  -            ++N3;  -            ++N2;  -        }  -  -        inline ~TX2() {  -            --N2;  -        }  -    };  -  +        { +            TStackArray<TX1> s(ALLOC(TX1, 10)); + +            UNIT_ASSERT_VALUES_EQUAL(N1, 10); +        } + +        UNIT_ASSERT_VALUES_EQUAL(N1, 0); +    } + +    static int N2 = 0; +    static int N3 = 0; + +    struct TX2 { +        inline TX2() { +            if (N2 >= 5) { +                ythrow yexception() << "ups"; +            } + +            ++N3; +            ++N2; +        } + +        inline ~TX2() { +            --N2; +        } +    }; +      Y_UNIT_TEST(Test3) { -        bool haveException = false;  -  -        try {  -            TStackArray<TX2> s(ALLOC_ON_STACK(TX2, 10));  -        } catch (...) {  -            haveException = true;  -        }  -  -        UNIT_ASSERT(haveException);  -        UNIT_ASSERT_VALUES_EQUAL(N2, 0);  -        UNIT_ASSERT_VALUES_EQUAL(N3, 5);  -    }  -}  +        bool haveException = false; + +        try { +            TStackArray<TX2> s(ALLOC_ON_STACK(TX2, 10)); +        } catch (...) { +            haveException = true; +        } + +        UNIT_ASSERT(haveException); +        UNIT_ASSERT_VALUES_EQUAL(N2, 0); +        UNIT_ASSERT_VALUES_EQUAL(N3, 5); +    } +} diff --git a/library/cpp/containers/stack_array/ut/ya.make b/library/cpp/containers/stack_array/ut/ya.make index f224ff2942f..7db7340073b 100644 --- a/library/cpp/containers/stack_array/ut/ya.make +++ b/library/cpp/containers/stack_array/ut/ya.make @@ -1,9 +1,9 @@  UNITTEST_FOR(library/cpp/containers/stack_array) -  -OWNER(pg)  -  -SRCS(  -    tests_ut.cpp  -)  -  -END()  + +OWNER(pg) + +SRCS( +    tests_ut.cpp +) + +END() diff --git a/library/cpp/containers/stack_array/ya.make b/library/cpp/containers/stack_array/ya.make index ad84393f022..9bc0afc66ca 100644 --- a/library/cpp/containers/stack_array/ya.make +++ b/library/cpp/containers/stack_array/ya.make @@ -1,10 +1,10 @@ -LIBRARY()  -  -OWNER(pg)  -  -SRCS(  -    range_ops.cpp  -    stack_array.cpp  -)  -  -END()  +LIBRARY() + +OWNER(pg) + +SRCS( +    range_ops.cpp +    stack_array.cpp +) + +END() diff --git a/library/cpp/containers/stack_vector/stack_vec.h b/library/cpp/containers/stack_vector/stack_vec.h index 0108642da17..fcc5d9a2a50 100644 --- a/library/cpp/containers/stack_vector/stack_vec.h +++ b/library/cpp/containers/stack_vector/stack_vec.h @@ -20,27 +20,27 @@ using TSmallVec = TStackVec<T, 16, true, Alloc>;  template <typename T, size_t CountOnStack = 256>  using TStackOnlyVec = TStackVec<T, CountOnStack, false>; -namespace NPrivate {  -    template <class Alloc, class StackAlloc, typename T, typename U>  -    struct TRebind {  +namespace NPrivate { +    template <class Alloc, class StackAlloc, typename T, typename U> +    struct TRebind {          typedef TReboundAllocator<Alloc, U> other;      }; -    template <class Alloc, class StackAlloc, typename T>  -    struct TRebind<Alloc, StackAlloc, T, T> {  +    template <class Alloc, class StackAlloc, typename T> +    struct TRebind<Alloc, StackAlloc, T, T> {          typedef StackAlloc other;      };      template <typename T, size_t CountOnStack, bool UseFallbackAlloc, class Alloc = std::allocator<T>> -    class TStackBasedAllocator: public Alloc {  +    class TStackBasedAllocator: public Alloc {      public:          typedef TStackBasedAllocator<T, CountOnStack, UseFallbackAlloc, Alloc> TSelf; -        using typename Alloc::difference_type;  +        using typename Alloc::difference_type;          using typename Alloc::size_type; -        using typename Alloc::value_type;  +        using typename Alloc::value_type; -        template <class U>  +        template <class U>          struct rebind: public ::NPrivate::TRebind<Alloc, TSelf, T, U> {          }; @@ -89,7 +89,7 @@ namespace NPrivate {              return static_cast<Alloc&>(*this);          }      }; -}  +}  template <typename T, size_t CountOnStack, bool UseFallbackAlloc, class Alloc>  class TStackVec: public TVector<T, ::NPrivate::TStackBasedAllocator<T, CountOnStack, UseFallbackAlloc, TReboundAllocator<Alloc, T>>> { @@ -98,11 +98,11 @@ private:      using TAllocator = typename TBase::allocator_type;  public: -    using typename TBase::const_iterator;  -    using typename TBase::const_reverse_iterator;  +    using typename TBase::const_iterator; +    using typename TBase::const_reverse_iterator;      using typename TBase::iterator;      using typename TBase::reverse_iterator; -    using typename TBase::size_type;  +    using typename TBase::size_type;      using typename TBase::value_type;  public: diff --git a/library/cpp/containers/str_map/str_map.cpp b/library/cpp/containers/str_map/str_map.cpp index 1b65718d429..58c65babda6 100644 --- a/library/cpp/containers/str_map/str_map.cpp +++ b/library/cpp/containers/str_map/str_map.cpp @@ -1 +1 @@ -#include "str_map.h"  +#include "str_map.h" diff --git a/library/cpp/containers/str_map/str_map.h b/library/cpp/containers/str_map/str_map.h index 47a45407870..31b00d1b997 100644 --- a/library/cpp/containers/str_map/str_map.h +++ b/library/cpp/containers/str_map/str_map.h @@ -1,44 +1,44 @@  #pragma once -#include <util/memory/segmented_string_pool.h>  +#include <util/memory/segmented_string_pool.h>  #include <util/generic/map.h>  #include <util/generic/hash.h> -#include <util/generic/buffer.h>  -#include <util/str_stl.h> // less<> and equal_to<> for const char*  +#include <util/generic/buffer.h> +#include <util/str_stl.h> // less<> and equal_to<> for const char*  #include <utility>  #include <util/generic/noncopyable.h> -template <class T, class HashFcn = THash<const char*>, class EqualTo = TEqualTo<const char*>, class Alloc = std::allocator<const char*>>  -class string_hash;  -  -template <class T, class HashFcn = THash<const char*>, class EqualTo = TEqualTo<const char*>>  -class segmented_string_hash;  -  +template <class T, class HashFcn = THash<const char*>, class EqualTo = TEqualTo<const char*>, class Alloc = std::allocator<const char*>> +class string_hash; + +template <class T, class HashFcn = THash<const char*>, class EqualTo = TEqualTo<const char*>> +class segmented_string_hash; +  template <class Map>  inline std::pair<typename Map::iterator, bool> -pool_insert(Map* m, const char* key, const typename Map::mapped_type& data, TBuffer& pool) {  +pool_insert(Map* m, const char* key, const typename Map::mapped_type& data, TBuffer& pool) {      std::pair<typename Map::iterator, bool> ins = m->insert(typename Map::value_type(key, data)); -    if (ins.second) {                    // new?  -        size_t buflen = strlen(key) + 1; // strlen???  -        const char* old_pool = pool.Begin();  -        pool.Append(key, buflen);  -        if (pool.Begin() != old_pool) // repoint?  +    if (ins.second) {                    // new? +        size_t buflen = strlen(key) + 1; // strlen??? +        const char* old_pool = pool.Begin(); +        pool.Append(key, buflen); +        if (pool.Begin() != old_pool) // repoint?              for (typename Map::iterator it = m->begin(); it != m->end(); ++it)                  if ((*it).first != key) -                    const_cast<const char*&>((*it).first) += (pool.Begin() - old_pool);  -        const_cast<const char*&>((*ins.first).first) = pool.End() - buflen;  +                    const_cast<const char*&>((*it).first) += (pool.Begin() - old_pool); +        const_cast<const char*&>((*ins.first).first) = pool.End() - buflen;      }      return ins;  }  #define HASH_SIZE_DEFAULT 100 -#define AVERAGEWORD_BUF 10  +#define AVERAGEWORD_BUF 10  template <class T, class HashFcn, class EqualTo, class Alloc>  class string_hash: public THashMap<const char*, T, HashFcn, EqualTo, Alloc> {  protected: -    TBuffer pool;  -  +    TBuffer pool; +  public:      using yh = THashMap<const char*, T, HashFcn, EqualTo, Alloc>;      using iterator = typename yh::iterator; @@ -46,25 +46,25 @@ public:      using mapped_type = typename yh::mapped_type;      using size_type = typename yh::size_type;      using pool_size_type = typename yh::size_type; -    string_hash() {  -        pool.Reserve(HASH_SIZE_DEFAULT * AVERAGEWORD_BUF); // reserve here  +    string_hash() { +        pool.Reserve(HASH_SIZE_DEFAULT * AVERAGEWORD_BUF); // reserve here      }      string_hash(size_type hash_size, pool_size_type pool_size)          : THashMap<const char*, T, HashFcn, EqualTo, Alloc>(hash_size)      { -        pool.Reserve(pool_size); // reserve here  +        pool.Reserve(pool_size); // reserve here      }      std::pair<iterator, bool> insert_copy(const char* key, const mapped_type& data) {          return ::pool_insert(this, key, data, pool);      } -    void clear_hash() {  +    void clear_hash() {          yh::clear(); -        pool.Clear();  +        pool.Clear();      } -    pool_size_type pool_size() const {  -        return pool.Size();  +    pool_size_type pool_size() const { +        return pool.Size();      }      string_hash(const string_hash& sh) @@ -83,7 +83,7 @@ public:              (const char*&)(*i).first += delta;      }      */ -    string_hash& operator=(const string_hash& sh) {  +    string_hash& operator=(const string_hash& sh) {          if (&sh != this) {              clear_hash();              for (const_iterator i = sh.begin(); i != sh.end(); ++i) @@ -92,7 +92,7 @@ public:          return *this;      } -    mapped_type& operator[](const char* key) {  +    mapped_type& operator[](const char* key) {          iterator I = yh::find(key);          if (I == yh::end())              I = insert_copy(key, mapped_type()).first; @@ -104,7 +104,7 @@ template <class C, class T, class HashFcn, class EqualTo>  class THashWithSegmentedPoolForKeys: protected  THashMap<const C*, T, HashFcn, EqualTo>, TNonCopyable {  protected:      segmented_pool<C> pool; -  +  public:      using yh = THashMap<const C*, T, HashFcn, EqualTo>;      using iterator = typename yh::iterator; @@ -176,7 +176,7 @@ public:  };  template <class T, class HashFcn, class EqualTo> -class segmented_string_hash: public THashWithSegmentedPoolForKeys<char, T, HashFcn, EqualTo> {  +class segmented_string_hash: public THashWithSegmentedPoolForKeys<char, T, HashFcn, EqualTo> {  public:      using Base = THashWithSegmentedPoolForKeys<char, T, HashFcn, EqualTo>;      using iterator = typename Base::iterator; @@ -185,10 +185,10 @@ public:      using size_type = typename Base::size_type;      using key_type = typename Base::key_type;      using value_type = typename Base::value_type; -  +  public:      segmented_string_hash(size_type hash_size = HASH_SIZE_DEFAULT, size_t segsize = HASH_SIZE_DEFAULT * AVERAGEWORD_BUF, bool afs = false) -        : Base(hash_size, segsize, afs)  +        : Base(hash_size, segsize, afs)      {      } diff --git a/library/cpp/containers/str_map/ya.make b/library/cpp/containers/str_map/ya.make index 9c887fd9e2f..b834159cda8 100644 --- a/library/cpp/containers/str_map/ya.make +++ b/library/cpp/containers/str_map/ya.make @@ -1,9 +1,9 @@ -LIBRARY()  -  -OWNER(pg)  -  -SRCS(  -    str_map.cpp  -)  -  -END()  +LIBRARY() + +OWNER(pg) + +SRCS( +    str_map.cpp +) + +END() diff --git a/library/cpp/containers/top_keeper/top_keeper.h b/library/cpp/containers/top_keeper/top_keeper.h index b5f901a86e5..2f282b5a9e1 100644 --- a/library/cpp/containers/top_keeper/top_keeper.h +++ b/library/cpp/containers/top_keeper/top_keeper.h @@ -14,13 +14,13 @@ private:          size_t HalfMaxSize;          TComparator Comparer;          size_t MinElementIndex; -  +      private:          void Reserve() {              Internal.reserve(2 * HalfMaxSize);          } -        template <class UT>  +        template <class UT>          bool Insert(UT&& value) noexcept {              if (Y_UNLIKELY(0 == HalfMaxSize)) {                  return false; @@ -55,7 +55,7 @@ private:              Reserve();          } -        template <class TAllocParam>  +        template <class TAllocParam>          TVectorWithMin(const size_t halfMaxSize, const TComparator& comp, TAllocParam&& param)              : Internal(std::forward<TAllocParam>(param))              , HalfMaxSize(halfMaxSize) @@ -89,7 +89,7 @@ private:              return Insert(std::move(value));          } -        template <class... TArgs>  +        template <class... TArgs>          bool Emplace(TArgs&&... args) {              return Insert(T(std::forward<TArgs>(args)...)); // TODO: make it "real" emplace, not that fake one          } @@ -133,7 +133,7 @@ private:      void CheckNotFinalized() {          Y_ENSURE(!Finalized, "Cannot insert after finalizing (Pop() / GetNext() / Finalize())! " -                             "Use TLimitedHeap for this scenario");  +                             "Use TLimitedHeap for this scenario");      }      size_t MaxSize; @@ -158,7 +158,7 @@ public:      {      } -    template <class TAllocParam>  +    template <class TAllocParam>      TTopKeeper(size_t maxSize, const TComparator& comp, TAllocParam&& param)          : MaxSize(maxSize)          , Comparer(comp) @@ -219,7 +219,7 @@ public:          return Internal.Push(std::move(value));      } -    template <class... TArgs>  +    template <class... TArgs>      bool Emplace(TArgs&&... args) {          CheckNotFinalized();          return Internal.Emplace(std::forward<TArgs>(args)...); @@ -244,7 +244,7 @@ public:      void SetMaxSize(size_t newMaxSize) {          Y_ENSURE(!Finalized, "Cannot resize after finalizing (Pop() / GetNext() / Finalize())! " -                             "Use TLimitedHeap for this scenario");  +                             "Use TLimitedHeap for this scenario");          MaxSize = newMaxSize;          Internal.SetMaxSize(newMaxSize);      } diff --git a/library/cpp/containers/top_keeper/top_keeper/top_keeper.h b/library/cpp/containers/top_keeper/top_keeper/top_keeper.h index b5f901a86e5..2f282b5a9e1 100644 --- a/library/cpp/containers/top_keeper/top_keeper/top_keeper.h +++ b/library/cpp/containers/top_keeper/top_keeper/top_keeper.h @@ -14,13 +14,13 @@ private:          size_t HalfMaxSize;          TComparator Comparer;          size_t MinElementIndex; -  +      private:          void Reserve() {              Internal.reserve(2 * HalfMaxSize);          } -        template <class UT>  +        template <class UT>          bool Insert(UT&& value) noexcept {              if (Y_UNLIKELY(0 == HalfMaxSize)) {                  return false; @@ -55,7 +55,7 @@ private:              Reserve();          } -        template <class TAllocParam>  +        template <class TAllocParam>          TVectorWithMin(const size_t halfMaxSize, const TComparator& comp, TAllocParam&& param)              : Internal(std::forward<TAllocParam>(param))              , HalfMaxSize(halfMaxSize) @@ -89,7 +89,7 @@ private:              return Insert(std::move(value));          } -        template <class... TArgs>  +        template <class... TArgs>          bool Emplace(TArgs&&... args) {              return Insert(T(std::forward<TArgs>(args)...)); // TODO: make it "real" emplace, not that fake one          } @@ -133,7 +133,7 @@ private:      void CheckNotFinalized() {          Y_ENSURE(!Finalized, "Cannot insert after finalizing (Pop() / GetNext() / Finalize())! " -                             "Use TLimitedHeap for this scenario");  +                             "Use TLimitedHeap for this scenario");      }      size_t MaxSize; @@ -158,7 +158,7 @@ public:      {      } -    template <class TAllocParam>  +    template <class TAllocParam>      TTopKeeper(size_t maxSize, const TComparator& comp, TAllocParam&& param)          : MaxSize(maxSize)          , Comparer(comp) @@ -219,7 +219,7 @@ public:          return Internal.Push(std::move(value));      } -    template <class... TArgs>  +    template <class... TArgs>      bool Emplace(TArgs&&... args) {          CheckNotFinalized();          return Internal.Emplace(std::forward<TArgs>(args)...); @@ -244,7 +244,7 @@ public:      void SetMaxSize(size_t newMaxSize) {          Y_ENSURE(!Finalized, "Cannot resize after finalizing (Pop() / GetNext() / Finalize())! " -                             "Use TLimitedHeap for this scenario");  +                             "Use TLimitedHeap for this scenario");          MaxSize = newMaxSize;          Internal.SetMaxSize(newMaxSize);      }  | 
