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