|
6 | 6 | #ifndef CPP_FILECOIN_MULTIMAP_HPP
|
7 | 7 | #define CPP_FILECOIN_MULTIMAP_HPP
|
8 | 8 |
|
9 |
| -#include "storage/hamt/hamt.hpp" |
| 9 | +#include "adt/array.hpp" |
| 10 | +#include "adt/map.hpp" |
10 | 11 |
|
11 | 12 | namespace fc::adt {
|
12 |
| - |
13 |
| - /** |
14 |
| - * Container for storing multiple values per key. |
15 |
| - * Implemented over a HAMT of AMTs. |
16 |
| - * The order of values by the same key is preserved. |
17 |
| - */ |
18 | 13 | struct Multimap {
|
19 |
| - using Value = storage::ipfs::IpfsDatastore::Value; |
20 |
| - using Visitor = std::function<outcome::result<void>(const Value &)>; |
21 |
| - |
22 |
| - explicit Multimap( |
23 |
| - const std::shared_ptr<storage::ipfs::IpfsDatastore> &store); |
24 |
| - Multimap(const std::shared_ptr<storage::ipfs::IpfsDatastore> &store, |
25 |
| - const CID &root); |
26 |
| - |
27 |
| - /** |
28 |
| - * Apply changes to storage |
29 |
| - * @return root CID |
30 |
| - */ |
31 |
| - outcome::result<CID> flush(); |
32 |
| - |
33 |
| - /// Adds a value by key to the end of array. Does not change the store |
34 |
| - outcome::result<void> add(const std::string &key, |
35 |
| - gsl::span<const uint8_t> value); |
36 |
| - |
37 |
| - /** |
38 |
| - * Adds a value which can be CBOR-encoded. |
39 |
| - * Does not change the store immediately |
40 |
| - * @tparam T value type that supports CBOR encoding |
41 |
| - * @param value to be marshalled |
42 |
| - * @return operation result |
43 |
| - */ |
44 |
| - template <typename T> |
45 |
| - outcome::result<void> addCbor(const std::string &key, const T &value) { |
46 |
| - OUTCOME_TRY(bytes, codec::cbor::encode(value)); |
47 |
| - return add(key, bytes); |
| 14 | + template <typename Value, typename Keyer, size_t bit_width> |
| 15 | + static outcome::result<void> append( |
| 16 | + Map<Array<Value>, Keyer, bit_width> &map, |
| 17 | + const typename Keyer::Key &key, |
| 18 | + const Value &value) { |
| 19 | + OUTCOME_TRY(array, map.tryGet(key)); |
| 20 | + if (!array) { |
| 21 | + array = Array<Value>{}; |
| 22 | + } |
| 23 | + array->load(map.hamt.getIpld()); |
| 24 | + OUTCOME_TRY(count, array->amt.count()); |
| 25 | + OUTCOME_TRY(array->set(count, value)); |
| 26 | + OUTCOME_TRY(array->flush()); |
| 27 | + return map.set(key, *array); |
48 | 28 | }
|
49 | 29 |
|
50 |
| - /// Removes array under the key |
51 |
| - outcome::result<void> removeAll(const std::string &key); |
52 |
| - |
53 |
| - /// Iterates over stored values by key |
54 |
| - outcome::result<void> visit(const std::string &key, const Visitor &visitor); |
55 |
| - |
56 |
| - private: |
57 |
| - std::shared_ptr<storage::ipfs::IpfsDatastore> store_; |
58 |
| - storage::hamt::Hamt hamt_; |
| 30 | + template <typename Value, typename Keyer, size_t bit_width> |
| 31 | + static outcome::result<void> visit( |
| 32 | + Map<Array<Value>, Keyer, bit_width> &map, |
| 33 | + const typename Keyer::Key &key, |
| 34 | + const std::function<outcome::result<void>(const Value &)> &visitor) { |
| 35 | + OUTCOME_TRY(array, map.tryGet(key)); |
| 36 | + if (array) { |
| 37 | + array->load(map.hamt.getIpld()); |
| 38 | + OUTCOME_TRY( |
| 39 | + array->visit([&](auto, auto &value) { return visitor(value); })); |
| 40 | + } |
| 41 | + return outcome::success(); |
| 42 | + } |
59 | 43 | };
|
60 | 44 | } // namespace fc::adt
|
61 | 45 |
|
|
0 commit comments