Class SemisparseByteArray
Notionally, the array is 2 to the power 64 bytes in size. Only the initialized values are actually stored. Uninitialized indices are assumed to have the value 0. Naturally, this implementation works best when the array is largely uninitialized. For efficient use, isolated initialized values should be avoided. Rather, an entire range should be initialized at the same time.
On a number line, the initialized indices of a semisparse array might be depicted:
----- --------- - ------ ---
In contrast, the same for a sparse array might be depicted:
- -- - - - --- -- - -
This implementation is well-suited for memory caches where the memory is accessed by reading ranges instead of individual bytes. Because consecutive reads and writes tend to occur in a common locality, caches using a semisparse array may perform well.
This implementation is also thread-safe. Any thread needing exclusive access for multiple reads and/or writes, e.g., to implement a compare-and-set operation, must apply additional synchronization.
-
Field Summary
Modifier and TypeFieldDescriptionstatic final int
The size of blocks used internally to store array values -
Constructor Summary
ModifierConstructorDescriptionprotected
SemisparseByteArray
(Map<Long, byte[]> blocks, ULongSpan.MutableULongSpanSet defined) -
Method Summary
Modifier and TypeMethodDescriptionvoid
clear()
Clear the arrayint
contiguousAvailableAfter
(long loc) Check how many contiguous bytes are available starting at the given addressfork()
void
getData
(long loc, byte[] data) Copy a range of data from the semisparse array into the given byte arrayvoid
getData
(long loc, byte[] data, int offset, int length) Copy a range of data from the semisparse array into a portion of the given byte arraygetInitialized
(long a, long b) Enumerate the initialized ranges within the given rangegetUninitialized
(long a, long b) Enumerate the uninitialized ranges within the given rangeboolean
isInitialized
(long a) Check if an index is initializedboolean
isInitialized
(long a, long b) Check if a range is completely initializedvoid
putAll
(SemisparseByteArray from) Copy the contents on another semisparse array into this onevoid
putData
(long loc, byte[] data) Initialize or modify a range of the array by copying from a given arrayvoid
putData
(long loc, byte[] data, int offset, int length) Initialize or modify a range of the array by copying a portion from a given array
-
Field Details
-
BLOCK_SIZE
public static final int BLOCK_SIZEThe size of blocks used internally to store array values- See Also:
-
-
Constructor Details
-
SemisparseByteArray
public SemisparseByteArray() -
SemisparseByteArray
-
-
Method Details
-
fork
-
clear
public void clear()Clear the arrayAll indices will be uninitialized after this call, just as it was immediately after construction
-
getData
public void getData(long loc, byte[] data) Copy a range of data from the semisparse array into the given byte array- Parameters:
loc
- the index to begin copying data outdata
- the array to copy data into- See Also:
-
getData
public void getData(long loc, byte[] data, int offset, int length) Copy a range of data from the semisparse array into a portion of the given byte arrayCopies
length
bytes of data from the semisparse array starting at indexloc
intodata
starting at indexoffset
. All initialized portions within the requested region are copied. The uninitialized portions may be treated as zeroes or not copied at all. Typically, the destination array has been initialized to zero by the caller, such that all uninitialized portions are zero. To avoid fetching uninitialized data, usecontiguousAvailableAfter(long)
as an upper bound on the length.- Parameters:
loc
- the index to begin copying data outdata
- the array to copy data intooffset
- the offset into the destination arraylength
- the length of data to read
-
getInitialized
Enumerate the initialized ranges within the given rangeThe given range is interpreted as closed, i.e., [a, b].
- Parameters:
a
- the lower-bound, inclusive, of the rangeb
- the upper-bound, inclusive, of the range- Returns:
- the set of initialized ranges
-
isInitialized
public boolean isInitialized(long a, long b) Check if a range is completely initializedThe given range is interpreted as closed, i.e., [a, b].
- Parameters:
a
- the lower-bound, inclusive, of the rangeb
- the upper-bound, inclusive, of the range- Returns:
- true if all indices in the range are initialized, false otherwise
-
isInitialized
public boolean isInitialized(long a) Check if an index is initialized- Parameters:
a
- the index to check- Returns:
- true if the index is initialized, false otherwise
-
getUninitialized
Enumerate the uninitialized ranges within the given rangeThe given range is interpreted as closed, i.e., [a, b].
- Parameters:
a
- the lower-bound, inclusive, of the rangeb
- the upper-bound, inclusive, of the range- Returns:
- the set of uninitialized ranges
-
putData
public void putData(long loc, byte[] data) Initialize or modify a range of the array by copying from a given array- Parameters:
loc
- the index of the semisparse array to begin copying intodata
- the data to copy- See Also:
-
putData
public void putData(long loc, byte[] data, int offset, int length) Initialize or modify a range of the array by copying a portion from a given array- Parameters:
loc
- the index of the semisparse array to begin copying intodata
- the source array to copy fromoffset
- the offset of the source array to begin copying fromlength
- the length of data to copy
-
putAll
Copy the contents on another semisparse array into this one- Parameters:
from
- the source array
-
contiguousAvailableAfter
public int contiguousAvailableAfter(long loc) Check how many contiguous bytes are available starting at the given address- Parameters:
loc
- the starting offset- Returns:
- the number of contiguous defined bytes following
-