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

masaori 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 53ea4f5600 Sever `PreservationTable` inheritance and add utility 
methods (#11731)
53ea4f5600 is described below

commit 53ea4f56001c168c220c93d0a2a97cd39750f937
Author: JosiahWI <[email protected]>
AuthorDate: Thu Aug 22 19:57:21 2024 -0500

    Sever `PreservationTable` inheritance and add utility methods (#11731)
    
    * Extract `PreservationTable::acquire`
    
    Each evacuation block is reference counted based on the number of readers
    accessing it (unless reference counting is disabled to force evacuation).
    This is why I've chosen the name `acquire` for the new method.
    
    * Extract `PreservationTable::release`
    
    This goes along with `PreservationTable::acquire` to do reference counting
    on evacuation blocks.
    
    * Extract private `PreservationTable::find`
    
    This is an internal utility method for finding a directory in a bucket.
    
    * Replace `PreservationTable` superclass with field
    
    * Extract public `PreservationTable::find`
    
    * Implement changes requested by Masaori Koshiba
    
     * Add _ prefix for private `_preserved_dirs` member
     * Restore bucket validity check to public `find` method
     * Use early return instead of goto
    
    * Fix narrowing conversion
---
 src/iocore/cache/CacheEvacuateDocVC.cc     | 142 ++++++++++++++---------------
 src/iocore/cache/P_CacheVol.h              |  29 +++++-
 src/iocore/cache/PreservationTable.cc      |  56 +++++++++++-
 src/iocore/cache/PreservationTable.h       |  61 +++++++++----
 src/iocore/cache/StripeSM.cc               |  62 +++----------
 src/iocore/cache/unit_tests/test_Stripe.cc |   8 +-
 6 files changed, 213 insertions(+), 145 deletions(-)

diff --git a/src/iocore/cache/CacheEvacuateDocVC.cc 
b/src/iocore/cache/CacheEvacuateDocVC.cc
index 5cfe610b3f..ad245ba74f 100644
--- a/src/iocore/cache/CacheEvacuateDocVC.cc
+++ b/src/iocore/cache/CacheEvacuateDocVC.cc
@@ -55,88 +55,82 @@ CacheEvacuateDocVC::evacuateDocDone(int /* event ATS_UNUSED 
*/, Event * /* e ATS
   DDbg(dbg_ctl_cache_evac, "evacuateDocDone %X o %d p %d new_o %d new_p %d", 
(int)key.slice32(0),
        (int)dir_offset(&this->overwrite_dir), 
(int)dir_phase(&this->overwrite_dir), (int)dir_offset(&this->dir),
        (int)dir_phase(&this->dir));
-  int i = dir_evac_bucket(&this->overwrite_dir);
   // nasty beeping race condition, need to have the EvacuationBlock here
-  EvacuationBlock *b = this->stripe->evac_bucket_valid(i) ? 
this->stripe->evacuate[i].head : nullptr;
-  for (; b; b = b->link.next) {
-    if (dir_offset(&b->dir) == dir_offset(&this->overwrite_dir)) {
-      // If the document is single fragment (although not tied to the vector),
-      // then we don't have to put the directory entry in the lookaside
-      // buffer. But, we have no way of finding out if the document is
-      // single fragment. doc->single_fragment() can be true for a multiple
-      // fragment document since total_len and doc->len could be equal at
-      // the time we write the fragment down. To be on the safe side, we
-      // only overwrite the entry in the directory if its not a head.
-      if (!dir_head(&this->overwrite_dir)) {
-        // find the earliest key
-        EvacuationKey *evac = &b->evac_frags;
-        for (; evac && !(evac->key == doc->key); evac = evac->link.next) {
-          ;
-        }
-        ink_assert(evac);
-        if (!evac) {
-          break;
-        }
-        if (evac->earliest_key.fold()) {
-          DDbg(dbg_ctl_cache_evac, "evacdocdone: evacuating key %X earliest 
%X", evac->key.slice32(0),
-               evac->earliest_key.slice32(0));
-          EvacuationBlock *eblock = nullptr;
-          Dir              dir_tmp;
-          dir_lookaside_probe(&evac->earliest_key, this->stripe, &dir_tmp, 
&eblock);
-          if (eblock) {
-            CacheEvacuateDocVC *earliest_evac  = eblock->earliest_evacuator;
-            earliest_evac->total_len          += doc->data_len();
-            if (earliest_evac->total_len == earliest_evac->doc_len) {
-              dir_lookaside_fixup(&evac->earliest_key, this->stripe);
-              free_CacheEvacuateDocVC(earliest_evac);
-            }
+  EvacuationBlock *b = 
this->stripe->get_preserved_dirs().find(this->overwrite_dir);
+  if (b) {
+    // If the document is single fragment (although not tied to the vector),
+    // then we don't have to put the directory entry in the lookaside
+    // buffer. But, we have no way of finding out if the document is
+    // single fragment. doc->single_fragment() can be true for a multiple
+    // fragment document since total_len and doc->len could be equal at
+    // the time we write the fragment down. To be on the safe side, we
+    // only overwrite the entry in the directory if its not a head.
+    if (!dir_head(&this->overwrite_dir)) {
+      // find the earliest key
+      EvacuationKey *evac = &b->evac_frags;
+      for (; evac && !(evac->key == doc->key); evac = evac->link.next) {
+        ;
+      }
+      ink_assert(evac);
+      if (!evac) {
+        return free_CacheEvacuateDocVC(this);
+      }
+      if (evac->earliest_key.fold()) {
+        DDbg(dbg_ctl_cache_evac, "evacdocdone: evacuating key %X earliest %X", 
evac->key.slice32(0), evac->earliest_key.slice32(0));
+        EvacuationBlock *eblock = nullptr;
+        Dir              dir_tmp;
+        dir_lookaside_probe(&evac->earliest_key, this->stripe, &dir_tmp, 
&eblock);
+        if (eblock) {
+          CacheEvacuateDocVC *earliest_evac  = eblock->earliest_evacuator;
+          earliest_evac->total_len          += doc->data_len();
+          if (earliest_evac->total_len == earliest_evac->doc_len) {
+            dir_lookaside_fixup(&evac->earliest_key, this->stripe);
+            free_CacheEvacuateDocVC(earliest_evac);
           }
         }
-        dir_overwrite(&doc->key, this->stripe, &this->dir, 
&this->overwrite_dir);
       }
-      // if the tag in the overwrite_dir matches the first_key in the
-      // document, then it has to be the vector. We guarantee that
-      // the first_key and the earliest_key will never collide (see
-      // Cache::open_write). Once we know its the vector, we can
-      // safely overwrite the first_key in the directory.
-      if (dir_head(&this->overwrite_dir) && b->f.evacuate_head) {
-        DDbg(dbg_ctl_cache_evac, "evacuateDocDone evacuate_head %X %X hlen %d 
offset %d", (int)key.slice32(0),
-             (int)doc->key.slice32(0), doc->hlen, 
(int)dir_offset(&this->overwrite_dir));
+      dir_overwrite(&doc->key, this->stripe, &this->dir, &this->overwrite_dir);
+    }
+    // if the tag in the overwrite_dir matches the first_key in the
+    // document, then it has to be the vector. We guarantee that
+    // the first_key and the earliest_key will never collide (see
+    // Cache::open_write). Once we know its the vector, we can
+    // safely overwrite the first_key in the directory.
+    if (dir_head(&this->overwrite_dir) && b->f.evacuate_head) {
+      DDbg(dbg_ctl_cache_evac, "evacuateDocDone evacuate_head %X %X hlen %d 
offset %d", (int)key.slice32(0),
+           (int)doc->key.slice32(0), doc->hlen, 
(int)dir_offset(&this->overwrite_dir));
 
-        if (dir_compare_tag(&this->overwrite_dir, &doc->first_key)) {
-          OpenDirEntry *cod;
-          DDbg(dbg_ctl_cache_evac, "evacuating vector: %X %d", 
(int)doc->first_key.slice32(0),
-               (int)dir_offset(&this->overwrite_dir));
-          if ((cod = this->stripe->open_read(&doc->first_key))) {
-            // writer  exists
-            DDbg(dbg_ctl_cache_evac, "overwriting the open directory %X %d 
%d", (int)doc->first_key.slice32(0),
-                 (int)dir_offset(&cod->first_dir), 
(int)dir_offset(&this->dir));
-            cod->first_dir = this->dir;
-          }
-          if (dir_overwrite(&doc->first_key, this->stripe, &this->dir, 
&this->overwrite_dir)) {
-            int64_t o = dir_offset(&this->overwrite_dir), n = 
dir_offset(&this->dir);
-            this->stripe->ram_cache->fixup(&doc->first_key, 
static_cast<uint64_t>(o), static_cast<uint64_t>(n));
-          }
-        } else {
-          DDbg(dbg_ctl_cache_evac, "evacuating earliest: %X %d", 
(int)doc->key.slice32(0), (int)dir_offset(&this->overwrite_dir));
-          ink_assert(dir_compare_tag(&this->overwrite_dir, &doc->key));
-          ink_assert(b->earliest_evacuator == this);
-          this->total_len    += doc->data_len();
-          this->first_key     = doc->first_key;
-          this->earliest_dir  = this->dir;
-          if (dir_probe(&this->first_key, this->stripe, &this->dir, 
&last_collision) > 0) {
-            dir_lookaside_insert(b, this->stripe, &this->earliest_dir);
-            // read the vector
-            SET_HANDLER(&CacheEvacuateDocVC::evacuateReadHead);
-            int ret = do_read_call(&this->first_key);
-            if (ret == EVENT_RETURN) {
-              return handleEvent(AIO_EVENT_DONE, nullptr);
-            }
-            return ret;
+      if (dir_compare_tag(&this->overwrite_dir, &doc->first_key)) {
+        OpenDirEntry *cod;
+        DDbg(dbg_ctl_cache_evac, "evacuating vector: %X %d", 
(int)doc->first_key.slice32(0), (int)dir_offset(&this->overwrite_dir));
+        if ((cod = this->stripe->open_read(&doc->first_key))) {
+          // writer  exists
+          DDbg(dbg_ctl_cache_evac, "overwriting the open directory %X %d %d", 
(int)doc->first_key.slice32(0),
+               (int)dir_offset(&cod->first_dir), (int)dir_offset(&this->dir));
+          cod->first_dir = this->dir;
+        }
+        if (dir_overwrite(&doc->first_key, this->stripe, &this->dir, 
&this->overwrite_dir)) {
+          int64_t o = dir_offset(&this->overwrite_dir), n = 
dir_offset(&this->dir);
+          this->stripe->ram_cache->fixup(&doc->first_key, 
static_cast<uint64_t>(o), static_cast<uint64_t>(n));
+        }
+      } else {
+        DDbg(dbg_ctl_cache_evac, "evacuating earliest: %X %d", 
(int)doc->key.slice32(0), (int)dir_offset(&this->overwrite_dir));
+        ink_assert(dir_compare_tag(&this->overwrite_dir, &doc->key));
+        ink_assert(b->earliest_evacuator == this);
+        this->total_len    += doc->data_len();
+        this->first_key     = doc->first_key;
+        this->earliest_dir  = this->dir;
+        if (dir_probe(&this->first_key, this->stripe, &this->dir, 
&last_collision) > 0) {
+          dir_lookaside_insert(b, this->stripe, &this->earliest_dir);
+          // read the vector
+          SET_HANDLER(&CacheEvacuateDocVC::evacuateReadHead);
+          int ret = do_read_call(&this->first_key);
+          if (ret == EVENT_RETURN) {
+            return handleEvent(AIO_EVENT_DONE, nullptr);
           }
+          return ret;
         }
       }
-      break;
     }
   }
   return free_CacheEvacuateDocVC(this);
diff --git a/src/iocore/cache/P_CacheVol.h b/src/iocore/cache/P_CacheVol.h
index 7f61e595cd..47423598d4 100644
--- a/src/iocore/cache/P_CacheVol.h
+++ b/src/iocore/cache/P_CacheVol.h
@@ -34,6 +34,7 @@
 #include "iocore/eventsystem/EThread.h"
 
 #include "tscore/CryptoHash.h"
+#include "tscore/List.h"
 
 #include <atomic>
 
@@ -66,7 +67,7 @@ struct DiskStripe;
 struct CacheVol;
 class CacheEvacuateDocVC;
 
-class StripeSM : public Continuation, public Stripe, public PreservationTable
+class StripeSM : public Continuation, public Stripe
 {
 public:
   CryptoHash hash_id;
@@ -205,7 +206,33 @@ public:
    */
   void shutdown(EThread *shutdown_thread);
 
+  bool
+  evac_bucket_valid(off_t bucket) const
+  {
+    return this->_preserved_dirs.evac_bucket_valid(bucket);
+  }
+
+  DLL<EvacuationBlock>
+  get_evac_bucket(off_t bucket) const
+  {
+    return this->_preserved_dirs.evacuate[bucket];
+  }
+
+  void
+  force_evacuate_head(Dir const *evac_dir, int pinned)
+  {
+    return this->_preserved_dirs.force_evacuate_head(evac_dir, pinned);
+  }
+
+  PreservationTable &
+  get_preserved_dirs()
+  {
+    return this->_preserved_dirs;
+  }
+
 private:
+  mutable PreservationTable _preserved_dirs;
+
   int _agg_copy(CacheVC *vc);
   int _copy_writer_to_aggregation(CacheVC *vc);
   int _copy_evacuator_to_aggregation(CacheVC *vc);
diff --git a/src/iocore/cache/PreservationTable.cc 
b/src/iocore/cache/PreservationTable.cc
index 73741b4cfc..67febf4bf4 100644
--- a/src/iocore/cache/PreservationTable.cc
+++ b/src/iocore/cache/PreservationTable.cc
@@ -26,6 +26,7 @@
 #include "PreservationTable.h"
 
 #include "AggregateWriteBuffer.h"
+#include "iocore/cache/CacheDefs.h"
 #include "Stripe.h"
 
 #include "tsutil/DbgCtl.h"
@@ -39,6 +40,17 @@ DbgCtl dbg_ctl_cache_evac{"cache_evac"};
 
 } // namespace
 
+EvacuationBlock *
+PreservationTable::find(Dir const &dir) const
+{
+  auto bucket{dir_evac_bucket(&dir)};
+  if (this->evac_bucket_valid(bucket)) {
+    return this->find(dir, bucket);
+  } else {
+    return nullptr;
+  }
+}
+
 void
 PreservationTable::force_evacuate_head(Dir const *evac_dir, int pinned)
 {
@@ -50,7 +62,7 @@ PreservationTable::force_evacuate_head(Dir const *evac_dir, 
int pinned)
   }
 
   // build an evacuation block for the object
-  EvacuationBlock *b = evacuation_block_exists(evac_dir, this);
+  EvacuationBlock *b = this->find(*evac_dir);
   // if we have already started evacuating this document, its too late
   // to evacuate the head...bad luck
   if (b && b->f.done) {
@@ -69,6 +81,38 @@ PreservationTable::force_evacuate_head(Dir const *evac_dir, 
int pinned)
   b->readers = 0;            // ensure that the block does not disappear
 }
 
+int
+PreservationTable::acquire(Dir const &dir, CacheKey const &key)
+{
+  int bucket = dir_evac_bucket(&dir);
+  if (EvacuationBlock * b{this->find(dir, bucket)}; nullptr != b) {
+    if (b->readers) {
+      ++b->readers;
+    }
+    return 0;
+  }
+  // we don't actually need to preserve this block as it is already in
+  // memory, but this is easier, and evacuations are rare
+  EvacuationBlock *b = new_EvacuationBlock();
+  b->readers         = 1;
+  b->dir             = dir;
+  b->evac_frags.key  = key;
+  this->evacuate[bucket].push(b);
+  return 1;
+}
+
+void
+PreservationTable::release(Dir const &dir)
+{
+  int bucket = dir_evac_bucket(&dir);
+  if (EvacuationBlock * b{this->find(dir, bucket)}; nullptr != b) {
+    if (b->readers && !--b->readers) {
+      this->evacuate[bucket].remove(b);
+      free_EvacuationBlock(b);
+    }
+  }
+}
+
 void
 PreservationTable::periodic_scan(Stripe *stripe)
 {
@@ -159,3 +203,13 @@ PreservationTable::remove_finished_blocks(Stripe const 
*stripe, int bucket)
     b = b->link.next;
   }
 }
+
+EvacuationBlock *
+PreservationTable::find(Dir const &dir, int bucket) const
+{
+  EvacuationBlock *b{this->evacuate[bucket].head};
+  while (b && (dir_offset(&b->dir) != dir_offset(&dir))) {
+    b = b->link.next;
+  }
+  return b;
+}
diff --git a/src/iocore/cache/PreservationTable.h 
b/src/iocore/cache/PreservationTable.h
index 944a330080..7641456b45 100644
--- a/src/iocore/cache/PreservationTable.h
+++ b/src/iocore/cache/PreservationTable.h
@@ -24,6 +24,7 @@
 #pragma once
 
 #include "AggregateWriteBuffer.h"
+#include "iocore/cache/CacheDefs.h"
 #include "P_CacheDir.h"
 #include "Stripe.h"
 
@@ -89,6 +90,8 @@ struct EvacuationBlock {
 class PreservationTable
 {
 public:
+  int evacuate_size{};
+
   /**
    * The table of preserved documents.
    *
@@ -112,12 +115,49 @@ public:
    */
   void force_evacuate_head(Dir const *evac_dir, int pinned);
 
-protected:
-  int evacuate_size{};
+  /**
+   * Find the evacuation block corresponding to @a dir.
+   *
+   * @param dir The directory entry to search for.
+   * @return Returns the corresponding block if it exists, nullptr otherwise.
+   */
+  EvacuationBlock *find(Dir const &dir) const;
+
+  /**
+   * Acquire the evacuation block for @a dir.
+   *
+   * Any number of readers may acquire the block at a time to prevent the
+   * block from being removed from the table. If no block for the directory
+   * entry is in the table yet, one will be added with @a key.
+   *
+   * @param dir The directory entry to acquire.
+   * @param key The key for the directory entry.
+   * @return Returns 1 if a new block was created, otherwise 0.
+   */
+  int acquire(Dir const &dir, CacheKey const &key);
+
+  /** Release the evacuation block for @a dir.
+   *
+   * When a block has been released once for every time it was acquired, it
+   * may be removed from the table, invalidating all pointers to it. Note that
+   * releasing more than once from the same reader may cause the block to be
+   * removed from the table while other readers that acquired it think it's
+   * valid. Be careful.
+   *
+   * A block that was evacuated with force_evacuate_head will not be removed
+   * from the table when it is released.
+   *
+   * @param dir The directory entry to release.
+   * @see force_evacuate_head
+   */
+  void release(Dir const &dir);
 
   /**
    * Remove completed documents from the table and add pinned documents.
    *
+   * Documents that were acquired by a reader and not released are not removed.
+   * Invalidates pointers to evacuation blocks unless they have been acquired.
+   *
    * @param Stripe The stripe to scan for pinned documents to preserve.
    */
   void periodic_scan(Stripe *stripe);
@@ -126,6 +166,8 @@ private:
   void cleanup(Stripe const *stripe);
   void remove_finished_blocks(Stripe const *stripe, int bucket);
   void scan_for_pinned_documents(Stripe const *stripe);
+
+  EvacuationBlock *find(Dir const &dir, int bucket) const;
 };
 
 inline bool
@@ -137,21 +179,6 @@ PreservationTable::evac_bucket_valid(off_t bucket) const
 extern ClassAllocator<EvacuationBlock> evacuationBlockAllocator;
 extern ClassAllocator<EvacuationKey>   evacuationKeyAllocator;
 
-inline EvacuationBlock *
-evacuation_block_exists(Dir const *dir, PreservationTable *stripe)
-{
-  auto bucket = dir_evac_bucket(dir);
-  if (stripe->evac_bucket_valid(bucket)) {
-    EvacuationBlock *b = stripe->evacuate[bucket].head;
-    for (; b; b = b->link.next) {
-      if (dir_offset(&b->dir) == dir_offset(dir)) {
-        return b;
-      }
-    }
-  }
-  return nullptr;
-}
-
 inline EvacuationBlock *
 new_EvacuationBlock()
 {
diff --git a/src/iocore/cache/StripeSM.cc b/src/iocore/cache/StripeSM.cc
index 4af3d3c05e..72251b58b0 100644
--- a/src/iocore/cache/StripeSM.cc
+++ b/src/iocore/cache/StripeSM.cc
@@ -121,25 +121,7 @@ StripeSM::begin_read(CacheVC *cont) const
   if (cont->f.single_fragment) {
     return 0;
   }
-  int              i = dir_evac_bucket(&cont->earliest_dir);
-  EvacuationBlock *b;
-  for (b = evacuate[i].head; b; b = b->link.next) {
-    if (dir_offset(&b->dir) != dir_offset(&cont->earliest_dir)) {
-      continue;
-    }
-    if (b->readers) {
-      b->readers = b->readers + 1;
-    }
-    return 0;
-  }
-  // we don't actually need to preserve this block as it is already in
-  // memory, but this is easier, and evacuations are rare
-  b                 = new_EvacuationBlock();
-  b->readers        = 1;
-  b->dir            = cont->earliest_dir;
-  b->evac_frags.key = cont->earliest_key;
-  evacuate[i].push(b);
-  return 1;
+  return this->_preserved_dirs.acquire(cont->earliest_dir, cont->earliest_key);
 }
 
 int
@@ -148,25 +130,9 @@ StripeSM::close_read(CacheVC *cont) const
   EThread *t = cont->mutex->thread_holding;
   ink_assert(t == this_ethread());
   ink_assert(t == mutex->thread_holding);
-  if (dir_is_empty(&cont->earliest_dir)) {
-    return 1;
+  if (!dir_is_empty(&cont->earliest_dir)) {
+    this->_preserved_dirs.release(cont->earliest_dir);
   }
-  int              i = dir_evac_bucket(&cont->earliest_dir);
-  EvacuationBlock *b;
-  for (b = evacuate[i].head; b;) {
-    EvacuationBlock *next = b->link.next;
-    if (dir_offset(&b->dir) != dir_offset(&cont->earliest_dir)) {
-      b = next;
-      continue;
-    }
-    if (b->readers && !--b->readers) {
-      evacuate[i].remove(b);
-      free_EvacuationBlock(b);
-      break;
-    }
-    b = next;
-  }
-
   return 1;
 }
 
@@ -213,10 +179,10 @@ StripeSM::init(char *s, off_t blocks, off_t dir_skip, 
bool clear)
   data_blocks         = (len - (start - skip)) / STORE_BLOCK_SIZE;
   hit_evacuate_window = (data_blocks * cache_config_hit_evacuate_percent) / 
100;
 
-  evacuate_size = static_cast<int>(len / EVACUATION_BUCKET_SIZE) + 2;
-  int evac_len  = evacuate_size * sizeof(DLL<EvacuationBlock>);
-  evacuate      = static_cast<DLL<EvacuationBlock> *>(ats_malloc(evac_len));
-  memset(static_cast<void *>(evacuate), 0, evac_len);
+  this->_preserved_dirs.evacuate_size = static_cast<int>(len / 
EVACUATION_BUCKET_SIZE) + 2;
+  int evac_len                        = this->_preserved_dirs.evacuate_size * 
sizeof(DLL<EvacuationBlock>);
+  this->_preserved_dirs.evacuate      = static_cast<DLL<EvacuationBlock> 
*>(ats_malloc(evac_len));
+  memset(static_cast<void *>(this->_preserved_dirs.evacuate), 0, evac_len);
 
   Dbg(dbg_ctl_cache_init, "Vol %s: allocating %zu directory bytes for a %lld 
byte volume (%lf%%)", hash_text.get(), dirlen(),
       (long long)this->len, (double)dirlen() / (double)this->len * 100.0);
@@ -664,7 +630,7 @@ StripeSM::handle_recover_write_dir(int /* event ATS_UNUSED 
*/, void * /* data AT
   set_io_not_in_progress();
   scan_pos = header->write_pos;
   ink_assert(this->mutex->thread_holding == this_ethread());
-  periodic_scan(this);
+  this->_preserved_dirs.periodic_scan(this);
   SET_HANDLER(&StripeSM::dir_init_done);
   return dir_init_done(EVENT_IMMEDIATE, nullptr);
 }
@@ -784,7 +750,7 @@ StripeSM::aggWriteDone(int event, Event *e)
     ink_assert(header->write_pos == header->agg_pos);
     if (header->write_pos + EVACUATION_SIZE > scan_pos) {
       ink_assert(this->mutex->thread_holding == this_ethread());
-      periodic_scan(this);
+      this->_preserved_dirs.periodic_scan(this);
     }
     this->_write_buffer.reset_buffer_pos();
     header->write_serial++;
@@ -1141,7 +1107,7 @@ StripeSM::agg_wrap()
     Note("Cache volume %d on disk '%s' wraps around", 
stripe->cache_vol->vol_number, stripe->hash_text.get());
   }
   ink_assert(this->mutex->thread_holding == this_ethread());
-  periodic_scan(this);
+  this->_preserved_dirs.periodic_scan(this);
 }
 
 int
@@ -1153,7 +1119,7 @@ StripeSM::evac_range(off_t low, off_t high, int 
evac_phase)
   int   ei = dir_offset_evac_bucket(e);
 
   for (int i = si; i <= ei; i++) {
-    EvacuationBlock *b            = evacuate[i].head;
+    EvacuationBlock *b            = this->_preserved_dirs.evacuate[i].head;
     EvacuationBlock *first        = nullptr;
     int64_t          first_offset = INT64_MAX;
     for (; b; b = b->link.next) {
@@ -1213,7 +1179,7 @@ StripeSM::evacuateDocReadDone(int event, Event *e)
        (int)dir_offset(&doc_evacuator->overwrite_dir));
 
   if (evac_bucket_valid(bucket)) {
-    b = evacuate[bucket].head;
+    b = this->_preserved_dirs.evacuate[bucket].head;
   }
   while (b) {
     if (dir_offset(&b->dir) == dir_offset(&doc_evacuator->overwrite_dir)) {
@@ -1295,13 +1261,13 @@ evacuate_fragments(CacheKey *key, CacheKey 
*earliest_key, int force, StripeSM *s
     if (dir_head(&dir)) {
       continue;
     }
-    EvacuationBlock *b = evacuation_block_exists(&dir, stripe);
+    EvacuationBlock *b = stripe->get_preserved_dirs().find(dir);
     if (!b) {
       b                          = new_EvacuationBlock();
       b->dir                     = dir;
       b->evac_frags.key          = *key;
       b->evac_frags.earliest_key = *earliest_key;
-      stripe->evacuate[dir_evac_bucket(&dir)].push(b);
+      stripe->get_evac_bucket(dir_evac_bucket(&dir)).push(b);
       i++;
     } else {
       ink_assert(dir_offset(&dir) == dir_offset(&b->dir));
diff --git a/src/iocore/cache/unit_tests/test_Stripe.cc 
b/src/iocore/cache/unit_tests/test_Stripe.cc
index b7aeffd646..34baca524e 100644
--- a/src/iocore/cache/unit_tests/test_Stripe.cc
+++ b/src/iocore/cache/unit_tests/test_Stripe.cc
@@ -125,8 +125,8 @@ init_stripe_for_writing(StripeSM &stripe, 
StripteHeaderFooter &header, CacheVol
   stripe.raw_dir     = static_cast<char *>(ats_memalign(ats_pagesize(), 
stripe.dirlen()));
   stripe.dir         = reinterpret_cast<Dir *>(stripe.raw_dir + 
stripe.headerlen());
 
-  stripe.evacuate = static_cast<DLL<EvacuationBlock> *>(ats_malloc(2024));
-  memset(static_cast<void *>(stripe.evacuate), 0, 2024);
+  stripe.get_preserved_dirs().evacuate = static_cast<DLL<EvacuationBlock> 
*>(ats_malloc(2024));
+  memset(static_cast<void *>(stripe.get_preserved_dirs().evacuate), 0, 2024);
 
   header.write_pos = 50000;
   header.agg_pos   = 1;
@@ -295,7 +295,7 @@ TEST_CASE("aggWrite behavior with f.evacuator unset")
   }
 
   ats_free(stripe.raw_dir);
-  ats_free(stripe.evacuate);
+  ats_free(stripe.get_preserved_dirs().evacuate);
 }
 
 // When f.evacuator is set, vc.buf must contain a Doc object including headers
@@ -392,5 +392,5 @@ TEST_CASE("aggWrite behavior with f.evacuator set")
 
   delete[] source;
   ats_free(stripe.raw_dir);
-  ats_free(stripe.evacuate);
+  ats_free(stripe.get_preserved_dirs().evacuate);
 }

Reply via email to