MCPcopy Create free account
hub / github.com/ElementsProject/elements / MakeRoomForWrite

Method MakeRoomForWrite

src/leveldb/db/db_impl.cc:1321–1381  ·  view source on GitHub ↗

REQUIRES: mutex_ is held REQUIRES: this thread is currently at the front of the writer queue

Source from the content-addressed store, hash-verified

1319// REQUIRES: mutex_ is held
1320// REQUIRES: this thread is currently at the front of the writer queue
1321Status DBImpl::MakeRoomForWrite(bool force) {
1322 mutex_.AssertHeld();
1323 assert(!writers_.empty());
1324 bool allow_delay = !force;
1325 Status s;
1326 while (true) {
1327 if (!bg_error_.ok()) {
1328 // Yield previous error
1329 s = bg_error_;
1330 break;
1331 } else if (allow_delay && versions_->NumLevelFiles(0) >=
1332 config::kL0_SlowdownWritesTrigger) {
1333 // We are getting close to hitting a hard limit on the number of
1334 // L0 files. Rather than delaying a single write by several
1335 // seconds when we hit the hard limit, start delaying each
1336 // individual write by 1ms to reduce latency variance. Also,
1337 // this delay hands over some CPU to the compaction thread in
1338 // case it is sharing the same core as the writer.
1339 mutex_.Unlock();
1340 env_->SleepForMicroseconds(1000);
1341 allow_delay = false; // Do not delay a single write more than once
1342 mutex_.Lock();
1343 } else if (!force &&
1344 (mem_->ApproximateMemoryUsage() <= options_.write_buffer_size)) {
1345 // There is room in current memtable
1346 break;
1347 } else if (imm_ != nullptr) {
1348 // We have filled up the current memtable, but the previous
1349 // one is still being compacted, so we wait.
1350 Log(options_.info_log, "Current memtable full; waiting...\n");
1351 background_work_finished_signal_.Wait();
1352 } else if (versions_->NumLevelFiles(0) >= config::kL0_StopWritesTrigger) {
1353 // There are too many level-0 files.
1354 Log(options_.info_log, "Too many L0 files; waiting...\n");
1355 background_work_finished_signal_.Wait();
1356 } else {
1357 // Attempt to switch to a new memtable and trigger compaction of old
1358 assert(versions_->PrevLogNumber() == 0);
1359 uint64_t new_log_number = versions_->NewFileNumber();
1360 WritableFile* lfile = nullptr;
1361 s = env_->NewWritableFile(LogFileName(dbname_, new_log_number), &lfile);
1362 if (!s.ok()) {
1363 // Avoid chewing through file number space in a tight loop.
1364 versions_->ReuseFileNumber(new_log_number);
1365 break;
1366 }
1367 delete log_;
1368 delete logfile_;
1369 logfile_ = lfile;
1370 logfile_number_ = new_log_number;
1371 log_ = new log::Writer(lfile);
1372 imm_ = mem_;
1373 has_imm_.store(true, std::memory_order_release);
1374 mem_ = new MemTable(internal_comparator_);
1375 mem_->Ref();
1376 force = false; // Do not force another compaction if have room
1377 MaybeScheduleCompaction();
1378 }

Callers

nothing calls this directly

Calls 14

LogFunction · 0.85
LogFileNameFunction · 0.85
NumLevelFilesMethod · 0.80
UnlockMethod · 0.80
LockMethod · 0.80
PrevLogNumberMethod · 0.80
NewFileNumberMethod · 0.80
ReuseFileNumberMethod · 0.80
emptyMethod · 0.45
SleepForMicrosecondsMethod · 0.45
WaitMethod · 0.45

Tested by

no test coverage detected