BIND 10 #1605: introduce special RRset for in memory data source
BIND 10 Development
do-not-reply at isc.org
Fri Feb 24 00:57:54 UTC 2012
#1605: introduce special RRset for in memory data source
-------------------------------------+-------------------------------------
Reporter: | Owner: jinmei
jinmei | Status: reviewing
Type: task | Milestone:
Priority: major | Sprint-20120306
Component: data | Resolution:
source | Sensitive: 0
Keywords: | Sub-Project: DNS
Defect Severity: N/A | Estimated Difficulty: 5
Feature Depending on Ticket: auth | Total Hours: 0
performance |
Add Hours to Ticket: 0 |
Internal?: 0 |
-------------------------------------+-------------------------------------
Comment (by jinmei):
First off, I made a few trivial changes directly to the branch
(0169ac7). I believe they are okay.
'''About general design'''
- I'd like to hide the definition (or ideally even the existence) of
`RBNodeRRset` more reliably. Conceptually, this class should be a
hidden client of the in-memory data source implementation and should
never be used by anyone else directly (are we on the same page about
this?). I see it'd still be good if we test the class directly, and
for that purpose we need to make it visible at least to the test,
so, as a compromise for that specific purpose (and basically only
for that purpose) I'm okay with defining it in a separate header
file. But I'd like to make it very clear that no other applications
than tests should use it directly via a comment, and probably by
introducing a separate (sub)namespace such as "internal" or
"detail".
On a side note, assuming it's conceptually hidden and only visible
to others as a const abstract object as the result of find() (and
its variants) method, not supporting methods that modify the object
should be justifiable. Maybe we want to note that fact.
- Also considering that `RBNodeRRset` is conceptually hidden, breaking
const_cast in addRRsig/removeRRsig would also be justifiable. But
to prevent accidental misuse by a broken application more reliably,
I'd rather keep them "not supported", and instead introduce a
separate (conceptually private) non virtual methods, say,
`addRRsigInternal` and `removeRRsigInternal`. The in-memory data
source implementation and tests will use the latter.
- Whether it's virtual or not, we could avoid using const_cast in
add/removeRRsig if we copy the given `RRset` on construction.
That's also safer in that we can prevent a surprising possible bug
where a passed RRset is reused for some other purpose with a (valid)
assumption that it's not magically modified. In practice, however,
such a bug is probably unlikely to happen because the `RRset` would
come from the masterLoad() function, which immediately gives up the
ownership of the created `RRset`. Also, not so far in future we'll
need to stop retaining the full copy of original `RRset` anyway
(firstly for memory consumption reasons, and possibly also for
further response optimization), so this safe measure is probably a
short term thing. In the end, I'd leave the decision on this point
to you.
'''rbnode_rrset.h'''
- This comment is a bit ambiguous to me:
{{{#!c++
/// - Calls that modify the associated RRSIGs of the RRset are allowed
(even
/// though the pointer is to a "const" object).
}}}
That could also be interpreted as modifying the content of the
associated RRSIGs. To be more accurate, I'd say e.g. "Calls that
add or remove the associated RRSIGs...". (but see also the general
design discussion about breaking constness).
- I'd make the constructor 'explicit'.
- getUnderlyingRRset() can be non virtual, and I think it's better.
'''rbnode_rrset_unittest'''
- Regarding type parameterisation: we can still do it partially by
extracting common patterns with template specialization or just by
defining separate tests for separate behaviors as we do for
NSEC/NSEC3. But the `RBNodeRRset` class will evolve more
substantially in near future as we add more optimization logic
there, and it may or may not make the test sharing more difficult,
so until it's clear it's probably okay to keep the tests separate.
(This is just a comment).
- toWireRenderer: I'd suggest getting data (and length) directly from
the renderer:
{{{#!c++
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, renderer.getData(),
renderer.getLength(), &wiredata[0],
wiredata.size());
}}}
It will be more robust after #1697 (which is ongoing). And,
whatever happens in #1697, using renderer should always be correct.
- With the suggested change above, toWireRenderer and toWireBuffer
could be unified into a single template function (if you want).
- About the added test wire data: if you share test data, I'd rather
add a data path and really share the data file than copying it. You
should be able to add a path here:
{{{#!c++
isc::UnitTestUtil::addDataPath(TEST_DATA_DIR);
}}}
(I noticed you modified rrset_toWire2. I was not sure if it was due
to an inevitable difference between the two rrset classes or just
for convenience. If it's the latter, I'd consider using the same
data in the same test pattern)
- checkSignature: I'd consider using rrsetCheck (defined in
lib/testutils/dnsmessage_test.h) or Rdata::compare() to compare two
RRs Comparing toText() result may not be very reliable.
- addRRsigConstRdataPointer: what's the purpose of intermediate 'data'
variable? It can be ConstRdataPtr from the beginning:
{{{#!c++
ConstRdataPtr data = createRdata(rrset_siga->getType(),
rrset_siga->getClass(),
RRSIG_TXT);
rrset_a.addRRsig(data);
checkSignature(rrset_a);
}}}
'''memory_datasrc_unittest'''
- Like checkSignature above, I'd suggest considering rrsetsCheck() to
compare two sets of RRsets. You can build two vector<RRset>s and
pass them to rrsetsCheck().
--
Ticket URL: <http://bind10.isc.org/ticket/1605#comment:9>
BIND 10 Development <http://bind10.isc.org>
BIND 10 Development
More information about the bind10-tickets
mailing list