Parcourir la source

[2268] Move Loader to live under ZoneDataUpdater

Mukund Sivaraman il y a 12 ans
Parent
commit
ae53c8fd69

+ 4 - 108
src/lib/datasrc/memory/memory_client.cc

@@ -36,11 +36,8 @@
 #include <dns/masterload.h>
 
 #include <boost/bind.hpp>
-#include <boost/foreach.hpp>
-#include <boost/noncopyable.hpp>
 
 #include <algorithm>
-#include <map>
 #include <utility>
 #include <cctype>
 #include <cassert>
@@ -65,109 +62,6 @@ public:
     }
 };
 
-// A helper internal class for load().  make it non-copyable to avoid
-// accidental copy.
-//
-// The current internal implementation expects that both a normal
-// (non RRSIG) RRset and (when signed) its RRSIG are added at once.
-// Also in the current implementation, the input sequence of RRsets
-// are grouped with their owner name (so once a new owner name is encountered,
-// no subsequent RRset has the previous owner name), but the ordering
-// in the same group is not fixed.  So we hold all RRsets of the same
-// owner name in node_rrsets_ and node_rrsigsets_, and add the matching
-// pairs of RRsets to the zone when we see a new owner name.
-//
-// The caller is responsible for adding the RRsets of the last group
-// in the input sequence by explicitly calling flushNodeRRsets() at the
-// end.  It's cleaner and more robust if we let the destructor of this class
-// do it, but since we cannot guarantee the adding operation is exception free,
-// we don't choose that option to maintain the common expectation for
-// destructors.
-class InMemoryClient::Loader : boost::noncopyable {
-    typedef std::map<RRType, ConstRRsetPtr> NodeRRsets;
-    typedef NodeRRsets::value_type NodeRRsetsVal;
-public:
-    Loader(util::MemorySegment& mem_sgmt, const RRClass rrclass,
-           const Name& zone_name, ZoneData& zone_data) :
-        updater_(mem_sgmt, rrclass, zone_name, zone_data)
-    {}
-    void addFromLoad(const ConstRRsetPtr& rrset) {
-        // If we see a new name, flush the temporary holders, adding the
-        // pairs of RRsets and RRSIGs of the previous name to the zone.
-        if ((!node_rrsets_.empty() || !node_rrsigsets_.empty()) &&
-            getCurrentName() != rrset->getName()) {
-            flushNodeRRsets();
-        }
-
-        // Store this RRset until it can be added to the zone.  The current
-        // implementation requires RRs of the same RRset should be added at
-        // once, so we check the "duplicate" here.
-        const bool is_rrsig = rrset->getType() == RRType::RRSIG();
-        NodeRRsets& node_rrsets = is_rrsig ? node_rrsigsets_ : node_rrsets_;
-        const RRType& rrtype = is_rrsig ?
-            getCoveredType(rrset) : rrset->getType();
-        if (!node_rrsets.insert(NodeRRsetsVal(rrtype, rrset)).second) {
-            isc_throw(ZoneDataUpdater::AddError,
-                      "Duplicate add of the same type of"
-                      << (is_rrsig ? " RRSIG" : "") << " RRset: "
-                      << rrset->getName() << "/" << rrtype);
-        }
-    }
-    void flushNodeRRsets() {
-        BOOST_FOREACH(NodeRRsetsVal val, node_rrsets_) {
-            // Identify the corresponding RRSIG for the RRset, if any.
-            // If found add both the RRset and its RRSIG at once.
-            ConstRRsetPtr sig_rrset;
-            NodeRRsets::iterator sig_it =
-                node_rrsigsets_.find(val.first);
-            if (sig_it != node_rrsigsets_.end()) {
-                sig_rrset = sig_it->second;
-                node_rrsigsets_.erase(sig_it);
-            }
-            updater_.add(val.second, sig_rrset);
-        }
-
-        // Right now, we don't accept RRSIG without covered RRsets (this
-        // should eventually allowed, but to do so we'll need to update the
-        // finder).
-        if (!node_rrsigsets_.empty()) {
-            isc_throw(ZoneDataUpdater::AddError,
-                      "RRSIG is added without covered RRset for "
-                      << getCurrentName());
-        }
-
-        node_rrsets_.clear();
-        node_rrsigsets_.clear();
-    }
-private:
-    // A helper to identify the covered type of an RRSIG.
-    static RRType getCoveredType(const ConstRRsetPtr& sig_rrset) {
-        RdataIteratorPtr it = sig_rrset->getRdataIterator();
-        // Empty RRSIG shouldn't be passed either via a master file or another
-        // data source iterator, but it could still happen if the iterator
-        // has a bug.  We catch and reject such cases.
-        if (it->isLast()) {
-            isc_throw(isc::Unexpected,
-                      "Empty RRset is passed in-memory loader, name: "
-                      << sig_rrset->getName());
-        }
-        return (dynamic_cast<const generic::RRSIG&>(it->getCurrent()).
-                typeCovered());
-    }
-    const Name& getCurrentName() const {
-        if (!node_rrsets_.empty()) {
-            return (node_rrsets_.begin()->second->getName());
-        }
-        assert(!node_rrsigsets_.empty());
-        return (node_rrsigsets_.begin()->second->getName());
-    }
-
-private:
-    NodeRRsets node_rrsets_;
-    NodeRRsets node_rrsigsets_;
-    ZoneDataUpdater updater_;
-};
-
 result::Result
 InMemoryClient::load(const Name& zone_name,
                      const string& filename,
@@ -176,8 +70,10 @@ InMemoryClient::load(const Name& zone_name,
     SegmentObjectHolder<ZoneData, RRClass> holder(
         mem_sgmt_, ZoneData::create(mem_sgmt_, zone_name), rrclass_);
 
-    Loader loader(mem_sgmt_, rrclass_, zone_name, *holder.get());
-    rrset_installer(boost::bind(&Loader::addFromLoad, &loader, _1));
+    ZoneDataUpdater::Loader loader(mem_sgmt_, rrclass_,
+                                   zone_name, *holder.get());
+    rrset_installer(boost::bind(&ZoneDataUpdater::Loader::addFromLoad,
+                                &loader, _1));
     // Add any last RRsets that were left
     loader.flushNodeRRsets();
 

+ 0 - 4
src/lib/datasrc/memory/memory_client.h

@@ -235,10 +235,6 @@ private:
     // A helper internal class used by the memory client, used for
     // deleting filenames stored in an internal tree.
     class FileNameDeleter;
-
-    // A helper internal class used by load().  It maintains some intermediate
-    // states while loading RRs of the zone.
-    class Loader;
 };
 
 } // namespace memory

