aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2024-03-28 14:01:22 +0100
committerGitHub Enterprise <[email protected]>2024-03-28 14:01:22 +0100
commit04f1b48b006373ac82ae23a947dcb048d56cf63f (patch)
tree905aa41750e8b60700b2c0a2ae516a4a1702f4c1 /src
parentFaster reading of compressed buffer headers by not materializing entire sourc... (diff)
downloadzen-04f1b48b006373ac82ae23a947dcb048d56cf63f.tar.xz
zen-04f1b48b006373ac82ae23a947dcb048d56cf63f.zip
add "fieldnames" query param for GetProjectFiles/GetProjectChunkInfos (#29)
- Improvement: It is now possible to control which fields to include in `/prj/{project}/oplog/{log}/chunkinfos` request by adding a comma delimited list of filed names for `fieldnames` parameter - Default fields are: `id`, `rawhash` and `rawsize` (translates to `?fieldnames=id,rawhash,rawsize`) - Use `?fieldnames=*` to get all the fields - Improvement: It is now possible to control which fields to include in `/prj/{project}/oplog/{log}/files` request by adding a comma delimited list of filed names for `fieldnames` parameter - Default fields are: `id`, `clientpath` and `serverpath` (translates to `?fieldnames=id,clientpath,serverpath`), `filter=client` only applies if `fieldnames` is not given as a parameter - Use `?fieldnames=*` to get all the fields
Diffstat (limited to 'src')
-rw-r--r--src/zenserver/projectstore/httpprojectstore.cpp48
-rw-r--r--src/zenserver/projectstore/projectstore.cpp97
-rw-r--r--src/zenserver/projectstore/projectstore.h15
3 files changed, 137 insertions, 23 deletions
diff --git a/src/zenserver/projectstore/httpprojectstore.cpp b/src/zenserver/projectstore/httpprojectstore.cpp
index e8a748c4c..f2bf5b353 100644
--- a/src/zenserver/projectstore/httpprojectstore.cpp
+++ b/src/zenserver/projectstore/httpprojectstore.cpp
@@ -621,10 +621,31 @@ HttpProjectService::HandleFilesRequest(HttpRouterRequest& Req)
HttpServerRequest::QueryParams Params = HttpReq.GetQueryParams();
- const bool FilterClient = Params.GetValue("filter"sv) == "client"sv;
+ std::unordered_set<std::string> WantedFieldNames;
+ if (auto FieldFilter = HttpServerRequest::Decode(Params.GetValue("fieldnames")); !FieldFilter.empty())
+ {
+ if (FieldFilter != "*") // Get all - empty FieldFilter equal getting all fields
+ {
+ ForEachStrTok(FieldFilter, ',', [&](std::string_view FieldName) {
+ WantedFieldNames.insert(std::string(FieldName));
+ return true;
+ });
+ }
+ }
+ else
+ {
+ const bool FilterClient = Params.GetValue("filter"sv) == "client"sv;
+ WantedFieldNames.insert("id");
+ WantedFieldNames.insert("clientpath");
+ if (!FilterClient)
+ {
+ WantedFieldNames.insert("serverpath");
+ }
+ }
CbObject ResponsePayload;
- std::pair<HttpResponseCode, std::string> Result = m_ProjectStore->GetProjectFiles(ProjectId, OplogId, FilterClient, ResponsePayload);
+ std::pair<HttpResponseCode, std::string> Result =
+ m_ProjectStore->GetProjectFiles(ProjectId, OplogId, WantedFieldNames, ResponsePayload);
if (Result.first == HttpResponseCode::OK)
{
if (HttpReq.AcceptContentType() == HttpContentType::kCompressedBinary)
@@ -666,8 +687,29 @@ HttpProjectService::HandleChunkInfosRequest(HttpRouterRequest& Req)
const auto& ProjectId = Req.GetCapture(1);
const auto& OplogId = Req.GetCapture(2);
+ HttpServerRequest::QueryParams Params = HttpReq.GetQueryParams();
+
+ std::unordered_set<std::string> WantedFieldNames;
+ if (auto FieldFilter = HttpServerRequest::Decode(Params.GetValue("fieldnames")); !FieldFilter.empty())
+ {
+ if (FieldFilter != "*") // Get all - empty FieldFilter equal getting all fields
+ {
+ ForEachStrTok(FieldFilter, ',', [&](std::string_view FieldName) {
+ WantedFieldNames.insert(std::string(FieldName));
+ return true;
+ });
+ }
+ }
+ else
+ {
+ WantedFieldNames.insert("id");
+ WantedFieldNames.insert("rawhash");
+ WantedFieldNames.insert("rawsize");
+ }
+
CbObject ResponsePayload;
- std::pair<HttpResponseCode, std::string> Result = m_ProjectStore->GetProjectChunkInfos(ProjectId, OplogId, ResponsePayload);
+ std::pair<HttpResponseCode, std::string> Result =
+ m_ProjectStore->GetProjectChunkInfos(ProjectId, OplogId, WantedFieldNames, ResponsePayload);
if (Result.first == HttpResponseCode::OK)
{
if (HttpReq.AcceptContentType() == HttpContentType::kCompressedBinary)
diff --git a/src/zenserver/projectstore/projectstore.cpp b/src/zenserver/projectstore/projectstore.cpp
index 3d8004be3..f01134fa5 100644
--- a/src/zenserver/projectstore/projectstore.cpp
+++ b/src/zenserver/projectstore/projectstore.cpp
@@ -2501,7 +2501,10 @@ ProjectStore::GetProjectsList()
}
std::pair<HttpResponseCode, std::string>
-ProjectStore::GetProjectFiles(const std::string_view ProjectId, const std::string_view OplogId, bool FilterClient, CbObject& OutPayload)
+ProjectStore::GetProjectFiles(const std::string_view ProjectId,
+ const std::string_view OplogId,
+ const std::unordered_set<std::string>& WantedFieldNames,
+ CbObject& OutPayload)
{
ZEN_TRACE_CPU("Store::GetProjectFiles");
@@ -2521,17 +2524,53 @@ ProjectStore::GetProjectFiles(const std::string_view ProjectId, const std::strin
}
Project->TouchOplog(OplogId);
+ const bool WantsAllFields = WantedFieldNames.empty();
+
+ const bool WantsIdField = WantsAllFields || WantedFieldNames.contains("id");
+ const bool WantsClientPathField = WantsAllFields || WantedFieldNames.contains("clientpath");
+ const bool WantsServerPathField = WantsAllFields || WantedFieldNames.contains("serverpath");
+ const bool WantsRawSizeField = WantsAllFields || WantedFieldNames.contains("rawsize");
+ const bool WantsSizeField = WantsAllFields || WantedFieldNames.contains("size");
+
CbObjectWriter Response;
Response.BeginArray("files"sv);
FoundLog->IterateFileMap([&](const Oid& Id, const std::string_view& ServerPath, const std::string_view& ClientPath) {
Response.BeginObject();
- Response << "id"sv << Id;
- Response << "clientpath"sv << ClientPath;
- if (!FilterClient && !ServerPath.empty())
+ if (WantsIdField)
+ {
+ Response << "id"sv << Id;
+ }
+ if (WantsClientPathField)
+ {
+ Response << "clientpath"sv << ClientPath;
+ }
+ if (WantsServerPathField && !ServerPath.empty())
{
Response << "serverpath"sv << ServerPath;
}
+ if (WantsRawSizeField || WantsSizeField)
+ {
+ IoBuffer Chunk = FoundLog->FindChunk(Id);
+ if (WantsSizeField)
+ {
+ Response << "size"sv << Chunk.GetSize();
+ }
+ if (WantsRawSizeField)
+ {
+ if (Chunk.GetContentType() == ZenContentType::kCompressedBinary)
+ {
+ IoHash _;
+ uint64_t RawSize = 0;
+ (void)CompressedBuffer::FromCompressed(SharedBuffer(Chunk), _, RawSize);
+ Response << "rawsize"sv << RawSize;
+ }
+ else
+ {
+ Response << "rawsize"sv << Chunk.GetSize();
+ }
+ }
+ }
Response.EndObject();
});
@@ -2541,7 +2580,10 @@ ProjectStore::GetProjectFiles(const std::string_view ProjectId, const std::strin
}
std::pair<HttpResponseCode, std::string>
-ProjectStore::GetProjectChunkInfos(const std::string_view ProjectId, const std::string_view OplogId, CbObject& OutPayload)
+ProjectStore::GetProjectChunkInfos(const std::string_view ProjectId,
+ const std::string_view OplogId,
+ const std::unordered_set<std::string>& WantedFieldNames,
+ CbObject& OutPayload)
{
ZEN_TRACE_CPU("ProjectStore::GetProjectChunkInfos");
@@ -2564,25 +2606,54 @@ ProjectStore::GetProjectChunkInfos(const std::string_view ProjectId, const std::
std::vector<std::pair<Oid, IoHash>> ChunkInfos;
FoundLog->IterateChunkMap([&ChunkInfos](const Oid& Id, const IoHash& Hash) { ChunkInfos.push_back({Id, Hash}); });
+ const bool WantsAllFields = WantedFieldNames.empty();
+
+ const bool WantsIdField = WantsAllFields || WantedFieldNames.contains("id");
+ const bool WantsRawHashField = WantsAllFields || WantedFieldNames.contains("rawhash");
+ const bool WantsRawSizeField = WantsAllFields || WantedFieldNames.contains("rawsize");
+ const bool WantsSizeField = WantsAllFields || WantedFieldNames.contains("size");
+
CbObjectWriter Response;
Response.BeginArray("chunkinfos"sv);
for (const auto& ChunkInfo : ChunkInfos)
{
- if (IoBuffer Chunk = FoundLog->FindChunk(ChunkInfo.first))
+ Response.BeginObject();
+ if (WantsIdField)
{
- Response.BeginObject();
Response << "id"sv << ChunkInfo.first;
+ }
+ if (WantsRawHashField)
+ {
Response << "rawhash"sv << ChunkInfo.second;
- uint64_t RawSize = Chunk.GetSize();
- if (Chunk.GetContentType() == ZenContentType::kCompressedBinary)
+ }
+
+ if (WantsRawSizeField || WantsSizeField)
+ {
+ if (IoBuffer Chunk = FoundLog->FindChunk(ChunkInfo.first))
{
- IoHash _;
- (void)CompressedBuffer::FromCompressed(SharedBuffer(Chunk), _, RawSize);
+ uint64_t Size = Chunk.GetSize();
+ if (WantsSizeField)
+ {
+ Response << "size"sv << Size;
+ }
+ if (WantsRawSizeField)
+ {
+ if (Chunk.GetContentType() == ZenContentType::kCompressedBinary)
+ {
+ IoHash _;
+ uint64_t RawSize = 0;
+ (void)CompressedBuffer::FromCompressed(SharedBuffer(Chunk), _, RawSize);
+ Response << "rawsize"sv << RawSize;
+ }
+ else
+ {
+ Response << "rawsize"sv << Size;
+ }
+ }
}
- Response << "rawsize"sv << RawSize;
- Response.EndObject();
}
+ Response.EndObject();
}
Response.EndArray();
diff --git a/src/zenserver/projectstore/projectstore.h b/src/zenserver/projectstore/projectstore.h
index 191dcf1f8..e07853ca8 100644
--- a/src/zenserver/projectstore/projectstore.h
+++ b/src/zenserver/projectstore/projectstore.h
@@ -316,13 +316,14 @@ public:
virtual std::vector<GcReferenceChecker*> CreateReferenceCheckers(GcCtx& Ctx) override;
CbArray GetProjectsList();
- std::pair<HttpResponseCode, std::string> GetProjectFiles(const std::string_view ProjectId,
- const std::string_view OplogId,
- bool FilterClient,
- CbObject& OutPayload);
- std::pair<HttpResponseCode, std::string> GetProjectChunkInfos(const std::string_view ProjectId,
- const std::string_view OplogId,
- CbObject& OutPayload);
+ std::pair<HttpResponseCode, std::string> GetProjectFiles(const std::string_view ProjectId,
+ const std::string_view OplogId,
+ const std::unordered_set<std::string>& WantedFieldNames,
+ CbObject& OutPayload);
+ std::pair<HttpResponseCode, std::string> GetProjectChunkInfos(const std::string_view ProjectId,
+ const std::string_view OplogId,
+ const std::unordered_set<std::string>& WantedFieldNames,
+ CbObject& OutPayload);
std::pair<HttpResponseCode, std::string> GetChunkInfo(const std::string_view ProjectId,
const std::string_view OplogId,
const std::string_view ChunkId,