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

bneradt 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 e31f53278a Extract CacheEvacuateDocVC from CacheVC (#10603)
e31f53278a is described below

commit e31f53278ad7f9813ae2b02c9f77a3c183dbb61f
Author: JosiahWI <[email protected]>
AuthorDate: Wed Oct 18 11:18:19 2023 -0500

    Extract CacheEvacuateDocVC from CacheVC (#10603)
    
    This extracts a subclass from CacheVC called CacheEvacuateDocVC and moves 
the logic for evacuating a doc to the new subclass. By having less code in it, 
CacheVC should be a little simpler. While doing the extraction, I also read 
through the logic and tried to clean up the logic flow a little bit. This last 
bit was risky, and I'm not confident we have enough test coverage to be sure it 
was done correctly. I did my best to double check my reasoning on every change, 
but please review carefully.
---
 iocore/cache/CMakeLists.txt        |   1 +
 iocore/cache/Cache.cc              |   1 +
 iocore/cache/CacheEvacuateDocVC.cc | 211 +++++++++++++++++++++++++++++++++++++
 iocore/cache/CacheEvacuateDocVC.h  |  72 +++++++++++++
 iocore/cache/CacheVC.h             |   2 -
 iocore/cache/CacheWrite.cc         | 169 ++---------------------------
 iocore/cache/I_Cache.h             |   1 +
 iocore/cache/Makefile.am           |   2 +
 iocore/cache/P_CacheDir.h          |   1 +
 iocore/cache/P_CacheInternal.h     |   3 +-
 iocore/cache/P_CacheVol.h          |   7 +-
 iocore/eventsystem/I_Thread.h      |   1 +
 12 files changed, 302 insertions(+), 169 deletions(-)

diff --git a/iocore/cache/CMakeLists.txt b/iocore/cache/CMakeLists.txt
index e4180a62f1..c807f2dc46 100644
--- a/iocore/cache/CMakeLists.txt
+++ b/iocore/cache/CMakeLists.txt
@@ -20,6 +20,7 @@ add_library(
   Cache.cc
   CacheDir.cc
   CacheDisk.cc
+  CacheEvacuateDocVC.cc
   CacheHosting.cc
   CacheHttp.cc
   CachePages.cc
diff --git a/iocore/cache/Cache.cc b/iocore/cache/Cache.cc
index 2a590a116d..9e6dc12464 100644
--- a/iocore/cache/Cache.cc
+++ b/iocore/cache/Cache.cc
@@ -91,6 +91,7 @@ CacheProcessor cacheProcessor;
 Vol **gvol             = nullptr;
 std::atomic<int> gnvol = 0;
 ClassAllocator<CacheVC> cacheVConnectionAllocator("cacheVConnection");
+ClassAllocator<CacheEvacuateDocVC> 
cacheEvacuateDocVConnectionAllocator("cacheEvacuateDocVC");
 ClassAllocator<EvacuationBlock> evacuationBlockAllocator("evacuationBlock");
 ClassAllocator<CacheRemoveCont> cacheRemoveContAllocator("cacheRemoveCont");
 ClassAllocator<EvacuationKey> evacuationKeyAllocator("evacuationKey");
diff --git a/iocore/cache/CacheEvacuateDocVC.cc 
b/iocore/cache/CacheEvacuateDocVC.cc
new file mode 100644
index 0000000000..390996da19
--- /dev/null
+++ b/iocore/cache/CacheEvacuateDocVC.cc
@@ -0,0 +1,211 @@
+/** @file
+
+  A brief file description
+
+  @section license License
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+
+// make sure there are no incomplete types
+#include "P_Cache.h"
+
+// inkcache
+#include "CacheEvacuateDocVC.h"
+#include "I_CacheDefs.h"
+#include "P_CacheDir.h"
+#include "P_CacheHttp.h"
+#include "P_CacheInternal.h"
+#include "P_CacheVol.h"
+
+// aio
+#include "I_AIO.h"
+
+// inkevent
+#include "I_EThread.h"
+
+// tscore
+#include "tscore/Diags.h"
+#include "tscore/ink_assert.h"
+
+// ts
+#include "ts/DbgCtl.h"
+
+namespace
+{
+DbgCtl dbg_ctl_cache_evac{"cache_evac"};
+} // end anonymous namespace
+
+int
+CacheEvacuateDocVC::evacuateDocDone(int /* event ATS_UNUSED */, Event * /* e 
ATS_UNUSED */)
+{
+  ink_assert(this->vol->mutex->thread_holding == this_ethread());
+  Doc *doc = reinterpret_cast<Doc *>(this->buf->data());
+  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->vol->evac_bucket_valid(i) ? 
this->vol->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->vol, &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->vol);
+              free_CacheVC(earliest_evac);
+            }
+          }
+        }
+        dir_overwrite(&doc->key, this->vol, &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->vol->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->vol, &this->dir, 
&this->overwrite_dir)) {
+            int64_t o = dir_offset(&this->overwrite_dir), n = 
dir_offset(&this->dir);
+            this->vol->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->vol, &this->dir, 
&last_collision) > 0) {
+            dir_lookaside_insert(b, this->vol, &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_CacheVC(this);
+}
+
+int
+CacheEvacuateDocVC::evacuateReadHead(int /* event ATS_UNUSED */, Event * /* e 
ATS_UNUSED */)
+{
+  // The evacuator vc shares the lock with the volition mutex
+  ink_assert(this->vol->mutex->thread_holding == this_ethread());
+  cancel_trigger();
+  Doc *doc                     = reinterpret_cast<Doc *>(this->buf->data());
+  CacheHTTPInfo *alternate_tmp = nullptr;
+  if (!io.ok()) {
+    goto Ldone;
+  }
+  // a directory entry which is no longer valid may have been overwritten
+  if (!dir_valid(this->vol, &this->dir)) {
+    last_collision = nullptr;
+    goto Lcollision;
+  }
+  if (doc->magic != DOC_MAGIC || !(doc->first_key == this->first_key)) {
+    goto Lcollision;
+  }
+  alternate_tmp = nullptr;
+  if (doc->doc_type == CACHE_FRAG_TYPE_HTTP && doc->hlen) {
+    // its an http document
+    if (this->load_http_info(&vector, doc) != doc->hlen) {
+      Note("bad vector detected during evacuation");
+      goto Ldone;
+    }
+    alternate_index = get_alternate_index(&vector, earliest_key);
+    if (alternate_index < 0) {
+      goto Ldone;
+    }
+    alternate_tmp = vector.get(alternate_index);
+    doc_len       = alternate_tmp->object_size_get();
+    Dbg(dbg_ctl_cache_evac, "evacuateReadHead http earliest %X first: %X len: 
%" PRId64, earliest_key.slice32(0),
+        this->first_key.slice32(0), doc_len);
+  } else {
+    // non-http document
+    CacheKey next_key;
+    next_CacheKey(&next_key, &doc->key);
+    if (!(next_key == earliest_key)) {
+      goto Ldone;
+    }
+    doc_len = doc->total_len;
+    DDbg(dbg_ctl_cache_evac, "evacuateReadHead non-http earliest %X first: %X 
len: %" PRId64, earliest_key.slice32(0),
+         this->first_key.slice32(0), doc_len);
+  }
+  if (doc_len == this->total_len) {
+    // the whole document has been evacuated. Insert the directory
+    // entry in the directory.
+    dir_lookaside_fixup(&earliest_key, this->vol);
+    return free_CacheVC(this);
+  }
+  return EVENT_CONT;
+Lcollision:
+  if (dir_probe(&this->first_key, this->vol, &this->dir, &last_collision)) {
+    int ret = do_read_call(&this->first_key);
+    if (ret == EVENT_RETURN) {
+      return handleEvent(AIO_EVENT_DONE, nullptr);
+    }
+    return ret;
+  }
+Ldone:
+  dir_lookaside_remove(&earliest_key, this->vol);
+  return free_CacheVC(this);
+}
diff --git a/iocore/cache/CacheEvacuateDocVC.h 
b/iocore/cache/CacheEvacuateDocVC.h
new file mode 100644
index 0000000000..2f4ede973d
--- /dev/null
+++ b/iocore/cache/CacheEvacuateDocVC.h
@@ -0,0 +1,72 @@
+/** @file
+
+  A brief file description
+
+  @section license License
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+
+#pragma once
+
+/*
+#include "P_CacheDir.h"
+*/
+
+#include "CacheVC.h"
+
+// eventsystem
+#include "I_Continuation.h"
+#include "I_EThread.h"
+#include "I_Event.h"
+#include "I_ProxyAllocator.h"
+
+// tscore
+#include "tscore/ink_assert.h"
+
+// ts
+#include "ts/DbgCtl.h"
+
+class CacheEvacuateDocVC : public CacheVC
+{
+public:
+  int evacuateDocDone(int /* event ATS_UNUSED */, Event * /* e ATS_UNUSED */);
+  int evacuateReadHead(int /* event ATS_UNUSED */, Event * /* e ATS_UNUSED */);
+};
+
+extern ClassAllocator<CacheEvacuateDocVC> cacheEvacuateDocVConnectionAllocator;
+
+inline CacheEvacuateDocVC *
+new_CacheEvacuateDocVC(Continuation *cont)
+{
+  EThread *t            = cont->mutex->thread_holding;
+  CacheEvacuateDocVC *c = THREAD_ALLOC(cacheEvacuateDocVConnectionAllocator, 
t);
+  c->vector.data.data   = &c->vector.data.fast_data[0];
+  c->_action            = cont;
+  c->mutex              = cont->mutex;
+  c->start_time         = ink_get_hrtime();
+  c->setThreadAffinity(t);
+  ink_assert(c->trigger == nullptr);
+  static DbgCtl dbg_ctl{"cache_new"};
+  Dbg(dbg_ctl, "new %p", c);
+#ifdef CACHE_STAT_PAGES
+  ink_assert(!c->stat_link.next);
+  ink_assert(!c->stat_link.prev);
+#endif
+  dir_clear(&c->dir);
+  return c;
+}
diff --git a/iocore/cache/CacheVC.h b/iocore/cache/CacheVC.h
index e345c99c07..f8b08dc7d7 100644
--- a/iocore/cache/CacheVC.h
+++ b/iocore/cache/CacheVC.h
@@ -199,8 +199,6 @@ struct CacheVC : public CacheVConnection {
   {
     io.aiocb.aio_fildes = AIO_AGG_WRITE_IN_PROGRESS;
   }
-  int evacuateDocDone(int event, Event *e);
-  int evacuateReadHead(int event, Event *e);
 
   void cancel_trigger();
   int64_t get_object_size() override;
diff --git a/iocore/cache/CacheWrite.cc b/iocore/cache/CacheWrite.cc
index 24d6104cf6..683fc3a1cb 100644
--- a/iocore/cache/CacheWrite.cc
+++ b/iocore/cache/CacheWrite.cc
@@ -22,6 +22,7 @@
  */
 
 #include "P_Cache.h"
+#include "CacheEvacuateDocVC.h"
 
 #define UINT_WRAP_LTE(_x, _y) (((_y) - (_x)) < INT_MAX)  // exploit overflow
 #define UINT_WRAP_GTE(_x, _y) (((_x) - (_y)) < INT_MAX)  // exploit overflow
@@ -435,179 +436,21 @@ Vol::aggWriteDone(int event, Event *e)
   return EVENT_CONT;
 }
 
-CacheVC *
+CacheEvacuateDocVC *
 new_DocEvacuator(int nbytes, Vol *vol)
 {
-  CacheVC *c = new_CacheVC(vol);
-  c->op_type = static_cast<int>(CacheOpType::Evacuate);
+  CacheEvacuateDocVC *c = new_CacheEvacuateDocVC(vol);
+  c->op_type            = static_cast<int>(CacheOpType::Evacuate);
   Metrics::increment(cache_rsb.status[c->op_type].active);
   Metrics::increment(vol->cache_vol->vol_rsb.status[c->op_type].active);
   c->buf         = new_IOBufferData(iobuffer_size_to_index(nbytes, 
MAX_BUFFER_SIZE_INDEX), MEMALIGNED);
   c->vol         = vol;
   c->f.evacuator = 1;
   c->earliest_key.clear();
-  SET_CONTINUATION_HANDLER(c, &CacheVC::evacuateDocDone);
+  SET_CONTINUATION_HANDLER(c, &CacheEvacuateDocVC::evacuateDocDone);
   return c;
 }
 
-int
-CacheVC::evacuateReadHead(int /* event ATS_UNUSED */, Event * /* e ATS_UNUSED 
*/)
-{
-  // The evacuator vc shares the lock with the volition mutex
-  ink_assert(vol->mutex->thread_holding == this_ethread());
-  cancel_trigger();
-  Doc *doc                     = reinterpret_cast<Doc *>(buf->data());
-  CacheHTTPInfo *alternate_tmp = nullptr;
-  if (!io.ok()) {
-    goto Ldone;
-  }
-  // a directory entry which is no longer valid may have been overwritten
-  if (!dir_valid(vol, &dir)) {
-    last_collision = nullptr;
-    goto Lcollision;
-  }
-  if (doc->magic != DOC_MAGIC || !(doc->first_key == first_key)) {
-    goto Lcollision;
-  }
-  alternate_tmp = nullptr;
-  if (doc->doc_type == CACHE_FRAG_TYPE_HTTP && doc->hlen) {
-    // its an http document
-    if (this->load_http_info(&vector, doc) != doc->hlen) {
-      Note("bad vector detected during evacuation");
-      goto Ldone;
-    }
-    alternate_index = get_alternate_index(&vector, earliest_key);
-    if (alternate_index < 0) {
-      goto Ldone;
-    }
-    alternate_tmp = vector.get(alternate_index);
-    doc_len       = alternate_tmp->object_size_get();
-    Dbg(dbg_ctl_cache_evac, "evacuateReadHead http earliest %X first: %X len: 
%" PRId64, earliest_key.slice32(0),
-        first_key.slice32(0), doc_len);
-  } else {
-    // non-http document
-    CacheKey next_key;
-    next_CacheKey(&next_key, &doc->key);
-    if (!(next_key == earliest_key)) {
-      goto Ldone;
-    }
-    doc_len = doc->total_len;
-    DDbg(dbg_ctl_cache_evac, "evacuateReadHead non-http earliest %X first: %X 
len: %" PRId64, earliest_key.slice32(0),
-         first_key.slice32(0), doc_len);
-  }
-  if (doc_len == total_len) {
-    // the whole document has been evacuated. Insert the directory
-    // entry in the directory.
-    dir_lookaside_fixup(&earliest_key, vol);
-    return free_CacheVC(this);
-  }
-  return EVENT_CONT;
-Lcollision:
-  if (dir_probe(&first_key, vol, &dir, &last_collision)) {
-    int ret = do_read_call(&first_key);
-    if (ret == EVENT_RETURN) {
-      return handleEvent(AIO_EVENT_DONE, nullptr);
-    }
-    return ret;
-  }
-Ldone:
-  dir_lookaside_remove(&earliest_key, vol);
-  return free_CacheVC(this);
-}
-
-int
-CacheVC::evacuateDocDone(int /* event ATS_UNUSED */, Event * /* e ATS_UNUSED 
*/)
-{
-  ink_assert(vol->mutex->thread_holding == this_ethread());
-  Doc *doc = reinterpret_cast<Doc *>(buf->data());
-  DDbg(dbg_ctl_cache_evac, "evacuateDocDone %X o %d p %d new_o %d new_p %d", 
(int)key.slice32(0), (int)dir_offset(&overwrite_dir),
-       (int)dir_phase(&overwrite_dir), (int)dir_offset(&dir), 
(int)dir_phase(&dir));
-  int i = dir_evac_bucket(&overwrite_dir);
-  // nasty beeping race condition, need to have the EvacuationBlock here
-  EvacuationBlock *b = vol->evac_bucket_valid(i) ? vol->evacuate[i].head : 
nullptr;
-  for (; b; b = b->link.next) {
-    if (dir_offset(&b->dir) == dir_offset(&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(&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, vol, &dir_tmp, &eblock);
-          if (eblock) {
-            CacheVC *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, vol);
-              free_CacheVC(earliest_evac);
-            }
-          }
-        }
-        dir_overwrite(&doc->key, vol, &dir, &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(&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(&overwrite_dir));
-
-        if (dir_compare_tag(&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(&overwrite_dir));
-          if ((cod = vol->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(&dir));
-            cod->first_dir = dir;
-          }
-          if (dir_overwrite(&doc->first_key, vol, &dir, &overwrite_dir)) {
-            int64_t o = dir_offset(&overwrite_dir), n = dir_offset(&dir);
-            vol->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(&overwrite_dir));
-          ink_assert(dir_compare_tag(&overwrite_dir, &doc->key));
-          ink_assert(b->earliest_evacuator == this);
-          total_len    += doc->data_len();
-          first_key     = doc->first_key;
-          earliest_dir  = dir;
-          if (dir_probe(&first_key, vol, &dir, &last_collision) > 0) {
-            dir_lookaside_insert(b, vol, &earliest_dir);
-            // read the vector
-            SET_HANDLER(&CacheVC::evacuateReadHead);
-            int ret = do_read_call(&first_key);
-            if (ret == EVENT_RETURN) {
-              return handleEvent(AIO_EVENT_DONE, nullptr);
-            }
-            return ret;
-          }
-        }
-      }
-      break;
-    }
-  }
-  return free_CacheVC(this);
-}
-
 static int
 evacuate_fragments(CacheKey *key, CacheKey *earliest_key, int force, Vol *vol)
 {
@@ -646,7 +489,7 @@ evacuate_fragments(CacheKey *key, CacheKey *earliest_key, 
int force, Vol *vol)
 }
 
 int
