blob: 1ffb52caee8fb21c0d35b82b20c4c21096ddced5 [file]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
#pragma once
#include <rocksdb/iterator.h>
#include <rocksdb/options.h>
#include "cluster/cluster_defs.h"
#include "storage.h"
namespace engine {
class SubKeyIterator {
public:
explicit SubKeyIterator(engine::Context &ctx, rocksdb::ReadOptions read_options, RedisType type, std::string prefix);
~SubKeyIterator() = default;
bool Valid() const;
void Seek();
void Next();
// return the raw key in rocksdb
Slice Key() const;
// return the user key without prefix
Slice UserKey() const;
rocksdb::ColumnFamilyHandle *ColumnFamilyHandle() const;
Slice Value() const;
void Reset();
private:
Storage *storage_;
rocksdb::ReadOptions read_options_;
RedisType type_;
std::string prefix_;
std::unique_ptr<rocksdb::Iterator> iter_;
rocksdb::ColumnFamilyHandle *cf_handle_ = nullptr;
};
class DBIterator {
public:
explicit DBIterator(engine::Context &ctx, rocksdb::ReadOptions read_options, int slot = -1);
~DBIterator() = default;
bool Valid() const;
void Seek(const std::string &target = "");
void Next();
// return the raw key in rocksdb
Slice Key() const;
// return the namespace and user key without prefix
std::tuple<Slice, Slice> UserKey() const;
Slice Value() const;
RedisType Type() const;
void Reset();
std::unique_ptr<SubKeyIterator> GetSubKeyIterator() const;
private:
void nextUntilValid();
Storage *storage_;
rocksdb::ReadOptions read_options_;
Context *ctx_;
int slot_ = -1;
Metadata metadata_ = Metadata(kRedisNone, false);
rocksdb::ColumnFamilyHandle *metadata_cf_handle_ = nullptr;
std::unique_ptr<rocksdb::Iterator> metadata_iter_;
std::unique_ptr<SubKeyIterator> subkey_iter_;
};
struct WALItem {
enum class Type : uint8_t {
kTypeInvalid = 0,
kTypeLogData = 1,
kTypePut = 2,
kTypeDelete = 3,
kTypeDeleteRange = 4,
};
WALItem() = default;
WALItem(WALItem::Type t, uint32_t cf_id, std::string k, std::string v)
: type(t), column_family_id(cf_id), key(std::move(k)), value(std::move(v)) {}
WALItem::Type type = WALItem::Type::kTypeInvalid;
uint32_t column_family_id = 0;
std::string key;
std::string value;
};
class WALBatchExtractor : public rocksdb::WriteBatch::Handler {
public:
// If set slot, storage must enable slot id encoding
explicit WALBatchExtractor(int slot = -1) : slot_range_(slot, slot) {}
explicit WALBatchExtractor(const SlotRange &slot_range) : slot_range_(slot_range) {}
rocksdb::Status PutCF(uint32_t column_family_id, const Slice &key, const Slice &value) override;
rocksdb::Status DeleteCF(uint32_t column_family_id, const rocksdb::Slice &key) override;
rocksdb::Status DeleteRangeCF(uint32_t column_family_id, const rocksdb::Slice &begin_key,
const rocksdb::Slice &end_key) override;
void LogData(const rocksdb::Slice &blob) override;
void Clear();
class Iter {
friend class WALBatchExtractor;
public:
bool Valid();
void Next();
WALItem Value();
private:
explicit Iter(std::vector<WALItem> *items) : items_(items), cur_(0) {}
std::vector<WALItem> *items_;
size_t cur_;
};
WALBatchExtractor::Iter GetIter();
private:
std::vector<WALItem> items_;
SlotRange slot_range_;
};
class WALIterator {
public:
explicit WALIterator(engine::Storage *storage, const SlotRange &slot_range)
: storage_(storage), slot_range_(slot_range), extractor_(slot_range), next_batch_seq_(0) {}
explicit WALIterator(engine::Storage *storage, int slot = -1)
: storage_(storage), slot_range_(slot, slot), extractor_(slot), next_batch_seq_(0) {}
~WALIterator() = default;
bool Valid() const;
void Seek(rocksdb::SequenceNumber seq);
void Next();
WALItem Item();
rocksdb::SequenceNumber NextSequenceNumber() const;
void Reset();
private:
void nextBatch();
engine::Storage *storage_;
SlotRange slot_range_;
std::unique_ptr<rocksdb::TransactionLogIterator> iter_;
WALBatchExtractor extractor_;
std::unique_ptr<WALBatchExtractor::Iter> batch_iter_;
rocksdb::SequenceNumber next_batch_seq_;
};
} // namespace engine