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;