-Vol::evacuateWrite(CacheVC *evacuator, int event, Event *e)
+Vol::evacuateWrite(CacheEvacuateDocVC *evacuator, int event, Event *e)
 {
   // push to front of aggregation write list, so it is written first
 
diff --git a/iocore/cache/I_Cache.h b/iocore/cache/I_Cache.h
index c12f606417..4984ce7846 100644
--- a/iocore/cache/I_Cache.h
+++ b/iocore/cache/I_Cache.h
@@ -49,6 +49,7 @@ static constexpr ts::ModuleVersion CACHE_MODULE_VERSION(1, 0);
 enum { RAM_HIT_COMPRESS_NONE = 1, RAM_HIT_COMPRESS_FASTLZ, 
RAM_HIT_COMPRESS_LIBZ, RAM_HIT_COMPRESS_LIBLZMA, RAM_HIT_LAST_ENTRY };
 
 struct CacheVC;
+class CacheEvacuateDocVC;
 struct CacheDisk;
 struct OverridableHttpConfigParams;
 class URL;
diff --git a/iocore/cache/Makefile.am b/iocore/cache/Makefile.am
index c2a0e628df..99c9e8fcd6 100644
--- a/iocore/cache/Makefile.am
+++ b/iocore/cache/Makefile.am
@@ -34,6 +34,8 @@ libinkcache_a_SOURCES = \
        Cache.cc \
        CacheDir.cc \
        CacheDisk.cc \
+       CacheEvacuateDocVC.cc \
+       CacheEvacuateDocVC.h \
        CacheHosting.cc \
        CacheHttp.cc \
        CachePages.cc \
diff --git a/iocore/cache/P_CacheDir.h b/iocore/cache/P_CacheDir.h
index ad8ef22135..0e57d56fd8 100644
--- a/iocore/cache/P_CacheDir.h
+++ b/iocore/cache/P_CacheDir.h
@@ -34,6 +34,7 @@
 struct Vol;
 struct InterimCacheVol;
 struct CacheVC;
+class CacheEvacuateDocVC;
 
 /*
   Directory layout
diff --git a/iocore/cache/P_CacheInternal.h b/iocore/cache/P_CacheInternal.h
index a102633475..5378b71739 100644
--- a/iocore/cache/P_CacheInternal.h
+++ b/iocore/cache/P_CacheInternal.h
@@ -32,6 +32,7 @@
 #include "api/Metrics.h"
 
 #include "CacheVC.h"
+#include "CacheEvacuateDocVC.h"
 
 using ts::Metrics;
 
@@ -152,7 +153,7 @@ extern CacheSync *cacheDirSync;
 // Function Prototypes
 int cache_write(CacheVC *, CacheHTTPInfoVector *);
 int get_alternate_index(CacheHTTPInfoVector *cache_vector, CacheKey key);
-CacheVC *new_DocEvacuator(int nbytes, Vol *vol);
+CacheEvacuateDocVC *new_DocEvacuator(int nbytes, Vol *vol);
 
 // inline Functions
 
diff --git a/iocore/cache/P_CacheVol.h b/iocore/cache/P_CacheVol.h
index ead9bee9cb..d13490593c 100644
--- a/iocore/cache/P_CacheVol.h
+++ b/iocore/cache/P_CacheVol.h
@@ -78,6 +78,7 @@ struct CacheDisk;
 struct VolInitInfo;
 struct DiskVol;
 struct CacheVol;
+class CacheEvacuateDocVC;
 
 struct VolHeaderFooter {
   unsigned int magic;
@@ -120,7 +121,7 @@ struct EvacuationBlock {
   Dir new_dir;
   // we need to have a list of evacuationkeys because of collision.
   EvacuationKey evac_frags;
-  CacheVC *earliest_evacuator;
+  CacheEvacuateDocVC *earliest_evacuator;
   LINK(EvacuationBlock, link);
 };
 
@@ -160,7 +161,7 @@ struct Vol : public Continuation {
   int evacuate_size              = 0;
   DLL<EvacuationBlock> *evacuate = nullptr;
   DLL<EvacuationBlock> lookaside[LOOKASIDE_SIZE];
-  CacheVC *doc_evacuator = nullptr;
+  CacheEvacuateDocVC *doc_evacuator = nullptr;
 
   VolInitInfo *init_info = nullptr;
 
@@ -219,7 +220,7 @@ struct Vol : public Continuation {
   int aggWrite(int event, void *e);
   void agg_wrap();
 
-  int evacuateWrite(CacheVC *evacuator, int event, Event *e);
+  int evacuateWrite(CacheEvacuateDocVC *evacuator, int event, Event *e);
   int evacuateDocReadDone(int event, Event *e);
   int evacuateDoc(int event, Event *e);
 
diff --git a/iocore/eventsystem/I_Thread.h b/iocore/eventsystem/I_Thread.h
index f90f5f0990..53c69f3885 100644
--- a/iocore/eventsystem/I_Thread.h
+++ b/iocore/eventsystem/I_Thread.h
@@ -126,6 +126,7 @@ public:
   ProxyAllocator hdrHeapAllocator;
   ProxyAllocator strHeapAllocator;
   ProxyAllocator cacheVConnectionAllocator;
+  ProxyAllocator cacheEvacuateDocVConnectionAllocator;
   ProxyAllocator openDirEntryAllocator;
   ProxyAllocator ramCacheCLFUSEntryAllocator;
   ProxyAllocator ramCacheLRUEntryAllocator;

Reply via email to