BIND 10 #192: Data source hotspot cache
BIND 10 Development
do-not-reply at isc.org
Fri Jun 18 22:22:47 UTC 2010
#192: Data source hotspot cache
-------------------------+--------------------------------------------------
Reporter: each | Owner: each
Type: enhancement | Status: reviewing
Priority: major | Milestone: 05. 3rd Incremental Release: Serious Secondary
Component: b10-auth | Resolution:
Keywords: | Sensitive: 0
-------------------------+--------------------------------------------------
Comment(by jinmei):
Replying to [comment:8 each]:
> > - We should really, really, seriously reconsider the current design
of making some of the class member variables public (from prev to qtype).
>
> With qname/qclass/qtype, we've been inconsistent in libdatasrc;
sometimes they're public member variables, sometimes they're functions. I
agree we should pick a way and stick with it. I've begun to wonder if we
should move toward using a QTuple struct for this.
>
> I had a specific reason for making next and prev public--originally I
hid them, but there was code in the HotCache class that became much
simpler if it had access to them. (This could be done by making them
protected and giving HotCache friend status, but we have avoided using
friend so far. Or it could be done by having next_ and prev_ be private
but exposed via next() and prev() accessor functions. But as this is
CacheNode, and next and prev both point to CacheNode and always will, it
seemed unlikely to me that there would ever be any implementation details
that would need to be hidden inside those accessor functions. I'm okay
with doing it that way if you wish, though.
In public APIs any unlikely things will happen by some user. So, yes, I
insist we should hide them.
Note, however, that we could adopt pimpl for CacheNode and hide the
implementation details within .cc. That way I'm okay with handling them
directly (I myself take that approach sometimes).
> > - document operator<. why we need this etc. note also that
Name::operator< is quite expensive (it calls the generic compare()
method).
>
> Can it be made cheaper?
Perhaps. MessageRenderer implements a bit simpler version of comparison,
but I must say that might be a premature optimization. This comment is
actually a heads-up rather than suggesting something else (one of the
disadvantages of operator overloading, which is they can make expensive
operations look cheaper). Before trying to tweak this, we should perform
benchmark first.
> > - retrieve() signature: why passing object copies?
>
> If you see me do that and don't know why I did it, the answer is nearly
always going to be "I forgot the &" and nothing more. Unfortunately the
C++ compiler isn't capable of telling me when I've made that mistake, and
I make it a lot.
I see. btw, making classes non copyable whenever possible helps avoid it.
that's one of the reasons why it's a good idea. unfortunately, however,
in this specific case these arguments objects are supposed to be copyable
and we can't exploit this technique.
> > - LRU list: why using in-house list, rather than std::list? (see
also the comment about the implementation).
>
> It just seemed more straightforward to roll my own type with built-in
promotion-on-access and LRU-cleanup behavior, rather than try to backfill
that behavior into the std::list type.
Admittedly, I expect the use of std::list will have its own negative
implications in this case. But you seem to underestimate the risk of in-
house based development with such reasons as "because it seems more
straightforward". In house list implementation requires us to write non
trivial manipulation code like this:
{{{
if (lru_head_) {
node->next = lru_head_;
lru_head_->prev = node;
lru_head_ = node;
} else {
}}}
which is not so trivial as the original developer might believe, and we in
fact often make bugs in the handmade logic. In fact, you probably
actually made one (see the ~HotCache() comment below).
So, while I don't insist std::list is definitely better in this case, I
would suggest you at least try a version with std::list, not just making a
decision based on seeming observation. If, after playing with both ways,
you are still sure the advantage of in-house implementation outweighs its
negative consequences, it's your call.
> > cache.cc
> > - HotCache::~HotCache(): I don't understand what the for loop does.
>
> Hm. Not sure this is still needed, it may be left over from an earlier
code iteration. But what it does is successively remove references to
each item on the list so that shared_ptr will deallocate them.
One thing I cannot understand is the loop condition:
{{{
for (node = lru_head_; node = node->next; node != CacheNodePtr()) {
}}}
At least the third statement doesn't make sense. I'm also not sure if
this loop ever stops because node doesn't seem to be changed in the loop.
Note also that if you used an STL container you wouldn't have to be
bothered with these things. Objects remaining in the container will
automatically cleaned up when the container is destructed.
--
Ticket URL: <https://bind10.isc.org/ticket/192#comment:20>
BIND 10 Development <http://bind10.isc.org>
BIND 10 Development
More information about the bind10-tickets
mailing list