diff --git a/pom.xml b/pom.xml index a61c695cb201a0c2e026602af9233a204b449420..410704e7b097c36eb3b6c599801e19c2ca191865 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.scijava</groupId> <artifactId>pom-scijava</artifactId> - <version>26.0.0</version> + <version>28.0.0</version> <relativePath /> </parent> @@ -87,8 +87,10 @@ <stringtemplate.version>3.2.1</stringtemplate.version> <!-- TODO: Remove these version pins and update the code. --> - <bigdataviewer-core.version>3.0.3</bigdataviewer-core.version> - <imglib2.version>3.3.0</imglib2.version> + <bigdataviewer-core.version>9.0.3</bigdataviewer-core.version> + <imglib2.version>5.9.0</imglib2.version> + <imglib2-cache.version>1.0.0-beta-13</imglib2-cache.version> + <spim_data.version>2.2.4</spim_data.version> </properties> <repositories> diff --git a/src/main/java/bdv/server/CellHandler.java b/src/main/java/bdv/server/CellHandler.java index 1cb8682b2b339e9bfbf79896e1582f7c478cab24..9777bf3bd1b9185ab14536897b517c6443f6edaf 100644 --- a/src/main/java/bdv/server/CellHandler.java +++ b/src/main/java/bdv/server/CellHandler.java @@ -10,10 +10,15 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.concurrent.ExecutionException; import javax.imageio.ImageIO; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import net.imglib2.cache.CacheLoader; +import net.imglib2.cache.LoaderCache; +import net.imglib2.cache.ref.SoftRefLoaderCache; +import net.imglib2.img.cell.Cell; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.util.log.Log; @@ -26,12 +31,7 @@ import org.jdom2.output.XMLOutputter; import com.google.gson.GsonBuilder; import bdv.BigDataViewer; -import bdv.cache.CacheHints; -import bdv.cache.LoadingStrategy; -import bdv.img.cache.VolatileCell; import bdv.img.cache.VolatileGlobalCellCache; -import bdv.img.cache.VolatileGlobalCellCache.Key; -import bdv.img.cache.VolatileGlobalCellCache.VolatileCellLoader; import bdv.img.hdf5.Hdf5ImageLoader; import bdv.img.hdf5.Hdf5VolatileShortArrayLoader; import bdv.img.remote.AffineTransform3DJsonSerializer; @@ -49,11 +49,74 @@ public class CellHandler extends ContextHandler { private static final org.eclipse.jetty.util.log.Logger LOG = Log.getLogger( CellHandler.class ); - private final VolatileGlobalCellCache cache; + /** + * Key for a cell identified by timepoint, setup, level, and index + * (flattened spatial coordinate). + */ + public static class Key + { + private final int timepoint; + + private final int setup; + + private final int level; + + private final long index; + + private final String[] parts; + + /** + * Create a Key for the specified cell. Note that {@code cellDims} and + * {@code cellMin} are not used for {@code hashcode()/equals()}. + * + * @param timepoint + * timepoint coordinate of the cell + * @param setup + * setup coordinate of the cell + * @param level + * level coordinate of the cell + * @param index + * index of the cell (flattened spatial coordinate of the + * cell) + */ + public Key( final int timepoint, final int setup, final int level, final long index, final String[] parts ) + { + this.timepoint = timepoint; + this.setup = setup; + this.level = level; + this.index = index; + this.parts = parts; + + int value = Long.hashCode( index ); + value = 31 * value + level; + value = 31 * value + setup; + value = 31 * value + timepoint; + hashcode = value; + } + + @Override + public boolean equals( final Object other ) + { + if ( this == other ) + return true; + if ( !( other instanceof VolatileGlobalCellCache.Key ) ) + return false; + final Key that = ( Key ) other; + return ( this.index == that.index ) && ( this.timepoint == that.timepoint ) && ( this.setup == that.setup ) && ( this.level == that.level ); + } - private final Hdf5VolatileShortArrayLoader loader; + final int hashcode; - private final CacheHints cacheHints; + @Override + public int hashCode() + { + return hashcode; + } + } + + private final CacheLoader< Key, Cell< ? > > loader; + + private final LoaderCache< Key, Cell< ? > > cache; /** * Full path of the dataset xml file this {@link CellHandler} is serving. @@ -98,9 +161,20 @@ public class CellHandler extends ContextHandler final SequenceDescriptionMinimal seq = spimData.getSequenceDescription(); final Hdf5ImageLoader imgLoader = ( Hdf5ImageLoader ) seq.getImgLoader(); - cache = imgLoader.getCacheControl(); - loader = imgLoader.getShortArrayLoader(); - cacheHints = new CacheHints( LoadingStrategy.BLOCKING, 0, false ); + final Hdf5VolatileShortArrayLoader cacheArrayLoader = imgLoader.getShortArrayLoader(); + loader = key -> { + final int[] cellDims = new int[] { + Integer.parseInt( key.parts[ 5 ] ), + Integer.parseInt( key.parts[ 6 ] ), + Integer.parseInt( key.parts[ 7 ] ) }; + final long[] cellMin = new long[] { + Long.parseLong( key.parts[ 8 ] ), + Long.parseLong( key.parts[ 9 ] ), + Long.parseLong( key.parts[ 10 ] ) }; + return new Cell<>( cellDims, cellMin, cacheArrayLoader.loadArray( key.timepoint, key.setup, key.level, cellDims, cellMin ) ); + }; + + cache = new SoftRefLoaderCache<>(); // dataSetURL property is used for providing the XML file by replace // SequenceDescription>ImageLoader>baseUrl @@ -145,23 +219,18 @@ public class CellHandler extends ContextHandler final int timepoint = Integer.parseInt( parts[ 2 ] ); final int setup = Integer.parseInt( parts[ 3 ] ); final int level = Integer.parseInt( parts[ 4 ] ); - final Key key = new VolatileGlobalCellCache.Key( timepoint, setup, level, index ); - VolatileCell< ? > cell = cache.getLoadingVolatileCache().getIfPresent( key, cacheHints ); - if ( cell == null ) + final Key key = new Key( timepoint, setup, level, index, parts ); + short[] data; + try + { + final Cell< ? > cell = cache.get( key, loader ); + data = ( ( VolatileShortArray ) cell.getData() ).getCurrentStorageArray(); + } + catch ( ExecutionException e ) { - final int[] cellDims = new int[] { - Integer.parseInt( parts[ 5 ] ), - Integer.parseInt( parts[ 6 ] ), - Integer.parseInt( parts[ 7 ] ) }; - final long[] cellMin = new long[] { - Long.parseLong( parts[ 8 ] ), - Long.parseLong( parts[ 9 ] ), - Long.parseLong( parts[ 10 ] ) }; - cell = cache.getLoadingVolatileCache().get( key, cacheHints, new VolatileCellLoader<>( loader, timepoint, setup, level, cellDims, cellMin ) ); + data = new short[ 0 ]; } - @SuppressWarnings( "unchecked" ) - final short[] data = ( ( VolatileCell< VolatileShortArray > ) cell ).getData().getCurrentStorageArray(); final byte[] buf = new byte[ 2 * data.length ]; for ( int i = 0, j = 0; i < data.length; i++ ) { diff --git a/src/main/java/bdv/util/ThumbnailGenerator.java b/src/main/java/bdv/util/ThumbnailGenerator.java index 92c0f322bce7e29f9406fd1d063dba49b65e25f5..f8d64a61efc32e9f4be13b7bee888a998077ea9a 100644 --- a/src/main/java/bdv/util/ThumbnailGenerator.java +++ b/src/main/java/bdv/util/ThumbnailGenerator.java @@ -114,7 +114,7 @@ public class ThumbnailGenerator final int numGroups = 10; final ArrayList< SourceGroup > groups = new ArrayList< SourceGroup >( numGroups ); for ( int i = 0; i < numGroups; ++i ) - groups.add( new SourceGroup( "", null ) ); + groups.add( new SourceGroup( "" ) ); state = new ViewerState( sources, groups, numTimePoints ); if ( !sources.isEmpty() )