24static std::map<std::pair<size_t, std::string>,
TTCacheEntry> ttCache;
26[[nodiscard]]
static constexpr size_t calcNumNodes(
size_t dataSize)
29 return (numBlocks == 0) ? 1 : 2 * numBlocks - 1;
32[[nodiscard]]
static TTCacheEntry& getCacheEntry(
33 TTData& data,
size_t dataSize,
const std::string& name)
35 auto& result = ttCache[std::pair(dataSize, name)];
36 if (!data.isCacheStillValid(result.time)) {
37 size_t numNodes = calcNumNodes(dataSize);
38 result.hash .resize(numNodes);
39 result.valid.resize(numNodes);
40 result.numNodes = numNodes;
41 ranges::fill(std::span{result.valid.data(), numNodes},
false);
42 result.numNodesValid = 0;
50 , entry(getCacheEntry(data, dataSize, name))
56 return calcHash(getTop(), progressCallback);
63 assert((offset + len) <= dataSize);
66 if (entry.
valid[getTop().n]) {
67 entry.
valid[getTop().n] =
false;
72 assert(first <= last);
74 auto node = getLeaf(first);
75 while (entry.
valid[node.n]) {
76 entry.
valid[node.n] =
false;
78 node = getParent(node);
80 }
while (++first <= last);
86 if (!entry.
valid[n]) {
89 auto left = getLeftChild (node);
90 auto right = getRightChild(node);
91 const auto& h1 =
calcHash(left, progressCallback);
92 const auto& h2 =
calcHash(right, progressCallback);
97 size_t l = dataSize - b;
104 auto* d = data.getData(b, l);
106 tiger(std::span{d - 1, l + 1}, entry.
hash[n]);
109 entry.
valid[n] =
true;
111 if (progressCallback) {
115 return entry.
hash[n];
141TigerTree::Node TigerTree::getTop()
const
147TigerTree::Node TigerTree::getLeaf(
size_t block)
const
149 assert((2 * block) < entry.
numNodes);
150 return {2 * block, 1};
153TigerTree::Node TigerTree::getParent(Node node)
const
157 node.n = (node.n & ~(2 * node.l)) + node.l;
163TigerTree::Node TigerTree::getLeftChild(Node node)
const
172TigerTree::Node TigerTree::getRightChild(Node node)
const
178 auto r = node.n + node.l;
179 if (r < entry.
numNodes)
return {r, node.l};
Assign new value to some variable and restore the original value when this object goes out of scope.
This class manages the lifetime of a block of memory.
The TigerTree class will query the to-be-hashed data via this abstract interface.
const TigerHash & calcHash(const std::function< void(size_t, size_t)> &progressCallback)
Calculate the hash value.
TigerTree(TTData &data, size_t dataSize, const std::string &name)
Create TigerTree calculator for the given (abstract) data block of given size.
void notifyChange(size_t offset, size_t len, time_t time)
Inform this calculator about changes in the input data.
static constexpr size_t BLOCK_SIZE
constexpr auto floodRight(std::unsigned_integral auto x) noexcept
Returns the smallest number of the form 2^n-1 that is greater or equal to the given number.
This file implemented 3 utility functions:
void tiger(std::span< const uint8_t > input, TigerHash &result)
Generic function to calculate a tiger-hash.
void tiger_int(const TigerHash &h0, const TigerHash &h1, TigerHash &result)
Use for tiger-tree internal node hash calculations.
void tiger_leaf(std::span< uint8_t > data, TigerHash &result)
Use for tiger-tree leaf node hash calculations.
constexpr void fill(ForwardRange &&range, const T &value)
MemBuffer< TigerHash > hash
This struct represents the result of a tiger-hash.