[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