Browse Source

[2831] added getCheckSum method

JINMEI Tatuya 12 years ago
parent
commit
27ae48b404

+ 16 - 0
src/lib/util/memory_segment_mapped.cc

@@ -18,6 +18,7 @@
 #include <boost/interprocess/exceptions.hpp>
 #include <boost/interprocess/managed_mapped_file.hpp>
 #include <boost/interprocess/offset_ptr.hpp>
+#include <boost/interprocess/mapped_region.hpp>
 
 #include <cassert>
 #include <string>
@@ -237,5 +238,20 @@ MemorySegmentMapped::getSize() const {
     return (impl_->base_sgmt_->get_size());
 }
 
+size_t
+MemorySegmentMapped::getCheckSum() const {
+    const size_t page_sz = boost::interprocess::mapped_region::get_page_size();
+    const uint8_t* const cp_beg = static_cast<const uint8_t*>(
+        impl_->base_sgmt_->get_address());
+    const uint8_t* const cp_end = cp_beg + impl_->base_sgmt_->get_size();
+
+    size_t sum = 0;
+    for (const uint8_t* cp = cp_beg; cp < cp_end; cp += page_sz) {
+        sum += *cp;
+    }
+
+    return (sum);
+}
+
 } // namespace util
 } // namespace isc

+ 12 - 0
src/lib/util/memory_segment_mapped.h

@@ -121,6 +121,18 @@ public:
     /// \throw None
     size_t getSize() const;
 
+    /// \brief Calculate a checksum over the memory segment.
+    ///
+    /// This method goes over all pages of the underlying mapped memory
+    /// segment, and returns the sum of the value of the first byte of each
+    /// page (ignoring any possible overflow).  It only proves weak integrity
+    /// of the file contents, but can run fast enough and will ensure all
+    /// pages are actually on memory.  The latter property will be useful
+    /// if the application cannot allow the initial page fault overhead.
+    ///
+    /// \throw None
+    size_t getCheckSum() const;
+
 private:
     struct Impl;
     Impl* impl_;

+ 17 - 0
src/lib/util/tests/memory_segment_mapped_unittest.cc

@@ -20,6 +20,7 @@
 #include <gtest/gtest.h>
 
 #include <boost/interprocess/file_mapping.hpp>
+#include <boost/interprocess/mapped_region.hpp>
 #include <boost/scoped_ptr.hpp>
 
 #include <stdint.h>
@@ -266,4 +267,20 @@ TEST_F(MemorySegmentMappedTest, violateReadOnly) {
                  isc::InvalidOperation);
 }
 
+TEST_F(MemorySegmentMappedTest, getCheckSum) {
+    const size_t old_cksum = segment_->getCheckSum();
+
+    // We assume the initial segment size is sufficiently larger than the
+    // page size.  We'll allocate memory of the page size, and increment all
+    // bytes in that region by one.  It will increase our simple checksum value
+    // by one, too.
+    const size_t page_sz = boost::interprocess::mapped_region::get_page_size();
+    uint8_t* cp0 = static_cast<uint8_t*>(segment_->allocate(page_sz));
+    for (uint8_t* cp = cp0; cp < cp0 + page_sz; ++cp) {
+        ++*cp;
+    }
+
+    EXPECT_EQ(old_cksum + 1, segment_->getCheckSum());
+}
+
 }