2020-06-01 21:32:27 +00:00
|
|
|
|
#pragma once
|
|
|
|
|
|
2020-06-01 22:53:31 +00:00
|
|
|
|
#include <variant>
|
2020-06-01 21:32:27 +00:00
|
|
|
|
#include "hash.hh"
|
2020-10-07 13:52:20 +00:00
|
|
|
|
#include "path.hh"
|
2020-06-01 21:32:27 +00:00
|
|
|
|
|
|
|
|
|
namespace nix {
|
|
|
|
|
|
2020-10-07 13:52:20 +00:00
|
|
|
|
/*
|
2020-10-13 03:30:14 +00:00
|
|
|
|
* Content addressing method
|
2020-10-07 13:52:20 +00:00
|
|
|
|
*/
|
|
|
|
|
|
2020-06-01 21:32:27 +00:00
|
|
|
|
enum struct FileIngestionMethod : uint8_t {
|
|
|
|
|
Flat = false,
|
|
|
|
|
Recursive = true
|
|
|
|
|
};
|
|
|
|
|
|
2020-10-13 03:30:14 +00:00
|
|
|
|
/*
|
|
|
|
|
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;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* Compute the prefix to the hash algorithm which indicates how the files were
|
|
|
|
|
ingested. */
|
|
|
|
|
std::string makeFileIngestionPrefix(const FileIngestionMethod m);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
typedef std::variant<
|
|
|
|
|
TextHashMethod,
|
|
|
|
|
FixedOutputHashMethod
|
|
|
|
|
> ContentAddressMethod;
|
|
|
|
|
|
|
|
|
|
ContentAddressMethod parseContentAddressMethod(std::string_view rawCaMethod);
|
|
|
|
|
|
|
|
|
|
std::string renderContentAddressMethod(ContentAddressMethod caMethod);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Mini content address
|
|
|
|
|
*/
|
2020-10-07 13:52:20 +00:00
|
|
|
|
|
2020-06-01 23:26:40 +00:00
|
|
|
|
struct TextHash {
|
|
|
|
|
Hash hash;
|
|
|
|
|
};
|
|
|
|
|
|
2020-06-01 21:32:27 +00:00
|
|
|
|
/// Pair of a hash, and how the file system was ingested
|
2020-06-19 15:18:19 +00:00
|
|
|
|
struct FixedOutputHash {
|
2020-06-01 21:32:27 +00:00
|
|
|
|
FileIngestionMethod method;
|
|
|
|
|
Hash hash;
|
|
|
|
|
std::string printMethodAlgo() const;
|
|
|
|
|
};
|
|
|
|
|
|
2020-06-01 22:53:31 +00: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 makeTextPath() / addTextToStore().
|
|
|
|
|
|
|
|
|
|
* ‘fixed:<r?>:<ht>:<h>’: For paths computed by
|
|
|
|
|
makeFixedOutputPath() / addToStore().
|
|
|
|
|
*/
|
|
|
|
|
typedef std::variant<
|
2020-06-01 23:26:40 +00:00
|
|
|
|
TextHash, // for paths computed by makeTextPath() / addTextToStore
|
2020-06-19 15:18:19 +00:00
|
|
|
|
FixedOutputHash // for path computed by makeFixedOutputPath
|
2020-06-01 22:53:31 +00:00
|
|
|
|
> ContentAddress;
|
|
|
|
|
|
2020-06-01 23:26:40 +00:00
|
|
|
|
std::string renderContentAddress(ContentAddress ca);
|
|
|
|
|
|
|
|
|
|
std::string renderContentAddress(std::optional<ContentAddress> ca);
|
|
|
|
|
|
2020-06-02 15:00:10 +00:00
|
|
|
|
ContentAddress parseContentAddress(std::string_view rawCa);
|
2020-06-02 00:37:43 +00:00
|
|
|
|
|
2020-06-02 15:00:10 +00:00
|
|
|
|
std::optional<ContentAddress> parseContentAddressOpt(std::string_view rawCaOpt);
|
2020-06-02 00:37:43 +00:00
|
|
|
|
|
2020-07-10 11:21:37 +00:00
|
|
|
|
Hash getContentAddressHash(const ContentAddress & ca);
|
|
|
|
|
|
2020-10-07 13:52:20 +00:00
|
|
|
|
/*
|
|
|
|
|
* References set
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
template<typename Ref>
|
|
|
|
|
struct PathReferences
|
|
|
|
|
{
|
|
|
|
|
std::set<Ref> references;
|
|
|
|
|
bool hasSelfReference = false;
|
|
|
|
|
|
|
|
|
|
bool operator == (const PathReferences<Ref> & other) const
|
|
|
|
|
{
|
|
|
|
|
return references == other.references
|
|
|
|
|
&& hasSelfReference == other.hasSelfReference;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Functions to view references + hasSelfReference as one set, mainly for
|
|
|
|
|
compatibility's sake. */
|
|
|
|
|
StorePathSet referencesPossiblyToSelf(const Ref & self) const;
|
|
|
|
|
void insertReferencePossiblyToSelf(const Ref & self, Ref && ref);
|
|
|
|
|
void setReferencesPossiblyToSelf(const Ref & self, std::set<Ref> && refs);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template<typename Ref>
|
|
|
|
|
StorePathSet PathReferences<Ref>::referencesPossiblyToSelf(const Ref & self) const
|
|
|
|
|
{
|
|
|
|
|
StorePathSet refs { references };
|
|
|
|
|
if (hasSelfReference)
|
|
|
|
|
refs.insert(self);
|
|
|
|
|
return refs;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename Ref>
|
|
|
|
|
void PathReferences<Ref>::insertReferencePossiblyToSelf(const Ref & self, Ref && ref)
|
|
|
|
|
{
|
|
|
|
|
if (ref == self)
|
|
|
|
|
hasSelfReference = true;
|
|
|
|
|
else
|
|
|
|
|
references.insert(std::move(ref));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename Ref>
|
|
|
|
|
void PathReferences<Ref>::setReferencesPossiblyToSelf(const Ref & self, std::set<Ref> && refs)
|
|
|
|
|
{
|
|
|
|
|
if (refs.count(self))
|
|
|
|
|
hasSelfReference = true;
|
|
|
|
|
refs.erase(self);
|
|
|
|
|
|
|
|
|
|
references = refs;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* 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 {
|
|
|
|
|
// References for the paths, self references disallowed
|
|
|
|
|
StorePathSet references;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct FixedOutputInfo : FixedOutputHash {
|
|
|
|
|
// References for the paths
|
|
|
|
|
PathReferences<StorePath> references;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
typedef std::variant<
|
|
|
|
|
TextInfo,
|
|
|
|
|
FixedOutputInfo
|
|
|
|
|
> ContentAddressWithReferences;
|
|
|
|
|
|
|
|
|
|
ContentAddressWithReferences caWithoutRefs(const ContentAddress &);
|
|
|
|
|
|
|
|
|
|
struct StorePathDescriptor {
|
|
|
|
|
std::string name;
|
|
|
|
|
ContentAddressWithReferences info;
|
|
|
|
|
|
|
|
|
|
bool operator == (const StorePathDescriptor & other) const
|
|
|
|
|
{
|
|
|
|
|
return name == other.name;
|
|
|
|
|
// FIXME second field
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool operator < (const StorePathDescriptor & other) const
|
|
|
|
|
{
|
|
|
|
|
return name < other.name;
|
|
|
|
|
// FIXME second field
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2020-06-01 21:32:27 +00:00
|
|
|
|
}
|