This 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.