I think I got it now. I'll clean up the code now, do multi-threading
tests now and then prepare a patch for review.

Just a question in the meantime: What's the purpose of the hash(Object)
function in PropertyCache? It seems to just hash a hash code. At any
rate, when I made sure that I always worked with the hashed hash code,
the whole thing suddenly started working.

BTW, I've upped the minimal bucket count to be equals to the segment
count so a lock on a segment is always the equivalent of a lock of the
set of buckets assigned to the segment. That allows more efficient
cleaning code.

On 22.08.2008 10:34:44 Jeremias Maerki wrote:
> Thanks for looking into it, Andreas!
> On 22.08.2008 00:15:00 Andreas Delmelle wrote:
> <snip/>
> > So, I was wondering about the role of the reference queue. Calling  
> > poll() returns the first reference /if/ one is available, so it seems  
> > likely that cleanSegment() does get called frequently enough, but  
> > there's always the possibility that it returns without a reference  
> > being available, yet. Or, as it happens, after throwing away only  
> > roughly half of the references.
> > Maybe it's only those that are also effectively enqueued at the time  
> > the cleanup is triggered (didn't try adding this to the stats yet).
> Javadoc says about WeakReference that the queueing may happen at some
> point after the reference is cleared. But a delay alone doesn't explain
> that so many instances weren't cleared.
> I got the impression that the cleaning wasn't done for some cache
> segments at all because the threshold never got reached. Just a feeling.
> > In the meantime, I've made some changes, bypassing the  
> > ReferenceQueue, and simply cleaning all buckets that map to the  
> > segment in question, and now the behavior already seems more like  
> > what I had in mind.
> > The first runs, each segment corresponds to one bucket, and the  
> > output now shows the number dropping to 0% for the related bucket.
> Segments: always 32
> Buckets: initially 8, rehash doubles the number of buckets each time
> That doesn't match what you're saying. Initially, 4 segments would share
> entries in 1 bucket. After a few rehashes, each segment would have its
> entries in a set of buckets. I think that's why in your patch the
> segment.count goes down into the negative (i.e. it's wrong).
> Plus, the removal of the reference queue polling just queues up
> references which are never cleared. I've fixed that locally.
> I'm going to try to fix the first problem above but I think that might
> not be possible without a performance penalty. Let's hope it's negligable.
> > See the attached patch. Still needs some cleanup, and haven't done  
> > any long-running tests, nor checked the cache for other types. I  
> > copied some, but not all of the added debug-code.
> > 
> > There are still a few things that bug me about StringProperty's  
> > cache, since for example, it is used in a lot of cases where not the  
> > property but its String value is attached to the FOs (reducing the  
> > benefits of caching somewhat, and probably explaining the large  
> > number of stale entries here...)
> Stale entries, yes, but at least the String instances are reused because
> they come from the canonicalized StringProperty. And we're using
> WeakReferences which get claimed very early. I don't think there's much
> we can/need to do about that.
> > 
> > Hope this helps some.
> Yes, it has shown me an aspect that I have missed.
> Jeremias Maerki

Jeremias Maerki

Reply via email to