diff options
| author | Dan Engelbrecht <[email protected]> | 2025-09-04 12:46:35 +0200 |
|---|---|---|
| committer | GitHub Enterprise <[email protected]> | 2025-09-04 12:46:35 +0200 |
| commit | 8d135a1e2b426ed4e44bfff26be1ecdba8bca222 (patch) | |
| tree | 33bd1423f58927d919ddc6482c0ea2cb666dbabf /src | |
| parent | Merge pull request #485 from ue-foundation/zs/cfg-enable-overwrite-prevention (diff) | |
| download | zen-8d135a1e2b426ed4e44bfff26be1ecdba8bca222.tar.xz zen-8d135a1e2b426ed4e44bfff26be1ecdba8bca222.zip | |
oplog memory usage reduction (#482)
- Improvement: For projectstore oplog GET operation, only read basic information and release it if the oplog is not already open to reduce memory usage when listing oplogs in web UI
- Improvement: Reduce memory usage for oplog Op address lookup
Refactored Oplog::EState -> Oplog ::EMode and make sure we open data files in read-only mode when EMode::kBasicReadOnly is used.
Diffstat (limited to 'src')
| -rw-r--r-- | src/zenserver/projectstore/httpprojectstore.cpp | 4 | ||||
| -rw-r--r-- | src/zenserver/projectstore/projectstore.cpp | 259 | ||||
| -rw-r--r-- | src/zenserver/projectstore/projectstore.h | 31 | ||||
| -rw-r--r-- | src/zenstore/gc.cpp | 2 |
4 files changed, 197 insertions, 99 deletions
diff --git a/src/zenserver/projectstore/httpprojectstore.cpp b/src/zenserver/projectstore/httpprojectstore.cpp index cb12d7ce9..feeec3e37 100644 --- a/src/zenserver/projectstore/httpprojectstore.cpp +++ b/src/zenserver/projectstore/httpprojectstore.cpp @@ -1483,7 +1483,7 @@ HttpProjectService::HandleOpLogRequest(HttpRouterRequest& Req) { case HttpVerb::kGet: { - Ref<ProjectStore::Oplog> OplogIt = Project->OpenOplog(OplogId, /*AllowCompact*/ true, /*VerifyPathOnDisk*/ true); + Ref<ProjectStore::Oplog> OplogIt = Project->ReadOplog(OplogId); if (!OplogIt) { return HttpReq.WriteResponse(HttpResponseCode::NotFound, @@ -1491,8 +1491,6 @@ HttpProjectService::HandleOpLogRequest(HttpRouterRequest& Req) fmt::format("oplog {} not found in project {}", OplogId, ProjectId)); } - Project->TouchOplog(OplogId); - ProjectStore::Oplog& Log = *OplogIt; CbObjectWriter Cb; diff --git a/src/zenserver/projectstore/projectstore.cpp b/src/zenserver/projectstore/projectstore.cpp index 7d4953a8f..56b64cee4 100644 --- a/src/zenserver/projectstore/projectstore.cpp +++ b/src/zenserver/projectstore/projectstore.cpp @@ -7,6 +7,7 @@ #include <zencore/compactbinarypackage.h> #include <zencore/compactbinaryutil.h> #include <zencore/compactbinaryvalidation.h> +#include <zencore/except.h> #include <zencore/filesystem.h> #include <zencore/fmtutils.h> #include <zencore/jobqueue.h> @@ -492,7 +493,6 @@ struct ProjectStore::OplogStorage : public RefCounted m_OplogStoragePath); try { - Flush(); m_Oplog.Close(); m_OpBlobs.Close(); } @@ -545,12 +545,22 @@ struct ProjectStore::OplogStorage : public RefCounted m_NextOpsOffset = RoundUp((NextOpFileOffset.Offset * m_OpsAlign) + NextOpFileOffset.Size, m_OpsAlign); } - void Open(bool IsCreate) + enum EMode + { + Create, + Read, + Write + }; + + void Open(EMode InMode) { ZEN_MEMSCOPE(GetProjectstoreTag()); ZEN_TRACE_CPU("Store::OplogStorage::Open"); - if (IsCreate) + CasLogFile::Mode LogMode = CasLogFile::Mode::kRead; + BasicFile::Mode BlobsMode = BasicFile::Mode::kRead; + + if (InMode == EMode::Create) { ZEN_DEBUG("oplog '{}/{}': initializing storage at '{}'", m_OwnerOplog->GetOuterProjectIdentifier(), @@ -559,19 +569,31 @@ struct ProjectStore::OplogStorage : public RefCounted DeleteDirectories(m_OplogStoragePath); CreateDirectories(m_OplogStoragePath); + + LogMode = CasLogFile::Mode::kTruncate; + BlobsMode = BasicFile::Mode::kTruncate; } - else + else if (InMode == EMode::Write) { + LogMode = CasLogFile::Mode::kWrite; + BlobsMode = BasicFile::Mode::kWrite; ZEN_DEBUG("oplog '{}/{}': opening storage at '{}'", m_OwnerOplog->GetOuterProjectIdentifier(), m_OwnerOplog->OplogId(), m_OplogStoragePath); } + else if (InMode == EMode::Read) + { + ZEN_DEBUG("oplog '{}/{}': opening read only storage at '{}'", + m_OwnerOplog->GetOuterProjectIdentifier(), + m_OwnerOplog->OplogId(), + m_OplogStoragePath); + } - m_Oplog.Open(GetLogPath(m_OplogStoragePath), IsCreate ? CasLogFile::Mode::kTruncate : CasLogFile::Mode::kWrite); + m_Oplog.Open(GetLogPath(m_OplogStoragePath), LogMode); m_Oplog.Initialize(); - m_OpBlobs.Open(GetBlobsPath(m_OplogStoragePath), IsCreate ? BasicFile::Mode::kTruncate : BasicFile::Mode::kWrite); + m_OpBlobs.Open(GetBlobsPath(m_OplogStoragePath), BlobsMode); ZEN_ASSERT(IsPow2(m_OpsAlign)); ZEN_ASSERT(!(m_NextOpsOffset & (m_OpsAlign - 1))); @@ -799,6 +821,10 @@ struct ProjectStore::OplogStorage : public RefCounted { tsl::robin_map<Oid, size_t, Oid::Hasher> LatestKeys; + if (m_Oplog.GetLogCount() > SkipEntryCount) + { + LatestKeys.reserve(m_Oplog.GetLogCount() - SkipEntryCount); + } m_Oplog.Replay( [&](const OplogEntry& LogEntry) { @@ -1125,13 +1151,17 @@ ProjectStore::Oplog::Oplog(const LoggerRef& InLog, std::string_view Id, CidStore& Store, const std::filesystem::path& BasePath, - const std::filesystem::path& MarkerPath) + const std::filesystem::path& MarkerPath, + EMode State) : m_Log(InLog) , m_OuterProjectId(ProjectIdentifier) , m_OplogId(Id) , m_CidStore(Store) , m_BasePath(BasePath) , m_MarkerPath(MarkerPath) +, m_TempPath(m_BasePath / std::string_view("temp")) +, m_MetaPath(m_BasePath / std::string_view("ops.meta")) +, m_Mode(State) , m_MetaValid(false) , m_PendingPrepOpAttachmentsRetainEnd(GcClock::Now()) { @@ -1139,21 +1169,32 @@ ProjectStore::Oplog::Oplog(const LoggerRef& InLog, using namespace std::literals; - m_Storage = new OplogStorage(this, m_BasePath); - bool StoreExists = m_Storage->Exists(); - if (StoreExists) + m_Storage = new OplogStorage(this, m_BasePath); + OplogStorage::EMode StorageMode = OplogStorage::EMode::Write; + if (m_Mode == EMode::kBasicReadOnly) { - if (!m_Storage->IsValid()) + StorageMode = OplogStorage::EMode::Read; + } + else + { + bool StoreExists = m_Storage->Exists(); + if (StoreExists) { - ZEN_WARN("Invalid oplog found at '{}'. Wiping state for oplog.", m_BasePath); - m_Storage->WipeState(); - std::error_code DummyEc; - RemoveFile(m_MetaPath, DummyEc); + if (!m_Storage->IsValid()) + { + ZEN_WARN("Invalid oplog found at '{}'. Wiping state for oplog.", m_BasePath); + m_Storage->WipeState(); + std::error_code DummyEc; + RemoveFile(m_MetaPath, DummyEc); + StoreExists = false; + } + } + if (!StoreExists) + { + StorageMode = OplogStorage::EMode::Create; } } - m_Storage->Open(/* IsCreate */ !StoreExists); - m_TempPath = m_BasePath / "temp"sv; - m_MetaPath = m_BasePath / "ops.meta"sv; + m_Storage->Open(StorageMode); m_MetaValid = !IsFileOlderThan(m_MetaPath, m_Storage->GetBlobsPath()); CleanDirectory(m_TempPath, /*ForceRemoveReadOnlyFiles*/ false); @@ -1174,21 +1215,24 @@ ProjectStore::Oplog::Flush() ZEN_TRACE_CPU("Oplog::Flush"); - RwLock::SharedLockScope Lock(m_OplogLock); + if (m_Mode == EMode::kFull) + { + RwLock::SharedLockScope Lock(m_OplogLock); - ZEN_ASSERT(m_Storage); + ZEN_ASSERT(m_Storage); - m_Storage->Flush(); - if (!m_MetaValid) - { - std::error_code DummyEc; - RemoveFile(m_MetaPath, DummyEc); - } + m_Storage->Flush(); + if (!m_MetaValid) + { + std::error_code DummyEc; + RemoveFile(m_MetaPath, DummyEc); + } - uint64_t LogCount = m_Storage->LogCount(); - if (m_LogFlushPosition != LogCount) - { - WriteIndexSnapshot(); + uint64_t LogCount = m_Storage->LogCount(); + if (m_LogFlushPosition != LogCount) + { + WriteIndexSnapshot(); + } } } @@ -1197,6 +1241,8 @@ ProjectStore::Oplog::Scrub(ScrubContext& Ctx) { ZEN_MEMSCOPE(GetProjectstoreTag()); + ZEN_ASSERT(m_Mode == EMode::kFull); + std::vector<Oid> BadEntryKeys; using namespace std::literals; @@ -1353,11 +1399,9 @@ ProjectStore::Oplog::Exists() const } void -ProjectStore::Oplog::Read(EState State) +ProjectStore::Oplog::Read() { ZEN_MEMSCOPE(GetProjectstoreTag()); - ZEN_ASSERT(m_State == EState::kUnread); - ZEN_ASSERT(State != EState::kUnread); using namespace std::literals; ZEN_TRACE_CPU("Oplog::Read"); @@ -1367,9 +1411,7 @@ ProjectStore::Oplog::Read(EState State) m_OuterProjectId, m_OplogId, m_BasePath, - State == EState::kFull ? "Full" : "BasicNoLookups"); - - m_State = State; + m_Mode == EMode::kFull ? "Full" : "BasicNoLookups"); std::optional<CbObject> Config = ReadStateFile(m_BasePath, [this]() { return Log(); }); if (Config.has_value()) @@ -1388,9 +1430,9 @@ ProjectStore::Oplog::Read(EState State) RemoveFile(m_MetaPath, DummyEc); } - ReadIndexSnapshot(m_State); + ReadIndexSnapshot(); - if (m_State == EState::kFull) + if (m_Mode == EMode::kFull) { m_Storage->ReplayLog( [&](CbObjectView Op, const OplogEntry& OpEntry) { @@ -1444,9 +1486,7 @@ void ProjectStore::Oplog::Write() { ZEN_MEMSCOPE(GetProjectstoreTag()); - ZEN_ASSERT(m_State != EState::kBasicNoLookups); - - m_State = EState::kFull; + ZEN_ASSERT(m_Mode != EMode::kBasicReadOnly); using namespace std::literals; @@ -1479,7 +1519,7 @@ bool ProjectStore::Oplog::Reset() { ZEN_MEMSCOPE(GetProjectstoreTag()); - + ZEN_ASSERT(m_Mode == EMode::kFull); std::filesystem::path MovedDir; { @@ -1489,7 +1529,7 @@ ProjectStore::Oplog::Reset() { m_Storage = new OplogStorage(this, m_BasePath); const bool StoreExists = m_Storage->Exists(); - m_Storage->Open(/* IsCreate */ !StoreExists); + m_Storage->Open(StoreExists ? OplogStorage::EMode::Write : OplogStorage::EMode::Create); m_MetaValid = !IsFileOlderThan(m_MetaPath, m_Storage->GetBlobsPath()); return false; } @@ -1499,7 +1539,7 @@ ProjectStore::Oplog::Reset() m_OpAddressMap.clear(); m_LatestOpMap.clear(); m_Storage = new OplogStorage(this, m_BasePath); - m_Storage->Open(true); + m_Storage->Open(OplogStorage::EMode::Create); m_MetaValid = false; CleanDirectory(m_TempPath, /*ForceRemoveReadOnlyFiles*/ false); Write(); @@ -1715,7 +1755,7 @@ ProjectStore::Oplog::WriteIndexSnapshot() ZEN_MEMSCOPE(GetProjectstoreTag()); ZEN_TRACE_CPU("Oplog::WriteIndexSnapshot"); - ZEN_ASSERT(m_State == EState::kFull); + ZEN_ASSERT(m_Mode == EMode::kFull); ZEN_DEBUG("oplog '{}/{}': write store snapshot at '{}'", m_OuterProjectId, m_OplogId, m_BasePath); uint64_t EntryCount = 0; @@ -1863,7 +1903,7 @@ ProjectStore::Oplog::WriteIndexSnapshot() } void -ProjectStore::Oplog::ReadIndexSnapshot(EState State) +ProjectStore::Oplog::ReadIndexSnapshot() { ZEN_MEMSCOPE(GetProjectstoreTag()); ZEN_TRACE_CPU("Oplog::ReadIndexSnapshot"); @@ -1959,11 +1999,15 @@ ProjectStore::Oplog::ReadIndexSnapshot(EState State) m_LatestOpMap.reserve(LatestOpMapEntries.size()); for (uint32_t LSN : LatestOpMapEntries) { + if (!m_OpAddressMap.contains(LSN)) + { + throw std::runtime_error(fmt::format("LSN {} is no present in Op address map", LSN)); + } m_LatestOpMap.insert_or_assign(Keys[KeyOffset++], LSN); MaxLSN = Max(MaxLSN, LSN); } } - if (State == EState::kFull) + if (m_Mode == EMode::kFull) { { std::vector<IoHash> ChunkMapEntries(Header.ChunkMapCount); @@ -2000,7 +2044,7 @@ ProjectStore::Oplog::ReadIndexSnapshot(EState State) MemoryView StringData = IndexFile.MakeView(Length, Offset); if (StringData.GetSize() != Length) { - throw std::runtime_error(fmt::format("Invalid format. Expected to read %u bytes but got %u", + throw std::runtime_error(fmt::format("Invalid format. Expected to read {} bytes but got {}", Length, uint32_t(StringData.GetSize()))); } @@ -2094,7 +2138,7 @@ ProjectStore::Oplog::Compact(bool DryRun, bool RetainLSNs, std::string_view LogP void ProjectStore::Oplog::Compact(RwLock::ExclusiveLockScope&, bool DryRun, bool RetainLSNs, std::string_view LogPrefix) { - ZEN_ASSERT(m_State == EState::kFull); + ZEN_ASSERT(m_Mode == EMode::kFull); ZEN_MEMSCOPE(GetProjectstoreTag()); @@ -2143,7 +2187,7 @@ ProjectStore::Oplog::Compact(RwLock::ExclusiveLockScope&, bool DryRun, bool Reta IoBuffer ProjectStore::Oplog::GetChunkByRawHash(const IoHash& RawHash) { - ZEN_ASSERT(m_State == EState::kFull); + ZEN_ASSERT(m_Mode == EMode::kFull); return m_CidStore.FindChunkByCid(RawHash); } @@ -2154,7 +2198,7 @@ ProjectStore::Oplog::IterateChunks(std::span<IoHash> RawHashes, WorkerThreadPool* OptionalWorkerPool, uint64_t LargeSizeLimit) { - ZEN_ASSERT(m_State == EState::kFull); + ZEN_ASSERT(m_Mode == EMode::kFull); return m_CidStore.IterateChunks( RawHashes, [&](size_t Index, const IoBuffer& Payload) { @@ -2172,7 +2216,7 @@ ProjectStore::Oplog::IterateChunks(const std::filesystem::path& P WorkerThreadPool* OptionalWorkerPool, uint64_t LargeSizeLimit) { - ZEN_ASSERT(m_State == EState::kFull); + ZEN_ASSERT(m_Mode == EMode::kFull); ZEN_MEMSCOPE(GetProjectstoreTag()); std::vector<size_t> CidChunkIndexes; @@ -2314,7 +2358,7 @@ ProjectStore::Oplog::IterateChunks(const std::filesystem::path& P IoBuffer ProjectStore::Oplog::FindChunk(const std::filesystem::path& ProjectRootDir, const Oid& ChunkId, uint64_t* OptOutModificationTag) { - ZEN_ASSERT(m_State == EState::kFull); + ZEN_ASSERT(m_Mode == EMode::kFull); RwLock::SharedLockScope OplogLock(m_OplogLock); if (!m_Storage) @@ -2372,7 +2416,7 @@ ProjectStore::Oplog::FindChunk(const std::filesystem::path& ProjectRootDir, cons std::vector<ProjectStore::Oplog::ChunkInfo> ProjectStore::Oplog::GetAllChunksInfo(const std::filesystem::path& ProjectRootDir) { - ZEN_ASSERT(m_State == EState::kFull); + ZEN_ASSERT(m_Mode == EMode::kFull); ZEN_MEMSCOPE(GetProjectstoreTag()); @@ -2415,7 +2459,7 @@ ProjectStore::Oplog::GetAllChunksInfo(const std::filesystem::path& ProjectRootDi void ProjectStore::Oplog::IterateChunkMap(std::function<void(const Oid&, const IoHash&)>&& Fn) { - ZEN_ASSERT(m_State == EState::kFull); + ZEN_ASSERT(m_Mode == EMode::kFull); RwLock::SharedLockScope _(m_OplogLock); if (!m_Storage) @@ -2433,7 +2477,7 @@ void ProjectStore::Oplog::IterateFileMap( std::function<void(const Oid&, const std::string_view& ServerPath, const std::string_view& ClientPath)>&& Fn) { - ZEN_ASSERT(m_State == EState::kFull); + ZEN_ASSERT(m_Mode == EMode::kFull); RwLock::SharedLockScope _(m_OplogLock); if (!m_Storage) @@ -3036,7 +3080,7 @@ ProjectStore::Oplog::RegisterOplogEntry(RwLock::ExclusiveLockScope& OplogLock, uint32_t ProjectStore::Oplog::AppendNewOplogEntry(CbPackage OpPackage) { - ZEN_ASSERT(m_State == EState::kFull); + ZEN_ASSERT(m_Mode == EMode::kFull); ZEN_MEMSCOPE(GetProjectstoreTag()); ZEN_TRACE_CPU("Store::Oplog::AppendNewOplogEntry"); @@ -3108,7 +3152,7 @@ ProjectStore::Oplog::GetStorage() uint32_t ProjectStore::Oplog::AppendNewOplogEntry(CbObjectView Core) { - ZEN_ASSERT(m_State == EState::kFull); + ZEN_ASSERT(m_Mode == EMode::kFull); ZEN_MEMSCOPE(GetProjectstoreTag()); ZEN_TRACE_CPU("Store::Oplog::AppendNewOplogEntry"); @@ -3140,7 +3184,7 @@ ProjectStore::Oplog::AppendNewOplogEntry(CbObjectView Core) std::vector<uint32_t> ProjectStore::Oplog::AppendNewOplogEntries(std::span<CbObjectView> Cores) { - ZEN_ASSERT(m_State == EState::kFull); + ZEN_ASSERT(m_Mode == EMode::kFull); ZEN_MEMSCOPE(GetProjectstoreTag()); ZEN_TRACE_CPU("Store::Oplog::AppendNewOplogEntries"); @@ -3411,7 +3455,7 @@ ProjectStore::Project::NewOplog(std::string_view OplogId, const std::filesystem: { Stopwatch Timer; - Ref<Oplog> NewLog(new Oplog(Log(), Identifier, OplogId, m_CidStore, OplogBasePath, MarkerPath)); + Ref<Oplog> NewLog(new Oplog(Log(), Identifier, OplogId, m_CidStore, OplogBasePath, MarkerPath, Oplog::EMode::kFull)); m_Oplogs.insert_or_assign(std::string{OplogId}, NewLog); NewLog->Write(); @@ -3442,6 +3486,50 @@ ProjectStore::Project::NewOplog(std::string_view OplogId, const std::filesystem: } Ref<ProjectStore::Oplog> +ProjectStore::Project::ReadOplog(std::string_view OplogId) +{ + ZEN_MEMSCOPE(GetProjectstoreTag()); + ZEN_TRACE_CPU("Store::OpenOplog"); + + std::filesystem::path OplogBasePath = BasePathForOplog(OplogId); + + RwLock::SharedLockScope Lock(m_ProjectLock); + + if (auto It = m_Oplogs.find(std::string{OplogId}); It != m_Oplogs.end()) + { + if (Oplog::ExistsAt(OplogBasePath)) + { + return It->second; + } + else + { + return {}; + } + } + + if (Oplog::ExistsAt(OplogBasePath)) + { + Stopwatch Timer; + + Ref<Oplog> ExistingLog(new Oplog(m_ProjectStore->Log(), + Identifier, + OplogId, + m_CidStore, + OplogBasePath, + std::filesystem::path{}, + Oplog::EMode::kBasicReadOnly)); + + ExistingLog->Read(); + Lock.ReleaseNow(); + + ZEN_INFO("oplog '{}/{}': read oplog at '{}' in {}", Identifier, OplogId, OplogBasePath, NiceTimeSpanMs(Timer.GetElapsedTimeMs())); + + return ExistingLog; + } + return {}; +} + +Ref<ProjectStore::Oplog> ProjectStore::Project::OpenOplog(std::string_view OplogId, bool AllowCompact, bool VerifyPathOnDisk) { ZEN_MEMSCOPE(GetProjectstoreTag()); @@ -3494,11 +3582,16 @@ ProjectStore::Project::OpenOplog(std::string_view OplogId, bool AllowCompact, bo { Stopwatch Timer; - Ref<Oplog> ExistingLog( - new Oplog(m_ProjectStore->Log(), Identifier, OplogId, m_CidStore, OplogBasePath, std::filesystem::path{})); + Ref<Oplog> ExistingLog(new Oplog(m_ProjectStore->Log(), + Identifier, + OplogId, + m_CidStore, + OplogBasePath, + std::filesystem::path{}, + Oplog::EMode::kFull)); m_Oplogs.insert_or_assign(std::string{OplogId}, ExistingLog); - ExistingLog->Read(Oplog::EState::kFull); + ExistingLog->Read(); Lock.ReleaseNow(); ZEN_INFO("oplog '{}/{}': opened oplog at '{}' in {}", @@ -6114,17 +6207,18 @@ public: { Stopwatch OplogTimer; std::filesystem::path OplogBasePath = Project->BasePathForOplog(OplogId); - OpLog = new ProjectStore::Oplog(Project->Log(), - Project->Identifier, - OplogId, - Project->m_CidStore, - OplogBasePath, - std::filesystem::path{}); - OpLog->Read( - ProjectStore::Oplog::EState::kFull); // We need it to be a full read so we can write a new index snapshot + OpLog = new ProjectStore::Oplog( + Project->Log(), + Project->Identifier, + OplogId, + Project->m_CidStore, + OplogBasePath, + std::filesystem::path{}, + ProjectStore::Oplog::EMode::kFull); // We need it to be a full read so we can write a new index snapshot + OpLog->Read(); if (Ctx.Settings.Verbose) { - ZEN_INFO("GCV2: projectstore [COMPACT] '{}': opened oplog '{}/{}' at '{}' in {}", + ZEN_INFO("GCV2: projectstore [COMPACT] '{}': read oplog '{}/{}' at '{}' in {}", m_BasePath, Project->Identifier, OplogId, @@ -6512,11 +6606,12 @@ public: m_OplogId, m_Project->m_CidStore, m_OplogBasePath, - std::filesystem::path{}); - Oplog->Read(ProjectStore::Oplog::EState::kBasicNoLookups); + std::filesystem::path{}, + ProjectStore::Oplog::EMode::kBasicReadOnly); + Oplog->Read(); if (Ctx.Settings.Verbose) { - ZEN_INFO("GCV2: projectstore [PRECACHE] '{}': opened oplog '{}/{}' in {}", + ZEN_INFO("GCV2: projectstore [PRECACHE] '{}': read oplog '{}/{}' in {}", m_OplogBasePath, m_Project->Identifier, m_OplogId, @@ -6593,11 +6688,12 @@ public: m_OplogId, m_Project->m_CidStore, m_OplogBasePath, - std::filesystem::path{})); - Oplog->Read(ProjectStore::Oplog::EState::kBasicNoLookups); + std::filesystem::path{}, + ProjectStore::Oplog::EMode::kBasicReadOnly)); + Oplog->Read(); if (Ctx.Settings.Verbose) { - ZEN_INFO("GCV2: projectstore [LOCKSTATE] '{}': opened oplog '{}/{}' in {}", + ZEN_INFO("GCV2: projectstore [LOCKSTATE] '{}': read oplog '{}/{}' in {}", m_OplogBasePath, m_Project->Identifier, m_OplogId, @@ -6802,11 +6898,12 @@ public: m_OplogId, Project->m_CidStore, OplogBasePath, - std::filesystem::path{})); - Oplog->Read(ProjectStore::Oplog::EState::kBasicNoLookups); + std::filesystem::path{}, + ProjectStore::Oplog::EMode::kBasicReadOnly)); + Oplog->Read(); if (Ctx.Settings.Verbose) { - ZEN_INFO("GCV2: projectstore [VALIDATE] '{}': opened oplog '{}/{}' in {}", + ZEN_INFO("GCV2: projectstore [VALIDATE] '{}': read oplog '{}/{}' in {}", OplogBasePath, Project->Identifier, m_OplogId, diff --git a/src/zenserver/projectstore/projectstore.h b/src/zenserver/projectstore/projectstore.h index 028ad0c6d..9f7de82b6 100644 --- a/src/zenserver/projectstore/projectstore.h +++ b/src/zenserver/projectstore/projectstore.h @@ -41,8 +41,8 @@ struct OplogEntry struct OplogEntryAddress { - uint64_t Offset; - uint64_t Size; + uint32_t Offset; // note: Multiple of m_OpsAlign! + uint32_t Size; }; static_assert(IsPow2(sizeof(OplogEntry))); @@ -80,25 +80,25 @@ public: struct Oplog : public RefCounted { + enum class EMode + { + kBasicReadOnly, + kFull + }; + Oplog(const LoggerRef& Log, std::string_view ProjectIdentifier, std::string_view Id, CidStore& Store, const std::filesystem::path& BasePath, - const std::filesystem::path& MarkerPath); + const std::filesystem::path& MarkerPath, + EMode State); ~Oplog(); [[nodiscard]] static bool ExistsAt(const std::filesystem::path& BasePath); bool Exists() const; - enum class EState - { - kUnread, - kBasicNoLookups, - kFull - }; - - void Read(EState State); + void Read(); void Write(); void Update(const std::filesystem::path& MarkerPath); bool Reset(); @@ -250,10 +250,10 @@ public: CidStore& m_CidStore; const std::filesystem::path m_BasePath; std::filesystem::path m_MarkerPath; - std::filesystem::path m_TempPath; - std::filesystem::path m_MetaPath; + const std::filesystem::path m_TempPath; + const std::filesystem::path m_MetaPath; - EState m_State = EState::kUnread; + const EMode m_Mode; mutable RwLock m_OplogLock; OidMap<IoHash> m_ChunkMap; // output data chunk id -> CAS address @@ -279,7 +279,7 @@ public: */ uint32_t GetUnusedSpacePercentLocked() const; void WriteIndexSnapshot(); - void ReadIndexSnapshot(EState ReadMode); + void ReadIndexSnapshot(); struct OplogEntryMapping { @@ -323,6 +323,7 @@ public: Ref<Oplog> NewOplog(std::string_view OplogId, const std::filesystem::path& MarkerPath); Ref<Oplog> OpenOplog(std::string_view OplogId, bool AllowCompact, bool VerifyPathOnDisk); + Ref<Oplog> ReadOplog(std::string_view OplogId); bool TryUnloadOplog(std::string_view OplogId); bool DeleteOplog(std::string_view OplogId); bool RemoveOplog(std::string_view OplogId, std::filesystem::path& OutDeletePath); diff --git a/src/zenstore/gc.cpp b/src/zenstore/gc.cpp index a7ef401d5..5023695b2 100644 --- a/src/zenstore/gc.cpp +++ b/src/zenstore/gc.cpp @@ -543,6 +543,8 @@ FilterReferences(GcCtx& Ctx, std::string_view Context, std::vector<IoHash>& InOu return false; } + auto Log = [&Ctx]() { return Ctx.Logger; }; + const bool Filter = Ctx.Settings.AttachmentRangeMax != IoHash::Max || Ctx.Settings.AttachmentRangeMin != IoHash::Zero; size_t TotalCount = InOutReferences.size(); |