From: JINMEI Tatuya Date: Fri, 9 Mar 2012 21:38:06 +0000 (-0800) Subject: [1608] build shortcut links to rbtnodes for additional records. X-Git-Tag: trac2351_base~226^2~116^2~127^2~3^2~16 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=08ac200f2f3e15548a81b4c252b72fc8ac72edbe;p=thirdparty%2Fkea.git [1608] build shortcut links to rbtnodes for additional records. no observable change yet. --- diff --git a/src/lib/datasrc/memory_datasrc.cc b/src/lib/datasrc/memory_datasrc.cc index 7f158359cc..15b0f3c580 100644 --- a/src/lib/datasrc/memory_datasrc.cc +++ b/src/lib/datasrc/memory_datasrc.cc @@ -108,15 +108,23 @@ struct ZoneData { }; } -// RBNodeRRset details namespace internal { +struct AdditionalNodeInfo { + AdditionalNodeInfo(DomainNode* node) : node_(node) {} + DomainNode* node_; +}; + +// +// RBNodeRRset details +// struct RBNodeRRsetImpl { public: RBNodeRRsetImpl(const ConstRRsetPtr& rrset) : rrset_(rrset) {} ConstRRsetPtr rrset_; ///< Underlying RRset + scoped_ptr > additionals_; }; RBNodeRRset::RBNodeRRset(const ConstRRsetPtr& rrset) : @@ -239,6 +247,14 @@ RBNodeRRset::getUnderlyingRRset() const { return (impl_->rrset_); } +void +RBNodeRRset::addAdditionalNode(const AdditionalNodeInfo& additional) { + if (!impl_->additionals_) { + impl_->additionals_.reset(new vector); + } + impl_->additionals_->push_back(additional); +} + } // end of internal class InMemoryZoneFinder::Context_ : public ZoneFinder::Context { @@ -253,6 +269,13 @@ public: const vector &all_set) : ZoneFinder::Context(finder, options, result, all_set) {} + +protected: + virtual void getAdditionalImpl(const vector& requested_types, + vector& result) + { + ZoneFinder::Context::getAdditionalImpl(requested_types, result); + } }; // Private data and hidden methods of InMemoryZoneFinder @@ -565,7 +588,9 @@ struct InMemoryZoneFinder::InMemoryZoneFinderImpl { * access is without the impl_-> and it will get inlined anyway. */ // Implementation of InMemoryZoneFinder::add - result::Result add(const ConstRRsetPtr& rawrrset, ZoneData& zone_data) { + result::Result add(const ConstRRsetPtr& rawrrset, ZoneData& zone_data, + vector* need_additionals) + { // Sanitize input. This will cause an exception to be thrown // if the input RRset is empty. addValidation(rawrrset); @@ -634,6 +659,12 @@ struct InMemoryZoneFinder::InMemoryZoneFinderImpl { node->setFlag(DomainNode::FLAG_CALLBACK); } + if (need_additionals != NULL && + (rrset->getType() == RRType::NS() || + rrset->getType() == RRType::MX())) { + need_additionals->push_back(rrset.get()); + } + // If we've added NSEC3PARAM at zone origin, set up NSEC3 specific // data or check consistency with already set up parameters. if (rrset->getType() == RRType::NSEC3PARAM() && @@ -662,8 +693,10 @@ struct InMemoryZoneFinder::InMemoryZoneFinderImpl { * Same as above, but it checks the return value and if it already exists, * it throws. */ - void addFromLoad(const ConstRRsetPtr& set, ZoneData* zone_data) { - switch (add(set, *zone_data)) { + void addFromLoad(const ConstRRsetPtr& set, ZoneData* zone_data, + vector* need_additionals) + { + switch (add(set, *zone_data, need_additionals)) { case result::EXIST: LOG_ERROR(logger, DATASRC_MEM_DUP_RRSET). arg(set->getName()).arg(set->getType()); @@ -1133,20 +1166,57 @@ InMemoryZoneFinder::findNSEC3(const Name& name, bool recursive) { result::Result InMemoryZoneFinder::add(const ConstRRsetPtr& rrset) { - return (impl_->add(rrset, *impl_->zone_data_)); + return (impl_->add(rrset, *impl_->zone_data_, NULL)); +} + +namespace { +// This should eventually be more generalized. +const Name& +getAdditionalName(RRType rrtype, const rdata::Rdata& rdata) { + if (rrtype == RRType::NS()) { + const generic::NS& ns = dynamic_cast(rdata); + return (ns.getNSName()); + } else if (rrtype == RRType::MX()) { + const generic::MX& mx = dynamic_cast(rdata); + return (mx.getMXName()); + } + // In our usage this shouldn't happen. + assert(false); } +void +addAdditional(internal::RBNodeRRset* rrset, ZoneData* zone_data) { + RdataIteratorPtr rdata_iterator = rrset->getRdataIterator(); + for (; !rdata_iterator->isLast(); rdata_iterator->next()) { + // TODO: zone cut consideration, empty node case + RBTreeNodeChain node_path; + DomainNode* node = NULL; + DomainTree::Result result = + zone_data->domains_.find( + getAdditionalName(rrset->getType(), + rdata_iterator->getCurrent()), + &node, node_path, NULL, NULL); + if (result == DomainTree::EXACTMATCH) { + rrset->addAdditionalNode(node); + } + } +} +} void InMemoryZoneFinder::load(const string& filename) { LOG_DEBUG(logger, DBG_TRACE_BASIC, DATASRC_MEM_LOAD).arg(getOrigin()). arg(filename); - // Load it into temporary zone data + // Load it into temporary zone data. + vector need_additionals; scoped_ptr tmp(new ZoneData(getOrigin())); masterLoad(filename.c_str(), getOrigin(), getClass(), boost::bind(&InMemoryZoneFinderImpl::addFromLoad, impl_, - _1, tmp.get())); + _1, tmp.get(), &need_additionals)); + + for_each(need_additionals.begin(), need_additionals.end(), + boost::bind(addAdditional, _1, tmp.get())); // If the zone is NSEC3-signed, check if it has NSEC3PARAM if (tmp->nsec3_data_) { diff --git a/src/lib/datasrc/rbnode_rrset.h b/src/lib/datasrc/rbnode_rrset.h index 9e46ffef5a..2b1d227e20 100644 --- a/src/lib/datasrc/rbnode_rrset.h +++ b/src/lib/datasrc/rbnode_rrset.h @@ -35,6 +35,8 @@ namespace internal { /// so that the In-memory data source implementation can refer to it. struct RBNodeRRsetImpl; +struct AdditionalNodeInfo; + /// \brief Special RRset for optimizing memory datasource requirement /// /// To speed up the performance of the in-memory data source, at load time @@ -148,6 +150,10 @@ public: virtual void removeRRsig(); + /// \brief TBD + /// Note: this method is mostly private to the in-memory implementation. + void addAdditionalNode(const AdditionalNodeInfo& additional); + /// \brief Return underlying RRset pointer /// /// ... mainly for testing.