]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
new frag encoding uses _most_ significant bits.
authorSage Weil <sage@newdream.net>
Thu, 12 Jun 2008 21:23:16 +0000 (14:23 -0700)
committerSage Weil <sage@newdream.net>
Thu, 12 Jun 2008 21:23:16 +0000 (14:23 -0700)
src/include/ceph_fs.h
src/include/frag.h
src/mds/CDir.cc

index dbc3b0add43c222ddad3a65c83586bc79827520b..c70486d6d65f9fe3b01c72ad0dec3e71b9f16359 100644 (file)
@@ -71,10 +71,89 @@ struct ceph_timespec {
        __le32 tv_nsec;
 } __attribute__ ((packed));
 
+
+/*
+ * frag encoding:
+ *   8 upper bits = "bits"
+ *  24 lower bits = "value"
+ * (We could go to 5+27 bits, but who cares.)
+ *
+ * We use the _most_ significant bits of the 24 bit value.  This makes
+ * values logically sort.
+ *
+ * Unfortunately, because the bits are still in the high bits, we
+ * can't sort encoded frags numerically.  However, it does allow you
+ * to feed encoded frags as values into frag_contains_value.
+ */
+static inline __u32 frag_make(__u32 b, __u32 v) {
+       return (b << 24) | 
+               (v & (0xffffffu << (24-b)) & 0xffffffu);
+}
+static inline __u32 frag_bits(__u32 f) { return f >> 24; }
+static inline __u32 frag_value(__u32 f) { return f & 0xffffffu; }
+static inline __u32 frag_mask(__u32 f) {
+       return (0xffffffu << (24-frag_bits(f))) & 0xffffffu;
+}
+static inline __u32 frag_mask_shift(__u32 f) {
+       return 24 - frag_bits(f);
+}
+
+static inline bool frag_contains_value(__u32 f, __u32 v) {
+       return (v & frag_mask(f)) == frag_value(f);
+}
+static inline bool frag_contains_frag(__u32 f, __u32 sub) {
+       /* as specific as us, and contained by us */
+       return frag_bits(sub) >= frag_bits(f) &&
+               (frag_value(sub) & frag_mask(f)) == frag_value(f);
+}
+
+static inline __u32 frag_parent(__u32 f) {
+       return frag_make(frag_bits(f) - 1,
+                        frag_value(f) & (frag_mask(f) << 1));
+}
+static inline bool frag_is_left_child(__u32 f) {
+       return frag_bits(f) > 0 &&
+               (frag_value(f) & (0x1000000 >> frag_bits(f)) == 0);
+}
+static inline bool frag_is_right_child(__u32 f) {
+       return frag_bits(f) > 0 &&
+               (frag_value(f) & (0x1000000 >> frag_bits(f)) == 1);
+}
+static inline __u32 frag_sibling(__u32 f) {
+       return frag_make(frag_bits(f),
+                        frag_value(f) ^ (0x1000000 >> frag_bits(f)));
+}
+static inline __u32 frag_left_child(__u32 f) {
+       return frag_make(frag_bits(f)+1, frag_value(f));
+}
+static inline __u32 frag_right_child(__u32 f) {
+       return frag_make(frag_bits(f)+1,
+                        frag_value(f) | (0x1000000 >> (1+frag_bits(f))));
+}
+static inline __u32 frag_make_child(__u32 f, int by, int i) {
+       int newbits = frag_bits(f) + by;
+       return frag_make(newbits,
+                        frag_value(f) | (i << (24 - newbits)));
+}
+static inline bool frag_is_leftmost(__u32 f) {
+       return frag_value(f) == 0;
+}
+static inline bool frag_is_rightmost(__u32 f) {
+       return frag_value(f) == frag_mask(f);
+}
+static inline __u32 frag_next(__u32 f) {
+       return frag_make(frag_bits(f),
+                        frag_value(f) + (0x1000000 >> frag_bits(f)));
+}
+
+
+#if 0
 /*
  * dir fragments
  *  8 upper bits = "bits"
- * 23 lower bits = "value"
+ * 24 lower bits = "value"
+ *
+ * We use the _least_ significant bits.
  *
  * This isn't quite ideal in that it doesn't sort well, and because we
  * are masking out the least significant bits instead of hte most
@@ -136,10 +215,8 @@ static inline __u32 frag_next(__u32 f) {
        }
        return frag_make(0, 0);  /* rightmost */
 }
