getPackedIndex(int, int, boolean) method is used
to look up the byte-index corresponding to the given (set tree) value byte of the given virtual index, and can
be used to add entries to represent that byte as needed. As a succesful getPackedIndex(int, int, boolean)
may require a resizing of the array, it can throw a ResizeException to indicate that the requested
packed index cannot be found or added without a resize of the physical storage.
| Modifier and Type | Class and Description |
|---|---|
| pack-priv class | |
| pack-priv class | |
| private static class |
| Modifier and Type | Field and Description |
|---|---|
| private final boolean | |
| private static final int | |
| pack-priv static final int | |
| pack-priv static final int | |
| private static final int | |
| private static final int | |
| private static final int | |
| private static final int | |
| private static final int | |
| private static final int | PACKED_ARRAY_GROWTH_INCREMENT
The physical representation uses an insert-at-the-end mechanism for adding contents to the array. |
| private int | |
| private static final int | |
| private int | |
| private int |
| Access | Constructor and Description |
|---|---|
| pack-priv |
| Modifier and Type | Method and Description |
|---|---|
| pack-priv abstract long | |
| pack-priv long | Returns: the afterAddValue. ((afterAddValue & 0x100) != 0) indicates a carry.index of byte value to add to byteIndex, final byte byte value to add valueToAdd)add a byte value to a current byte value in the array |
| pack-priv abstract boolean | |
| pack-priv boolean | |
| private boolean | casIndexAtEntrySlot(final int entryIndex, final int slot, final short expectedIndexValue, final short newIndexValue)
|
| private boolean | casIndexAtEntrySlotIfNonZeroAndLessThan(final int entryIndex, final int slot, final short newIndexValue)
|
| pack-priv abstract boolean | |
| pack-priv abstract boolean | |
| pack-priv abstract void | |
| private void | consolidateEntry(final int
The shortIndex of the entry to be consolidated entryIndex)Consolidate entry with previous entry verison if one exists |
| private long | |
| private void | copyEntriesAtLevelFromOther(final AbstractPackedArrayContext other, final int otherLevelEntryIndex, final int levelEntryIndexPointer, final int otherIndexShift)
|
| pack-priv int | |
| private void | |
| private int | Returns: the updated index of the entry (-1 if epansion failed due to conflict)the index of the entry existingEntryIndex, final int index to the slot pointing to the entry (needs to be fixed up) entryPointerIndex, final int realtive [packed] index of slot being inserted into entry insertedSlotIndex, final int mask value fo slot being inserted insertedSlotMask, final boolean the level below this one is a leaf level nextLevelIsLeaf)Expand entry as indicated. |
| private int | |
| pack-priv byte | |
| pack-priv abstract long | |
| pack-priv short | |
| pack-priv abstract long | |
| private short | |
| pack-priv short | |
| pack-priv int | Returns: the byte-index corresponding to the given (set tree) value byte of the given virtual indexThe set tree number (0-7, 0 corresponding with the LSByte set tree) setNumber, final int The virtual index into the PackedArray virtualIndex, final boolean If true, will insert new set tree nodes as needed if they do not already exist insertAsNeeded)Get the byte-index (into the packed array) corresponding to a given (set tree) value byte of given virtual index. |
| private int | |
| pack-priv int | |
| pack-priv int | |
| pack-priv int | |
| pack-priv abstract int | |
| private short | |
| private int | |
| private int | |
| pack-priv int | |
| pack-priv int | |
| pack-priv abstract long | |
| pack-priv void | |
| pack-priv boolean | |
| pack-priv abstract void | |
| pack-priv abstract void | |
| private String | |
| pack-priv abstract int | |
| private int | |
| private int | |
| private String | |
| pack-priv Iterable | Returns: an Iterator over all non-Zero values in the arrayAn Iterator over all non-Zero values in the array |
| pack-priv void | |
| private String | |
| pack-priv abstract void | |
| private int | seekToPopulatedVirtualIndexStartingAtLevel(final int startingVirtualIndex, final int levelEntryIndex, final int indexShift)
|
| pack-priv void | |
| pack-priv void | |
| pack-priv abstract void | |
| private void | |
| private void | |
| private void | |
| private void | |
| pack-priv void | setValuePart(final int longIndex, final long valuePartAsLong, final long valuePartMask, final int valuePartShift)
|
| pack-priv void | |
| public String | |
| pack-priv abstract String |
| isPacked | back to summary |
|---|---|
| private final boolean isPacked | |
| LEAF_LEVEL_SHIFT | back to summary |
|---|---|
| private static final int LEAF_LEVEL_SHIFT | |
| MAX_SUPPORTED_PACKED_COUNTS_ARRAY_LENGTH | back to summary |
|---|---|
| pack-priv static final int MAX_SUPPORTED_PACKED_COUNTS_ARRAY_LENGTH | |
| MINIMUM_INITIAL_PACKED_ARRAY_CAPACITY | back to summary |
|---|---|
| pack-priv static final int MINIMUM_INITIAL_PACKED_ARRAY_CAPACITY | |
| NON_LEAF_ENTRY_HEADER_SIZE_IN_SHORTS | back to summary |
|---|---|
| private static final int NON_LEAF_ENTRY_HEADER_SIZE_IN_SHORTS | |
| NON_LEAF_ENTRY_PREVIOUS_VERSION_OFFSET | back to summary |
|---|---|
| private static final int NON_LEAF_ENTRY_PREVIOUS_VERSION_OFFSET | |
| NON_LEAF_ENTRY_SLOT_INDICATORS_OFFSET | back to summary |
|---|---|
| private static final int NON_LEAF_ENTRY_SLOT_INDICATORS_OFFSET | |
| NUMBER_OF_SETS | back to summary |
|---|---|
| private static final int NUMBER_OF_SETS | |
| PACKED_ARRAY_GROWTH_FRACTION_POW2 | back to summary |
|---|---|
| private static final int PACKED_ARRAY_GROWTH_FRACTION_POW2 | |
| PACKED_ARRAY_GROWTH_INCREMENT | back to summary |
|---|---|
| private static final int PACKED_ARRAY_GROWTH_INCREMENT The physical representation uses an insert-at-the-end mechanism for adding contents to the array. Any insertion will occur at the very end of the array, and any expansion of an element will move it to the end, leaving an empty slot behind. Terminology: long-word: a 64-bit-aligned 64 bit word short-word: a 16-bit-aligned 16 bit word byte: an 8-bit-aligned byte long-index: an index of a 64-bit-aligned word within the overall array (i.e. in multiples of 8 bytes) short-index: an index of a 16-bit aligned short within the overall array (i.e. in multiples of 2 bytes) byte-index: an index of an 8-bit aligned byte within the overall array (i.e. in multiples of 1 byte) The storage array stores long (64 bit) words. Lookups for the variuous sizes are done as such: long getAtLongIndex(int longIndex) { return array[longIndex]; } short getAtShortIndex(int shortIndex) { return (short)((array[shortIndex >> 2] >> (shortIndex & 0x3)) & 0xffff); } byte getAtByteIndex(int byteIndex) { return (byte)((array[byteIndex >> 3] >> (byteIndex & 0x7)) & 0xff); } [Therefore there is no dependence on byte endiannes of the underlying arhcitecture] Structure: The packed array captures values at virtual indexes in a collection of striped "set trees" (also called "sets"), with each set tree representing one byte of the value at the virtual index in question. As such, there are 8 sets in the array, each corresponding to a byte in the overall value being stored. Set 0 contains the LSByte of the value, and Set 7 contains the MSByte of the value. The array contents is comprised of thre types of entries: - The root indexes: A fixed size 8 short-words array of short indexes at the start of the array, containing the short-index of the root entry of each of the 8 set trees. - Non-Leaf Entires: Variable sized, 2-18 short-words entries representing non-leaf entries in a set tree. Non-Leaf entries comprise of a 2 short-word header containing a packed slot indicators bitmask and the (optional non-zero) index of previous version of the entry, followed by an array of 0-16 shortwords. The short-word found at a given slot in this array holds an index to an entry in the next level of the set tree. - Leaf Entries: comprised of long-words. Each byte [0-7] in the longword holds an actual value. Specifically, the byte-index of that LeafEntry byte in the array is the byte-index for the given set's byte value of a virtual index. If a given virtual index for a given set has no entry in a given set tree, the byte value for that set of that virtual index interpreted as 0. If a given set tree does not have an entry for a given virtual index, it is safe to assume that no higher significance set tree have one either. Non-leaf entries structure and mutation protocols: The structure of a Non-Leaf entry in the array can be roughly desctibed in terms of this C-stylre struct: struct nonLeafEntry { short packedSlotIndicators; short previousVersionIndex; short[] enrtrySlotsIndexes; } Non-leaf entries are 2-18 short-words in length, with the length determined by the number of bits set in the packedSlotIndicators short-word in the entry. The packed slot indicators short-word is a bit mask which represents the 16 possible next-level entries below the given entry, and has a bit set (to '1') for each slot that is actually populated with a next level entry. Each of the short-words in the enrtrySlots is associated with a specific active ('1') bit in the packedSlotIndicators short-word, and holds the index to the next level's entry associated with ta given path in the tree. [Note: the values in enrtrySlotsIndexes[] are short-indexes if the next level is not a leaf level, and long-indexes if the next level is a leaf.] Summary of Non-leaf entry use and replacement protocol: - No value in any enrtrySlotsIndexes[] array is ever initialized to a zero value. Zero values in enrtrySlotsIndexes[] can only appear through consolidation (see below). Once an enrtrySlotsIndexes[] slot is observed to contain a zero, it cannot change to a non-zero value. - Zero values encountered in enrtrySlotsIndexes[] arrays are never followed. If a zero value is found when looking for the index to a lower level entry during a tree walk, the tree walking operation is restarted from the root. - A Non-Leaf entry with an active (non zero index) previous version is never followed or expanded. Instead, any thread encountering a Non-leaf entry with an active previous version will consolidate the previous version with the current one. the consolidation opeartion will clear (zero) the previousVersionIndex, which will then allow the caller to continue with whatever use the thread was attempting to make of the entry. - Expansion of entries: Since entries hold only enough storage to represent currently populated paths below them in the set tree, any addition of entries at a lower level requires the expansion of the entry to make room for a larger enrtrySlotsIndexes array. Expansion allocates a new and larger entry structure, and populates the newly inserted slot in it with an index to a newly allocated next-level entry. It then links the newly expanded entry the previous entry structure via the previousVersionIndex field, and publishes the newly expanded entry by [atomically] replacing the "pointer index" to the previous entry (located at a higher level entry's slot, or in the root indexes) with a "pointer index" to the newly expanded entry structure. A failure to atomically publish a newly expanded entry (e.g. if the "pointer index" being replaced holds a value other than that in our not-yet-published previousVersionIndex) will restart the expansion operation from the beginning. When first published, a newly-visible expanded entry is immediately "usable" because it has an active, "not yet consolidated" previous version entry, and any user of the entry will first have to consolidate it. The expansion will follow publication of the expanded entry with a consolidation of the previous entry into the new one, clearing the previousVersionIndex field in the process, and enabling normal use of the expanded entry. - Concurrent consolidation: While expansion and consolidation are ongoing, other threads can be concurrently walking the set trees. Per the protocol stated here, any tree walk encountering a Non-Leaf entry with an active previous version will consolidate the entry before using it. Consolidation can of a given entry can occur concurrently by an an expanding thread and by multiple walking threads. - Consolidation of a a previous version entry into a current one is done by: - For each non-zero index in the previous version enrty, copy that index to the new assocaited entry slot in the entry, and CAS a zero in the old entry slot. If the CAS fails, repeat (including the zero check). - Once all entry slots in the previous version entry have been consolidated and zeroed, zero the index to the previous version entry. | |
| physicalLength | back to summary |
|---|---|
| private int physicalLength | |
| SET_0_START_INDEX | back to summary |
|---|---|
| private static final int SET_0_START_INDEX | |
| topLevelShift | back to summary |
|---|---|
| private int topLevelShift | |
| virtualLength | back to summary |
|---|---|
| private int virtualLength | |
| AbstractPackedArrayContext | back to summary |
|---|---|
| pack-priv AbstractPackedArrayContext(final int virtualLength, final int initialPhysicalLength) | |
| addAndGetAtUnpackedIndex | back to summary |
|---|---|
| pack-priv abstract long addAndGetAtUnpackedIndex(int index, long valueToAdd) | |
| addAtByteIndex | back to summary |
|---|---|
| pack-priv long addAtByteIndex(final int byteIndex, final byte valueToAdd) add a byte value to a current byte value in the array
| |
| casAtLongIndex | back to summary |
|---|---|
| pack-priv abstract boolean casAtLongIndex(int longIndex, long expectedValue, long newValue) | |
| casAtShortIndex | back to summary |
|---|---|
| pack-priv boolean casAtShortIndex(final int shortIndex, final short expectedValue, final short newValue) | |
| casIndexAtEntrySlot | back to summary |
|---|---|
| private boolean casIndexAtEntrySlot(final int entryIndex, final int slot, final short expectedIndexValue, final short newIndexValue) | |
| casIndexAtEntrySlotIfNonZeroAndLessThan | back to summary |
|---|---|
| private boolean casIndexAtEntrySlotIfNonZeroAndLessThan(final int entryIndex, final int slot, final short newIndexValue) | |
| casPopulatedLongLength | back to summary |
|---|---|
| pack-priv abstract boolean casPopulatedLongLength(int expectedPopulatedShortLength, int newPopulatedShortLength) | |
| casPopulatedShortLength | back to summary |
|---|---|
| pack-priv abstract boolean casPopulatedShortLength(int expectedPopulatedShortLength, int newPopulatedShortLength) | |
| clearContents | back to summary |
|---|---|
| pack-priv abstract void clearContents() | |
| consolidateEntry | back to summary |
|---|---|
| private void consolidateEntry(final int entryIndex) Consolidate entry with previous entry verison if one exists
| |
| contextLocalGetValueAtIndex | back to summary |
|---|---|
| private long contextLocalGetValueAtIndex(final int virtualIndex) | |
| copyEntriesAtLevelFromOther | back to summary |
|---|---|
| private void copyEntriesAtLevelFromOther(final AbstractPackedArrayContext other, final int otherLevelEntryIndex, final int levelEntryIndexPointer, final int otherIndexShift) | |
| determineTopLevelShiftForVirtualLength | back to summary |
|---|---|
| pack-priv int determineTopLevelShiftForVirtualLength(final int virtualLength) | |
| expandArrayIfNeeded | back to summary |
|---|---|
| private void expandArrayIfNeeded(final int entryLengthInLongs) throws ResizeException | |
| expandEntry | back to summary |
|---|---|
| private int expandEntry(final int existingEntryIndex, final int entryPointerIndex, final int insertedSlotIndex, final int insertedSlotMask, final boolean nextLevelIsLeaf) throws RetryException, ResizeException Expand entry as indicated.
| |
| findFirstPotentiallyPopulatedVirtualIndexStartingAt | back to summary |
|---|---|
| private int findFirstPotentiallyPopulatedVirtualIndexStartingAt(final int startingVirtualIndex) | |
| getAtByteIndex | back to summary |
|---|---|
| pack-priv byte getAtByteIndex(final int byteIndex) | |
| getAtLongIndex | back to summary |
|---|---|
| pack-priv abstract long getAtLongIndex(int longIndex) | |
| getAtShortIndex | back to summary |
|---|---|
| pack-priv short getAtShortIndex(final int shortIndex) | |
| getAtUnpackedIndex | back to summary |
|---|---|
| pack-priv abstract long getAtUnpackedIndex(int index) | |
| getIndexAtEntrySlot | back to summary |
|---|---|
| private short getIndexAtEntrySlot(final int entryIndex, final int slot) | |
| getIndexAtShortIndex | back to summary |
|---|---|
| pack-priv short getIndexAtShortIndex(final int shortIndex) | |
| getPackedIndex | back to summary |
|---|---|
| pack-priv int getPackedIndex(final int setNumber, final int virtualIndex, final boolean insertAsNeeded) throws ResizeException Get the byte-index (into the packed array) corresponding to a given (set tree) value byte of given virtual index. Inserts new set tree nodes as needed if indicated.
| |
| getPackedSlotIndicators | back to summary |
|---|---|
| private int getPackedSlotIndicators(final int entryIndex) | |
| getPhysicalLength | back to summary |
|---|---|
| pack-priv int getPhysicalLength() | |
| getPopulatedByteLength | back to summary |
|---|---|
| pack-priv int getPopulatedByteLength() | |
| getPopulatedLongLength | back to summary |
|---|---|
| pack-priv int getPopulatedLongLength() | |
| getPopulatedShortLength | back to summary |
|---|---|
| pack-priv abstract int getPopulatedShortLength() | |
| getPreviousVersionIndex | back to summary |
|---|---|
| private short getPreviousVersionIndex(final int entryIndex) | |
| getRootEntry | back to summary |
|---|---|
| private int getRootEntry(final int setNumber) | |
| getRootEntry | back to summary |
|---|---|
| private int getRootEntry(final int setNumber, boolean insertAsNeeded) throws RetryException, ResizeException | |
| getTopLevelShift | back to summary |
|---|---|
| pack-priv int getTopLevelShift() | |
| getVirtualLength | back to summary |
|---|---|
| pack-priv int getVirtualLength() | |
| incrementAndGetAtUnpackedIndex | back to summary |
|---|---|
| pack-priv abstract long incrementAndGetAtUnpackedIndex(int index) | |
| init | back to summary |
|---|---|
| pack-priv void init(final int virtualLength) | |
| isPacked | back to summary |
|---|---|
| pack-priv boolean isPacked() | |
| lazySetAtLongIndex | back to summary |
|---|---|
| pack-priv abstract void lazySetAtLongIndex(int longIndex, long newValue) | |
| lazysetAtUnpackedIndex | back to summary |
|---|---|
| pack-priv abstract void lazysetAtUnpackedIndex(int index, long newValue) | |
| leafEntryToString | back to summary |
|---|---|
| private String leafEntryToString(final int entryIndex, final int indentLevel) | |
| length | back to summary |
|---|---|
| pack-priv abstract int length() | |
| newEntry | back to summary |
|---|---|
| private int newEntry(final int entryLengthInShorts) throws ResizeException | |
| newLeafEntry | back to summary |
|---|---|
| private int newLeafEntry() throws ResizeException | |
| nonLeafEntryToString | back to summary |
|---|---|
| private String nonLeafEntryToString(final int entryIndex, final int indexShift, final int indentLevel) | |
| nonZeroValues | back to summary |
|---|---|
| pack-priv Iterable An Iterator over all non-Zero values in the array
| |
| populateEquivalentEntriesWithZerosFromOther | back to summary |
|---|---|
| pack-priv void populateEquivalentEntriesWithZerosFromOther(final AbstractPackedArrayContext other) | |
| recordedValuesToString | back to summary |
|---|---|
| private String recordedValuesToString() | |
| resizeArray | back to summary |
|---|---|
| pack-priv abstract void resizeArray(int newLength) | |
| seekToPopulatedVirtualIndexStartingAtLevel | back to summary |
|---|---|
| private int seekToPopulatedVirtualIndexStartingAtLevel(final int startingVirtualIndex, final int levelEntryIndex, final int indexShift) throws RetryException | |
| setAtByteIndex | back to summary |
|---|---|
| pack-priv void setAtByteIndex(final int byteIndex, final byte value) | |
| setAtShortIndex | back to summary |
|---|---|
| pack-priv void setAtShortIndex(final int shortIndex, final short value) | |
| setAtUnpackedIndex | back to summary |
|---|---|
| pack-priv abstract void setAtUnpackedIndex(int index, long newValue) | |
| setIndexAtEntrySlot | back to summary |
|---|---|
| private void setIndexAtEntrySlot(final int entryIndex, final int slot, final short newIndexValue) | |
| setPackedSlotIndicators | back to summary |
|---|---|
| private void setPackedSlotIndicators(final int entryIndex, final short newPackedSlotIndicators) | |
| setPreviousVersionIndex | back to summary |
|---|---|
| private void setPreviousVersionIndex(final int entryIndex, final short newPreviosVersionIndex) | |
| setTopLevelShift | back to summary |
|---|---|
| private void setTopLevelShift(final int topLevelShift) | |
| setValuePart | back to summary |
|---|---|
| pack-priv void setValuePart(final int longIndex, final long valuePartAsLong, final long valuePartMask, final int valuePartShift) | |
| setVirtualLength | back to summary |
|---|---|
| pack-priv void setVirtualLength(final int virtualLength) | |
| toString | back to summary |
|---|---|
| public String toString() Overrides java. Doc from java. Returns a string representation of the object. | |
| unpackedToString | back to summary |
|---|---|
| pack-priv abstract String unpackedToString() | |
| Access | Constructor and Description |
|---|---|
| pack-priv |
| Modifier and Type | Method and Description |
|---|---|
| public Iterator |
| NonZeroValues | back to summary |
|---|---|
| pack-priv NonZeroValues() | |
| iterator | back to summary |
|---|---|
| public Iterator Implements java. Doc from java. Returns an iterator over elements of type
| |
| Modifier and Type | Field and Description |
|---|---|
| pack-priv final IterationValue | |
| pack-priv long | |
| pack-priv int |
| Access | Constructor and Description |
|---|---|
| pack-priv |
| Modifier and Type | Method and Description |
|---|---|
| private void | |
| public boolean | |
| public IterationValue | |
| public void | remove()
Overrides default java. |
| currentIterationValue | back to summary |
|---|---|
| pack-priv final IterationValue currentIterationValue | |
| nextValue | back to summary |
|---|---|
| pack-priv long nextValue | |
| nextVirtrualIndex | back to summary |
|---|---|
| pack-priv int nextVirtrualIndex | |
| NonZeroValuesIterator | back to summary |
|---|---|
| pack-priv NonZeroValuesIterator() | |
| findFirstNonZeroValueVirtualIndexStartingAt | back to summary |
|---|---|
| private void findFirstNonZeroValueVirtualIndexStartingAt(final int startingVirtualIndex) | |
| hasNext | back to summary |
|---|---|
| public boolean hasNext() Implements java. Doc from java. Returns
| |
| next | back to summary |
|---|---|
| public IterationValue next() Implements java. Doc from java. Returns the next element in the iteration.
| |
| remove | back to summary |
|---|---|
| public void remove() Overrides default java. Doc from java. Removes from the underlying collection the last element returned
by this iterator (optional operation). This method can be called
only once per call to The behavior of an iterator is unspecified if the underlying collection is modified while the iteration is in progress in any way other than by calling this method, unless an overriding class has specified a concurrent modification policy.
The behavior of an iterator is unspecified if this method is called
after a call to the
| |
| Access | Constructor and Description |
|---|---|
| private |
| RetryException | back to summary |
|---|---|
| private RetryException() | |