[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:
Siying Dong 2013-12-12 10:54:03 -08:00
parent aaf9c6203c
commit e8ab1934d9

View File

@ -2528,39 +2528,40 @@ static void CleanupIteratorState(void* arg1, void* arg2) {
Iterator* DBImpl::NewInternalIterator(const ReadOptions& options,
SequenceNumber* latest_snapshot) {
IterState* cleanup = new IterState;
mutex_.Lock();
*latest_snapshot = versions_->LastSequence();
MemTable* mutable_mem;
std::vector<MemTable*> immutables;
Version* version;
// Collect together all needed child iterators for mem
std::vector<Iterator*> list;
mutex_.Lock();
*latest_snapshot = versions_->LastSequence();
mem_->Ref();
list.push_back(mem_->NewIterator(options));
cleanup->mem.push_back(mem_);
mutable_mem = mem_;
// Collect together all needed child iterators for imm_
std::vector<MemTable*> immutables;
imm_.GetMemTables(&immutables);
for (unsigned int i = 0; i < immutables.size(); i++) {
MemTable* m = immutables[i];
m->Ref();
immutables[i]->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));
cleanup->mem.push_back(m);
}
// Collect iterators for files in L0 - Ln
versions_->current()->AddIterators(options, storage_options_, &list);
version->AddIterators(options, storage_options_, &list);
Iterator* internal_iter =
NewMergingIterator(env_, &internal_comparator_, &list[0], list.size());
versions_->current()->Ref();
cleanup->version = version;
cleanup->mu = &mutex_;
cleanup->db = this;
cleanup->version = versions_->current();
internal_iter->RegisterCleanup(CleanupIteratorState, cleanup, nullptr);
mutex_.Unlock();
LogFlush(options_.info_log);
return internal_iter;
}