This is an automated email from the ASF dual-hosted git repository.
jvanderzee 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 ed0a36d30d Extract Stripe superclass from StripeSM (#11565)
ed0a36d30d is described below
commit ed0a36d30ddcdc05c133066da43946e7cf090988
Author: JosiahWI <[email protected]>
AuthorDate: Thu Jul 25 05:47:53 2024 -0500
Extract Stripe superclass from StripeSM (#11565)
* Extract `Stripe` superclass from `StripeSM`
The `StripeSM` class retains all the evacuation data and the mutex.
* Update documentation
---
.../cache-architecture/architecture.en.rst | 4 +-
.../cache-architecture/data-structures.en.rst | 22 +-
src/iocore/cache/AggregateWriteBuffer.h | 4 +-
src/iocore/cache/Cache.cc | 4 +-
src/iocore/cache/CacheDir.cc | 33 +--
src/iocore/cache/CacheVC.cc | 10 +-
src/iocore/cache/P_CacheDir.h | 42 ++--
src/iocore/cache/P_CacheVol.h | 247 +++-----------------
src/iocore/cache/Stripe.cc | 14 +-
src/iocore/cache/Stripe.h | 252 +++++++++++++++++++++
10 files changed, 352 insertions(+), 280 deletions(-)
diff --git a/doc/developer-guide/cache-architecture/architecture.en.rst
b/doc/developer-guide/cache-architecture/architecture.en.rst
index d7cfae3638..db2eab0e8e 100644
--- a/doc/developer-guide/cache-architecture/architecture.en.rst
+++ b/doc/developer-guide/cache-architecture/architecture.en.rst
@@ -280,11 +280,11 @@ start
The offset for the start of the content, after the stripe metadata.
length
- Total number of bytes in the stripe. :cpp:member:`StripeSM::len`.
+ Total number of bytes in the stripe. :cpp:member:`Stripe::len`.
data length
Total number of blocks in the stripe available for content storage.
- :cpp:member:`StripeSM::data_blocks`.
+ :cpp:member:`Stripe::data_blocks`.
.. note::
diff --git a/doc/developer-guide/cache-architecture/data-structures.en.rst
b/doc/developer-guide/cache-architecture/data-structures.en.rst
index 0cbee69c08..d8ce281fbf 100644
--- a/doc/developer-guide/cache-architecture/data-structures.en.rst
+++ b/doc/developer-guide/cache-architecture/data-structures.en.rst
@@ -133,7 +133,7 @@ Data Structures
* Timestamps for request and response from :term:`origin server`.
-.. class:: StripeSM
+.. class:: Stripe
This represents a :term:`storage unit` inside a :term:`cache volume`.
@@ -141,10 +141,6 @@ Data Structures
The number of blocks of storage in the stripe.
- .. cpp:member:: int aggWrite(int event, void * e)
-
- Schedule the aggregation buffer to be written to disk.
-
.. member:: off_t segments
The number of segments in the volume. This will be roughly the total
@@ -158,15 +154,23 @@ Data Structures
values this is around 16,384 (2^16 / 4). Buckets are used as the targets
of the index hash.
+ .. member:: off_t len
+
+ Length of stripe in bytes.
+
+.. class:: StripeSM
+
+ Defined in :ts:git:`src/iocore/cache/Stripe.h`.
+
+ .. cpp:member:: int aggWrite(int event, void * e)
+
+ Schedule the aggregation buffer to be written to disk.
+
.. member:: DLL<EvacuationBlock> evacuate
Array of :class:`EvacuationBlock` buckets. This is sized so there
is one bucket for every evacuation span.
- .. member:: off_t len
-
- Length of stripe in bytes.
-
.. member:: int evac_range(off_t low, off_t high, int evac_phase)
Start an evacuation if there is any :class:`EvacuationBlock` in the
range
diff --git a/src/iocore/cache/AggregateWriteBuffer.h
b/src/iocore/cache/AggregateWriteBuffer.h
index 998b081260..ad99b03ce0 100644
--- a/src/iocore/cache/AggregateWriteBuffer.h
+++ b/src/iocore/cache/AggregateWriteBuffer.h
@@ -80,7 +80,7 @@ public:
* have a correct len field, and its headers and data must follow it. This
* requires a pointer to a full document buffer - not just the Doc struct.
* @param approx_size The approximate size of all headers and data as
- * determined by StripeSM::round_to_approx_size. The document may not need
+ * determined by Stripe::round_to_approx_size. The document may not need
* this much space.
*
*/
@@ -100,7 +100,7 @@ public:
* The new document will be uninitialized.
*
* @param approx_size The approximate size of all headers and data as
- * determined by StripeSM::round_to_approx_size. The document may not need
+ * determined by Stripe::round_to_approx_size. The document may not need
* this much space.
* @return Returns a non-owning pointer to the new document.
*/
diff --git a/src/iocore/cache/Cache.cc b/src/iocore/cache/Cache.cc
index 2045edf825..1f1beb5edb 100644
--- a/src/iocore/cache/Cache.cc
+++ b/src/iocore/cache/Cache.cc
@@ -785,10 +785,10 @@ CacheProcessor::stop()
}
int
-CacheProcessor::dir_check(bool afix)
+CacheProcessor::dir_check(bool /* afix ATS_UNUSED */)
{
for (int i = 0; i < gnstripes; i++) {
- gstripes[i]->dir_check(afix);
+ gstripes[i]->dir_check();
}
return 0;
}
diff --git a/src/iocore/cache/CacheDir.cc b/src/iocore/cache/CacheDir.cc
index d892130110..c50b872ddd 100644
--- a/src/iocore/cache/CacheDir.cc
+++ b/src/iocore/cache/CacheDir.cc
@@ -24,6 +24,7 @@
#include "P_Cache.h"
#include "P_CacheDir.h"
#include "P_CacheDoc.h"
+#include "Stripe.h"
#include "tscore/hugepages.h"
#include "tscore/Random.h"
@@ -214,7 +215,7 @@ dir_bucket_loop_check(Dir *start_dir, Dir *seg)
// adds all the directory entries
// in a segment to the segment freelist
void
-dir_init_segment(int s, StripeSM *stripe)
+dir_init_segment(int s, Stripe *stripe)
{
stripe->header->freelist[s] = 0;
Dir *seg = stripe->dir_segment(s);
@@ -231,7 +232,7 @@ dir_init_segment(int s, StripeSM *stripe)
// break the infinite loop in directory entries
// Note : abuse of the token bit in dir entries
int
-dir_bucket_loop_fix(Dir *start_dir, int s, StripeSM *stripe)
+dir_bucket_loop_fix(Dir *start_dir, int s, Stripe *stripe)
{
if (!dir_bucket_loop_check(start_dir, stripe->dir_segment(s))) {
Warning("Dir loop exists, clearing segment %d", s);
@@ -242,7 +243,7 @@ dir_bucket_loop_fix(Dir *start_dir, int s, StripeSM *stripe)
}
int
-dir_freelist_length(StripeSM *stripe, int s)
+dir_freelist_length(Stripe *stripe, int s)
{
int free = 0;
Dir *seg = stripe->dir_segment(s);
@@ -258,7 +259,7 @@ dir_freelist_length(StripeSM *stripe, int s)
}
int
-dir_bucket_length(Dir *b, int s, StripeSM *stripe)
+dir_bucket_length(Dir *b, int s, Stripe *stripe)
{
Dir *e = b;
int i = 0;
@@ -278,7 +279,7 @@ dir_bucket_length(Dir *b, int s, StripeSM *stripe)
}
int
-check_dir(StripeSM *stripe)
+check_dir(Stripe *stripe)
{
int i, s;
Dbg(dbg_ctl_cache_check_dir, "inside check dir");
@@ -301,7 +302,7 @@ check_dir(StripeSM *stripe)
}
inline void
-unlink_from_freelist(Dir *e, int s, StripeSM *stripe)
+unlink_from_freelist(Dir *e, int s, Stripe *stripe)
{
Dir *seg = stripe->dir_segment(s);
Dir *p = dir_from_offset(dir_prev(e), seg);
@@ -317,7 +318,7 @@ unlink_from_freelist(Dir *e, int s, StripeSM *stripe)
}
inline Dir *
-dir_delete_entry(Dir *e, Dir *p, int s, StripeSM *stripe)
+dir_delete_entry(Dir *e, Dir *p, int s, Stripe *stripe)
{
Dir *seg = stripe->dir_segment(s);
int no = dir_next(e);
@@ -347,7 +348,7 @@ dir_delete_entry(Dir *e, Dir *p, int s, StripeSM *stripe)
}
inline void
-dir_clean_bucket(Dir *b, int s, StripeSM *stripe)
+dir_clean_bucket(Dir *b, int s, Stripe *stripe)
{
Dir *e = b, *p = nullptr;
Dir *seg = stripe->dir_segment(s);
@@ -380,7 +381,7 @@ dir_clean_bucket(Dir *b, int s, StripeSM *stripe)
}
void
-dir_clean_segment(int s, StripeSM *stripe)
+dir_clean_segment(int s, Stripe *stripe)
{
Dir *seg = stripe->dir_segment(s);
for (int64_t i = 0; i < stripe->buckets; i++) {
@@ -390,7 +391,7 @@ dir_clean_segment(int s, StripeSM *stripe)
}
void
-dir_clean_vol(StripeSM *stripe)
+dir_clean_vol(Stripe *stripe)
{
for (int64_t i = 0; i < stripe->segments; i++) {
dir_clean_segment(i, stripe);
@@ -399,7 +400,7 @@ dir_clean_vol(StripeSM *stripe)
}
void
-dir_clear_range(off_t start, off_t end, StripeSM *stripe)
+dir_clear_range(off_t start, off_t end, Stripe *stripe)
{
for (off_t i = 0; i < stripe->buckets * DIR_DEPTH * stripe->segments; i++) {
Dir *e = dir_index(stripe, i);
@@ -426,7 +427,7 @@ check_bucket_not_contains(Dir *b, Dir *e, Dir *seg)
}
void
-freelist_clean(int s, StripeSM *stripe)
+freelist_clean(int s, Stripe *stripe)
{
dir_clean_segment(s, stripe);
if (stripe->header->freelist[s]) {
@@ -450,7 +451,7 @@ freelist_clean(int s, StripeSM *stripe)
}
inline Dir *
-freelist_pop(int s, StripeSM *stripe)
+freelist_pop(int s, Stripe *stripe)
{
Dir *seg = stripe->dir_segment(s);
Dir *e = dir_from_offset(stripe->header->freelist[s], seg);
@@ -472,7 +473,7 @@ freelist_pop(int s, StripeSM *stripe)
}
int
-dir_segment_accounted(int s, StripeSM *stripe, int offby, int *f, int *u, int
*et, int *v, int *av, int *as)
+dir_segment_accounted(int s, Stripe *stripe, int offby, int *f, int *u, int
*et, int *v, int *av, int *as)
{
int free = dir_freelist_length(stripe, s);
int used = 0, empty = 0;
@@ -525,7 +526,7 @@ dir_segment_accounted(int s, StripeSM *stripe, int offby,
int *f, int *u, int *e
}
void
-dir_free_entry(Dir *e, int s, StripeSM *stripe)
+dir_free_entry(Dir *e, int s, Stripe *stripe)
{
Dir *seg = stripe->dir_segment(s);
unsigned int fo = stripe->header->freelist[s];
@@ -932,7 +933,7 @@ CacheSync::aio_write(int fd, char *b, int n, off_t o)
}
uint64_t
-dir_entries_used(StripeSM *stripe)
+dir_entries_used(Stripe *stripe)
{
uint64_t full = 0;
uint64_t sfull = 0;
diff --git a/src/iocore/cache/CacheVC.cc b/src/iocore/cache/CacheVC.cc
index 7c2041f092..6ab876f29e 100644
--- a/src/iocore/cache/CacheVC.cc
+++ b/src/iocore/cache/CacheVC.cc
@@ -27,7 +27,7 @@
#include "P_CacheDoc.h"
#include "P_CacheHttp.h"
#include "P_CacheInternal.h"
-#include "P_CacheVol.h"
+#include "Stripe.h"
// must be included after the others
#include "iocore/cache/CacheVC.h"
@@ -97,7 +97,7 @@ extern int64_t cache_config_ram_cache_cutoff;
* vol_map - precalculated map
* offset - offset to start looking at (and data at this location has not been
read yet). */
static off_t
-next_in_map(StripeSM *stripe, char *vol_map, off_t offset)
+next_in_map(Stripe *stripe, char *vol_map, off_t offset)
{
off_t start_offset = stripe->vol_offset_to_offset(0);
off_t new_off = (offset - start_offset);
@@ -113,16 +113,16 @@ next_in_map(StripeSM *stripe, char *vol_map, off_t offset)
}
// Function in CacheDir.cc that we need for make_vol_map().
-int dir_bucket_loop_fix(Dir *start_dir, int s, StripeSM *stripe);
+int dir_bucket_loop_fix(Dir *start_dir, int s, Stripe *stripe);
// TODO: If we used a bit vector, we could make a smaller map structure.
// TODO: If we saved a high water mark we could have a smaller buf, and avoid
searching it
// when we are asked about the highest interesting offset.
/* Make map of what blocks in partition are used.
*
- * d - StripeSM to make a map of. */
+ * d - Stripe to make a map of. */
static char *
-make_vol_map(StripeSM *stripe)
+make_vol_map(Stripe *stripe)
{
// Map will be one byte for each SCAN_BUF_SIZE bytes.
off_t start_offset = stripe->vol_offset_to_offset(0);
diff --git a/src/iocore/cache/P_CacheDir.h b/src/iocore/cache/P_CacheDir.h
index d1056f8c33..ffa91eaf0a 100644
--- a/src/iocore/cache/P_CacheDir.h
+++ b/src/iocore/cache/P_CacheDir.h
@@ -33,6 +33,7 @@
// aio
#include "iocore/aio/AIO.h"
+class Stripe;
class StripeSM;
struct InterimCacheVol;
struct CacheVC;
@@ -266,29 +267,28 @@ struct CacheSync : public Continuation {
// Global Functions
-int dir_probe(const CacheKey *, StripeSM *, Dir *, Dir **);
-int dir_insert(const CacheKey *key, StripeSM *stripe, Dir *to_part);
-int dir_overwrite(const CacheKey *key, StripeSM *stripe, Dir *to_part, Dir
*overwrite, bool must_overwrite = true);
-int dir_delete(const CacheKey *key, StripeSM *stripe, Dir *del);
-int dir_lookaside_probe(const CacheKey *key, StripeSM *stripe, Dir *result,
EvacuationBlock **eblock);
-int dir_lookaside_insert(EvacuationBlock *b, StripeSM *stripe, Dir *to);
-int dir_lookaside_fixup(const CacheKey *key, StripeSM *stripe);
-void dir_lookaside_cleanup(StripeSM *stripe);
-void dir_lookaside_remove(const CacheKey *key, StripeSM *stripe);
-void dir_free_entry(Dir *e, int s, StripeSM *stripe);
-void dir_sync_init();
-int check_dir(StripeSM *stripe);
-void dir_clean_vol(StripeSM *stripe);
-void dir_clear_range(off_t start, off_t end, StripeSM *stripe);
-int dir_segment_accounted(int s, StripeSM *stripe, int offby = 0, int *free =
nullptr, int *used = nullptr, int *empty = nullptr,
- int *valid = nullptr, int *agg_valid = nullptr, int
*avg_size = nullptr);
-uint64_t dir_entries_used(StripeSM *stripe);
+int dir_probe(const CacheKey *, StripeSM *, Dir *, Dir **);
+int dir_insert(const CacheKey *key, StripeSM *stripe, Dir *to_part);
+int dir_overwrite(const CacheKey *key, StripeSM *stripe, Dir *to_part,
Dir *overwrite, bool must_overwrite = true);
+int dir_delete(const CacheKey *key, StripeSM *stripe, Dir *del);
+int dir_lookaside_probe(const CacheKey *key, StripeSM *stripe, Dir
*result, EvacuationBlock **eblock);
+int dir_lookaside_insert(EvacuationBlock *b, StripeSM *stripe, Dir *to);
+int dir_lookaside_fixup(const CacheKey *key, StripeSM *stripe);
+void dir_lookaside_cleanup(StripeSM *stripe);
+void dir_lookaside_remove(const CacheKey *key, StripeSM *stripe);
+void dir_free_entry(Dir *e, int s, Stripe *stripe);
+void dir_sync_init();
+int check_dir(Stripe *stripe);
+void dir_clean_vol(Stripe *stripe);
+void dir_clear_range(off_t start, off_t end, Stripe *stripe);
+int dir_segment_accounted(int s, Stripe *stripe, int offby = 0, int *free
= nullptr, int *used = nullptr, int *empty = nullptr,
+ int *valid = nullptr, int *agg_valid = nullptr,
int *avg_size = nullptr);
+uint64_t dir_entries_used(Stripe *stripe);
void sync_cache_dir_on_shutdown();
-int dir_freelist_length(StripeSM *stripe, int s);
-int dir_bucket_length(Dir *b, int s, StripeSM *stripe);
-int dir_freelist_length(StripeSM *stripe, int s);
-void dir_clean_segment(int s, StripeSM *stripe);
+int dir_bucket_length(Dir *b, int s, Stripe *stripe);
+int dir_freelist_length(Stripe *stripe, int s);
+void dir_clean_segment(int s, Stripe *stripe);
// Inline Functions
diff --git a/src/iocore/cache/P_CacheVol.h b/src/iocore/cache/P_CacheVol.h
index 02dd78d07b..2766db459c 100644
--- a/src/iocore/cache/P_CacheVol.h
+++ b/src/iocore/cache/P_CacheVol.h
@@ -28,6 +28,7 @@
#include "P_CacheStats.h"
#include "P_RamCache.h"
#include "AggregateWriteBuffer.h"
+#include "Stripe.h"
#include "iocore/eventsystem/EThread.h"
@@ -35,13 +36,6 @@
#include <atomic>
-#define CACHE_BLOCK_SHIFT 9
-#define CACHE_BLOCK_SIZE (1 << CACHE_BLOCK_SHIFT) // 512, smallest
sector size
-#define ROUND_TO_STORE_BLOCK(_x) INK_ALIGN((_x), STORE_BLOCK_SIZE)
-#define ROUND_TO_CACHE_BLOCK(_x) INK_ALIGN((_x), CACHE_BLOCK_SIZE)
-#define ROUND_TO_SECTOR(_p, _x) INK_ALIGN((_x), _p->sector_size)
-#define ROUND_TO(_x, _y) INK_ALIGN((_x), (_y))
-
// Stripe
#define STRIPE_MAGIC 0xF1D0F00D
#define START_BLOCKS 16 // 8k, STORE_BLOCK_SIZE
@@ -58,7 +52,6 @@
#define STRIPE_HASH_ALLOC_SIZE (8 * 1024 * 1024) // one chance per this
unit
#define LOOKASIDE_SIZE 256
#define EVACUATION_BUCKET_SIZE (2 * EVACUATION_SIZE) // 16MB
-#define RECOVERY_SIZE EVACUATION_SIZE // 8MB
#define AIO_NOT_IN_PROGRESS -1
#define AIO_AGG_WRITE_IN_PROGRESS -2
#define AUTO_SIZE_RAM_CACHE -1 // 1-1 with
directory size
@@ -80,24 +73,6 @@ struct DiskStripe;
struct CacheVol;
class CacheEvacuateDocVC;
-struct StripteHeaderFooter {
- unsigned int magic;
- ts::VersionNumber version;
- time_t create_time;
- off_t write_pos;
- off_t last_write_pos;
- off_t agg_pos;
- uint32_t generation; // token generation (vary), this cannot be 0
- uint32_t phase;
- uint32_t cycle;
- uint32_t sync_serial;
- uint32_t write_serial;
- uint32_t dirty;
- uint32_t sector_size;
- uint32_t unused; // pad out to 8 byte boundary
- uint16_t freelist[1];
-};
-
// Key and Earliest key for each fragment that needs to be evacuated
struct EvacuationKey {
SLink<EvacuationKey> link;
@@ -125,53 +100,36 @@ struct EvacuationBlock {
LINK(EvacuationBlock, link);
};
-class StripeSM : public Continuation
+class StripeSM : public Continuation, public Stripe
{
public:
- char *path = nullptr;
- ats_scoped_str hash_text;
- CryptoHash hash_id;
- int fd = -1;
-
- char *raw_dir = nullptr;
- Dir *dir = nullptr;
- StripteHeaderFooter *header = nullptr;
- StripteHeaderFooter *footer = nullptr;
- int segments = 0;
- off_t buckets = 0;
- off_t recover_pos = 0;
- off_t prev_recover_pos = 0;
- off_t scan_pos = 0;
- off_t skip = 0; // start of headers
- off_t start = 0; // start of data
- off_t len = 0;
- off_t data_blocks = 0;
- int hit_evacuate_window = 0;
- AIOCallbackInternal io;
+ CryptoHash hash_id;
+
+ int hit_evacuate_window{};
+
+ off_t recover_pos = 0;
+ off_t prev_recover_pos = 0;
+ AIOCallbackInternal io;
Queue<CacheVC, Continuation::Link_link> sync;
Event *trigger = nullptr;
OpenDir open_dir;
- RamCache *ram_cache = nullptr;
- int evacuate_size = 0;
- DLL<EvacuationBlock> *evacuate = nullptr;
+ RamCache *ram_cache = nullptr;
+ DLL<EvacuationBlock> *evacuate = nullptr;
DLL<EvacuationBlock> lookaside[LOOKASIDE_SIZE];
CacheEvacuateDocVC *doc_evacuator = nullptr;
StripeInitInfo *init_info = nullptr;
- CacheDisk *disk = nullptr;
- Cache *cache = nullptr;
- CacheVol *cache_vol = nullptr;
- uint32_t last_sync_serial = 0;
- uint32_t last_write_serial = 0;
- uint32_t sector_size = 0;
- bool recover_wrapped = false;
- bool dir_sync_waiting = false;
- bool dir_sync_in_progress = false;
- bool writing_end_marker = false;
+ Cache *cache = nullptr;
+ uint32_t last_sync_serial = 0;
+ uint32_t last_write_serial = 0;
+ bool recover_wrapped = false;
+ bool dir_sync_waiting = false;
+ bool dir_sync_in_progress = false;
+ bool writing_end_marker = false;
CacheKey first_fragment_key;
int64_t first_fragment_offset = 0;
@@ -207,10 +165,6 @@ public:
int dir_init_done(int event, void *data);
- int dir_check(bool fix);
-
- bool evac_bucket_valid(off_t bucket) const;
-
int is_io_in_progress() const;
void set_io_not_in_progress();
@@ -249,25 +203,8 @@ public:
void evacuate_cleanup_blocks(int i);
void evacuate_cleanup();
EvacuationBlock *force_evacuate_head(Dir const *dir, int pinned);
- int within_hit_evacuate_window(Dir const *dir) const;
- uint32_t round_to_approx_size(uint32_t l) const;
-
- // inline functions
- int headerlen() const; // calculates the total length of the vol
header and the freelist
- int direntries() const; // total number of dir entries
- Dir *dir_segment(int s) const; // returns the first dir in the segment s
- size_t dirlen() const; // calculates the total length of header,
directories and footer
- int vol_out_of_phase_valid(Dir const *e) const;
-
- int vol_out_of_phase_agg_valid(Dir const *e) const;
- int vol_out_of_phase_write_valid(Dir const *e) const;
- int vol_in_phase_valid(Dir const *e) const;
- int vol_in_phase_agg_buf_valid(Dir const *e) const;
-
- off_t vol_offset(Dir const *e) const;
- off_t offset_to_vol_offset(off_t pos) const;
- off_t vol_offset_to_offset(off_t pos) const;
- off_t vol_relative_length(off_t start_offset) const;
+
+ int within_hit_evacuate_window(Dir const *dir) const;
StripeSM() : Continuation(new_ProxyMutex())
{
@@ -276,7 +213,6 @@ public:
}
Queue<CacheVC, Continuation::Link_link> &get_pending_writers();
- int get_agg_buf_pos() const;
/**
* Add a virtual connection waiting to write to this stripe.
@@ -310,31 +246,10 @@ public:
*/
void shutdown(EThread *shutdown_thread);
- /**
- * Retrieve a document from the aggregate write buffer.
- *
- * This is used to speed up reads by copying from the in-memory write buffer
- * instead of reading from disk. If the document is not in the write buffer,
- * nothing will be copied.
- *
- * @param dir: The directory entry for the desired document.
- * @param dest: The destination buffer where the document will be copied to.
- * @param nbytes: The size of the document (number of bytes to copy).
- * @return Returns true if the document was copied, false otherwise.
- */
- bool copy_from_aggregate_write_buffer(char *dest, Dir const &dir, size_t
nbytes) const;
-
private:
- void _clear_init();
- void _init_dir();
- void _init_data_internal();
- void _init_data();
- int _agg_copy(CacheVC *vc);
- int _copy_writer_to_aggregation(CacheVC *vc);
- int _copy_evacuator_to_aggregation(CacheVC *vc);
- bool flush_aggregate_write_buffer();
-
- AggregateWriteBuffer _write_buffer;
+ int _agg_copy(CacheVC *vc);
+ int _copy_writer_to_aggregation(CacheVC *vc);
+ int _copy_evacuator_to_aggregation(CacheVC *vc);
};
struct AIO_failure_handler : public Continuation {
@@ -369,87 +284,6 @@ extern unsigned short *vol_hash_table;
// inline Functions
-inline int
-StripeSM::headerlen() const
-{
- return ROUND_TO_STORE_BLOCK(sizeof(StripteHeaderFooter) + sizeof(uint16_t) *
(this->segments - 1));
-}
-
-inline Dir *
-StripeSM::dir_segment(int s) const
-{
- return (Dir *)(((char *)this->dir) + (s * this->buckets) * DIR_DEPTH *
SIZEOF_DIR);
-}
-
-inline size_t
-StripeSM::dirlen() const
-{
- return this->headerlen() + ROUND_TO_STORE_BLOCK(((size_t)this->buckets) *
DIR_DEPTH * this->segments * SIZEOF_DIR) +
- ROUND_TO_STORE_BLOCK(sizeof(StripteHeaderFooter));
-}
-
-inline int
-StripeSM::direntries() const
-{
- return this->buckets * DIR_DEPTH * this->segments;
-}
-
-inline int
-StripeSM::vol_out_of_phase_valid(Dir const *e) const
-{
- return (dir_offset(e) - 1 >= ((this->header->agg_pos - this->start) /
CACHE_BLOCK_SIZE));
-}
-
-inline int
-StripeSM::vol_out_of_phase_agg_valid(Dir const *e) const
-{
- return (dir_offset(e) - 1 >= ((this->header->agg_pos - this->start +
AGG_SIZE) / CACHE_BLOCK_SIZE));
-}
-
-inline int
-StripeSM::vol_out_of_phase_write_valid(Dir const *e) const
-{
- return (dir_offset(e) - 1 >= ((this->header->write_pos - this->start) /
CACHE_BLOCK_SIZE));
-}
-
-inline int
-StripeSM::vol_in_phase_valid(Dir const *e) const
-{
- return (dir_offset(e) - 1 < ((this->header->write_pos +
this->_write_buffer.get_buffer_pos() - this->start) / CACHE_BLOCK_SIZE));
-}
-
-inline off_t
-StripeSM::vol_offset(Dir const *e) const
-{
- return this->start + (off_t)dir_offset(e) * CACHE_BLOCK_SIZE -
CACHE_BLOCK_SIZE;
-}
-
-inline off_t
-StripeSM::offset_to_vol_offset(off_t pos) const
-{
- return ((pos - this->start + CACHE_BLOCK_SIZE) / CACHE_BLOCK_SIZE);
-}
-
-inline off_t
-StripeSM::vol_offset_to_offset(off_t pos) const
-{
- return this->start + pos * CACHE_BLOCK_SIZE - CACHE_BLOCK_SIZE;
-}
-
-inline int
-StripeSM::vol_in_phase_agg_buf_valid(Dir const *e) const
-{
- return (this->vol_offset(e) >= this->header->write_pos &&
- this->vol_offset(e) < (this->header->write_pos +
this->_write_buffer.get_buffer_pos()));
-}
-
-// length of the partition not including the offset of location 0.
-inline off_t
-StripeSM::vol_relative_length(off_t start_offset) const
-{
- return (this->len + this->skip) - start_offset;
-}
-
// inline Functions
inline EvacuationBlock *
@@ -505,31 +339,6 @@ StripeSM::open_read(const CryptoHash *key) const
return open_dir.open_read(key);
}
-inline int
-StripeSM::within_hit_evacuate_window(Dir const *xdir) const
-{
- off_t oft = dir_offset(xdir) - 1;
- off_t write_off = (header->write_pos + AGG_SIZE - start) / CACHE_BLOCK_SIZE;
- off_t delta = oft - write_off;
- if (delta >= 0)
- return delta < hit_evacuate_window;
- else
- return -delta > (data_blocks - hit_evacuate_window) && -delta <
data_blocks;
-}
-
-inline uint32_t
-StripeSM::round_to_approx_size(uint32_t l) const
-{
- uint32_t ll = round_to_approx_dir_size(l);
- return ROUND_TO_SECTOR(this, ll);
-}
-
-inline bool
-StripeSM::evac_bucket_valid(off_t bucket) const
-{
- return (bucket >= 0 && bucket < evacuate_size);
-}
-
inline int
StripeSM::is_io_in_progress() const
{
@@ -549,7 +358,13 @@ StripeSM::get_pending_writers()
}
inline int
-StripeSM::get_agg_buf_pos() const
+StripeSM::within_hit_evacuate_window(Dir const *xdir) const
{
- return this->_write_buffer.get_buffer_pos();
+ off_t oft = dir_offset(xdir) - 1;
+ off_t write_off = (header->write_pos + AGG_SIZE - start) / CACHE_BLOCK_SIZE;
+ off_t delta = oft - write_off;
+ if (delta >= 0)
+ return delta < hit_evacuate_window;
+ else
+ return -delta > (data_blocks - hit_evacuate_window) && -delta <
data_blocks;
}
diff --git a/src/iocore/cache/Stripe.cc b/src/iocore/cache/Stripe.cc
index 2f37dfadd8..c8ba5268af 100644
--- a/src/iocore/cache/Stripe.cc
+++ b/src/iocore/cache/Stripe.cc
@@ -720,7 +720,7 @@ StripeSM::dir_init_done(int /* event ATS_UNUSED */, void *
/* data ATS_UNUSED */
}
int
-StripeSM::dir_check(bool /* fix ATS_UNUSED */) // TODO: we should eliminate
this parameter ?
+Stripe::dir_check()
{
static int const SEGMENT_HISTOGRAM_WIDTH = 16;
int hist[SEGMENT_HISTOGRAM_WIDTH + 1] = {0};
@@ -876,7 +876,7 @@ StripeSM::dir_check(bool /* fix ATS_UNUSED */) // TODO: we
should eliminate this
}
void
-StripeSM::_clear_init()
+Stripe::_clear_init()
{
size_t dir_len = this->dirlen();
memset(this->raw_dir, 0, dir_len);
@@ -895,7 +895,7 @@ StripeSM::_clear_init()
}
void
-StripeSM::_init_dir()
+Stripe::_init_dir()
{
int b, s, l;
@@ -912,7 +912,7 @@ StripeSM::_init_dir()
}
void
-StripeSM::_init_data_internal()
+Stripe::_init_data_internal()
{
// step1: calculate the number of entries.
off_t total_entries = (this->len - (this->start - this->skip)) /
cache_config_min_average_object_size;
@@ -927,7 +927,7 @@ StripeSM::_init_data_internal()
}
void
-StripeSM::_init_data()
+Stripe::_init_data()
{
// iteratively calculate start + buckets
this->_init_data_internal();
@@ -1170,7 +1170,7 @@ StripeSM::_copy_evacuator_to_aggregation(CacheVC *vc)
}
bool
-StripeSM::flush_aggregate_write_buffer()
+Stripe::flush_aggregate_write_buffer()
{
// set write limit
this->header->agg_pos = this->header->write_pos +
this->_write_buffer.get_buffer_pos();
@@ -1188,7 +1188,7 @@ StripeSM::flush_aggregate_write_buffer()
}
bool
-StripeSM::copy_from_aggregate_write_buffer(char *dest, Dir const &dir, size_t
nbytes) const
+Stripe::copy_from_aggregate_write_buffer(char *dest, Dir const &dir, size_t
nbytes) const
{
if (!dir_agg_buf_valid(this, &dir)) {
return false;
diff --git a/src/iocore/cache/Stripe.h b/src/iocore/cache/Stripe.h
new file mode 100644
index 0000000000..f9ce59aec3
--- /dev/null
+++ b/src/iocore/cache/Stripe.h
@@ -0,0 +1,252 @@
+/** @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 "AggregateWriteBuffer.h"
+#include "P_CacheDir.h"
+#include "P_CacheDisk.h"
+
+#include "iocore/cache/Store.h"
+
+#include "tscore/ink_align.h"
+#include "tscore/ink_memory.h"
+#include "tscore/ink_platform.h"
+
+#include <cstdint>
+
+#define CACHE_BLOCK_SHIFT 9
+#define CACHE_BLOCK_SIZE (1 << CACHE_BLOCK_SHIFT) // 512, smallest
sector size
+#define ROUND_TO_STORE_BLOCK(_x) INK_ALIGN((_x), STORE_BLOCK_SIZE)
+#define ROUND_TO_CACHE_BLOCK(_x) INK_ALIGN((_x), CACHE_BLOCK_SIZE)
+#define ROUND_TO_SECTOR(_p, _x) INK_ALIGN((_x), _p->sector_size)
+#define ROUND_TO(_x, _y) INK_ALIGN((_x), (_y))
+
+// This is defined here so CacheVC can avoid including P_CacheVol.h.
+#define RECOVERY_SIZE EVACUATION_SIZE // 8MB
+
+struct CacheVol;
+
+struct StripteHeaderFooter {
+ unsigned int magic;
+ ts::VersionNumber version;
+ time_t create_time;
+ off_t write_pos;
+ off_t last_write_pos;
+ off_t agg_pos;
+ uint32_t generation; // token generation (vary), this cannot be 0
+ uint32_t phase;
+ uint32_t cycle;
+ uint32_t sync_serial;
+ uint32_t write_serial;
+ uint32_t dirty;
+ uint32_t sector_size;
+ uint32_t unused; // pad out to 8 byte boundary
+ uint16_t freelist[1];
+};
+
+class Stripe
+{
+public:
+ ats_scoped_str hash_text;
+ char *path = nullptr;
+ int fd{-1};
+
+ char *raw_dir{nullptr};
+ Dir *dir{};
+ StripteHeaderFooter *header{};
+ StripteHeaderFooter *footer{};
+ int segments{};
+ off_t buckets{};
+ off_t scan_pos{};
+ off_t skip{}; // start of headers
+ off_t start{}; // start of data
+ off_t len{};
+ off_t data_blocks{};
+
+ int evacuate_size{};
+
+ CacheDisk *disk{};
+ uint32_t sector_size{};
+
+ CacheVol *cache_vol{};
+
+ int dir_check();
+
+ bool evac_bucket_valid(off_t bucket) const;
+
+ uint32_t round_to_approx_size(uint32_t l) const;
+
+ // inline functions
+ /* Calculates the total length of the vol header and the freelist.
+ */
+ int headerlen() const;
+ /* Total number of dir entries.
+ */
+ int direntries() const;
+ /* Returns the first dir in segment @a s.
+ */
+ Dir *dir_segment(int s) const;
+ /* Calculates the total length of the header, directories and footer.
+ */
+ size_t dirlen() const;
+ int vol_out_of_phase_valid(Dir const *e) const;
+
+ int vol_out_of_phase_agg_valid(Dir const *e) const;
+ int vol_out_of_phase_write_valid(Dir const *e) const;
+ int vol_in_phase_valid(Dir const *e) const;
+ int vol_in_phase_agg_buf_valid(Dir const *e) const;
+
+ off_t vol_offset(Dir const *e) const;
+ off_t offset_to_vol_offset(off_t pos) const;
+ off_t vol_offset_to_offset(off_t pos) const;
+ /* Length of the partition not including the offset of location 0.
+ */
+ off_t vol_relative_length(off_t start_offset) const;
+
+ int get_agg_buf_pos() const;
+
+ /**
+ * Retrieve a document from the aggregate write buffer.
+ *
+ * This is used to speed up reads by copying from the in-memory write buffer
+ * instead of reading from disk. If the document is not in the write buffer,
+ * nothing will be copied.
+ *
+ * @param dir: The directory entry for the desired document.
+ * @param dest: The destination buffer where the document will be copied to.
+ * @param nbytes: The size of the document (number of bytes to copy).
+ * @return Returns true if the document was copied, false otherwise.
+ */
+ bool copy_from_aggregate_write_buffer(char *dest, Dir const &dir, size_t
nbytes) const;
+
+protected:
+ AggregateWriteBuffer _write_buffer;
+
+ void _clear_init();
+ void _init_dir();
+ void _init_data();
+ bool flush_aggregate_write_buffer();
+
+private:
+ void _init_data_internal();
+};
+
+inline bool
+Stripe::evac_bucket_valid(off_t bucket) const
+{
+ return (bucket >= 0 && bucket < evacuate_size);
+}
+
+inline uint32_t
+Stripe::round_to_approx_size(uint32_t l) const
+{
+ uint32_t ll = round_to_approx_dir_size(l);
+ return ROUND_TO_SECTOR(this, ll);
+}
+
+inline int
+Stripe::headerlen() const
+{
+ return ROUND_TO_STORE_BLOCK(sizeof(StripteHeaderFooter) + sizeof(uint16_t) *
(this->segments - 1));
+}
+
+inline int
+Stripe::direntries() const
+{
+ return this->buckets * DIR_DEPTH * this->segments;
+}
+
+inline Dir *
+Stripe::dir_segment(int s) const
+{
+ return (Dir *)(((char *)this->dir) + (s * this->buckets) * DIR_DEPTH *
SIZEOF_DIR);
+}
+
+inline size_t
+Stripe::dirlen() const
+{
+ return this->headerlen() + ROUND_TO_STORE_BLOCK(((size_t)this->buckets) *
DIR_DEPTH * this->segments * SIZEOF_DIR) +
+ ROUND_TO_STORE_BLOCK(sizeof(StripteHeaderFooter));
+}
+
+inline int
+Stripe::vol_out_of_phase_valid(Dir const *e) const
+{
+ return (dir_offset(e) - 1 >= ((this->header->agg_pos - this->start) /
CACHE_BLOCK_SIZE));
+}
+
+inline int
+Stripe::vol_out_of_phase_agg_valid(Dir const *e) const
+{
+ return (dir_offset(e) - 1 >= ((this->header->agg_pos - this->start +
AGG_SIZE) / CACHE_BLOCK_SIZE));
+}
+
+inline int
+Stripe::vol_out_of_phase_write_valid(Dir const *e) const
+{
+ return (dir_offset(e) - 1 >= ((this->header->write_pos - this->start) /
CACHE_BLOCK_SIZE));
+}
+
+inline int
+Stripe::vol_in_phase_valid(Dir const *e) const
+{
+ return (dir_offset(e) - 1 < ((this->header->write_pos +
this->_write_buffer.get_buffer_pos() - this->start) / CACHE_BLOCK_SIZE));
+}
+
+inline int
+Stripe::vol_in_phase_agg_buf_valid(Dir const *e) const
+{
+ return (this->vol_offset(e) >= this->header->write_pos &&
+ this->vol_offset(e) < (this->header->write_pos +
this->_write_buffer.get_buffer_pos()));
+}
+
+inline off_t
+Stripe::vol_offset(Dir const *e) const
+{
+ return this->start + (off_t)dir_offset(e) * CACHE_BLOCK_SIZE -
CACHE_BLOCK_SIZE;
+}
+
+inline off_t
+Stripe::offset_to_vol_offset(off_t pos) const
+{
+ return ((pos - this->start + CACHE_BLOCK_SIZE) / CACHE_BLOCK_SIZE);
+}
+
+inline off_t
+Stripe::vol_offset_to_offset(off_t pos) const
+{
+ return this->start + pos * CACHE_BLOCK_SIZE - CACHE_BLOCK_SIZE;
+}
+
+inline off_t
+Stripe::vol_relative_length(off_t start_offset) const
+{
+ return (this->len + this->skip) - start_offset;
+}
+
+inline int
+Stripe::get_agg_buf_pos() const
+{
+ return this->_write_buffer.get_buffer_pos();
+}