/*
* Created on 08.01.2008
* Caleido AG, All Rights Reserved
* Author: Luzius Meisser
*/
package quickbase.internal.consumer;
import quickbase.exception.AbortVisitException;
import quickbase.exception.BasicFileOperationDatabaseException;
import quickbase.exception.ClearDatabaseException;
import quickbase.exception.IExceptionHandlingStrategy;
import quickbase.exception.InvalidDataDatabaseException;
import quickbase.exception.SerializationDatabaseException;
import quickbase.internal.entries.AddEntry;
import quickbase.internal.entries.Entry;
import quickbase.internal.entries.HashFunction;
import quickbase.internal.files.DataFileAbandonedException;
import quickbase.internal.files.DataFiles;
import quickbase.internal.index.Index;
public abstract class AbstractConsumer<K, V> implements IEntryConsumer {
private IExceptionHandlingStrategy strategy;
private Index index;
protected HashFunction hash;
private DataFiles original;
public AbstractConsumer(HashFunction hash, IExceptionHandlingStrategy strategy, Index index, DataFiles data) {
this.hash = hash;
this.strategy = strategy;
this.index = index;
this.original = data;
}
public boolean consume(Entry entry, long pos) throws BasicFileOperationDatabaseException, ClearDatabaseException, SerializationDatabaseException, AbortVisitException {
if (entry instanceof AddEntry) {
long filePos = index.getPosition(hash.getHash(entry));
checkLater((AddEntry) entry, pos, filePos);
}
return true;
}
private void checkLater(AddEntry entry, long pos, long filePos) throws BasicFileOperationDatabaseException, ClearDatabaseException, SerializationDatabaseException, AbortVisitException {
if (filePos == pos) {
visit(entry);
} else if (filePos > pos) {
try {
Entry later = original.get(filePos);
if (later.hasKey(entry.getKey())) {
// we will get to that entry again later, skip it now
} else {
filePos = later.getPrevPos();
if (filePos < 0) {
throw new InvalidDataDatabaseException("Invalid file pos: " + filePos);
} else {
checkLater(entry, pos, filePos);
}
}
} catch (InvalidDataDatabaseException e) {
strategy.handleInvalidData(e);
} catch (DataFileAbandonedException e) {
strategy.handleMissingFile(e);
}
} else {
strategy.handleInvalidData(new InvalidDataDatabaseException(hash.getHash(entry) + " has pos " + filePos + " in index but found entry later at " + pos));
}
}
protected abstract void visit(AddEntry entry) throws SerializationDatabaseException, BasicFileOperationDatabaseException, AbortVisitException;
public void flush() throws BasicFileOperationDatabaseException {
}
public boolean needsValues() {
return true;
}
}