This is an automated email from the ASF dual-hosted git repository.

zwoop pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/master by this push:
     new 42d86fea90 Improve seen list for the RAM cache (#10662)
42d86fea90 is described below

commit 42d86fea90085721d3f49e85c2589f8841cffd22
Author: Leif Hedstrom <[email protected]>
AuthorDate: Thu Apr 4 13:44:17 2024 -0600

    Improve seen list for the RAM cache (#10662)
---
 doc/admin-guide/files/records.yaml.en.rst | 11 ++++++++-
 src/iocore/cache/RamCacheLRU.cc           | 38 +++++++++++++++++++------------
 src/records/RecordsConfig.cc              |  2 +-
 3 files changed, 35 insertions(+), 16 deletions(-)

diff --git a/doc/admin-guide/files/records.yaml.en.rst 
b/doc/admin-guide/files/records.yaml.en.rst
index 6045e3d7f1..a1fdc5b7ae 100644
--- a/doc/admin-guide/files/records.yaml.en.rst
+++ b/doc/admin-guide/files/records.yaml.en.rst
@@ -2559,10 +2559,19 @@ RAM Cache
 
    Enabling this option will filter inserts into the RAM cache to ensure that
    they have been seen at least once.  For the **LRU**, this provides scan
-   resistance. Note that **CLFUS** already requires that a document have 
history
+   resistance.
+
+   As of ATS v10.0.0 and later, this setting can take values in the range 
``0`` to
+   ``9``. Values above ``1`` will only enable the seen filter after a certain
+   threshold of RAM cache usage has been reached.  The threshold is determined 
by
+   the value of this setting, with ``2`` being 50% filled, ``3`` being 67% 
filled,
+   and so on.
+
+   Note that **CLFUS** already requires that a document have history
    before it is inserted, so for **CLFUS**, setting this option means that a
    document must be seen three times before it is added to the RAM cache.
 
+
 .. ts:cv:: CONFIG proxy.config.cache.ram_cache.compress INT 0
 
    The **CLFUS** RAM cache also supports an optional in-memory compression.
diff --git a/src/iocore/cache/RamCacheLRU.cc b/src/iocore/cache/RamCacheLRU.cc
index 3da2e7644a..01f2d09c66 100644
--- a/src/iocore/cache/RamCacheLRU.cc
+++ b/src/iocore/cache/RamCacheLRU.cc
@@ -22,6 +22,8 @@
  */
 
 #include "P_Cache.h"
+#include <vector>
+#include <iterator>
 
 struct RamCacheLRUEntry {
   CryptoHash key;
@@ -47,7 +49,7 @@ struct RamCacheLRU : public RamCache {
   void init(int64_t max_bytes, Stripe *stripe) override;
 
   // private
-  uint16_t *seen = nullptr;
+  std::vector<bool> *seen = nullptr;
   Que(RamCacheLRUEntry, lru_link) lru;
   DList(RamCacheLRUEntry, hash_link) *bucket = nullptr;
   int nbuckets                               = 0;
@@ -84,13 +86,14 @@ RamCacheLRU::size() const
 
 ClassAllocator<RamCacheLRUEntry> ramCacheLRUEntryAllocator("RamCacheLRUEntry");
 
-static const int bucket_sizes[] = {127,     251,      509,      1021,     
2039,      4093,      8191,     16381,
-                                   32749,   65521,    131071,   262139,   
524287,    1048573,   2097143,  4194301,
-                                   8388593, 16777213, 33554393, 67108859, 
134217689, 268435399, 536870909};
+static const int bucket_sizes[] = {8191,    16381,   32749,    65521,    
131071,   262139,    524287,    1048573,   2097143,
+                                   4194301, 8388593, 16777213, 33554393, 
67108859, 134217689, 268435399, 536870909, 1073741827};
 
 void
 RamCacheLRU::resize_hashtable()
 {
+  ink_release_assert(ibuckets < static_cast<int>(std::size(bucket_sizes)));
+
   int anbuckets = bucket_sizes[ibuckets];
   DDbg(dbg_ctl_ram_cache, "resize hashtable %d", anbuckets);
   int64_t s                                      = anbuckets * 
sizeof(DList(RamCacheLRUEntry, hash_link));
@@ -107,11 +110,12 @@ RamCacheLRU::resize_hashtable()
   }
   bucket   = new_bucket;
   nbuckets = anbuckets;
-  ats_free(seen);
-  int size = bucket_sizes[ibuckets] * sizeof(uint16_t);
+  delete seen;
   if (cache_config_ram_cache_use_seen_filter) {
-    seen = static_cast<uint16_t *>(ats_malloc(size));
-    memset(seen, 0, size);
+    int size = bucket_sizes[ibuckets];
+
+    seen = new std::vector<bool>(size * 2); // Twice the size, to reduce 
collision risks.
+    seen->assign(size * 2, false);
   }
 }
 
@@ -181,15 +185,21 @@ RamCacheLRU::put(CryptoHash *key, IOBufferData *data, 
uint32_t len, bool, uint64
     return 0;
   }
   uint32_t i = key->slice32(3) % nbuckets;
-  if (cache_config_ram_cache_use_seen_filter) {
-    uint16_t k  = key->slice32(3) >> 16;
-    uint16_t kk = seen[i];
-    seen[i]     = k;
-    if ((kk != k)) {
+  if ((cache_config_ram_cache_use_seen_filter == 1) ||
+      // If proxy.config.cache.ram_cache.use_seen_filter is > 1,  and the 
cache is more than <n>% full, then use the seen filter.
+      // <n>% is calculated based on this setting, with 2 == 50%, 3 == 67%, 4 
== 75%, up to 9 == 90%.
+      ((cache_config_ram_cache_use_seen_filter > 1) && (bytes >= max_bytes * 
(1 - (1 / cache_config_ram_cache_use_seen_filter))))) {
+    uint32_t j = key->slice32(3) % (nbuckets * 2); // The seen filter bucket 
size is 2x
+
+    if (!(*seen)[j]) {
       DDbg(dbg_ctl_ram_cache, "put %X %" PRIu64 " len %d UNSEEN", 
key->slice32(3), auxkey, len);
+      (*seen)[j] = true;
       return 0;
+    } else {
+      (*seen)[j] = false; // Clear the seen filter slot for future entries.
     }
   }
+
   RamCacheLRUEntry *e = bucket[i].head;
   while (e) {
     if (e->key == *key) {
@@ -223,7 +233,7 @@ RamCacheLRU::put(CryptoHash *key, IOBufferData *data, 
uint32_t len, bool, uint64
     }
   }
   DDbg(dbg_ctl_ram_cache, "put %X %" PRIu64 " INSERTED", key->slice32(3), 
auxkey);
-  if (objects > nbuckets) {
+  if (objects > nbuckets * 0.75) { // Resize when 75% "full"
     ++ibuckets;
     resize_hashtable();
   }
diff --git a/src/records/RecordsConfig.cc b/src/records/RecordsConfig.cc
index 9e3df88167..a9546a4917 100644
--- a/src/records/RecordsConfig.cc
+++ b/src/records/RecordsConfig.cc
@@ -809,7 +809,7 @@ static const RecordElement RecordsConfig[] =
   ,
   {RECT_CONFIG, "proxy.config.cache.ram_cache.algorithm", RECD_INT, "1", 
RECU_RESTART_TS, RR_NULL, RECC_INT, "[0-1]", RECA_NULL}
   ,
-  {RECT_CONFIG, "proxy.config.cache.ram_cache.use_seen_filter", RECD_INT, "1", 
RECU_RESTART_TS, RR_NULL, RECC_INT, "[0-1]", RECA_NULL}
+  {RECT_CONFIG, "proxy.config.cache.ram_cache.use_seen_filter", RECD_INT, "1", 
RECU_RESTART_TS, RR_NULL, RECC_INT, "[0-9]", RECA_NULL}
   ,
   {RECT_CONFIG, "proxy.config.cache.ram_cache.compress", RECD_INT, "0", 
RECU_RESTART_TS, RR_NULL, RECC_INT, "[0-3]", RECA_NULL}
   ,

Reply via email to