From: JINMEI Tatuya Date: Thu, 22 Mar 2012 08:49:24 +0000 (-0700) Subject: [1775] use a template to share the same code for const/non cost of findNode. X-Git-Tag: trac2351_base~226^2~116^2~66^2~8^2~3 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=40d727bf4c011c28575fb099fa8370591afa4a2a;p=thirdparty%2Fkea.git [1775] use a template to share the same code for const/non cost of findNode. we can then avoid const_cast. --- diff --git a/src/lib/datasrc/memory_datasrc.cc b/src/lib/datasrc/memory_datasrc.cc index 533aca2c46..4a5b99c2b9 100644 --- a/src/lib/datasrc/memory_datasrc.cc +++ b/src/lib/datasrc/memory_datasrc.cc @@ -162,8 +162,16 @@ public: }; scoped_ptr nsec3_data_; // non NULL only when it's NSEC3 signed - // This structure encapsulates the find result of findNode() method below. - struct FindNodeResult { + // This templated structure encapsulates the find result of findNode() + // method (also templated) below. + // The template parameter is expected to be either 'const DomainNode' or + // 'DomainNode' (to avoid misuse the template definition itself is kept + // private - we only expose expected typedefs). The former is expected + // to be used for lookups, and the latter is expected to be used for + // constructing the zone. +private: + template + struct FindNodeResultBase { // Bitwise flags to represent supplemental information of the // search result: // Search resulted in a wildcard match. @@ -172,45 +180,27 @@ public: // a glue. static const unsigned int FIND_ZONECUT = 2; - FindNodeResult(ZoneFinder::Result code_param, - const DomainNode* node_param, - ConstRBNodeRRsetPtr rrset_param, - unsigned int flags_param = 0) : + FindNodeResultBase(ZoneFinder::Result code_param, + NodeType* node_param, + ConstRBNodeRRsetPtr rrset_param, + unsigned int flags_param = 0) : code(code_param), node(node_param), rrset(rrset_param), flags(flags_param) {} const ZoneFinder::Result code; - const DomainNode* const node; + NodeType* const node; ConstRBNodeRRsetPtr const rrset; const unsigned int flags; }; +public: + typedef FindNodeResultBase FindNodeResult; + typedef FindNodeResultBase FindMutableNodeResult; // Identify the RBTree node that best matches the given name. // See implementation notes below. - FindNodeResult findNode(const Name& name, - ZoneFinder::FindOptions options) const; - - // Mutable version of findNode(). If it finds an exact match for the - // given name, it returns a mutable pointer to that node via nodep. - // This is intentionally separated from findNode() and is expected to - // be used during the construction of zone, while keeping the const - // version as efficient and safe as possible. - FindNodeResult findMutableNode(const Name& name, - ZoneFinder::FindOptions options, - DomainNode** nodep) - { - FindNodeResult result = findNode(name, options); - if (result.code != ZoneFinder::SUCCESS) { - *nodep = NULL; - } else { - // For the tradeoff between safety and performance (of the - // const version), we discard the constness here. In practice - // this should be okay because internally this node was retrieved - // from the zone tree as a mutable pointer anyway. - *nodep = const_cast(result.node); - } - return (result); - } + template + ResultType findNode(const Name& name, + ZoneFinder::FindOptions options) const; }; /// Maintain intermediate data specific to the search context used in @@ -353,7 +343,8 @@ bool cutCallback(const DomainNode& node, FindState* state) { // // If none of the above succeeds, we conclude the name doesn't exist in // the zone. -ZoneData::FindNodeResult +template +ResultType ZoneData::findNode(const Name& name, ZoneFinder::FindOptions options) const { DomainNode* node = NULL; RBTreeNodeChain node_path; @@ -364,27 +355,26 @@ ZoneData::findNode(const Name& name, ZoneFinder::FindOptions options) const { const unsigned int zonecut_flag = (state.zonecut_node_ != NULL) ? FindNodeResult::FIND_ZONECUT : 0; if (result == DomainTree::EXACTMATCH) { - return (FindNodeResult(ZoneFinder::SUCCESS, node, state.rrset_, - zonecut_flag)); + return (ResultType(ZoneFinder::SUCCESS, node, state.rrset_, + zonecut_flag)); } if (result == DomainTree::PARTIALMATCH) { assert(node != NULL); if (state.dname_node_ != NULL) { // DNAME LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_MEM_DNAME_FOUND). arg(state.rrset_->getName()); - return (FindNodeResult(ZoneFinder::DNAME, NULL, state.rrset_)); + return (ResultType(ZoneFinder::DNAME, NULL, state.rrset_)); } if (state.zonecut_node_ != NULL) { // DELEGATION due to NS LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_MEM_DELEG_FOUND). arg(state.rrset_->getName()); - return (FindNodeResult(ZoneFinder::DELEGATION, NULL, - state.rrset_)); + return (ResultType(ZoneFinder::DELEGATION, NULL, state.rrset_)); } if (node_path.getLastComparisonResult().getRelation() == NameComparisonResult::SUPERDOMAIN) { // empty node, so NXRRSET LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_MEM_SUPER_STOP).arg(name); - return (FindNodeResult(ZoneFinder::NXRRSET, node, - ConstRBNodeRRsetPtr())); + return (ResultType(ZoneFinder::NXRRSET, node, + ConstRBNodeRRsetPtr())); } if (node->getFlag(domain_flag::WILD)) { // maybe a wildcard if (node_path.getLastComparisonResult().getRelation() == @@ -399,8 +389,8 @@ ZoneData::findNode(const Name& name, ZoneFinder::FindOptions options) const { // little bit). LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_MEM_WILDCARD_CANCEL).arg(name); - return (FindNodeResult(ZoneFinder::NXDOMAIN, NULL, - ConstRBNodeRRsetPtr())); + return (ResultType(ZoneFinder::NXDOMAIN, NULL, + ConstRBNodeRRsetPtr())); } // Now the wildcard should be the best match. const Name wildcard(Name("*").concatenate( @@ -409,14 +399,14 @@ ZoneData::findNode(const Name& name, ZoneFinder::FindOptions options) const { // Otherwise, why would the domain_flag::WILD be there if // there was no wildcard under it? assert(result == DomainTree::EXACTMATCH); - return (FindNodeResult(ZoneFinder::SUCCESS, node, state.rrset_, - FindNodeResult::FIND_WILDCARD | - zonecut_flag)); + return (ResultType(ZoneFinder::SUCCESS, node, state.rrset_, + FindNodeResult::FIND_WILDCARD | + zonecut_flag)); } } // Nothing really matched. The name may even be out-of-bailiwick. LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_MEM_NOT_FOUND).arg(name); - return (FindNodeResult(ZoneFinder::NXDOMAIN, node, state.rrset_)); + return (ResultType(ZoneFinder::NXDOMAIN, node, state.rrset_)); } } // unnamed namespace @@ -1199,7 +1189,7 @@ struct InMemoryZoneFinder::InMemoryZoneFinderImpl { // Get the node. All other cases than an exact match are handled // in findNode(). We simply construct a result structure and return. const ZoneData::FindNodeResult node_result = - zone_data_->findNode(name, options); + zone_data_->findNode(name, options); if (node_result.code != SUCCESS) { return (createFindResult(node_result.code, node_result.rrset)); } @@ -1443,12 +1433,14 @@ addAdditional(RBNodeRRset* rrset, ZoneData* zone_data) { DomainNode* node = NULL; const Name& name = getAdditionalName(rrset->getType(), rdata_iterator->getCurrent()); - const ZoneData::FindNodeResult result = - zone_data->findMutableNode(name, ZoneFinder::FIND_GLUE_OK, &node); + const ZoneData::FindMutableNodeResult result = + zone_data->findNode( + name, ZoneFinder::FIND_GLUE_OK); if (result.code != ZoneFinder::SUCCESS) { // We are not interested in anything but a successful match. continue; } + node = result.node; assert(node != NULL); if ((result.flags & ZoneData::FindNodeResult::FIND_ZONECUT) != 0 || (node->getFlag(DomainNode::FLAG_CALLBACK) &&