From: Mukund Sivaraman Date: Thu, 4 Oct 2012 18:46:58 +0000 (+0530) Subject: [2268] Move Loader to live under ZoneDataUpdater X-Git-Tag: trac2402_base~62 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ae53c8fd697e2cd037facfccc8205d580b27f04e;p=thirdparty%2Fkea.git [2268] Move Loader to live under ZoneDataUpdater --- diff --git a/src/lib/datasrc/memory/memory_client.cc b/src/lib/datasrc/memory/memory_client.cc index e1c1089a85..27d42861cb 100644 --- a/src/lib/datasrc/memory/memory_client.cc +++ b/src/lib/datasrc/memory/memory_client.cc @@ -36,11 +36,8 @@ #include #include -#include -#include #include -#include #include #include #include @@ -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 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(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 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(); diff --git a/src/lib/datasrc/memory/memory_client.h b/src/lib/datasrc/memory/memory_client.h index 438e3fb4eb..8c3efebf9b 100644 --- a/src/lib/datasrc/memory/memory_client.h +++ b/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 diff --git a/src/lib/datasrc/memory/zone_data_updater.cc b/src/lib/datasrc/memory/zone_data_updater.cc index 1d02432ae6..f5a85a41c9 100644 --- a/src/lib/datasrc/memory/zone_data_updater.cc +++ b/src/lib/datasrc/memory/zone_data_updater.cc @@ -18,6 +18,7 @@ #include #include +#include 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(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 diff --git a/src/lib/datasrc/memory/zone_data_updater.h b/src/lib/datasrc/memory/zone_data_updater.h index dc02aba7d4..1c00aef898 100644 --- a/src/lib/datasrc/memory/zone_data_updater.h +++ b/src/lib/datasrc/memory/zone_data_updater.h @@ -24,6 +24,7 @@ #include #include +#include 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 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