]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
common/Checksummer: allow the initial/seed value to be supplied
authorJason Dillaman <dillaman@redhat.com>
Mon, 3 Apr 2017 21:10:29 +0000 (17:10 -0400)
committerJason Dillaman <dillaman@redhat.com>
Mon, 17 Apr 2017 23:10:47 +0000 (19:10 -0400)
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/common/Checksummer.h

index 396778b1c96485d291b6de5b4005e254237ae5e2..6611e8749f4d3a80b622cd8dafcc6492e265fe78 100644 (file)
@@ -44,6 +44,18 @@ public:
       return CSUM_CRC32C_8;
     return -EINVAL;
   }
+
+  static size_t get_csum_init_value_size(int csum_type) {
+    switch (csum_type) {
+    case CSUM_NONE: return 0;
+    case CSUM_XXHASH32: return sizeof(xxhash32::init_value_t);
+    case CSUM_XXHASH64: return sizeof(xxhash64::init_value_t);
+    case CSUM_CRC32C: return sizeof(crc32c::init_value_t);
+    case CSUM_CRC32C_16: return sizeof(crc32c_16::init_value_t);
+    case CSUM_CRC32C_8: return sizeof(crc32c_8::init_value_t);
+    default: return 0;
+    }
+  }
   static size_t get_csum_value_size(int csum_type) {
     switch (csum_type) {
     case CSUM_NONE: return 0;
@@ -57,6 +69,7 @@ public:
   }
 
   struct crc32c {
+    typedef uint32_t init_value_t;
     typedef __le32 value_t;
 
     // we have no execution context/state.
@@ -68,14 +81,16 @@ public:
 
     static value_t calc(
       state_t state,
+      init_value_t init_value,
       size_t len,
       bufferlist::const_iterator& p
       ) {
-      return p.crc32c(len, -1);
+      return p.crc32c(len, init_value);
     }
   };
 
   struct crc32c_16 {
+    typedef uint32_t init_value_t;
     typedef __le16 value_t;
 
     // we have no execution context/state.
@@ -87,14 +102,16 @@ public:
 
     static value_t calc(
       state_t state,
+      init_value_t init_value,
       size_t len,
       bufferlist::const_iterator& p
       ) {
-      return p.crc32c(len, -1) & 0xffff;
+      return p.crc32c(len, init_value) & 0xffff;
     }
   };
 
   struct crc32c_8 {
+    typedef uint32_t init_value_t;
     typedef __u8 value_t;
 
     // we have no execution context/state.
@@ -106,14 +123,16 @@ public:
 
     static value_t calc(
       state_t state,
+      init_value_t init_value,
       size_t len,
       bufferlist::const_iterator& p
       ) {
-      return p.crc32c(len, -1) & 0xff;
+      return p.crc32c(len, init_value) & 0xff;
     }
   };
 
   struct xxhash32 {
+    typedef uint32_t init_value_t;
     typedef __le32 value_t;
 
     typedef XXH32_state_t *state_t;
@@ -126,10 +145,11 @@ public:
 
     static value_t calc(
       state_t state,
+      init_value_t init_value,
       size_t len,
       bufferlist::const_iterator& p
       ) {
-      XXH32_reset(state, -1);
+      XXH32_reset(state, init_value);
       while (len > 0) {
        const char *data;
        size_t l = p.get_ptr_and_advance(len, &data);
@@ -141,6 +161,7 @@ public:
   };
 
   struct xxhash64 {
+    typedef uint64_t init_value_t;
     typedef __le64 value_t;
 
     typedef XXH64_state_t *state_t;
@@ -153,10 +174,11 @@ public:
 
     static value_t calc(
       state_t state,
+      init_value_t init_value,
       size_t len,
       bufferlist::const_iterator& p
       ) {
-      XXH64_reset(state, -1);
+      XXH64_reset(state, init_value);
       while (len > 0) {
        const char *data;
        size_t l = p.get_ptr_and_advance(len, &data);
@@ -175,6 +197,17 @@ public:
     const bufferlist &bl,
     bufferptr* csum_data
     ) {
+    return calculate<Alg>(-1, csum_block_size, offset, length, bl, csum_data);
+  }
+
+  template<class Alg>
+  static int calculate(
+      typename Alg::init_value_t init_value,
+      size_t csum_block_size,
+      size_t offset,
+      size_t length,
+      const bufferlist &bl,
+      bufferptr* csum_data) {
     assert(length % csum_block_size == 0);
     size_t blocks = length / csum_block_size;
     bufferlist::const_iterator p = bl.begin();
@@ -190,7 +223,7 @@ public:
       reinterpret_cast<typename Alg::value_t*>(csum_data->c_str());
     pv += offset / csum_block_size;
     while (blocks--) {
-      *pv = Alg::calc(state, csum_block_size, p);
+      *pv = Alg::calc(state, init_value, csum_block_size, p);
       ++pv;
     }
     Alg::fini(&state);
@@ -218,7 +251,7 @@ public:
     pv += offset / csum_block_size;
     size_t pos = offset;
     while (length > 0) {
-      typename Alg::value_t v = Alg::calc(state, csum_block_size, p);
+      typename Alg::value_t v = Alg::calc(state, -1, csum_block_size, p);
       if (*pv != v) {
        if (bad_csum) {
          *bad_csum = v;