| 189 | : db_(db), prefix_(prefix), codec_(Codec{}) {} |
| 190 | |
| 191 | class iterator { |
| 192 | public: |
| 193 | using value_type = std::pair<key_type, mapped_type>; |
| 194 | using difference_type = std::ptrdiff_t; |
| 195 | using iterator_category = std::forward_iterator_tag; |
| 196 | using pointer = value_type*; |
| 197 | using reference = value_type&; |
| 198 | |
| 199 | private: |
| 200 | rocksdb::DB* db_; |
| 201 | std::string prefix_; |
| 202 | Codec codec_; |
| 203 | // When it_ is nullptr, this iterator is at end. |
| 204 | std::unique_ptr<rocksdb::Iterator> it_; |
| 205 | mutable value_type cached_value_; |
| 206 | |
| 207 | void check_valid() { |
| 208 | #ifdef IFOPSH_WITH_ROCKSDB |
| 209 | if (!it_ || !it_->Valid() || !it_->key().starts_with(prefix_)) { |
| 210 | it_.reset(); |
| 211 | } |
| 212 | #endif |
| 213 | } |
| 214 | |
| 215 | public: |
| 216 | iterator() : db_(nullptr), prefix_(), codec_(Codec{}), it_(nullptr) {} |
| 217 | |
| 218 | iterator(rocksdb::DB* db, const std::string& prefix, |
| 219 | std::unique_ptr<rocksdb::Iterator> iter, Codec codec = Codec{}) |
| 220 | : db_(db), prefix_(prefix), codec_(codec), it_(std::move(iter)) |
| 221 | { |
| 222 | check_valid(); |
| 223 | } |
| 224 | |
| 225 | iterator(const iterator& other) |
| 226 | : db_(other.db_), prefix_(other.prefix_), codec_(other.codec_) |
| 227 | { |
| 228 | #ifdef IFOPSH_WITH_ROCKSDB |
| 229 | if (other.it_) { |
| 230 | std::string curr = other.it_->key().ToString(); |
| 231 | it_.reset(db_->NewIterator(rocksdb::ReadOptions{})); |
| 232 | it_->Seek(curr); |
| 233 | if (!it_->Valid() || it_->key().ToString() != curr) |
| 234 | it_.reset(); |
| 235 | } |
| 236 | #endif |
| 237 | } |
| 238 | |
| 239 | iterator& operator=(const iterator& other) { |
| 240 | #ifdef IFOPSH_WITH_ROCKSDB |
| 241 | if (this != &other) { |
| 242 | db_ = other.db_; |
| 243 | prefix_ = other.prefix_; |
| 244 | codec_ = other.codec_; |
| 245 | if (other.it_) { |
| 246 | std::string curr = other.it_->key().ToString(); |
| 247 | it_.reset(db_->NewIterator(rocksdb::ReadOptions{})); |
| 248 | it_->Seek(curr); |