aboutsummaryrefslogtreecommitdiff
path: root/src/zenserver/projectstore/httpprojectstore.cpp
diff options
context:
space:
mode:
authorMatt Peters <[email protected]>2024-10-11 06:07:06 -0600
committerGitHub Enterprise <[email protected]>2024-10-11 06:07:06 -0600
commitb62af061371fd8dd2128e7e7b928efee8463c6ef (patch)
treeefeb15a387f00914016f188fb21ae343b6a8b49a /src/zenserver/projectstore/httpprojectstore.cpp
parent5.5.9-pre1 (diff)
downloadzen-b62af061371fd8dd2128e7e7b928efee8463c6ef.tar.xz
zen-b62af061371fd8dd2128e7e7b928efee8463c6ef.zip
Add ability to read the oplog's ReferencedSet, as written by the cook… (#190)v5.5.9-pre7
Add ability to read the oplog's ReferencedSet, as written by the cooker, from the ReferencedSet op. Filter oplog entries requests by the ReferencedSet, if trim_by_referencedset parameter is present.. Add -trim=true/false parameter to oplog-mirror command, default to true, to request the trimmed/not trimmed oplog. Helper functions: Add paging to IterateOpLogWithKey. Add unit tests for IterateOpLog functions. Move OpKeyStringAsOid from httpprojectstore into projectstore.
Diffstat (limited to 'src/zenserver/projectstore/httpprojectstore.cpp')
-rw-r--r--src/zenserver/projectstore/httpprojectstore.cpp75
1 files changed, 48 insertions, 27 deletions
diff --git a/src/zenserver/projectstore/httpprojectstore.cpp b/src/zenserver/projectstore/httpprojectstore.cpp
index cffd2569f..5f4f44e31 100644
--- a/src/zenserver/projectstore/httpprojectstore.cpp
+++ b/src/zenserver/projectstore/httpprojectstore.cpp
@@ -2,6 +2,7 @@
#include "httpprojectstore.h"
+#include "oplogreferencedset.h"
#include "projectstore.h"
#include <zencore/compactbinarybuilder.h>
@@ -12,27 +13,10 @@
#include <zencore/logging.h>
#include <zencore/stream.h>
#include <zencore/trace.h>
+#include <zenstore/zenstore.h>
namespace zen {
-Oid
-OpKeyStringAsOId(std::string_view OpKey)
-{
- using namespace std::literals;
-
- CbObjectWriter Writer;
- Writer << "key"sv << OpKey;
-
- XXH3_128Stream KeyHasher;
- Writer.Save()["key"sv].WriteToStream([&](const void* Data, size_t Size) { KeyHasher.Append(Data, Size); });
- XXH3_128 KeyHash = KeyHasher.GetHash();
-
- Oid OpId;
- memcpy(OpId.OidBits, &KeyHash, sizeof(OpId.OidBits));
-
- return OpId;
-}
-
void
CSVHeader(bool Details, bool AttachmentDetails, StringBuilderBase& CSVWriter)
{
@@ -1401,6 +1385,28 @@ HttpProjectService::HandleOpLogRequest(HttpRouterRequest& Req)
}
}
+std::optional<OplogReferencedSet>
+LoadReferencedSet(ProjectStore::Oplog& Log)
+{
+ using namespace std::literals;
+
+ Oid ReferencedSetOplogId = OpKeyStringAsOid(OplogReferencedSet::ReferencedSetOplogKey);
+ std::optional<CbObject> ReferencedSetOp = Log.GetOpByKey(ReferencedSetOplogId);
+ if (!ReferencedSetOp)
+ {
+ return std::optional<OplogReferencedSet>();
+ }
+ // We expect only a single file in the "files" array; get the chunk for the first file
+ CbFieldView FileField = *(*ReferencedSetOp)["files"sv].AsArrayView().CreateViewIterator();
+ Oid ChunkId = FileField.AsObjectView()["id"sv].AsObjectId();
+ if (ChunkId == Oid::Zero)
+ {
+ return std::optional<OplogReferencedSet>();
+ }
+
+ return OplogReferencedSet::LoadFromChunk(Log.FindChunk(ChunkId));
+}
+
void
HttpProjectService::HandleOpLogEntriesRequest(HttpRouterRequest& Req)
{
@@ -1456,7 +1462,7 @@ HttpProjectService::HandleOpLogEntriesRequest(HttpRouterRequest& Req)
if (auto OpKey = Params.GetValue("opkey"); !OpKey.empty())
{
- Oid OpKeyId = OpKeyStringAsOId(OpKey);
+ Oid OpKeyId = OpKeyStringAsOid(OpKey);
std::optional<CbObject> Op = FoundLog->GetOpByKey(OpKeyId);
if (Op.has_value())
@@ -1477,6 +1483,11 @@ HttpProjectService::HandleOpLogEntriesRequest(HttpRouterRequest& Req)
}
else
{
+ std::optional<OplogReferencedSet> ReferencedSet;
+ if (auto TrimString = Params.GetValue("trim_by_referencedset"); TrimString == "true")
+ {
+ ReferencedSet = LoadReferencedSet(*FoundLog);
+ }
Response.BeginArray("entries"sv);
ProjectStore::Oplog::Paging EntryPaging;
@@ -1495,14 +1506,24 @@ HttpProjectService::HandleOpLogEntriesRequest(HttpRouterRequest& Req)
}
}
- if (FieldNamesFilter.empty())
- {
- FoundLog->IterateOplog([&Response](CbObjectView Op) { Response << Op; }, EntryPaging);
- }
- else
- {
- FoundLog->IterateOplog([this, &Response, &FilterObject](CbObjectView Op) { Response << FilterObject(Op); }, EntryPaging);
- }
+ bool ShouldFilterFields = !FieldNamesFilter.empty();
+ FoundLog->IterateOplogWithKey(
+ [this, &Response, &FilterObject, ShouldFilterFields, &ReferencedSet](uint32_t /* LSN */, const Oid& Key, CbObjectView Op) {
+ if (ReferencedSet && !ReferencedSet->Contains(Key, Op["key"].AsString()))
+ {
+ return;
+ }
+
+ if (ShouldFilterFields)
+ {
+ Response << FilterObject(Op);
+ }
+ else
+ {
+ Response << Op;
+ }
+ },
+ EntryPaging);
Response.EndArray();
}