com.kolibrifx.plovercrest.server.internal.engine.DeferredReader Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of plovercrest-server Show documentation
Show all versions of plovercrest-server Show documentation
Plovercrest server library.
The newest version!
/*
* Copyright (c) 2010-2017, KolibriFX AS. Licensed under the Apache License, version 2.0.
*/
package com.kolibrifx.plovercrest.server.internal.engine;
import org.apache.log4j.Logger;
import com.kolibrifx.plovercrest.client.TableClosedException;
import com.kolibrifx.plovercrest.server.ReadObserver;
import com.kolibrifx.plovercrest.server.internal.engine.TableMapper.ReadIterator;
public class DeferredReader {
private static final Logger log = Logger.getLogger(DeferredReader.class);
private ReadIterator iterator = null;
private final DeferredTableMapper mapper;
public DeferredReader(final DeferredTableMapper mapper) {
this.mapper = mapper;
}
private ReadIterator getIterator() {
if (iterator == null) {
// Note that getReadIterator(0) can throw a TableClosedException
iterator = mapper.getMapper().getReadIterator(0);
}
mapper.recordUse();
return iterator;
}
private void handleTableClosed(final TableClosedException e) {
if (mapper.isClosed()) {
// the table really is closed, so rethrow
throw e;
}
try {
if (iterator == null) {
// can happen if the first getIterator() call failed
iterator = mapper.getMapper().getReadIterator(0);
} else {
// the table mapper has been evicted, so recreate the read iterator at the same index
// getting the entry index from the old iterator should work even if the mapper has been closed
final long entryIndex = iterator.getEntryIndex();
iterator = mapper.getMapper().getReadIterator(entryIndex);
}
} catch (final TableClosedException e2) {
// Yes, this is possible when really stressing the cache. Should be very rare in practice, though.
log.warn("Caught TableClosedException during exception handling");
}
}
public T read(final ReadObserver observer) {
while (true) {
try {
return getIterator().next(observer);
} catch (final TableClosedException e) {
handleTableClosed(e);
}
}
}
public long seekTakePrevious(final long desiredTimestamp) {
while (true) {
try {
return getIterator().seekTakePrevious(desiredTimestamp);
} catch (final TableClosedException e) {
handleTableClosed(e);
}
}
}
public long seekTakeNext(final long desiredTimestamp) {
while (true) {
try {
return getIterator().seekTakeNext(desiredTimestamp);
} catch (final TableClosedException e) {
handleTableClosed(e);
}
}
}
public void seekToEntryIndex(final long entryIndex) {
while (true) {
try {
getIterator().seekToEntryIndex(entryIndex);
return;
} catch (final TableClosedException e) {
handleTableClosed(e);
}
}
}
public long getEntryIndex() {
while (true) {
try {
return getIterator().getEntryIndex();
} catch (final TableClosedException e) {
handleTableClosed(e);
}
}
}
public long getLastTimestamp() {
return mapper.getLastTimestamp();
}
public long getFirstTimestamp() {
return mapper.getFirstTimestamp();
}
public long getLastValidTimestamp() {
return mapper.getLastValidTimestamp();
}
}