changeset 400:d12b13664ad6

table_*: Mask/unmask per-table-block CRC checksums.
author Lewin Bormann <lbo@spheniscida.de>
date Tue, 10 Oct 2017 21:16:17 +0200
parents 5679d04a98c9
children 4df7f572afdb
files src/log.rs src/table_builder.rs src/table_reader.rs
diffstat 3 files changed, 13 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/log.rs	Tue Oct 10 21:15:44 2017 +0200
+++ b/src/log.rs	Tue Oct 10 21:16:17 2017 +0200
@@ -202,11 +202,11 @@
 
 const MASK_DELTA: u32 = 0xa282ead8;
 
-fn mask_crc(c: u32) -> u32 {
+pub fn mask_crc(c: u32) -> u32 {
     (c.wrapping_shr(15) | c.wrapping_shl(17)).wrapping_add(MASK_DELTA)
 }
 
-fn unmask_crc(mc: u32) -> u32 {
+pub fn unmask_crc(mc: u32) -> u32 {
     let rot = mc.wrapping_sub(MASK_DELTA);
     (rot.wrapping_shr(17) | rot.wrapping_shl(15))
 }
@@ -224,6 +224,12 @@
     }
 
     #[test]
+    fn test_crc_sanity() {
+        assert_eq!(0x8a9136aa, crc32::checksum_castagnoli(&[0 as u8; 32]));
+        assert_eq!(0x62a8ab43, crc32::checksum_castagnoli(&[0xff as u8; 32]));
+    }
+
+    #[test]
     fn test_writer() {
         let data = &["hello world. My first log entry.", "and my second", "and my third"];
         let mut lw = LogWriter::new(Vec::new());
--- a/src/table_builder.rs	Tue Oct 10 21:15:44 2017 +0200
+++ b/src/table_builder.rs	Tue Oct 10 21:16:17 2017 +0200
@@ -6,6 +6,7 @@
 use filter::{InternalFilterPolicy, NoFilterPolicy};
 use filter_block::FilterBlockBuilder;
 use key_types::InternalKey;
+use log::mask_crc;
 use options::{CompressionType, Options};
 
 use std::cmp::Ordering;
@@ -204,7 +205,7 @@
 
         digest.write(&block);
         digest.write(&[self.opt.compression_type as u8; TABLE_BLOCK_COMPRESS_LEN]);
-        digest.sum32().encode_fixed(&mut buf);
+        mask_crc(digest.sum32()).encode_fixed(&mut buf);
 
         self.dst.write(&block)?;
         self.dst.write(&[t as u8; TABLE_BLOCK_COMPRESS_LEN])?;
--- a/src/table_reader.rs	Tue Oct 10 21:15:44 2017 +0200
+++ b/src/table_reader.rs	Tue Oct 10 21:16:17 2017 +0200
@@ -7,6 +7,7 @@
 use filter;
 use filter_block::FilterBlockReader;
 use key_types::InternalKey;
+use log::unmask_crc;
 use options::{self, CompressionType, Options};
 use table_builder::{self, Footer};
 use types::{current_key_val, LdbIterator};
@@ -50,9 +51,10 @@
                                     &BlockHandle::new(location.offset() + location.size() +
                                                       table_builder::TABLE_BLOCK_COMPRESS_LEN,
                                                       table_builder::TABLE_BLOCK_CKSUM_LEN)));
+
         Ok(TableBlock {
             block: Block::new(opt, buf),
-            checksum: u32::decode_fixed(&cksum),
+            checksum: unmask_crc(u32::decode_fixed(&cksum)),
             compression: options::int_to_compressiontype(compress[0] as u32)
                 .unwrap_or(CompressionType::CompressionNone),
         })
@@ -63,7 +65,6 @@
         let mut digest = crc32::Digest::new(crc32::CASTAGNOLI);
         digest.write(&self.block.contents());
         digest.write(&[self.compression as u8; 1]);
-
         digest.sum32() == self.checksum
     }
 }