do not store keymapping for simple enumerator

This commit is contained in:
Maxim.Mossienko
2011-08-08 20:01:55 +04:00
parent 754e5ac71c
commit 6ecbc12ef9
2 changed files with 45 additions and 11 deletions
@@ -58,17 +58,20 @@ public class PersistentBTreeEnumerator<Data> extends PersistentEnumeratorBase<Da
private IntToIntBtree btree;
private final boolean myInlineKeysNoMapping;
private boolean myExternalKeysNoMapping;
private static final int DIRTY_MAGIC = 0xbabe1977;
private static final int VERSION = 5 + IntToIntBtree.VERSION;
private static final int CORRECTLY_CLOSED_MAGIC = 0xebabafc + VERSION + PAGE_SIZE;
private static Version ourVersion = new Version(CORRECTLY_CLOSED_MAGIC, DIRTY_MAGIC);
private static final int KEY_SHIFT = 1;
public PersistentBTreeEnumerator(File file, KeyDescriptor<Data> dataDescriptor, int initialSize) throws IOException {
super(file, new MappedFileSimpleStorage(file, initialSize, 1024 * 1024), dataDescriptor, initialSize,
ourVersion, new RecordBufferHandler());
myInlineKeysNoMapping = myDataDescriptor instanceof InlineKeyDescriptor && !wantInlineKeyMapping();
myInlineKeysNoMapping = myDataDescriptor instanceof InlineKeyDescriptor && !wantKeyMapping();
myExternalKeysNoMapping = !(myDataDescriptor instanceof InlineKeyDescriptor) && !wantKeyMapping();
if (btree == null) {
synchronized (ourLock) {
@@ -83,7 +86,7 @@ public class PersistentBTreeEnumerator<Data> extends PersistentEnumeratorBase<Da
return new File(file.getPath() + "_i");
}
protected boolean wantInlineKeyMapping() {
protected boolean wantKeyMapping() {
return false;
}
@@ -166,8 +169,9 @@ public class PersistentBTreeEnumerator<Data> extends PersistentEnumeratorBase<Da
@Override
public boolean traverseAllRecords(RecordsProcessor p) throws IOException {
synchronized (ourLock) {
if (myInlineKeysNoMapping) {
if (myInlineKeysNoMapping || myExternalKeysNoMapping) {
List<IntToIntBtree.BtreeIndexNodeView> leafPages = new ArrayList<IntToIntBtree.BtreeIndexNodeView> ();
btree.root.setAddress(btree.root.address);
collectLeafPages(btree.root, leafPages);
Collections.sort(leafPages, new Comparator<IntToIntBtree.BtreeIndexNodeView>() {
@Override
@@ -182,7 +186,16 @@ public class PersistentBTreeEnumerator<Data> extends PersistentEnumeratorBase<Da
Integer record = btree.get(key);
p.setCurrentKey(key);
assert record != null;
if (!p.process(record)) break out;
if (record > 0) {
if (!p.process(record)) break out;
} else {
int rec = - record;
while(rec != 0) {
int id = myStorage.getInt(rec);
if (!p.process(id)) break out;
rec = myStorage.getInt(rec + COLLISION_OFFSET);
}
}
}
}
return true;
@@ -219,6 +232,11 @@ public class PersistentBTreeEnumerator<Data> extends PersistentEnumeratorBase<Da
@Override
protected int indexToAddr(int idx) {
if (myExternalKeysNoMapping) {
IntToIntBtree.myAssert(idx > 0);
return idx - KEY_SHIFT;
}
int anInt = myStorage.getInt(idx);
if (IntToIntBtree.doSanityCheck) {
IntToIntBtree.myAssert(anInt >= 0 || myDataDescriptor instanceof InlineKeyDescriptor);
@@ -226,6 +244,18 @@ public class PersistentBTreeEnumerator<Data> extends PersistentEnumeratorBase<Da
return anInt;
}
@Override
protected int setupValueId(int hashCode, int dataOff) {
if (myExternalKeysNoMapping) return dataOff + KEY_SHIFT;
return super.setupValueId(hashCode, dataOff);
}
@Override
public void setRecordHandler(PersistentEnumeratorBase.RecordBufferHandler<PersistentEnumeratorBase> recordHandler) {
myExternalKeysNoMapping = false;
super.setRecordHandler(recordHandler);
}
protected int enumerateImpl(final Data value, final boolean saveNewValue) throws IOException {
try {
if (IntToIntBtree.doDump) System.out.println(value);
@@ -209,7 +209,7 @@ abstract class PersistentEnumeratorBase<Data> implements Forceable, Closeable {
return myRecordHandler;
}
public final void setRecordHandler(RecordBufferHandler<PersistentEnumeratorBase> recordHandler) {
public void setRecordHandler(RecordBufferHandler<PersistentEnumeratorBase> recordHandler) {
myRecordHandler = recordHandler;
}
@@ -316,8 +316,6 @@ abstract class PersistentEnumeratorBase<Data> implements Forceable, Closeable {
markDirty(true);
final int dataOff = myKeyStorage != null ? (int)myKeyStorage.length() : ((InlineKeyDescriptor<Data>)myDataDescriptor).toInt(value);
final byte[] buf = myRecordHandler.getRecordBuffer(this);
myRecordHandler.setupRecord(this, hashCode, dataOff, buf);
if (myKeyStorage != null) {
final BufferExposingByteArrayOutputStream bos = new BufferExposingByteArrayOutputStream();
@@ -326,16 +324,22 @@ abstract class PersistentEnumeratorBase<Data> implements Forceable, Closeable {
myKeyStorage.put(dataOff, bos.getInternalBuffer(), 0, bos.size());
}
final int pos = myRecordHandler.recordWriteOffset(this, buf);
myStorage.put(pos, buf, 0, buf.length);
return pos;
return setupValueId(hashCode, dataOff);
}
catch (IOException e) {
throw new RuntimeException(e);
}
}
protected int setupValueId(int hashCode, int dataOff) {
final byte[] buf = myRecordHandler.getRecordBuffer(this);
myRecordHandler.setupRecord(this, hashCode, dataOff, buf);
final int pos = myRecordHandler.recordWriteOffset(this, buf);
myStorage.put(pos, buf, 0, buf.length);
return pos;
}
protected boolean iterateData(final Processor<Data> processor) throws IOException {
if (myKeyStorage == null) {
throw new UnsupportedOperationException("Iteration over InlineIntegerKeyDescriptors is not supported");