]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
fix frag_next, using lame old frag encoding strategy
authorSage Weil <sage@newdream.net>
Thu, 12 Jun 2008 19:59:57 +0000 (12:59 -0700)
committerSage Weil <sage@newdream.net>
Thu, 12 Jun 2008 19:59:57 +0000 (12:59 -0700)
src/include/ceph_fs.h
src/include/frag.h

index 04b4eda42f495829f112cc6c84180868a3d2a1f2..dbc3b0add43c222ddad3a65c83586bc79827520b 100644 (file)
@@ -73,18 +73,73 @@ struct ceph_timespec {
 
 /*
  * dir fragments
+ *  8 upper bits = "bits"
+ * 23 lower bits = "value"
+ *
+ * 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
+ * significant bits.  But, mapping onto low bits has some advantage
+ * for weak hashes.  Bah.  FIXME.
  */
 static inline __u32 frag_make(__u32 b, __u32 v) { return (b << 24) | (v & (0xffffffu >> (24-b))); }
 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)); }
-static inline __u32 frag_next(__u32 f) { return frag_make(frag_bits(f), frag_value(f)+1); }
+
+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) & (1 << (frag_bits(f)-1)) == 0);
+}
+static inline bool frag_is_right_child(__u32 f) {
+       return frag_bits(f) > 0 &&
+               (frag_value(f) & (1 << (frag_bits(f)-1)) == 1);
+}
+static inline __u32 frag_sibling(__u32 f) {
+       return frag_make(frag_bits(f),
+                        frag_value(f) ^ (1 << (frag_bits(f)-1)));
+}
+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) | (1<<frag_bits(f)));
+}
+
 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) {
+       unsigned b = frag_bits(f) - 1;
+       unsigned v = frag_value(f);
+       while (b >= 0) {
+               if (v & (1<<b) == 0)
+                       return frag_make(b+1, v | (1<<b));
+               v &= ~(1<<b);
+               b--;
+       }
+       return frag_make(0, 0);  /* rightmost */
+}
+
+/*
+ * 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);
@@ -100,10 +155,6 @@ static inline int frag_compare(__u32 a, __u32 b) {
                return 1;
        return 0;
 }
-static inline bool frag_contains_value(__u32 f, __u32 v)
-{
-       return (v & frag_mask(f)) == frag_value(f);
-}
 
 
 /*
index 50e441373df241766d703270b52d6f58c5da4835..410858cb58e32ab6d5aa7fcb56a8b8a159c07ab0 100644 (file)
@@ -91,19 +91,12 @@ class frag_t {
   operator _frag_t() const { return _enc; }
 
   // tests
-  bool contains(unsigned v) const {
-    return (v & mask()) == value();
-  }
-  bool contains(frag_t sub) const {
-    return (sub.bits() >= bits() &&             // they at least as specific as us,
-           (sub.value() & mask()) == value()); // and they are contained by us.
-  }
-  bool is_root() const { 
-    return bits() == 0; 
-  }
+  bool contains(unsigned v) const { return frag_contains_value(_enc, v); }
+  bool contains(frag_t sub) const { return frag_contains_frag(_enc, sub._enc); }
+  bool is_root() const { return bits() == 0; }
   frag_t parent() const {
     assert(bits() > 0);
-    return frag_t(value() & (mask() >> 1), bits()-1);
+    return frag_t(frag_parent(_enc));
   }
 
   // splitting
@@ -118,32 +111,16 @@ class frag_t {
   // binary splitting
   frag_t get_sibling() const {
     assert(!is_root());
-    return frag_t(value() ^ (1 << (bits()-1)), bits());
-  }
-  bool is_left() const {
-    return 
-      bits() > 0 &&
-      (value() & (1 << (bits()-1)) == 0);
-  }
-  bool is_right() const {
-    return 
-      bits() > 0 &&
-      (value() & (1 << (bits()-1)) == 1);
-  }
-  frag_t left_child() const {
-    return frag_t(value(), bits()+1);
-  }
-  frag_t right_child() const {
-    return frag_t(value() | (1<<bits()), bits()+1);
+    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);
-  }
-  bool is_rightmost() const {
-    return frag_is_rightmost(_enc);
-  }
+  bool is_leftmost() const { return frag_is_leftmost(_enc); }
+  bool is_rightmost() const { return frag_is_rightmost(_enc); }
   frag_t next() const {
     assert(!is_rightmost());
     return frag_t(frag_next(_enc));