summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSage Weil <sage@inktank.com>2013-09-09 18:18:26 -0700
committerSage Weil <sage@inktank.com>2013-09-11 23:02:55 -0700
commitd1c68979e2246e2a2ef4d3043600b830317b3086 (patch)
tree517e40f0629725c5e683697f0a52eadc3231441b
parent759edd07b35abf42562c9925f40f81779c4cd444 (diff)
downloadceph-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.cc51
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;
}