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

JosiahWI 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 0847dc6f85 Move some directory helpers to `Directory` (#13245)
0847dc6f85 is described below

commit 0847dc6f853a045b2dc7335fec052e748a5645a3
Author: JosiahWI <[email protected]>
AuthorDate: Tue Jun 9 06:56:28 2026 -0500

    Move some directory helpers to `Directory` (#13245)
    
    * Move `dir_init_segment` to `Directory`
    
    * Move `dir_init_segment` to `Directory`
    
    * Move `dir_bucket_loop_fix` to `Directory`
    
    * Move `unlink_from_freelist` to `Directory`
    
    * Move `dir_delete_entry` to `Directory`
    
    Co-authored-by: Copilot Autofix powered by AI 
<[email protected]>
---
 src/iocore/cache/CacheDir.cc  | 97 +++++++++++--------------------------------
 src/iocore/cache/CacheVC.cc   |  5 +--
 src/iocore/cache/P_CacheDir.h | 85 +++++++++++++++++++++++++++++++------
 3 files changed, 97 insertions(+), 90 deletions(-)

diff --git a/src/iocore/cache/CacheDir.cc b/src/iocore/cache/CacheDir.cc
index ee14d521ff..7997c50108 100644
--- a/src/iocore/cache/CacheDir.cc
+++ b/src/iocore/cache/CacheDir.cc
@@ -210,16 +210,16 @@ 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, Directory *directory)
+Directory::init_segment(int s)
 {
-  directory->header->freelist[s] = 0;
-  Dir *seg                       = directory->get_segment(s);
+  this->header->freelist[s] = 0;
+  Dir *seg                  = this->get_segment(s);
   int  l, b;
-  memset(static_cast<void *>(seg), 0, SIZEOF_DIR * DIR_DEPTH * 
directory->buckets);
+  memset(static_cast<void *>(seg), 0, SIZEOF_DIR * DIR_DEPTH * this->buckets);
   for (l = 1; l < DIR_DEPTH; l++) {
-    for (b = 0; b < directory->buckets; b++) {
+    for (b = 0; b < this->buckets; b++) {
       Dir *bucket = dir_bucket(b, seg);
-      directory->free_entry(dir_bucket_row(bucket, l), s);
+      this->free_entry(dir_bucket_row(bucket, l), s);
     }
   }
 }
@@ -227,11 +227,11 @@ dir_init_segment(int s, Directory *directory)
 // 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, Directory *directory)
+Directory::bucket_loop_fix(Dir *start_dir, int s)
 {
-  if (!dir_bucket_loop_check(start_dir, directory->get_segment(s))) {
+  if (!dir_bucket_loop_check(start_dir, this->get_segment(s))) {
     Warning("Dir loop exists, clearing segment %d", s);
-    dir_init_segment(s, directory);
+    this->init_segment(s);
     return 1;
   }
   return 0;
@@ -243,7 +243,7 @@ Directory::freelist_length(int s)
   int  free = 0;
   Dir *seg  = this->get_segment(s);
   Dir *e    = dir_from_offset(this->header->freelist[s], seg);
-  if (dir_bucket_loop_fix(e, s, this)) {
+  if (this->bucket_loop_fix(e, s)) {
     return (DIR_DEPTH - 1) * this->buckets;
   }
   while (e) {
@@ -260,7 +260,7 @@ Directory::bucket_length(Dir *b, int s)
   int  i   = 0;
   Dir *seg = this->get_segment(s);
 #ifdef LOOP_CHECK_MODE
-  if (dir_bucket_loop_fix(b, s, this))
+  if (this->bucket_loop_fix(b, s))
     return 1;
 #endif
   while (e) {
@@ -296,55 +296,6 @@ Directory::check()
   return 1;
 }
 
-inline void
-unlink_from_freelist(Dir *e, int s, Directory *directory)
-{
-  Dir *seg = directory->get_segment(s);
-  Dir *p   = dir_from_offset(dir_prev(e), seg);
-  if (p) {
-    dir_set_next(p, dir_next(e));
-  } else {
-    directory->header->freelist[s] = dir_next(e);
-  }
-  Dir *n = dir_from_offset(dir_next(e), seg);
-  if (n) {
-    dir_set_prev(n, dir_prev(e));
-  }
-}
-
-inline Dir *
-dir_delete_entry(Dir *e, Dir *p, int s, Directory *directory)
-{
-  Dir *seg                 = directory->get_segment(s);
-  int  no                  = dir_next(e);
-  directory->header->dirty = 1;
-  if (p) {
-    unsigned int fo = 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);
-    }
-    directory->header->freelist[s] = eo;
-  } else {
-    Dir *n = next_dir(e, seg);
-    if (n) {
-      // "Shuffle" here means that we're copying the second entry's data to 
the head entry's location, and removing the second entry
-      // - because the head entry can't be moved.
-      ATS_PROBE3(cache_dir_shuffle, s, dir_to_offset(e, seg), dir_to_offset(n, 
seg));
-      dir_assign(e, n);
-      dir_delete_entry(n, e, s, directory);
-      return e;
-    } else {
-      dir_clear(e);
-      return nullptr;
-    }
-  }
-  return dir_from_offset(no, seg);
-}
-
 inline void
 dir_clean_bucket(Dir *b, int s, StripeSM *stripe)
 {
@@ -357,7 +308,7 @@ dir_clean_bucket(Dir *b, int s, StripeSM *stripe)
 #ifdef LOOP_CHECK_MODE
     loop_count++;
     if (loop_count > DIR_LOOP_THRESHOLD) {
-      if (dir_bucket_loop_fix(b, s, vol->directory))
+      if (vol->directory.bucket_loop_fix(b, s))
         return;
     }
 #endif
@@ -372,7 +323,7 @@ dir_clean_bucket(Dir *b, int s, StripeSM *stripe)
       }
       // Match cache_dir_remove arguments
       ATS_PROBE7(cache_dir_remove_clean_bucket, stripe->fd, s, 
dir_to_offset(e, seg), dir_offset(e), dir_approx_size(e), 0, 0);
-      e = dir_delete_entry(e, p, s, &stripe->directory);
+      e = stripe->directory.delete_entry(e, p, s);
       continue;
     }
     p = e;
@@ -462,7 +413,7 @@ freelist_pop(int s, StripeSM *stripe)
   stripe->directory.header->freelist[s] = dir_next(e);
   // if the freelist if bad, punt.
   if (dir_offset(e)) {
-    dir_init_segment(s, &stripe->directory);
+    stripe->directory.init_segment(s);
     return nullptr;
   }
   Dir *h = dir_from_offset(stripe->directory.header->freelist[s], seg);
@@ -495,7 +446,7 @@ Directory::probe(const CacheKey *key, StripeSM *stripe, Dir 
*result, Dir **last_
   Dir *e = nullptr, *p = nullptr, *collision = *last_collision;
   CHECK_DIR(d);
 #ifdef LOOP_CHECK_MODE
-  if (dir_bucket_loop_fix(dir_bucket(b, seg), s, this))
+  if (this->bucket_loop_fix(dir_bucket(b, seg), s))
     return 0;
 #endif
 Lagain:
@@ -506,7 +457,7 @@ Lagain:
         ink_assert(dir_offset(e));
         // Bug: 51680. Need to check collision before checking
         // dir_valid(). In case of a collision, if !dir_valid(), we
-        // don't want to call dir_delete_entry.
+        // don't want to call Directory::delete_entry.
         if (collision) {
           if (collision == e) {
             collision = nullptr;
@@ -533,7 +484,7 @@ Lagain:
           
ts::Metrics::Gauge::decrement(stripe->cache_vol->vol_rsb.direntries_used);
           ATS_PROBE7(cache_dir_remove_invalid, stripe->fd, s, dir_to_offset(e, 
seg), dir_offset(e), dir_approx_size(e),
                      key->slice64(0), key->slice64(1));
-          e = dir_delete_entry(e, p, s, this);
+          e = this->delete_entry(e, p, s);
           continue;
         }
       } else {
@@ -585,7 +536,7 @@ Lagain:
   for (l = 1; l < DIR_DEPTH; l++) {
     e = dir_bucket_row(b, l);
     if (dir_is_empty(e)) {
-      unlink_from_freelist(e, s, this);
+      this->unlink_from_freelist(e, s);
       goto Llink;
     }
   }
@@ -653,7 +604,7 @@ Lagain:
 #ifdef LOOP_CHECK_MODE
       loop_count++;
       if (loop_count > DIR_LOOP_THRESHOLD && loop_possible) {
-        if (dir_bucket_loop_fix(b, s, this)) {
+        if (this->bucket_loop_fix(b, s)) {
           loop_possible = false;
           goto Lagain;
         }
@@ -679,7 +630,7 @@ Lagain:
   for (l = 1; l < DIR_DEPTH; l++) {
     e = dir_bucket_row(b, l);
     if (dir_is_empty(e)) {
-      unlink_from_freelist(e, s, this);
+      this->unlink_from_freelist(e, s);
       goto Llink;
     }
   }
@@ -733,7 +684,7 @@ Directory::remove(const CacheKey *key, StripeSM *stripe, 
Dir *del)
 #ifdef LOOP_CHECK_MODE
       loop_count++;
       if (loop_count > DIR_LOOP_THRESHOLD) {
-        if (dir_bucket_loop_fix(dir_bucket(b, seg), s, this))
+        if (this->bucket_loop_fix(dir_bucket(b, seg), s))
           return 0;
       }
 #endif
@@ -743,7 +694,7 @@ Directory::remove(const CacheKey *key, StripeSM *stripe, 
Dir *del)
         
ts::Metrics::Gauge::decrement(stripe->cache_vol->vol_rsb.direntries_used);
         ATS_PROBE7(cache_dir_remove, stripe->fd, s, dir_to_offset(e, seg), 
offset, dir_approx_size(e), key->slice64(0),
                    key->slice64(1));
-        dir_delete_entry(e, p, s, this);
+        this->delete_entry(e, p, s);
         CHECK_DIR(d);
         return 1;
       }
@@ -939,7 +890,7 @@ Directory::entries_used()
     sfull    = 0;
     for (int b = 0; b < this->buckets; b++) {
       Dir *e = dir_bucket(b, seg);
-      if (dir_bucket_loop_fix(e, s, this)) {
+      if (this->bucket_loop_fix(e, s)) {
         sfull = 0;
         break;
       }
@@ -1068,7 +1019,7 @@ Lrestart:
       /* Don't sync the directory to disk if its not dirty. Syncing the
          clean directory to disk is also the cause of INKqa07151. Increasing
          the serial number causes the cache to recover more data than 
necessary.
-         The dirty bit it set in dir_insert, overwrite and dir_delete_entry
+         The dirty bit is set in dir_insert, overwrite and 
Directory::delete_entry
        */
       if (!stripe->directory.header->dirty) {
         Dbg(dbg_ctl_cache_dir_sync, "Dir %s not dirty", 
stripe->hash_text.get());
diff --git a/src/iocore/cache/CacheVC.cc b/src/iocore/cache/CacheVC.cc
index 54a7abc739..821dce534a 100644
--- a/src/iocore/cache/CacheVC.cc
+++ b/src/iocore/cache/CacheVC.cc
@@ -111,9 +111,6 @@ next_in_map(Stripe *stripe, char *vol_map, off_t offset)
   return new_off + start_offset;
 }
 
-// Function in CacheDir.cc that we need for make_vol_map().
-int dir_bucket_loop_fix(Dir *start_dir, int s, Directory *directory);
-
 // 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.
@@ -137,7 +134,7 @@ make_vol_map(Stripe *stripe)
     Dir *seg = stripe->directory.get_segment(s);
     for (int b = 0; b < stripe->directory.buckets; b++) {
       Dir *e = dir_bucket(b, seg);
-      if (dir_bucket_loop_fix(e, s, &stripe->directory)) {
+      if (stripe->directory.bucket_loop_fix(e, s)) {
         break;
       }
       while (e) {
diff --git a/src/iocore/cache/P_CacheDir.h b/src/iocore/cache/P_CacheDir.h
index fbd2f0b25b..0a9150f483 100644
--- a/src/iocore/cache/P_CacheDir.h
+++ b/src/iocore/cache/P_CacheDir.h
@@ -30,6 +30,8 @@
 #include "tscore/Version.h"
 #include "tscore/hugepages.h"
 
+#include <ts/ats_probe.h>
+
 #include <cstdint>
 #include <ctime>
 
@@ -286,7 +288,9 @@ struct StripeHeaderFooter {
   uint16_t          freelist[1];
 };
 
-struct Directory {
+class Directory
+{
+public:
   char               *raw_dir{nullptr};
   Dir                *dir{};
   StripeHeaderFooter *header{};
@@ -316,19 +320,13 @@ struct Directory {
   int      bucket_length(Dir *b, int s);
   int      freelist_length(int s);
   void     clean_segment(int s, StripeSM *stripe);
-};
-
-inline int
-Directory::entries() const
-{
-  return this->buckets * DIR_DEPTH * this->segments;
-}
+  void     init_segment(int s);
+  int      bucket_loop_fix(Dir *start_dir, int s);
+  Dir     *delete_entry(Dir *e, Dir *p, int s);
 
-inline Dir *
-Directory::get_segment(int s) const
-{
-  return reinterpret_cast<Dir *>((reinterpret_cast<char *>(this->dir)) + (s * 
this->buckets) * DIR_DEPTH * SIZEOF_DIR);
-}
+private:
+  void unlink_from_freelist(Dir *e, int s);
+};
 
 // Global Functions
 
@@ -394,3 +392,64 @@ dir_bucket_row(Dir *b, int64_t i)
 {
   return dir_in_seg(b, i);
 }
+
+inline int
+Directory::entries() const
+{
+  return this->buckets * DIR_DEPTH * this->segments;
+}
+
+inline Dir *
+Directory::get_segment(int s) const
+{
+  return reinterpret_cast<Dir *>((reinterpret_cast<char *>(this->dir)) + (s * 
this->buckets) * DIR_DEPTH * SIZEOF_DIR);
+}
+
+inline void
+Directory::unlink_from_freelist(Dir *e, int s)
+{
+  Dir *seg = this->get_segment(s);
+  Dir *p   = dir_from_offset(dir_prev(e), seg);
+  if (p) {
+    dir_set_next(p, dir_next(e));
+  } else {
+    this->header->freelist[s] = dir_next(e);
+  }
+  Dir *n = dir_from_offset(dir_next(e), seg);
+  if (n) {
+    dir_set_prev(n, dir_prev(e));
+  }
+}
+
+inline Dir *
+Directory::delete_entry(Dir *e, Dir *p, int s)
+{
+  Dir *seg            = this->get_segment(s);
+  int  no             = dir_next(e);
+  this->header->dirty = 1;
+  if (p) {
+    unsigned int fo = this->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);
+    }
+    this->header->freelist[s] = eo;
+  } else {
+    Dir *n = next_dir(e, seg);
+    if (n) {
+      // "Shuffle" here means that we're copying the second entry's data to 
the head entry's location, and removing the second entry
+      // - because the head entry can't be moved.
+      ATS_PROBE3(cache_dir_shuffle, s, dir_to_offset(e, seg), dir_to_offset(n, 
seg));
+      dir_assign(e, n);
+      this->delete_entry(n, e, s);
+      return e;
+    } else {
+      dir_clear(e);
+      return nullptr;
+    }
+  }
+  return dir_from_offset(no, seg);
+}

Reply via email to