From 552ca8995958aa3765614df00225e4898fa337d2 Mon Sep 17 00:00:00 2001 From: Simone Mainardi Date: Thu, 31 Oct 2019 09:54:00 +0100 Subject: [PATCH] Counts also idle entries to honor -X and -x --- include/GenericHash.h | 10 +++++++++- src/GenericHash.cpp | 25 ++++++++++++++++++++----- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/include/GenericHash.h b/include/GenericHash.h index 65856b4479ba..06612ade389f 100644 --- a/include/GenericHash.h +++ b/include/GenericHash.h @@ -85,6 +85,14 @@ class GenericHash { */ inline u_int32_t getNumEntries() { return(current_size); }; + /** + * @brief Get number of idle entries, that is, entries no longer in the hash table but still to be purged. + * @details Inline method. + * + * @return The number of idle entries. + */ + int32_t getNumIdleEntries() const; + /** * @brief Add new entry to generic hash. * @details If current_size < max_hash_size, this method calculate a new hash key for the new entry, add it and update the current_size value. @@ -156,7 +164,7 @@ class GenericHash { * * @return true if there is space left, or false if the hash is full */ - inline bool hasEmptyRoom() { return((current_size < max_hash_size) ? true : false); }; + bool hasEmptyRoom(); /** * @brief Populates a lua table with hash table stats, including diff --git a/src/GenericHash.cpp b/src/GenericHash.cpp index 6266dd9aa711..73a50aabc133 100644 --- a/src/GenericHash.cpp +++ b/src/GenericHash.cpp @@ -342,8 +342,23 @@ u_int GenericHash::purgeIdle(bool force_idle) { /* ************************************ */ +int32_t GenericHash::getNumIdleEntries() const { + return entry_state_transition_counters.num_idle_transitions - entry_state_transition_counters.num_purged; +}; + +/* ************************************ */ + +bool GenericHash::hasEmptyRoom() { + /* Allow the total number of entries (that is, active and those idle but still not yet purged) + to be 30% more than the maximum hash table size specified. This prevents memory from growing + indefinitely when for example the purging is slow. */ + return getNumEntries() + getNumIdleEntries() <= max_hash_size * 1.3; +}; + +/* ************************************ */ + void GenericHash::lua(lua_State *vm) { - int64_t delta; + int64_t num_idle; lua_newtable(vm); @@ -357,11 +372,11 @@ void GenericHash::lua(lua_State *vm) { entry_state_transition_counters.num_purged); #endif - delta = entry_state_transition_counters.num_idle_transitions - entry_state_transition_counters.num_purged; - if(delta < 0) - ntop->getTrace()->traceEvent(TRACE_ERROR, "Internal error: unexpected number of entries in state [iface: %s][%s][hash_entry_state_idle: %i][num_idle_transitions: %u][num_purged: %u]", iface ? iface->get_name(): "", name, delta, entry_state_transition_counters.num_idle_transitions, entry_state_transition_counters.num_purged); + num_idle = getNumIdleEntries(); + if(num_idle < 0) + ntop->getTrace()->traceEvent(TRACE_ERROR, "Internal error: unexpected number of entries in state [iface: %s][%s][hash_entry_state_idle: %i][num_idle_transitions: %u][num_purged: %u]", iface ? iface->get_name(): "", name, num_idle, entry_state_transition_counters.num_idle_transitions, entry_state_transition_counters.num_purged); else - lua_push_uint64_table_entry(vm, "hash_entry_state_idle", (u_int64_t)delta); + lua_push_uint64_table_entry(vm, "hash_entry_state_idle", (u_int64_t)num_idle); lua_push_uint64_table_entry(vm, "hash_entry_state_active", (u_int64_t)getNumEntries());