aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/archive/directory_models_archive_reader.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/archive/directory_models_archive_reader.cpp
downloadydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/archive/directory_models_archive_reader.cpp')
-rw-r--r--library/cpp/archive/directory_models_archive_reader.cpp115
1 files changed, 115 insertions, 0 deletions
diff --git a/library/cpp/archive/directory_models_archive_reader.cpp b/library/cpp/archive/directory_models_archive_reader.cpp
new file mode 100644
index 0000000000..6de9424c7c
--- /dev/null
+++ b/library/cpp/archive/directory_models_archive_reader.cpp
@@ -0,0 +1,115 @@
+#include "directory_models_archive_reader.h"
+#include "yarchive.h"
+
+#include <util/folder/dirut.h>
+#include <util/folder/filelist.h>
+#include <util/folder/path.h>
+#include <util/memory/blob.h>
+#include <util/stream/file.h>
+#include <util/stream/input.h>
+#include <util/stream/mem.h>
+
+TDirectoryModelsArchiveReader::TDirectoryModelsArchiveReader(const TString& path, bool lockMemory, bool ownBlobs)
+ : Path_(path)
+{
+ Y_ENSURE(IsDir(path), "directory not found on this path");
+
+ LoadFilesAndSubdirs("", lockMemory, ownBlobs);
+}
+
+TDirectoryModelsArchiveReader::~TDirectoryModelsArchiveReader() {}
+
+size_t TDirectoryModelsArchiveReader::Count() const noexcept {
+ return Recs_.size();
+}
+
+TString TDirectoryModelsArchiveReader::KeyByIndex(size_t n) const {
+ Y_ENSURE(n < Count(), "incorrect index " << n);
+ return Recs_[n];
+}
+
+bool TDirectoryModelsArchiveReader::Has(const TStringBuf key) const {
+ return BlobByKey_.contains(key) || PathByKey_.contains(key);
+}
+
+namespace {
+ struct TBlobOwningStream : public TMemoryInput {
+ TBlob Blob;
+ TBlobOwningStream(TBlob blob)
+ : TMemoryInput(blob.Data(), blob.Length())
+ , Blob(blob)
+ {}
+ };
+}
+
+TAutoPtr<IInputStream> TDirectoryModelsArchiveReader::ObjectByKey(const TStringBuf key) const {
+ return new TBlobOwningStream(BlobByKey(key));
+}
+
+TBlob TDirectoryModelsArchiveReader::ObjectBlobByKey(const TStringBuf key) const {
+ return BlobByKey(key);
+}
+
+TBlob TDirectoryModelsArchiveReader::BlobByKey(const TStringBuf key) const {
+ Y_ENSURE(Has(key), "key " << key << " not found");
+ if (auto ptr = BlobByKey_.FindPtr(key); ptr) {
+ return *ptr;
+ }
+ if (auto ptr = PathByKey_.FindPtr(key); ptr) {
+ return TBlob::FromFile(*ptr);
+ }
+ Y_UNREACHABLE();
+}
+
+bool TDirectoryModelsArchiveReader::Compressed() const {
+ return false;
+}
+
+TString TDirectoryModelsArchiveReader::NormalizePath(TString path) const {
+ path = "/" + path;
+ for (size_t i = 0; i < path.size(); i++) {
+ if (path[i] == '\\')
+ path[i] = '/';
+ }
+ return path;
+}
+
+void TDirectoryModelsArchiveReader::LoadFilesAndSubdirs(const TString& subPath, bool lockMemory, bool ownBlobs) {
+ TFileList fileList;
+ fileList.Fill(JoinFsPaths(Path_, subPath));
+ const char* file;
+ while ((file = fileList.Next()) != nullptr) {
+ TString key = JoinFsPaths(subPath, TString(file));
+ TString fullPath = JoinFsPaths(Path_, key);
+ TBlob fileBlob;
+ if (lockMemory) {
+ fileBlob = TBlob::LockedFromFile(fullPath);
+ } else {
+ fileBlob = TBlob::FromFile(fullPath);
+ }
+ if (key.EndsWith(".archive")) {
+ TArchiveReader reader(fileBlob);
+ for (size_t i = 0, iEnd = reader.Count(); i < iEnd; ++i) {
+ const TString archiveKey = reader.KeyByIndex(i);
+ const TString normalizedPath = NormalizePath(JoinFsPaths(subPath, archiveKey.substr(1)));
+ BlobByKey_.emplace(normalizedPath, reader.ObjectBlobByKey(archiveKey));
+ Recs_.push_back(normalizedPath);
+ }
+ } else {
+ const TString normalizedPath = NormalizePath(key);
+ if (lockMemory || ownBlobs) {
+ BlobByKey_.emplace(normalizedPath, fileBlob);
+ } else {
+ PathByKey_.emplace(normalizedPath, RealPath(fullPath));
+ }
+ Recs_.push_back(normalizedPath);
+ }
+ }
+
+ TDirsList dirsList;
+ dirsList.Fill(JoinFsPaths(Path_, subPath));
+ const char* dir;
+ while ((dir = dirsList.Next()) != nullptr) {
+ LoadFilesAndSubdirs(JoinFsPaths(subPath, TString(dir)), lockMemory, ownBlobs);
+ }
+}