/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package com.github.geophile.erdo.forest;
import com.github.geophile.erdo.AbstractKey;
import com.github.geophile.erdo.map.LazyRecord;
import com.github.geophile.erdo.map.MapCursor;
import com.github.geophile.erdo.map.mergescan.AbstractMultiRecord;
import java.io.IOException;
class RemoveDeletedRecordCursor extends MapCursor
{
// MapCursor interface
@Override
public LazyRecord next() throws IOException, InterruptedException
{
return neighbor(true);
}
@Override
public LazyRecord previous() throws IOException, InterruptedException
{
return neighbor(false);
}
@Override
public void close()
{
cursor = null;
}
// RemoveDeletedRecordCursor interface
public RemoveDeletedRecordCursor(MapCursor cursor, long maxDeletionTimestamp)
{
super(null, false);
this.cursor = cursor;
this.maxDeletionTimestamp = maxDeletionTimestamp;
}
// For use by this class
private LazyRecord neighbor(boolean forward) throws IOException, InterruptedException
{
LazyRecord neighbor = null;
AbstractKey key;
if (cursor != null) {
boolean removeDeletedRecord;
do {
neighbor = forward ? cursor.next() : cursor.previous();
if (neighbor != null &&
(key = neighbor.key()).deleted() &&
checkSingleRecord(neighbor) &&
key.transactionTimestamp() <= maxDeletionTimestamp) {
neighbor.destroyRecordReference();
removeDeletedRecord = true;
} else {
removeDeletedRecord = false;
}
} while (removeDeletedRecord);
if (neighbor == null) {
close();
}
}
return neighbor;
}
private boolean checkSingleRecord(LazyRecord record)
{
// AbstractKey.deleted(), (called in next() above), should always be false for a multi-record.
// So if we get here, (called after next()), then the record must not be a multi-record.
assert !(record instanceof AbstractMultiRecord) : record;
return true;
}
// Object state
private MapCursor cursor;
private final long maxDeletionTimestamp;
}