aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2023-12-14 13:09:22 +0100
committerGitHub <[email protected]>2023-12-14 13:09:22 +0100
commitff0e3b4fbef6a981a74a3d3e75b80ce208714dc3 (patch)
tree565bf05898eccd74c8381d79d902c29ba72abe41 /src
parent0.2.37 (diff)
downloadzen-ff0e3b4fbef6a981a74a3d3e75b80ce208714dc3.tar.xz
zen-ff0e3b4fbef6a981a74a3d3e75b80ce208714dc3.zip
implement cache recording segment split by age (#611)
- also fixes weird DateTime/TimeSpan comparison operator
Diffstat (limited to 'src')
-rw-r--r--src/zencore/compactbinary.cpp52
-rw-r--r--src/zencore/include/zencore/compactbinary.h36
-rw-r--r--src/zenutil/cache/rpcrecording.cpp39
3 files changed, 110 insertions, 17 deletions
diff --git a/src/zencore/compactbinary.cpp b/src/zencore/compactbinary.cpp
index 9152a8bfc..6677b5a61 100644
--- a/src/zencore/compactbinary.cpp
+++ b/src/zencore/compactbinary.cpp
@@ -2463,6 +2463,58 @@ TEST_CASE("json.uson")
}
}
+//////////////////////////////////////////////////////////////////////////
+
+TEST_SUITE_BEGIN("core.datetime");
+
+TEST_CASE("core.datetime.compare")
+{
+ DateTime T1(2000, 12, 13);
+ DateTime T2(2000, 12, 14);
+ CHECK(T1 < T2);
+ CHECK(T2 > T1);
+ CHECK(T1 == T1);
+ CHECK(T1 != T2);
+ CHECK(T1 >= T1);
+ CHECK(T2 >= T1);
+ CHECK(T1 <= T1);
+ CHECK(T1 <= T2);
+}
+
+TEST_CASE("core.datetime.add")
+{
+ DateTime T1(2000, 12, 13);
+ DateTime T2(2000, 12, 14);
+ TimeSpan dT = T2 - T1;
+ TimeSpan dT1 = T1 - T1;
+
+ CHECK(T1 + dT == T2);
+ CHECK(dT + T1 == T2);
+ CHECK(dT + T1 - T2 == dT1);
+}
+
+TEST_SUITE_END();
+
+TEST_SUITE_BEGIN("core.timespan");
+
+TEST_CASE("core.timespan.compare")
+{
+ TimeSpan T1(1000);
+ TimeSpan T2(1001);
+ CHECK(T1 < T2);
+ CHECK(T2 > T1);
+ CHECK(T1 == T1);
+ CHECK(T1 != T2);
+ CHECK(T1 >= T1);
+ CHECK(T2 >= T1);
+ CHECK(T1 <= T1);
+ CHECK(T1 <= T2);
+}
+
+TEST_SUITE_END();
+
+//////////////////////////////////////////////////////////////////////////
+
#endif
} // namespace zen
diff --git a/src/zencore/include/zencore/compactbinary.h b/src/zencore/include/zencore/compactbinary.h
index cb032e34a..675e2a8d4 100644
--- a/src/zencore/include/zencore/compactbinary.h
+++ b/src/zencore/include/zencore/compactbinary.h
@@ -26,12 +26,13 @@
namespace zen {
-class CbObjectView;
class CbArrayView;
+class CbObjectView;
+class CbValue;
+class CompressedBuffer;
class BinaryReader;
class BinaryWriter;
-class CompressedBuffer;
-class CbValue;
+class TimeSpan;
class DateTime
{
@@ -58,7 +59,11 @@ public:
void GetDate(int& Year, int& Month, int& Day) const;
inline bool operator==(const DateTime& Rhs) const { return Ticks == Rhs.Ticks; }
- inline auto operator<=>(const DateTime& Rhs) const { return Ticks - Rhs.Ticks; }
+ inline auto operator<=>(const DateTime& Rhs) const = default;
+
+ friend inline TimeSpan operator-(const DateTime& Lhs, const DateTime& Rhs);
+ friend inline DateTime operator+(const DateTime& Lhs, const TimeSpan& Rhs);
+ friend inline DateTime operator+(const TimeSpan& Lhs, const DateTime& Rhs);
std::string ToString(const char* Format) const;
std::string ToIso8601() const;
@@ -78,7 +83,7 @@ public:
inline uint64_t GetTicks() const { return Ticks; }
inline bool operator==(const TimeSpan& Rhs) const { return Ticks == Rhs.Ticks; }
- inline auto operator<=>(const TimeSpan& Rhs) const { return Ticks - Rhs.Ticks; }
+ inline auto operator<=>(const TimeSpan& Rhs) const = default;
/**
* Time span related constants.
@@ -136,12 +141,33 @@ public:
ZENCORE_API std::string ToString(const char* Format) const;
ZENCORE_API std::string ToString() const;
+ friend inline DateTime operator+(const DateTime& Lhs, const TimeSpan& Rhs);
+ friend inline DateTime operator+(const TimeSpan& Lhs, const DateTime& Rhs);
+
private:
void Set(int Days, int Hours, int Minutes, int Seconds, int FractionNano);
uint64_t Ticks;
};
+inline TimeSpan
+operator-(const DateTime& Lhs, const DateTime& Rhs)
+{
+ return TimeSpan(Lhs.Ticks - Rhs.Ticks);
+}
+
+inline DateTime
+operator+(const DateTime& Lhs, const TimeSpan& Rhs)
+{
+ return DateTime(Lhs.Ticks + Rhs.Ticks);
+}
+
+inline DateTime
+operator+(const TimeSpan& Lhs, const DateTime& Rhs)
+{
+ return DateTime(Lhs.Ticks + Rhs.Ticks);
+}
+
//////////////////////////////////////////////////////////////////////////
/**
diff --git a/src/zenutil/cache/rpcrecording.cpp b/src/zenutil/cache/rpcrecording.cpp
index 054ac0e56..00cecb8f7 100644
--- a/src/zenutil/cache/rpcrecording.cpp
+++ b/src/zenutil/cache/rpcrecording.cpp
@@ -2,6 +2,7 @@
#include <zencore/compactbinarybuilder.h>
#include <zencore/filesystem.h>
+#include <zencore/fmtutils.h>
#include <zencore/logging.h>
#include <zencore/system.h>
#include <zenutil/basicfile.h>
@@ -264,7 +265,7 @@ struct RecordedRequest
static_assert(sizeof(RecordedRequest) == 24);
const uint64_t RecordedRequestBlockSize = 1 * 1024 * 1024 * 1024; // 1GiB
-const uint64_t StandaloneFileSizeThreshold = 1 * 1024 * 1024ull; // 1MiB
+const uint64_t StandaloneFileSizeThreshold = 16 * 1024 * 1024ull; // 16MiB
const uint64_t SegmentRequestCount = 10 * 1000 * 1000;
const uint64_t LooseFileThreshold = 5000; // Somewhat arbitrary, but we try to keep the
// number of files in a directory below this level
@@ -321,6 +322,7 @@ struct RecordedRequestsWriter
RecordedRequestsSegmentWriter& EnsureCurrentSegment();
void CommitCurrentSegment(RwLock::ExclusiveLockScope&);
void EndWrite();
+ void WriteRecordingMetadata();
uint64_t WriteRequest(const RecordedRequestInfo& RequestInfo, const IoBuffer& RequestBuffer);
private:
@@ -547,6 +549,7 @@ RecordedRequestsSegmentReader::BeginRead(const std::filesystem::path& BasePath,
}
return m_Entries.size();
}
+
void
RecordedRequestsSegmentReader::EndRead()
{
@@ -600,6 +603,8 @@ RecordedRequestsWriter::EnsureCurrentSegment()
{
bool StartNewSegment = false;
+ TimeSpan SegmentAge(DateTime::NowTicks() - m_CurrentWriter->GetStartTime().GetTicks());
+
if (m_CurrentWriter->GetRequestCount() >= SegmentRequestCount)
{
ZEN_DEBUG("starting new RPC recording segment due to request count >= {}", SegmentRequestCount);
@@ -615,6 +620,12 @@ RecordedRequestsWriter::EnsureCurrentSegment()
ZEN_DEBUG("starting new RPC recording segment due to footprint >= {} bytes", SegmentByteThreshold);
StartNewSegment = true;
}
+ else if (SegmentAge >= SegmentTimeThreshold)
+ {
+ ZEN_DEBUG("starting new RPC recording segment due to age >= {}",
+ NiceTimeSpanMs(SegmentTimeThreshold.GetTicks() / TimeSpan::TicksPerMillisecond));
+ StartNewSegment = true;
+ }
if (StartNewSegment)
{
@@ -654,8 +665,22 @@ RecordedRequestsWriter::EndWrite()
CommitCurrentSegment(_);
- // Emit some metadata alongside the recording
+ WriteRecordingMetadata();
+}
+uint64_t
+RecordedRequestsWriter::WriteRequest(const RecordedRequestInfo& RequestInfo, const IoBuffer& RequestBuffer)
+{
+ RecordedRequestsSegmentWriter& Writer = EnsureCurrentSegment();
+
+ const uint64_t SegmentLocalIndex = Writer.WriteRequest(RequestInfo, RequestBuffer);
+
+ return Writer.GetBaseRequestIndex() + SegmentLocalIndex;
+}
+
+void
+RecordedRequestsWriter::WriteRecordingMetadata()
+{
try
{
DateTime EndTime = DateTime::Now();
@@ -702,16 +727,6 @@ RecordedRequestsWriter::EndWrite()
}
}
-uint64_t
-RecordedRequestsWriter::WriteRequest(const RecordedRequestInfo& RequestInfo, const IoBuffer& RequestBuffer)
-{
- RecordedRequestsSegmentWriter& Writer = EnsureCurrentSegment();
-
- const uint64_t SegmentLocalIndex = Writer.WriteRequest(RequestInfo, RequestBuffer);
-
- return Writer.GetBaseRequestIndex() + SegmentLocalIndex;
-}
-
//////////////////////////////////////////////////////////////////////////
uint64_t