diff options
author | Devtools Arcadia <arcadia-devtools@yandex-team.ru> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/on_disk/chunks/chunked_helpers.cpp | |
download | ydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/on_disk/chunks/chunked_helpers.cpp')
-rw-r--r-- | library/cpp/on_disk/chunks/chunked_helpers.cpp | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/library/cpp/on_disk/chunks/chunked_helpers.cpp b/library/cpp/on_disk/chunks/chunked_helpers.cpp new file mode 100644 index 0000000000..b7adba2753 --- /dev/null +++ b/library/cpp/on_disk/chunks/chunked_helpers.cpp @@ -0,0 +1,67 @@ +#include <util/ysaveload.h> + +#include "chunked_helpers.h" + +TBlob GetBlock(const TBlob& blob, size_t index) { + TChunkedDataReader reader(blob); + if (index >= reader.GetBlocksCount()) + ythrow yexception() << "index " << index << " is >= than block count " << reader.GetBlocksCount(); + size_t begin = (const char*)reader.GetBlock(index) - (const char*)blob.Data(); + return blob.SubBlob(begin, begin + reader.GetBlockLen(index)); +} + +/*************************** TNamedChunkedDataReader ***************************/ + +static const char* NamedChunkedDataMagic = "NamedChunkedData"; + +TNamedChunkedDataReader::TNamedChunkedDataReader(const TBlob& blob) + : TChunkedDataReader(blob) +{ + if (TChunkedDataReader::GetBlocksCount() < 1) + throw yexception() << "Too few blocks"; + + size_t block = TChunkedDataReader::GetBlocksCount() - 1; + size_t magicLen = strlen(NamedChunkedDataMagic); + if (GetBlockLen(block) < magicLen || memcmp(GetBlock(block), NamedChunkedDataMagic, magicLen) != 0) + throw yexception() << "Not a valid named chunked data file"; + + TMemoryInput input(static_cast<const char*>(GetBlock(block)) + magicLen, GetBlockLen(block) - magicLen); + Load(&input, Names); + + size_t index = 0; + for (TVector<TString>::const_iterator it = Names.begin(); it != Names.end(); ++it, ++index) { + if (!it->empty()) + NameToIndex[*it] = index; + } +} + +/*************************** TNamedChunkedDataWriter ***************************/ + +TNamedChunkedDataWriter::TNamedChunkedDataWriter(IOutputStream& slave) + : TChunkedDataWriter(slave) +{ +} + +TNamedChunkedDataWriter::~TNamedChunkedDataWriter() { +} + +void TNamedChunkedDataWriter::NewBlock() { + NewBlock(""); +} + +void TNamedChunkedDataWriter::NewBlock(const TString& name) { + if (!name.empty()) { + if (NameToIndex.count(name) != 0) + throw yexception() << "Block name is not unique"; + NameToIndex[name] = Names.size(); + } + Names.push_back(name); + TChunkedDataWriter::NewBlock(); +} + +void TNamedChunkedDataWriter::WriteFooter() { + NewBlock(""); + Write(NamedChunkedDataMagic); + Save(this, Names); + TChunkedDataWriter::WriteFooter(); +} |