diff options
author | Sage Weil <sage@inktank.com> | 2013-09-09 18:18:26 -0700 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2013-09-11 23:02:55 -0700 |
commit | d1c68979e2246e2a2ef4d3043600b830317b3086 (patch) | |
tree | 517e40f0629725c5e683697f0a52eadc3231441b | |
parent | 759edd07b35abf42562c9925f40f81779c4cd444 (diff) | |
download | ceph-d1c68979e2246e2a2ef4d3043600b830317b3086.tar.gz |
buffer: lame attempt at caching crc values
This only works if the base value also matches, which it generally won't.
Signed-off-by: Sage Weil <sage@inktank.com>
-rw-r--r-- | src/common/buffer.cc | 51 |
1 files changed, 47 insertions, 4 deletions
diff --git a/src/common/buffer.cc b/src/common/buffer.cc index 13fa5805c3f..29d78f37e74 100644 --- a/src/common/buffer.cc +++ b/src/common/buffer.cc @@ -21,6 +21,7 @@ #include "include/atomic.h" #include "include/types.h" #include "include/compat.h" +#include "include/Spinlock.h" #include <errno.h> #include <fstream> @@ -60,9 +61,13 @@ bool buffer_track_alloc = get_env_bool("CEPH_BUFFER_TRACK"); unsigned len; atomic_t nref; - raw(unsigned l) : data(NULL), len(l), nref(0) + Spinlock crc_lock; + int64_t crc_in; ///< cached crc base; -1 if invalid + int64_t crc_out; ///< cached crc value; -1 if invalid + + raw(unsigned l) : data(NULL), len(l), nref(0), crc_in(-1), crc_out(-1) { } - raw(char *c, unsigned l) : data(c), len(l), nref(0) + raw(char *c, unsigned l) : data(c), len(l), nref(0), crc_in(-1), crc_out(-1) { } virtual ~raw() {}; @@ -77,12 +82,35 @@ bool buffer_track_alloc = get_env_bool("CEPH_BUFFER_TRACK"); return c; } + unsigned length() const { + return len; + } + bool is_page_aligned() { return ((long)data & ~CEPH_PAGE_MASK) == 0; } bool is_n_page_sized() { return (len & ~CEPH_PAGE_MASK) == 0; } + bool have_crc() const { + Spinlock::Locker l(crc_lock); + return crc_in >= 0; + } + uint32_t get_crc_base() const { + Spinlock::Locker l(crc_lock); + assert(crc_in >= 0); + return crc_in; + } + uint32_t get_crc_value() const { + Spinlock::Locker l(crc_lock); + assert(crc_out >= 0); + return crc_out; + } + void set_crc(uint32_t b, uint32_t v) { + Spinlock::Locker l(crc_lock); + crc_in = b; + crc_out = v; + } }; class buffer::raw_malloc : public buffer::raw { @@ -1272,8 +1300,23 @@ __u32 buffer::list::crc32c(__u32 crc) const for (std::list<ptr>::const_iterator it = _buffers.begin(); it != _buffers.end(); ++it) - if (it->length()) - crc = ceph_crc32c(crc, (unsigned char*)it->c_str(), it->length()); + if (it->length()) { + raw *r = it->get_raw(); + if (it->offset() == 0 && + it->length() == r->length()) { + if (r->have_crc() && + r->get_crc_base() == crc) { + crc = r->get_crc_value(); + } else { + uint32_t base = crc; + crc = ceph_crc32c(crc, (unsigned char*)it->c_str(), it->length()); + r->set_crc(base, crc); + } + } else { + // partial extent of raw buffer; continue + crc = ceph_crc32c(crc, (unsigned char*)it->c_str(), it->length()); + } + } return crc; } |