From 5592bb717beb7afa43a232a13e78d2c62a794fb1 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Sat, 27 Sep 2025 16:30:36 -0400 Subject: [PATCH] Implement realisation operations on dummy store --- src/libstore-tests/dummy-store.cc | 15 +++++++++++++-- src/libstore/dummy-store.cc | 19 ++++++++++++++++--- .../include/nix/store/dummy-store-impl.hh | 12 ++++++++++++ src/libstore/include/nix/store/dummy-store.hh | 2 ++ src/libutil/include/nix/util/hash.hh | 19 +++++++++++++++++++ 5 files changed, 62 insertions(+), 5 deletions(-) diff --git a/src/libstore-tests/dummy-store.cc b/src/libstore-tests/dummy-store.cc index b841d7890..3dd8137a3 100644 --- a/src/libstore-tests/dummy-store.cc +++ b/src/libstore-tests/dummy-store.cc @@ -1,6 +1,6 @@ #include -#include "nix/store/dummy-store.hh" +#include "nix/store/dummy-store-impl.hh" #include "nix/store/globals.hh" #include "nix/store/realisation.hh" @@ -13,7 +13,7 @@ TEST(DummyStore, realisation_read) auto store = [] { auto cfg = make_ref(StoreReference::Params{}); cfg->readOnly = false; - return cfg->openStore(); + return cfg->openDummyStore(); }(); auto drvHash = Hash::parseExplicitFormatUnprefixed( @@ -22,6 +22,17 @@ TEST(DummyStore, realisation_read) auto outputName = "foo"; EXPECT_EQ(store->queryRealisation({drvHash, outputName}), nullptr); + + UnkeyedRealisation value{ + .outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo.drv"}, + }; + + store->buildTrace.insert({drvHash, {{outputName, make_ref(value)}}}); + + auto value2 = store->queryRealisation({drvHash, outputName}); + + ASSERT_TRUE(value2); + EXPECT_EQ(*value2, value); } } // namespace nix diff --git a/src/libstore/dummy-store.cc b/src/libstore/dummy-store.cc index 209be3ce9..509b7a0b1 100644 --- a/src/libstore/dummy-store.cc +++ b/src/libstore/dummy-store.cc @@ -3,6 +3,7 @@ #include "nix/util/callback.hh" #include "nix/util/memory-source-accessor.hh" #include "nix/store/dummy-store-impl.hh" +#include "nix/store/realisation.hh" #include @@ -251,7 +252,10 @@ struct DummyStoreImpl : DummyStore void registerDrvOutput(const Realisation & output) override { - unsupported("registerDrvOutput"); + auto ref = make_ref(output); + buildTrace.insert_or_visit({output.id.drvHash, {{output.id.outputName, ref}}}, [&](auto & kv) { + kv.second.insert_or_assign(output.id.outputName, make_ref(output)); + }); } void narFromPath(const StorePath & path, Sink & sink) override @@ -267,9 +271,18 @@ struct DummyStoreImpl : DummyStore } void queryRealisationUncached( - const DrvOutput &, Callback> callback) noexcept override + const DrvOutput & drvOutput, Callback> callback) noexcept override { - callback(nullptr); + bool visited = false; + buildTrace.cvisit(drvOutput.drvHash, [&](const auto & kv) { + if (auto it = kv.second.find(drvOutput.outputName); it != kv.second.end()) { + visited = true; + callback(it->second.get_ptr()); + } + }); + + if (!visited) + callback(nullptr); } std::shared_ptr getFSAccessor(const StorePath & path, bool requireValidPath) override diff --git a/src/libstore/include/nix/store/dummy-store-impl.hh b/src/libstore/include/nix/store/dummy-store-impl.hh index e05bb94ff..4c9f54e98 100644 --- a/src/libstore/include/nix/store/dummy-store-impl.hh +++ b/src/libstore/include/nix/store/dummy-store-impl.hh @@ -30,6 +30,18 @@ struct DummyStore : virtual Store */ boost::concurrent_flat_map contents; + /** + * The build trace maps the pair of a content-addressing (fixed or + * floating) derivations an one of its output to a + * (content-addressed) store object. + * + * It is [curried](https://en.wikipedia.org/wiki/Currying), so we + * instead having a single output with a `DrvOutput` key, we have an + * outer map for the derivation, and inner maps for the outputs of a + * given derivation. + */ + boost::concurrent_flat_map>> buildTrace; + DummyStore(ref config) : Store{*config} , config(config) diff --git a/src/libstore/include/nix/store/dummy-store.hh b/src/libstore/include/nix/store/dummy-store.hh index 95c09078c..d371c4e51 100644 --- a/src/libstore/include/nix/store/dummy-store.hh +++ b/src/libstore/include/nix/store/dummy-store.hh @@ -3,6 +3,8 @@ #include "nix/store/store-api.hh" +#include + namespace nix { struct DummyStore; diff --git a/src/libutil/include/nix/util/hash.hh b/src/libutil/include/nix/util/hash.hh index 571b6acca..0b16b423c 100644 --- a/src/libutil/include/nix/util/hash.hh +++ b/src/libutil/include/nix/util/hash.hh @@ -222,3 +222,22 @@ public: }; } // namespace nix + +template<> +struct std::hash +{ + std::size_t operator()(const nix::Hash & hash) const noexcept + { + assert(hash.hashSize > sizeof(size_t)); + return *reinterpret_cast(&hash.hash); + } +}; + +namespace nix { + +inline std::size_t hash_value(const Hash & hash) +{ + return std::hash{}(hash); +} + +} // namespace nix