*/
private VLSNBucket getGTEBucketFromDatabase(VLSN target,
VLSNBucket currentBucketInUse)
throws DatabaseException {
Cursor cursor = null;
Locker locker = null;
try {
locker = BasicLocker.createBasicLocker(envImpl);
cursor = makeCursor(locker);
/*
* Look at the bucket at key >= target.Will return null if no GTE
* bucket.
*/
VLSNBucket bucket = examineGTEBucket(target, cursor);
if (bucket != null) {
return bucket;
}
/*
* We're here because we did not find a bucket >= target. Let's
* examine the last bucket in this database. We know that it will
* either be:
*
* 1) a bucket that's < target, but owns the mapping
* 2) if the index was appended to by VLSNTracker.flushToDatabase
* while the search is going on, the last bucket may be one
* that is > or >= target.
* Using the example above, the last bucket could be case 1:
*
* a bucket that is < target 22:
* key=vlsn 20, data = bucket: vlsn 20 -> lsn 0x11/100
* vlsn 25 -> lsn 0x11/150
*
* or case 2, a bucket that is >= target 22, because the index grew
* key=vlsn 30, data = bucket: vlsn 30 -> lsn 0x12/100
* vlsn 35 -> lsn 0x12/150
*/
assert(TestHookExecute.doHookIfSet(searchGTEHook));
VLSNBucket endBucket = null;
DatabaseEntry key = new DatabaseEntry();
DatabaseEntry data = new DatabaseEntry();
OperationStatus status = cursor.getLast(key, data,
LockMode.DEFAULT);
if (isValidBucket(status, key)) {
endBucket = VLSNBucket.readFromDatabase(data);
if (endBucket.owns(target)) {
return endBucket;
}
/*
* If this end bucket is not the owner of the target VLSN, we
* expect it to be a greaterThan bucket which was inserted
* because of a concurrent VLSNTracker.flushToDatabase call
* that did not exist when we did the previous
* cursor.getKeyRangeSearch (case 2), In that case, we can
* search again for the owning bucket.
*/
if (endBucket.follows(target)) {
bucket = examineGTEBucket(target, cursor);
if (bucket != null) {
return bucket;
}
}
}
/*
* Shouldn't get here! There should have been a bucket in this
* database >= this target.
*/
/* Dump the bucket database for debugging. */
int count = 0;
StringBuilder sb = new StringBuilder();
status = cursor.getFirst(key, data, LockMode.DEFAULT);
while (status == OperationStatus.SUCCESS) {
Long keyValue = LongBinding.entryToLong(key);
sb.append("key => " + keyValue + "\n");
if (count == 0) {
VLSNRange range = VLSNRange.readFromDatabase(data);
sb.append("range =>" + range + "\n");
} else {
bucket = VLSNBucket.readFromDatabase(data);
sb.append("bucket => " + bucket + "\n");
}
count++;
status = cursor.getNext(key, data, LockMode.DEFAULT);
}
LoggerUtils.severe(logger, envImpl, "VLSNIndex Dump: " +
sb.toString());
throw EnvironmentFailureException.unexpectedState
(envImpl, "Couldn't find bucket for GTE VLSN " + target +
" in database. EndBucket=" + endBucket + "currentBucket=" +
currentBucketInUse + " tracker = " + tracker);
} finally {
if (cursor != null) {
cursor.close();
}
if (locker != null) {
locker.operationEnd(true);
}