public abstract class ConnectedObjectScanner
extends java.lang.Object
implements java.lang.Cloneable
Connected objects scanner: the class performing scanning and clearing connected objects, "drawn" on some ndimensional updatable bit matrix.
More precisely, let's consider an AlgART bit matrix
(Matrix
<? extends UpdatableBitArray
>).
The connected object is a connected component of the graph, built on the matrix,
where unit matrix elements are vertices, and neighbour unit elements are connected by edges.
In 2D case, we can consider that the matrix contains images of some objects:
unit bits (1) are white pixels, belonging to objects, zero bits (0) are black pixels of the background.
Then our term "connected objects" describes the white objects, separated by black space.
We define two kinds of connectivity: straight
and straightanddiagonal
. In the first case
(straight connectivity), two unit elements with coordinates
∑ i_{k}−j_{k}=1
For 2D matrices, this connectivity kind is also known as "4connectivity". It the second case (straightanddiagonal connectivity), two unit elements are neighbours if several (at least one) from their coordinates differ by 1 and all other coordinates are equal:
max (i_{k}−j_{k})=1
For 2D matrices, this connectivity kind is also known as "8connectivity".
The connectivity kind is described by ConnectivityType
class.
The instance of this class works with some concrete bit matrix
(Matrix
<? extends UpdatableBitArray
>),
named the scanned matrix, and with some concrete connectivity type (ConnectivityType
).
Both the scanned matrix and the connectivity type are specified while creating the instance.
This class allows to visit all elements of the scanner matrix,
belonging to one connected object, by its main
clear
method.
"Visiting" means that this method calls ConnectedObjectScanner.ElementVisitor.visit(long[], long)
method for every visited element, passing the index of the element
in the underlying array
of the matrix to that method,
maybe, together with its coordinates in the matrix
(if getting coordinates does not slow down the scanning algorithm).
Besides, the clear
method clears (sets to 0) all visited elements in the bit matrix.
But note: actual clearing may be not performed if forceClearing argument of this method
is false.
There are following methods allowing to create the instance of this class:
getBreadthFirstScanner(Matrix, ConnectivityType)
,getDepthFirstScanner(Matrix, ConnectivityType)
,getStacklessDepthFirstScanner(Matrix, ConnectivityType)
,getUncheckedBreadthFirstScanner(Matrix, ConnectivityType)
,getUncheckedDepthFirstScanner(Matrix, ConnectivityType)
,getUncheckedStacklessDepthFirstScanner(Matrix, ConnectivityType)
,clone()
.You can switch to another scanned bit matrix with the same dimensions by matrix(Matrix)
method.
You can use this instance (call its clear
method)
many times to scan different connected objects at one matrix.
You may use nextUnitBit(long[])
method to find next connected object
after scanning and clearing the previous one.
However, you must not use this instance after any modifications in the scanned matrix, performed by an external code. If you modify the matrix, you must create new instance of this class after this.
Note: this class works much faster (in several times)
if the scanned matrix is created by SimpleMemoryModel
.
So, if the matrix is not created by SimpleMemoryModel
and is not too large,
we recommend to create its clone by SimpleMemoryModel
and use this class for the clone.
Note: this class cannot process matrices with too large number of dimensions.
The maximal allowed number of dimensions is Matrix.MAX_DIM_COUNT_FOR_SOME_ALGORITHMS
,
that is more than enough for most situations.
This class does not use multithreading optimization, unlike
Arrays.copy(ArrayContext, UpdatableArray, Array)
and similar methods.
In other words, all methods of this class are executed in the current thread.
This class is not threadsafe, but is threadcompatible and can be synchronized manually, if multithread access is necessary. However, usually there are no reasons to use the same instance of this class in different threads: usually there is much better idea to create a separate instance for every thread.
Modifier and Type  Class and Description 

static interface 
ConnectedObjectScanner.ElementVisitor
Visitor of matrix elements.

