aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/content-address.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstore/content-address.hh')
-rw-r--r--src/libstore/content-address.hh198
1 files changed, 166 insertions, 32 deletions
diff --git a/src/libstore/content-address.hh b/src/libstore/content-address.hh
index 368a7ec48..2f98950fb 100644
--- a/src/libstore/content-address.hh
+++ b/src/libstore/content-address.hh
@@ -3,12 +3,30 @@
#include <variant>
#include "hash.hh"
+#include "path.hh"
#include "comparator.hh"
namespace nix {
+/*
+ * Content addressing method
+ */
+
+/* We only have one way to hash text with references, so this is a single-value
+ type, mainly useful with std::variant.
+*/
+
+/**
+ * The single way we can serialize "text" file system objects.
+ *
+ * Somewhat obscure, used by \ref Derivation derivations and
+ * `builtins.toFile` currently.
+ */
+struct TextHashMethod : std::monostate { };
+
/**
- * An enumeration of the ways we can serialize file system objects.
+ * An enumeration of the main ways we can serialize file system
+ * objects.
*/
enum struct FileIngestionMethod : uint8_t {
/**
@@ -23,6 +41,53 @@ enum struct FileIngestionMethod : uint8_t {
};
/**
+ * Compute the prefix to the hash algorithm which indicates how the
+ * files were ingested.
+ */
+std::string makeFileIngestionPrefix(FileIngestionMethod m);
+
+struct FixedOutputHashMethod {
+ FileIngestionMethod fileIngestionMethod;
+ HashType hashType;
+
+ GENERATE_CMP(FixedOutputHashMethod, me->fileIngestionMethod, me->hashType);
+};
+
+/**
+ * An enumeration of all the ways we can serialize file system objects.
+ *
+ * Just the type of a content address. Combine with the hash itself, and
+ * we have a `ContentAddress` as defined below. Combine that, in turn,
+ * with info on references, and we have `ContentAddressWithReferences`,
+ * as defined further below.
+ */
+struct ContentAddressMethod
+{
+ typedef std::variant<
+ TextHashMethod,
+ FixedOutputHashMethod
+ > Raw;
+
+ Raw raw;
+
+ GENERATE_CMP(ContentAddressMethod, me->raw);
+
+ /* The moral equivalent of `using Raw::Raw;` */
+ ContentAddressMethod(auto &&... arg)
+ : raw(std::forward<decltype(arg)>(arg)...)
+ { }
+
+ static ContentAddressMethod parse(std::string_view rawCaMethod);
+
+ std::string render() const;
+};
+
+
+/*
+ * Mini content address
+ */
+
+/**
* Somewhat obscure, used by \ref Derivation derivations and
* `builtins.toFile` currently.
*/
@@ -36,7 +101,7 @@ struct TextHash {
};
/**
- * For path computed by makeFixedOutputPath.
+ * Used by most store objects that are content-addressed.
*/
struct FixedOutputHash {
/**
@@ -65,41 +130,96 @@ struct FixedOutputHash {
* - ‘fixed:<r?>:<ht>:<h>’: For paths computed by
* Store::makeFixedOutputPath() / Store::addToStore().
*/
-typedef std::variant<
- TextHash,
- FixedOutputHash
-> ContentAddress;
+struct ContentAddress
+{
+ typedef std::variant<
+ TextHash,
+ FixedOutputHash
+ > Raw;
-/**
- * Compute the prefix to the hash algorithm which indicates how the
- * files were ingested.
+ Raw raw;
+
+ GENERATE_CMP(ContentAddress, me->raw);
+
+ /* The moral equivalent of `using Raw::Raw;` */
+ ContentAddress(auto &&... arg)
+ : raw(std::forward<decltype(arg)>(arg)...)
+ { }
+
+ /**
+ * Compute the content-addressability assertion (ValidPathInfo::ca) for
+ * paths created by Store::makeFixedOutputPath() / Store::addToStore().
+ */
+ std::string render() const;
+
+ static ContentAddress parse(std::string_view rawCa);
+
+ static std::optional<ContentAddress> parseOpt(std::string_view rawCaOpt);
+
+ const Hash & getHash() const;
+};
+
+std::string renderContentAddress(std::optional<ContentAddress> ca);
+
+
+/*
+ * Full content address
+ *
+ * See the schema for store paths in store-api.cc
*/
-std::string makeFileIngestionPrefix(const FileIngestionMethod m);
/**
- * Compute the content-addressability assertion (ValidPathInfo::ca) for
- * paths created by Store::makeFixedOutputPath() / Store::addToStore().
+ * A set of references to other store objects.
+ *
+ * References to other store objects are tracked with store paths, self
+ * references however are tracked with a boolean.
*/
-std::string makeFixedOutputCA(FileIngestionMethod method, const Hash & hash);
+struct StoreReferences {
+ /**
+ * References to other store objects
+ */
+ StorePathSet others;
-std::string renderContentAddress(ContentAddress ca);
+ /**
+ * Reference to this store object
+ */
+ bool self = false;
-std::string renderContentAddress(std::optional<ContentAddress> ca);
+ /**
+ * @return true iff no references, i.e. others is empty and self is
+ * false.
+ */
+ bool empty() const;
-ContentAddress parseContentAddress(std::string_view rawCa);
+ /**
+ * Returns the numbers of references, i.e. the size of others + 1
+ * iff self is true.
+ */
+ size_t size() const;
-std::optional<ContentAddress> parseContentAddressOpt(std::string_view rawCaOpt);
+ GENERATE_CMP(StoreReferences, me->self, me->others);
+};
-Hash getContentAddressHash(const ContentAddress & ca);
+// This matches the additional info that we need for makeTextPath
+struct TextInfo {
+ TextHash hash;
+ /**
+ * References to other store objects only; self references
+ * disallowed
+ */
+ StorePathSet references;
-/*
- We only have one way to hash text with references, so this is single-value
- type is only useful in std::variant.
-*/
-struct TextHashMethod { };
-struct FixedOutputHashMethod {
- FileIngestionMethod fileIngestionMethod;
- HashType hashType;
+ GENERATE_CMP(TextInfo, me->hash, me->references);
+};
+
+struct FixedOutputInfo {
+ FixedOutputHash hash;
+ /**
+ * References to other store objects or this one.
+ */
+ StoreReferences references;
+
+ GENERATE_CMP(FixedOutputInfo, me->hash, me->references);
};
/**
@@ -107,13 +227,27 @@ struct FixedOutputHashMethod {
*
* A ContentAddress without a Hash.
*/
-typedef std::variant<
- TextHashMethod,
- FixedOutputHashMethod
- > ContentAddressMethod;
+struct ContentAddressWithReferences
+{
+ typedef std::variant<
+ TextInfo,
+ FixedOutputInfo
+ > Raw;
+
+ Raw raw;
-ContentAddressMethod parseContentAddressMethod(std::string_view rawCaMethod);
+ GENERATE_CMP(ContentAddressWithReferences, me->raw);
-std::string renderContentAddressMethod(ContentAddressMethod caMethod);
+ /* The moral equivalent of `using Raw::Raw;` */
+ ContentAddressWithReferences(auto &&... arg)
+ : raw(std::forward<decltype(arg)>(arg)...)
+ { }
+
+ /**
+ * Create a ContentAddressWithReferences from a mere ContentAddress, by
+ * assuming no references in all cases.
+ */
+ static ContentAddressWithReferences withoutRefs(const ContentAddress &);
+};
}