diff options
| author | botay <[email protected]> | 2022-02-10 16:50:00 +0300 | 
|---|---|---|
| committer | Daniil Cherednik <[email protected]> | 2022-02-10 16:50:00 +0300 | 
| commit | c77325c5428270f74dd0d69adba028943a2b5ca8 (patch) | |
| tree | 5d5cb817648f650d76cf1076100726fd9b8448e8 /library/cpp/on_disk | |
| parent | bdd495d3600d61815512f5dc4c1c02f65f047a16 (diff) | |
Restoring authorship annotation for <[email protected]>. Commit 2 of 2.
Diffstat (limited to 'library/cpp/on_disk')
| -rw-r--r-- | library/cpp/on_disk/chunks/chunked_helpers.h | 282 | ||||
| -rw-r--r-- | library/cpp/on_disk/chunks/chunks_ut.cpp | 438 | 
2 files changed, 360 insertions, 360 deletions
| diff --git a/library/cpp/on_disk/chunks/chunked_helpers.h b/library/cpp/on_disk/chunks/chunked_helpers.h index 5f2215c5e11..5fa96afdca0 100644 --- a/library/cpp/on_disk/chunks/chunked_helpers.h +++ b/library/cpp/on_disk/chunks/chunked_helpers.h @@ -6,10 +6,10 @@  #include <util/generic/cast.h>  #include <util/generic/ymath.h>  #include <util/memory/blob.h> -#include <util/stream/buffer.h>  +#include <util/stream/buffer.h>  #include <util/stream/mem.h>  #include <util/system/unaligned_mem.h> -#include <util/ysaveload.h>  +#include <util/ysaveload.h>  #include "reader.h"  #include "writer.h" @@ -30,11 +30,11 @@ public:      {      } -    void Get(size_t idx, T& t) const {  -        assert(idx < (size_t)Size);  +    void Get(size_t idx, T& t) const { +        assert(idx < (size_t)Size);          t = ReadUnaligned<T>(Data + idx); -    }  -  +    } +      const T& At(size_t idx) const {          assert(idx < (size_t)Size);          return Data[idx]; @@ -44,10 +44,10 @@ public:          return Size;      } -    size_t RealSize() const {  +    size_t RealSize() const {          return sizeof(ui64) + Size * sizeof(T); -    }  -  +    } +      ~TYVector() = default;  }; @@ -109,21 +109,21 @@ struct TYVectorG<X, true> {      typedef TYVectorWriter<X> T;  }; -template <typename T>  -struct TIsMemsetThisWithZeroesSupported {  -    enum {  -        Result = TTypeTraits<T>::IsPod  -    };  -};  -  +template <typename T> +struct TIsMemsetThisWithZeroesSupported { +    enum { +        Result = TTypeTraits<T>::IsPod +    }; +}; +  #define MEMSET_THIS_WITH_ZEROES_SUPPORTED(type)     \      template <>                                     \      struct TIsMemsetThisWithZeroesSupported<type> { \          enum {                                      \              Result = true                           \          };                                          \ -    };  -  +    }; +  class TPlainHashCommon {  protected:  #pragma pack(push, 8) @@ -134,35 +134,35 @@ protected:          TKey Key;          TValue Value; -    private:  +    private:          static_assert(TIsMemsetThisWithZeroesSupported<TKey>::Result, "expect TIsMemsetThisWithZeroesSupported<TKey>::Result");          static_assert(TIsMemsetThisWithZeroesSupported<TValue>::Result, "expect TIsMemsetThisWithZeroesSupported<TValue>::Result"); -  -        /// to aviod uninitialized bytes  -        void Init(const TKey& key, const TValue& value) {  -            memset(static_cast<TThis*>(this), 0, sizeof(TThis));  -            Key = key;  -            Value = value;  -        }  -  + +        /// to aviod uninitialized bytes +        void Init(const TKey& key, const TValue& value) { +            memset(static_cast<TThis*>(this), 0, sizeof(TThis)); +            Key = key; +            Value = value; +        } +      public: -        TPackedPair(typename TTypeTraits<TKey>::TFuncParam key, typename TTypeTraits<TValue>::TFuncParam value) {  -            Init(key, value);  +        TPackedPair(typename TTypeTraits<TKey>::TFuncParam key, typename TTypeTraits<TValue>::TFuncParam value) { +            Init(key, value);          } -        TPackedPair(const TThis& rhs) {  -            Init(rhs.Key, rhs.Value);  +        TPackedPair(const TThis& rhs) { +            Init(rhs.Key, rhs.Value);          }          TPackedPair& operator=(const TThis& rhs) {              if (this != &rhs) { -                Init(rhs.Key, rhs.Value);  +                Init(rhs.Key, rhs.Value);              }              return *this;          } -        TPackedPair() {  -            Init(TKey(), TValue());  +        TPackedPair() { +            Init(TKey(), TValue());          }          typename TTypeTraits<TKey>::TFuncParam First() const { @@ -289,7 +289,7 @@ public:              for (size_t j = 0; j < data2[i].size(); ++j)                  for (size_t k = j + 1; k < data2[i].size(); ++k)                      if (TKeyValuePair::GetFirst(&data2[i][j]) == TKeyValuePair::GetFirst(&data2[i][k])) -                        ythrow yexception() << "key clash";  +                        ythrow yexception() << "key clash";          }  #endif          out.Write(intervals.data(), intervals.size() * sizeof(intervals[0])); @@ -525,150 +525,150 @@ private:      TVector<TString> Names;      THashMap<TString, size_t> NameToIndex;  }; -  +  template <class T> -struct TSaveLoadVectorNonPodElement {  +struct TSaveLoadVectorNonPodElement {      static inline void Save(IOutputStream* out, const T& t) { -        TSerializer<T>::Save(out, t);  -    }  -  +        TSerializer<T>::Save(out, t); +    } +      static inline void Load(IInputStream* in, T& t, size_t elementSize) {          Y_ASSERT(elementSize > 0); -        TSerializer<T>::Load(in, t);  -    }  -};  -  +        TSerializer<T>::Load(in, t); +    } +}; +  template <class T, bool isPod> -class TVectorTakingIntoAccountThePodType {  -private:  -    ui64 SizeofOffsets;  -    const ui64* Offsets;  -    const char* Data;  -  -public:  -    TVectorTakingIntoAccountThePodType(const TBlob& blob) {  +class TVectorTakingIntoAccountThePodType { +private: +    ui64 SizeofOffsets; +    const ui64* Offsets; +    const char* Data; + +public: +    TVectorTakingIntoAccountThePodType(const TBlob& blob) {          SizeofOffsets = ReadUnaligned<ui64>(blob.Begin());          Y_ASSERT(SizeofOffsets > 0); -        Offsets = reinterpret_cast<const ui64*>(blob.Begin() + sizeof(ui64));  +        Offsets = reinterpret_cast<const ui64*>(blob.Begin() + sizeof(ui64));          Data = reinterpret_cast<const char*>(blob.Begin() + sizeof(ui64) + SizeofOffsets * sizeof(ui64)); -    }  -  -    size_t GetSize() const {  +    } + +    size_t GetSize() const {          return (size_t)(SizeofOffsets - 1); -    }  -  -    size_t GetLength(ui64 index) const {  -        if (index + 1 >= SizeofOffsets)  -            ythrow yexception() << "bad offset";  +    } + +    size_t GetLength(ui64 index) const { +        if (index + 1 >= SizeofOffsets) +            ythrow yexception() << "bad offset";          return IntegerCast<size_t>(ReadUnaligned<ui64>(Offsets + index + 1) - ReadUnaligned<ui64>(Offsets + index)); -    }  -  -    void Get(ui64 index, T& t) const {  -        const size_t len = GetLength(index);  +    } + +    void Get(ui64 index, T& t) const { +        const size_t len = GetLength(index);          TMemoryInput input(Data + ReadUnaligned<ui64>(Offsets + index), len); -        TSaveLoadVectorNonPodElement<T>::Load(&input, t, len);  -    }  -  -    T Get(ui64 index) const {  -        T ret;  -        Get(index, ret);  -        return ret;  -    }  -  -    size_t RealSize() const {  +        TSaveLoadVectorNonPodElement<T>::Load(&input, t, len); +    } + +    T Get(ui64 index) const { +        T ret; +        Get(index, ret); +        return ret; +    } + +    size_t RealSize() const {          return sizeof(ui64) * (SizeofOffsets + 1) + ReadUnaligned<ui64>(Offsets + SizeofOffsets - 1); -    }  -};  -  +    } +}; +  template <class T, bool isPod> -class TVectorTakingIntoAccountThePodTypeWriter : TNonCopyable {  -private:  +class TVectorTakingIntoAccountThePodTypeWriter : TNonCopyable { +private:      typedef TVector<ui64> TOffsets; -    TOffsets Offsets;  -    TBuffer Data;  -    TBufferOutput DataStream;  -  -public:  -    TVectorTakingIntoAccountThePodTypeWriter()  -        : DataStream(Data)  -    {  -    }  -  -    void PushBack(const T& t) {  +    TOffsets Offsets; +    TBuffer Data; +    TBufferOutput DataStream; + +public: +    TVectorTakingIntoAccountThePodTypeWriter() +        : DataStream(Data) +    { +    } + +    void PushBack(const T& t) {          Offsets.push_back((ui64) Data.size()); -        TSaveLoadVectorNonPodElement<T>::Save(&DataStream, t);  -    }  -  -    size_t Size() const {  -        return Offsets.size();  -    }  -  +        TSaveLoadVectorNonPodElement<T>::Save(&DataStream, t); +    } + +    size_t Size() const { +        return Offsets.size(); +    } +      void Save(IOutputStream& out) const {          ui64 sizeofOffsets = Offsets.size() + 1; -        out.Write(&sizeofOffsets, sizeof(sizeofOffsets));  +        out.Write(&sizeofOffsets, sizeof(sizeofOffsets));          out.Write(Offsets.data(), Offsets.size() * sizeof(Offsets[0]));          ui64 lastOffset = (ui64) Data.size(); -        out.Write(&lastOffset, sizeof(lastOffset));  +        out.Write(&lastOffset, sizeof(lastOffset));          out.Write(Data.data(), Data.size()); -    }  -};  -  +    } +}; +  template <class T>  class TVectorTakingIntoAccountThePodType<T, true>: public TYVector<T> { -public:  -    TVectorTakingIntoAccountThePodType(const TBlob& blob)  -        : TYVector<T>(blob)  -    {  -    }  -};  -  +public: +    TVectorTakingIntoAccountThePodType(const TBlob& blob) +        : TYVector<T>(blob) +    { +    } +}; +  template <class T>  class TVectorTakingIntoAccountThePodTypeWriter<T, true>: public TYVectorWriter<T> { -};  -  +}; +  template <typename T>  class TGeneralVector: public TVectorTakingIntoAccountThePodType<T, TTypeTraits<T>::IsPod> { -    typedef TVectorTakingIntoAccountThePodType<T, TTypeTraits<T>::IsPod> TBase;  - -public:  -    TGeneralVector(const TBlob& blob)  -        : TBase(blob)  -    {  -    }  -};  -  +    typedef TVectorTakingIntoAccountThePodType<T, TTypeTraits<T>::IsPod> TBase; + +public: +    TGeneralVector(const TBlob& blob) +        : TBase(blob) +    { +    } +}; +  template <typename T>  class TGeneralVectorWriter: public TVectorTakingIntoAccountThePodTypeWriter<T, TTypeTraits<T>::IsPod> { -};  -  +}; +  template <typename TItem, bool> -struct TGeneralVectorG;  -  +struct TGeneralVectorG; +  template <typename TItem> -struct TGeneralVectorG<TItem, false> {  -    typedef TGeneralVector<TItem> T;  -};  -  +struct TGeneralVectorG<TItem, false> { +    typedef TGeneralVector<TItem> T; +}; +  template <typename TItem> -struct TGeneralVectorG<TItem, true> {  -    typedef TGeneralVectorWriter<TItem> T;  -};  -  +struct TGeneralVectorG<TItem, true> { +    typedef TGeneralVectorWriter<TItem> T; +}; +  template <>  struct TSaveLoadVectorNonPodElement<TString> {      static inline void Save(IOutputStream* out, const TString& s) {          out->Write(s.data(), s.size() + 1); -    }  -  +    } +      static inline void Load(TMemoryInput* in, TString& s, size_t elementSize) {          Y_ASSERT(elementSize > 0 && in->Avail() >= elementSize); -        s.assign(in->Buf(), elementSize - 1); /// excluding 0 at the end  -    }  -};  -  +        s.assign(in->Buf(), elementSize - 1); /// excluding 0 at the end +    } +}; +  template <bool G>  struct TStringsVectorG: public TGeneralVectorG<TString, G> { -};  -  +}; +  using TStringsVector = TGeneralVector<TString>;  using TStringsVectorWriter = TGeneralVectorWriter<TString>; diff --git a/library/cpp/on_disk/chunks/chunks_ut.cpp b/library/cpp/on_disk/chunks/chunks_ut.cpp index 8410bda27b1..f727647f7f2 100644 --- a/library/cpp/on_disk/chunks/chunks_ut.cpp +++ b/library/cpp/on_disk/chunks/chunks_ut.cpp @@ -1,279 +1,279 @@  #include <library/cpp/testing/unittest/registar.h> -#include <util/stream/file.h>  -#include <util/system/filemap.h>  -#include <util/system/tempfile.h>  +#include <util/stream/file.h> +#include <util/system/filemap.h> +#include <util/system/tempfile.h>  #include "chunked_helpers.h" -/// Data for TChunkedHelpersTest::TestGeneralVector  -struct TPodStruct {  -    int x;  -    float y;  -    TPodStruct(int _x = 0, float _y = 0)  -        : x(_x)  -        , y(_y)  -    {  -    }  -};  -/// And its serialization  +/// Data for TChunkedHelpersTest::TestGeneralVector +struct TPodStruct { +    int x; +    float y; +    TPodStruct(int _x = 0, float _y = 0) +        : x(_x) +        , y(_y) +    { +    } +}; +/// And its serialization  template <> -struct TSaveLoadVectorNonPodElement<TPodStruct> {  -    typedef TPodStruct TItem;  +struct TSaveLoadVectorNonPodElement<TPodStruct> { +    typedef TPodStruct TItem;      static inline void Save(IOutputStream* out, const TItem& item) { -        TSerializer<int>::Save(out, item.x);  -        TSerializer<float>::Save(out, item.y);  -    }  -  +        TSerializer<int>::Save(out, item.x); +        TSerializer<float>::Save(out, item.y); +    } +      static inline void Load(IInputStream* in, TItem& item, size_t elementSize) {          Y_ASSERT(elementSize == sizeof(TItem)); -        TSerializer<int>::Load(in, item.x);  -        TSerializer<float>::Load(in, item.y);  -    }  -};  -  +        TSerializer<int>::Load(in, item.x); +        TSerializer<float>::Load(in, item.y); +    } +}; +  class TChunkedHelpersTest: public TTestBase { -    UNIT_TEST_SUITE(TChunkedHelpersTest);  +    UNIT_TEST_SUITE(TChunkedHelpersTest);      UNIT_TEST(TestHash)      UNIT_TEST(TestGeneralVector)      UNIT_TEST(TestStrings);      UNIT_TEST(TestNamedChunkedData); -    UNIT_TEST_SUITE_END();  - -public:  -    void TestHash() {  -        {  -            TBufferStream stream;  -            {  -                TPlainHashWriter<ui64, ui16> writer;  -                writer.Add(5, 7);  -                writer.Save(stream);  -            }  -  -            {  -                TBlob temp = TBlob::FromStreamSingleThreaded(stream);  -                TPlainHash<ui64, ui16> reader(temp);  +    UNIT_TEST_SUITE_END(); + +public: +    void TestHash() { +        { +            TBufferStream stream; +            { +                TPlainHashWriter<ui64, ui16> writer; +                writer.Add(5, 7); +                writer.Save(stream); +            } + +            { +                TBlob temp = TBlob::FromStreamSingleThreaded(stream); +                TPlainHash<ui64, ui16> reader(temp);                  ui16 value = 0;                  UNIT_ASSERT(reader.Find(5, &value));                  UNIT_ASSERT_EQUAL(7, value); -                UNIT_ASSERT(!reader.Find(6, &value));  -            }  -        }  -  -        {  -            TBufferStream stream;  -            int v = 1;  -            wchar16 k = 'a';  -            {  -                TPlainHashWriter<wchar16, void*> writer;  -                writer.Add(k, &v);  -                writer.Save(stream);  -            }  -            {  -                TBlob temp = TBlob::FromStreamSingleThreaded(stream);  -                TPlainHash<wchar16, void*> reader(temp);  +                UNIT_ASSERT(!reader.Find(6, &value)); +            } +        } + +        { +            TBufferStream stream; +            int v = 1; +            wchar16 k = 'a'; +            { +                TPlainHashWriter<wchar16, void*> writer; +                writer.Add(k, &v); +                writer.Save(stream); +            } +            { +                TBlob temp = TBlob::FromStreamSingleThreaded(stream); +                TPlainHash<wchar16, void*> reader(temp);                  void* value = nullptr; -                UNIT_ASSERT(reader.Find(k, &value));  -                UNIT_ASSERT_EQUAL((int*)value, &v);  -            }  -        }  -    }  -  -    void TestGeneralVector() {  -        { /// ui32  -            const size_t N = 3;  +                UNIT_ASSERT(reader.Find(k, &value)); +                UNIT_ASSERT_EQUAL((int*)value, &v); +            } +        } +    } + +    void TestGeneralVector() { +        { /// ui32 +            const size_t N = 3;              TBufferStream stream;              { -                TGeneralVectorWriter<ui32> writer;  -                for (size_t i = 0; i < N; ++i)  -                    writer.PushBack(i);  +                TGeneralVectorWriter<ui32> writer; +                for (size_t i = 0; i < N; ++i) +                    writer.PushBack(i);                  writer.Save(stream);              } -            {  +            {                  TBlob temp = TBlob::FromStreamSingleThreaded(stream);                  TGeneralVector<ui32> reader(temp); -                UNIT_ASSERT_EQUAL(reader.GetSize(), N);  -                for (size_t i = 0; i < N; ++i) {  -                    ui32 value;  -                    reader.Get(i, value);  -                    UNIT_ASSERT_EQUAL(value, i);  -                    UNIT_ASSERT_EQUAL(reader.At(i), i);  -                }  +                UNIT_ASSERT_EQUAL(reader.GetSize(), N); +                for (size_t i = 0; i < N; ++i) { +                    ui32 value; +                    reader.Get(i, value); +                    UNIT_ASSERT_EQUAL(value, i); +                    UNIT_ASSERT_EQUAL(reader.At(i), i); +                }                  UNIT_ASSERT_EQUAL(reader.RealSize(), sizeof(ui64) + N * sizeof(ui32)); -            }  -        }  +            } +        }          { /// TString -            const size_t N = 4;  -            TBufferStream stream;  -            {  +            const size_t N = 4; +            TBufferStream stream; +            {                  TGeneralVectorWriter<TString> writer; -                for (size_t i = 0; i < N; ++i)  -                    writer.PushBack(ToString(i));  -                writer.Save(stream);  -            }  -            {  +                for (size_t i = 0; i < N; ++i) +                    writer.PushBack(ToString(i)); +                writer.Save(stream); +            } +            {                  TBlob temp = TBlob::FromStreamSingleThreaded(stream);                  TGeneralVector<TString> reader(temp); -                UNIT_ASSERT_EQUAL(reader.GetSize(), N);  -                for (size_t i = 0; i < N; ++i) {  +                UNIT_ASSERT_EQUAL(reader.GetSize(), N); +                for (size_t i = 0; i < N; ++i) {                      TString value; -                    reader.Get(i, value);  -                    UNIT_ASSERT_EQUAL(value, ToString(i));  -                    UNIT_ASSERT_EQUAL(reader.Get(i), ToString(i));  -                }  +                    reader.Get(i, value); +                    UNIT_ASSERT_EQUAL(value, ToString(i)); +                    UNIT_ASSERT_EQUAL(reader.Get(i), ToString(i)); +                }                  UNIT_ASSERT_EQUAL(reader.RealSize(), sizeof(ui64) * (N + 2) + N * 2); -            }  -        }  -        { /// some other struct  -            typedef TPodStruct TItem;  -            const size_t N = 2;  -            TBufferStream stream;  -            {  -                TGeneralVectorWriter<TItem> writer;  -                writer.PushBack(TItem(1, 2));  -                writer.PushBack(TItem(3, 4));  -                writer.Save(stream);  -            }  -            {  +            } +        } +        { /// some other struct +            typedef TPodStruct TItem; +            const size_t N = 2; +            TBufferStream stream; +            { +                TGeneralVectorWriter<TItem> writer; +                writer.PushBack(TItem(1, 2)); +                writer.PushBack(TItem(3, 4)); +                writer.Save(stream); +            } +            {                  TBlob temp = TBlob::FromStreamSingleThreaded(stream);                  TGeneralVector<TItem> reader(temp); -                UNIT_ASSERT_EQUAL(reader.GetSize(), N);  - -                TItem value;  -                reader.Get(0, value);  -                UNIT_ASSERT(value.x == 1 && value.y == 2.0);  -  -                reader.Get(1, value);  -                UNIT_ASSERT(value.x == 3 && value.y == 4.0);  -  +                UNIT_ASSERT_EQUAL(reader.GetSize(), N); + +                TItem value; +                reader.Get(0, value); +                UNIT_ASSERT(value.x == 1 && value.y == 2.0); + +                reader.Get(1, value); +                UNIT_ASSERT(value.x == 3 && value.y == 4.0); +                  UNIT_ASSERT_EQUAL(reader.RealSize(), sizeof(ui64) * (N + 2) + N * sizeof(TItem)); -            }  -        }  -        { /// pointer  -            const size_t N = 3;  +            } +        } +        { /// pointer +            const size_t N = 3;              TVector<int> data_holder(N); -            int* a = &(data_holder[0]);  -            TBufferStream stream;  +            int* a = &(data_holder[0]); +            TBufferStream stream;              { -                TGeneralVectorWriter<int*> writer;  -                for (size_t i = 0; i < N; ++i) {  -                    a[i] = i;  -                    writer.PushBack(a + i);  -                }  -                writer.Save(stream);  +                TGeneralVectorWriter<int*> writer; +                for (size_t i = 0; i < N; ++i) { +                    a[i] = i; +                    writer.PushBack(a + i); +                } +                writer.Save(stream);              } -            {  +            {                  TBlob temp = TBlob::FromStreamSingleThreaded(stream);                  TGeneralVector<int*> reader(temp); -                UNIT_ASSERT_EQUAL(reader.GetSize(), N);  -                for (size_t i = 0; i < N; ++i) {  -                    int* value;  -                    reader.Get(i, value);  -                    UNIT_ASSERT_EQUAL(value, a + i);  -                    UNIT_ASSERT_EQUAL(reader.At(i), a + i);  -                }  +                UNIT_ASSERT_EQUAL(reader.GetSize(), N); +                for (size_t i = 0; i < N; ++i) { +                    int* value; +                    reader.Get(i, value); +                    UNIT_ASSERT_EQUAL(value, a + i); +                    UNIT_ASSERT_EQUAL(reader.At(i), a + i); +                }                  UNIT_ASSERT_EQUAL(reader.RealSize(), sizeof(ui64) + N * sizeof(int*)); -            }  +            }          }          { /// std::pair<int, int>              typedef std::pair<int, int> TItem; -            const size_t N = 3;  -            TBufferStream stream;  -            {  -                TGeneralVectorWriter<TItem> writer;  -                for (size_t i = 0; i < N; ++i)  -                    writer.PushBack(TItem(i, i));  -                writer.Save(stream);  -            }  -            {  +            const size_t N = 3; +            TBufferStream stream; +            { +                TGeneralVectorWriter<TItem> writer; +                for (size_t i = 0; i < N; ++i) +                    writer.PushBack(TItem(i, i)); +                writer.Save(stream); +            } +            {                  TBlob temp = TBlob::FromStreamSingleThreaded(stream);                  TGeneralVector<TItem> reader(temp); -                UNIT_ASSERT_EQUAL(reader.GetSize(), N);  -                for (size_t i = 0; i < N; ++i) {  -                    TItem value;  -                    reader.Get(i, value);  -                    UNIT_ASSERT_EQUAL(value, TItem(i, i));  -                }  +                UNIT_ASSERT_EQUAL(reader.GetSize(), N); +                for (size_t i = 0; i < N; ++i) { +                    TItem value; +                    reader.Get(i, value); +                    UNIT_ASSERT_EQUAL(value, TItem(i, i)); +                }                  UNIT_ASSERT_EQUAL(reader.RealSize(), sizeof(ui64) + N * sizeof(TItem)); -            }  -        }  +            } +        }      } -    void TestStrings() {  +    void TestStrings() {          const TString FILENAME = "chunked_helpers_test.bin"; -        TTempFileHandle file(FILENAME.c_str());  +        TTempFileHandle file(FILENAME.c_str()); -        {  +        {              TFixedBufferFileOutput fOut(FILENAME); -            TStringsVectorWriter stringsWriter;  -            stringsWriter.PushBack("");  -            stringsWriter.PushBack("test");  -            TChunkedDataWriter writer(fOut);  -            WriteBlock(writer, stringsWriter);  -            writer.WriteFooter();  -        }  -  -        {  +            TStringsVectorWriter stringsWriter; +            stringsWriter.PushBack(""); +            stringsWriter.PushBack("test"); +            TChunkedDataWriter writer(fOut); +            WriteBlock(writer, stringsWriter); +            writer.WriteFooter(); +        } + +        {              TBlob fIn = TBlob::FromFileSingleThreaded(FILENAME); -            TStringsVector vct(GetBlock(fIn, 0));  -            UNIT_ASSERT_EQUAL(vct.Get(0), "");  -            UNIT_ASSERT_EQUAL(vct.Get(1), "test");  -  -            bool wasException = false;  -            try {  -                vct.Get(2);  -            } catch (...) {  -                wasException = true;  -            }  -            UNIT_ASSERT(wasException);  -        }  -    }  -  -    void TestNamedChunkedData() {  +            TStringsVector vct(GetBlock(fIn, 0)); +            UNIT_ASSERT_EQUAL(vct.Get(0), ""); +            UNIT_ASSERT_EQUAL(vct.Get(1), "test"); + +            bool wasException = false; +            try { +                vct.Get(2); +            } catch (...) { +                wasException = true; +            } +            UNIT_ASSERT(wasException); +        } +    } + +    void TestNamedChunkedData() {          const TString filename = MakeTempName(nullptr, "named_chunked_data_test");          TTempFile file(filename); -  -        {  + +        {              TFixedBufferFileOutput fOut(filename); -            TNamedChunkedDataWriter writer(fOut);  -  -            writer.NewBlock("alpha");  -            writer.Write("123456");  -  -            writer.NewBlock();  -            writer.Write("anonymous");  -  -            writer.NewBlock("omega");  -            writer.Write("12345678901234567");  -  -            writer.WriteFooter();  -        }  -  -        {  +            TNamedChunkedDataWriter writer(fOut); + +            writer.NewBlock("alpha"); +            writer.Write("123456"); + +            writer.NewBlock(); +            writer.Write("anonymous"); + +            writer.NewBlock("omega"); +            writer.Write("12345678901234567"); + +            writer.WriteFooter(); +        } + +        {              TBlob mf = TBlob::FromFileSingleThreaded(filename); -            TNamedChunkedDataReader reader(mf);  -  -            UNIT_ASSERT(reader.GetBlocksCount() == 3);  -  -            UNIT_ASSERT(reader.HasBlock("alpha"));  -            UNIT_ASSERT(reader.HasBlock("omega"));  -  -            UNIT_ASSERT_STRINGS_EQUAL(reader.GetBlockName(0), "alpha");  -            UNIT_ASSERT_STRINGS_EQUAL(reader.GetBlockName(1), "");  -            UNIT_ASSERT_STRINGS_EQUAL(reader.GetBlockName(2), "omega");  -  +            TNamedChunkedDataReader reader(mf); + +            UNIT_ASSERT(reader.GetBlocksCount() == 3); + +            UNIT_ASSERT(reader.HasBlock("alpha")); +            UNIT_ASSERT(reader.HasBlock("omega")); + +            UNIT_ASSERT_STRINGS_EQUAL(reader.GetBlockName(0), "alpha"); +            UNIT_ASSERT_STRINGS_EQUAL(reader.GetBlockName(1), ""); +            UNIT_ASSERT_STRINGS_EQUAL(reader.GetBlockName(2), "omega"); +              UNIT_ASSERT_EQUAL(reader.GetBlockLenByName("alpha"), 6); // padding not included -            UNIT_ASSERT_EQUAL(reader.GetBlockLenByName("omega"), 17);  -  -            UNIT_ASSERT(memcmp(reader.GetBlockByName("alpha"), "123456", 6) == 0);  -            UNIT_ASSERT(memcmp(reader.GetBlock(1), "anonymous", 9) == 0);  -            UNIT_ASSERT(memcmp(reader.GetBlockByName("omega"), "12345678901234567", 17) == 0);  -        }  -    }  -};  -  -UNIT_TEST_SUITE_REGISTRATION(TChunkedHelpersTest);  -  +            UNIT_ASSERT_EQUAL(reader.GetBlockLenByName("omega"), 17); + +            UNIT_ASSERT(memcmp(reader.GetBlockByName("alpha"), "123456", 6) == 0); +            UNIT_ASSERT(memcmp(reader.GetBlock(1), "anonymous", 9) == 0); +            UNIT_ASSERT(memcmp(reader.GetBlockByName("omega"), "12345678901234567", 17) == 0); +        } +    } +}; + +UNIT_TEST_SUITE_REGISTRATION(TChunkedHelpersTest); +  class TChunkedDataTest: public TTestBase {  private:      UNIT_TEST_SUITE(TChunkedDataTest); | 