static class 
ConnectedObjectScanner.MaskElementCounter
The simplest implementation of
ConnectedObjectScanner.ElementVisitor interface. 
Modifier and Type  Method and Description 

long 
clear(ArrayContext context,
ConnectedObjectScanner.ElementVisitor elementVisitor,
long... coordinates)
Equivalent to
clear(context, elementVisitor, coordinates, true) . 
long 
clear(ArrayContext context,
ConnectedObjectScanner.ElementVisitor elementVisitor,
long[] coordinates,
boolean forceClearing)
Visits all unit (1) elements of the matrix, belonging to the connected object containing
the element with the specified coordinates, calls
elementVisitor.
visit method for each element
and clears this element (UpdatableBitArray.clearBit(long) ). 
long 
clear(ArrayContext context,
long... coordinates)
Equivalent to
clear(context, null, coordinates, true) . 
long 
clear(ArrayContext context,
long[] coordinates,
boolean forceClearing)
Equivalent to
clear(context, null, coordinates, forceClearing) . 
long 
clearAllBySizes(ArrayContext context,
Matrix<? extends BitArray> mask,
long minNonClearedSize,
long maxNonClearedSize)
Clears all elements of all connected objects in the matrix, the volume of which
is less than minNonClearedSize or greater than maxNonClearedSize.

long 
clearAllConnected(ArrayContext context,
Matrix<? extends UpdatableBitArray> secondaryMatrix)
Clears all elements of all connected objects in the
matrix, corresponding to this object ,
and also clears all objects in the passed second matrix with same sizes, which are connected with at least
one unit (1) element of the first matrix. 
abstract ConnectedObjectScanner 
clone()
Creates the instance, implementing the same algorithm with the same connectivity kind
an the same scanned matrix as this one.

ConnectivityType 
connectivityType()
Returns the connectivity kind, used by this object.

void 
freeResources(ArrayContext context)
If there are some AlgART arrays or matrices, allocated by this object for storing temporary data,
this method calls
Array.freeResources(context) /
Matrix.freeResources(context) methods for them. 
static ConnectedObjectScanner 
getBreadthFirstScanner(Matrix<? extends UpdatableBitArray> matrix,
ConnectivityType connectivityType)
Creates an instance of this class, implementing the classic breadthfirst scanning algorithm.

static ConnectedObjectScanner 
getDepthFirstScanner(Matrix<? extends UpdatableBitArray> matrix,
ConnectivityType connectivityType)
Creates an instance of this class, implementing the classic depthfirst scanning algorithm.

static ConnectedObjectScanner 
getStacklessDepthFirstScanner(Matrix<? extends UpdatableBitArray> matrix,
ConnectivityType connectivityType)
Creates an instance of this class, implementing the classic depthfirst scanning algorithm,
but not using an explicit stack.

static ConnectedObjectScanner 
getUncheckedBreadthFirstScanner(Matrix<? extends UpdatableBitArray> matrix,
ConnectivityType connectivityType)
An analog of
getBreadthFirstScanner(net.algart.arrays.Matrix<? extends net.algart.arrays.UpdatableBitArray>, net.algart.matrices.scanning.ConnectivityType) method, returning the instance, which works correctly
only if all matrix elements with zero and maximal coordinates are zero. 
static ConnectedObjectScanner 
getUncheckedDepthFirstScanner(Matrix<? extends UpdatableBitArray> matrix,
ConnectivityType connectivityType)
An analog of
getDepthFirstScanner(net.algart.arrays.Matrix<? extends net.algart.arrays.UpdatableBitArray>, net.algart.matrices.scanning.ConnectivityType) method, returning the instance, which works correctly
only if all matrix elements with zero and maximal coordinates are zero. 
static ConnectedObjectScanner 
getUncheckedStacklessDepthFirstScanner(Matrix<? extends UpdatableBitArray> matrix,
ConnectivityType connectivityType)
An analog of
getStacklessDepthFirstScanner(net.algart.arrays.Matrix<? extends net.algart.arrays.UpdatableBitArray>, net.algart.matrices.scanning.ConnectivityType) method, returning the instance, which works correctly
only if all matrix elements with zero and maximal coordinates are zero. 
Matrix<? extends UpdatableBitArray> 
matrix()
Returns a reference to the matrix, scanned by this object.

