Remove the unnecessary use of shared_ptr
Summary: shared_ptr is slower than unique_ptr (which literally comes with no performance cost compare with raw pointers). In memtable and memtable rep, we use shared_ptr when we'd actually should use unique_ptr. According to igor's previous work, we are likely to make quite some performance gain from this diff. Test Plan: make check Reviewers: dhruba, igor, sdong, haobo CC: leveldb Differential Revision: https://reviews.facebook.net/D15213
This commit is contained in:
parent
787f11bb3b
commit
eae1804f29
@ -85,11 +85,11 @@ class MemTableIterator: public Iterator {
|
||||
MemTableIterator(MemTableRep* table, const ReadOptions& options)
|
||||
: iter_() {
|
||||
if (options.prefix) {
|
||||
iter_ = table->GetPrefixIterator(*options.prefix);
|
||||
iter_.reset(table->GetPrefixIterator(*options.prefix));
|
||||
} else if (options.prefix_seek) {
|
||||
iter_ = table->GetDynamicPrefixIterator();
|
||||
iter_.reset(table->GetDynamicPrefixIterator());
|
||||
} else {
|
||||
iter_ = table->GetIterator();
|
||||
iter_.reset(table->GetIterator());
|
||||
}
|
||||
}
|
||||
|
||||
@ -110,7 +110,7 @@ class MemTableIterator: public Iterator {
|
||||
virtual Status status() const { return Status::OK(); }
|
||||
|
||||
private:
|
||||
std::shared_ptr<MemTableRep::Iterator> iter_;
|
||||
std::unique_ptr<MemTableRep::Iterator> iter_;
|
||||
std::string tmp_; // For passing to EncodeKey
|
||||
|
||||
// No copying allowed
|
||||
@ -161,7 +161,7 @@ void MemTable::Add(SequenceNumber s, ValueType type,
|
||||
bool MemTable::Get(const LookupKey& key, std::string* value, Status* s,
|
||||
MergeContext& merge_context, const Options& options) {
|
||||
Slice memkey = key.memtable_key();
|
||||
std::shared_ptr<MemTableRep::Iterator> iter(
|
||||
std::unique_ptr<MemTableRep::Iterator> iter(
|
||||
table_->GetIterator(key.user_key()));
|
||||
iter->Seek(memkey.data());
|
||||
|
||||
@ -267,7 +267,7 @@ bool MemTable::Update(SequenceNumber seq, ValueType type,
|
||||
LookupKey lkey(key, seq);
|
||||
Slice memkey = lkey.memtable_key();
|
||||
|
||||
std::shared_ptr<MemTableRep::Iterator> iter(
|
||||
std::unique_ptr<MemTableRep::Iterator> iter(
|
||||
table_->GetIterator(lkey.user_key()));
|
||||
iter->Seek(memkey.data());
|
||||
|
||||
@ -329,7 +329,7 @@ size_t MemTable::CountSuccessiveMergeEntries(const LookupKey& key) {
|
||||
// A total ordered iterator is costly for some memtablerep (prefix aware
|
||||
// reps). By passing in the user key, we allow efficient iterator creation.
|
||||
// The iterator only needs to be ordered within the same user key.
|
||||
std::shared_ptr<MemTableRep::Iterator> iter(
|
||||
std::unique_ptr<MemTableRep::Iterator> iter(
|
||||
table_->GetIterator(key.user_key()));
|
||||
iter->Seek(memkey.data());
|
||||
|
||||
|
@ -143,7 +143,7 @@ class MemTable {
|
||||
KeyComparator comparator_;
|
||||
int refs_;
|
||||
ArenaImpl arena_impl_;
|
||||
shared_ptr<MemTableRep> table_;
|
||||
unique_ptr<MemTableRep> table_;
|
||||
|
||||
// These are used to manage memtable flushes to storage
|
||||
bool flush_in_progress_; // started the flush
|
||||
|
@ -111,27 +111,23 @@ class MemTableRep {
|
||||
};
|
||||
|
||||
// Return an iterator over the keys in this representation.
|
||||
virtual std::shared_ptr<Iterator> GetIterator() = 0;
|
||||
virtual Iterator* GetIterator() = 0;
|
||||
|
||||
// Return an iterator over at least the keys with the specified user key. The
|
||||
// iterator may also allow access to other keys, but doesn't have to. Default:
|
||||
// GetIterator().
|
||||
virtual std::shared_ptr<Iterator> GetIterator(const Slice& user_key) {
|
||||
return GetIterator();
|
||||
}
|
||||
virtual Iterator* GetIterator(const Slice& user_key) { return GetIterator(); }
|
||||
|
||||
// Return an iterator over at least the keys with the specified prefix. The
|
||||
// iterator may also allow access to other keys, but doesn't have to. Default:
|
||||
// GetIterator().
|
||||
virtual std::shared_ptr<Iterator> GetPrefixIterator(const Slice& prefix) {
|
||||
virtual Iterator* GetPrefixIterator(const Slice& prefix) {
|
||||
return GetIterator();
|
||||
}
|
||||
|
||||
// Return an iterator that has a special Seek semantics. The result of
|
||||
// a Seek might only include keys with the same prefix as the target key.
|
||||
virtual std::shared_ptr<Iterator> GetDynamicPrefixIterator() {
|
||||
return GetIterator();
|
||||
}
|
||||
virtual Iterator* GetDynamicPrefixIterator() { return GetIterator(); }
|
||||
|
||||
protected:
|
||||
// When *key is an internal key concatenated with the value, returns the
|
||||
@ -144,8 +140,8 @@ class MemTableRep {
|
||||
class MemTableRepFactory {
|
||||
public:
|
||||
virtual ~MemTableRepFactory() { };
|
||||
virtual std::shared_ptr<MemTableRep> CreateMemTableRep(
|
||||
MemTableRep::KeyComparator&, Arena*) = 0;
|
||||
virtual MemTableRep* CreateMemTableRep(MemTableRep::KeyComparator&,
|
||||
Arena*) = 0;
|
||||
virtual const char* Name() const = 0;
|
||||
};
|
||||
|
||||
@ -161,8 +157,8 @@ class VectorRepFactory : public MemTableRepFactory {
|
||||
const size_t count_;
|
||||
public:
|
||||
explicit VectorRepFactory(size_t count = 0) : count_(count) { }
|
||||
virtual std::shared_ptr<MemTableRep> CreateMemTableRep(
|
||||
MemTableRep::KeyComparator&, Arena*) override;
|
||||
virtual MemTableRep* CreateMemTableRep(MemTableRep::KeyComparator&,
|
||||
Arena*) override;
|
||||
virtual const char* Name() const override {
|
||||
return "VectorRepFactory";
|
||||
}
|
||||
@ -171,8 +167,8 @@ public:
|
||||
// This uses a skip list to store keys. It is the default.
|
||||
class SkipListFactory : public MemTableRepFactory {
|
||||
public:
|
||||
virtual std::shared_ptr<MemTableRep> CreateMemTableRep(
|
||||
MemTableRep::KeyComparator&, Arena*) override;
|
||||
virtual MemTableRep* CreateMemTableRep(MemTableRep::KeyComparator&,
|
||||
Arena*) override;
|
||||
virtual const char* Name() const override {
|
||||
return "SkipListFactory";
|
||||
}
|
||||
|
@ -31,17 +31,15 @@ class HashSkipListRep : public MemTableRep {
|
||||
|
||||
virtual ~HashSkipListRep();
|
||||
|
||||
virtual std::shared_ptr<MemTableRep::Iterator> GetIterator() override;
|
||||
virtual MemTableRep::Iterator* GetIterator() override;
|
||||
|
||||
virtual std::shared_ptr<MemTableRep::Iterator> GetIterator(
|
||||
const Slice& slice) override;
|
||||
virtual MemTableRep::Iterator* GetIterator(const Slice& slice) override;
|
||||
|
||||
virtual std::shared_ptr<MemTableRep::Iterator> GetPrefixIterator(
|
||||
const Slice& prefix) override;
|
||||
|
||||
virtual std::shared_ptr<MemTableRep::Iterator> GetDynamicPrefixIterator()
|
||||
virtual MemTableRep::Iterator* GetPrefixIterator(const Slice& prefix)
|
||||
override;
|
||||
|
||||
virtual MemTableRep::Iterator* GetDynamicPrefixIterator() override;
|
||||
|
||||
private:
|
||||
friend class DynamicIterator;
|
||||
typedef SkipList<const char*, MemTableRep::KeyComparator&> Bucket;
|
||||
@ -208,18 +206,15 @@ class HashSkipListRep : public MemTableRep {
|
||||
virtual void SeekToLast() { }
|
||||
private:
|
||||
};
|
||||
|
||||
std::shared_ptr<EmptyIterator> empty_iterator_;
|
||||
};
|
||||
|
||||
HashSkipListRep::HashSkipListRep(MemTableRep::KeyComparator& compare,
|
||||
Arena* arena, const SliceTransform* transform, size_t bucket_size)
|
||||
Arena* arena, const SliceTransform* transform,
|
||||
size_t bucket_size)
|
||||
: bucket_size_(bucket_size),
|
||||
transform_(transform),
|
||||
compare_(compare),
|
||||
arena_(arena),
|
||||
empty_iterator_(std::make_shared<EmptyIterator>()) {
|
||||
|
||||
arena_(arena) {
|
||||
buckets_ = new port::AtomicPointer[bucket_size];
|
||||
|
||||
for (size_t i = 0; i < bucket_size_; ++i) {
|
||||
@ -263,7 +258,7 @@ size_t HashSkipListRep::ApproximateMemoryUsage() {
|
||||
return sizeof(buckets_);
|
||||
}
|
||||
|
||||
std::shared_ptr<MemTableRep::Iterator> HashSkipListRep::GetIterator() {
|
||||
MemTableRep::Iterator* HashSkipListRep::GetIterator() {
|
||||
auto list = new Bucket(compare_, arena_);
|
||||
for (size_t i = 0; i < bucket_size_; ++i) {
|
||||
auto bucket = GetBucket(i);
|
||||
@ -274,35 +269,30 @@ std::shared_ptr<MemTableRep::Iterator> HashSkipListRep::GetIterator() {
|
||||
}
|
||||
}
|
||||
}
|
||||
return std::make_shared<Iterator>(list);
|
||||
return new Iterator(list);
|
||||
}
|
||||
|
||||
std::shared_ptr<MemTableRep::Iterator> HashSkipListRep::GetPrefixIterator(
|
||||
const Slice& prefix) {
|
||||
MemTableRep::Iterator* HashSkipListRep::GetPrefixIterator(const Slice& prefix) {
|
||||
auto bucket = GetBucket(prefix);
|
||||
if (bucket == nullptr) {
|
||||
return empty_iterator_;
|
||||
return new EmptyIterator();
|
||||
}
|
||||
return std::make_shared<Iterator>(bucket, false);
|
||||
return new Iterator(bucket, false);
|
||||
}
|
||||
|
||||
std::shared_ptr<MemTableRep::Iterator> HashSkipListRep::GetIterator(
|
||||
const Slice& slice) {
|
||||
MemTableRep::Iterator* HashSkipListRep::GetIterator(const Slice& slice) {
|
||||
return GetPrefixIterator(transform_->Transform(slice));
|
||||
}
|
||||
|
||||
std::shared_ptr<MemTableRep::Iterator>
|
||||
HashSkipListRep::GetDynamicPrefixIterator() {
|
||||
return std::make_shared<DynamicIterator>(*this);
|
||||
MemTableRep::Iterator* HashSkipListRep::GetDynamicPrefixIterator() {
|
||||
return new DynamicIterator(*this);
|
||||
}
|
||||
|
||||
} // anon namespace
|
||||
|
||||
std::shared_ptr<MemTableRep>
|
||||
HashSkipListRepFactory::CreateMemTableRep(MemTableRep::KeyComparator &compare,
|
||||
Arena *arena) {
|
||||
return std::make_shared<HashSkipListRep>(compare, arena, transform_,
|
||||
bucket_count_);
|
||||
MemTableRep* HashSkipListRepFactory::CreateMemTableRep(
|
||||
MemTableRep::KeyComparator& compare, Arena* arena) {
|
||||
return new HashSkipListRep(compare, arena, transform_, bucket_count_);
|
||||
}
|
||||
|
||||
MemTableRepFactory* NewHashSkipListRepFactory(
|
||||
|
@ -21,8 +21,8 @@ class HashSkipListRepFactory : public MemTableRepFactory {
|
||||
|
||||
virtual ~HashSkipListRepFactory() { delete transform_; }
|
||||
|
||||
virtual std::shared_ptr<MemTableRep> CreateMemTableRep(
|
||||
MemTableRep::KeyComparator& compare, Arena* arena) override;
|
||||
virtual MemTableRep* CreateMemTableRep(MemTableRep::KeyComparator& compare,
|
||||
Arena* arena) override;
|
||||
|
||||
virtual const char* Name() const override {
|
||||
return "HashSkipListRepFactory";
|
||||
|
@ -90,15 +90,15 @@ public:
|
||||
// Unhide default implementations of GetIterator
|
||||
using MemTableRep::GetIterator;
|
||||
|
||||
virtual std::shared_ptr<MemTableRep::Iterator> GetIterator() override {
|
||||
return std::make_shared<SkipListRep::Iterator>(&skip_list_);
|
||||
virtual MemTableRep::Iterator* GetIterator() override {
|
||||
return new SkipListRep::Iterator(&skip_list_);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
std::shared_ptr<MemTableRep> SkipListFactory::CreateMemTableRep (
|
||||
MemTableRep* SkipListFactory::CreateMemTableRep(
|
||||
MemTableRep::KeyComparator& compare, Arena* arena) {
|
||||
return std::shared_ptr<MemTableRep>(new SkipListRep(compare, arena));
|
||||
return new SkipListRep(compare, arena);
|
||||
}
|
||||
|
||||
} // namespace rocksdb
|
||||
|
@ -88,7 +88,7 @@ class VectorRep : public MemTableRep {
|
||||
using MemTableRep::GetIterator;
|
||||
|
||||
// Return an iterator over the keys in this representation.
|
||||
virtual std::shared_ptr<MemTableRep::Iterator> GetIterator() override;
|
||||
virtual MemTableRep::Iterator* GetIterator() override;
|
||||
|
||||
private:
|
||||
friend class Iterator;
|
||||
@ -228,22 +228,22 @@ void VectorRep::Iterator::SeekToLast() {
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<MemTableRep::Iterator> VectorRep::GetIterator() {
|
||||
MemTableRep::Iterator* VectorRep::GetIterator() {
|
||||
ReadLock l(&rwlock_);
|
||||
// Do not sort here. The sorting would be done the first time
|
||||
// a Seek is performed on the iterator.
|
||||
if (immutable_) {
|
||||
return std::make_shared<Iterator>(this, bucket_, compare_);
|
||||
return new Iterator(this, bucket_, compare_);
|
||||
} else {
|
||||
std::shared_ptr<Bucket> tmp;
|
||||
tmp.reset(new Bucket(*bucket_)); // make a copy
|
||||
return std::make_shared<Iterator>(nullptr, tmp, compare_);
|
||||
return new Iterator(nullptr, tmp, compare_);
|
||||
}
|
||||
}
|
||||
} // anon namespace
|
||||
|
||||
std::shared_ptr<MemTableRep> VectorRepFactory::CreateMemTableRep(
|
||||
MemTableRep* VectorRepFactory::CreateMemTableRep(
|
||||
MemTableRep::KeyComparator& compare, Arena* arena) {
|
||||
return std::make_shared<VectorRep>(compare, arena, count_);
|
||||
return new VectorRep(compare, arena, count_);
|
||||
}
|
||||
} // namespace rocksdb
|
||||
|
Loading…
Reference in New Issue
Block a user