diff --git a/db/memtable.h b/db/memtable.h index 0aeadce80..961707008 100644 --- a/db/memtable.h +++ b/db/memtable.h @@ -138,7 +138,7 @@ class MemTable { // As a cheap version of `ApproximateMemoryUsage()`, this function doens't // require external synchronization. The value may be less accurate though - size_t ApproximateMemoryUsageFast() { + size_t ApproximateMemoryUsageFast() const { return approximate_memory_usage_.load(std::memory_order_relaxed); } diff --git a/db/memtable_list.cc b/db/memtable_list.cc index 93ab2e77c..2d4c514e1 100644 --- a/db/memtable_list.cc +++ b/db/memtable_list.cc @@ -280,7 +280,7 @@ void MemTableListVersion::Remove(MemTable* m, } // return the total memory usage assuming the oldest flushed memtable is dropped -size_t MemTableListVersion::ApproximateMemoryUsageExcludingLast() { +size_t MemTableListVersion::ApproximateMemoryUsageExcludingLast() const { size_t total_memtable_size = 0; for (auto& memtable : memlist_) { total_memtable_size += memtable->ApproximateMemoryUsage(); @@ -566,7 +566,7 @@ size_t MemTableList::ApproximateUnflushedMemTablesMemoryUsage() { size_t MemTableList::ApproximateMemoryUsage() { return current_memory_usage_; } -size_t MemTableList::ApproximateMemoryUsageExcludingLast() { +size_t MemTableList::ApproximateMemoryUsageExcludingLast() const { size_t usage = current_memory_usage_excluding_last_.load(std::memory_order_relaxed); return usage; diff --git a/db/memtable_list.h b/db/memtable_list.h index d78a8b5ea..aad4fddea 100644 --- a/db/memtable_list.h +++ b/db/memtable_list.h @@ -162,7 +162,7 @@ class MemTableListVersion { // excluding the last MemTable in memlist_history_. The reason for excluding // the last MemTable is to see if dropping the last MemTable will keep total // memory usage above or equal to max_write_buffer_size_to_maintain_ - size_t ApproximateMemoryUsageExcludingLast(); + size_t ApproximateMemoryUsageExcludingLast() const; bool MemtableLimitExceeded(size_t usage); @@ -267,7 +267,7 @@ class MemTableList { size_t ApproximateMemoryUsage(); // Returns the cached current_memory_usage_excluding_last_ value - size_t ApproximateMemoryUsageExcludingLast(); + size_t ApproximateMemoryUsageExcludingLast() const; // Update current_memory_usage_excluding_last_ from MemtableListVersion void UpdateMemoryUsageExcludingLast(); diff --git a/db/write_batch.cc b/db/write_batch.cc index 350c1a1c0..71104ea35 100644 --- a/db/write_batch.cc +++ b/db/write_batch.cc @@ -1784,14 +1784,28 @@ class MemTableInserter : public WriteBatch::Handler { // check if memtable_list size exceeds max_write_buffer_size_to_maintain if (trim_history_scheduler_ != nullptr) { auto* cfd = cf_mems_->current(); - assert(cfd != nullptr); - if (cfd->ioptions()->max_write_buffer_size_to_maintain > 0 && - cfd->mem()->ApproximateMemoryUsageFast() + - cfd->imm()->ApproximateMemoryUsageExcludingLast() >= - static_cast( - cfd->ioptions()->max_write_buffer_size_to_maintain) && - cfd->imm()->MarkTrimHistoryNeeded()) { - trim_history_scheduler_->ScheduleWork(cfd); + + assert(cfd); + assert(cfd->ioptions()); + + const size_t size_to_maintain = static_cast( + cfd->ioptions()->max_write_buffer_size_to_maintain); + + if (size_to_maintain > 0) { + MemTableList* const imm = cfd->imm(); + assert(imm); + + if (imm->NumFlushed() > 0) { + const MemTable* const mem = cfd->mem(); + assert(mem); + + if (mem->ApproximateMemoryUsageFast() + + imm->ApproximateMemoryUsageExcludingLast() >= + size_to_maintain && + imm->MarkTrimHistoryNeeded()) { + trim_history_scheduler_->ScheduleWork(cfd); + } + } } } }