void 
matrix(Matrix<? extends UpdatableBitArray> matrix)
Changes the current scanned bit matrix for this instance.

long 
maxUsedMemory()
Returns the maximal amount of work memory (in bytes), that was allocated by this instance
allocated during its work since its creation or calling
resetUsedMemory() method. 
boolean 
nextUnitBit(long[] coordinates)
Finds the next unit matrix element, starting from coordinates, saves the result
in the same coordinates array and returns true if such element was found.

void 
resetUsedMemory()
Resets the memory counter returned by
maxUsedMemory() method. 
void 
updateProgress(ArrayContext context,
long... coordinates)

public static ConnectedObjectScanner getBreadthFirstScanner(Matrix<? extends UpdatableBitArray> matrix, ConnectivityType connectivityType)
In this case, the clear
method uses a queue,
stored in an AlgART array, created via the memory model
returned by the array context
.
While the queue is little enough, the algorithm stores it in a usual Java array instead of AlgART array.
In typical situations, the queue stays very little (several kilobytes).
It is a good choice for most situations. But
getStacklessDepthFirstScanner(Matrix, ConnectivityType)
method
usually works faster for little matrices: see comments to that method.
matrix
 the matrix that will be scanned and cleared by the created instance.connectivityType
 the connectivity kind used by the created instance.java.lang.NullPointerException
 if matrix or connectivityType argument is null.java.lang.IllegalArgumentException
 if matrix.dimCount()
> Matrix.MAX_DIM_COUNT_FOR_SOME_ALGORITHMS
.getUncheckedBreadthFirstScanner(Matrix, ConnectivityType)
public static ConnectedObjectScanner getDepthFirstScanner(Matrix<? extends UpdatableBitArray> matrix, ConnectivityType connectivityType)
In this case, the clear
method uses a stack,
stored in an AlgART array, created via the memory model
returned by the array context
.
While the stack is little enough, the algorithm stores it in a usual Java array instead of AlgART array.
Unlike the breadthfirst
search,
this algorithm often requires large stack. If the matrix contains large areas ("objects"),
filled by 1, the length of stack is comparable with the number of unit elements in such areas,
if the worst case (1filled matrix) — the total number of matrix elements.
Every stack element require several long values, so, the total occupied work memory
can be in 100 and more times larger, than the memory occupied by the source bit matrix.
The main advantage of this method is the wellspecified order of visiting elements, defined by the depthfirst search. It can be a good choice for scanning thin "skeletons", when the connectivity graph is a tree.
matrix
 the matrix that will be scanned and cleared by the created instance.connectivityType
 the connectivity kind used by the created instance.java.lang.NullPointerException
 if matrix or connectivityType argument is null.java.lang.IllegalArgumentException
 if matrix.dimCount()
