I've found the answer to my own question.
Looks like the only time a node is considered to have been "visited" is if you make the call TreeCache.get(Fqn fqn,Object key).
If you do the functionally equivalent call by calling TreeCache.get(Fqn) and then asking the returned node for its data, eviction still occurs.
// eviction doesn't happen if you do it this way myCache.get(fqn,key); // this allows eviction to happens myCache.get(fqn).getData().get(key);
Is this a bug, or performing as designed?
In my situation, I need to a portion of the tree and examining the data of the node as I go. These count as "visits" to me.
Node get(Fqn) is somewhat of a pain for us: we give you direct access to the internal nodes, bypassing the interceptors (locking, cacheloading etc).
This is not meant to be used by application developers, only by interceptors, or the cache itself. This may go away in the future, and is only public because we don't have a 'friend' modifier like in C++.
So you're saying that TreeCache.get(Fqn) is not safe to be used at all?
In my case I need an efficient and safe way to walk through the tree. My scenario is that given a starting node, I then need to do a depth first walk through the tree. I need to acquire read locks on any/all nodes I visit, but don't need to track visitation (I've worked around my original issue by making my custom eviction policy a little smarter).
Can you advise then on the most efficient (safe) way to do this? I see how I could use TreeCache.getChildrenNames(Fqn) but this seems pretty inefficient as each call in turn uses findNode(Fqn) which walks through the tree from the root. Since my tree is pretty deep and wide, that spells trouble.
Is there a way that I can do the locking myself by using one of Node's locking methods?
Finally, aAre there any plans to refactor out the truly public methods of TreeCache into an interface? This would certainly help useability and encourage us users to stay away from unsafe methods. You could then have a single base implementation providing the additional internal helper methods. If you then have to do some funky casting internally that breaks the interface encapsulation then that is far preferable to leaving non-safe methods out there that will go away in the future.
Another suggestion would be to use the Javadoc @exclude tag on the non-public methods so they don't get included in the javadocs.
#1 Yes, getChildrenNames() is currently the recommended way to traverse the tree.
#2 We plan to extract TreeCache/TreeCacheAop into an interface