Skip to content
Snippets Groups Projects
Commit 15d762e6 authored by Tobias Pietzsch's avatar Tobias Pietzsch
Browse files

Moved Entry.loaded flags to Entry.ref.loaded

This allows to drop the "V extends VolatileCacheValue" requirement without
running into concurrent modification problems. (hopefully...)
parent 49da56bd
Branches
No related tags found
No related merge requests found
...@@ -8,13 +8,12 @@ import java.util.concurrent.ConcurrentHashMap; ...@@ -8,13 +8,12 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import bdv.cache.CacheHints; import bdv.cache.CacheHints;
import bdv.cache.VolatileCacheValue;
import bdv.cache.iotiming.CacheIoTiming; import bdv.cache.iotiming.CacheIoTiming;
import bdv.cache.iotiming.IoStatistics; import bdv.cache.iotiming.IoStatistics;
import bdv.cache.iotiming.IoTimeBudget; import bdv.cache.iotiming.IoTimeBudget;
import bdv.cache.util.BlockingFetchQueues; import bdv.cache.util.BlockingFetchQueues;
public class WeakRefVolatileCache< K, V extends VolatileCacheValue > implements VolatileCache< K, V > public class WeakRefVolatileCache< K, V > implements VolatileCache< K, V >
{ {
final ConcurrentHashMap< K, Entry > map = new ConcurrentHashMap<>(); final ConcurrentHashMap< K, Entry > map = new ConcurrentHashMap<>();
...@@ -36,10 +35,20 @@ public class WeakRefVolatileCache< K, V extends VolatileCacheValue > implements ...@@ -36,10 +35,20 @@ public class WeakRefVolatileCache< K, V extends VolatileCacheValue > implements
{ {
private final Entry entry; private final Entry entry;
public CacheWeakReference( final V referent, final Entry entry ) final int loaded;
public CacheWeakReference( final V referent )
{
super( referent );
entry = null;
loaded = NOTLOADED;
}
public CacheWeakReference( final V referent, final Entry entry, final int loaded )
{ {
super( referent, queue ); super( referent, queue );
this.entry = entry; this.entry = entry;
this.loaded = loaded;
} }
public void clean() public void clean()
...@@ -57,11 +66,9 @@ public class WeakRefVolatileCache< K, V extends VolatileCacheValue > implements ...@@ -57,11 +66,9 @@ public class WeakRefVolatileCache< K, V extends VolatileCacheValue > implements
final class Entry final class Entry
{ {
private WeakReference< V > ref;
final K key; final K key;
int loaded; CacheWeakReference ref;
long enqueueFrame; long enqueueFrame;
...@@ -71,8 +78,7 @@ public class WeakRefVolatileCache< K, V extends VolatileCacheValue > implements ...@@ -71,8 +78,7 @@ public class WeakRefVolatileCache< K, V extends VolatileCacheValue > implements
{ {
this.key = key; this.key = key;
this.loader = loader; this.loader = loader;
this.ref = new WeakReference<>( null ); this.ref = new CacheWeakReference( null );
this.loaded = NOTLOADED;
this.enqueueFrame = -1; this.enqueueFrame = -1;
} }
...@@ -83,15 +89,13 @@ public class WeakRefVolatileCache< K, V extends VolatileCacheValue > implements ...@@ -83,15 +89,13 @@ public class WeakRefVolatileCache< K, V extends VolatileCacheValue > implements
public void setInvalid( final V value ) public void setInvalid( final V value )
{ {
loaded = INVALID; ref = new CacheWeakReference( value, this, INVALID );
ref = new CacheWeakReference( value, this );
} }
// Precondition: caller must hold lock on this. // Precondition: caller must hold lock on this.
public void setValid( final V value ) public void setValid( final V value )
{ {
loaded = VALID; ref = new CacheWeakReference( value, this, VALID );
ref = new CacheWeakReference( value, this );
loader = null; loader = null;
enqueueFrame = Long.MAX_VALUE; enqueueFrame = Long.MAX_VALUE;
notifyAll(); notifyAll();
...@@ -111,8 +115,9 @@ public class WeakRefVolatileCache< K, V extends VolatileCacheValue > implements ...@@ -111,8 +115,9 @@ public class WeakRefVolatileCache< K, V extends VolatileCacheValue > implements
if ( entry == null ) if ( entry == null )
return null; return null;
final V v = entry.getValue(); final CacheWeakReference ref = entry.ref;
if ( v != null && v.isValid() ) final V v = ref.get();
if ( v != null && ref.loaded == VALID )
return v; return v;
cleanUp( 50 ); cleanUp( 50 );
...@@ -147,8 +152,9 @@ public class WeakRefVolatileCache< K, V extends VolatileCacheValue > implements ...@@ -147,8 +152,9 @@ public class WeakRefVolatileCache< K, V extends VolatileCacheValue > implements
*/ */
final Entry entry = map.computeIfAbsent( key, k -> new Entry( k, loader ) ); final Entry entry = map.computeIfAbsent( key, k -> new Entry( k, loader ) );
V v = entry.getValue(); final CacheWeakReference ref = entry.ref;
if ( v != null && v.isValid() ) V v = ref.get();
if ( v != null && ref.loaded == VALID )
return v; return v;
cleanUp( 50 ); cleanUp( 50 );
...@@ -247,7 +253,7 @@ public class WeakRefVolatileCache< K, V extends VolatileCacheValue > implements ...@@ -247,7 +253,7 @@ public class WeakRefVolatileCache< K, V extends VolatileCacheValue > implements
if ( v != null ) if ( v != null )
return v; return v;
if ( entry.loaded != NOTLOADED ) if ( entry.ref.loaded != NOTLOADED )
{ {
map.remove( entry.key, entry ); map.remove( entry.key, entry );
return null; return null;
...@@ -270,14 +276,15 @@ public class WeakRefVolatileCache< K, V extends VolatileCacheValue > implements ...@@ -270,14 +276,15 @@ public class WeakRefVolatileCache< K, V extends VolatileCacheValue > implements
{ {
synchronized( entry ) synchronized( entry )
{ {
V v = entry.getValue(); final CacheWeakReference ref = entry.ref;
if ( v == null && entry.loaded != NOTLOADED ) V v = ref.get();
if ( v == null && ref.loaded != NOTLOADED )
{ {
map.remove( entry.key, entry ); map.remove( entry.key, entry );
return null; return null;
} }
if ( entry.loaded == VALID ) // v.isValid() if ( ref.loaded == VALID )
return v; return v;
final V vl = backingCache.getIfPresent( entry.key ); final V vl = backingCache.getIfPresent( entry.key );
...@@ -287,7 +294,7 @@ public class WeakRefVolatileCache< K, V extends VolatileCacheValue > implements ...@@ -287,7 +294,7 @@ public class WeakRefVolatileCache< K, V extends VolatileCacheValue > implements
return vl; return vl;
} }
if ( entry.loaded == NOTLOADED ) if ( ref.loaded == NOTLOADED )
{ {
v = entry.loader.createInvalid(); v = entry.loader.createInvalid();
entry.setInvalid( v ); entry.setInvalid( v );
...@@ -302,15 +309,16 @@ public class WeakRefVolatileCache< K, V extends VolatileCacheValue > implements ...@@ -302,15 +309,16 @@ public class WeakRefVolatileCache< K, V extends VolatileCacheValue > implements
{ {
synchronized( entry ) synchronized( entry )
{ {
V v = entry.getValue(); CacheWeakReference ref = entry.ref;
if ( v == null && entry.loaded != NOTLOADED ) V v = ref.get();
if ( v == null && ref.loaded != NOTLOADED )
{ {
// printEntryCollected( "map.remove getBudgeted 1", entry ); // printEntryCollected( "map.remove getBudgeted 1", entry );
map.remove( entry.key, entry ); map.remove( entry.key, entry );
return null; return null;
} }
if ( entry.loaded == VALID ) // v.isValid() if ( ref.loaded == VALID )
return v; return v;
enqueue( entry, hints ); enqueue( entry, hints );
...@@ -335,10 +343,11 @@ public class WeakRefVolatileCache< K, V extends VolatileCacheValue > implements ...@@ -335,10 +343,11 @@ public class WeakRefVolatileCache< K, V extends VolatileCacheValue > implements
budget.use( t, priority ); budget.use( t, priority );
} }
v = entry.getValue(); ref = entry.ref;
v = ref.get();
if ( v == null ) if ( v == null )
{ {
if ( entry.loaded == NOTLOADED ) if ( ref.loaded == NOTLOADED )
{ {
v = entry.loader.createInvalid(); v = entry.loader.createInvalid();
entry.setInvalid( v ); entry.setInvalid( v );
...@@ -360,15 +369,16 @@ public class WeakRefVolatileCache< K, V extends VolatileCacheValue > implements ...@@ -360,15 +369,16 @@ public class WeakRefVolatileCache< K, V extends VolatileCacheValue > implements
VolatileLoader< ? extends V > loader; VolatileLoader< ? extends V > loader;
synchronized( entry ) synchronized( entry )
{ {
final V v = entry.getValue(); final CacheWeakReference ref = entry.ref;
if ( v == null && entry.loaded != NOTLOADED ) final V v = ref.get();
if ( v == null && ref.loaded != NOTLOADED )
{ {
// printEntryCollected( "map.remove getBlocking 1", entry ); // printEntryCollected( "map.remove getBlocking 1", entry );
map.remove( entry.key, entry ); map.remove( entry.key, entry );
return null; return null;
} }
if ( entry.loaded == VALID ) // v.isValid() if ( ref.loaded == VALID ) // v.isValid()
return v; return v;
loader = entry.loader; loader = entry.loader;
...@@ -376,15 +386,16 @@ public class WeakRefVolatileCache< K, V extends VolatileCacheValue > implements ...@@ -376,15 +386,16 @@ public class WeakRefVolatileCache< K, V extends VolatileCacheValue > implements
final V vl = backingCache.get( entry.key, loader ); final V vl = backingCache.get( entry.key, loader );
synchronized( entry ) synchronized( entry )
{ {
final V v = entry.getValue(); final CacheWeakReference ref = entry.ref;
if ( v == null && entry.loaded != NOTLOADED ) final V v = ref.get();
if ( v == null && ref.loaded != NOTLOADED )
{ {
// printEntryCollected( "map.remove getBlocking 2", entry ); // printEntryCollected( "map.remove getBlocking 2", entry );
map.remove( entry.key, entry ); map.remove( entry.key, entry );
return null; return null;
} }
if ( entry.loaded == VALID ) // v.isValid() if ( ref.loaded == VALID ) // v.isValid()
return v; return v;
// entry.loaded == INVALID // entry.loaded == INVALID
...@@ -416,11 +427,11 @@ public class WeakRefVolatileCache< K, V extends VolatileCacheValue > implements ...@@ -416,11 +427,11 @@ public class WeakRefVolatileCache< K, V extends VolatileCacheValue > implements
*/ */
private synchronized void printEntryCollected( final String title, final Entry entry ) private synchronized void printEntryCollected( final String title, final Entry entry )
{ {
final String state = entry.loaded == 0 final String state = entry.ref.loaded == 0
? "NOTLOADED" ? "NOTLOADED"
: ( entry.loaded == 1 : ( entry.ref.loaded == 1
? "INVALID" ? "INVALID"
: ( entry.loaded == 2 : ( entry.ref.loaded == 2
? "VALID" ? "VALID"
: "UNDEFINED" ) ); : "UNDEFINED" ) );
System.out.println( title + " entry.loaded = " + state ); System.out.println( title + " entry.loaded = " + state );
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment