From: Sage Weil Date: Thu, 12 Jun 2008 21:23:16 +0000 (-0700) Subject: new frag encoding uses _most_ significant bits. X-Git-Tag: v0.3~129 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=416cac16b65d0b7f014e5dd46750064e832d06cd;p=ceph.git new frag encoding uses _most_ significant bits. --- diff --git a/src/include/ceph_fs.h b/src/include/ceph_fs.h index dbc3b0add43c2..c70486d6d65f9 100644 --- a/src/include/ceph_fs.h +++ b/src/include/ceph_fs.h @@ -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 */ diff --git a/src/include/frag.h b/src/include/frag.h index 410858cb58e32..aeba3f885b611 100644 --- a/src/include/frag.h +++ b/src/include/frag.h @@ -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<& fragments) const { assert(nb > 0); unsigned nway = 1 << nb; for (unsigned i=0; i& subs, list& 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);