BIND 10 #2096: Define and implement `RdataIterator` class
BIND 10 Development
do-not-reply at isc.org
Tue Jul 3 06:49:15 UTC 2012
#2096: Define and implement `RdataIterator` class
-------------------------------------+-------------------------------------
Reporter: | Owner:
jinmei | Status: new
Type: task | Milestone: Next-Sprint-
Priority: | Proposed
medium | Resolution:
Component: data | Sensitive: 0
source | Sub-Project: DNS
Keywords: | Estimated Difficulty: 0
Defect Severity: N/A | Total Hours: 0
Feature Depending on Ticket: |
scalable inmemory |
Add Hours to Ticket: 0 |
Internal?: 0 |
-------------------------------------+-------------------------------------
Comment (by jinmei):
Replying to [comment:2 vorner]:
> Is there a reason to use it by callbacks instead of repeatedly calling a
function? This way the code will end up more confusing I believe.
>
> If there's a compelling reason, I'd like not to call it Iterator. It
looks like something similar to foreach.
I don't know callback was the only feasible way, but my motivation at
the time of the experiments was that I didn't like to have the caller
switch their behavior based on the type of field (essentially either
name or data) on each "iteration".
Suppose we are trying to do additional section processing for an MX
RDATA. Internally it consists of one 2-byte (fixed-length) data field
and one name field as shown in
http://bind10.isc.org/wiki/InMemoryZoneDesign#a6.AdditionalRecordProcessing
With the pure-iteration design, the conceptual code would be
{{{#!cpp
RRset* answer_rrset; // of MX, but the code doesn't have to know it.
RdataIterator it(answer_rrset->getType(), answer_rrset->getRRCount());
while (!it->isLast()) {
RdataFieldIterator fit(it);
while (!fit->isLast()) {
pair<type,data> spec = fit->getCurrent();
if (spec.first == Name) {
// convert "data" to LabelSequence somehow, then look up the
// zone for the required additional RRs of the sequence
} else {
// It's a data field. We are not interested in it for
additional
// handling.
}
}
}
}}}
On the other hand, the callback version would be:
{{{#!cpp
RRset* answer_rrset; // of MX, but the code doesn't have to know it.
RdataIterator it(answer_rrset->getType(), answer_rrset->getRRCount(),
boost::bind(&Finder::findAdditional, this, ..., _1,
_2),
NULL); // we don't need data
while (!it.isLast()) {
it.action();
}
// the findAdditional would look like this:
void
Finder::findAdditional(const LabelSequence* seq, unsigned int
attributes)
{
// check attributes to see if it requires additional handling,
// if so:
node = zone_data->findNode(*seq, ...);
// then find AAAA/A on node
}
}}}
I just thought the latter was cleaner and would help the overall code
simpler as I saw this type of while loop in several places. But
different people should always have different opinions on this type of
details. As long as the resulting code is reasonably readable and
sufficiently efficient, any workable approach is okay.
Regarding the name, anything that sounds most intuitive should be
used.
The experimental code was shown here only for clarifying what's
necessary. It's not the spec itself.
--
Ticket URL: <http://bind10.isc.org/ticket/2096#comment:3>
BIND 10 Development <http://bind10.isc.org>
BIND 10 Development
More information about the bind10-tickets
mailing list