> Matrix.MAX_DIM_COUNT_FOR_SOME_ALGORITHMS
.getUncheckedDepthFirstScanner(Matrix, ConnectivityType)
public static ConnectedObjectScanner getStacklessDepthFirstScanner(Matrix<? extends UpdatableBitArray> matrix, ConnectivityType connectivityType)
In this case, the first call of clear
method allocates a temporary work matrix
with the same dimensions as the passed one. Then this matrix is used for saving information,
necessary to perform correct depthfirst search. The element type of the work matrix are byte,
if connectivityType.numberOfNeighbours
(matrix.dimCount()
)<128,
or short in other cases (very exotic situation).
If the total number of matrix elements
(array()
.length()
Arrays.SystemSettings.maxTempJavaMemory()
,
then the work matrix is allocated by SimpleMemoryModel
.
In other case, it is allocated by
getMemoryModel()
clear
method).
This is the only algorithm, that always uses the constant amount of memory: in 8 times larger
than the source bit matrix occupies (in 16 times for high number of dimensions).
If the work matrix is allocated by SimpleMemoryModel
,
it is the quickest algorithm and the best choice in most situations.
But if the matrix is large enough
(Arrays.SystemSettings.maxTempJavaMemory()
clear
method
offers nonsimple memory model, the breadthfirst scanning algorithm
is usually better choice.
Please note: in this case the first call of clear
method requires essential time
for allocating and initializing work matrix. If you need to scan only one connected object,
breadthfirst scanning algorithm
will probably be better choice.
matrix
 the matrix that will be scanned and cleared by the created instance.connectivityType
 the connectivity kind used by the created instance.java.lang.NullPointerException
 if matrix or connectivityType argument is null.java.lang.IllegalArgumentException
 if matrix.dimCount()
> Matrix.MAX_DIM_COUNT_FOR_SOME_ALGORITHMS
.getUncheckedStacklessDepthFirstScanner(Matrix, ConnectivityType)
public static ConnectedObjectScanner getUncheckedBreadthFirstScanner(Matrix<? extends UpdatableBitArray> matrix, ConnectivityType connectivityType)
getBreadthFirstScanner(net.algart.arrays.Matrix<? extends net.algart.arrays.UpdatableBitArray>, net.algart.matrices.scanning.ConnectivityType)
method, returning the instance, which works correctly
only if all matrix elements with zero and maximal coordinates are zero.
More precisely, this method may be used only if one of the following conditions is complied:
dim
(j)1,
is zero;dim
(j)1,
is zero, and also each matrix bit with last coordinate
i_{n−1}=0 or i_{n−1}=1 is zero
(first two lines in the 2dimensional case).
Here n=matrix.dimCount()
is the number of matrix dimensions.
If both conditions are not complied, the clear
method of the returned instance
can visit (and clear) some extra elements or can throw unexpected IndexOutOfBoundsException
while scanning. (And it is the only undesirable effect; no other data will be damaged,
no invariants will be violated.)
The scanner, returned by this method, works faster than the scanner,
returned by getBreadthFirstScanner(Matrix, ConnectivityType)
.
So, if possible, we recommend to provide the required condition and to use this method.
The simplest way to provide the necessary 1st condition
is the following call:
matrix.where all from[k]==1 and to[k]=matrix.subMatrix
(from, to,Matrix.ContinuationMode.ZERO_CONSTANT
);
dim
(k)+1.
Note: please copy the matrix, created by this
subMatrix
call,
to some newly created bit matrix,
in other case the performance will not be improved (because access to each element of the submatrix is slow).matrix
 the matrix that will be scanned and cleared by the created instance.connectivityType
 the connectivity kind used by the created instance.java.lang.NullPointerException
 if matrix or connectivityType argument is null.java.lang.IllegalArgumentException
 if matrix.dimCount()
> Matrix.MAX_DIM_COUNT_FOR_SOME_ALGORITHMS
.public static ConnectedObjectScanner getUncheckedDepthFirstScanner(Matrix<? extends UpdatableBitArray> matrix, ConnectivityType connectivityType)
getDepthFirstScanner(net.algart.arrays.Matrix<? extends net.algart.arrays.UpdatableBitArray>, net.algart.matrices.scanning.ConnectivityType)
method, returning the instance, which works correctly
only if all matrix elements with zero and maximal coordinates are zero.
More precisely, this method may be used only if one of the following conditions is complied:
dim
(j)1,
is zero;dim
(j)1,
is zero, and also each matrix bit with last coordinate
i_{n−1}=0 or i_{n−1}=1 is zero
(first two lines in the 2dimensional case).
Here n=matrix.dimCount()
is the number of matrix dimensions.
If both conditions are not complied, the clear
method of the returned instance
can visit (and clear) some extra elements or can throw unexpected IndexOutOfBoundsException
while scanning. (And it is the only undesirable effect; no other data will be damaged,
no invariants will be violated.)
The scanner, returned by this method, works faster than the scanner,
returned by getDepthFirstScanner(Matrix, ConnectivityType)
.
So, if possible, we recommend to provide the required condition and to use this method.
The simplest way to provide the necessary 1st condition
is the following call:
matrix.where all from[k]==1 and to[k]=matrix.subMatrix
(from, to,Matrix.ContinuationMode.ZERO_CONSTANT
);
dim
(k)+1.
Note: please copy the matrix, created by this
subMatrix
call,
to some newly created bit matrix,
in other case the performance will not be improved (because access to each element of the submatrix is slow).matrix
 the matrix that will be scanned and cleared by the created instance.connectivityType
 the connectivity kind used by the created instance.java.lang.NullPointerException
 if matrix or connectivityType argument is null.java.lang.IllegalArgumentException
 if matrix.dimCount()
> Matrix.MAX_DIM_COUNT_FOR_SOME_ALGORITHMS
.public static ConnectedObjectScanner getUncheckedStacklessDepthFirstScanner(Matrix<? extends UpdatableBitArray> matrix, ConnectivityType connectivityType)
getStacklessDepthFirstScanner(net.algart.arrays.Matrix<? extends net.algart.arrays.UpdatableBitArray>, net.algart.matrices.scanning.ConnectivityType)
method, returning the instance, which works correctly
only if all matrix elements with zero and maximal coordinates are zero.
More precisely, this method may be used only if one of the following conditions is complied:
dim
(j)1,
is zero;dim
(j)1,
is zero, and also each matrix bit with last coordinate
i_{n−1}=0 or i_{n−1}=1 is zero
(first two lines in the 2dimensional case).
Here n=matrix.dimCount()
is the number of matrix dimensions.
If both conditions are not complied, the clear
method of the returned instance
can visit (and clear) some extra elements or can throw unexpected IndexOutOfBoundsException
while scanning. (And it is the only undesirable effect; no other data will be damaged,
no invariants will be violated.)
The scanner, returned by this method, works faster than the scanner,
returned by getStacklessDepthFirstScanner(Matrix, ConnectivityType)
.
So, if possible, we recommend to provide the required condition and to use this method.
The simplest way to provide the necessary 1st condition
is the following call:
matrix.where all from[k]==1 and to[k]=matrix.subMatrix
(from, to,Matrix.ContinuationMode.ZERO_CONSTANT
);
dim
(k)+1.
Note: please copy the matrix, created by this
subMatrix
call,
to some newly created bit matrix,
in other case the performance will not be improved (because access to each element of the submatrix is slow).matrix
 the matrix that will be scanned and cleared by the created instance.connectivityType
 the connectivity kind used by the created instance.java.lang.NullPointerException
 if matrix or connectivityType argument is null.java.lang.IllegalArgumentException
 if matrix.dimCount()
> Matrix.MAX_DIM_COUNT_FOR_SOME_ALGORITHMS
.public abstract ConnectedObjectScanner clone()
maxUsedMemory()
value as this one.
If this instance allocated some temporary buffers, they are not inherited:
the returned instance will allocate and use its own temporary buffers.clone
in class java.lang.Object
public void matrix(Matrix<? extends UpdatableBitArray> matrix)
dimensions
as the current one
.matrix
 new matrix that will be scanned and cleared by this instance.java.lang.NullPointerException
 if the argument is null.SizeMismatchException
 if the dimensions of the passed matrix
differ from the dimensions of the current one.matrix()
public Matrix<? extends UpdatableBitArray> matrix()
matrix(Matrix)
method.public ConnectivityType connectivityType()
public boolean nextUnitBit(long[] coordinates)
If clear(net.algart.arrays.ArrayContext, net.algart.matrices.scanning.ConnectedObjectScanner.ElementVisitor, long[], boolean)
method was never called with forceClearing=false,
this method is equivalent to the following operators:
long from = matrix.index
(coordinates); long index =matrix()
.array().indexOf
(from,matrix()
.size()
, true); if (index == 1) { return false; } else { matrix.coordinates(index, coordinates); return true; }
coordinates
 coordinates of some matrix element;
the coordinates of the next unit element will be saved here.java.lang.NullPointerException
 if coordinate argument is null.java.lang.IllegalArgumentException
 if coordinate.length is not equal to
matrix()
.dimCount()
.java.lang.IndexOutOfBoundsException
 if some coordinates are out of the scanned matrix
.public long clear(ArrayContext context, ConnectedObjectScanner.ElementVisitor elementVisitor, long[] coordinates, boolean forceClearing)
visit
method for each element
and clears this element (UpdatableBitArray.clearBit(long)
).
Returns the number of visited elements.
If the element with the specified coordinates is zero, does nothing and returns 0.
However, if forceClearing argument is false, this method
may skip actual clearing the visited elements in the scanned matrix,
but clear bits in some internal buffer instead.
In this case, the nextUnitBit(long[])
method will work as if the bits was actually cleared.
This mode is useful if you don't really need to clear bits in the source matrix,
but only need to visit all unit elements: this mode can improve performance.
If forceClearing argument is true, the behavior is strict:
all visited elements will be immediately cleared in the scanned matrix.
The elementVisitor.visit
method is called before clearing the element.
The elementVisitor argument may be null: then this method only clears the elements of the connected object. It may be enough if your only intention is to count the elements of the connected object.
The order of visiting elements is not specified and depends on concrete implementation of this class.
This method never modifies the passed coordinates array: it is cloned in the beginning of the method and is not used after this. It can be important in a case of multithread access.
context
 the context of scanning; may be null, then will be ignored.
The main purpose of the context in most implementation is to allow interruption
of this method via ArrayContext.checkInterruption()
and to allocate
work memory via ArrayContext.getMemoryModel()
.
This method does not try to update execution progress via the context:
its methods ArrayContext.updateProgress(net.algart.arrays.ArrayContext.Event)
and
ArrayContext.checkInterruptionAndUpdateProgress(java.lang.Class<?>, long, long)
are not called.elementVisitor
 the visitor, called for every visited element;
may be null, then will be ignored.coordinates
 the coordinates of some matrix element, belonging to the connected object
that should be scanned.forceClearing
 false value allows the method not to perform actual clearing
bits in the scanned matrix; true value requires actual clearing.java.lang.NullPointerException
 if coordinates argument is null.java.lang.IllegalArgumentException
 if the number of passed coordinates (coordinates.length)
is not equal to the number of dimensions of the
scanned matrix
.java.lang.IndexOutOfBoundsException
 if some coordinates are out of the scanned matrix
.java.lang.OutOfMemoryError
 (low probability) if the form of the object is too complex and there is
not enough memory to allocate necessary data structures.public long clear(ArrayContext context, ConnectedObjectScanner.ElementVisitor elementVisitor, long... coordinates)
clear(context, elementVisitor, coordinates, true)
.context
 the context of scanning; may be null, then will be ignored.
The main purpose of the context in most implementation is to allow interruption
of this method via ArrayContext.checkInterruption()
and to allocate
work memory via ArrayContext.getMemoryModel()
.elementVisitor
 the visitor, called for every visited element;
may be null, then will be ignored.coordinates
 the coordinates of some matrix element, belonging to the connected object
that should be scanned.java.lang.NullPointerException
 if coordinates argument is null.java.lang.IllegalArgumentException
 if the number of passed coordinates (coordinates.length)
is not equal to the number of dimensions of the
scanned matrix
.java.lang.IndexOutOfBoundsException
 if some coordinates are out of the scanned matrix
.java.lang.OutOfMemoryError
 (low probability) if the form of the object is too complex and there is
not enough memory to allocate necessary data structures.public long clear(ArrayContext context, long[] coordinates, boolean forceClearing)
clear(context, null, coordinates, forceClearing)
.context
 the context of scanning; may be null, then will be ignored.
The main purpose of the context in most implementation is to allow interruption
of this method via ArrayContext.checkInterruption()
and to allocate
work memory via ArrayContext.getMemoryModel()
.coordinates
 the coordinates of some matrix element, belonging to the connected object
that should be scanned.forceClearing
 false value allows the method not to perform actual clearing
bits in the scanned matrix; true value requires actual clearing.java.lang.NullPointerException
 if coordinates argument is null.java.lang.IllegalArgumentException
 if the number of passed coordinates (coordinates.length)
is not equal to the number of dimensions of the
scanned matrix
.java.lang.IndexOutOfBoundsException
 if some coordinates are out of the scanned matrix
.public long clear(ArrayContext context, long... coordinates)
clear(context, null, coordinates, true)
.context
 the context of scanning; may be null, then will be ignored.
The main purpose of the context in most implementation is to allow interruption
of this method via ArrayContext.checkInterruption()
and to allocate
work memory via ArrayContext.getMemoryModel()
.coordinates
 the coordinates of some matrix element, belonging to the connected object
that should be scanned.java.lang.NullPointerException
 if coordinates argument is null.java.lang.IllegalArgumentException
 if the number of passed coordinates (coordinates.length)
is not equal to the number of dimensions of the
scanned matrix
.java.lang.IndexOutOfBoundsException
 if some coordinates are out of the scanned matrix
.java.lang.OutOfMemoryError
 (low probability) if the form of the object is too complex and there is
not enough memory to allocate necessary data structures.public long clearAllBySizes(ArrayContext context, Matrix<? extends BitArray> mask, long minNonClearedSize, long maxNonClearedSize)
clear
method)
— if the mask argument is null;If mask matrix is not null, it must have the same dimensions as the
scanned matrix
.
This method creates a temporary copy of the scanned matrix
and performs a loop of nextUnitBit(long[])
and clear
methods.
The temporary matrix is allocated while the first call of this method and used again in the further calls.
context
 the context of scanning; may be null, then will be ignored.mask
 the bit mask, on which the volume should be counted; may be null,
