diff options
| author | mattpetersepic <[email protected]> | 2022-02-01 08:06:36 -0700 |
|---|---|---|
| committer | GitHub <[email protected]> | 2022-02-01 08:06:36 -0700 |
| commit | 154743f2d2ff2b7163bcf8d7b76eea3e3579aaba (patch) | |
| tree | aef417b5c9a0d5502c7afdb01c4cc598071e956d /zenutil/include | |
| parent | Tweaked remote_build.py TTY output (diff) | |
| download | zen-154743f2d2ff2b7163bcf8d7b76eea3e3579aaba.tar.xz zen-154743f2d2ff2b7163bcf8d7b76eea3e3579aaba.zip | |
Cache policy support (#47)
Add HandleRpc methods for the remaining ICacheStore requests from unreal: PutCacheValues/GetCacheValues. We now have batched versions for PutCacheRecords,GetCacheRecords,PutCacheValues,GetCacheValues,GetCacheChunks. Add support for CachePolicy flags to all of these batched methods.
* Add Batched PutCacheValues/GetCacheValues. Rename old GetCacheValues to GetCacheChunks.
* HandleRpcGetCacheRecords: Receive a CacheRecordPolicy with each key, and skipdata on attachments we already have.
* Changes to CachePolicy copied from Release-5.0 depot. Change serialization to use the key BasePolicy instead of DefaultValuePolicy.
* GetChunks: Read CacheRecords from remote if necessary to find ContentId. Implement QueryLocal, StoreLocal, and SkipData.
Diffstat (limited to 'zenutil/include')
| -rw-r--r-- | zenutil/include/zenutil/cache/cachekey.h | 6 | ||||
| -rw-r--r-- | zenutil/include/zenutil/cache/cachepolicy.h | 143 |
2 files changed, 105 insertions, 44 deletions
diff --git a/zenutil/include/zenutil/cache/cachekey.h b/zenutil/include/zenutil/cache/cachekey.h index a0a83a883..aa649b4dc 100644 --- a/zenutil/include/zenutil/cache/cachekey.h +++ b/zenutil/include/zenutil/cache/cachekey.h @@ -50,6 +50,12 @@ struct CacheChunkRequest CachePolicy Policy = CachePolicy::Default; }; +struct CacheKeyRequest +{ + CacheKey Key; + CacheRecordPolicy Policy; +}; + inline bool operator<(const CacheChunkRequest& A, const CacheChunkRequest& B) { diff --git a/zenutil/include/zenutil/cache/cachepolicy.h b/zenutil/include/zenutil/cache/cachepolicy.h index b3602edbd..3eb0fda66 100644 --- a/zenutil/include/zenutil/cache/cachepolicy.h +++ b/zenutil/include/zenutil/cache/cachepolicy.h @@ -12,14 +12,26 @@ #include <span> #include <unordered_map> +#define BACKWARDS_COMPATABILITY_JAN2022 1 +#if BACKWARDS_COMPATABILITY_JAN2022 +# define BACKWARDS_COMPATABILITY_JAN2022_CODE(...) __VA_ARGS__ +#else +# define BACKWARDS_COMPATABILITY_JAN2022_CODE(...) +#endif + +namespace zen::Private { +class ICacheRecordPolicyShared; +} namespace zen { class CbObjectView; class CbWriter; +class OptionalCacheRecordPolicy; + enum class CachePolicy : uint32_t { - /** A value without any flags set. */ + /** A value with no flags. Disables access to the cache unless combined with other flags. */ None = 0, /** Allow a cache request to query local caches. */ @@ -29,17 +41,26 @@ enum class CachePolicy : uint32_t /** Allow a cache request to query any caches. */ Query = QueryLocal | QueryRemote, - /** Allow cache records and values to be stored in local caches. */ + /** Allow cache requests to query and store records and values in local caches. */ StoreLocal = 1 << 2, /** Allow cache records and values to be stored in remote caches. */ StoreRemote = 1 << 3, /** Allow cache records and values to be stored in any caches. */ Store = StoreLocal | StoreRemote, - /** Skip fetching the metadata for record requests. */ - SkipMeta = 1 << 4, + /** Allow cache requests to query and store records and values in local caches. */ + Local = QueryLocal | StoreLocal, + /** Allow cache requests to query and store records and values in remote caches. */ + Remote = QueryRemote | StoreRemote, + + /** Allow cache requests to query and store records and values in any caches. */ + Default = Query | Store, + /** Skip fetching the data for values. */ - SkipData = 1 << 5, + SkipData = 1 << 4, + + /** Skip fetching the metadata for record requests. */ + SkipMeta = 1 << 5, /** * Partial output will be provided with the error status when a required value is missing. @@ -48,7 +69,7 @@ enum class CachePolicy : uint32_t * without rebuilding the whole record. The cache automatically adds this flag when there are * other cache stores that it may be able to recover missing values from. * - * Missing values will be returned in the records or chunks, but with only the hash and size. + * Missing values will be returned in the records, but with only the hash and size. * * Applying this flag for a put of a record allows a partial record to be stored. */ @@ -61,50 +82,48 @@ enum class CachePolicy : uint32_t * to be used when subsequent accesses will not tolerate a cache miss. */ KeepAlive = 1 << 7, - - /** Allow cache requests to query and store records and values in local caches. */ - Local = QueryLocal | StoreLocal, - /** Allow cache requests to query and store records and values in remote caches. */ - Remote = QueryRemote | StoreRemote, - - /** Allow cache requests to query and store records and values in any caches. */ - Default = Query | Store, - - /** Do not allow cache requests to query or store records and values in any caches. */ - Disable = None, }; gsl_DEFINE_ENUM_BITMASK_OPERATORS(CachePolicy); -/** Serialize Policy to text and append to Builder. Appended text will not be empty. */ +/** Append a non-empty text version of the policy to the builder. */ StringBuilderBase& operator<<(StringBuilderBase& Builder, CachePolicy Policy); -/** Parse text written by operator<< back into an ECachePolicy. Text must not be empty. */ +/** Parse non-empty text written by operator<< into a policy. */ CachePolicy ParseCachePolicy(std::string_view Text); +/** Return input converted into the equivalent policy that the upstream should use when forwarding a put or get to an upstream server. */ +CachePolicy ConvertToUpstream(CachePolicy Policy); + +inline CachePolicy +Union(CachePolicy A, CachePolicy B) +{ + constexpr CachePolicy InvertedFlags = CachePolicy::SkipData | CachePolicy::SkipMeta; + return (A & ~(InvertedFlags)) | (B & ~(InvertedFlags)) | (A & B & InvertedFlags); +} /** A value ID and the cache policy to use for that value. */ struct CacheValuePolicy { Oid Id; CachePolicy Policy = CachePolicy::Default; + + /** Flags that are valid on a value policy. */ + static constexpr CachePolicy PolicyMask = CachePolicy::Default | CachePolicy::SkipData; }; -namespace Private { - /** Interface for the private implementation of the cache record policy. */ - class ICacheRecordPolicyShared : public RefCounted - { - public: - virtual ~ICacheRecordPolicyShared() = default; - virtual std::span<const CacheValuePolicy> GetValuePolicies() const = 0; - virtual void AddValuePolicy(const CacheValuePolicy& Policy) = 0; - virtual void Build() = 0; - }; -} // namespace Private +/** Interface for the private implementation of the cache record policy. */ +class Private::ICacheRecordPolicyShared : public RefCounted +{ +public: + virtual ~ICacheRecordPolicyShared() = default; + virtual void AddValuePolicy(const CacheValuePolicy& Policy) = 0; + virtual std::span<const CacheValuePolicy> GetValuePolicies() const = 0; +}; /** * Flags to control the behavior of cache record requests, with optional overrides by value. * * Examples: - * - A base policy of Disable, with value policy overrides of Default, will fetch those values if - * they exist in the record, and skip data for any other values. + * - A base policy of None with value policy overrides of Default will fetch those values if they + * exist in the record, and skip data for any other values. * - A base policy of Default, with value policy overrides of (Query | SkipData), will skip those * values, but still check if they exist, and will load any other values. */ @@ -115,34 +134,35 @@ public: CacheRecordPolicy() = default; /** Construct a cache record policy with a uniform policy for the record and every value. */ - inline CacheRecordPolicy(CachePolicy Policy) : RecordPolicy(Policy), DefaultValuePolicy(Policy) {} + inline CacheRecordPolicy(CachePolicy BasePolicy) + : RecordPolicy(BasePolicy) + , DefaultValuePolicy(BasePolicy & CacheValuePolicy::PolicyMask) + { + } /** Returns true if the record and every value use the same cache policy. */ - inline bool IsUniform() const { return !Shared && RecordPolicy == DefaultValuePolicy; } + inline bool IsUniform() const { return !Shared; } /** Returns the cache policy to use for the record. */ inline CachePolicy GetRecordPolicy() const { return RecordPolicy; } + /** Returns the base cache policy that this was constructed from. */ + inline CachePolicy GetBasePolicy() const { return DefaultValuePolicy | (RecordPolicy & ~CacheValuePolicy::PolicyMask); } + /** Returns the cache policy to use for the value. */ CachePolicy GetValuePolicy(const Oid& Id) const; - /** Returns the cache policy to use for values with no override. */ - inline CachePolicy GetDefaultValuePolicy() const { return DefaultValuePolicy; } - /** Returns the array of cache policy overrides for values, sorted by ID. */ inline std::span<const CacheValuePolicy> GetValuePolicies() const { return Shared ? Shared->GetValuePolicies() : std::span<const CacheValuePolicy>(); } - /** Save the values from *this into the given writer. */ + /** Saves the cache record policy to a compact binary object. */ void Save(CbWriter& Writer) const; - /** - * Returns a policy loaded from values on Object. - * Invalid data will result in a uniform CacheRecordPolicy with defaultValuePolicy == DefaultPolicy. - */ - static CacheRecordPolicy Load(CbObjectView Object, CachePolicy DefaultPolicy = CachePolicy::Default); + /** Loads a cache record policy from an object. */ + static OptionalCacheRecordPolicy Load(CbObjectView Object); /** Return *this converted into the equivalent policy that the upstream should use when forwarding a put or get to an upstream server. */ @@ -150,6 +170,7 @@ public: private: friend class CacheRecordPolicyBuilder; + friend class OptionalCacheRecordPolicy; CachePolicy RecordPolicy = CachePolicy::Default; CachePolicy DefaultValuePolicy = CachePolicy::Default; @@ -167,7 +188,7 @@ public: inline explicit CacheRecordPolicyBuilder(CachePolicy Policy) : BasePolicy(Policy) {} /** Adds a cache policy override for a value. */ - void AddValuePolicy(const CacheValuePolicy& Policy); + void AddValuePolicy(const CacheValuePolicy& Value); inline void AddValuePolicy(const Oid& Id, CachePolicy Policy) { AddValuePolicy({Id, Policy}); } /** Build a cache record policy, which makes this builder subsequently unusable. */ @@ -178,4 +199,38 @@ private: RefPtr<Private::ICacheRecordPolicyShared> Shared; }; +/** + * A cache record policy that can be null. + * + * @see CacheRecordPolicy + */ +class OptionalCacheRecordPolicy : private CacheRecordPolicy +{ +public: + inline OptionalCacheRecordPolicy() : CacheRecordPolicy(~CachePolicy::None) {} + + inline OptionalCacheRecordPolicy(CacheRecordPolicy&& InOutput) : CacheRecordPolicy(std::move(InOutput)) {} + inline OptionalCacheRecordPolicy(const CacheRecordPolicy& InOutput) : CacheRecordPolicy(InOutput) {} + inline OptionalCacheRecordPolicy& operator=(CacheRecordPolicy&& InOutput) + { + CacheRecordPolicy::operator=(std::move(InOutput)); + return *this; + } + inline OptionalCacheRecordPolicy& operator=(const CacheRecordPolicy& InOutput) + { + CacheRecordPolicy::operator=(InOutput); + return *this; + } + + /** Returns the cache record policy. The caller must check for null before using this accessor. */ + inline const CacheRecordPolicy& Get() const& { return *this; } + inline CacheRecordPolicy Get() && { return std::move(*this); } + + inline bool IsNull() const { return RecordPolicy == ~CachePolicy::None; } + inline bool IsValid() const { return !IsNull(); } + inline explicit operator bool() const { return !IsNull(); } + + inline void Reset() { *this = OptionalCacheRecordPolicy(); } +}; + } // namespace zen |