aboutsummaryrefslogtreecommitdiff
path: root/zenutil/include
diff options
context:
space:
mode:
authormattpetersepic <[email protected]>2022-02-01 08:06:36 -0700
committerGitHub <[email protected]>2022-02-01 08:06:36 -0700
commit154743f2d2ff2b7163bcf8d7b76eea3e3579aaba (patch)
treeaef417b5c9a0d5502c7afdb01c4cc598071e956d /zenutil/include
parentTweaked remote_build.py TTY output (diff)
downloadzen-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.h6
-rw-r--r--zenutil/include/zenutil/cache/cachepolicy.h143
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