[RocksDB Performance Branch] DBImpl.NewInternalIterator() to reduce works inside mutex
Summary: To reduce mutex contention caused by DBImpl.NewInternalIterator(), in this function, move all the iteration creation works out of mutex, only leaving object ref and get. Test Plan: make all check will run db_stress for a while too to make sure no problem. Reviewers: haobo, dhruba, kailiu Reviewed By: haobo CC: igor, leveldb Differential Revision: https://reviews.facebook.net/D14589
This commit is contained in:
parent
aaf9c6203c
commit
e8ab1934d9
@ -2528,39 +2528,40 @@ static void CleanupIteratorState(void* arg1, void* arg2) {
|
|||||||
Iterator* DBImpl::NewInternalIterator(const ReadOptions& options,
|
Iterator* DBImpl::NewInternalIterator(const ReadOptions& options,
|
||||||
SequenceNumber* latest_snapshot) {
|
SequenceNumber* latest_snapshot) {
|
||||||
IterState* cleanup = new IterState;
|
IterState* cleanup = new IterState;
|
||||||
mutex_.Lock();
|
MemTable* mutable_mem;
|
||||||
*latest_snapshot = versions_->LastSequence();
|
std::vector<MemTable*> immutables;
|
||||||
|
Version* version;
|
||||||
|
|
||||||
// Collect together all needed child iterators for mem
|
// Collect together all needed child iterators for mem
|
||||||
std::vector<Iterator*> list;
|
mutex_.Lock();
|
||||||
|
*latest_snapshot = versions_->LastSequence();
|
||||||
mem_->Ref();
|
mem_->Ref();
|
||||||
list.push_back(mem_->NewIterator(options));
|
mutable_mem = mem_;
|
||||||
|
|
||||||
cleanup->mem.push_back(mem_);
|
|
||||||
|
|
||||||
// Collect together all needed child iterators for imm_
|
// Collect together all needed child iterators for imm_
|
||||||
std::vector<MemTable*> immutables;
|
|
||||||
imm_.GetMemTables(&immutables);
|
imm_.GetMemTables(&immutables);
|
||||||
for (unsigned int i = 0; i < immutables.size(); i++) {
|
for (unsigned int i = 0; i < immutables.size(); i++) {
|
||||||
MemTable* m = immutables[i];
|
immutables[i]->Ref();
|
||||||
m->Ref();
|
}
|
||||||
|
// Collect iterators for files in L0 - Ln
|
||||||
|
versions_->current()->Ref();
|
||||||
|
version = versions_->current();
|
||||||
|
mutex_.Unlock();
|
||||||
|
|
||||||
|
std::vector<Iterator*> list;
|
||||||
|
list.push_back(mutable_mem->NewIterator(options));
|
||||||
|
cleanup->mem.push_back(mutable_mem);
|
||||||
|
for (MemTable* m : immutables) {
|
||||||
list.push_back(m->NewIterator(options));
|
list.push_back(m->NewIterator(options));
|
||||||
cleanup->mem.push_back(m);
|
cleanup->mem.push_back(m);
|
||||||
}
|
}
|
||||||
|
version->AddIterators(options, storage_options_, &list);
|
||||||
// Collect iterators for files in L0 - Ln
|
|
||||||
versions_->current()->AddIterators(options, storage_options_, &list);
|
|
||||||
Iterator* internal_iter =
|
Iterator* internal_iter =
|
||||||
NewMergingIterator(env_, &internal_comparator_, &list[0], list.size());
|
NewMergingIterator(env_, &internal_comparator_, &list[0], list.size());
|
||||||
versions_->current()->Ref();
|
cleanup->version = version;
|
||||||
|
|
||||||
cleanup->mu = &mutex_;
|
cleanup->mu = &mutex_;
|
||||||
cleanup->db = this;
|
cleanup->db = this;
|
||||||
cleanup->version = versions_->current();
|
|
||||||
internal_iter->RegisterCleanup(CleanupIteratorState, cleanup, nullptr);
|
internal_iter->RegisterCleanup(CleanupIteratorState, cleanup, nullptr);
|
||||||
|
|
||||||
mutex_.Unlock();
|
|
||||||
LogFlush(options_.info_log);
|
|
||||||
return internal_iter;
|
return internal_iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user