c293472908
Summary: Add kTypeBlobIndex value type, which will be used by blob db only, to insert a (key, blob_offset) KV pair. The purpose is to 1. Make it possible to open existing rocksdb instance as blob db. Existing value will be of kTypeIndex type, while value inserted by blob db will be of kTypeBlobIndex. 2. Make rocksdb able to detect if the db contains value written by blob db, if so return error. 3. Make it possible to have blob db optionally store value in SST file (with kTypeValue type) or as a blob value (with kTypeBlobIndex type). The root db (DBImpl) basically pretended kTypeBlobIndex are normal value on write. On Get if is_blob is provided, return whether the value read is of kTypeBlobIndex type, or return Status::NotSupported() status if is_blob is not provided. On scan allow_blob flag is pass and if the flag is true, return wether the value is of kTypeBlobIndex type via iter->IsBlob(). Changes on blob db side will be in a separate patch. Closes https://github.com/facebook/rocksdb/pull/2886 Differential Revision: D5838431 Pulled By: yiwu-arbug fbshipit-source-id: 3c5306c62bc13bb11abc03422ec5cbcea1203cca
106 lines
3.9 KiB
C++
106 lines
3.9 KiB
C++
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
|
|
// This source code is licensed under both the GPLv2 (found in the
|
|
// COPYING file in the root directory) and Apache 2.0 License
|
|
// (found in the LICENSE.Apache file in the root directory).
|
|
//
|
|
// 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.
|
|
|
|
#pragma once
|
|
#include <stdint.h>
|
|
#include <string>
|
|
#include "db/db_impl.h"
|
|
#include "db/dbformat.h"
|
|
#include "db/range_del_aggregator.h"
|
|
#include "options/cf_options.h"
|
|
#include "rocksdb/db.h"
|
|
#include "rocksdb/iterator.h"
|
|
#include "util/arena.h"
|
|
#include "util/autovector.h"
|
|
|
|
namespace rocksdb {
|
|
|
|
class Arena;
|
|
class DBIter;
|
|
class InternalIterator;
|
|
|
|
// Return a new iterator that converts internal keys (yielded by
|
|
// "*internal_iter") that were live at the specified "sequence" number
|
|
// into appropriate user keys.
|
|
extern Iterator* NewDBIterator(Env* env, const ReadOptions& read_options,
|
|
const ImmutableCFOptions& cf_options,
|
|
const Comparator* user_key_comparator,
|
|
InternalIterator* internal_iter,
|
|
const SequenceNumber& sequence,
|
|
uint64_t max_sequential_skip_in_iterations,
|
|
bool allow_blob = false);
|
|
|
|
// A wrapper iterator which wraps DB Iterator and the arena, with which the DB
|
|
// iterator is supposed be allocated. This class is used as an entry point of
|
|
// a iterator hierarchy whose memory can be allocated inline. In that way,
|
|
// accessing the iterator tree can be more cache friendly. It is also faster
|
|
// to allocate.
|
|
class ArenaWrappedDBIter : public Iterator {
|
|
public:
|
|
virtual ~ArenaWrappedDBIter();
|
|
|
|
// Get the arena to be used to allocate memory for DBIter to be wrapped,
|
|
// as well as child iterators in it.
|
|
virtual Arena* GetArena() { return &arena_; }
|
|
virtual RangeDelAggregator* GetRangeDelAggregator();
|
|
|
|
// Set the internal iterator wrapped inside the DB Iterator. Usually it is
|
|
// a merging iterator.
|
|
virtual void SetIterUnderDBIter(InternalIterator* iter);
|
|
virtual bool Valid() const override;
|
|
virtual void SeekToFirst() override;
|
|
virtual void SeekToLast() override;
|
|
virtual void Seek(const Slice& target) override;
|
|
virtual void SeekForPrev(const Slice& target) override;
|
|
virtual void Next() override;
|
|
virtual void Prev() override;
|
|
virtual Slice key() const override;
|
|
virtual Slice value() const override;
|
|
virtual Status status() const override;
|
|
virtual Status Refresh() override;
|
|
bool IsBlob() const;
|
|
|
|
virtual Status GetProperty(std::string prop_name, std::string* prop) override;
|
|
|
|
void Init(Env* env, const ReadOptions& read_options,
|
|
const ImmutableCFOptions& cf_options,
|
|
const SequenceNumber& sequence,
|
|
uint64_t max_sequential_skip_in_iterations, uint64_t version_number,
|
|
bool allow_blob);
|
|
|
|
void StoreRefreshInfo(const ReadOptions& read_options, DBImpl* db_impl,
|
|
ColumnFamilyData* cfd, bool allow_blob) {
|
|
read_options_ = read_options;
|
|
db_impl_ = db_impl;
|
|
cfd_ = cfd;
|
|
allow_blob_ = allow_blob;
|
|
}
|
|
|
|
private:
|
|
DBIter* db_iter_;
|
|
Arena arena_;
|
|
uint64_t sv_number_;
|
|
ColumnFamilyData* cfd_ = nullptr;
|
|
DBImpl* db_impl_ = nullptr;
|
|
ReadOptions read_options_;
|
|
bool allow_blob_ = false;
|
|
};
|
|
|
|
// Generate the arena wrapped iterator class.
|
|
// `db_impl` and `cfd` are used for reneweal. If left null, renewal will not
|
|
// be supported.
|
|
extern ArenaWrappedDBIter* NewArenaWrappedDbIterator(
|
|
Env* env, const ReadOptions& read_options,
|
|
const ImmutableCFOptions& cf_options, const SequenceNumber& sequence,
|
|
uint64_t max_sequential_skip_in_iterations, uint64_t version_number,
|
|
DBImpl* db_impl = nullptr, ColumnFamilyData* cfd = nullptr,
|
|
bool allow_blob = false);
|
|
|
|
} // namespace rocksdb
|