谢瑞阳&徐翔宇的KV分离LEVELDB实现
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

115 lines
3.0 KiB

// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.
#include "db/true_iter.h"
#include "db/db_impl.h"
#include "db/dbformat.h"
#include "db/filename.h"
#include <fstream>
#include <iostream>
#include <queue>
#include <thread>
#include "leveldb/env.h"
#include "leveldb/iterator.h"
#include "port/port.h"
#include "util/logging.h"
#include "util/mutexlock.h"
#include "util/random.h"
namespace leveldb {
namespace {
// DBTrueIter simply wrap the DbIter and will parse the true value (maybe from
// valuelog) for user.
// if the crc check fail, DBTrueIter will skip the bad record
// and show it to user by status().
// bad status will remain showed by status(), like other iterator.
class DBTrueIter : public Iterator {
public:
DBTrueIter(DBImpl* db, Iterator* iter, bool check_crc)
: db_(db), iter_(iter), check_crc_(check_crc) {}
DBTrueIter(const DBTrueIter&) = delete;
DBTrueIter& operator=(const DBTrueIter&) = delete;
~DBTrueIter() override { delete iter_; }
bool Valid() const override { return iter_->Valid(); }
Slice key() const override { return iter_->key(); }
Slice value() const override {
return Slice(buf_for_value.data(), buf_for_value.size());
}
Status status() const override {
if (status_.ok())
return iter_->status();
else
return status_;
}
void Next() override;
void Prev() override;
void Seek(const Slice& target) override;
void SeekToFirst() override;
void SeekToLast() override;
private:
Status GetAndParseTrueValue(Slice tmp_value) {
Status status = db_->parseTrueValue(&tmp_value, &buf_for_value, check_crc_);
if (!status.ok()) status_ = status;
return status;
}
DBImpl* db_;
Iterator* const iter_;
std::string buf_for_value;
Status status_ = Status::OK();
bool check_crc_;
};
void DBTrueIter::Next() {
iter_->Next();
while (iter_->Valid()) {
Status res = GetAndParseTrueValue(iter_->value());
if (res.ok()) break;
iter_->Next();
}
}
void DBTrueIter::Prev() {
iter_->Prev();
while (iter_->Valid()) {
Status res = GetAndParseTrueValue(iter_->value());
if (res.ok()) break;
iter_->Prev();
}
}
void DBTrueIter::Seek(const Slice& target) {
iter_->Seek(target);
if (iter_->Valid()) {
Status res = GetAndParseTrueValue(iter_->value());
if (!res.ok()) Next(); // lowerbound
}
}
void DBTrueIter::SeekToFirst() {
iter_->SeekToFirst();
if (iter_->Valid()) {
Status res = GetAndParseTrueValue(iter_->value());
if (!res.ok()) Next();
}
}
void DBTrueIter::SeekToLast() {
iter_->SeekToLast();
if (iter_->Valid()) {
Status res = GetAndParseTrueValue(iter_->value());
if (!res.ok()) Prev();
}
}
} // anonymous namespace
Iterator* NewTrueIterator(DBImpl* db, Iterator* db_iter, bool check_crc) {
return new DBTrueIter(db, db_iter, check_crc);
}
} // namespace leveldb