Class SequenceGenerator
- java.lang.Object
-
- org.apache.derby.impl.sql.catalog.SequenceGenerator
-
public class SequenceGenerator extends java.lang.ObjectThis is a generic machine for pre-allocating ranges of sequence numbers in order to improve concurrency. The public methods are synchronized and should be brief. The caller of the methods in this class is responsible for updating values on disk when the generator is exhausted or when it needs to allocate a new range of values.
The most used method in this class is getCurrentValueAndAdvance(). This method returns the next number in the range managed by the sequence generator. This method will raise an exception if the sequence generator is exhausted. Otherwise getCurrentValueAndAdvance() hands back a tuple of return values:
( status, currentValue, lastAllocatedValue, numberOfValuesAllocated )
The status field takes the following values:
- RET_I_AM_CONFUSED - This value should never be returned. If this value comes back, then the sequence generator is confused.
- RET_OK - This means that the generator has successfully obtained a next value. That value is currentValue.
- RET_MARK_EXHAUSTED - This means that the generator has reached the end of its legal range and is handing back its very last value. The caller must mark the catalogs to indicate that the range is exhausted. The very last value being handed back is currentValue.
- RET_ALLOCATE_NEW_VALUES - This means that the generator has come to the end
of its pre-allocated values. The caller needs to update the catalog to grab a new range of
legal values and then call allocateNewRange() to tell the generator that the range was
successfully allocated. The remaining values in the return tuple have these meanings:
- currentValue - This is what is expected to be the current value in the catalog before allocating a new range. If, in fact, this is not the value in the catalog, then we are racing with another session to drain values from the generator and update the disk. Do not update the catalog if the value there is not currentValue. Instead, assume that another session got in ahead of us and grabbed a new range of values. Simply call getCurrentValueAndAdvance() again.
- lastAllocatedValue - This is the next value to write to the catalog.
- numberOfValuesAllocated - This is the number of values which were allocated if we successfully updated the catalog. If we successfully updated the catalog, then we should call allocateNewRange(), handing it this value so that it can reset its range. As a sanity check, we also hand allocateNewRange() the currentValue that we were given. The allocateNewRange() method will assume we're racing another session and will ignore us if its sense of currentValue does not agree with ours.
It may happen that getCurrentValueAndAdvance() tells its caller to allocate a new range of sequence numbers in the system catalog. If the caller successfully allocates a new range, the caller should call allocateNewRange() to tell the generator to update its internal memory of that range.
The peekAtCurrentValue() method is provided so that unused, pre-allocated values can be flushed when the sequence generator is being discarded. The caller updates the catalog with the value returned by peekAtCurrentValue(). The peekAtCurrentValue() method is also called by the syscs_peek_at_sequence() function which users should call rather than try to scan the underlying catalog themselves.
-
-
Field Summary
Fields Modifier and Type Field Description private boolean_CAN_CYCLEprivate long_currentValueprivate long_INCREMENTprivate boolean_isExhaustedprivate long_MAX_VALUEprivate long_MIN_VALUEprivate SequencePreallocator_PREALLOCATORprivate long_remainingPreallocatedValuesprivate long_RESTART_VALUEprivate java.lang.String_SCHEMA_NAMEprivate java.lang.String_SEQUENCE_NAMEprivate boolean_STEP_INCREASESstatic intCVAA_CURRENT_VALUEstatic intCVAA_LAST_ALLOCATED_VALUEstatic intCVAA_LENGTHstatic intCVAA_NUMBER_OF_VALUES_ALLOCATEDstatic intCVAA_STATUSprivate static intPREALLOCATION_THRESHHOLDIf pre-allocation drops below this level, then we need to grab another chunk of numbersstatic intRET_ALLOCATE_NEW_VALUESstatic intRET_I_AM_CONFUSEDstatic intRET_MARK_EXHAUSTEDstatic intRET_OK
-
Constructor Summary
Constructors Constructor Description SequenceGenerator(java.lang.Long currentValue, boolean canCycle, long increment, long maxValue, long minValue, long restartValue, java.lang.String schemaName, java.lang.String sequenceName, SequencePreallocator sequencePreallocator)Normal constructor
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description private voidadvanceValue(long[] retval)Advance the sequence generator.voidallocateNewRange(long expectedCurrentValue, long numberOfAllocatedValues)Allocate a new range.SequenceGeneratorclone(boolean restart)Clone this sequence generator.SequenceGeneratorclone(java.lang.Long newStartValue)Clone this sequence generator.private voidcomputeNewAllocation(long oldCurrentValue, long[] retval)Compute the number of values to allocate.private intcomputePreAllocationCount()This method returns the number of values to pre-allocate when we grab a new chunk of values.private longcomputeRemainingValues(long oldCurrentValue)Get the number of values remaining until we bump against an endpoint of the legal range of values.long[]getCurrentValueAndAdvance()Get the next sequence number managed by this generator and advance the number.java.lang.StringgetName()Get the name of this sequence generator.java.lang.StringgetSchemaName()Get the name of the schema of this sequence generator.private voidmarkExhausted(long[] retval)Mark the generator as exhausted.private booleanoverflowed(long originalValue, long incrementedValue)Return true if an overflow/underflow occurred.java.lang.LongpeekAtCurrentValue()Peek at the current value of the sequence generator without advancing the generator.
-
-
-
Field Detail
-
PREALLOCATION_THRESHHOLD
private static final int PREALLOCATION_THRESHHOLD
If pre-allocation drops below this level, then we need to grab another chunk of numbers- See Also:
- Constant Field Values
-
RET_I_AM_CONFUSED
public static final int RET_I_AM_CONFUSED
- See Also:
- Constant Field Values
-
RET_OK
public static final int RET_OK
- See Also:
- Constant Field Values
-
RET_MARK_EXHAUSTED
public static final int RET_MARK_EXHAUSTED
- See Also:
- Constant Field Values
-
RET_ALLOCATE_NEW_VALUES
public static final int RET_ALLOCATE_NEW_VALUES
- See Also:
- Constant Field Values
-
CVAA_STATUS
public static final int CVAA_STATUS
- See Also:
- Constant Field Values
-
CVAA_CURRENT_VALUE
public static final int CVAA_CURRENT_VALUE
- See Also:
- Constant Field Values
-
CVAA_LAST_ALLOCATED_VALUE
public static final int CVAA_LAST_ALLOCATED_VALUE
- See Also:
- Constant Field Values
-
CVAA_NUMBER_OF_VALUES_ALLOCATED
public static final int CVAA_NUMBER_OF_VALUES_ALLOCATED
- See Also:
- Constant Field Values
-
CVAA_LENGTH
public static final int CVAA_LENGTH
- See Also:
- Constant Field Values
-
_CAN_CYCLE
private final boolean _CAN_CYCLE
-
_STEP_INCREASES
private final boolean _STEP_INCREASES
-
_INCREMENT
private final long _INCREMENT
-
_MAX_VALUE
private final long _MAX_VALUE
-
_MIN_VALUE
private final long _MIN_VALUE
-
_RESTART_VALUE
private final long _RESTART_VALUE
-
_SCHEMA_NAME
private final java.lang.String _SCHEMA_NAME
-
_SEQUENCE_NAME
private final java.lang.String _SEQUENCE_NAME
-
_PREALLOCATOR
private final SequencePreallocator _PREALLOCATOR
-
_isExhausted
private boolean _isExhausted
-
_currentValue
private long _currentValue
-
_remainingPreallocatedValues
private long _remainingPreallocatedValues
-
-
Constructor Detail
-
SequenceGenerator
public SequenceGenerator(java.lang.Long currentValue, boolean canCycle, long increment, long maxValue, long minValue, long restartValue, java.lang.String schemaName, java.lang.String sequenceName, SequencePreallocator sequencePreallocator)Normal constructor
-
-
Method Detail
-
clone
public SequenceGenerator clone(boolean restart)
Clone this sequence generator. This method supports the special bulk-insert optimization in InsertResultSet.
- Parameters:
restart- True if the clone should be reset to start at the beginning instead of at the current value.
-
clone
public SequenceGenerator clone(java.lang.Long newStartValue)
Clone this sequence generator. This method supports the special bulk-insert optimization in InsertResultSet.
- Parameters:
newStartValue- New value to start with.
-
getSchemaName
public java.lang.String getSchemaName()
Get the name of the schema of this sequence generator. Technically, this doesn't need to be synchronized. But it is simpler to just maintain a rule that all public methods should be synchronized.
-
getName
public java.lang.String getName()
Get the name of this sequence generator. Technically, this doesn't need to be synchronized. But it is simpler to just maintain a rule that all public methods should be synchronized.
-
allocateNewRange
public void allocateNewRange(long expectedCurrentValue, long numberOfAllocatedValues)Allocate a new range. Is a NOP if the current value is not what we expected. See the class header comment for more information on how this method is used.
-
peekAtCurrentValue
public java.lang.Long peekAtCurrentValue()
Peek at the current value of the sequence generator without advancing the generator. Returns null if the generator is exhausted.
-
getCurrentValueAndAdvance
public long[] getCurrentValueAndAdvance() throws StandardExceptionGet the next sequence number managed by this generator and advance the number. Could raise an exception if the legal range is exhausted and wrap-around is not allowed--that is, if NO CYCLE was specified when the sequence was defined. See the class header comment for a description of how this method operates.
- Returns:
- Returns an array of longs indexed by the CVAA_* constants.
- Throws:
StandardException
-
advanceValue
private void advanceValue(long[] retval) throws StandardExceptionAdvance the sequence generator. Pre-allocate a range of new values if necessary.
- Parameters:
retval- Array of return values to fill in: see CVAA_* constants- Throws:
StandardException
-
markExhausted
private void markExhausted(long[] retval)
Mark the generator as exhausted.
-
overflowed
private boolean overflowed(long originalValue, long incrementedValue)Return true if an overflow/underflow occurred. This happens if the originalValue and incrementedValue have opposite sign. Overflow also occurs if the incrementedValue falls outside the range of the sequence.
-
computeNewAllocation
private void computeNewAllocation(long oldCurrentValue, long[] retval) throws StandardExceptionCompute the number of values to allocate. The range may wrap around.
- Parameters:
oldCurrentValue- INPUT Used to compute how many values need to be allocatedretval- OUTPUT Array of values to fill in (see CVAA_* constants)- Throws:
StandardException- if any error occurs.
-
computeRemainingValues
private long computeRemainingValues(long oldCurrentValue)
Get the number of values remaining until we bump against an endpoint of the legal range of values. This is a positive number and so may understate the number of remaining values if the datatype is BIGINT.
-
computePreAllocationCount
private int computePreAllocationCount()
This method returns the number of values to pre-allocate when we grab a new chunk of values. This is a bit of defensive coding to cover the case when the sequence's parameters are absurdly large.
-
-