*/
private OperationStatus retrieveNextNoDups(final DatabaseEntry key,
final DatabaseEntry data,
final LockMode lockMode,
final GetMode getModeParam) {
final GetMode getMode;
switch (getModeParam) {
case NEXT_DUP:
case PREV_DUP:
return OperationStatus.NOTFOUND;
case NEXT_NODUP:
getMode = GetMode.NEXT;
break;
case PREV_NODUP:
getMode = GetMode.PREV;
break;
default:
getMode = getModeParam;
}
try {
if (!isSerializableIsolation(lockMode)) {
return retrieveNextAllowPhantoms
(key, data, getLockType(lockMode, false), getMode,
cursorRangeConstraint);
}
/*
* Perform range locking to prevent phantoms and handle restarts.
*/
while (true) {
try {
/* Get a range lock for 'prev' operations. */
if (!getMode.isForward()) {
rangeLockCurrentPosition(getMode);
}
/* Use a range lock if performing a 'next' operation. */
final LockType lockType =
getLockType(lockMode, getMode.isForward());
/* Do not modify key/data params until SUCCESS. */
final DatabaseEntry tryKey = cloneEntry(key);
final DatabaseEntry tryData = cloneEntry(data);
final KeyChangeStatus result;
/* Perform the operation with a null rangeConstraint. */
OperationStatus status = retrieveNextAllowPhantoms
(tryKey, tryData, lockType, getMode,
null /*rangeConstraint*/);
if (getMode.isForward() &&
status != OperationStatus.SUCCESS) {
/* NEXT: lock the EOF node. */
cursorImpl.lockEof(LockType.RANGE_READ);
}