diff options
| author | Dan Engelbrecht <[email protected]> | 2025-10-03 15:57:42 +0200 |
|---|---|---|
| committer | GitHub Enterprise <[email protected]> | 2025-10-03 15:57:42 +0200 |
| commit | 42a2c2582b10a598ce5ef50f7feb4bab394b8fc1 (patch) | |
| tree | 267816281dcdbeda9900a38e6863265ecc257f15 /src/zenutil/cache | |
| parent | 5.7.5-pre0 (diff) | |
| download | zen-42a2c2582b10a598ce5ef50f7feb4bab394b8fc1.tar.xz zen-42a2c2582b10a598ce5ef50f7feb4bab394b8fc1.zip | |
cacherequests helpers test only (#551)
* don't use cacherequests utils in cache_cmd.cpp
* make zenutil/cacherequests code into test code helpers only
Diffstat (limited to 'src/zenutil/cache')
| -rw-r--r-- | src/zenutil/cache/cachekey.cpp | 9 | ||||
| -rw-r--r-- | src/zenutil/cache/cachepolicy.cpp | 426 | ||||
| -rw-r--r-- | src/zenutil/cache/cacherequests.cpp | 1689 |
3 files changed, 0 insertions, 2124 deletions
diff --git a/src/zenutil/cache/cachekey.cpp b/src/zenutil/cache/cachekey.cpp deleted file mode 100644 index 545b47f11..000000000 --- a/src/zenutil/cache/cachekey.cpp +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright Epic Games, Inc. All Rights Reserved. - -#include <zenutil/cache/cachekey.h> - -namespace zen { - -const CacheKey CacheKey::Empty = CacheKey{.Bucket = std::string(), .Hash = IoHash()}; - -} // namespace zen diff --git a/src/zenutil/cache/cachepolicy.cpp b/src/zenutil/cache/cachepolicy.cpp deleted file mode 100644 index 0bdfd87ce..000000000 --- a/src/zenutil/cache/cachepolicy.cpp +++ /dev/null @@ -1,426 +0,0 @@ -// Copyright Epic Games, Inc. All Rights Reserved. - -#include <zenutil/cache/cachepolicy.h> - -#include <zencore/compactbinary.h> -#include <zencore/compactbinarybuilder.h> -#include <zencore/enumflags.h> -#include <zencore/string.h> - -#include <algorithm> -#include <unordered_map> - -#if ZEN_WITH_TESTS -# include <zencore/testing.h> -#endif - -namespace zen::Private { -class CacheRecordPolicyShared; -} - -namespace zen { - -using namespace std::literals; - -namespace DerivedData::Private { - - constinit char CachePolicyDelimiter = ','; - - struct CachePolicyToTextData - { - CachePolicy Policy; - std::string_view Text; - }; - - constinit CachePolicyToTextData CachePolicyToText[]{ - // Flags with multiple bits are ordered by bit count to minimize token count in the text format. - {CachePolicy::Default, "Default"sv}, - {CachePolicy::Remote, "Remote"sv}, - {CachePolicy::Local, "Local"sv}, - {CachePolicy::Store, "Store"sv}, - {CachePolicy::Query, "Query"sv}, - // Flags with only one bit can be in any order. Match the order in CachePolicy. - {CachePolicy::QueryLocal, "QueryLocal"sv}, - {CachePolicy::QueryRemote, "QueryRemote"sv}, - {CachePolicy::StoreLocal, "StoreLocal"sv}, - {CachePolicy::StoreRemote, "StoreRemote"sv}, - {CachePolicy::SkipMeta, "SkipMeta"sv}, - {CachePolicy::SkipData, "SkipData"sv}, - {CachePolicy::PartialRecord, "PartialRecord"sv}, - {CachePolicy::KeepAlive, "KeepAlive"sv}, - // None must be last because it matches every policy. - {CachePolicy::None, "None"sv}, - }; - - constinit CachePolicy CachePolicyKnownFlags = - CachePolicy::Default | CachePolicy::SkipMeta | CachePolicy::SkipData | CachePolicy::PartialRecord | CachePolicy::KeepAlive; - - StringBuilderBase& CachePolicyToString(StringBuilderBase& Builder, CachePolicy Policy) - { - // Mask out unknown flags. None will be written if no flags are known. - Policy &= CachePolicyKnownFlags; - for (const CachePolicyToTextData& Pair : CachePolicyToText) - { - if (EnumHasAllFlags(Policy, Pair.Policy)) - { - EnumRemoveFlags(Policy, Pair.Policy); - Builder << Pair.Text << CachePolicyDelimiter; - if (Policy == CachePolicy::None) - { - break; - } - } - } - Builder.RemoveSuffix(1); - return Builder; - } - - CachePolicy ParseCachePolicy(const std::string_view Text) - { - ZEN_ASSERT(!Text.empty()); // ParseCachePolicy requires a non-empty string - CachePolicy Policy = CachePolicy::None; - ForEachStrTok(Text, CachePolicyDelimiter, [&Policy, Index = int32_t(0)](const std::string_view& Token) mutable { - const int32_t EndIndex = Index; - for (; size_t(Index) < sizeof(CachePolicyToText) / sizeof(CachePolicyToText[0]); ++Index) - { - if (CachePolicyToText[Index].Text == Token) - { - Policy |= CachePolicyToText[Index].Policy; - ++Index; - return true; - } - } - for (Index = 0; Index < EndIndex; ++Index) - { - if (CachePolicyToText[Index].Text == Token) - { - Policy |= CachePolicyToText[Index].Policy; - ++Index; - return true; - } - } - return true; - }); - return Policy; - } - -} // namespace DerivedData::Private - -StringBuilderBase& -operator<<(StringBuilderBase& Builder, CachePolicy Policy) -{ - return DerivedData::Private::CachePolicyToString(Builder, Policy); -} - -CachePolicy -ParseCachePolicy(std::string_view Text) -{ - return DerivedData::Private::ParseCachePolicy(Text); -} - -CachePolicy -ConvertToUpstream(CachePolicy Policy) -{ - // Set Local flags equal to downstream's Remote flags. - // Delete Skip flags if StoreLocal is true, otherwise use the downstream value. - // Use the downstream value for all other flags. - - CachePolicy UpstreamPolicy = CachePolicy::None; - - if (EnumHasAllFlags(Policy, CachePolicy::QueryRemote)) - { - UpstreamPolicy |= CachePolicy::QueryLocal; - } - - if (EnumHasAllFlags(Policy, CachePolicy::StoreRemote)) - { - UpstreamPolicy |= CachePolicy::StoreLocal; - } - - if (!EnumHasAllFlags(Policy, CachePolicy::StoreLocal)) - { - UpstreamPolicy |= (Policy & (CachePolicy::SkipData | CachePolicy::SkipMeta)); - } - - UpstreamPolicy |= Policy & ~(CachePolicy::Local | CachePolicy::SkipData | CachePolicy::SkipMeta); - - return UpstreamPolicy; -} - -class Private::CacheRecordPolicyShared final : public Private::ICacheRecordPolicyShared -{ -public: - inline void AddValuePolicy(const CacheValuePolicy& Value) final - { - ZEN_ASSERT(Value.Id); // Failed to add value policy because the ID is null. - const auto Insert = - std::lower_bound(Values.begin(), Values.end(), Value, [](const CacheValuePolicy& Existing, const CacheValuePolicy& New) { - return Existing.Id < New.Id; - }); - ZEN_ASSERT( - !(Insert < Values.end() && - Insert->Id == Value.Id)); // Failed to add value policy with ID %s because it has an existing value policy with that ID. ") - Values.insert(Insert, Value); - } - - inline std::span<const CacheValuePolicy> GetValuePolicies() const final { return Values; } - -private: - std::vector<CacheValuePolicy> Values; -}; - -CachePolicy -CacheRecordPolicy::GetValuePolicy(const Oid& Id) const -{ - if (Shared) - { - const std::span<const CacheValuePolicy> Values = Shared->GetValuePolicies(); - const auto Iter = - std::lower_bound(Values.begin(), Values.end(), Id, [](const CacheValuePolicy& A, const Oid& B) { return A.Id < B; }); - if (Iter != Values.end() && Iter->Id == Id) - { - return Iter->Policy; - } - } - return DefaultValuePolicy; -} - -void -CacheRecordPolicy::Save(CbWriter& Writer) const -{ - Writer.BeginObject(); - // The RecordPolicy is calculated from the ValuePolicies and does not need to be saved separately. - Writer.AddString("BasePolicy"sv, WriteToString<128>(GetBasePolicy())); - if (!IsUniform()) - { - Writer.BeginArray("ValuePolicies"sv); - for (const CacheValuePolicy& Value : GetValuePolicies()) - { - Writer.BeginObject(); - Writer.AddObjectId("Id"sv, Value.Id); - Writer.AddString("Policy"sv, WriteToString<128>(Value.Policy)); - Writer.EndObject(); - } - Writer.EndArray(); - } - Writer.EndObject(); -} - -OptionalCacheRecordPolicy -CacheRecordPolicy::Load(const CbObjectView Object) -{ - std::string_view BasePolicyText = Object["BasePolicy"sv].AsString(); - if (BasePolicyText.empty()) - { - return {}; - } - - CacheRecordPolicyBuilder Builder(ParseCachePolicy(BasePolicyText)); - for (CbFieldView ValueField : Object["ValuePolicies"sv]) - { - const CbObjectView Value = ValueField.AsObjectView(); - const Oid Id = Value["Id"sv].AsObjectId(); - const std::string_view PolicyText = Value["Policy"sv].AsString(); - if (!Id || PolicyText.empty()) - { - return {}; - } - CachePolicy Policy = ParseCachePolicy(PolicyText); - if (EnumHasAnyFlags(Policy, ~CacheValuePolicy::PolicyMask)) - { - return {}; - } - Builder.AddValuePolicy(Id, Policy); - } - - return Builder.Build(); -} - -CacheRecordPolicy -CacheRecordPolicy::ConvertToUpstream() const -{ - CacheRecordPolicyBuilder Builder(zen::ConvertToUpstream(GetBasePolicy())); - for (const CacheValuePolicy& ValuePolicy : GetValuePolicies()) - { - Builder.AddValuePolicy(ValuePolicy.Id, zen::ConvertToUpstream(ValuePolicy.Policy)); - } - return Builder.Build(); -} - -void -CacheRecordPolicyBuilder::AddValuePolicy(const CacheValuePolicy& Value) -{ - ZEN_ASSERT(!EnumHasAnyFlags(Value.Policy, - ~Value.PolicyMask)); // Value policy contains flags that only make sense on the record policy. Policy: %s - if (Value.Policy == (BasePolicy & Value.PolicyMask)) - { - return; - } - if (!Shared) - { - Shared = new Private::CacheRecordPolicyShared; - } - Shared->AddValuePolicy(Value); -} - -CacheRecordPolicy -CacheRecordPolicyBuilder::Build() -{ - CacheRecordPolicy Policy(BasePolicy); - if (Shared) - { - const auto Add = [](const CachePolicy A, const CachePolicy B) { - return ((A | B) & ~CachePolicy::SkipData) | ((A & B) & CachePolicy::SkipData); - }; - const std::span<const CacheValuePolicy> Values = Shared->GetValuePolicies(); - Policy.RecordPolicy = BasePolicy; - for (const CacheValuePolicy& ValuePolicy : Values) - { - Policy.RecordPolicy = Add(Policy.RecordPolicy, ValuePolicy.Policy); - } - Policy.Shared = std::move(Shared); - } - return Policy; -} - -#if ZEN_WITH_TESTS -TEST_CASE("cachepolicy") -{ - SUBCASE("atomics serialization") - { - CachePolicy SomeAtomics[] = {CachePolicy::None, - CachePolicy::QueryLocal, - CachePolicy::StoreRemote, - CachePolicy::SkipData, - CachePolicy::KeepAlive}; - for (CachePolicy Atomic : SomeAtomics) - { - CHECK(ParseCachePolicy(WriteToString<128>(Atomic)) == Atomic); - } - // Also verify that we ignore unrecognized bits - for (CachePolicy Atomic : SomeAtomics) - { - CHECK(ParseCachePolicy(WriteToString<128>(Atomic | (CachePolicy)0x10000000)) == Atomic); - } - } - SUBCASE("aliases serialization") - { - CachePolicy SomeAliases[] = {CachePolicy::Query, CachePolicy::Local}; - for (CachePolicy Alias : SomeAliases) - { - CHECK(ParseCachePolicy(WriteToString<128>(Alias)) == Alias); - } - // Also verify that we ignore unrecognized bits - for (CachePolicy Alias : SomeAliases) - { - CHECK(ParseCachePolicy(WriteToString<128>(Alias | (CachePolicy)0x10000000)) == Alias); - } - } - SUBCASE("aliases take priority over atomics") - { - CHECK(WriteToString<128>(CachePolicy::Default).ToView() == "Default"sv); - CHECK(WriteToString<128>(CachePolicy::Query).ToView() == "Query"sv); - CHECK(WriteToString<128>(CachePolicy::Local).ToView() == "Local"sv); - } - SUBCASE("policies requiring multiple strings work") - { - char Delimiter = ','; - CachePolicy Combination = CachePolicy::SkipData | CachePolicy::QueryLocal; - CHECK(WriteToString<128>(Combination).ToView().find(Delimiter) != std::string_view::npos); - CHECK(ParseCachePolicy(WriteToString<128>(Combination)) == Combination); - } - SUBCASE("parsing invalid text") - { - CHECK(ParseCachePolicy(",,,") == CachePolicy::None); - CHECK(ParseCachePolicy("fee,fie,foo,fum") == CachePolicy::None); - CHECK(ParseCachePolicy("fee,KeepAlive,foo,fum") == CachePolicy::KeepAlive); - } -} - -TEST_CASE("cacherecordpolicy") -{ - SUBCASE("policy with no values") - { - CachePolicy Policy = CachePolicy::SkipData | CachePolicy::QueryLocal | CachePolicy::PartialRecord; - CachePolicy ValuePolicy = Policy & CacheValuePolicy::PolicyMask; - CacheRecordPolicy RecordPolicy; - CacheRecordPolicyBuilder Builder(Policy); - RecordPolicy = Builder.Build(); - SUBCASE("construct") - { - CHECK(RecordPolicy.IsUniform()); - CHECK(RecordPolicy.GetRecordPolicy() == Policy); - CHECK(RecordPolicy.GetBasePolicy() == Policy); - CHECK(RecordPolicy.GetValuePolicy(Oid::NewOid()) == ValuePolicy); - CHECK(RecordPolicy.GetValuePolicies().size() == 0); - } - SUBCASE("saveload") - { - CbWriter Writer; - RecordPolicy.Save(Writer); - CbObject Saved = Writer.Save()->AsObject(); - CacheRecordPolicy Loaded = CacheRecordPolicy::Load(Saved).Get(); - CHECK(Loaded.IsUniform()); - CHECK(Loaded.GetRecordPolicy() == Policy); - CHECK(Loaded.GetBasePolicy() == Policy); - CHECK(Loaded.GetValuePolicy(Oid::NewOid()) == ValuePolicy); - CHECK(Loaded.GetValuePolicies().size() == 0); - } - } - - SUBCASE("policy with values") - { - CachePolicy DefaultPolicy = CachePolicy::StoreRemote | CachePolicy::QueryLocal | CachePolicy::PartialRecord; - CachePolicy DefaultValuePolicy = DefaultPolicy & CacheValuePolicy::PolicyMask; - CachePolicy PartialOverlap = CachePolicy::StoreRemote; - CachePolicy NoOverlap = CachePolicy::QueryRemote; - CachePolicy UnionPolicy = DefaultPolicy | PartialOverlap | NoOverlap | CachePolicy::PartialRecord; - - CacheRecordPolicy RecordPolicy; - CacheRecordPolicyBuilder Builder(DefaultPolicy); - Oid PartialOid = Oid::NewOid(); - Oid NoOverlapOid = Oid::NewOid(); - Oid OtherOid = Oid::NewOid(); - Builder.AddValuePolicy(PartialOid, PartialOverlap); - Builder.AddValuePolicy(NoOverlapOid, NoOverlap); - RecordPolicy = Builder.Build(); - SUBCASE("construct") - { - CHECK(!RecordPolicy.IsUniform()); - CHECK(RecordPolicy.GetRecordPolicy() == UnionPolicy); - CHECK(RecordPolicy.GetBasePolicy() == DefaultPolicy); - CHECK(RecordPolicy.GetValuePolicy(PartialOid) == PartialOverlap); - CHECK(RecordPolicy.GetValuePolicy(NoOverlapOid) == NoOverlap); - CHECK(RecordPolicy.GetValuePolicy(OtherOid) == DefaultValuePolicy); - CHECK(RecordPolicy.GetValuePolicies().size() == 2); - } - SUBCASE("saveload") - { - CbWriter Writer; - RecordPolicy.Save(Writer); - CbObject Saved = Writer.Save()->AsObject(); - CacheRecordPolicy Loaded = CacheRecordPolicy::Load(Saved).Get(); - CHECK(!RecordPolicy.IsUniform()); - CHECK(RecordPolicy.GetRecordPolicy() == UnionPolicy); - CHECK(RecordPolicy.GetBasePolicy() == DefaultPolicy); - CHECK(RecordPolicy.GetValuePolicy(PartialOid) == PartialOverlap); - CHECK(RecordPolicy.GetValuePolicy(NoOverlapOid) == NoOverlap); - CHECK(RecordPolicy.GetValuePolicy(OtherOid) == DefaultValuePolicy); - CHECK(RecordPolicy.GetValuePolicies().size() == 2); - } - } - - SUBCASE("parsing invalid text") - { - OptionalCacheRecordPolicy Loaded = CacheRecordPolicy::Load(CbObject()); - CHECK(Loaded.IsNull()); - } -} -#endif - -void -cachepolicy_forcelink() -{ -} - -} // namespace zen diff --git a/src/zenutil/cache/cacherequests.cpp b/src/zenutil/cache/cacherequests.cpp deleted file mode 100644 index b8169182d..000000000 --- a/src/zenutil/cache/cacherequests.cpp +++ /dev/null @@ -1,1689 +0,0 @@ -// Copyright Epic Games, Inc. All Rights Reserved. - -#include <zenutil/cache/cacherequests.h> - -#include <zencore/compactbinary.h> -#include <zencore/compactbinarybuilder.h> -#include <zencore/compactbinarypackage.h> -#include <zencore/fmtutils.h> -#include <zencore/logging.h> -#include <zencore/zencore.h> - -#include <string> -#include <string_view> -#include <unordered_map> - -#if ZEN_WITH_TESTS -# include <zencore/testing.h> -#endif - -namespace zen { - -namespace cacherequests { - - namespace { - constinit AsciiSet ValidNamespaceNameCharactersSet{"abcdefghijklmnopqrstuvwxyz0123456789-_.ABCDEFGHIJKLMNOPQRSTUVWXYZ"}; - constinit AsciiSet ValidBucketNameCharactersSet{"abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"}; - } // namespace - - std::optional<std::string> GetValidNamespaceName(std::string_view Name) - { - if (Name.empty()) - { - ZEN_WARN("Namespace is invalid, empty namespace is not allowed"); - return {}; - } - - if (Name.length() > 64) - { - ZEN_WARN("Namespace '{}' is invalid, length exceeds 64 characters", Name); - return {}; - } - - if (!AsciiSet::HasOnly(Name, ValidNamespaceNameCharactersSet)) - { - ZEN_WARN("Namespace '{}' is invalid, invalid characters detected", Name); - return {}; - } - - return ToLower(Name); - } - - std::optional<std::string> GetValidBucketName(std::string_view Name) - { - if (Name.empty()) - { - ZEN_WARN("Bucket name is invalid, empty bucket name is not allowed"); - return {}; - } - - if (!AsciiSet::HasOnly(Name, ValidBucketNameCharactersSet)) - { - ZEN_WARN("Bucket name '{}' is invalid, invalid characters detected", Name); - return {}; - } - - return ToLower(Name); - } - - std::optional<IoHash> GetValidIoHash(std::string_view Hash) - { - if (Hash.length() != IoHash::StringLength) - { - return {}; - } - - IoHash KeyHash; - if (!ParseHexBytes(Hash.data(), Hash.size(), KeyHash.Hash)) - { - return {}; - } - return KeyHash; - } - - std::optional<CacheRecordPolicy> Convert(const OptionalCacheRecordPolicy& Policy) - { - return Policy.IsValid() ? Policy.Get() : std::optional<CacheRecordPolicy>{}; - }; - - std::optional<std::string> GetRequestNamespace(const CbObjectView& Params) - { - CbFieldView NamespaceField = Params["Namespace"]; - if (!NamespaceField) - { - return std::string("!default!"); // ZenCacheStore::DefaultNamespace); - } - - if (NamespaceField.HasError()) - { - return {}; - } - if (!NamespaceField.IsString()) - { - return {}; - } - return GetValidNamespaceName(NamespaceField.AsString()); - } - - bool GetRequestCacheKey(const CbObjectView& KeyView, CacheKey& Key) - { - CbFieldView BucketField = KeyView["Bucket"]; - if (BucketField.HasError()) - { - return false; - } - if (!BucketField.IsString()) - { - return false; - } - std::optional<std::string> Bucket = GetValidBucketName(BucketField.AsString()); - if (!Bucket.has_value()) - { - return false; - } - CbFieldView HashField = KeyView["Hash"]; - if (HashField.HasError()) - { - return false; - } - if (!HashField.IsHash()) - { - return false; - } - Key.Bucket = *Bucket; - Key.Hash = HashField.AsHash(); - return true; - } - - void WriteCacheRequestKey(CbObjectWriter& Writer, const CacheKey& Value) - { - Writer.BeginObject("Key"); - { - Writer << "Bucket" << Value.Bucket; - Writer << "Hash" << Value.Hash; - } - Writer.EndObject(); - } - - void WriteOptionalCacheRequestPolicy(CbObjectWriter& Writer, std::string_view FieldName, const std::optional<CacheRecordPolicy>& Policy) - { - if (Policy) - { - Writer.SetName(FieldName); - Policy->Save(Writer); - } - } - - std::optional<CachePolicy> GetCachePolicy(CbObjectView ObjectView, std::string_view FieldName) - { - std::string_view DefaultPolicyText = ObjectView[FieldName].AsString(); - if (DefaultPolicyText.empty()) - { - return {}; - } - return ParseCachePolicy(DefaultPolicyText); - } - - void WriteCachePolicy(CbObjectWriter& Writer, std::string_view FieldName, const std::optional<CachePolicy>& Policy) - { - if (Policy) - { - Writer << FieldName << WriteToString<128>(*Policy); - } - } - - bool PutCacheRecordsRequest::Parse(const CbPackage& Package) - { - CbObjectView BatchObject = Package.GetObject(); - ZEN_ASSERT(BatchObject["Method"].AsString() == "PutCacheRecords"); - AcceptMagic = BatchObject["AcceptType"].AsUInt32(0); - - CbObjectView Params = BatchObject["Params"].AsObjectView(); - std::optional<std::string> RequestNamespace = GetRequestNamespace(Params); - if (!RequestNamespace) - { - return false; - } - Namespace = *RequestNamespace; - DefaultPolicy = GetCachePolicy(Params, "DefaultPolicy").value_or(CachePolicy::Default); - - CbArrayView RequestFieldArray = Params["Requests"].AsArrayView(); - Requests.resize(RequestFieldArray.Num()); - for (size_t RequestIndex = 0; CbFieldView RequestField : RequestFieldArray) - { - CbObjectView RequestObject = RequestField.AsObjectView(); - CbObjectView RecordObject = RequestObject["Record"].AsObjectView(); - CbObjectView KeyView = RecordObject["Key"].AsObjectView(); - - PutCacheRecordRequest& Request = Requests[RequestIndex++]; - - if (!GetRequestCacheKey(KeyView, Request.Key)) - { - return false; - } - - Request.Policy = Convert(CacheRecordPolicy::Load(RequestObject["Policy"].AsObjectView())); - - std::unordered_map<IoHash, size_t, IoHash::Hasher> RawHashToAttachmentIndex; - - CbArrayView ValuesArray = RecordObject["Values"].AsArrayView(); - Request.Values.resize(ValuesArray.Num()); - RawHashToAttachmentIndex.reserve(ValuesArray.Num()); - for (size_t Index = 0; CbFieldView Value : ValuesArray) - { - CbObjectView ObjectView = Value.AsObjectView(); - IoHash AttachmentHash = ObjectView["RawHash"].AsHash(); - RawHashToAttachmentIndex[AttachmentHash] = Index; - Request.Values[Index++] = {.Id = ObjectView["Id"].AsObjectId(), .RawHash = AttachmentHash}; - } - - RecordObject.IterateAttachments([&](CbFieldView HashView) { - const IoHash ValueHash = HashView.AsHash(); - if (const CbAttachment* Attachment = Package.FindAttachment(ValueHash)) - { - if (Attachment->IsCompressedBinary()) - { - auto It = RawHashToAttachmentIndex.find(ValueHash); - ZEN_ASSERT(It != RawHashToAttachmentIndex.end()); - PutCacheRecordRequestValue& Value = Request.Values[It->second]; - ZEN_ASSERT(Value.RawHash == ValueHash); - Value.Body = Attachment->AsCompressedBinary(); - ZEN_ASSERT_SLOW(Value.Body.DecodeRawHash() == Value.RawHash); - } - } - }); - } - - return true; - } - - bool PutCacheRecordsRequest::Format(CbPackage& OutPackage) const - { - CbObjectWriter Writer; - Writer << "Method" - << "PutCacheRecords"; - if (AcceptMagic != 0) - { - Writer << "Accept" << AcceptMagic; - } - - Writer.BeginObject("Params"); - { - Writer << "DefaultPolicy" << WriteToString<128>(DefaultPolicy); - Writer << "Namespace" << Namespace; - - Writer.BeginArray("Requests"); - for (const PutCacheRecordRequest& RecordRequest : Requests) - { - Writer.BeginObject(); - { - Writer.BeginObject("Record"); - { - WriteCacheRequestKey(Writer, RecordRequest.Key); - Writer.BeginArray("Values"); - for (const PutCacheRecordRequestValue& Value : RecordRequest.Values) - { - Writer.BeginObject(); - { - Writer.AddObjectId("Id", Value.Id); - const CompressedBuffer& Buffer = Value.Body; - if (Buffer) - { - IoHash AttachmentHash = Buffer.DecodeRawHash(); // TODO: Slow! - Writer.AddBinaryAttachment("RawHash", AttachmentHash); - OutPackage.AddAttachment(CbAttachment(Buffer, AttachmentHash)); - Writer.AddInteger("RawSize", Buffer.DecodeRawSize()); // TODO: Slow! - } - else - { - if (Value.RawHash == IoHash::Zero) - { - return false; - } - Writer.AddBinaryAttachment("RawHash", Value.RawHash); - } - } - Writer.EndObject(); - } - Writer.EndArray(); - } - Writer.EndObject(); - WriteOptionalCacheRequestPolicy(Writer, "Policy", RecordRequest.Policy); - } - Writer.EndObject(); - } - Writer.EndArray(); - } - Writer.EndObject(); - OutPackage.SetObject(Writer.Save()); - - return true; - } - - bool PutCacheRecordsResult::Parse(const CbPackage& Package) - { - CbArrayView ResultsArray = Package.GetObject()["Result"].AsArrayView(); - if (!ResultsArray) - { - return false; - } - CbFieldViewIterator It = ResultsArray.CreateViewIterator(); - while (It.HasValue()) - { - Success.push_back(It.AsBool()); - It++; - } - - CbArrayView DetailsArray = Package.GetObject()["Details"].AsArrayView(); - if (DetailsArray) - { - It = DetailsArray.CreateViewIterator(); - while (It.HasValue()) - { - Details.push_back(It.AsObjectView()); - It++; - } - } - return true; - } - - bool PutCacheRecordsResult::Format(CbPackage& OutPackage) const - { - CbObjectWriter ResponseObject; - ResponseObject.BeginArray("Result"); - for (bool Value : Success) - { - ResponseObject.AddBool(Value); - } - ResponseObject.EndArray(); - if (!Details.empty()) - { - ResponseObject.BeginArray("Details"); - for (CbObjectView Value : Details) - { - ResponseObject.AddObject(Value); - } - ResponseObject.EndArray(); - } - OutPackage.SetObject(ResponseObject.Save()); - return true; - } - - bool GetCacheRecordsRequest::Parse(const CbObjectView& RpcRequest) - { - ZEN_ASSERT(RpcRequest["Method"].AsString() == "GetCacheRecords"); - AcceptMagic = RpcRequest["AcceptType"].AsUInt32(0); - AcceptOptions = RpcRequest["AcceptFlags"].AsUInt16(0); - ProcessPid = RpcRequest["Pid"].AsInt32(0); - - CbObjectView Params = RpcRequest["Params"].AsObjectView(); - std::optional<std::string> RequestNamespace = GetRequestNamespace(Params); - if (!RequestNamespace) - { - return false; - } - - Namespace = *RequestNamespace; - DefaultPolicy = GetCachePolicy(Params, "DefaultPolicy").value_or(CachePolicy::Default); - - CbArrayView RequestsArray = Params["Requests"].AsArrayView(); - Requests.reserve(RequestsArray.Num()); - for (CbFieldView RequestField : RequestsArray) - { - CbObjectView RequestObject = RequestField.AsObjectView(); - CbObjectView KeyObject = RequestObject["Key"].AsObjectView(); - - GetCacheRecordRequest& Request = Requests.emplace_back(); - - if (!GetRequestCacheKey(KeyObject, Request.Key)) - { - return false; - } - - Request.Policy = Convert(CacheRecordPolicy::Load(RequestObject["Policy"].AsObjectView())); - } - return true; - } - - bool GetCacheRecordsRequest::Parse(const CbPackage& RpcRequest) { return Parse(RpcRequest.GetObject()); } - - bool GetCacheRecordsRequest::Format(CbObjectWriter& Writer, const std::span<const size_t> OptionalRecordFilter) const - { - Writer << "Method" - << "GetCacheRecords"; - if (AcceptMagic != 0) - { - Writer << "Accept" << AcceptMagic; - } - if (AcceptOptions != 0) - { - Writer << "AcceptFlags" << AcceptOptions; - } - if (ProcessPid != 0) - { - Writer << "Pid" << ProcessPid; - } - - Writer.BeginObject("Params"); - { - Writer << "DefaultPolicy" << WriteToString<128>(DefaultPolicy); - Writer << "Namespace" << Namespace; - Writer.BeginArray("Requests"); - if (OptionalRecordFilter.empty()) - { - for (const GetCacheRecordRequest& RecordRequest : Requests) - { - Writer.BeginObject(); - { - WriteCacheRequestKey(Writer, RecordRequest.Key); - WriteOptionalCacheRequestPolicy(Writer, "Policy", RecordRequest.Policy); - } - Writer.EndObject(); - } - } - else - { - for (size_t Index : OptionalRecordFilter) - { - const GetCacheRecordRequest& RecordRequest = Requests[Index]; - Writer.BeginObject(); - { - WriteCacheRequestKey(Writer, RecordRequest.Key); - WriteOptionalCacheRequestPolicy(Writer, "Policy", RecordRequest.Policy); - } - Writer.EndObject(); - } - } - Writer.EndArray(); - } - Writer.EndObject(); - - return true; - } - - bool GetCacheRecordsRequest::Format(CbPackage& OutPackage, const std::span<const size_t> OptionalRecordFilter) const - { - CbObjectWriter Writer; - if (!Format(Writer, OptionalRecordFilter)) - { - return false; - } - OutPackage.SetObject(Writer.Save()); - return true; - } - - bool GetCacheRecordsResult::Parse(const CbPackage& Package, const std::span<const size_t> OptionalRecordResultIndexes) - { - CbObject ResponseObject = Package.GetObject(); - CbArrayView ResultsArray = ResponseObject["Result"].AsArrayView(); - if (!ResultsArray) - { - return false; - } - - Results.reserve(ResultsArray.Num()); - if (!OptionalRecordResultIndexes.empty() && ResultsArray.Num() != OptionalRecordResultIndexes.size()) - { - return false; - } - for (size_t Index = 0; CbFieldView RecordView : ResultsArray) - { - size_t ResultIndex = OptionalRecordResultIndexes.empty() ? Index : OptionalRecordResultIndexes[Index]; - Index++; - - if (Results.size() <= ResultIndex) - { - Results.resize(ResultIndex + 1); - } - if (RecordView.IsNull()) - { - continue; - } - Results[ResultIndex] = GetCacheRecordResult{}; - GetCacheRecordResult& Request = Results[ResultIndex].value(); - CbObjectView RecordObject = RecordView.AsObjectView(); - CbObjectView KeyObject = RecordObject["Key"].AsObjectView(); - if (!GetRequestCacheKey(KeyObject, Request.Key)) - { - return false; - } - - CbArrayView ValuesArray = RecordObject["Values"].AsArrayView(); - Request.Values.reserve(ValuesArray.Num()); - for (CbFieldView Value : ValuesArray) - { - CbObjectView ValueObject = Value.AsObjectView(); - IoHash RawHash = ValueObject["RawHash"].AsHash(); - uint64_t RawSize = ValueObject["RawSize"].AsUInt64(); - Oid Id = ValueObject["Id"].AsObjectId(); - const CbAttachment* Attachment = Package.FindAttachment(RawHash); - if (!Attachment) - { - Request.Values.push_back({.Id = Id, .RawHash = RawHash, .RawSize = RawSize, .Body = {}}); - continue; - } - if (!Attachment->IsCompressedBinary()) - { - return false; - } - Request.Values.push_back({.Id = Id, .RawHash = RawHash, .RawSize = RawSize, .Body = Attachment->AsCompressedBinary()}); - } - } - return true; - } - - bool GetCacheRecordsResult::Format(CbPackage& OutPackage) const - { - CbObjectWriter Writer; - - Writer.BeginArray("Result"); - for (const std::optional<GetCacheRecordResult>& RecordResult : Results) - { - if (!RecordResult.has_value()) - { - Writer.AddNull(); - continue; - } - Writer.BeginObject(); - WriteCacheRequestKey(Writer, RecordResult->Key); - - Writer.BeginArray("Values"); - for (const GetCacheRecordResultValue& Value : RecordResult->Values) - { - IoHash AttachmentHash = Value.Body ? Value.Body.DecodeRawHash() : Value.RawHash; - Writer.BeginObject(); - { - Writer.AddObjectId("Id", Value.Id); - Writer.AddHash("RawHash", AttachmentHash); - Writer.AddInteger("RawSize", Value.Body ? Value.Body.DecodeRawSize() : Value.RawSize); - } - Writer.EndObject(); - if (Value.Body) - { - OutPackage.AddAttachment(CbAttachment(Value.Body, AttachmentHash)); - } - } - - Writer.EndArray(); - Writer.EndObject(); - } - Writer.EndArray(); - - OutPackage.SetObject(Writer.Save()); - return true; - } - - bool PutCacheValuesRequest::Parse(const CbPackage& Package) - { - CbObjectView BatchObject = Package.GetObject(); - ZEN_ASSERT(BatchObject["Method"].AsString() == "PutCacheValues"); - AcceptMagic = BatchObject["AcceptType"].AsUInt32(0); - - CbObjectView Params = BatchObject["Params"].AsObjectView(); - std::optional<std::string> RequestNamespace = cacherequests::GetRequestNamespace(Params); - if (!RequestNamespace) - { - return false; - } - - Namespace = *RequestNamespace; - DefaultPolicy = GetCachePolicy(Params, "DefaultPolicy").value_or(CachePolicy::Default); - - CbArrayView RequestsArray = Params["Requests"].AsArrayView(); - Requests.reserve(RequestsArray.Num()); - for (CbFieldView RequestField : RequestsArray) - { - CbObjectView RequestObject = RequestField.AsObjectView(); - CbObjectView KeyObject = RequestObject["Key"].AsObjectView(); - - PutCacheValueRequest& Request = Requests.emplace_back(); - - if (!GetRequestCacheKey(KeyObject, Request.Key)) - { - return false; - } - - Request.RawHash = RequestObject["RawHash"].AsBinaryAttachment(); - Request.Policy = GetCachePolicy(RequestObject, "Policy"); - - if (const CbAttachment* Attachment = Package.FindAttachment(Request.RawHash)) - { - if (!Attachment->IsCompressedBinary()) - { - return false; - } - Request.Body = Attachment->AsCompressedBinary(); - } - } - return true; - } - - bool PutCacheValuesRequest::Format(CbPackage& OutPackage) const - { - CbObjectWriter Writer; - Writer << "Method" - << "PutCacheValues"; - if (AcceptMagic != 0) - { - Writer << "Accept" << AcceptMagic; - } - - Writer.BeginObject("Params"); - { - Writer << "DefaultPolicy" << WriteToString<128>(DefaultPolicy); - Writer << "Namespace" << Namespace; - - Writer.BeginArray("Requests"); - for (const PutCacheValueRequest& ValueRequest : Requests) - { - Writer.BeginObject(); - { - WriteCacheRequestKey(Writer, ValueRequest.Key); - if (ValueRequest.Body) - { - IoHash AttachmentHash = ValueRequest.Body.DecodeRawHash(); - if (ValueRequest.RawHash != IoHash::Zero && AttachmentHash != ValueRequest.RawHash) - { - return false; - } - Writer.AddBinaryAttachment("RawHash", AttachmentHash); - OutPackage.AddAttachment(CbAttachment(ValueRequest.Body, AttachmentHash)); - } - else if (ValueRequest.RawHash != IoHash::Zero) - { - Writer.AddBinaryAttachment("RawHash", ValueRequest.RawHash); - } - else - { - return false; - } - WriteCachePolicy(Writer, "Policy", ValueRequest.Policy); - } - Writer.EndObject(); - } - Writer.EndArray(); - } - Writer.EndObject(); - - OutPackage.SetObject(Writer.Save()); - return true; - } - - bool PutCacheValuesResult::Parse(const CbPackage& Package) - { - CbArrayView ResultsArray = Package.GetObject()["Result"].AsArrayView(); - if (!ResultsArray) - { - return false; - } - CbFieldViewIterator It = ResultsArray.CreateViewIterator(); - while (It.HasValue()) - { - Success.push_back(It.AsBool()); - It++; - } - return true; - } - - bool PutCacheValuesResult::Format(CbPackage& OutPackage) const - { - if (Success.empty()) - { - return false; - } - CbObjectWriter ResponseObject; - ResponseObject.BeginArray("Result"); - for (bool Value : Success) - { - ResponseObject.AddBool(Value); - } - ResponseObject.EndArray(); - - OutPackage.SetObject(ResponseObject.Save()); - return true; - } - - bool GetCacheValuesRequest::Parse(const CbObjectView& BatchObject) - { - ZEN_ASSERT(BatchObject["Method"].AsString() == "GetCacheValues"); - AcceptMagic = BatchObject["AcceptType"].AsUInt32(0); - AcceptOptions = BatchObject["AcceptFlags"].AsUInt16(0); - ProcessPid = BatchObject["Pid"].AsInt32(0); - - CbObjectView Params = BatchObject["Params"].AsObjectView(); - std::optional<std::string> RequestNamespace = cacherequests::GetRequestNamespace(Params); - if (!RequestNamespace) - { - return false; - } - - Namespace = *RequestNamespace; - DefaultPolicy = GetCachePolicy(Params, "DefaultPolicy").value_or(CachePolicy::Default); - - CbArrayView RequestsArray = Params["Requests"].AsArrayView(); - Requests.reserve(RequestsArray.Num()); - for (CbFieldView RequestField : RequestsArray) - { - CbObjectView RequestObject = RequestField.AsObjectView(); - CbObjectView KeyObject = RequestObject["Key"].AsObjectView(); - - GetCacheValueRequest& Request = Requests.emplace_back(); - - if (!GetRequestCacheKey(KeyObject, Request.Key)) - { - return false; - } - - Request.Policy = GetCachePolicy(RequestObject, "Policy"); - } - return true; - } - - bool GetCacheValuesRequest::Format(CbPackage& OutPackage, const std::span<const size_t> OptionalValueFilter) const - { - CbObjectWriter Writer; - Writer << "Method" - << "GetCacheValues"; - if (AcceptMagic != 0) - { - Writer << "Accept" << AcceptMagic; - } - if (AcceptOptions != 0) - { - Writer << "AcceptFlags" << AcceptOptions; - } - if (ProcessPid != 0) - { - Writer << "Pid" << ProcessPid; - } - - Writer.BeginObject("Params"); - { - Writer << "DefaultPolicy" << WriteToString<128>(DefaultPolicy); - Writer << "Namespace" << Namespace; - - Writer.BeginArray("Requests"); - if (OptionalValueFilter.empty()) - { - for (const GetCacheValueRequest& ValueRequest : Requests) - { - Writer.BeginObject(); - { - WriteCacheRequestKey(Writer, ValueRequest.Key); - WriteCachePolicy(Writer, "Policy", ValueRequest.Policy); - } - Writer.EndObject(); - } - } - else - { - for (size_t Index : OptionalValueFilter) - { - const GetCacheValueRequest& ValueRequest = Requests[Index]; - Writer.BeginObject(); - { - WriteCacheRequestKey(Writer, ValueRequest.Key); - WriteCachePolicy(Writer, "Policy", ValueRequest.Policy); - } - Writer.EndObject(); - } - } - Writer.EndArray(); - } - Writer.EndObject(); - - OutPackage.SetObject(Writer.Save()); - return true; - } - - bool CacheValuesResult::Parse(const CbPackage& Package, const std::span<const size_t> OptionalValueResultIndexes) - { - CbObject ResponseObject = Package.GetObject(); - CbArrayView ResultsArray = ResponseObject["Result"].AsArrayView(); - if (!ResultsArray) - { - return false; - } - Results.reserve(ResultsArray.Num()); - if (!OptionalValueResultIndexes.empty() && ResultsArray.Num() != OptionalValueResultIndexes.size()) - { - return false; - } - for (size_t Index = 0; CbFieldView RecordView : ResultsArray) - { - size_t ResultIndex = OptionalValueResultIndexes.empty() ? Index : OptionalValueResultIndexes[Index]; - Index++; - - if (Results.size() <= ResultIndex) - { - Results.resize(ResultIndex + 1); - } - if (RecordView.IsNull()) - { - continue; - } - - CacheValueResult& ValueResult = Results[ResultIndex]; - CbObjectView RecordObject = RecordView.AsObjectView(); - - CbFieldView RawHashField = RecordObject["RawHash"]; - ValueResult.RawHash = RawHashField.AsHash(); - bool Succeeded = !RawHashField.HasError(); - if (Succeeded) - { - ValueResult.FragmentOffset = RecordObject["FragmentOffset"].AsUInt64(0); - ValueResult.FragmentHash = RecordObject["FragmentHash"].AsHash(); - const CbAttachment* Attachment = - Package.FindAttachment(ValueResult.FragmentHash == IoHash::Zero ? ValueResult.RawHash : ValueResult.FragmentHash); - ValueResult.Body = Attachment ? Attachment->AsCompressedBinary().MakeOwned() : CompressedBuffer(); - if (ValueResult.Body) - { - ValueResult.RawSize = ValueResult.Body.DecodeRawSize(); - } - else - { - ValueResult.RawSize = RecordObject["RawSize"].AsUInt64(UINT64_MAX); - } - } - } - return true; - } - - bool CacheValuesResult::Format(CbPackage& OutPackage) const - { - CbObjectWriter ResponseObject; - - ResponseObject.BeginArray("Result"); - for (const CacheValueResult& ValueResult : Results) - { - ResponseObject.BeginObject(); - if (ValueResult.RawHash != IoHash::Zero) - { - ResponseObject.AddHash("RawHash", ValueResult.RawHash); - if (ValueResult.Body) - { - OutPackage.AddAttachment(CbAttachment(ValueResult.Body, ValueResult.RawHash)); - } - else - { - ResponseObject.AddInteger("RawSize", ValueResult.RawSize); - } - } - ResponseObject.EndObject(); - } - ResponseObject.EndArray(); - - OutPackage.SetObject(ResponseObject.Save()); - return true; - } - - bool GetCacheChunksRequest::Parse(const CbObjectView& BatchObject) - { - ZEN_ASSERT(BatchObject["Method"].AsString() == "GetCacheChunks"); - AcceptMagic = BatchObject["AcceptType"].AsUInt32(0); - AcceptOptions = BatchObject["AcceptFlags"].AsUInt16(0); - ProcessPid = BatchObject["Pid"].AsInt32(0); - - CbObjectView Params = BatchObject["Params"].AsObjectView(); - std::optional<std::string> RequestNamespace = cacherequests::GetRequestNamespace(Params); - if (!RequestNamespace) - { - return false; - } - - Namespace = *RequestNamespace; - DefaultPolicy = GetCachePolicy(Params, "DefaultPolicy").value_or(CachePolicy::Default); - - CbArrayView RequestsArray = Params["ChunkRequests"].AsArrayView(); - Requests.reserve(RequestsArray.Num()); - for (CbFieldView RequestField : RequestsArray) - { - CbObjectView RequestObject = RequestField.AsObjectView(); - CbObjectView KeyObject = RequestObject["Key"].AsObjectView(); - - GetCacheChunkRequest& Request = Requests.emplace_back(); - - if (!GetRequestCacheKey(KeyObject, Request.Key)) - { - return false; - } - - Request.ValueId = RequestObject["ValueId"].AsObjectId(); - Request.ChunkId = RequestObject["ChunkId"].AsHash(); - Request.RawOffset = RequestObject["RawOffset"].AsUInt64(); - Request.RawSize = RequestObject["RawSize"].AsUInt64(UINT64_MAX); - - Request.Policy = GetCachePolicy(RequestObject, "Policy"); - } - return true; - } - - bool GetCacheChunksRequest::Format(CbPackage& OutPackage) const - { - CbObjectWriter Writer; - Writer << "Method" - << "GetCacheChunks"; - if (AcceptMagic != 0) - { - Writer << "Accept" << AcceptMagic; - } - if (AcceptOptions != 0) - { - Writer << "AcceptFlags" << AcceptOptions; - } - if (ProcessPid != 0) - { - Writer << "Pid" << ProcessPid; - } - - Writer.BeginObject("Params"); - { - Writer << "DefaultPolicy" << WriteToString<128>(DefaultPolicy); - Writer << "Namespace" << Namespace; - - Writer.BeginArray("ChunkRequests"); - for (const GetCacheChunkRequest& ValueRequest : Requests) - { - Writer.BeginObject(); - { - WriteCacheRequestKey(Writer, ValueRequest.Key); - - Writer.AddObjectId("ValueId", ValueRequest.ValueId); - Writer.AddHash("ChunkId", ValueRequest.ChunkId); - Writer.AddInteger("RawOffset", ValueRequest.RawOffset); - Writer.AddInteger("RawSize", ValueRequest.RawSize); - - WriteCachePolicy(Writer, "Policy", ValueRequest.Policy); - } - Writer.EndObject(); - } - Writer.EndArray(); - } - Writer.EndObject(); - - OutPackage.SetObject(Writer.Save()); - return true; - } - - bool HttpRequestParseRelativeUri(std::string_view Key, std::string_view DefaultNamespace, HttpRequestData& Data) - { - std::vector<std::string_view> Tokens; - uint32_t TokenCount = ForEachStrTok(Key, '/', [&](const std::string_view& Token) { - Tokens.push_back(Token); - return true; - }); - - switch (TokenCount) - { - case 0: - return true; - case 1: - Data.Namespace = GetValidNamespaceName(Tokens[0]); - return Data.Namespace.has_value(); - case 2: - { - std::optional<IoHash> PossibleHashKey = GetValidIoHash(Tokens[1]); - if (PossibleHashKey.has_value()) - { - // Legacy bucket/key request - Data.Bucket = GetValidBucketName(Tokens[0]); - if (!Data.Bucket.has_value()) - { - return false; - } - Data.HashKey = PossibleHashKey; - Data.Namespace = DefaultNamespace; - return true; - } - Data.Namespace = GetValidNamespaceName(Tokens[0]); - if (!Data.Namespace.has_value()) - { - return false; - } - Data.Bucket = GetValidBucketName(Tokens[1]); - if (!Data.Bucket.has_value()) - { - return false; - } - return true; - } - case 3: - { - std::optional<IoHash> PossibleHashKey = GetValidIoHash(Tokens[1]); - if (PossibleHashKey.has_value()) - { - // Legacy bucket/key/valueid request - Data.Bucket = GetValidBucketName(Tokens[0]); - if (!Data.Bucket.has_value()) - { - return false; - } - Data.HashKey = PossibleHashKey; - Data.ValueContentId = GetValidIoHash(Tokens[2]); - if (!Data.ValueContentId.has_value()) - { - return false; - } - Data.Namespace = DefaultNamespace; - return true; - } - Data.Namespace = GetValidNamespaceName(Tokens[0]); - if (!Data.Namespace.has_value()) - { - return false; - } - Data.Bucket = GetValidBucketName(Tokens[1]); - if (!Data.Bucket.has_value()) - { - return false; - } - Data.HashKey = GetValidIoHash(Tokens[2]); - if (!Data.HashKey) - { - return false; - } - return true; - } - case 4: - { - Data.Namespace = GetValidNamespaceName(Tokens[0]); - if (!Data.Namespace.has_value()) - { - return false; - } - - Data.Bucket = GetValidBucketName(Tokens[1]); - if (!Data.Bucket.has_value()) - { - return false; - } - - Data.HashKey = GetValidIoHash(Tokens[2]); - if (!Data.HashKey.has_value()) - { - return false; - } - - Data.ValueContentId = GetValidIoHash(Tokens[3]); - if (!Data.ValueContentId.has_value()) - { - return false; - } - return true; - } - default: - return false; - } - } - - // bool CacheRecord::Parse(CbObjectView& Reader) - // { - // CbObjectView KeyView = Reader["Key"].AsObjectView(); - // - // if (!GetRequestCacheKey(KeyView, Key)) - // { - // return false; - // } - // CbArrayView ValuesArray = Reader["Values"].AsArrayView(); - // Values.reserve(ValuesArray.Num()); - // for (CbFieldView Value : ValuesArray) - // { - // CbObjectView ObjectView = Value.AsObjectView(); - // Values.push_back({.Id = ObjectView["Id"].AsObjectId(), - // .RawHash = ObjectView["RawHash"].AsHash(), - // .RawSize = ObjectView["RawSize"].AsUInt64()}); - // } - // return true; - // } - // - // bool CacheRecord::Format(CbObjectWriter& Writer) const - // { - // WriteCacheRequestKey(Writer, Key); - // Writer.BeginArray("Values"); - // for (const CacheRecordValue& Value : Values) - // { - // Writer.BeginObject(); - // { - // Writer.AddObjectId("Id", Value.Id); - // Writer.AddHash("RawHash", Value.RawHash); - // Writer.AddInteger("RawSize", Value.RawSize); - // } - // Writer.EndObject(); - // } - // Writer.EndArray(); - // return true; - // } - -#if ZEN_WITH_TESTS - - static bool operator==(const PutCacheRecordRequestValue& Lhs, const PutCacheRecordRequestValue& Rhs) - { - const IoHash LhsRawHash = Lhs.RawHash != IoHash::Zero ? Lhs.RawHash : Lhs.Body.DecodeRawHash(); - const IoHash RhsRawHash = Rhs.RawHash != IoHash::Zero ? Rhs.RawHash : Rhs.Body.DecodeRawHash(); - return Lhs.Id == Rhs.Id && LhsRawHash == RhsRawHash && - Lhs.Body.GetCompressed().Flatten().GetView().EqualBytes(Rhs.Body.GetCompressed().Flatten().GetView()); - } - - static bool operator==(const zen::CacheValuePolicy& Lhs, const zen::CacheValuePolicy& Rhs) - { - return (Lhs.Id == Rhs.Id) && (Lhs.Policy == Rhs.Policy); - } - - static bool operator==(const std::span<const zen::CacheValuePolicy>& Lhs, const std::span<const zen::CacheValuePolicy>& Rhs) - { - if (Lhs.size() != Lhs.size()) - { - return false; - } - for (size_t Idx = 0; Idx < Lhs.size(); ++Idx) - { - if (Lhs[Idx] != Rhs[Idx]) - { - return false; - } - } - return true; - } - - static bool operator==(const zen::CacheRecordPolicy& Lhs, const zen::CacheRecordPolicy& Rhs) - { - return (Lhs.GetRecordPolicy() == Rhs.GetRecordPolicy()) && (Lhs.GetBasePolicy() == Rhs.GetBasePolicy()) && - (Lhs.GetValuePolicies() == Rhs.GetValuePolicies()); - } - - static bool operator==(const std::optional<CacheRecordPolicy>& Lhs, const std::optional<CacheRecordPolicy>& Rhs) - { - return (Lhs.has_value() == Rhs.has_value()) && (!Lhs || (*Lhs == *Rhs)); - } - - static bool operator==(const PutCacheRecordRequest& Lhs, const PutCacheRecordRequest& Rhs) - { - return (Lhs.Key == Rhs.Key) && (Lhs.Values == Rhs.Values) && (Lhs.Policy == Rhs.Policy); - } - - static bool operator==(const PutCacheRecordsRequest& Lhs, const PutCacheRecordsRequest& Rhs) - { - return (Lhs.DefaultPolicy == Rhs.DefaultPolicy) && (Lhs.Namespace == Rhs.Namespace) && (Lhs.Requests == Rhs.Requests); - } - - static bool operator==(const PutCacheRecordsResult& Lhs, const PutCacheRecordsResult& Rhs) { return (Lhs.Success == Rhs.Success); } - - static bool operator==(const GetCacheRecordRequest& Lhs, const GetCacheRecordRequest& Rhs) - { - return (Lhs.Key == Rhs.Key) && (Lhs.Policy == Rhs.Policy); - } - - static bool operator==(const GetCacheRecordsRequest& Lhs, const GetCacheRecordsRequest& Rhs) - { - return (Lhs.DefaultPolicy == Rhs.DefaultPolicy) && (Lhs.Namespace == Rhs.Namespace) && (Lhs.Requests == Rhs.Requests); - } - - static bool operator==(const GetCacheRecordResultValue& Lhs, const GetCacheRecordResultValue& Rhs) - { - if ((Lhs.Id != Rhs.Id) || (Lhs.RawHash != Rhs.RawHash) || (Lhs.RawSize != Rhs.RawSize)) - { - return false; - } - if (bool(Lhs.Body) != bool(Rhs.Body)) - { - return false; - } - if (bool(Lhs.Body) && Lhs.Body.DecodeRawHash() != Rhs.Body.DecodeRawHash()) - { - return false; - } - return true; - } - - static bool operator==(const GetCacheRecordResult& Lhs, const GetCacheRecordResult& Rhs) - { - return Lhs.Key == Rhs.Key && Lhs.Values == Rhs.Values; - } - - static bool operator==(const std::optional<GetCacheRecordResult>& Lhs, const std::optional<GetCacheRecordResult>& Rhs) - { - if (Lhs.has_value() != Rhs.has_value()) - { - return false; - } - return *Lhs == Rhs; - } - - static bool operator==(const GetCacheRecordsResult& Lhs, const GetCacheRecordsResult& Rhs) { return Lhs.Results == Rhs.Results; } - - static bool operator==(const PutCacheValueRequest& Lhs, const PutCacheValueRequest& Rhs) - { - if ((Lhs.Key != Rhs.Key) || (Lhs.RawHash != Rhs.RawHash)) - { - return false; - } - - if (bool(Lhs.Body) != bool(Rhs.Body)) - { - return false; - } - if (!Lhs.Body) - { - return true; - } - return Lhs.Body.GetCompressed().Flatten().GetView().EqualBytes(Rhs.Body.GetCompressed().Flatten().GetView()); - } - - static bool operator==(const PutCacheValuesRequest& Lhs, const PutCacheValuesRequest& Rhs) - { - return (Lhs.DefaultPolicy == Rhs.DefaultPolicy) && (Lhs.Namespace == Rhs.Namespace) && (Lhs.Requests == Rhs.Requests); - } - - static bool operator==(const PutCacheValuesResult& Lhs, const PutCacheValuesResult& Rhs) { return (Lhs.Success == Rhs.Success); } - - static bool operator==(const GetCacheValueRequest& Lhs, const GetCacheValueRequest& Rhs) - { - return Lhs.Key == Rhs.Key && Lhs.Policy == Rhs.Policy; - } - - static bool operator==(const GetCacheValuesRequest& Lhs, const GetCacheValuesRequest& Rhs) - { - return Lhs.DefaultPolicy == Rhs.DefaultPolicy && Lhs.Namespace == Rhs.Namespace && Lhs.Requests == Rhs.Requests; - } - - static bool operator==(const CacheValueResult& Lhs, const CacheValueResult& Rhs) - { - if (Lhs.RawHash != Rhs.RawHash) - { - return false; - }; - if (Lhs.Body) - { - if (!Rhs.Body) - { - return false; - } - return Lhs.Body.GetCompressed().Flatten().GetView().EqualBytes(Rhs.Body.GetCompressed().Flatten().GetView()); - } - return Lhs.RawSize == Rhs.RawSize; - } - - static bool operator==(const CacheValuesResult& Lhs, const CacheValuesResult& Rhs) { return Lhs.Results == Rhs.Results; } - - static bool operator==(const GetCacheChunkRequest& Lhs, const GetCacheChunkRequest& Rhs) - { - return Lhs.Key == Rhs.Key && Lhs.ValueId == Rhs.ValueId && Lhs.ChunkId == Rhs.ChunkId && Lhs.RawOffset == Rhs.RawOffset && - Lhs.RawSize == Rhs.RawSize && Lhs.Policy == Rhs.Policy; - } - - static bool operator==(const GetCacheChunksRequest& Lhs, const GetCacheChunksRequest& Rhs) - { - return Lhs.DefaultPolicy == Rhs.DefaultPolicy && Lhs.Namespace == Rhs.Namespace && Lhs.Requests == Rhs.Requests; - } - - static CompressedBuffer MakeCompressedBuffer(size_t Size) { return CompressedBuffer::Compress(SharedBuffer(IoBuffer(Size))); }; - - TEST_CASE("cacherequests.put.cache.records") - { - PutCacheRecordsRequest EmptyRequest; - CbPackage EmptyRequestPackage; - CHECK(EmptyRequest.Format(EmptyRequestPackage)); - PutCacheRecordsRequest EmptyRequestCopy; - CHECK(!EmptyRequestCopy.Parse(EmptyRequestPackage)); // Namespace is required - - PutCacheRecordsRequest FullRequest = { - .DefaultPolicy = CachePolicy::Remote, - .Namespace = "the_namespace", - .Requests = {{.Key = {.Bucket = "thebucket", .Hash = IoHash::FromHexString("177030568fdd461bf4fe5ddbf4d463e514e8178e")}, - .Values = {{.Id = Oid::NewOid(), .Body = MakeCompressedBuffer(2134)}, - {.Id = Oid::NewOid(), .Body = MakeCompressedBuffer(213)}, - {.Id = Oid::NewOid(), .Body = MakeCompressedBuffer(7)}}, - .Policy = CachePolicy::StoreLocal}, - {.Key = {.Bucket = "thebucket", .Hash = IoHash::FromHexString("d1df59fcab06793a5f2c372d795bb907a15cab15")}, - .Values = {{.Id = Oid::NewOid(), .Body = MakeCompressedBuffer(1234)}, - {.Id = Oid::NewOid(), .Body = MakeCompressedBuffer(99)}, - {.Id = Oid::NewOid(), .Body = MakeCompressedBuffer(124)}}, - .Policy = CachePolicy::Store}, - {.Key = {.Bucket = "theotherbucket", .Hash = IoHash::FromHexString("e1ce9e1ac8a6f5953dc14c1fa9512b804ed689df")}, - .Values = {{.Id = Oid::NewOid(), .Body = MakeCompressedBuffer(19)}, - {.Id = Oid::NewOid(), .Body = MakeCompressedBuffer(1248)}, - {.Id = Oid::NewOid(), .Body = MakeCompressedBuffer(823)}}}}}; - - CbPackage FullRequestPackage; - CHECK(FullRequest.Format(FullRequestPackage)); - PutCacheRecordsRequest FullRequestCopy; - CHECK(FullRequestCopy.Parse(FullRequestPackage)); - CHECK(FullRequest == FullRequestCopy); - - PutCacheRecordsResult EmptyResult; - CbPackage EmptyResponsePackage; - CHECK(EmptyResult.Format(EmptyResponsePackage)); - PutCacheRecordsResult EmptyResultCopy; - CHECK(!EmptyResultCopy.Parse(EmptyResponsePackage)); - CHECK(EmptyResult == EmptyResultCopy); - - PutCacheRecordsResult FullResult = {.Success = {true, false, true, true, false}}; - CbPackage FullResponsePackage; - CHECK(FullResult.Format(FullResponsePackage)); - PutCacheRecordsResult FullResultCopy; - CHECK(FullResultCopy.Parse(FullResponsePackage)); - CHECK(FullResult == FullResultCopy); - } - - TEST_CASE("cacherequests.get.cache.records") - { - GetCacheRecordsRequest EmptyRequest; - CbPackage EmptyRequestPackage; - CHECK(EmptyRequest.Format(EmptyRequestPackage)); - GetCacheRecordsRequest EmptyRequestCopy; - CHECK(!EmptyRequestCopy.Parse(EmptyRequestPackage)); // Namespace is required - - GetCacheRecordsRequest FullRequest = { - .DefaultPolicy = CachePolicy::StoreLocal, - .Namespace = "other_namespace", - .Requests = {{.Key = {.Bucket = "finebucket", .Hash = IoHash::FromHexString("d1df59fcab06793a5f2c372d795bb907a15cab15")}, - .Policy = CachePolicy::Local}, - {.Key = {.Bucket = "badbucket", .Hash = IoHash::FromHexString("177030568fdd461bf4fe5ddbf4d463e514e8178e")}, - .Policy = CachePolicy::Remote}, - {.Key = {.Bucket = "badbucket", .Hash = IoHash::FromHexString("e1ce9e1ac8a6f5953dc14c1fa9512b804ed689df")}}}}; - - CbPackage FullRequestPackage; - CHECK(FullRequest.Format(FullRequestPackage)); - GetCacheRecordsRequest FullRequestCopy; - CHECK(FullRequestCopy.Parse(FullRequestPackage)); - CHECK(FullRequest == FullRequestCopy); - - CbPackage PartialRequestPackage; - CHECK(FullRequest.Format(PartialRequestPackage, std::initializer_list<size_t>{0, 2})); - GetCacheRecordsRequest PartialRequest = FullRequest; - PartialRequest.Requests.erase(PartialRequest.Requests.begin() + 1); - GetCacheRecordsRequest PartialRequestCopy; - CHECK(PartialRequestCopy.Parse(PartialRequestPackage)); - CHECK(PartialRequest == PartialRequestCopy); - - GetCacheRecordsResult EmptyResult; - CbPackage EmptyResponsePackage; - CHECK(EmptyResult.Format(EmptyResponsePackage)); - GetCacheRecordsResult EmptyResultCopy; - CHECK(!EmptyResultCopy.Parse(EmptyResponsePackage)); - CHECK(EmptyResult == EmptyResultCopy); - - PutCacheRecordsRequest FullPutRequest = { - .DefaultPolicy = CachePolicy::Remote, - .Namespace = "the_namespace", - .Requests = {{.Key = {.Bucket = "thebucket", .Hash = IoHash::FromHexString("177030568fdd461bf4fe5ddbf4d463e514e8178e")}, - .Values = {{.Id = Oid::NewOid(), .Body = MakeCompressedBuffer(2134)}, - {.Id = Oid::NewOid(), .Body = MakeCompressedBuffer(213)}, - {.Id = Oid::NewOid(), .Body = MakeCompressedBuffer(7)}}, - .Policy = CachePolicy::StoreLocal}, - {.Key = {.Bucket = "thebucket", .Hash = IoHash::FromHexString("d1df59fcab06793a5f2c372d795bb907a15cab15")}, - .Values = {{.Id = Oid::NewOid(), .Body = MakeCompressedBuffer(1234)}, - {.Id = Oid::NewOid(), .Body = MakeCompressedBuffer(99)}, - {.Id = Oid::NewOid(), .Body = MakeCompressedBuffer(124)}}, - .Policy = CachePolicy::Store}, - {.Key = {.Bucket = "theotherbucket", .Hash = IoHash::FromHexString("e1ce9e1ac8a6f5953dc14c1fa9512b804ed689df")}, - .Values = {{.Id = Oid::NewOid(), .Body = MakeCompressedBuffer(19)}, - {.Id = Oid::NewOid(), .Body = MakeCompressedBuffer(1248)}, - {.Id = Oid::NewOid(), .Body = MakeCompressedBuffer(823)}}}}}; - - CbPackage FullPutRequestPackage; - CHECK(FullPutRequest.Format(FullPutRequestPackage)); - PutCacheRecordsRequest FullPutRequestCopy; - CHECK(FullPutRequestCopy.Parse(FullPutRequestPackage)); - - GetCacheRecordsResult FullResult = { - {GetCacheRecordResult{.Key = FullPutRequestCopy.Requests[0].Key, - .Values = {{.Id = FullPutRequestCopy.Requests[0].Values[0].Id, - .RawHash = FullPutRequestCopy.Requests[0].Values[0].Body.DecodeRawHash(), - .RawSize = FullPutRequestCopy.Requests[0].Values[0].Body.DecodeRawSize(), - .Body = FullPutRequestCopy.Requests[0].Values[0].Body}, - {.Id = FullPutRequestCopy.Requests[0].Values[1].Id, - - .RawHash = FullPutRequestCopy.Requests[0].Values[1].Body.DecodeRawHash(), - .RawSize = FullPutRequestCopy.Requests[0].Values[1].Body.DecodeRawSize(), - .Body = FullPutRequestCopy.Requests[0].Values[1].Body}, - {.Id = FullPutRequestCopy.Requests[0].Values[2].Id, - .RawHash = FullPutRequestCopy.Requests[0].Values[2].Body.DecodeRawHash(), - .RawSize = FullPutRequestCopy.Requests[0].Values[2].Body.DecodeRawSize(), - .Body = FullPutRequestCopy.Requests[0].Values[2].Body}}}, - {}, // Simulate not have! - GetCacheRecordResult{.Key = FullPutRequestCopy.Requests[2].Key, - .Values = {{.Id = FullPutRequestCopy.Requests[2].Values[0].Id, - .RawHash = FullPutRequestCopy.Requests[2].Values[0].Body.DecodeRawHash(), - .RawSize = FullPutRequestCopy.Requests[2].Values[0].Body.DecodeRawSize(), - .Body = FullPutRequestCopy.Requests[2].Values[0].Body}, - {.Id = FullPutRequestCopy.Requests[2].Values[1].Id, - .RawHash = FullPutRequestCopy.Requests[2].Values[1].Body.DecodeRawHash(), - .RawSize = FullPutRequestCopy.Requests[2].Values[1].Body.DecodeRawSize(), - .Body = {}}, // Simulate not have - {.Id = FullPutRequestCopy.Requests[2].Values[2].Id, - .RawHash = FullPutRequestCopy.Requests[2].Values[2].Body.DecodeRawHash(), - .RawSize = FullPutRequestCopy.Requests[2].Values[2].Body.DecodeRawSize(), - .Body = FullPutRequestCopy.Requests[2].Values[2].Body}}}}}; - CbPackage FullResponsePackage; - CHECK(FullResult.Format(FullResponsePackage)); - GetCacheRecordsResult FullResultCopy; - CHECK(FullResultCopy.Parse(FullResponsePackage)); - CHECK(FullResult.Results[0] == FullResultCopy.Results[0]); - CHECK(!FullResultCopy.Results[1]); - CHECK(FullResult.Results[2] == FullResultCopy.Results[2]); - - GetCacheRecordsResult PartialResultCopy; - CHECK(PartialResultCopy.Parse(FullResponsePackage, std::initializer_list<size_t>{0, 3, 4})); - CHECK(FullResult.Results[0] == PartialResultCopy.Results[0]); - CHECK(!PartialResultCopy.Results[1]); - CHECK(!PartialResultCopy.Results[2]); - CHECK(!PartialResultCopy.Results[3]); - CHECK(FullResult.Results[2] == PartialResultCopy.Results[4]); - } - - TEST_CASE("cacherequests.put.cache.values") - { - PutCacheValuesRequest EmptyRequest; - CbPackage EmptyRequestPackage; - CHECK(EmptyRequest.Format(EmptyRequestPackage)); - PutCacheValuesRequest EmptyRequestCopy; - CHECK(!EmptyRequestCopy.Parse(EmptyRequestPackage)); // Namespace is required - - CompressedBuffer Buffers[3] = {MakeCompressedBuffer(969), MakeCompressedBuffer(3469), MakeCompressedBuffer(9)}; - PutCacheValuesRequest FullRequest = { - .DefaultPolicy = CachePolicy::StoreLocal, - .Namespace = "other_namespace", - .Requests = {{.Key = {.Bucket = "finebucket", .Hash = IoHash::FromHexString("d1df59fcab06793a5f2c372d795bb907a15cab15")}, - .RawHash = Buffers[0].DecodeRawHash(), - .Body = Buffers[0], - .Policy = CachePolicy::Local}, - {.Key = {.Bucket = "badbucket", .Hash = IoHash::FromHexString("177030568fdd461bf4fe5ddbf4d463e514e8178e")}, - .RawHash = Buffers[1].DecodeRawHash(), - .Body = Buffers[1], - .Policy = CachePolicy::Remote}, - {.Key = {.Bucket = "badbucket", .Hash = IoHash::FromHexString("e1ce9e1ac8a6f5953dc14c1fa9512b804ed689df")}, - .RawHash = Buffers[2].DecodeRawHash()}}}; - - CbPackage FullRequestPackage; - CHECK(FullRequest.Format(FullRequestPackage)); - PutCacheValuesRequest FullRequestCopy; - CHECK(FullRequestCopy.Parse(FullRequestPackage)); - CHECK(FullRequest == FullRequestCopy); - - PutCacheValuesResult EmptyResult; - CbPackage EmptyResponsePackage; - CHECK(!EmptyResult.Format(EmptyResponsePackage)); - - PutCacheValuesResult FullResult = {.Success = {true, false, true}}; - - CbPackage FullResponsePackage; - CHECK(FullResult.Format(FullResponsePackage)); - PutCacheValuesResult FullResultCopy; - CHECK(FullResultCopy.Parse(FullResponsePackage)); - CHECK(FullResult == FullResultCopy); - } - - TEST_CASE("cacherequests.get.cache.values") - { - GetCacheValuesRequest EmptyRequest; - CbPackage EmptyRequestPackage; - CHECK(EmptyRequest.Format(EmptyRequestPackage)); - GetCacheValuesRequest EmptyRequestCopy; - CHECK(!EmptyRequestCopy.Parse(EmptyRequestPackage.GetObject())); // Namespace is required - - GetCacheValuesRequest FullRequest = { - .DefaultPolicy = CachePolicy::StoreLocal, - .Namespace = "other_namespace", - .Requests = {{.Key = {.Bucket = "finebucket", .Hash = IoHash::FromHexString("d1df59fcab06793a5f2c372d795bb907a15cab15")}, - .Policy = CachePolicy::Local}, - {.Key = {.Bucket = "badbucket", .Hash = IoHash::FromHexString("177030568fdd461bf4fe5ddbf4d463e514e8178e")}, - .Policy = CachePolicy::Remote}, - {.Key = {.Bucket = "badbucket", .Hash = IoHash::FromHexString("e1ce9e1ac8a6f5953dc14c1fa9512b804ed689df")}}}}; - - CbPackage FullRequestPackage; - CHECK(FullRequest.Format(FullRequestPackage)); - GetCacheValuesRequest FullRequestCopy; - CHECK(FullRequestCopy.Parse(FullRequestPackage.GetObject())); - CHECK(FullRequest == FullRequestCopy); - - CbPackage PartialRequestPackage; - CHECK(FullRequest.Format(PartialRequestPackage, std::initializer_list<size_t>{0, 2})); - GetCacheValuesRequest PartialRequest = FullRequest; - PartialRequest.Requests.erase(PartialRequest.Requests.begin() + 1); - GetCacheValuesRequest PartialRequestCopy; - CHECK(PartialRequestCopy.Parse(PartialRequestPackage.GetObject())); - CHECK(PartialRequest == PartialRequestCopy); - - CacheValuesResult EmptyResult; - CbPackage EmptyResponsePackage; - CHECK(EmptyResult.Format(EmptyResponsePackage)); - CacheValuesResult EmptyResultCopy; - CHECK(!EmptyResultCopy.Parse(EmptyResponsePackage)); - CHECK(EmptyResult == EmptyResultCopy); - - CompressedBuffer Buffers[3][3] = {{MakeCompressedBuffer(123), MakeCompressedBuffer(321), MakeCompressedBuffer(333)}, - {MakeCompressedBuffer(6123), MakeCompressedBuffer(8321), MakeCompressedBuffer(7333)}, - {MakeCompressedBuffer(5123), MakeCompressedBuffer(2321), MakeCompressedBuffer(2333)}}; - CacheValuesResult FullResult = { - .Results = {CacheValueResult{.RawSize = 0, .RawHash = Buffers[0][0].DecodeRawHash(), .Body = Buffers[0][0]}, - CacheValueResult{.RawSize = 0, .RawHash = Buffers[0][1].DecodeRawHash(), .Body = Buffers[0][1]}, - CacheValueResult{.RawSize = 0, .RawHash = Buffers[0][2].DecodeRawHash(), .Body = Buffers[0][2]}, - CacheValueResult{.RawSize = 0, .RawHash = Buffers[2][0].DecodeRawHash(), .Body = Buffers[2][0]}, - CacheValueResult{.RawSize = 0, .RawHash = Buffers[2][1].DecodeRawHash(), .Body = Buffers[2][1]}, - CacheValueResult{.RawSize = Buffers[2][2].DecodeRawSize(), .RawHash = Buffers[2][2].DecodeRawHash()}}}; - CbPackage FullResponsePackage; - CHECK(FullResult.Format(FullResponsePackage)); - CacheValuesResult FullResultCopy; - CHECK(FullResultCopy.Parse(FullResponsePackage)); - CHECK(FullResult == FullResultCopy); - - CacheValuesResult PartialResultCopy; - CHECK(PartialResultCopy.Parse(FullResponsePackage, std::initializer_list<size_t>{0, 3, 4, 5, 6, 9})); - CHECK(PartialResultCopy.Results[0] == FullResult.Results[0]); - CHECK(PartialResultCopy.Results[1].RawHash == IoHash::Zero); - CHECK(PartialResultCopy.Results[2].RawHash == IoHash::Zero); - CHECK(PartialResultCopy.Results[3] == FullResult.Results[1]); - CHECK(PartialResultCopy.Results[4] == FullResult.Results[2]); - CHECK(PartialResultCopy.Results[5] == FullResult.Results[3]); - CHECK(PartialResultCopy.Results[6] == FullResult.Results[4]); - CHECK(PartialResultCopy.Results[7].RawHash == IoHash::Zero); - CHECK(PartialResultCopy.Results[8].RawHash == IoHash::Zero); - CHECK(PartialResultCopy.Results[9] == FullResult.Results[5]); - } - - TEST_CASE("cacherequests.get.cache.chunks") - { - GetCacheChunksRequest EmptyRequest; - CbPackage EmptyRequestPackage; - CHECK(EmptyRequest.Format(EmptyRequestPackage)); - GetCacheChunksRequest EmptyRequestCopy; - CHECK(!EmptyRequestCopy.Parse(EmptyRequestPackage.GetObject())); // Namespace is required - - GetCacheChunksRequest FullRequest = { - .DefaultPolicy = CachePolicy::StoreLocal, - .Namespace = "other_namespace", - .Requests = {{.Key = {.Bucket = "finebucket", .Hash = IoHash::FromHexString("d1df59fcab06793a5f2c372d795bb907a15cab15")}, - .ValueId = Oid::NewOid(), - .ChunkId = IoHash::FromHexString("ab3917854bfef7e7af2c372d795bb907a15cab15"), - .RawOffset = 77, - .RawSize = 33, - .Policy = CachePolicy::Local}, - {.Key = {.Bucket = "badbucket", .Hash = IoHash::FromHexString("177030568fdd461bf4fe5ddbf4d463e514e8178e")}, - .ValueId = Oid::NewOid(), - .ChunkId = IoHash::FromHexString("372d795bb907a15cab15ab3917854bfef7e7af2c"), - .Policy = CachePolicy::Remote}, - { - .Key = {.Bucket = "badbucket", .Hash = IoHash::FromHexString("e1ce9e1ac8a6f5953dc14c1fa9512b804ed689df")}, - .ChunkId = IoHash::FromHexString("372d795bb907a15cab15ab3917854bfef7e7af2c"), - }}}; - - CbPackage FullRequestPackage; - CHECK(FullRequest.Format(FullRequestPackage)); - GetCacheChunksRequest FullRequestCopy; - CHECK(FullRequestCopy.Parse(FullRequestPackage.GetObject())); - CHECK(FullRequest == FullRequestCopy); - - GetCacheChunksResult EmptyResult; - CbPackage EmptyResponsePackage; - CHECK(EmptyResult.Format(EmptyResponsePackage)); - GetCacheChunksResult EmptyResultCopy; - CHECK(!EmptyResultCopy.Parse(EmptyResponsePackage)); - CHECK(EmptyResult == EmptyResultCopy); - - CompressedBuffer Buffers[3][3] = {{MakeCompressedBuffer(123), MakeCompressedBuffer(321), MakeCompressedBuffer(333)}, - {MakeCompressedBuffer(6123), MakeCompressedBuffer(8321), MakeCompressedBuffer(7333)}, - {MakeCompressedBuffer(5123), MakeCompressedBuffer(2321), MakeCompressedBuffer(2333)}}; - GetCacheChunksResult FullResult = { - .Results = {CacheValueResult{.RawSize = 0, .RawHash = Buffers[0][0].DecodeRawHash(), .Body = Buffers[0][0]}, - CacheValueResult{.RawSize = 0, .RawHash = Buffers[0][1].DecodeRawHash(), .Body = Buffers[0][1]}, - CacheValueResult{.RawSize = 0, .RawHash = Buffers[0][2].DecodeRawHash(), .Body = Buffers[0][2]}, - CacheValueResult{.RawSize = 0, .RawHash = Buffers[2][0].DecodeRawHash(), .Body = Buffers[2][0]}, - CacheValueResult{.RawSize = 0, .RawHash = Buffers[2][1].DecodeRawHash(), .Body = Buffers[2][1]}, - CacheValueResult{.RawSize = Buffers[2][2].DecodeRawSize(), .RawHash = Buffers[2][2].DecodeRawHash()}}}; - CbPackage FullResponsePackage; - CHECK(FullResult.Format(FullResponsePackage)); - GetCacheChunksResult FullResultCopy; - CHECK(FullResultCopy.Parse(FullResponsePackage)); - CHECK(FullResult == FullResultCopy); - } - - TEST_CASE("cachrequests.parse.relative.Uri") - { - using namespace std::literals; - - HttpRequestData RootRequest; - CHECK(HttpRequestParseRelativeUri("", "!default!", RootRequest)); - CHECK(!RootRequest.Namespace.has_value()); - CHECK(!RootRequest.Bucket.has_value()); - CHECK(!RootRequest.HashKey.has_value()); - CHECK(!RootRequest.ValueContentId.has_value()); - - RootRequest = {}; - CHECK(HttpRequestParseRelativeUri("/", "!default!", RootRequest)); - CHECK(!RootRequest.Namespace.has_value()); - CHECK(!RootRequest.Bucket.has_value()); - CHECK(!RootRequest.HashKey.has_value()); - CHECK(!RootRequest.ValueContentId.has_value()); - - HttpRequestData LegacyBucketRequestBecomesNamespaceRequest; - CHECK(HttpRequestParseRelativeUri("test", "!default!", LegacyBucketRequestBecomesNamespaceRequest)); - CHECK(LegacyBucketRequestBecomesNamespaceRequest.Namespace == "test"sv); - CHECK(!LegacyBucketRequestBecomesNamespaceRequest.Bucket.has_value()); - CHECK(!LegacyBucketRequestBecomesNamespaceRequest.HashKey.has_value()); - CHECK(!LegacyBucketRequestBecomesNamespaceRequest.ValueContentId.has_value()); - - HttpRequestData LegacyHashKeyRequest; - CHECK(HttpRequestParseRelativeUri("test/0123456789abcdef12340123456789abcdef1234", "!default!", LegacyHashKeyRequest)); - CHECK(LegacyHashKeyRequest.Namespace == "!default!"); - CHECK(LegacyHashKeyRequest.Bucket == "test"sv); - CHECK(LegacyHashKeyRequest.HashKey == IoHash::FromHexString("0123456789abcdef12340123456789abcdef1234"sv)); - CHECK(!LegacyHashKeyRequest.ValueContentId.has_value()); - - HttpRequestData LegacyValueContentIdRequest; - CHECK(HttpRequestParseRelativeUri("test/0123456789abcdef12340123456789abcdef1234/56789abcdef12345678956789abcdef123456789", - "!default!", - LegacyValueContentIdRequest)); - CHECK(LegacyValueContentIdRequest.Namespace == "!default!"); - CHECK(LegacyValueContentIdRequest.Bucket == "test"sv); - CHECK(LegacyValueContentIdRequest.HashKey == IoHash::FromHexString("0123456789abcdef12340123456789abcdef1234"sv)); - CHECK(LegacyValueContentIdRequest.ValueContentId == IoHash::FromHexString("56789abcdef12345678956789abcdef123456789"sv)); - - HttpRequestData V2DefaultNamespaceRequest; - CHECK(HttpRequestParseRelativeUri("ue4.ddc", "!default!", V2DefaultNamespaceRequest)); - CHECK(V2DefaultNamespaceRequest.Namespace == "ue4.ddc"); - CHECK(!V2DefaultNamespaceRequest.Bucket.has_value()); - CHECK(!V2DefaultNamespaceRequest.HashKey.has_value()); - CHECK(!V2DefaultNamespaceRequest.ValueContentId.has_value()); - - HttpRequestData V2NamespaceRequest; - CHECK(HttpRequestParseRelativeUri("nicenamespace", "!default!", V2NamespaceRequest)); - CHECK(V2NamespaceRequest.Namespace == "nicenamespace"sv); - CHECK(!V2NamespaceRequest.Bucket.has_value()); - CHECK(!V2NamespaceRequest.HashKey.has_value()); - CHECK(!V2NamespaceRequest.ValueContentId.has_value()); - - HttpRequestData V2BucketRequestWithDefaultNamespace; - CHECK(HttpRequestParseRelativeUri("ue4.ddc/test", "!default!", V2BucketRequestWithDefaultNamespace)); - CHECK(V2BucketRequestWithDefaultNamespace.Namespace == "ue4.ddc"); - CHECK(V2BucketRequestWithDefaultNamespace.Bucket == "test"sv); - CHECK(!V2BucketRequestWithDefaultNamespace.HashKey.has_value()); - CHECK(!V2BucketRequestWithDefaultNamespace.ValueContentId.has_value()); - - HttpRequestData V2BucketRequestWithNamespace; - CHECK(HttpRequestParseRelativeUri("nicenamespace/test", "!default!", V2BucketRequestWithNamespace)); - CHECK(V2BucketRequestWithNamespace.Namespace == "nicenamespace"sv); - CHECK(V2BucketRequestWithNamespace.Bucket == "test"sv); - CHECK(!V2BucketRequestWithNamespace.HashKey.has_value()); - CHECK(!V2BucketRequestWithNamespace.ValueContentId.has_value()); - - HttpRequestData V2HashKeyRequest; - CHECK(HttpRequestParseRelativeUri("test/0123456789abcdef12340123456789abcdef1234", "!default!", V2HashKeyRequest)); - CHECK(V2HashKeyRequest.Namespace == "!default!"); - CHECK(V2HashKeyRequest.Bucket == "test"); - CHECK(V2HashKeyRequest.HashKey == IoHash::FromHexString("0123456789abcdef12340123456789abcdef1234"sv)); - CHECK(!V2HashKeyRequest.ValueContentId.has_value()); - - HttpRequestData V2ValueContentIdRequest; - CHECK(HttpRequestParseRelativeUri( - "nicenamespace/test/0123456789abcdef12340123456789abcdef1234/56789abcdef12345678956789abcdef123456789", - "!default!", - V2ValueContentIdRequest)); - CHECK(V2ValueContentIdRequest.Namespace == "nicenamespace"sv); - CHECK(V2ValueContentIdRequest.Bucket == "test"sv); - CHECK(V2ValueContentIdRequest.HashKey == IoHash::FromHexString("0123456789abcdef12340123456789abcdef1234"sv)); - CHECK(V2ValueContentIdRequest.ValueContentId == IoHash::FromHexString("56789abcdef12345678956789abcdef123456789"sv)); - - HttpRequestData Invalid; - CHECK(!HttpRequestParseRelativeUri("bad\2_namespace", "!default!", Invalid)); - CHECK(!HttpRequestParseRelativeUri("nice/\2\1bucket", "!default!", Invalid)); - CHECK(!HttpRequestParseRelativeUri("namespace/bucket/0123456789a", "!default!", Invalid)); - CHECK(!HttpRequestParseRelativeUri("namespace/bucket/0123456789abcdef12340123456789abcdef1234/56789abcdef1234", - "!default!", - Invalid)); - CHECK(!HttpRequestParseRelativeUri("namespace/bucket/pppppppp89abcdef12340123456789abcdef1234", "!default!", Invalid)); - CHECK(!HttpRequestParseRelativeUri("namespace/bucket/0123456789abcdef12340123456789abcdef1234/56789abcd", "!default!", Invalid)); - CHECK(!HttpRequestParseRelativeUri( - "namespace/bucket/0123456789abcdef12340123456789abcdef1234/ppppppppdef12345678956789abcdef123456789", - "!default!", - Invalid)); - } -#endif -} // namespace cacherequests - -void -cacherequests_forcelink() -{ -} - -} // namespace zen |