cfd->GetName().c_str(), m->file_number_, mem_id);
assert(m->file_number_ > 0);
current_->Remove(m, to_delete);
- UpdateMemoryUsageExcludingLast();
+ UpdateCachedValuesFromMemTableListVersion();
ResetTrimHistoryNeeded();
++mem_id;
}
if (num_flush_not_started_ == 1) {
imm_flush_needed.store(true, std::memory_order_release);
}
- UpdateMemoryUsageExcludingLast();
+ UpdateCachedValuesFromMemTableListVersion();
ResetTrimHistoryNeeded();
}
void MemTableList::TrimHistory(autovector<MemTable*>* to_delete, size_t usage) {
InstallNewVersion();
current_->TrimHistory(to_delete, usage);
- UpdateMemoryUsageExcludingLast();
+ UpdateCachedValuesFromMemTableListVersion();
ResetTrimHistoryNeeded();
}
size_t MemTableList::ApproximateMemoryUsage() { return current_memory_usage_; }
size_t MemTableList::ApproximateMemoryUsageExcludingLast() const {
- size_t usage =
+ const size_t usage =
current_memory_usage_excluding_last_.load(std::memory_order_relaxed);
return usage;
}
-// Update current_memory_usage_excluding_last_, need to call whenever state
-// changes for MemtableListVersion (whenever InstallNewVersion() is called)
-void MemTableList::UpdateMemoryUsageExcludingLast() {
- size_t total_memtable_size = current_->ApproximateMemoryUsageExcludingLast();
+bool MemTableList::HasHistory() const {
+ const bool has_history = current_has_history_.load(std::memory_order_relaxed);
+ return has_history;
+}
+
+void MemTableList::UpdateCachedValuesFromMemTableListVersion() {
+ const size_t total_memtable_size =
+ current_->ApproximateMemoryUsageExcludingLast();
current_memory_usage_excluding_last_.store(total_memtable_size,
std::memory_order_relaxed);
+
+ const bool has_history = current_->HasHistory();
+ current_has_history_.store(has_history, std::memory_order_relaxed);
}
uint64_t MemTableList::ApproximateOldestKeyTime() const {
cfds[i]->GetName().c_str(), m->GetFileNumber(),
mem_id);
imm->current_->Remove(m, to_delete);
- imm->UpdateMemoryUsageExcludingLast();
+ imm->UpdateCachedValuesFromMemTableListVersion();
imm->ResetTrimHistoryNeeded();
}
}
imm_flush_needed.store(false, std::memory_order_release);
}
}
- UpdateMemoryUsageExcludingLast();
+
+ UpdateCachedValuesFromMemTableListVersion();
ResetTrimHistoryNeeded();
}
// memory usage above or equal to max_write_buffer_size_to_maintain_
size_t ApproximateMemoryUsageExcludingLast() const;
+ // Whether this version contains flushed memtables that are only kept around
+ // for transaction conflict checking.
+ bool HasHistory() const { return !memlist_history_.empty(); }
+
bool MemtableLimitExceeded(size_t usage);
// Immutable MemTables that have not yet been flushed.
commit_in_progress_(false),
flush_requested_(false),
current_memory_usage_(0),
- current_memory_usage_excluding_last_(0) {
+ current_memory_usage_excluding_last_(0),
+ current_has_history_(false) {
current_->Ref();
}
// Returns an estimate of the number of bytes of data in use.
size_t ApproximateMemoryUsage();
- // Returns the cached current_memory_usage_excluding_last_ value
+ // Returns the cached current_memory_usage_excluding_last_ value.
size_t ApproximateMemoryUsageExcludingLast() const;
- // Update current_memory_usage_excluding_last_ from MemtableListVersion
- void UpdateMemoryUsageExcludingLast();
+ // Returns the cached current_has_history_ value.
+ bool HasHistory() const;
+
+ // Updates current_memory_usage_excluding_last_ and current_has_history_
+ // from MemTableListVersion. Must be called whenever InstallNewVersion is
+ // called.
+ void UpdateCachedValuesFromMemTableListVersion();
// `usage` is the current size of the mutable Memtable. When
// max_write_buffer_size_to_maintain is used, total size of mutable and
// The current memory usage.
size_t current_memory_usage_;
+ // Cached value of current_->ApproximateMemoryUsageExcludingLast().
std::atomic<size_t> current_memory_usage_excluding_last_;
+
+ // Cached value of current_->HasHistory().
+ std::atomic<bool> current_has_history_;
};
// Installs memtable atomic flush results.