[Mulgara-svn] r938 - in projects/xa2/object-pool/src: data scheduler trie
andrae at mulgara.org
andrae at mulgara.org
Wed May 14 05:06:36 UTC 2008
Author: andrae
Date: 2008-05-13 22:06:35 -0700 (Tue, 13 May 2008)
New Revision: 938
Modified:
projects/xa2/object-pool/src/data/DataFile.java
projects/xa2/object-pool/src/scheduler/Block.java
projects/xa2/object-pool/src/scheduler/FileHandleFactory.java
projects/xa2/object-pool/src/scheduler/IOScheduler.java
projects/xa2/object-pool/src/trie/ByteMap.java
projects/xa2/object-pool/src/trie/DiskTrie.java
projects/xa2/object-pool/src/trie/MemoryTrie.java
Log:
Completes the migration of the disk-based trie across to the new io-scheduler classes.
Note: DataEntry already provides lazy loading of data blocks, however ultimately we will need to go further
than this.
Modified: projects/xa2/object-pool/src/data/DataFile.java
===================================================================
--- projects/xa2/object-pool/src/data/DataFile.java 2008-05-14 05:01:12 UTC (rev 937)
+++ projects/xa2/object-pool/src/data/DataFile.java 2008-05-14 05:06:35 UTC (rev 938)
@@ -20,15 +20,15 @@
private FileHandle handle;
- public DataFile(String filename, IOScheduler scheduler) {
+ public DataFile(String filename, IOScheduler scheduler) throws IOException {
this.handle = scheduler.open(filename, MAGIC, LOG2_BLOCK_SIZE);
}
public DataEntry getEntry(long position) throws IOException {
- return DataEntry.getDataEntry(handle, position);
+ return DataEntry.getEntry(handle, position);
}
- public long write(DataEntry entry) {
+ public long write(DataEntry entry) throws IOException {
return entry.write(handle);
}
}
Modified: projects/xa2/object-pool/src/scheduler/Block.java
===================================================================
--- projects/xa2/object-pool/src/scheduler/Block.java 2008-05-14 05:01:12 UTC (rev 937)
+++ projects/xa2/object-pool/src/scheduler/Block.java 2008-05-14 05:06:35 UTC (rev 938)
@@ -50,6 +50,10 @@
return (ByteBuffer)(buffer.clear());
}
+ public long getLong() throws BufferUnderflowException {
+ return buffer.getLong();
+ }
+
public int getInt() throws BufferUnderflowException {
return buffer.getInt();
}
@@ -62,18 +66,22 @@
return buffer.get();
}
- public void putInt(int i) {
- buffer.putInt(i);
+ public void putByte(byte b) {
+ buffer.put(b);
}
public void putShort(short s) {
buffer.putShort(s);
}
- public void putByte(byte b) {
- buffer.put(b);
+ public void putInt(int i) {
+ buffer.putInt(i);
}
+ public void putLong(long l) {
+ buffer.putLong(l);
+ }
+
public int position() {
return buffer.position();
}
Modified: projects/xa2/object-pool/src/scheduler/FileHandleFactory.java
===================================================================
--- projects/xa2/object-pool/src/scheduler/FileHandleFactory.java 2008-05-14 05:01:12 UTC (rev 937)
+++ projects/xa2/object-pool/src/scheduler/FileHandleFactory.java 2008-05-14 05:06:35 UTC (rev 938)
@@ -6,6 +6,9 @@
package scheduler;
import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
/**
* A canonical mapping of File objects to FileHandles.
@@ -13,27 +16,27 @@
public class FileHandleFactory {
public FileHandleFactory() {}
- public FileHandle createNew(File file, int magic, int blocksize) {
+ public FileHandle createNew(File file, int magic, int blocksize) throws IOException {
if (file.exists()) {
throw new IllegalArgumentException("File exists: " + file);
}
- return new FileHandle(new FileInputStream(file), magic, blocksize);
+ return new FileHandle(file, new FileInputStream(file), magic, blocksize);
}
- public FileHandle openExisting(File file, int magic, int blocksize) {
+ public FileHandle openExisting(File file, int magic, int blocksize) throws IOException {
if (!file.exists()) {
throw new IllegalArgumentException("File does not exist: " + file);
}
- return new FileHandle(new FileOutputStream(file), magic, blocksize);
+ return new FileHandle(file, new FileOutputStream(file), magic, blocksize);
}
- public FileHandle open(File file, int magic, int blocksize) {
+ public FileHandle open(File file, int magic, int blocksize) throws IOException {
if (file.exists()) {
return openExisting(file, magic, blocksize);
} else {
- return openNew(file, magic, blocksize);
+ return createNew(file, magic, blocksize);
}
}
}
Modified: projects/xa2/object-pool/src/scheduler/IOScheduler.java
===================================================================
--- projects/xa2/object-pool/src/scheduler/IOScheduler.java 2008-05-14 05:01:12 UTC (rev 937)
+++ projects/xa2/object-pool/src/scheduler/IOScheduler.java 2008-05-14 05:06:35 UTC (rev 938)
@@ -6,6 +6,7 @@
package scheduler;
import java.io.File;
+import java.io.IOException;
public class IOScheduler {
private FileHandleFactory fileHandleFactory;
@@ -24,9 +25,9 @@
}
}
- public FileHandle open(String name, int magic, int blocksize) {
+ public FileHandle open(String name, int magic, int blocksize) throws IOException {
File file = new File(dir, name);
- return fileHandleFactory.open(file, int, blocksize);
+ return fileHandleFactory.open(file, magic, blocksize);
}
}
Modified: projects/xa2/object-pool/src/trie/ByteMap.java
===================================================================
--- projects/xa2/object-pool/src/trie/ByteMap.java 2008-05-14 05:01:12 UTC (rev 937)
+++ projects/xa2/object-pool/src/trie/ByteMap.java 2008-05-14 05:06:35 UTC (rev 938)
@@ -165,10 +165,10 @@
return 2 + 2 * low.length;
}
- public void writeHeader(ByteBuffer bb) {
- bb.putShort(high);
+ public void writeHeader(Block block) {
+ block.putShort(high);
for (int i = 0; i < low.length; i++) {
- bb.putShort(low[i]);
+ block.putShort(low[i]);
}
}
}
Modified: projects/xa2/object-pool/src/trie/DiskTrie.java
===================================================================
--- projects/xa2/object-pool/src/trie/DiskTrie.java 2008-05-14 05:01:12 UTC (rev 937)
+++ projects/xa2/object-pool/src/trie/DiskTrie.java 2008-05-14 05:06:35 UTC (rev 938)
@@ -6,12 +6,12 @@
package trie;
import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.channels.FileChannel;
import java.util.HashMap;
import java.util.Map;
+import data.DataEntry;
+import data.DataFile;
+import scheduler.Block;
import scheduler.FileHandle;
/**
@@ -69,14 +69,14 @@
if (indexBlock.getBlockId() != Block.UNALLOCATED) throw new IllegalArgumentException("Attempt to reuse block in DiskTrie");
this.indexBlock = indexBlock;
- this.space = (short)((blockSize - 8) / WORST_CASE_ENTRY_SIZE); // -8 leaves room for header info.
+ this.space = (short)((indexBlock.getBlockSize() - 8) / WORST_CASE_ENTRY_SIZE); // -8 leaves room for header info.
}
public DiskTrie(Block indexBlock, DataFile data) throws IOException {
super();
- if (indexBlock.getBlockId == Block.UNALLOCATED) throw new IllegalArgumentException("Attempt to read unallocated block in DiskTrie");
+ if (indexBlock.getBlockId() == Block.UNALLOCATED) throw new IllegalArgumentException("Attempt to read unallocated block in DiskTrie");
- indexBlock.prepare();
+ indexBlock.clear();
// I should be able to replace this with a stack.
// The child->parent relationship is implicit in the ordering of the nodes in the file.
@@ -88,7 +88,7 @@
short rootLocation = -1;
while (rootLocation == -1) {
- short location = (short)index.position();
+ short location = (short)indexBlock.position();
byte type = indexBlock.getByte();
switch (type) {
case TYPE_BRANCH_TERM:
@@ -101,8 +101,8 @@
nodeMap.put(location, readTrieLeaf(indexBlock, data));
break;
case TYPE_ROOT_LOC:
- index.getByte(); // Skip padding.
- rootLocation = index.getShort();
+ indexBlock.getByte(); // Skip padding.
+ rootLocation = indexBlock.getShort();
break;
default:
throw new IllegalArgumentException("Invalid trie-node");
@@ -119,7 +119,7 @@
// trie-block, but if we haven't we should recalculate the space available.
if (space == 0) {
int size = totalIndexSize(root);
- space = (short)((blockSize - size - 8) / WORST_CASE_ENTRY_SIZE);
+ space = (short)((indexBlock.getBlockSize() - size - 8) / WORST_CASE_ENTRY_SIZE);
if (space < 0) {
throw new IllegalStateException("Overfilled CompBlockTrie");
} else if (space == 0) {
@@ -141,16 +141,16 @@
HashMap<TrieNode, Short> locationMap = new HashMap<TrieNode, Short>();
- index.putInt(MAGIC);
+ indexBlock.putInt(MAGIC);
if (root != null) {
writeTrieNode(root, indexBlock, data, locationMap);
}
- index.put(TYPE_ROOT_LOC);
- index.put((byte)0xFF);
+ indexBlock.putByte(TYPE_ROOT_LOC);
+ indexBlock.putByte((byte)0xFF);
if (root != null) {
- index.putShort(locationMap.get(root));
+ indexBlock.putShort(locationMap.get(root));
} else {
- index.putShort((short)0x0000);
+ indexBlock.putShort((short)0x0000);
}
}
@@ -160,7 +160,7 @@
writerMap.put(TrieLeaf.class, new TrieLeafWriter());
}
- protected static void writeTrieNode(TrieNode node, ByteBuffer index, FileChannel data,
+ protected static void writeTrieNode(TrieNode node, Block index, DataFile data,
Map<TrieNode, Short> locationMap) throws IOException {
writerMap.get(node.getClass()).write(node, index, data, locationMap);
}
@@ -173,11 +173,11 @@
* The data buffer is the target of the byte[]/value pairs stored in the leaves. We want to keep these
* separate for caching purposes.
*/
- public void write(TrieNode node, ByteBuffer index, FileChannel data, Map<TrieNode, Short> locationMap) throws IOException;
+ public void write(TrieNode node, Block index, DataFile data, Map<TrieNode, Short> locationMap) throws IOException;
}
private static class TrieBranchWriter implements TrieNodeWriter {
- public void write(TrieNode node, Block index, FileChannel data, Map<TrieNode, Short> locationMap) throws IOException {
+ public void write(TrieNode node, Block index, DataFile data, Map<TrieNode, Short> locationMap) throws IOException {
TrieBranch branch = (TrieBranch)node;
if (branch.term != null) {
writeTrieNode(branch.term, index, data, locationMap);
@@ -188,8 +188,8 @@
locationMap.put(branch, (short)index.position());
- index.put((branch.term == null) ? TYPE_BRANCH_NOTERM : TYPE_BRANCH_TERM);
- index.put((byte)0xFF); // Padding to keep things short-aligned. 0xFF is more visible in hexdump than 0x00.
+ index.putByte((branch.term == null) ? TYPE_BRANCH_NOTERM : TYPE_BRANCH_TERM);
+ index.putByte((byte)0xFF); // Padding to keep things short-aligned. 0xFF is more visible in hexdump than 0x00.
index.putInt(branch.offset);
if (branch.term != null) {
index.putShort(locationMap.get(branch.term));
@@ -208,8 +208,8 @@
long keyLocation = data.write(leaf.entry);
locationMap.put(leaf, (short)index.position());
- index.put(TYPE_LEAF);
- index.put((byte)0xFF); // Pad to 16-bit aligned.
+ index.putByte(TYPE_LEAF);
+ index.putByte((byte)0xFF); // Pad to 16-bit aligned.
index.putLong(keyLocation);
}
}
@@ -238,12 +238,12 @@
}
private TrieLeaf readTrieLeaf(Block index, DataFile dataFile) throws IOException {
- index.get(); // skip padding.
+ index.getByte(); // skip padding.
long keyLocation = index.getLong();
DataEntry entry = dataFile.getEntry(keyLocation);
- return new TrieLeaf(entry, false);
+ return new TrieLeaf(entry);
}
private static Map<Class, TrieNodeSizer> sizerMap = new HashMap<Class, TrieNodeSizer>();
Modified: projects/xa2/object-pool/src/trie/MemoryTrie.java
===================================================================
--- projects/xa2/object-pool/src/trie/MemoryTrie.java 2008-05-14 05:01:12 UTC (rev 937)
+++ projects/xa2/object-pool/src/trie/MemoryTrie.java 2008-05-14 05:06:35 UTC (rev 938)
@@ -5,6 +5,8 @@
*/
package trie;
+import java.io.IOException;
+
import data.DataEntry;
/**
@@ -77,9 +79,13 @@
return false;
}
- int cmp = lhs.slice(lhsOff, len).compareTo(rhs.slice(rhsOff, len));
+ try {
+ int cmp = lhs.slice(lhsOff, len).compareTo(rhs.slice(rhsOff, len));
- return (cmp == 0);
+ return (cmp == 0);
+ } catch (IOException ei) {
+ throw new IllegalStateException("Failed to compare entries", ei);
+ }
}
}
@@ -114,38 +120,42 @@
// lcp/offset of the new node.
aLeaf = newNode;
- DataEntry lhs = oldNode.aLeaf.entry.rewind();
- DataEntry rhs = newNode.entry.rewind();
+ try {
+ DataEntry lhs = oldNode.aLeaf.entry.rewind();
+ DataEntry rhs = newNode.entry.rewind();
- // FIXME: Replace this loop with a compareTo.
- int i = 0;
- while (i < lhs.dataSize() && i < rhs.dataSize()) {
- byte lb = lhs.get();
- byte rb = rhs.get();
- if (lb != rb) {
- offset = i;
- children.insert(lb, oldNode);
- children.insert(rb, newNode);
+ // FIXME: Replace this loop with a compareTo.
+ int i = 0;
+ while (i < lhs.dataSize() && i < rhs.dataSize()) {
+ byte lb = lhs.get();
+ byte rb = rhs.get();
+ if (lb != rb) {
+ offset = i;
+ children.insert(lb, oldNode);
+ children.insert(rb, newNode);
- return; // Escape here.
+ return; // Escape here.
+ }
+ i++;
}
- i++;
- }
- if (i < lhs.dataSize()) {
- offset = i;
- children.insert(lhs.get(), oldNode);
- term = newNode;
- } else if (i < rhs.dataSize()) {
- if (oldNode instanceof TrieLeaf) {
+ if (i < lhs.dataSize()) {
offset = i;
- children.insert(rhs.get(), newNode);
- term = (TrieLeaf)oldNode;
+ children.insert(lhs.get(), oldNode);
+ term = newNode;
+ } else if (i < rhs.dataSize()) {
+ if (oldNode instanceof TrieLeaf) {
+ offset = i;
+ children.insert(rhs.get(), newNode);
+ term = (TrieLeaf)oldNode;
+ } else {
+ throw new IllegalStateException("Attempt to create new branch node with leaf > branch.");
+ }
} else {
- throw new IllegalStateException("Attempt to create new branch node with leaf > branch.");
+ throw new IllegalStateException("Attempt to create new branch node with equal children");
}
- } else {
- throw new IllegalStateException("Attempt to create new branch node with equal children");
+ } catch (IOException ei) {
+ throw new IllegalStateException("Unable to insert entry into trie", ei);
}
}
@@ -162,16 +172,20 @@
return term.insert(node, offset);
}
} else {
- // new node is expected to terminate in one of this nodes children.
- TrieNode child = children.lookup(node.entry.get(offset));
- if (child == null) {
- // this is the first node to be inserted on this branching key.
- children.insert(node.entry.get(offset), node);
- } else {
- // there is an existing child node branching on this branching key.
- if (!child.insert(node, offset)) {
- children.insert(node.entry.get(offset), new TrieBranch(child, node));
+ try {
+ // new node is expected to terminate in one of this nodes children.
+ TrieNode child = children.lookup(node.entry.get(offset));
+ if (child == null) {
+ // this is the first node to be inserted on this branching key.
+ children.insert(node.entry.get(offset), node);
+ } else {
+ // there is an existing child node branching on this branching key.
+ if (!child.insert(node, offset)) {
+ children.insert(node.entry.get(offset), new TrieBranch(child, node));
+ }
}
+ } catch (IOException ei) {
+ throw new IllegalStateException("Failed to insert leaf into trie", ei);
}
}
@@ -197,13 +211,17 @@
return 0;
}
} else {
- // new node is expected to terminate in one of this nodes children.
- child = children.lookup(key.get(offset));
- if (child != null) {
- return child.lookup(key, offset, valid);
- } else {
- valid[0] = false;
- return 0;
+ try {
+ // new node is expected to terminate in one of this nodes children.
+ child = children.lookup(key.get(offset));
+ if (child != null) {
+ return child.lookup(key, offset, valid);
+ } else {
+ valid[0] = false;
+ return 0;
+ }
+ } catch (IOException ei) {
+ throw new IllegalStateException("Failed to lookup entry in trie", ei);
}
}
}
More information about the Mulgara-svn
mailing list