Skip to content

Commit

Permalink
Group directory related Stripe fields into struct (#11926)
Browse files Browse the repository at this point in the history
* Group Stripe directory fields into struct

* Move `Directory` to P_CacheDir.h

* Move `Stripe::direntries` to `Directory::entries`

This also replaces some explicit computations of the same quantity with the
method call.

* Move `Stripe::dir_segment` to Directory
  • Loading branch information
JosiahWI authored Jan 8, 2025
1 parent 87de4b7 commit 799ff20
Show file tree
Hide file tree
Showing 14 changed files with 312 additions and 292 deletions.
120 changes: 60 additions & 60 deletions src/iocore/cache/CacheDir.cc
Original file line number Diff line number Diff line change
Expand Up @@ -218,12 +218,12 @@ dir_bucket_loop_check(Dir *start_dir, Dir *seg)
void
dir_init_segment(int s, Stripe *stripe)
{
stripe->header->freelist[s] = 0;
Dir *seg = stripe->dir_segment(s);
stripe->directory.header->freelist[s] = 0;
Dir *seg = stripe->directory.get_segment(s);
int l, b;
memset(static_cast<void *>(seg), 0, SIZEOF_DIR * DIR_DEPTH * stripe->buckets);
memset(static_cast<void *>(seg), 0, SIZEOF_DIR * DIR_DEPTH * stripe->directory.buckets);
for (l = 1; l < DIR_DEPTH; l++) {
for (b = 0; b < stripe->buckets; b++) {
for (b = 0; b < stripe->directory.buckets; b++) {
Dir *bucket = dir_bucket(b, seg);
dir_free_entry(dir_bucket_row(bucket, l), s, stripe);
}
Expand All @@ -235,7 +235,7 @@ dir_init_segment(int s, Stripe *stripe)
int
dir_bucket_loop_fix(Dir *start_dir, int s, Stripe *stripe)
{
if (!dir_bucket_loop_check(start_dir, stripe->dir_segment(s))) {
if (!dir_bucket_loop_check(start_dir, stripe->directory.get_segment(s))) {
Warning("Dir loop exists, clearing segment %d", s);
dir_init_segment(s, stripe);
return 1;
Expand All @@ -247,10 +247,10 @@ int
dir_freelist_length(Stripe *stripe, int s)
{
int free = 0;
Dir *seg = stripe->dir_segment(s);
Dir *e = dir_from_offset(stripe->header->freelist[s], seg);
Dir *seg = stripe->directory.get_segment(s);
Dir *e = dir_from_offset(stripe->directory.header->freelist[s], seg);
if (dir_bucket_loop_fix(e, s, stripe)) {
return (DIR_DEPTH - 1) * stripe->buckets;
return (DIR_DEPTH - 1) * stripe->directory.buckets;
}
while (e) {
free++;
Expand All @@ -264,7 +264,7 @@ dir_bucket_length(Dir *b, int s, Stripe *stripe)
{
Dir *e = b;
int i = 0;
Dir *seg = stripe->dir_segment(s);
Dir *seg = stripe->directory.get_segment(s);
#ifdef LOOP_CHECK_MODE
if (dir_bucket_loop_fix(b, s, vol))
return 1;
Expand All @@ -284,9 +284,9 @@ check_dir(Stripe *stripe)
{
int i, s;
Dbg(dbg_ctl_cache_check_dir, "inside check dir");
for (s = 0; s < stripe->segments; s++) {
Dir *seg = stripe->dir_segment(s);
for (i = 0; i < stripe->buckets; i++) {
for (s = 0; s < stripe->directory.segments; s++) {
Dir *seg = stripe->directory.get_segment(s);
for (i = 0; i < stripe->directory.buckets; i++) {
Dir *b = dir_bucket(i, seg);
if (!(dir_bucket_length(b, s, stripe) >= 0)) {
return 0;
Expand All @@ -305,12 +305,12 @@ check_dir(Stripe *stripe)
inline void
unlink_from_freelist(Dir *e, int s, Stripe *stripe)
{
Dir *seg = stripe->dir_segment(s);
Dir *seg = stripe->directory.get_segment(s);
Dir *p = dir_from_offset(dir_prev(e), seg);
if (p) {
dir_set_next(p, dir_next(e));
} else {
stripe->header->freelist[s] = dir_next(e);
stripe->directory.header->freelist[s] = dir_next(e);
}
Dir *n = dir_from_offset(dir_next(e), seg);
if (n) {
Expand All @@ -321,19 +321,19 @@ unlink_from_freelist(Dir *e, int s, Stripe *stripe)
inline Dir *
dir_delete_entry(Dir *e, Dir *p, int s, Stripe *stripe)
{
Dir *seg = stripe->dir_segment(s);
int no = dir_next(e);
stripe->header->dirty = 1;
Dir *seg = stripe->directory.get_segment(s);
int no = dir_next(e);
stripe->directory.header->dirty = 1;
if (p) {
unsigned int fo = stripe->header->freelist[s];
unsigned int fo = stripe->directory.header->freelist[s];
unsigned int eo = dir_to_offset(e, seg);
dir_clear(e);
dir_set_next(p, no);
dir_set_next(e, fo);
if (fo) {
dir_set_prev(dir_from_offset(fo, seg), eo);
}
stripe->header->freelist[s] = eo;
stripe->directory.header->freelist[s] = eo;
} else {
Dir *n = next_dir(e, seg);
if (n) {
Expand All @@ -352,7 +352,7 @@ inline void
dir_clean_bucket(Dir *b, int s, Stripe *stripe)
{
Dir *e = b, *p = nullptr;
Dir *seg = stripe->dir_segment(s);
Dir *seg = stripe->directory.get_segment(s);
#ifdef LOOP_CHECK_MODE
int loop_count = 0;
#endif
Expand Down Expand Up @@ -384,8 +384,8 @@ dir_clean_bucket(Dir *b, int s, Stripe *stripe)
void
dir_clean_segment(int s, Stripe *stripe)
{
Dir *seg = stripe->dir_segment(s);
for (int64_t i = 0; i < stripe->buckets; i++) {
Dir *seg = stripe->directory.get_segment(s);
for (int64_t i = 0; i < stripe->directory.buckets; i++) {
dir_clean_bucket(dir_bucket(i, seg), s, stripe);
ink_assert(!dir_next(dir_bucket(i, seg)) || dir_offset(dir_bucket(i, seg)));
}
Expand All @@ -394,7 +394,7 @@ dir_clean_segment(int s, Stripe *stripe)
void
dir_clean_vol(Stripe *stripe)
{
for (int64_t i = 0; i < stripe->segments; i++) {
for (int64_t i = 0; i < stripe->directory.segments; i++) {
dir_clean_segment(i, stripe);
}
CHECK_DIR(d);
Expand All @@ -403,7 +403,7 @@ dir_clean_vol(Stripe *stripe)
void
dir_clear_range(off_t start, off_t end, Stripe *stripe)
{
for (off_t i = 0; i < stripe->buckets * DIR_DEPTH * stripe->segments; i++) {
for (off_t i = 0; i < stripe->directory.entries(); i++) {
Dir *e = dir_index(stripe, i);
if (dir_offset(e) >= static_cast<int64_t>(start) && dir_offset(e) < static_cast<int64_t>(end)) {
Metrics::Gauge::decrement(cache_rsb.direntries_used);
Expand Down Expand Up @@ -431,13 +431,13 @@ void
freelist_clean(int s, StripeSM *stripe)
{
dir_clean_segment(s, stripe);
if (stripe->header->freelist[s]) {
if (stripe->directory.header->freelist[s]) {
return;
}
Warning("cache directory overflow on '%s' segment %d, purging...", stripe->disk->path, s);
int n = 0;
Dir *seg = stripe->dir_segment(s);
for (int bi = 0; bi < stripe->buckets; bi++) {
Dir *seg = stripe->directory.get_segment(s);
for (int bi = 0; bi < stripe->directory.buckets; bi++) {
Dir *b = dir_bucket(bi, seg);
for (int l = 0; l < DIR_DEPTH; l++) {
Dir *e = dir_bucket_row(b, l);
Expand All @@ -454,19 +454,19 @@ freelist_clean(int s, StripeSM *stripe)
inline Dir *
freelist_pop(int s, StripeSM *stripe)
{
Dir *seg = stripe->dir_segment(s);
Dir *e = dir_from_offset(stripe->header->freelist[s], seg);
Dir *seg = stripe->directory.get_segment(s);
Dir *e = dir_from_offset(stripe->directory.header->freelist[s], seg);
if (!e) {
freelist_clean(s, stripe);
return nullptr;
}
stripe->header->freelist[s] = dir_next(e);
stripe->directory.header->freelist[s] = dir_next(e);
// if the freelist if bad, punt.
if (dir_offset(e)) {
dir_init_segment(s, stripe);
return nullptr;
}
Dir *h = dir_from_offset(stripe->header->freelist[s], seg);
Dir *h = dir_from_offset(stripe->directory.header->freelist[s], seg);
if (h) {
dir_set_prev(h, 0);
}
Expand All @@ -476,23 +476,23 @@ freelist_pop(int s, StripeSM *stripe)
void
dir_free_entry(Dir *e, int s, Stripe *stripe)
{
Dir *seg = stripe->dir_segment(s);
unsigned int fo = stripe->header->freelist[s];
Dir *seg = stripe->directory.get_segment(s);
unsigned int fo = stripe->directory.header->freelist[s];
unsigned int eo = dir_to_offset(e, seg);
dir_set_next(e, fo);
if (fo) {
dir_set_prev(dir_from_offset(fo, seg), eo);
}
stripe->header->freelist[s] = eo;
stripe->directory.header->freelist[s] = eo;
}

int
dir_probe(const CacheKey *key, StripeSM *stripe, Dir *result, Dir **last_collision)
{
ink_assert(stripe->mutex->thread_holding == this_ethread());
int s = key->slice32(0) % stripe->segments;
int b = key->slice32(1) % stripe->buckets;
Dir *seg = stripe->dir_segment(s);
int s = key->slice32(0) % stripe->directory.segments;
int b = key->slice32(1) % stripe->directory.buckets;
Dir *seg = stripe->directory.get_segment(s);
Dir *e = nullptr, *p = nullptr, *collision = *last_collision;
CHECK_DIR(d);
#ifdef LOOP_CHECK_MODE
Expand Down Expand Up @@ -559,10 +559,10 @@ int
dir_insert(const CacheKey *key, StripeSM *stripe, Dir *to_part)
{
ink_assert(stripe->mutex->thread_holding == this_ethread());
int s = key->slice32(0) % stripe->segments, l;
int bi = key->slice32(1) % stripe->buckets;
int s = key->slice32(0) % stripe->directory.segments, l;
int bi = key->slice32(1) % stripe->directory.buckets;
ink_assert(dir_approx_size(to_part) <= MAX_FRAG_SIZE + sizeof(Doc));
Dir *seg = stripe->dir_segment(s);
Dir *seg = stripe->directory.get_segment(s);
Dir *e = nullptr;
Dir *b = dir_bucket(bi, seg);
#if defined(DEBUG) && defined(DO_CHECK_DIR_FAST)
Expand Down Expand Up @@ -605,7 +605,7 @@ dir_insert(const CacheKey *key, StripeSM *stripe, Dir *to_part)
do {
prev = last;
last = next_dir(last, seg);
} while (last && (++l <= stripe->buckets * DIR_DEPTH));
} while (last && (++l <= stripe->directory.buckets * DIR_DEPTH));

dir_set_next(e, 0);
dir_set_next(prev, dir_to_offset(e, seg));
Expand All @@ -616,7 +616,7 @@ dir_insert(const CacheKey *key, StripeSM *stripe, Dir *to_part)
DDbg(dbg_ctl_dir_insert, "insert %p %X into vol %d bucket %d at %p tag %X %X boffset %" PRId64 "", e, key->slice32(0), stripe->fd,
bi, e, key->slice32(1), dir_tag(e), dir_offset(e));
CHECK_DIR(d);
stripe->header->dirty = 1;
stripe->directory.header->dirty = 1;
Metrics::Gauge::increment(cache_rsb.direntries_used);
Metrics::Gauge::increment(stripe->cache_vol->vol_rsb.direntries_used);

Expand All @@ -627,9 +627,9 @@ int
dir_overwrite(const CacheKey *key, StripeSM *stripe, Dir *dir, Dir *overwrite, bool must_overwrite)
{
ink_assert(stripe->mutex->thread_holding == this_ethread());
int s = key->slice32(0) % stripe->segments, l;
int bi = key->slice32(1) % stripe->buckets;
Dir *seg = stripe->dir_segment(s);
int s = key->slice32(0) % stripe->directory.segments, l;
int bi = key->slice32(1) % stripe->directory.buckets;
Dir *seg = stripe->directory.get_segment(s);
Dir *e = nullptr;
Dir *b = dir_bucket(bi, seg);
unsigned int t = DIR_MASK_TAG(key->slice32(2));
Expand Down Expand Up @@ -695,7 +695,7 @@ dir_overwrite(const CacheKey *key, StripeSM *stripe, Dir *dir, Dir *overwrite, b
do {
prev = last;
last = next_dir(last, seg);
} while (last && (++l <= stripe->buckets * DIR_DEPTH));
} while (last && (++l <= stripe->directory.buckets * DIR_DEPTH));

dir_set_next(e, 0);
dir_set_next(prev, dir_to_offset(e, seg));
Expand All @@ -706,17 +706,17 @@ dir_overwrite(const CacheKey *key, StripeSM *stripe, Dir *dir, Dir *overwrite, b
DDbg(dbg_ctl_dir_overwrite, "overwrite %p %X into vol %d bucket %d at %p tag %X %X boffset %" PRId64 "", e, key->slice32(0),
stripe->fd, bi, e, t, dir_tag(e), dir_offset(e));
CHECK_DIR(d);
stripe->header->dirty = 1;
stripe->directory.header->dirty = 1;
return res;
}

int
dir_delete(const CacheKey *key, StripeSM *stripe, Dir *del)
{
ink_assert(stripe->mutex->thread_holding == this_ethread());
int s = key->slice32(0) % stripe->segments;
int b = key->slice32(1) % stripe->buckets;
Dir *seg = stripe->dir_segment(s);
int s = key->slice32(0) % stripe->directory.segments;
int b = key->slice32(1) % stripe->directory.buckets;
Dir *seg = stripe->directory.get_segment(s);
Dir *e = nullptr, *p = nullptr;
#ifdef LOOP_CHECK_MODE
int loop_count = 0;
Expand Down Expand Up @@ -885,10 +885,10 @@ dir_entries_used(Stripe *stripe)
{
uint64_t full = 0;
uint64_t sfull = 0;
for (int s = 0; s < stripe->segments; full += sfull, s++) {
Dir *seg = stripe->dir_segment(s);
for (int s = 0; s < stripe->directory.segments; full += sfull, s++) {
Dir *seg = stripe->directory.get_segment(s);
sfull = 0;
for (int b = 0; b < stripe->buckets; b++) {
for (int b = 0; b < stripe->directory.buckets; b++) {
Dir *e = dir_bucket(b, seg);
if (dir_bucket_loop_fix(e, s, stripe)) {
sfull = 0;
Expand Down Expand Up @@ -996,7 +996,7 @@ CacheSync::mainEvent(int event, Event *e)
the serial number causes the cache to recover more data than necessary.
The dirty bit it set in dir_insert, dir_overwrite and dir_delete_entry
*/
if (!stripe->header->dirty) {
if (!stripe->directory.header->dirty) {
Dbg(dbg_ctl_cache_dir_sync, "Dir %s not dirty", stripe->hash_text.get());
goto Ldone;
}
Expand All @@ -1008,9 +1008,9 @@ CacheSync::mainEvent(int event, Event *e)
}
return EVENT_CONT;
}
Dbg(dbg_ctl_cache_dir_sync, "pos: %" PRIu64 " Dir %s dirty...syncing to disk", stripe->header->write_pos,
Dbg(dbg_ctl_cache_dir_sync, "pos: %" PRIu64 " Dir %s dirty...syncing to disk", stripe->directory.header->write_pos,
stripe->hash_text.get());
stripe->header->dirty = 0;
stripe->directory.header->dirty = 0;
if (buflen < dirlen) {
if (buf) {
if (buf_huge) {
Expand All @@ -1030,13 +1030,13 @@ CacheSync::mainEvent(int event, Event *e)
buf_huge = false;
}
}
stripe->header->sync_serial++;
stripe->footer->sync_serial = stripe->header->sync_serial;
stripe->directory.header->sync_serial++;
stripe->directory.footer->sync_serial = stripe->directory.header->sync_serial;
CHECK_DIR(d);
memcpy(buf, stripe->raw_dir, dirlen);
memcpy(buf, stripe->directory.raw_dir, dirlen);
stripe->dir_sync_in_progress = true;
}
size_t B = stripe->header->sync_serial & 1;
size_t B = stripe->directory.header->sync_serial & 1;
off_t start = stripe->skip + (B ? dirlen : 0);

if (!writepos) {
Expand Down
18 changes: 9 additions & 9 deletions src/iocore/cache/CacheProcessor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,8 @@ inline int64_t
cache_bytes_used(int index)
{
if (!DISK_BAD(gstripes[index]->disk)) {
if (!gstripes[index]->header->cycle) {
return gstripes[index]->header->write_pos - gstripes[index]->start;
if (!gstripes[index]->directory.header->cycle) {
return gstripes[index]->directory.header->write_pos - gstripes[index]->start;
} else {
return gstripes[index]->len - gstripes[index]->dirlen() - EVACUATION_SIZE;
}
Expand Down Expand Up @@ -456,7 +456,7 @@ CacheProcessor::mark_storage_offline(CacheDisk *d, ///< Target disk

for (p = 0; p < gnstripes; p++) {
if (d->fd == gstripes[p]->fd) {
total_dir_delete += gstripes[p]->buckets * gstripes[p]->segments * DIR_DEPTH;
total_dir_delete += gstripes[p]->directory.entries();
used_dir_delete += dir_entries_used(gstripes[p]);
total_bytes_delete += gstripes[p]->len - gstripes[p]->dirlen();
}
Expand Down Expand Up @@ -1420,16 +1420,16 @@ CacheProcessor::cacheInitialized()

// Update stripe version data.
if (gnstripes) { // start with whatever the first stripe is.
cacheProcessor.min_stripe_version = cacheProcessor.max_stripe_version = gstripes[0]->header->version;
cacheProcessor.min_stripe_version = cacheProcessor.max_stripe_version = gstripes[0]->directory.header->version;
}
// scan the rest of the stripes.
for (int i = 1; i < gnstripes; i++) {
StripeSM *v = gstripes[i];
if (v->header->version < cacheProcessor.min_stripe_version) {
cacheProcessor.min_stripe_version = v->header->version;
if (v->directory.header->version < cacheProcessor.min_stripe_version) {
cacheProcessor.min_stripe_version = v->directory.header->version;
}
if (cacheProcessor.max_stripe_version < v->header->version) {
cacheProcessor.max_stripe_version = v->header->version;
if (cacheProcessor.max_stripe_version < v->directory.header->version) {
cacheProcessor.max_stripe_version = v->directory.header->version;
}
}

Expand Down Expand Up @@ -1514,7 +1514,7 @@ CacheProcessor::cacheInitialized()
Dbg(dbg_ctl_cache_init, "total_cache_bytes = %" PRId64 " = %" PRId64 "Mb", total_cache_bytes,
total_cache_bytes / (1024 * 1024));

uint64_t vol_total_direntries = stripe->buckets * stripe->segments * DIR_DEPTH;
uint64_t vol_total_direntries = stripe->directory.entries();
total_direntries += vol_total_direntries;
Metrics::Gauge::increment(stripe->cache_vol->vol_rsb.direntries_total, vol_total_direntries);

Expand Down
Loading

0 comments on commit 799ff20

Please sign in to comment.