public final class RawGrowableArray
extends java.lang.Object
The memory format contains a header is as follows:
Byte Meaning -------------------------------------------- 0..3 Pointer to the growable block. Null if the number of records <= inlineRecordCount 4..7 Record [0] 8..11 Record [1] ... k...k+4 Record [inlineRecordCount-1]As shown above, the first few records are stored inline with the array. inlineRecordCount is a tunable parameter which may be 0. If there are fewer than inlineRecordCount records, there is no growable block and all records are stored in the header. Storing the first few records in the header is intended as an optimization for very small arrays in the case where small arrays are expected to be a common case. If there are fewer than inlineRecordCount records stored in the array, the size of the array is not stored explicitly. It is computed on demand by searching for the first null entry among the inline records.
The memory format for a growable block is as follows:
Byte Meaning
--------------------------------------------
0..3 Size of the array, including all inline records. This is also the index at which the next entry will
be inserted
4..7 Capacity of this growable block.
8..11 Record [n]
12..15 Record [n+1]
...
k...k+4 Record [blockSize-1]
The growable block itself begins with a 4-byte int holding the size of the array, followed by a 4-byte int holding
the capacity of the growable block. In the event that the array is larger than
GrowableBlockHeader#MAX_GROWABLE_SIZE enough to be using a metablock, there will be multiple growable blocks
in use. In this case, the size and capacity stored in the metablock is used for the array and the size and capacity
stored in each growable block will be filled in with 0s.
If capacity <= MAX_BLOCK_SIZE then this is a normal block containing a flat array of record pointers starting from the element numbered inlineRecordCount. If capacity > MAX_BLOCK_SIZE then then it is a metablock which holds record pointers to separate growable blocks, each of which holds exactly MAX_BLOCK_SIZE elements.
Every time an element is inserted in the array, the add method returns the element's index. Indices can be used to remove elements in constant time, but will be reassigned by the RawGrowableArray during removes by swapping the removed element with the last element in the array. If the owner of the array is keeping track of indices, it should update the relevant indices on remove.
The array itself is tightly packed. When an element is removed, the last element in the array is swapped into its location. Anyone keeping track of indices may rely on the fact that they are consecutive integers.
These arrays preserve insertion order until the first call to "remove". If element order matters, you should not remove individual elements but should instead destroy and rebuild the entire array.
Element additions and removals run in constant amortized time.
There are a lot of ints and longs used in the implementation of this class. In order to help clarify their function, they get the following suffixes:
| Constructor and Description |
|---|
RawGrowableArray(int inlineRecords) |
| Modifier and Type | Method and Description |
|---|---|
int |
add(Nd nd,
long address,
long value)
Adds the given value to the array.
|
void |
destruct(Nd nd,
long address) |
void |
ensureCapacity(Nd nd,
long address,
int desiredSize)
Ensures that the array contains at least enough space allocated to fit the given number of new elements.
|
long |
get(Nd nd,
long address,
int index)
Returns the element at the given index (nonzero).
|
int |
getCapacity(Nd nd,
long address) |
static int |
getMaxGrowableBlockSize() |
int |
getRecordSize()
Returns the record size for a RawGrowableSize with the given number of inline records
|
boolean |
isEmpty(Nd nd,
long address)
Returns true iff the size of the array is 0
|
long |
remove(Nd nd,
long address,
int index)
Removes an entry from the array, given an element index.
|
int |
size(Nd nd,
long address)
Returns the size of the array.
|
public static int getMaxGrowableBlockSize()
public int size(Nd nd, long address)
address - address of the arraypublic int add(Nd nd, long address, long value)
public long get(Nd nd, long address, int index)
public void ensureCapacity(Nd nd, long address, int desiredSize)
public long remove(Nd nd, long address, int index)
public int getRecordSize()
public void destruct(Nd nd, long address)
public boolean isEmpty(Nd nd, long address)
address - address of the arraypublic int getCapacity(Nd nd, long address)