then the volume is the full number of elements in connected objects.minNonClearedSize
 minimal volume of connected objects that will not be cleared.maxNonClearedSize
 maximal volume of connected objects that will not be cleared.SizeMismatchException
 if mask!=null, and mask and the scanned matrix
have different dimensions.public long clearAllConnected(ArrayContext context, Matrix<? extends UpdatableBitArray> secondaryMatrix)
matrix, corresponding to this object
,
and also clears all objects in the passed second matrix with same sizes, which are connected with at least
one unit (1) element of the first matrix. In other words, this method just calls
clear
method for coordinates, corresponding to all unit
elements of the first matrix, in a clone
of this scanner,
where the processed matrix is replaced
with secondaryMatrix.context
 the context of scanning; may be null, then will be ignored.secondaryMatrix
 the second matrix, where this method clears all objects connected with some objects
in the matrix, corresponding to this object.java.lang.NullPointerException
 if secondaryMatrix argument is null.SizeMismatchException
 if secondaryMatrix and the scanned matrix have different dimensions.public final void updateProgress(ArrayContext context, long... coordinates)
matrix()
.size()
, matrix()
.index
(coordinates))The method can be useful while sequentially scanning the matrix via a loop of
clear
and nextUnitBit
calls.
context
 the context of execution;
may be null, then it will be ignored.coordinates
 coordinates of currently scanned matrix element.public long maxUsedMemory()
resetUsedMemory()
method.
Can be used for profiling or debugging needs.public void resetUsedMemory()
maxUsedMemory()
method.public void freeResources(ArrayContext context)
Array.freeResources(context)
/
Matrix.freeResources(context)
methods for them.
This method may be used in situations when the instance of this object has long time life and will be reused in future.
context
 the context of execution; may be null, then it will be ignored.