/*
* 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/.
*/
/*
* 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.map.diskmap.tree;
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.util.IdGenerator;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
abstract class LevelOneMultiRecordCursor extends MapCursor
{
// Object interface
@Override
public String toString()
{
return String.format("LevelOneMultiRecordCursor(%s)", id);
}
// MapCursor interface
@Override
public abstract LazyRecord next() throws IOException, InterruptedException;
@Override
public LazyRecord previous() throws IOException, InterruptedException
{
throw new UnsupportedOperationException();
}
@Override
public void close()
{
if (state != State.DONE) {
if (position != null) {
position.destroyRecordReference();
}
// Don't call end.destroyRecordReference. end is passed in, and is not owned by this.
super.close();
if (LOG.isLoggable(Level.INFO)) {
LOG.log(Level.INFO, "{0} closed", this);
}
}
}
@Override
public void goToFirst() throws IOException, InterruptedException
{
throw new UnsupportedOperationException();
}
@Override
public void goToLast() throws IOException, InterruptedException
{
throw new UnsupportedOperationException();
}
@Override
public void goTo(AbstractKey key) throws IOException, InterruptedException
{
throw new UnsupportedOperationException();
}
@Override
protected boolean isOpen(AbstractKey key)
{
throw new UnsupportedOperationException();
}
// LevelOneMultiRecordCursor interface
public static LevelOneMultiRecordCursor inclusiveAtEnd(TreePosition startPosition, TreePosition stopPosition)
{
return new InclusiveAtEnd(startPosition, stopPosition);
}
public static LevelOneMultiRecordCursor exclusiveAtEnd(TreePosition startPosition, TreePosition stopPosition)
{
return new ExclusiveAtEnd(startPosition, stopPosition);
}
// For use by subclasses
LevelOneMultiRecordCursor(TreePosition startPosition, TreePosition stopPosition)
{
super(null, false);
this.position = startPosition.copy();
this.stopPosition = stopPosition;
}
// Class state
protected static final Logger LOG = Logger.getLogger(LevelOneMultiRecordCursor.class.getName());
private static final IdGenerator idGenerator = new IdGenerator(0);
private final long id = idGenerator.nextId();
protected final TreePosition position;
protected final TreePosition stopPosition;
// Inner classes
private static class InclusiveAtEnd extends LevelOneMultiRecordCursor
{
@Override
public LazyRecord next() throws IOException, InterruptedException
{
TreePosition next = null;
if (state != State.DONE) {
state = State.IN_USE;
if (position.atEnd()) {
close();
} else if (position.equals(stopPosition)) {
next = position.copy();
close();
} else {
next = position.copy();
position.goToNextRecord();
}
}
if (LOG.isLoggable(Level.FINE)) {
LOG.log(Level.FINE, "{0} next: {1}", new Object[]{this, next});
}
return next;
}
InclusiveAtEnd(TreePosition startPosition, TreePosition stopPosition)
{
super(startPosition, stopPosition);
}
}
private static class ExclusiveAtEnd extends LevelOneMultiRecordCursor
{
@Override
public LazyRecord next() throws IOException, InterruptedException
{
TreePosition next = null;
if (state != State.DONE) {
state = State.IN_USE;
if (position.atEnd() || position.equals(stopPosition)) {
close();
} else {
next = position.copy();
position.goToNextRecord();
}
}
if (LOG.isLoggable(Level.FINE)) {
LOG.log(Level.FINE, "{0} next: {1}", new Object[]{this, next});
}
return next;
}
ExclusiveAtEnd(TreePosition startPosition, TreePosition stopPosition)
{
super(startPosition, stopPosition);
}
}
}