diff options
| author | Stefan Boberg <[email protected]> | 2021-09-19 19:30:16 +0200 |
|---|---|---|
| committer | Stefan Boberg <[email protected]> | 2021-09-19 19:30:16 +0200 |
| commit | 8f82467ea5e8e90e459d78d603c67a7938ae8ead (patch) | |
| tree | a7d1a3e2d897e9a53e075485c437c440f3684ce2 /zenstore/CAS.cpp | |
| parent | Added zenstore.h and made headers use it (diff) | |
| download | zen-8f82467ea5e8e90e459d78d603c67a7938ae8ead.tar.xz zen-8f82467ea5e8e90e459d78d603c67a7938ae8ead.zip | |
Changed some code over from ATL to BasicFile and added Scrub() stubs.
Diffstat (limited to 'zenstore/CAS.cpp')
| -rw-r--r-- | zenstore/CAS.cpp | 85 |
1 files changed, 62 insertions, 23 deletions
diff --git a/zenstore/CAS.cpp b/zenstore/CAS.cpp index e77c0ed64..af0fcc609 100644 --- a/zenstore/CAS.cpp +++ b/zenstore/CAS.cpp @@ -11,6 +11,7 @@ #include <zencore/logging.h> #include <zencore/memory.h> #include <zencore/string.h> +#include <zencore/testutils.h> #include <zencore/thread.h> #include <zencore/uid.h> @@ -20,15 +21,17 @@ #include <functional> #include <unordered_map> -struct IUnknown; // Workaround for "combaseapi.h(229): error C2187: syntax error: 'identifier' was unexpected here" when using /permissive- -#include <atlfile.h> - ////////////////////////////////////////////////////////////////////////// namespace zen { /** - * Slightly less naive CAS store + * CAS store implementation + * + * Uses a basic strategy of splitting payloads by size, to improve ability to reclaim space + * quickly for unused large chunks and to maintain locality for small chunks which are + * frequently accessed together. + * */ class CasImpl : public CasStore { @@ -41,10 +44,9 @@ public: virtual IoBuffer FindChunk(const IoHash& ChunkHash) override; virtual void FilterChunks(CasChunkSet& InOutChunks) override; virtual void Flush() override; + virtual void Scrub() override; private: - void PickDefaultDirectory(); - CasContainerStrategy m_TinyStrategy; CasContainerStrategy m_SmallStrategy; FileCasStrategy m_LargeStrategy; @@ -63,13 +65,16 @@ CasImpl::Initialize(const CasStoreConfiguration& InConfig) { m_Config = InConfig; - ZEN_INFO("initializing CAS pool at {}", m_Config.RootDirectory); + ZEN_INFO("initializing CAS pool at '{}'", m_Config.RootDirectory); // Ensure root directory exists - create if it doesn't exist already std::filesystem::create_directories(m_Config.RootDirectory); // Open or create manifest + // + // The manifest is not currently fully implemented. The goal is to + // use it for recovery and configuration bool IsNewStore = false; @@ -77,23 +82,22 @@ CasImpl::Initialize(const CasStoreConfiguration& InConfig) std::filesystem::path ManifestPath = m_Config.RootDirectory; ManifestPath /= ".ucas_root"; - CAtlFile marker; - HRESULT hRes = marker.Create(ManifestPath.c_str(), GENERIC_READ, 0, OPEN_EXISTING); + std::error_code Ec; + BasicFile Marker; + Marker.Open(ManifestPath.c_str(), /* IsCreate */ false, Ec); - if (FAILED(hRes)) + if (Ec) { IsNewStore = true; ExtendableStringBuilder<128> manifest; - manifest.Append("#CAS_ROOT\n"); // TODO: should write something meaningful here + manifest.Append("#CAS_ROOT\n"); manifest.Append("ID="); zen::Oid id = zen::Oid::NewOid(); id.ToString(manifest); - hRes = marker.Create(ManifestPath.c_str(), GENERIC_WRITE, 0, CREATE_ALWAYS); - - if (SUCCEEDED(hRes)) - marker.Write(manifest.c_str(), (DWORD)manifest.Size()); + Marker.Open(ManifestPath.c_str(), /* IsCreate */ true); + Marker.Write(manifest.c_str(), (DWORD)manifest.Size(), 0); } } @@ -160,6 +164,14 @@ CasImpl::Flush() m_LargeStrategy.Flush(); } +void +CasImpl::Scrub() +{ + m_SmallStrategy.Scrub(); + m_TinyStrategy.Scrub(); + m_LargeStrategy.Scrub(); +} + ////////////////////////////////////////////////////////////////////////// CasStore* @@ -173,18 +185,45 @@ CreateCasStore() // Testing related code follows... // -void -CAS_forcelink() -{ -} - TEST_CASE("CasStore") { + ScopedTemporaryDirectory TempDir; + zen::CasStoreConfiguration config; - config.RootDirectory = "c:\\temp\\test"; + config.RootDirectory = TempDir.Path(); + + std::unique_ptr<zen::CasStore> Store{CreateCasStore()}; + Store->Initialize(config); + Store->Scrub(); + + IoBuffer Value1{16}; + memcpy(Value1.MutableData(), "1234567890123456", 16); + IoHash Hash1 = IoHash::HashBuffer(Value1.Data(), Value1.Size()); + CasStore::InsertResult Result1 = Store->InsertChunk(Value1, Hash1); + CHECK(Result1.New); + + IoBuffer Value2{16}; + memcpy(Value2.MutableData(), "ABCDEFGHIJKLMNOP", 16); + IoHash Hash2 = IoHash::HashBuffer(Value2.Data(), Value2.Size()); + CasStore::InsertResult Result2 = Store->InsertChunk(Value2, Hash2); + CHECK(Result2.New); + + CasChunkSet ChunkSet; + ChunkSet.AddChunk(Hash1); + ChunkSet.AddChunk(Hash2); + + Store->FilterChunks(ChunkSet); + CHECK(ChunkSet.GetChunkSet().size() == 0); + + IoBuffer Lookup1 = Store->FindChunk(Hash1); + CHECK(Lookup1); + IoBuffer Lookup2 = Store->FindChunk(Hash2); + CHECK(Lookup2); +} - std::unique_ptr<zen::CasStore> store{CreateCasStore()}; - store->Initialize(config); +void +CAS_forcelink() +{ } } // namespace zen |