I noticed that UnversionedNode.getData() is taking a lot of time in my app. Then I saw that it actually creates a new HashMap, calls getKeys, then gets the value for each key separately and puts it in the map.
Every single cache.get(fqn, k) separately fires the whole chain of interceptors... transaction, locking, notification and whatnot. Couldn't it do it only once, on the node as a whole?
Yes, this should delegate to Cache.getData(Fqn). Corrected in CVS.
Also, I found a little gem in LockMap.java:
// a CopyOnWriteArraySet is HUGELY inefficient since MANY LockMaps are created and are frequently read from. Until we have a better impl ...
private final Set readOwnerList_ = new CopyOnWriteArraySet();
I added this comment, and then toyed with a striped-lock/CHM based implementation of a ConcurrentHashSet (see o.j.c.util.concurrent.ConcurrentHashSet) and while this was more performant than a CopyOnWriteArraySet in many places in the cache, it wasn't so in the LockMap. After profiling, the LockMap was actually quicker with the CopyOnWriteArraySet.
Anyway, we do have plans to overhaul the whole concurrency/locking aspects of the cache, see http://wiki.jboss.org/wiki/Wiki.jsp?page=JBossCacheMVCC
Thanks, it runs a tiny little bit faster now :p
It jumped from about 350 to 1500 transactions/s (!!!!!)
About the locks, is ConcurrentHashSet faster than a plain synchronized HashSet, when there are a lot of adds & removes?
is ConcurrentHashSet faster
I meant CopyOnWriteArraySet
To answer Manik's question for him, I ran some tests in JBCache and the performance for a plain synchronized HashSet compared to CopyOnWriteArraySet was worse, by about 10-20%. This is on a dual-core laptop, and probably for a four or eight-way, the difference might be more noticeable.
COWAL actually does have some heavy synchronization for add and remove in JDK 1.5. For JDK 1.6, a read-write lock is used. (not sure this would help., as every operation done is a add or remove.) COWAL is more designed for more readers than writers.
Thx, genman. :-)