aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/on_disk/chunks/chunked_helpers.cpp
diff options
context:
space:
mode:
authorDevtools Arcadia <arcadia-devtools@yandex-team.ru>2022-02-07 18:08:42 +0300
committerDevtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net>2022-02-07 18:08:42 +0300
commit1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch)
treee26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/on_disk/chunks/chunked_helpers.cpp
downloadydb-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.cpp67
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();
+}