aboutsummaryrefslogtreecommitdiff
path: root/src/zenserver/projectstore/projectstore.cpp
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2023-11-27 09:38:06 -0500
committerGitHub <[email protected]>2023-11-27 15:38:06 +0100
commit765855296a28df198572d97207ac917f3d249014 (patch)
treeef0bd3be7997361206446c3885e93aa782b2681b /src/zenserver/projectstore/projectstore.cpp
parentoptimized index snapshot reading/writing (#561) (diff)
downloadzen-765855296a28df198572d97207ac917f3d249014.tar.xz
zen-765855296a28df198572d97207ac917f3d249014.zip
gcv2 tests for project store and bugfixes (#571)
* gcv2 tests for project store and bugfixes
Diffstat (limited to 'src/zenserver/projectstore/projectstore.cpp')
-rw-r--r--src/zenserver/projectstore/projectstore.cpp293
1 files changed, 209 insertions, 84 deletions
diff --git a/src/zenserver/projectstore/projectstore.cpp b/src/zenserver/projectstore/projectstore.cpp
index 200aba3a9..882d78c7e 100644
--- a/src/zenserver/projectstore/projectstore.cpp
+++ b/src/zenserver/projectstore/projectstore.cpp
@@ -1759,6 +1759,10 @@ ProjectStore::DiscoverProjects()
for (const std::filesystem::path& DirPath : DirContent.Directories)
{
std::string DirName = PathToUtf8(DirPath.filename());
+ if (DirName.starts_with("[dropped]"))
+ {
+ continue;
+ }
OpenProject(DirName);
}
}
@@ -3190,6 +3194,7 @@ ProjectStore::RemoveExpiredData(GcCtx& Ctx, GcStats& Stats)
RwLock::SharedLockScope Lock(m_ProjectsLock);
for (auto& Kv : m_Projects)
{
+ Stats.CheckedCount++;
if (Kv.second->IsExpired(Lock, Ctx.Settings.ProjectStoreExpireTime))
{
ExpiredProjects.push_back(Kv.second);
@@ -3212,7 +3217,6 @@ ProjectStore::RemoveExpiredData(GcCtx& Ctx, GcStats& Stats)
}
}
- size_t OplogCount = 0;
size_t ExpiredOplogCount = 0;
for (const Ref<Project>& Project : Projects)
{
@@ -3224,8 +3228,8 @@ ProjectStore::RemoveExpiredData(GcCtx& Ctx, GcStats& Stats)
std::vector<std::string> ExpiredOplogs;
{
Project->IterateOplogs(
- [&Ctx, &Project, &ExpiredOplogs, &OplogCount](const RwLock::SharedLockScope& Lock, ProjectStore::Oplog& Oplog) {
- OplogCount++;
+ [&Ctx, &Stats, &Project, &ExpiredOplogs](const RwLock::SharedLockScope& Lock, ProjectStore::Oplog& Oplog) {
+ Stats.CheckedCount++;
if (Project->IsExpired(Lock, Ctx.Settings.ProjectStoreExpireTime, Oplog))
{
ExpiredOplogs.push_back(Oplog.OplogId());
@@ -3248,9 +3252,6 @@ ProjectStore::RemoveExpiredData(GcCtx& Ctx, GcStats& Stats)
Project->Flush();
}
}
- size_t ProjectCount = Projects.size();
-
- Stats.CheckedCount += ProjectCount + OplogCount;
if (ExpiredProjects.empty() && ExpiredOplogCount == 0)
{
@@ -3628,11 +3629,17 @@ TEST_CASE("project.store.gc")
BasicFile ProjectFile;
ProjectFile.Open(Project2FilePath, BasicFile::Mode::kTruncate);
}
- std::filesystem::path Project2OplogPath = TempDir.Path() / "game1" / "saves" / "cooked" / ".projectstore";
+ std::filesystem::path Project2Oplog1Path = TempDir.Path() / "game1" / "saves" / "cooked" / ".projectstore";
+ {
+ CreateDirectories(Project2Oplog1Path.parent_path());
+ BasicFile OplogFile;
+ OplogFile.Open(Project2Oplog1Path, BasicFile::Mode::kTruncate);
+ }
+ std::filesystem::path Project2Oplog2Path = TempDir.Path() / "game2" / "saves" / "cooked" / ".projectstore";
{
- CreateDirectories(Project2OplogPath.parent_path());
+ CreateDirectories(Project2Oplog2Path.parent_path());
BasicFile OplogFile;
- OplogFile.Open(Project2OplogPath, BasicFile::Mode::kTruncate);
+ OplogFile.Open(Project2Oplog2Path, BasicFile::Mode::kTruncate);
}
{
@@ -3658,94 +3665,212 @@ TEST_CASE("project.store.gc")
EngineRootDir.string(),
Project2RootDir.string(),
Project2FilePath.string()));
- ProjectStore::Oplog* Oplog = Project2->NewOplog("oplog2", Project2OplogPath);
- CHECK(Oplog != nullptr);
+ {
+ ProjectStore::Oplog* Oplog = Project2->NewOplog("oplog2", Project2Oplog1Path);
+ CHECK(Oplog != nullptr);
- Oplog->AppendNewOplogEntry(CreateOplogPackage(Oid::NewOid(), {}));
- Oplog->AppendNewOplogEntry(CreateOplogPackage(Oid::NewOid(), CreateAttachments(std::initializer_list<size_t>{177})));
- Oplog->AppendNewOplogEntry(CreateOplogPackage(Oid::NewOid(), CreateAttachments(std::initializer_list<size_t>{9123, 383, 590, 96})));
- Oplog->AppendNewOplogEntry(CreateOplogPackage(Oid::NewOid(), CreateAttachments(std::initializer_list<size_t>{535, 221})));
- }
+ Oplog->AppendNewOplogEntry(CreateOplogPackage(Oid::NewOid(), {}));
+ Oplog->AppendNewOplogEntry(CreateOplogPackage(Oid::NewOid(), CreateAttachments(std::initializer_list<size_t>{177})));
+ Oplog->AppendNewOplogEntry(
+ CreateOplogPackage(Oid::NewOid(), CreateAttachments(std::initializer_list<size_t>{9123, 383, 590, 96})));
+ Oplog->AppendNewOplogEntry(CreateOplogPackage(Oid::NewOid(), CreateAttachments(std::initializer_list<size_t>{535, 221})));
+ }
+ {
+ ProjectStore::Oplog* Oplog = Project2->NewOplog("oplog3", Project2Oplog2Path);
+ CHECK(Oplog != nullptr);
- {
- GcContext GcCtx(GcClock::Now() - std::chrono::hours(24), GcClock::Now() - std::chrono::hours(24));
- ProjectStore.GatherReferences(GcCtx);
- size_t RefCount = 0;
- GcCtx.IterateCids([&RefCount](const IoHash&) { RefCount++; });
- CHECK(RefCount == 14);
- ProjectStore.CollectGarbage(GcCtx);
- CHECK(ProjectStore.OpenProject("proj1"sv));
- CHECK(ProjectStore.OpenProject("proj2"sv));
+ Oplog->AppendNewOplogEntry(CreateOplogPackage(Oid::NewOid(), {}));
+ Oplog->AppendNewOplogEntry(CreateOplogPackage(Oid::NewOid(), CreateAttachments(std::initializer_list<size_t>{137})));
+ Oplog->AppendNewOplogEntry(
+ CreateOplogPackage(Oid::NewOid(), CreateAttachments(std::initializer_list<size_t>{9723, 683, 594, 98})));
+ Oplog->AppendNewOplogEntry(CreateOplogPackage(Oid::NewOid(), CreateAttachments(std::initializer_list<size_t>{531, 271})));
+ }
}
+ SUBCASE("v1")
{
- GcContext GcCtx(GcClock::Now() + std::chrono::hours(24), GcClock::Now() + std::chrono::hours(24));
- ProjectStore.GatherReferences(GcCtx);
- size_t RefCount = 0;
- GcCtx.IterateCids([&RefCount](const IoHash&) { RefCount++; });
- CHECK(RefCount == 14);
- ProjectStore.CollectGarbage(GcCtx);
- CHECK(ProjectStore.OpenProject("proj1"sv));
- CHECK(ProjectStore.OpenProject("proj2"sv));
- }
+ {
+ GcContext GcCtx(GcClock::Now() - std::chrono::hours(24), GcClock::Now() - std::chrono::hours(24));
+ ProjectStore.GatherReferences(GcCtx);
+ size_t RefCount = 0;
+ GcCtx.IterateCids([&RefCount](const IoHash&) { RefCount++; });
+ CHECK(RefCount == 21);
+ ProjectStore.CollectGarbage(GcCtx);
+ CHECK(ProjectStore.OpenProject("proj1"sv));
+ CHECK(ProjectStore.OpenProject("proj2"sv));
+ }
- std::filesystem::remove(Project1FilePath);
+ {
+ GcContext GcCtx(GcClock::Now() + std::chrono::hours(24), GcClock::Now() + std::chrono::hours(24));
+ ProjectStore.GatherReferences(GcCtx);
+ size_t RefCount = 0;
+ GcCtx.IterateCids([&RefCount](const IoHash&) { RefCount++; });
+ CHECK(RefCount == 21);
+ ProjectStore.CollectGarbage(GcCtx);
+ CHECK(ProjectStore.OpenProject("proj1"sv));
+ CHECK(ProjectStore.OpenProject("proj2"sv));
+ }
- {
- GcContext GcCtx(GcClock::Now() - std::chrono::hours(24), GcClock::Now() - std::chrono::hours(24));
- ProjectStore.GatherReferences(GcCtx);
- size_t RefCount = 0;
- GcCtx.IterateCids([&RefCount](const IoHash&) { RefCount++; });
- CHECK(RefCount == 14);
- ProjectStore.CollectGarbage(GcCtx);
- CHECK(ProjectStore.OpenProject("proj1"sv));
- CHECK(ProjectStore.OpenProject("proj2"sv));
- }
+ std::filesystem::remove(Project1FilePath);
- {
- GcContext GcCtx(GcClock::Now() + std::chrono::hours(24), GcClock::Now() + std::chrono::hours(24));
- ProjectStore.GatherReferences(GcCtx);
- size_t RefCount = 0;
- GcCtx.IterateCids([&RefCount](const IoHash&) { RefCount++; });
- CHECK(RefCount == 7);
- ProjectStore.CollectGarbage(GcCtx);
- CHECK(!ProjectStore.OpenProject("proj1"sv));
- CHECK(ProjectStore.OpenProject("proj2"sv));
- }
+ {
+ GcContext GcCtx(GcClock::Now() - std::chrono::hours(24), GcClock::Now() - std::chrono::hours(24));
+ ProjectStore.GatherReferences(GcCtx);
+ size_t RefCount = 0;
+ GcCtx.IterateCids([&RefCount](const IoHash&) { RefCount++; });
+ CHECK(RefCount == 21);
+ ProjectStore.CollectGarbage(GcCtx);
+ CHECK(ProjectStore.OpenProject("proj1"sv));
+ CHECK(ProjectStore.OpenProject("proj2"sv));
+ }
- std::filesystem::remove(Project2OplogPath);
- {
- GcContext GcCtx(GcClock::Now() - std::chrono::hours(24), GcClock::Now() - std::chrono::hours(24));
- ProjectStore.GatherReferences(GcCtx);
- size_t RefCount = 0;
- GcCtx.IterateCids([&RefCount](const IoHash&) { RefCount++; });
- CHECK(RefCount == 7);
- ProjectStore.CollectGarbage(GcCtx);
- CHECK(!ProjectStore.OpenProject("proj1"sv));
- CHECK(ProjectStore.OpenProject("proj2"sv));
- }
+ {
+ GcContext GcCtx(GcClock::Now() + std::chrono::hours(24), GcClock::Now() + std::chrono::hours(24));
+ ProjectStore.GatherReferences(GcCtx);
+ size_t RefCount = 0;
+ GcCtx.IterateCids([&RefCount](const IoHash&) { RefCount++; });
+ CHECK(RefCount == 14);
+ ProjectStore.CollectGarbage(GcCtx);
+ CHECK(!ProjectStore.OpenProject("proj1"sv));
+ CHECK(ProjectStore.OpenProject("proj2"sv));
+ }
- {
- GcContext GcCtx(GcClock::Now() + std::chrono::hours(24), GcClock::Now() + std::chrono::hours(24));
- ProjectStore.GatherReferences(GcCtx);
- size_t RefCount = 0;
- GcCtx.IterateCids([&RefCount](const IoHash&) { RefCount++; });
- CHECK(RefCount == 0);
- ProjectStore.CollectGarbage(GcCtx);
- CHECK(!ProjectStore.OpenProject("proj1"sv));
- CHECK(ProjectStore.OpenProject("proj2"sv));
+ std::filesystem::remove(Project2Oplog1Path);
+ {
+ GcContext GcCtx(GcClock::Now() - std::chrono::hours(24), GcClock::Now() - std::chrono::hours(24));
+ ProjectStore.GatherReferences(GcCtx);
+ size_t RefCount = 0;
+ GcCtx.IterateCids([&RefCount](const IoHash&) { RefCount++; });
+ CHECK(RefCount == 14);
+ ProjectStore.CollectGarbage(GcCtx);
+ CHECK(!ProjectStore.OpenProject("proj1"sv));
+ CHECK(ProjectStore.OpenProject("proj2"sv));
+ }
+
+ {
+ GcContext GcCtx(GcClock::Now() + std::chrono::hours(24), GcClock::Now() + std::chrono::hours(24));
+ ProjectStore.GatherReferences(GcCtx);
+ size_t RefCount = 0;
+ GcCtx.IterateCids([&RefCount](const IoHash&) { RefCount++; });
+ CHECK(RefCount == 7);
+ ProjectStore.CollectGarbage(GcCtx);
+ CHECK(!ProjectStore.OpenProject("proj1"sv));
+ CHECK(ProjectStore.OpenProject("proj2"sv));
+ }
+
+ std::filesystem::remove(Project2FilePath);
+ {
+ GcContext GcCtx(GcClock::Now() + std::chrono::hours(24), GcClock::Now() + std::chrono::hours(24));
+ ProjectStore.GatherReferences(GcCtx);
+ size_t RefCount = 0;
+ GcCtx.IterateCids([&RefCount](const IoHash&) { RefCount++; });
+ CHECK(RefCount == 0);
+ ProjectStore.CollectGarbage(GcCtx);
+ CHECK(!ProjectStore.OpenProject("proj1"sv));
+ CHECK(!ProjectStore.OpenProject("proj2"sv));
+ }
}
- std::filesystem::remove(Project2FilePath);
+ SUBCASE("v2")
{
- GcContext GcCtx(GcClock::Now() + std::chrono::hours(24), GcClock::Now() + std::chrono::hours(24));
- ProjectStore.GatherReferences(GcCtx);
- size_t RefCount = 0;
- GcCtx.IterateCids([&RefCount](const IoHash&) { RefCount++; });
- CHECK(RefCount == 0);
- ProjectStore.CollectGarbage(GcCtx);
- CHECK(!ProjectStore.OpenProject("proj1"sv));
- CHECK(!ProjectStore.OpenProject("proj2"sv));
+ {
+ GcSettings Settings = {.CacheExpireTime = GcClock::Now() - std::chrono::hours(24),
+ .ProjectStoreExpireTime = GcClock::Now() - std::chrono::hours(24),
+ .IsDeleteMode = true};
+ GcResult Result = Gc.CollectGarbage(Settings);
+ CHECK_EQ(5u, Result.ReferencerStatSum.RemoveExpiredDataStats.CheckedCount);
+ CHECK_EQ(0u, Result.ReferencerStatSum.RemoveExpiredDataStats.DeletedCount);
+ CHECK_EQ(21u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.CheckedCount);
+ CHECK_EQ(0u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.DeletedCount);
+ CHECK(ProjectStore.OpenProject("proj1"sv));
+ CHECK(ProjectStore.OpenProject("proj2"sv));
+ }
+
+ {
+ GcSettings Settings = {.CacheExpireTime = GcClock::Now() + std::chrono::hours(24),
+ .ProjectStoreExpireTime = GcClock::Now() + std::chrono::hours(24),
+ .IsDeleteMode = true};
+ GcResult Result = Gc.CollectGarbage(Settings);
+ CHECK_EQ(5u, Result.ReferencerStatSum.RemoveExpiredDataStats.CheckedCount);
+ CHECK_EQ(0u, Result.ReferencerStatSum.RemoveExpiredDataStats.DeletedCount);
+ CHECK_EQ(21u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.CheckedCount);
+ CHECK_EQ(0u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.DeletedCount);
+ CHECK(ProjectStore.OpenProject("proj1"sv));
+ CHECK(ProjectStore.OpenProject("proj2"sv));
+ }
+
+ std::filesystem::remove(Project1FilePath);
+
+ {
+ GcSettings Settings = {.CacheExpireTime = GcClock::Now() - std::chrono::hours(24),
+ .ProjectStoreExpireTime = GcClock::Now() - std::chrono::hours(24),
+ .IsDeleteMode = true};
+ GcResult Result = Gc.CollectGarbage(Settings);
+ CHECK_EQ(5u, Result.ReferencerStatSum.RemoveExpiredDataStats.CheckedCount);
+ CHECK_EQ(0u, Result.ReferencerStatSum.RemoveExpiredDataStats.DeletedCount);
+ CHECK_EQ(21u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.CheckedCount);
+ CHECK_EQ(0u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.DeletedCount);
+ CHECK(ProjectStore.OpenProject("proj1"sv));
+ CHECK(ProjectStore.OpenProject("proj2"sv));
+ }
+
+ {
+ GcSettings Settings = {.CacheExpireTime = GcClock::Now() + std::chrono::hours(24),
+ .ProjectStoreExpireTime = GcClock::Now() + std::chrono::hours(24),
+ .CollectSmallObjects = true,
+ .IsDeleteMode = true};
+ GcResult Result = Gc.CollectGarbage(Settings);
+ CHECK_EQ(4u, Result.ReferencerStatSum.RemoveExpiredDataStats.CheckedCount);
+ CHECK_EQ(1u, Result.ReferencerStatSum.RemoveExpiredDataStats.DeletedCount);
+ CHECK_EQ(21u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.CheckedCount);
+ CHECK_EQ(7u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.DeletedCount);
+ CHECK(!ProjectStore.OpenProject("proj1"sv));
+ CHECK(ProjectStore.OpenProject("proj2"sv));
+ }
+
+ std::filesystem::remove(Project2Oplog1Path);
+ {
+ GcSettings Settings = {.CacheExpireTime = GcClock::Now() - std::chrono::hours(24),
+ .ProjectStoreExpireTime = GcClock::Now() - std::chrono::hours(24),
+ .CollectSmallObjects = true,
+ .IsDeleteMode = true};
+ GcResult Result = Gc.CollectGarbage(Settings);
+ CHECK_EQ(3u, Result.ReferencerStatSum.RemoveExpiredDataStats.CheckedCount);
+ CHECK_EQ(0u, Result.ReferencerStatSum.RemoveExpiredDataStats.DeletedCount);
+ CHECK_EQ(14u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.CheckedCount);
+ CHECK_EQ(0u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.DeletedCount);
+ CHECK(!ProjectStore.OpenProject("proj1"sv));
+ CHECK(ProjectStore.OpenProject("proj2"sv));
+ }
+
+ {
+ GcSettings Settings = {.CacheExpireTime = GcClock::Now() + std::chrono::hours(24),
+ .ProjectStoreExpireTime = GcClock::Now() + std::chrono::hours(24),
+ .CollectSmallObjects = true,
+ .IsDeleteMode = true};
+ GcResult Result = Gc.CollectGarbage(Settings);
+ CHECK_EQ(3u, Result.ReferencerStatSum.RemoveExpiredDataStats.CheckedCount);
+ CHECK_EQ(0u, Result.ReferencerStatSum.RemoveExpiredDataStats.DeletedCount);
+ CHECK_EQ(14u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.CheckedCount);
+ CHECK_EQ(0u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.DeletedCount);
+ CHECK(!ProjectStore.OpenProject("proj1"sv));
+ CHECK(ProjectStore.OpenProject("proj2"sv));
+ }
+
+ std::filesystem::remove(Project2FilePath);
+ {
+ GcSettings Settings = {.CacheExpireTime = GcClock::Now() + std::chrono::hours(24),
+ .ProjectStoreExpireTime = GcClock::Now() + std::chrono::hours(24),
+ .CollectSmallObjects = true,
+ .IsDeleteMode = true};
+ GcResult Result = Gc.CollectGarbage(Settings);
+ CHECK_EQ(1u, Result.ReferencerStatSum.RemoveExpiredDataStats.CheckedCount);
+ CHECK_EQ(1u, Result.ReferencerStatSum.RemoveExpiredDataStats.DeletedCount);
+ CHECK_EQ(14u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.CheckedCount);
+ CHECK_EQ(14u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.DeletedCount);
+ CHECK(!ProjectStore.OpenProject("proj1"sv));
+ CHECK(!ProjectStore.OpenProject("proj2"sv));
+ }
}
}