incubator-jena-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Paolo Castagna <>
Subject Re: SPARQL query equality and "equivalence"...
Date Tue, 15 Mar 2011 19:39:08 GMT
Hi Andy.

Andy Seaborne wrote:
>> I had a first go at implementing a cached QueryEngineHTTP:

>> Invalidation is by service end-point and this approach makes sense only
>> if you have mostly reads with few and non frequent updates.
>> I am not happy with all those synchronized and the static cache.
>   synchronized (cache) {
>      if (cache.containsKey(key)) {
>            return (ResultSetRewindable) cache.get(key);
>       }
>     }
>     rs = ResultSetFactory.makeRewindable(super.execSelect());
>       synchronized (cache) {
>          cache.put(key, rs);
>     }
> The synchronization needs to be over the get and the put together.  What 
> if another thread comes in after the first block?  Both find .get is null.

This was my first solution, then I tried to be clever...
I wanted to reduce as much as possible the synchronized part and in particular
I wanted not to have a potentially long operation inside the synchronized
block. The risk is to have two threads making the query remotely and adding
the result to the cache.

My fear was that the approach below will reduce concurrency on the client,
but this is probably not true.

> You then have two threads executing the makeRewindable/execSelect  This 
> happens to be safe because of the operation super.execSelect() is safe 
> in parallel but in general the operation being cached is not thread safe.
> Generally this is safer: a single sync over get and the 
> put-if-cache-miss.  And in this case just as fast, and makes only one 
> call to the far end:
>  (thread 2 waits on the lock, not makes the query on the remote end):
>   synchronized (cache) {
>      if (cache.containsKey(key)) {
>            return (ResultSetRewindable) cache.get(key);
>      rs = ResultSetFactory.makeRewindable(super.execSelect());
>      cache.put(key, rs);
>     }

I'll follow your suggestion.

I also added one which uses Memcached and one which uses Redis as well:

Cache invalidation is the problem. :-)

I've tried to follow your advice on implementing a new QueryEngine
with a factory/implementation pair, but I got confused... it was
late and this is somehow "out-of-band" activity.

However, I would like to have a good/proper example to show how you
can have a cached query engine either local or remote.


>     Andy

View raw message