|
16 | 16 | #define MAPCACHER_H |
17 | 17 |
|
18 | 18 | #include "include/Context.h" |
| 19 | +#include "include/expected.hpp" |
19 | 20 | #include "common/sharedptr_registry.hpp" |
20 | 21 |
|
21 | 22 | namespace MapCacher { |
@@ -130,6 +131,50 @@ class MapCacher { |
130 | 131 | return -EINVAL; |
131 | 132 | } ///< @return error value, 0 on success, -ENOENT if no more entries |
132 | 133 |
|
| 134 | + /// Fetch first key/value std::pair after specified key |
| 135 | + struct PosAndData { |
| 136 | + K last_key; |
| 137 | + V data; |
| 138 | + }; |
| 139 | + using MaybePosAndData = tl::expected<PosAndData, int>; |
| 140 | + |
| 141 | + MaybePosAndData get_1st_after_key( |
| 142 | + K key ///< [in] key after which to get next |
| 143 | + ) |
| 144 | + { |
| 145 | + ceph_assert(driver); |
| 146 | + while (true) { |
| 147 | + std::pair<K, boost::optional<V>> cached; |
| 148 | + bool got_cached = in_progress.get_next(key, &cached); |
| 149 | + |
| 150 | + ///\todo a driver->get_next() that returns an expected<K, V> would be nice |
| 151 | + bool got_store{false}; |
| 152 | + std::pair<K, V> store; |
| 153 | + int r = driver->get_next(key, &store); |
| 154 | + if (r < 0 && r != -ENOENT) { |
| 155 | + return tl::unexpected(r); |
| 156 | + } else if (r == 0) { |
| 157 | + got_store = true; |
| 158 | + } |
| 159 | + |
| 160 | + if (!got_cached && !got_store) { |
| 161 | + return tl::unexpected(-ENOENT); |
| 162 | + } else if (got_cached && (!got_store || store.first >= cached.first)) { |
| 163 | + if (cached.second) { |
| 164 | + return PosAndData{cached.first, *cached.second}; |
| 165 | + } else { |
| 166 | + key = cached.first; |
| 167 | + continue; // value was cached as removed, recurse |
| 168 | + } |
| 169 | + } else { |
| 170 | + return PosAndData{store.first, store.second}; |
| 171 | + } |
| 172 | + } |
| 173 | + ceph_abort(); // not reachable |
| 174 | + return tl::unexpected(-EINVAL); |
| 175 | + } |
| 176 | + |
| 177 | + |
133 | 178 | /// Adds operation setting keys to Transaction |
134 | 179 | void set_keys( |
135 | 180 | const std::map<K, V> &keys, ///< [in] keys/values to std::set |
|
0 commit comments