+ 76 - 0
src/lib/datasrc/memory/zone_data_updater.cc

@@ -18,6 +18,7 @@
 #include <dns/rdataclass.h>
 
 #include <boost/scoped_ptr.hpp>
+#include <boost/foreach.hpp>
 
 using namespace isc::dns;
 using namespace isc::dns::rdata;
@@ -385,6 +386,81 @@ ZoneDataUpdater::add(const ConstRRsetPtr& rrset,
     addRdataSet(rrset, sig_rrset);
 }
 
+
+void
+ZoneDataUpdater::Loader::addFromLoad(const ConstRRsetPtr& rrset) {
+    // If we see a new name, flush the temporary holders, adding the
+    // pairs of RRsets and RRSIGs of the previous name to the zone.
+    if ((!node_rrsets_.empty() || !node_rrsigsets_.empty()) &&
+        (getCurrentName() != rrset->getName())) {
+        flushNodeRRsets();
+    }
+
+    // Store this RRset until it can be added to the zone.  The current
+    // implementation requires RRs of the same RRset should be added at
+    // once, so we check the "duplicate" here.
+    const bool is_rrsig = rrset->getType() == RRType::RRSIG();
+    NodeRRsets& node_rrsets = is_rrsig ? node_rrsigsets_ : node_rrsets_;
+    const RRType& rrtype = is_rrsig ? getCoveredType(rrset) : rrset->getType();
+    if (!node_rrsets.insert(NodeRRsetsVal(rrtype, rrset)).second) {
+        isc_throw(ZoneDataUpdater::AddError,
+                  "Duplicate add of the same type of"
+                  << (is_rrsig ? " RRSIG" : "") << " RRset: "
+                  << rrset->getName() << "/" << rrtype);
+    }
+}
+
+void
+ZoneDataUpdater::Loader::flushNodeRRsets() {
+    BOOST_FOREACH(NodeRRsetsVal val, node_rrsets_) {
+        // Identify the corresponding RRSIG for the RRset, if any.  If
+        // found add both the RRset and its RRSIG at once.
+        ConstRRsetPtr sig_rrset;
+        NodeRRsets::iterator sig_it = node_rrsigsets_.find(val.first);
+        if (sig_it != node_rrsigsets_.end()) {
+            sig_rrset = sig_it->second;
+            node_rrsigsets_.erase(sig_it);
+        }
+        updater_.add(val.second, sig_rrset);
+    }
+
+    // Right now, we don't accept RRSIG without covered RRsets (this
+    // should eventually allowed, but to do so we'll need to update the
+    // finder).
+    if (!node_rrsigsets_.empty()) {
+        isc_throw(ZoneDataUpdater::AddError,
+                  "RRSIG is added without covered RRset for "
+                  << getCurrentName());
+    }
+
+    node_rrsets_.clear();
+    node_rrsigsets_.clear();
+}
+
+RRType
+ZoneDataUpdater::Loader::getCoveredType(const ConstRRsetPtr& sig_rrset) {
+    RdataIteratorPtr it = sig_rrset->getRdataIterator();
+    // Empty RRSIG shouldn't be passed either via a master file or
+    // another data source iterator, but it could still happen if the
+    // iterator has a bug.  We catch and reject such cases.
+    if (it->isLast()) {
+        isc_throw(isc::Unexpected,
+                  "Empty RRset is passed in-memory loader, name: "
+                  << sig_rrset->getName());
+    }
+    return (dynamic_cast<const generic::RRSIG&>(it->getCurrent()).
+            typeCovered());
+}
+
+const Name&
+ZoneDataUpdater::Loader::getCurrentName() const {
+    if (!node_rrsets_.empty()) {
+        return (node_rrsets_.begin()->second->getName());
+    }
+    assert(!node_rrsigsets_.empty());
+    return (node_rrsigsets_.begin()->second->getName());
+}
+
 } // namespace memory
 } // namespace datasrc
 } // namespace isc

