@@ -24,26 +24,24 @@ OUTCOME_CPP_DEFINE_CATEGORY(fc::storage::hamt, HamtError, e) {
24
24
namespace fc ::storage::hamt {
25
25
using fc::common::which;
26
26
27
- // assuming 8-bit indices
28
- auto keyToIndices (const std::string &key, int n = -1 ) {
29
- std::vector<uint8_t > key_bytes (key.begin (), key.end ());
30
- auto hash = crypto::murmur::hash (key_bytes);
31
- return std::vector<size_t >(n == -1 ? hash.begin () : hash.end () - n + 1 ,
32
- hash.end ());
33
- }
34
-
35
27
auto consumeIndex (gsl::span<const size_t > indices) {
36
28
return indices.subspan (1 );
37
29
}
38
30
39
- Hamt::Hamt (std::shared_ptr<ipfs::IpfsDatastore> store)
40
- : store_(std::move(store)), root_(std::make_shared<Node>()) {}
31
+ Hamt::Hamt (std::shared_ptr<ipfs::IpfsDatastore> store, size_t bit_width)
32
+ : store_{std::move (store)},
33
+ root_{std::make_shared<Node>()},
34
+ bit_width_{bit_width} {}
41
35
42
36
Hamt::Hamt (std::shared_ptr<ipfs::IpfsDatastore> store, Node::Ptr root)
43
- : store_(std::move(store)), root_(std::move(root)) {}
37
+ : store_{std::move (store)},
38
+ root_{std::move (root)},
39
+ bit_width_{kDefaultBitWidth } {}
44
40
45
- Hamt::Hamt (std::shared_ptr<ipfs::IpfsDatastore> store, const CID &root)
46
- : store_(std::move(store)), root_(root) {}
41
+ Hamt::Hamt (std::shared_ptr<ipfs::IpfsDatastore> store,
42
+ const CID &root,
43
+ size_t bit_width)
44
+ : store_{std::move (store)}, root_{root}, bit_width_{bit_width} {}
47
45
48
46
outcome::result<void > Hamt::set (const std::string &key,
49
47
gsl::span<const uint8_t > value) {
@@ -84,6 +82,30 @@ namespace fc::storage::hamt {
84
82
return boost::get<CID>(root_);
85
83
}
86
84
85
+ std::vector<size_t > Hamt::keyToIndices (const std::string &key, int n) const {
86
+ std::vector<uint8_t > key_bytes (key.begin (), key.end ());
87
+ auto hash = crypto::murmur::hash (key_bytes);
88
+ std::vector<size_t > indices;
89
+ constexpr auto byte_bits = 8 ;
90
+ auto max_bits = byte_bits * hash.size ();
91
+ max_bits -= max_bits % bit_width_;
92
+ auto offset = 0 ;
93
+ if (n != -1 ) {
94
+ offset = max_bits - (n - 1 ) * bit_width_;
95
+ }
96
+ while (offset + bit_width_ <= max_bits) {
97
+ size_t index = 0 ;
98
+ for (auto i = 0u ; i < bit_width_; ++i, ++offset) {
99
+ index <<= 1 ;
100
+ index |= 1
101
+ & (hash[offset / byte_bits]
102
+ >> (byte_bits - 1 - offset % byte_bits));
103
+ }
104
+ indices.push_back (index);
105
+ }
106
+ return indices;
107
+ }
108
+
87
109
outcome::result<void > Hamt::set (Node &node,
88
110
gsl::span<const size_t > indices,
89
111
const std::string &key,
0 commit comments