aboutsummaryrefslogtreecommitdiff
path: root/src/zenserver/projectstore/projectstore.cpp
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2023-09-20 15:22:03 +0200
committerGitHub <[email protected]>2023-09-20 15:22:03 +0200
commit14d7568f9c7d970b7bbf7b6463a0a8530f98bb6f (patch)
treebf24ac15759385cea339f7e1cf5380f984f5699a /src/zenserver/projectstore/projectstore.cpp
parentchangelog version bump (diff)
downloadzen-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.cpp110
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, {}};