Browse Source

[2850] Unify checksum and header processing code

Mukund Sivaraman 12 years ago
parent
commit
6548cfede8

+ 64 - 61
src/lib/datasrc/memory/zone_table_segment_mapped.cc

@@ -42,36 +42,74 @@ ZoneTableSegmentMapped::ZoneTableSegmentMapped(const RRClass& rrclass) :
 }
 
 void
-ZoneTableSegmentMapped::openCreate(const std::string& filename) {
-    // In case there is a checksum mismatch, we throw. We want the
-    // segment to be automatically destroyed then.
-    std::auto_ptr<MemorySegmentMapped> segment
-        (new MemorySegmentMapped(filename, MemorySegmentMapped::CREATE_ONLY));
-    // There must be no previously saved checksum.
+ZoneTableSegmentMapped::processChecksum(MemorySegmentMapped& segment,
+                                        bool createMode)
+{
     MemorySegment::NamedAddressResult result =
-        segment->getNamedAddress(ZONE_TABLE_CHECKSUM_NAME);
+        segment.getNamedAddress(ZONE_TABLE_CHECKSUM_NAME);
     if (result.first) {
-        isc_throw(isc::Unexpected,
-                  "There is already a saved checksum in a mapped segment "
-                  "opened in create mode.");
+        if (createMode) {
+            // There must be no previously saved checksum.
+            isc_throw(isc::Unexpected,
+                      "There is already a saved checksum in a mapped segment "
+                      "opened in create mode.");
+        } else {
+            // The segment was already shrunk when it was last
+            // closed. Check that its checksum is consistent.
+            assert(result.second);
+            uint32_t* checksum = static_cast<uint32_t*>(result.second);
+            const uint32_t saved_checksum = *checksum;
+            // First, clear the checksum so that getCheckSum() returns a
+            // consistent value.
+            *checksum = 0;
+            const uint32_t new_checksum = segment.getCheckSum();
+            if (saved_checksum != new_checksum) {
+                isc_throw(isc::Unexpected,
+                          "Saved checksum doesn't match mapped segment data");
+            }
+        }
+    } else {
+        // Allocate space for a checksum (which is saved during close).
+        void* checksum = segment.allocate(sizeof(uint32_t));
+        *static_cast<uint32_t*>(checksum) = 0;
+        segment.setNamedAddress(ZONE_TABLE_CHECKSUM_NAME, checksum);
     }
-    // Allocate space for a checksum (which is saved during close).
-    void* checksum = segment->allocate(sizeof(uint32_t));
-    *static_cast<uint32_t*>(checksum) = 0;
-    segment->setNamedAddress(ZONE_TABLE_CHECKSUM_NAME, checksum);
+}
 
-    // There must be no previously saved ZoneTableHeader.
-    result = segment->getNamedAddress(ZONE_TABLE_HEADER_NAME);
+void
+ZoneTableSegmentMapped::processHeader(MemorySegmentMapped& segment,
+                                      bool createMode)
+{
+    MemorySegment::NamedAddressResult result =
+        segment.getNamedAddress(ZONE_TABLE_HEADER_NAME);
     if (result.first) {
-        isc_throw(isc::Unexpected,
-                  "There is already a saved ZoneTableHeader in a "
-                  "mapped segment opened in create mode.");
+        if (createMode) {
+            // There must be no previously saved checksum.
+            isc_throw(isc::Unexpected,
+                      "There is already a saved ZoneTableHeader in a "
+                      "mapped segment opened in create mode.");
+        } else {
+            assert(result.second);
+            header_ = static_cast<ZoneTableHeader*>(result.second);
+        }
+    } else {
+        void* ptr = segment.allocate(sizeof(ZoneTableHeader));
+        ZoneTableHeader* new_header = new(ptr)
+            ZoneTableHeader(ZoneTable::create(segment, rrclass_));
+        segment.setNamedAddress(ZONE_TABLE_HEADER_NAME, new_header);
+        header_ = new_header;
     }
-    void* ptr = segment->allocate(sizeof(ZoneTableHeader));
-    ZoneTableHeader* new_header = new(ptr)
-        ZoneTableHeader(ZoneTable::create(*segment, rrclass_));
-    segment->setNamedAddress(ZONE_TABLE_HEADER_NAME, new_header);
-    header_ = new_header;
+}
+
+void
+ZoneTableSegmentMapped::openCreate(const std::string& filename) {
+    // In case there is a checksum mismatch, we throw. We want the
+    // segment to be automatically destroyed then.
+    std::auto_ptr<MemorySegmentMapped> segment
+        (new MemorySegmentMapped(filename, MemorySegmentMapped::CREATE_ONLY));
+
+    processChecksum(*segment, true);
+    processHeader(*segment, true);
 
     mem_sgmt_.reset(segment.release());
 }
@@ -83,44 +121,9 @@ ZoneTableSegmentMapped::openReadWrite(const std::string& filename) {
     std::auto_ptr<MemorySegmentMapped> segment
         (new MemorySegmentMapped(filename,
                                  MemorySegmentMapped::OPEN_OR_CREATE));
-    // If there is a previously saved checksum, verify that it is
-    // consistent. Otherwise, allocate space for a checksum (which is
-    // saved during close).
-    MemorySegment::NamedAddressResult result =
-        segment->getNamedAddress(ZONE_TABLE_CHECKSUM_NAME);
-    if (result.first) {
-        // The segment was already shrunk when it was last closed. Check
-        // that its checksum is consistent.
-        assert(result.second);
-        uint32_t* checksum = static_cast<uint32_t*>(result.second);
-        const uint32_t saved_checksum = *checksum;
-        // First, clear the checksum so that getCheckSum() returns a
-        // consistent value.
-        *checksum = 0;
-        const uint32_t new_checksum = segment->getCheckSum();
-        if (saved_checksum != new_checksum) {
-            isc_throw(isc::Unexpected,
-                      "Saved checksum doesn't match mapped segment data");
-        }
-    } else {
-        void* checksum = segment->allocate(sizeof(uint32_t));
-        *static_cast<uint32_t*>(checksum) = 0;
-        segment->setNamedAddress(ZONE_TABLE_CHECKSUM_NAME, checksum);
-    }
 
-    // If there is a previously saved ZoneTableHeader, use
-    // it. Otherwise, allocate a new header.
-    result = segment->getNamedAddress(ZONE_TABLE_HEADER_NAME);
-    if (result.first) {
-        assert(result.second);
-        header_ = static_cast<ZoneTableHeader*>(result.second);
-    } else {
-        void* ptr = segment->allocate(sizeof(ZoneTableHeader));
-        ZoneTableHeader* new_header = new(ptr)
-            ZoneTableHeader(ZoneTable::create(*segment, rrclass_));
-        segment->setNamedAddress(ZONE_TABLE_HEADER_NAME, new_header);
-        header_ = new_header;
-    }
+    processChecksum(*segment, false);
+    processHeader(*segment, false);
 
     mem_sgmt_.reset(segment.release());
 }

+ 3 - 0
src/lib/datasrc/memory/zone_table_segment_mapped.h

@@ -98,6 +98,9 @@ public:
                        isc::data::ConstElementPtr params);
 
 private:
+    void processChecksum(isc::util::MemorySegmentMapped& segment, bool create);
+    void processHeader(isc::util::MemorySegmentMapped& segment, bool create);
+
     void openCreate(const std::string& filename);
     void openReadWrite(const std::string& filename);
     void openReadOnly(const std::string& filename);