From 6e1b138ff95e36299bce8f099a06a5e5ad84f89b Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Mon, 6 Feb 2023 17:05:11 +0100 Subject: [PATCH] Postpone Cell linking to CellRandomAccess.get() Previously the CellRandomAccess would link Cell data to the Type as soon as the RA is positioned in a new Cell. Specifically, for LazyCellImgs this would trigger loading of the Cell (potentially unnecessary). This addresses #252. --- .../java/net/imglib2/img/cell/CellGrid.java | 32 +++++++++++- .../imglib2/img/cell/CellRandomAccess.java | 51 ++++++++----------- 2 files changed, 53 insertions(+), 30 deletions(-) diff --git a/src/main/java/net/imglib2/img/cell/CellGrid.java b/src/main/java/net/imglib2/img/cell/CellGrid.java index 8b2cecdbe..40e75811f 100644 --- a/src/main/java/net/imglib2/img/cell/CellGrid.java +++ b/src/main/java/net/imglib2/img/cell/CellGrid.java @@ -34,13 +34,13 @@ package net.imglib2.img.cell; import java.util.Arrays; -import java.util.Iterator; import net.imglib2.Cursor; import net.imglib2.FinalInterval; import net.imglib2.FlatIterationOrder; import net.imglib2.Interval; import net.imglib2.IterableInterval; +import net.imglib2.Localizable; import net.imglib2.Point; import net.imglib2.Positionable; import net.imglib2.RandomAccess; @@ -337,6 +337,36 @@ public void getCellPosition( final long[] position, final Positionable cellPos ) cellPos.setPosition( position[ d ] / cellDimensions[ d ], d ); } + /** + * Compute all cell-related coordinates/sizes required by CellRandomAccess. + * + * @param position + * current image position + * @param cellSteps + * allocation steps for cell are written here. + * @param cellMin + * offset of the cell in image coordinates are written here. + * @param cellMax is set to the + * max of the cell in image coordinates are written here. + * @return index within the cell. + */ + int getCellCoordinates( final long[] position, final int[] cellSteps, final long[] cellMin, final long[] cellMax ) + { + int steps = 1; + int i = 0; + for ( int d = 0; d < n; ++d ) + { + final long gridPos = position[ d ] / cellDimensions[ d ]; + final int cellDim = ( gridPos + 1 == numCells[ d ] ) ? borderSize[ d ] : cellDimensions[ d ]; + cellMin[ d ] = gridPos * cellDimensions[ d ]; + cellMax[ d ] = cellMin[ d ] + cellDim - 1; + cellSteps[ d ] = steps; + i += steps * ( position[ d ] - cellMin[ d ] ); + steps *= cellDim; + } + return i; + } + @Override public int hashCode() { diff --git a/src/main/java/net/imglib2/img/cell/CellRandomAccess.java b/src/main/java/net/imglib2/img/cell/CellRandomAccess.java index e5f34c880..01d2869d6 100644 --- a/src/main/java/net/imglib2/img/cell/CellRandomAccess.java +++ b/src/main/java/net/imglib2/img/cell/CellRandomAccess.java @@ -34,6 +34,7 @@ package net.imglib2.img.cell; +import java.util.Arrays; import net.imglib2.AbstractLocalizable; import net.imglib2.Localizable; import net.imglib2.RandomAccess; @@ -64,17 +65,16 @@ public class CellRandomAccess< T extends NativeType< T >, C extends Cell< ? > > protected final long[] dimensions; - protected int[] currentCellSteps; + protected final int[] currentCellSteps; - protected long[] currentCellMin; + protected final long[] currentCellMin; - protected long[] currentCellMax; + protected final long[] currentCellMax; protected boolean isOutOfBounds; - protected final long[] oobCellMin; + private boolean typeNeedsUpdate = true; - protected final long[] oobCellMax; /** * The current index of the type. It is faster to duplicate this here than @@ -95,13 +95,11 @@ protected CellRandomAccess( final CellRandomAccess< T, C > randomAccess ) cellDims = randomAccess.cellDims; dimensions = randomAccess.dimensions; - currentCellSteps = randomAccess.currentCellSteps; - currentCellMin = randomAccess.currentCellMin; - currentCellMax = randomAccess.currentCellMax; + currentCellSteps = randomAccess.currentCellSteps.clone(); + currentCellMin = randomAccess.currentCellMin.clone(); + currentCellMax = randomAccess.currentCellMax.clone(); isOutOfBounds = randomAccess.isOutOfBounds; - oobCellMin = randomAccess.oobCellMin; - oobCellMax = randomAccess.oobCellMax; index = randomAccess.index; if ( !isOutOfBounds ) @@ -123,14 +121,11 @@ public CellRandomAccess( final AbstractCellImg< T, ?, C, ? > img ) img.getCellGrid().cellDimensions( cellDims ); img.getCellGrid().imgDimensions( dimensions ); + currentCellSteps = new int[ n ]; + currentCellMin = new long[ n ]; + currentCellMax = new long[ n ]; + isOutOfBounds = false; - oobCellMin = new long[ n ]; - oobCellMax = new long[ n ]; - for ( int d = 0; d < n; ++d ) - { - oobCellMin[ d ] = Long.MAX_VALUE; - oobCellMax[ d ] = Long.MIN_VALUE; - } img.getCellGrid().getCellPosition( position, randomAccessOnCells ); updatePosition( false ); @@ -145,6 +140,11 @@ public C getCell() @Override public T get() { + if ( typeNeedsUpdate ) + { + typeNeedsUpdate = false; + type.updateContainer( this ); + } return type; } @@ -326,7 +326,7 @@ public void setPosition( final long pos, final int d ) { index += ( int ) ( pos - position[ d ] ) * currentCellSteps[ d ]; position[ d ] = pos; - if ( pos < currentCellMin[ d ] || pos > currentCellMax[ d ] ) + if ( position[ d ] < currentCellMin[ d ] || position[ d ] > currentCellMax[ d ] ) { randomAccessOnCells.setPosition( pos / cellDims[ d ], d ); updatePosition( position[ d ] < 0 || position[ d ] >= dimensions[ d ] ); @@ -452,8 +452,8 @@ private void updatePosition( final boolean movedOutOfBounds ) if ( movedOutOfBounds ) { isOutOfBounds = true; - currentCellMin = oobCellMin; - currentCellMax = oobCellMax; + Arrays.fill( currentCellMin, Long.MAX_VALUE ); + Arrays.fill( currentCellMax, Long.MIN_VALUE ); } else { @@ -470,15 +470,8 @@ private void updatePosition( final boolean movedOutOfBounds ) isOutOfBounds = false; grid.getCellPosition( position, randomAccessOnCells ); } - - final C cell = getCell(); - - currentCellSteps = cell.steps; - currentCellMin = cell.min; - currentCellMax = cell.max; - - index = cell.globalPositionToIndex( position ); - type.updateContainer( this ); + index = grid.getCellCoordinates( position, currentCellSteps, currentCellMin, currentCellMax ); + typeNeedsUpdate = true; } } }