diff options
| author | Stefan Boberg <[email protected]> | 2023-09-20 15:22:03 +0200 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-09-20 15:22:03 +0200 |
| commit | 14d7568f9c7d970b7bbf7b6463a0a8530f98bb6f (patch) | |
| tree | bf24ac15759385cea339f7e1cf5380f984f5699a /src/zenserver/projectstore/projectstore.cpp | |
| parent | changelog version bump (diff) | |
| download | zen-14d7568f9c7d970b7bbf7b6463a0a8530f98bb6f.tar.xz zen-14d7568f9c7d970b7bbf7b6463a0a8530f98bb6f.zip | |
VFS implementation for local storage service (#396)
currently, only Windows (using Projected File System) is supported
Diffstat (limited to 'src/zenserver/projectstore/projectstore.cpp')
| -rw-r--r-- | src/zenserver/projectstore/projectstore.cpp | 110 |
1 files changed, 102 insertions, 8 deletions
diff --git a/src/zenserver/projectstore/projectstore.cpp b/src/zenserver/projectstore/projectstore.cpp index 9be600e4e..1ad4403f4 100644 --- a/src/zenserver/projectstore/projectstore.cpp +++ b/src/zenserver/projectstore/projectstore.cpp @@ -691,6 +691,45 @@ ProjectStore::Oplog::FindChunk(Oid ChunkId) return {}; } +std::vector<ProjectStore::Oplog::ChunkInfo> +ProjectStore::Oplog::GetAllChunksInfo() +{ + // First just capture all the chunk ids + + std::vector<ChunkInfo> InfoArray; + + { + RwLock::SharedLockScope _(m_OplogLock); + + if (m_Storage) + { + const size_t NumEntries = m_FileMap.size() + m_ChunkMap.size(); + + InfoArray.reserve(NumEntries); + + for (const auto& Kv : m_FileMap) + { + InfoArray.push_back({.ChunkId = Kv.first}); + } + + for (const auto& Kv : m_ChunkMap) + { + InfoArray.push_back({.ChunkId = Kv.first}); + } + } + } + + for (ChunkInfo& Info : InfoArray) + { + if (IoBuffer Chunk = FindChunk(Info.ChunkId)) + { + Info.ChunkSize = Chunk.GetSize(); + } + } + + return InfoArray; +} + void ProjectStore::Oplog::IterateFileMap( std::function<void(const Oid&, const std::string_view& ServerPath, const std::string_view& ClientPath)>&& Fn) @@ -2056,6 +2095,49 @@ ProjectStore::GetProjectFiles(const std::string_view ProjectId, const std::strin } std::pair<HttpResponseCode, std::string> +ProjectStore::GetProjectChunks(const std::string_view ProjectId, const std::string_view OplogId, CbObject& OutPayload) +{ + ZEN_TRACE_CPU("ProjectStore::GetProjectChunks"); + + using namespace std::literals; + + Ref<ProjectStore::Project> Project = OpenProject(ProjectId); + if (!Project) + { + return {HttpResponseCode::NotFound, fmt::format("unknown project '{}'", ProjectId)}; + } + Project->TouchProject(); + + ProjectStore::Oplog* FoundLog = Project->OpenOplog(OplogId); + if (!FoundLog) + { + return {HttpResponseCode::NotFound, fmt::format("unknown oplog '{}/{}'", ProjectId, OplogId)}; + } + Project->TouchOplog(OplogId); + + std::vector<ProjectStore::Oplog::ChunkInfo> ChunkInfo = FoundLog->GetAllChunksInfo(); + + CbObjectWriter Response; + + Response.BeginArray("chunks"sv); + for (ProjectStore::Oplog::ChunkInfo& Info : ChunkInfo) + { + Response << Info.ChunkId; + } + Response.EndArray(); + + Response.BeginArray("sizes"sv); + for (ProjectStore::Oplog::ChunkInfo& Info : ChunkInfo) + { + Response << Info.ChunkSize; + } + Response.EndArray(); + + OutPayload = Response.Save(); + return {HttpResponseCode::OK, {}}; +} + +std::pair<HttpResponseCode, std::string> ProjectStore::GetChunkInfo(const std::string_view ProjectId, const std::string_view OplogId, const std::string_view ChunkId, @@ -2120,6 +2202,25 @@ ProjectStore::GetChunkRange(const std::string_view ProjectId, ZenContentType AcceptType, IoBuffer& OutChunk) { + if (ChunkId.size() != 2 * sizeof(Oid::OidBits)) + { + return {HttpResponseCode::BadRequest, fmt::format("Chunk request for invalid chunk id '{}/{}'/'{}'", ProjectId, OplogId, ChunkId)}; + } + + const Oid Obj = Oid::FromHexString(ChunkId); + + return GetChunkRange(ProjectId, OplogId, Obj, Offset, Size, AcceptType, OutChunk); +} + +std::pair<HttpResponseCode, std::string> +ProjectStore::GetChunkRange(const std::string_view ProjectId, + const std::string_view OplogId, + Oid ChunkId, + uint64_t Offset, + uint64_t Size, + ZenContentType AcceptType, + IoBuffer& OutChunk) +{ bool IsOffset = Offset != 0 || Size != ~(0ull); Ref<ProjectStore::Project> Project = OpenProject(ProjectId); @@ -2136,14 +2237,7 @@ ProjectStore::GetChunkRange(const std::string_view ProjectId, } Project->TouchOplog(OplogId); - if (ChunkId.size() != 2 * sizeof(Oid::OidBits)) - { - return {HttpResponseCode::BadRequest, fmt::format("Chunk request for invalid chunk id '{}/{}'/'{}'", ProjectId, OplogId, ChunkId)}; - } - - const Oid Obj = Oid::FromHexString(ChunkId); - - IoBuffer Chunk = FoundLog->FindChunk(Obj); + IoBuffer Chunk = FoundLog->FindChunk(ChunkId); if (!Chunk) { return {HttpResponseCode::NotFound, {}}; |