};
scoped_ptr<NSEC3Data> 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 <typename NodeType>
+ struct FindNodeResultBase {
// Bitwise flags to represent supplemental information of the
// search result:
// Search resulted in a wildcard match.
// 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<const DomainNode> FindNodeResult;
+ typedef FindNodeResultBase<DomainNode> 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<DomainNode*>(result.node);
- }
- return (result);
- }
+ template <typename ResultType>
+ ResultType findNode(const Name& name,
+ ZoneFinder::FindOptions options) const;
};
/// Maintain intermediate data specific to the search context used in
//
// If none of the above succeeds, we conclude the name doesn't exist in
// the zone.
-ZoneData::FindNodeResult
+template <typename ResultType>
+ResultType
ZoneData::findNode(const Name& name, ZoneFinder::FindOptions options) const {
DomainNode* node = NULL;
RBTreeNodeChain<Domain> node_path;
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() ==
// 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(
// 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
// 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<ZoneData::FindNodeResult>(name, options);
if (node_result.code != SUCCESS) {
return (createFindResult(node_result.code, node_result.rrset));
}
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<ZoneData::FindMutableNodeResult>(
+ 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) &&