+#endif
 
-/*
- * note: this is not in a "nice" sorted order, by any means.
- */
 static inline int frag_compare(__u32 a, __u32 b) {
        unsigned va = frag_value(a);
        unsigned vb = frag_value(b);
@@ -156,7 +233,6 @@ static inline int frag_compare(__u32 a, __u32 b) {
        return 0;
 }
 
-
 /*
  * object layout - how objects are mapped into PGs
  */
index 410858cb58e32ab6d5aa7fcb56a8b8a159c07ab0..aeba3f885b611bd6492ab39d3c5290df24f494fc 100644 (file)
@@ -69,9 +69,9 @@
 typedef uint32_t _frag_t;
 
 class frag_t {
-  /* encoded value.
-   *  8 upper bits = "bits"
-   * 24 lower bits = "value"
+  /*
+   * encoding is dictated by frag_* functions in ceph_fs.h.  use those
+   * helpers _exclusively_.
    */
  public:
   _frag_t _enc;  
@@ -87,6 +87,7 @@ class frag_t {
   unsigned value() const { return frag_value(_enc); }
   unsigned bits() const { return frag_bits(_enc); }
   unsigned mask() const { return frag_mask(_enc); }
+  unsigned mask_shift() const { return frag_mask_shift(_enc); }
 
   operator _frag_t() const { return _enc; }
 
@@ -100,23 +101,27 @@ class frag_t {
   }
 
   // splitting
+  frag_t make_child(int i, int nb) const {
+    assert(i < (1<<nb));
+    return frag_t(frag_make_child(_enc, nb, i));
+  }
   void split(int nb, std::list<frag_t>& fragments) const {
     assert(nb > 0);
     unsigned nway = 1 << nb;
     for (unsigned i=0; i<nway; i++) 
-      fragments.push_back( frag_t(value() | (i << bits()), 
-                                 bits()+nb) );
+      fragments.push_back(make_child(i, nb));
   }
 
   // binary splitting
+  frag_t left_child() const { return frag_t(frag_left_child(_enc)); }
+  frag_t right_child() const { return frag_t(frag_right_child(_enc)); }
+
+  bool is_left() const { return frag_is_left_child(_enc); }
+  bool is_right() const { return frag_is_right_child(_enc); }
   frag_t get_sibling() const {
     assert(!is_root());
     return frag_t(frag_sibling(_enc));
   }
-  bool is_left() const { return frag_is_left_child(_enc); }
-  bool is_right() const { return frag_is_right_child(_enc); }
-  frag_t left_child() const { return frag_t(frag_left_child(_enc)); }
-  frag_t right_child() const { return frag_t(frag_right_child(_enc)); }
 
   // sequencing
   bool is_leftmost() const { return frag_is_leftmost(_enc); }
@@ -308,8 +313,7 @@ public:
       unsigned nway = 1 << nb;
       unsigned i;
       for (i=0; i<nway; i++) {
-       frag_t n(t.value() | (i << t.bits()), 
-                t.bits()+nb);
+       frag_t n = t.make_child(i, nb);
        if (n.contains(v)) {
          t = n;
          break;
index 9f13f293b96c5e42d056f9e85bbe74edc4e59f1d..7be36c4f43428aa085cbe4c6e9863e574349c408 100644 (file)
@@ -619,7 +619,7 @@ void CDir::split(int bits, list<CDir*>& subs, list<Context*>& waiters)
     
     CDentry *dn = p->second;
     frag_t subfrag = inode->pick_dirfrag(p->first);
-    int n = subfrag.value() >> frag.bits();
+    int n = (subfrag.value() & (subfrag.mask() ^ frag.mask())) >> subfrag.mask_shift();
     dout(15) << " subfrag " << subfrag << " n=" << n << " for " << p->first << dendl;
     CDir *f = subfrags[n];
     f->steal_dentry(dn);