diff --git a/arangod/Cache/Cache.cpp b/arangod/Cache/Cache.cpp index 1895623a5b..d324891375 100644 --- a/arangod/Cache/Cache.cpp +++ b/arangod/Cache/Cache.cpp @@ -283,6 +283,11 @@ bool Cache::reportInsert(bool hadEviction) { if (((++_insertsTotal) & _evictionMask) == 0) { if (_insertEvictions.load() > _evictionThreshold) { shouldMigrate = true; + bool ok = _state.lock(triesGuarantee); + if (ok) { + _table->signalEvictions(); + _state.unlock(); + } } _insertEvictions = 0; } diff --git a/arangod/Cache/State.h b/arangod/Cache/State.h index 69e3550e17..1be364a255 100644 --- a/arangod/Cache/State.h +++ b/arangod/Cache/State.h @@ -59,12 +59,13 @@ struct State { locked = 0x00000001, blacklisted = 0x00000002, disabled = 0x00000004, - migrated = 0x00000008, - migrating = 0x00000010, - rebalancing = 0x00000020, - resizing = 0x00000040, - shutdown = 0x00000080, - shuttingDown = 0x00000100 + evictions = 0x00000008, + migrated = 0x00000010, + migrating = 0x00000020, + rebalancing = 0x00000040, + resizing = 0x00000080, + shutdown = 0x00000100, + shuttingDown = 0x00000200, }; ////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Cache/Table.cpp b/arangod/Cache/Table.cpp index 003afba999..5fe2db1af0 100644 --- a/arangod/Cache/Table.cpp +++ b/arangod/Cache/Table.cpp @@ -243,7 +243,30 @@ bool Table::slotEmptied() { (_logSize > Table::minLogSize)); } -uint32_t Table::idealSize() const { +void Table::signalEvictions() { + bool ok = _state.lock(triesGuarantee); + if (ok) { + if (!_state.isSet(State::Flag::evictions)) { + _state.toggleFlag(State::Flag::evictions); + } + _state.unlock(); + } +} + +uint32_t Table::idealSize() { + bool ok = _state.lock(triesGuarantee); + bool forceGrowth = false; + if (ok) { + forceGrowth = _state.isSet(State::Flag::evictions); + if (forceGrowth) { + _state.toggleFlag(State::Flag::evictions); + } + _state.unlock(); + } + if (forceGrowth) { + return logSize() + 1; + } + return (((static_cast(_slotsUsed.load()) / static_cast(_slotsTotal)) > Table::idealUpperRatio) ? (logSize() + 1) diff --git a/arangod/Cache/Table.h b/arangod/Cache/Table.h index 9cac913ea2..c4779689a3 100644 --- a/arangod/Cache/Table.h +++ b/arangod/Cache/Table.h @@ -173,10 +173,17 @@ class Table : public std::enable_shared_from_this { ////////////////////////////////////////////////////////////////////////////// bool slotEmptied(); + ////////////////////////////////////////////////////////////////////////////// + /// @brief Report that there have been too many evictions. + /// + /// Will force a subsequent idealSize() call to return a larger table size. + ////////////////////////////////////////////////////////////////////////////// + void signalEvictions(); + ////////////////////////////////////////////////////////////////////////////// /// @brief Returns the ideal size of the table based on fill ratio. ////////////////////////////////////////////////////////////////////////////// - uint32_t idealSize() const; + uint32_t idealSize(); private: static constexpr double idealLowerRatio = 0.05;