nix-super/src/libstore/content-address.hh

230 lines
5.6 KiB
C++
Raw Normal View History

2020-06-02 00:32:27 +03:00
#pragma once
2020-06-02 01:53:31 +03:00
#include <variant>
2020-06-02 00:32:27 +03:00
#include "hash.hh"
2020-10-07 16:52:20 +03:00
#include "path.hh"
#include "comparator.hh"
2020-06-02 00:32:27 +03:00
namespace nix {
2020-10-07 16:52:20 +03:00
/*
* Content addressing method
2020-10-07 16:52:20 +03:00
*/
/* 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 main ways we can serialize file system
* objects.
*/
2020-06-02 00:32:27 +03:00
enum struct FileIngestionMethod : uint8_t {
/**
* Flat-file hashing. Directly ingest the contents of a single file
*/
2020-06-02 00:32:27 +03:00
Flat = false,
/**
* Recursive (or NAR) hashing. Serializes the file-system object in Nix
* Archive format and ingest that
*/
2020-06-02 00:32:27 +03:00
Recursive = true
};
/**
* Compute the prefix to the hash algorithm which indicates how the
* files were ingested.
*/
std::string makeFileIngestionPrefix(FileIngestionMethod m);
/**
* 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.
*/
typedef std::variant<
TextHashMethod,
FileIngestionMethod
> ContentAddressMethod;
/* Parse and pretty print the algorithm which indicates how the files
were ingested, with the the fixed output case not prefixed for back
compat. */
std::string makeContentAddressingPrefix(ContentAddressMethod m);
ContentAddressMethod parseContentAddressingPrefix(std::string_view & m);
/* Parse and pretty print a content addressing method and hash in a
nicer way, prefixing both cases. */
std::string renderContentAddressMethodAndHash(ContentAddressMethod cam, HashType ht);
std::pair<ContentAddressMethod, HashType> parseContentAddressMethod(std::string_view caMethod);
2020-10-07 16:52:20 +03:00
/*
* Mini content address
*/
2020-10-07 16:52:20 +03:00
/**
* Somewhat obscure, used by \ref Derivation derivations and
* `builtins.toFile` currently.
*/
2020-06-02 02:26:40 +03:00
struct TextHash {
/**
* Hash of the contents of the text/file.
*/
2020-06-02 02:26:40 +03:00
Hash hash;
GENERATE_CMP(TextHash, me->hash);
2020-06-02 02:26:40 +03:00
};
/**
* Used by most store objects that are content-addressed.
*/
struct FixedOutputHash {
/**
* How the file system objects are serialized
*/
2020-06-02 00:32:27 +03:00
FileIngestionMethod method;
/**
* Hash of that serialization
*/
2020-06-02 00:32:27 +03:00
Hash hash;
2020-06-02 00:32:27 +03:00
std::string printMethodAlgo() const;
GENERATE_CMP(FixedOutputHash, me->method, me->hash);
2020-06-02 00:32:27 +03:00
};
/**
* We've accumulated several types of content-addressed paths over the
* years; fixed-output derivations support multiple hash algorithms and
* serialisation methods (flat file vs NAR). Thus, ca has one of the
* following forms:
*
* - text:sha256:<sha256 hash of file contents>: For paths
* computed by Store::makeTextPath() / Store::addTextToStore().
*
* - fixed:<r?>:<ht>:<h>: For paths computed by
* Store::makeFixedOutputPath() / Store::addToStore().
*/
2020-06-02 01:53:31 +03:00
typedef std::variant<
TextHash,
FixedOutputHash
2020-06-02 01:53:31 +03:00
> ContentAddress;
/**
* Compute the content-addressability assertion (ValidPathInfo::ca) for
* paths created by Store::makeFixedOutputPath() / Store::addToStore().
*/
2020-06-02 02:26:40 +03:00
std::string renderContentAddress(ContentAddress ca);
std::string renderContentAddress(std::optional<ContentAddress> ca);
ContentAddress parseContentAddress(std::string_view rawCa);
2020-06-02 03:37:43 +03:00
std::optional<ContentAddress> parseContentAddressOpt(std::string_view rawCaOpt);
2020-06-02 03:37:43 +03:00
Hash getContentAddressHash(const ContentAddress & ca);
/**
* 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.
2020-10-07 16:52:20 +03:00
*/
struct StoreReferences {
/**
* References to other store objects
*/
StorePathSet others;
/**
* Reference to this store object
*/
bool self = false;
/**
* @return true iff no references, i.e. others is empty and self is
* false.
*/
bool empty() const;
/**
* Returns the numbers of references, i.e. the size of others + 1
* iff self is true.
*/
size_t size() const;
GENERATE_CMP(StoreReferences, me->self, me->others);
};
2020-10-07 16:52:20 +03:00
/*
* Full content address
*
* See the schema for store paths in store-api.cc
*/
// This matches the additional info that we need for makeTextPath
struct TextInfo {
TextHash hash;
/**
* References to other store objects only; self references
* disallowed
*/
2020-10-07 16:52:20 +03:00
StorePathSet references;
GENERATE_CMP(TextInfo, me->hash, me->references);
2020-10-07 16:52:20 +03:00
};
struct FixedOutputInfo {
FixedOutputHash hash;
/**
* References to other store objects or this one.
*/
StoreReferences references;
GENERATE_CMP(FixedOutputInfo, me->hash, me->references);
2020-10-07 16:52:20 +03:00
};
/**
* Ways of content addressing but not a complete ContentAddress.
*
* A ContentAddress without a Hash.
*/
2020-10-07 16:52:20 +03:00
typedef std::variant<
TextInfo,
FixedOutputInfo
> ContentAddressWithReferences;
/**
* Create a ContentAddressWithReferences from a mere ContentAddress, by
* assuming no references in all cases.
*/
2020-10-07 16:52:20 +03:00
ContentAddressWithReferences caWithoutRefs(const ContentAddress &);
ContentAddressWithReferences contentAddressFromMethodHashAndRefs(
ContentAddressMethod method, Hash && hash, StoreReferences && refs);
ContentAddressMethod getContentAddressMethod(const ContentAddressWithReferences & ca);
Hash getContentAddressHash(const ContentAddressWithReferences & ca);
std::string printMethodAlgo(const ContentAddressWithReferences &);
2020-06-02 00:32:27 +03:00
}