+ 48 - 0
src/lib/datasrc/memory/zone_data_updater.h

@@ -24,6 +24,7 @@
 #include <util/memory_segment.h>
 
 #include <boost/noncopyable.hpp>
+#include <map>
 
 namespace isc {
 namespace datasrc {
@@ -84,6 +85,10 @@ public:
     void add(const isc::dns::ConstRRsetPtr& rrset,
              const isc::dns::ConstRRsetPtr& sig_rrset);
 
+    // A helper internal class used by InMemoryClient::load(). It
+    // maintains some intermediate states while loading RRs of the zone.
+    class Loader;
+
 private:
     // Add the necessary magic for any wildcard contained in 'name'
     // (including itself) to be found in the zone.
@@ -128,6 +133,49 @@ private:
     isc::dns::NSEC3Hash* hash_;
 };
 
+// A helper internal class for load().  make it non-copyable to avoid
+// accidental copy.
+//
+// The current internal implementation expects that both a normal
+// (non RRSIG) RRset and (when signed) its RRSIG are added at once.
+// Also in the current implementation, the input sequence of RRsets
+// are grouped with their owner name (so once a new owner name is encountered,
+// no subsequent RRset has the previous owner name), but the ordering
+// in the same group is not fixed.  So we hold all RRsets of the same
+// owner name in node_rrsets_ and node_rrsigsets_, and add the matching
+// pairs of RRsets to the zone when we see a new owner name.
+//
+// The caller is responsible for adding the RRsets of the last group
+// in the input sequence by explicitly calling flushNodeRRsets() at the
+// end.  It's cleaner and more robust if we let the destructor of this class
+// do it, but since we cannot guarantee the adding operation is exception free,
+// we don't choose that option to maintain the common expectation for
+// destructors.
+class ZoneDataUpdater::Loader : boost::noncopyable {
+public:
+    Loader(util::MemorySegment& mem_sgmt, const isc::dns::RRClass rrclass,
+           const isc::dns::Name& zone_name, ZoneData& zone_data) :
+        updater_(mem_sgmt, rrclass, zone_name, zone_data)
+    {}
+
+    void addFromLoad(const isc::dns::ConstRRsetPtr& rrset);
+    void flushNodeRRsets();
+
+private:
+    typedef std::map<isc::dns::RRType, isc::dns::ConstRRsetPtr> NodeRRsets;
+    typedef NodeRRsets::value_type NodeRRsetsVal;
+
+    // A helper to identify the covered type of an RRSIG.
+    static isc::dns::RRType getCoveredType
+        (const isc::dns::ConstRRsetPtr& sig_rrset);
+    const isc::dns::Name& getCurrentName() const;
+
+private:
+    NodeRRsets node_rrsets_;
+    NodeRRsets node_rrsigsets_;
+    ZoneDataUpdater updater_;
+};
+
 } // namespace memory
 } // namespace datasrc
 } // namespace isc