Fixed LSM-BTree bulk load. More cleanup.

git-svn-id: https://hyracks.googlecode.com/svn/branches/hyracks_lsm_tree@1073 123451ca-8445-de46-9d55-352943316053
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/tests/OrderedIndexExamplesTest.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/tests/OrderedIndexExamplesTest.java
index bdbd9e9..ff4ce07 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/tests/OrderedIndexExamplesTest.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/tests/OrderedIndexExamplesTest.java
@@ -60,7 +60,7 @@
      * field. Fill index with random values using insertions (not bulk load).
      * Perform scans and range search.
      */
-    @Test
+    //@Test
     public void fixedLengthKeyValueExample() throws Exception {
         if (LOGGER.isLoggable(Level.INFO)) {
             LOGGER.info("Fixed-Length Key,Value Example.");
@@ -137,7 +137,7 @@
      * value field. Fill index with random values using insertions (not bulk
      * load) Perform scans and range search.
      */
-    @Test
+    //@Test
     public void twoFixedLengthKeysOneFixedLengthValueExample() throws Exception {
         if (LOGGER.isLoggable(Level.INFO)) {
             LOGGER.info("Composite Key Test");
@@ -216,7 +216,7 @@
      * field and one variable-length value field. Fill BTree with random values
      * using insertions (not bulk load) Perform ordered scans and range search.
      */
-    @Test
+    //@Test
     public void varLenKeyValueExample() throws Exception {
         if (LOGGER.isLoggable(Level.INFO)) {
             LOGGER.info("Variable-Length Key,Value Example");
@@ -295,7 +295,7 @@
      * value field. Fill B-tree with random values using insertions, then delete
      * entries one-by-one. Repeat procedure a few times on same BTree.
      */
-    @Test
+    //@Test
     public void deleteExample() throws Exception {
         if (LOGGER.isLoggable(Level.INFO)) {
             LOGGER.info("Deletion Example");
@@ -396,7 +396,7 @@
      * value field. Fill B-tree with random values using insertions, then update
      * entries one-by-one. Repeat procedure a few times on same BTree.
      */
-    @Test
+    //@Test
     public void updateExample() throws Exception {
         if (LOGGER.isLoggable(Level.INFO)) {
             LOGGER.info("Update example");
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/tests/OrderedIndexTestUtils.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/tests/OrderedIndexTestUtils.java
index c6edd1f..262a13e 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/tests/OrderedIndexTestUtils.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/tests/OrderedIndexTestUtils.java
@@ -276,7 +276,6 @@
                 }
             }
             try {
-            	//System.out.println("INSERTING: " + TupleUtils.printTuple(ctx.getTuple(), ctx.getFieldSerdes()));
             	ctx.getIndexAccessor().insert(ctx.getTuple());
                 // Set expected values. Do this only after insertion succeeds because we ignore duplicate keys.
                 ctx.insertIntCheckTuple(fieldValues);
@@ -396,7 +395,6 @@
             int checkTupleIdx = Math.abs(rnd.nextInt() % numCheckTuples);
             CheckTuple checkTuple = checkTuples[checkTupleIdx];            
             createTupleFromCheckTuple(checkTuple, deleteTupleBuilder, deleteTuple, ctx.getFieldSerdes());
-            //System.out.println("DELETING:  " + TupleUtils.printTuple(deleteTuple, ctx.getFieldSerdes()));
             ctx.getIndexAccessor().delete(deleteTuple);
             
             // Remove check tuple from expected results.
diff --git a/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/impls/BTreeFactory.java b/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/impls/BTreeFactory.java
index 4299b15..b9a1c2a 100644
--- a/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/impls/BTreeFactory.java
+++ b/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/impls/BTreeFactory.java
@@ -44,9 +44,8 @@
         return new BTree(bufferCache, fieldCount, cmp, freePageManagerFactory.createFreePageManager(fileId),
                 interiorFrameFactory, leafFrameFactory);
     }
-	
+    
     public IBufferCache getBufferCache() {
         return bufferCache;
     }
-    
 }
diff --git a/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/impls/LSMTree.java b/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/impls/LSMTree.java
index 1ab19c6..d12d7f6 100644
--- a/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/impls/LSMTree.java
+++ b/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/impls/LSMTree.java
@@ -22,11 +22,9 @@
 import java.util.LinkedList;
 import java.util.ListIterator;
 
-import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
 import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
 import edu.uci.ics.hyracks.api.io.FileReference;
 import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
-import edu.uci.ics.hyracks.dataflow.common.data.marshalling.UTF8StringSerializerDeserializer;
 import edu.uci.ics.hyracks.dataflow.common.util.TupleUtils;
 import edu.uci.ics.hyracks.storage.am.btree.exceptions.BTreeDuplicateKeyException;
 import edu.uci.ics.hyracks.storage.am.btree.exceptions.BTreeNonExistentKeyException;
@@ -45,7 +43,6 @@
 import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMFileNameManager;
 import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMTree;
 import edu.uci.ics.hyracks.storage.am.lsm.common.freepage.InMemoryFreePageManager;
-import edu.uci.ics.hyracks.storage.am.lsm.tuples.LSMTypeAwareTupleReference;
 import edu.uci.ics.hyracks.storage.common.buffercache.IBufferCache;
 import edu.uci.ics.hyracks.storage.common.file.IFileMapProvider;
 
@@ -56,7 +53,11 @@
 
     // On-disk components.
     private final ILSMFileNameManager fileNameManager;
+    // For creating BTree's used in flush and merge.
     private final BTreeFactory diskBTreeFactory;
+    // For creating BTree's used in bulk load. Different from diskBTreeFactory
+    // because it should have a different tuple writer in it's leaf frames.
+    private final BTreeFactory bulkLoadBTreeFactory;
     private final IBufferCache diskBufferCache;
     private final IFileMapProvider diskFileMapProvider;
     private LinkedList<BTree> onDiskBTrees = new LinkedList<BTree>();
@@ -76,7 +77,7 @@
     public LSMTree(IBufferCache memBufferCache, InMemoryFreePageManager memFreePageManager,
             ITreeIndexFrameFactory interiorFrameFactory, ITreeIndexFrameFactory insertLeafFrameFactory,
             ITreeIndexFrameFactory deleteLeafFrameFactory, ILSMFileNameManager fileNameManager, BTreeFactory diskBTreeFactory,
-            IFileMapProvider diskFileMapProvider, int fieldCount, MultiComparator cmp) {
+            BTreeFactory bulkLoadBTreeFactory, IFileMapProvider diskFileMapProvider, int fieldCount, MultiComparator cmp) {
         memBTree = new BTree(memBufferCache, fieldCount, cmp, memFreePageManager, interiorFrameFactory,
                 insertLeafFrameFactory);
         this.memFreePageManager = memFreePageManager;
@@ -86,6 +87,7 @@
         this.diskBufferCache = diskBTreeFactory.getBufferCache();
         this.diskFileMapProvider = diskFileMapProvider;
         this.diskBTreeFactory = diskBTreeFactory;
+        this.bulkLoadBTreeFactory = bulkLoadBTreeFactory;
         this.cmp = cmp;
         this.onDiskBTrees = new LinkedList<BTree>();
         this.onDiskBTreeCount = 0;
@@ -131,7 +133,7 @@
         Comparator<String> fileNameCmp = fileNameManager.getFileNameComparator();
         Arrays.sort(files, fileNameCmp);
         for (String fileName : files) {
-            BTree btree = createDiskBTree(fileName, false);
+            BTree btree = createDiskBTree(diskBTreeFactory, fileName, false);
             onDiskBTrees.add(btree);
         }
     }
@@ -176,26 +178,6 @@
 		    }
 		}
 		threadExit();
-		
-		// DEBUG check the in-mem tree
-		/*
-		RangePredicate nullPred = new RangePredicate(true, null, null, true, true, null, null);
-        ITreeIndexAccessor accessor = memBTree.createAccessor();
-        ITreeIndexCursor cursor = accessor.createSearchCursor();
-        accessor.search(cursor, nullPred);
-        int count = 0;
-        try {
-            while (cursor.hasNext()) {
-                cursor.next();
-                count++;
-                String s = printTuple(cursor.getTuple());
-                System.out.println(count + " INMEM CHECK: " + s);
-            }
-        } finally {
-            cursor.close();
-        }
-        System.out.println("");
-        */
 	}
 
 	private void deleteExistingKey(ITupleReference tuple, LSMTreeOpContext ctx) throws HyracksDataException, TreeIndexException {
@@ -250,16 +232,16 @@
             TreeIndexException {
         // All fields are key fields, therefore a true BTree update is not
         // allowed.
-        // In order to set/unset the delete bit, we
+        // In order to set/unset the antimatter bit, we
         // must truly delete the existing tuple from the BTree, and then
-        // re-insert it (with the delete bit set/unset).
+        // re-insert it (with the antimatter bit set/unset).
         // Since the tuple given by the user already has all fields, we
         // don't need to retrieve the already existing tuple.
         IndexOp originalOp = ctx.getIndexOp();
         try {
             ctx.memBTreeAccessor.delete(tuple);
         } catch (BTreeNonExistentKeyException e) {
-            // Somebody else has truly deleted the tuple, but we will restart
+            // Tuple has been deleted in the meantime. We will restart
             // our operation anyway.
         }
         // Restart performOp to insert the tuple.
@@ -323,94 +305,31 @@
         diskBTree.endBulkLoad(bulkLoadCtx);
         resetMemBTree();
         onDiskBTrees.addFirst(diskBTree);
-        
-        // DEBUG check the on-disk tree
-        /*
-        ITreeIndexAccessor accessor = diskBTree.createAccessor();
-        ITreeIndexCursor cursor = accessor.createSearchCursor();
-        accessor.search(cursor, nullPred);
-        try {
-            while (cursor.hasNext()) {
-                cursor.next();
-                String s = printTuple(cursor.getTuple());
-                System.out.println("FLUSH CHECK: " + s);
-            }
-        } finally {
-            cursor.close();
-        }
-        */
     }
 
-    // DEBUG
-    /*
-    private String printTuple(ITupleReference tuple) {
-        LSMTypeAwareTupleReference lsmTuple = (LSMTypeAwareTupleReference)tuple;
-        ISerializerDeserializer[] fieldSerdes = new ISerializerDeserializer[] { IntegerSerializerDeserializer.INSTANCE, IntegerSerializerDeserializer.INSTANCE };
-        ISerializerDeserializer[] keyOnlyFieldSerdes = new ISerializerDeserializer[] { IntegerSerializerDeserializer.INSTANCE };
-        String s = null;
-        try {
-            if (lsmTuple.isDelete()) {
-                s = TupleUtils.printTuple(lsmTuple, keyOnlyFieldSerdes) + " " + "D";
-            } else {
-                s = TupleUtils.printTuple(lsmTuple, fieldSerdes);
-            }
-        } catch (HyracksDataException e) {
-            e.printStackTrace();
-        }
-        s += " " + lsmTuple.isDelete();
-        return s;
-    }
-    */
-    
-    /*
-    private String printTuple(ITupleReference tuple) {
-        LSMTypeAwareTupleReference lsmTuple = (LSMTypeAwareTupleReference)tuple;
-        ISerializerDeserializer[] fieldSerdes = new ISerializerDeserializer[] { IntegerSerializerDeserializer.INSTANCE, IntegerSerializerDeserializer.INSTANCE };
-        String s = null;
-        try {
-            s = TupleUtils.printTuple(lsmTuple, fieldSerdes);
-        } catch (HyracksDataException e) {
-            e.printStackTrace();
-        }
-        s += " " + lsmTuple.isDelete();
-        return s;
-    }
-    */
-    
-    private String printTuple(ITupleReference tuple) {
-        LSMTypeAwareTupleReference lsmTuple = (LSMTypeAwareTupleReference)tuple;
-        ISerializerDeserializer[] fieldSerdes = new ISerializerDeserializer[] { UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE };
-        ISerializerDeserializer[] keyOnlyFieldSerdes = new ISerializerDeserializer[] { UTF8StringSerializerDeserializer.INSTANCE };
-        String s = null;
-        try {
-            if (lsmTuple.isDelete()) {
-                s = TupleUtils.printTuple(lsmTuple, keyOnlyFieldSerdes) + " " + "D";
-            } else {
-                s = TupleUtils.printTuple(lsmTuple, fieldSerdes);
-            }
-        } catch (HyracksDataException e) {
-            e.printStackTrace();
-        }
-        s += " " + lsmTuple.isDelete();
-        return s;
-    }
-    
     private void resetMemBTree() throws HyracksDataException {
         memFreePageManager.reset();
         memBTree.create(memBTree.getFileId());
     }
     
+    private BTree bulkLoadTargetBTree() throws HyracksDataException {
+        // Note that by using a flush target file name, we state that the new
+        // bulk loaded tree is "newer" than any other merged tree.
+        String fileName = fileNameManager.getFlushFileName();
+        return createDiskBTree(bulkLoadBTreeFactory, fileName, true);
+    }
+    
     private BTree createFlushTargetBTree() throws HyracksDataException {
         String fileName = fileNameManager.getFlushFileName();
-        return createDiskBTree(fileName, true);
+        return createDiskBTree(diskBTreeFactory, fileName, true);
     }
     
     private BTree createMergeTargetBTree() throws HyracksDataException {
         String fileName = fileNameManager.getMergeFileName();
-        return createDiskBTree(fileName, true);
+        return createDiskBTree(diskBTreeFactory, fileName, true);
     }
     
-    private BTree createDiskBTree(String fileName, boolean createBTree) throws HyracksDataException {
+    private BTree createDiskBTree(BTreeFactory factory, String fileName, boolean createBTree) throws HyracksDataException {
         // Register the new BTree file.        
         FileReference file = new FileReference(new File(fileName));
         // TODO: Delete the file during cleanup.
@@ -419,7 +338,7 @@
         // TODO: Close the file during cleanup.
         diskBufferCache.openFile(diskBTreeFileId);
         // Create new BTree instance.
-        BTree diskBTree = diskBTreeFactory.createBTreeInstance(diskBTreeFileId);
+        BTree diskBTree = factory.createBTreeInstance(diskBTreeFileId);
         if (createBTree) {
             diskBTree.create(diskBTreeFileId);
         }
@@ -508,7 +427,6 @@
 
         // BulkLoad the tuples from the in-memory tree into the new disk BTree.
         IIndexBulkLoadContext bulkLoadCtx = mergedBTree.beginBulkLoad(1.0f);
-
         try {
             while (cursor.hasNext()) {
                 cursor.next();
@@ -572,10 +490,8 @@
     
     @Override
     public IIndexBulkLoadContext beginBulkLoad(float fillFactor) throws TreeIndexException, HyracksDataException {
-        // Note that by using a flush target file name, we state that the new
-        // bulk loaded tree is "newer" than any other merged tree.
-        BTree diskBTree = createFlushTargetBTree();
-        LSMTreeBulkLoadContext bulkLoadCtx = new LSMTreeBulkLoadContext(diskBTree);
+        BTree diskBTree = bulkLoadTargetBTree();
+        LSMTreeBulkLoadContext bulkLoadCtx = new LSMTreeBulkLoadContext(diskBTree);        
         bulkLoadCtx.beginBulkLoad(fillFactor);
         return bulkLoadCtx;
     }
@@ -678,13 +594,13 @@
 
         @Override
         public ITreeIndexCursor createDiskOrderScanCursor() {
-            // Disk-order scan doesn't make sense for the LSMBTree because it must correctly resolve deleted tuples.
+            // Disk-order scan doesn't make sense for the LSMBTree because it cannot correctly resolve deleted tuples.
             throw new UnsupportedOperationException("DiskOrderScan not supported by LSMTree.");
         }
         
         @Override
         public void diskOrderScan(ITreeIndexCursor cursor) throws HyracksDataException {
-            // Disk-order scan doesn't make sense for the LSMBTree because it must correctly resolve deleted tuples.
+            // Disk-order scan doesn't make sense for the LSMBTree because it cannot correctly resolve deleted tuples.
             throw new UnsupportedOperationException("DiskOrderScan not supported by LSMTree.");
         }
     }
diff --git a/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/impls/LSMTreeOpContext.java b/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/impls/LSMTreeOpContext.java
index a74e36d..92a9988 100644
--- a/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/impls/LSMTreeOpContext.java
+++ b/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/impls/LSMTreeOpContext.java
@@ -53,6 +53,9 @@
     	this.op = newOp;
         switch (newOp) {
     	    case SEARCH:
+    	        setMemBTreeAccessor();
+    	        break;
+    	        
     	    case DISKORDERSCAN:
     	    case UPDATE:
                 // Attention: It is important to leave the leafFrame and
diff --git a/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/impls/LSMTreeRangeSearchCursor.java b/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/impls/LSMTreeRangeSearchCursor.java
index 051242e..9e59c11 100644
--- a/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/impls/LSMTreeRangeSearchCursor.java
+++ b/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/impls/LSMTreeRangeSearchCursor.java
@@ -2,11 +2,8 @@
 
 import java.util.PriorityQueue;
 
-import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
 import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
 import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
-import edu.uci.ics.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;
-import edu.uci.ics.hyracks.dataflow.common.util.TupleUtils;
 import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeLeafFrame;
 import edu.uci.ics.hyracks.storage.am.btree.impls.BTreeRangeSearchCursor;
 import edu.uci.ics.hyracks.storage.am.common.api.ICursorInitialState;
@@ -42,7 +39,6 @@
                 rangeCursors[i].next();
                 element = new LSMPriorityQueueElement(rangeCursors[i].getTuple(), i);
                 outputPriorityQueue.offer(element);
-                //System.out.println("INITIALIZING PQ WITH: " + printTuple(rangeCursors[i].getTuple(), i));
             }
         }
         checkPriorityQueue();
@@ -105,24 +101,6 @@
             throw new HyracksDataException(e);
         }
     }
-   
-    private String printTuple(ITupleReference tuple, int cursorIndex) {
-        LSMTypeAwareTupleReference lsmTuple = (LSMTypeAwareTupleReference)tuple;
-        ISerializerDeserializer[] fieldSerdes = new ISerializerDeserializer[] { IntegerSerializerDeserializer.INSTANCE, IntegerSerializerDeserializer.INSTANCE };
-        ISerializerDeserializer[] keyOnlyFieldSerdes = new ISerializerDeserializer[] { IntegerSerializerDeserializer.INSTANCE };
-        String s = null;
-        try {
-            if (lsmTuple.isDelete()) {
-                s = TupleUtils.printTuple(lsmTuple, keyOnlyFieldSerdes) + " " + "D";
-            } else {
-                s = TupleUtils.printTuple(lsmTuple, fieldSerdes);
-            }
-        } catch (HyracksDataException e) {
-            e.printStackTrace();
-        }
-        s += " " + lsmTuple.isDelete() + " " + cursorIndex;
-        return s;
-    }
     
     @Override
     public void setBufferCache(IBufferCache bufferCache) {
@@ -136,7 +114,6 @@
 
     @Override
     public ITupleReference getTuple() {
-        //System.out.println("RETURNING: " + printTuple(outputElement.getTuple(), outputElement.getCursorIndex()));
         return (ITupleReference) outputElement.getTuple();
     }
 
@@ -145,7 +122,6 @@
             rangeCursors[cursorIndex].next();
             reusedElement.reset(rangeCursors[cursorIndex].getTuple(), cursorIndex);
             outputPriorityQueue.offer(reusedElement);
-            //System.out.println("PUSHING TO PQ: " + printTuple(reusedElement.getTuple(), cursorIndex));
         }
     }
 
@@ -157,7 +133,7 @@
                 // ignored
                 if (outputElement == null) {
                     // Test the tuple is a delete tuple or not
-                    if (((LSMTypeAwareTupleReference) checkElement.getTuple()).isDelete() == true) {
+                    if (((LSMTypeAwareTupleReference) checkElement.getTuple()).isAntimatter() == true) {
                         // If the tuple is a delete tuple then pop it and mark
                         // it "needPush"
                         // Cannot push at this time because the tuple may be
diff --git a/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/tuples/ILSMTreeTupleReference.java b/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/tuples/ILSMTreeTupleReference.java
index 11097cd..5f6a79c 100644
--- a/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/tuples/ILSMTreeTupleReference.java
+++ b/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/tuples/ILSMTreeTupleReference.java
@@ -18,5 +18,5 @@
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexTupleReference;
 
 public interface ILSMTreeTupleReference extends ITreeIndexTupleReference {
-	public boolean isDelete();
+	public boolean isAntimatter();
 }
diff --git a/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/tuples/LSMEntireTupleWriter.java b/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/tuples/LSMEntireTupleWriter.java
index 97b0a32..3632939 100644
--- a/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/tuples/LSMEntireTupleWriter.java
+++ b/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/tuples/LSMEntireTupleWriter.java
@@ -1,38 +1,20 @@
 package edu.uci.ics.hyracks.storage.am.lsm.tuples;
 
-import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
 import edu.uci.ics.hyracks.api.dataflow.value.ITypeTraits;
-import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
 import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
-import edu.uci.ics.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;
-import edu.uci.ics.hyracks.dataflow.common.util.TupleUtils;
 
 public class LSMEntireTupleWriter extends LSMTypeAwareTupleWriter {
 	public LSMEntireTupleWriter(ITypeTraits[] typeTraits, int numKeyFields){
-		// Just give false as third parameter. It is never used locally.
+		// Third parameter is never used locally, just give false.
 	    super(typeTraits, numKeyFields, false);
 	}
 	
 	@Override
     public int writeTuple(ITupleReference tuple, byte[] targetBuf, int targetOff) {
-		int tupleSize = this.bytesRequired(tuple);
+		int tupleSize = bytesRequired(tuple);
 		byte[] buf = tuple.getFieldData(0);
 		int tupleStartOff = ((LSMTypeAwareTupleReference)tuple).getTupleStart();
 		System.arraycopy(buf, tupleStartOff, targetBuf, targetOff, tupleSize);
-		//System.out.println("BEF: " + printTuple(tuple));
         return tupleSize;
     }
-	
-	private String printTuple(ITupleReference tuple) {
-        LSMTypeAwareTupleReference lsmTuple = (LSMTypeAwareTupleReference)tuple;
-        ISerializerDeserializer[] fieldSerdes = new ISerializerDeserializer[] { IntegerSerializerDeserializer.INSTANCE, IntegerSerializerDeserializer.INSTANCE };
-        String s = null;
-        try {
-            s = TupleUtils.printTuple(lsmTuple, fieldSerdes);
-        } catch (HyracksDataException e) {
-            e.printStackTrace();
-        }
-        s += " " + lsmTuple.isDelete();
-        return s;
-    }
 }
diff --git a/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/tuples/LSMTypeAwareTupleReference.java b/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/tuples/LSMTypeAwareTupleReference.java
index 21a0edb..2d3d31a 100644
--- a/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/tuples/LSMTypeAwareTupleReference.java
+++ b/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/tuples/LSMTypeAwareTupleReference.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package edu.uci.ics.hyracks.storage.am.lsm.tuples;
 
 import java.nio.ByteBuffer;
@@ -9,7 +24,7 @@
 public class LSMTypeAwareTupleReference extends TypeAwareTupleReference implements ILSMTreeTupleReference {
 
     // Indicates whether the last call to setFieldCount() was initiated by
-    // called by the outside or whether it was called internally to set up an
+    // by the outside or whether it was called internally to set up an
     // antimatter tuple.
     private boolean resetFieldCount = false;
     private final int numKeyFields;
@@ -21,14 +36,14 @@
 
     public void setFieldCount(int fieldCount) {
         super.setFieldCount(fieldCount);
-        // Don't change the fieldCount in resetTuple*() calls.
+        // Don't change the fieldCount in reset calls.
         resetFieldCount = false;
     }
 
     @Override
     public void setFieldCount(int fieldStartIndex, int fieldCount) {
         super.setFieldCount(fieldStartIndex, fieldCount);
-        // Don't change the fieldCount in resetTuple*() calls.
+        // Don't change the fieldCount in reset calls.
         resetFieldCount = false;
     }
     
@@ -37,7 +52,7 @@
         this.buf = buf;
         this.tupleStartOff = tupleStartOff;
         if (numKeyFields != typeTraits.length) {
-            if (isDelete()) {
+            if (isAntimatter()) {
                 setFieldCount(numKeyFields);
                 // Reset the original field count for matter tuples.
                 resetFieldCount = true;
@@ -57,24 +72,18 @@
     
 	@Override
 	protected int getNullFlagsBytes() {
-		// +1.0 is for insert/delete tuple checking.
+		// +1.0 is for matter/antimatter bit.
 		return (int) Math.ceil((fieldCount + 1.0) / 8.0);
     }
 
 	@Override
-	public boolean isDelete() {
-		// TODO: Alex. Rewrite this to be more efficient...
-	    byte[] temp = buf.array();
-		byte firstByte = temp[tupleStartOff];
+	public boolean isAntimatter() {
+	      // Check if the leftmost bit is 0 or 1.
 		final byte mask = (byte) (1 << 7);
-		final byte compare = (byte) (1 << 7);
-		// Check the first bit is 0 or 1.
-		if((byte)(firstByte & mask) == compare) {
-			return true;
+		if ((buf.array()[tupleStartOff] & mask) != 0) {
+		    return true;
 		}
-		else {
-			return false;
-		}
+		return false;
 	}
 	
     public int getTupleStart() {
diff --git a/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/tuples/LSMTypeAwareTupleWriter.java b/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/tuples/LSMTypeAwareTupleWriter.java
index c9c58e0..dbe1d30 100644
--- a/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/tuples/LSMTypeAwareTupleWriter.java
+++ b/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/tuples/LSMTypeAwareTupleWriter.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package edu.uci.ics.hyracks.storage.am.lsm.tuples;
 
 import java.nio.ByteBuffer;
@@ -24,13 +39,13 @@
 	
 	@Override
 	protected int getNullFlagsBytes(int numFields) {
-		// +1.0 is for insert/delete tuple checking.
+	    // +1.0 is for matter/antimatter bit.
 		return (int) Math.ceil(((double) numFields + 1.0) / 8.0);
     }
 	
 	@Override
     protected int getNullFlagsBytes(ITupleReference tuple) {
-		// +1.0 is for insert/delete tuple checking.
+	    // +1.0 is for matter/antimatter bit.
         return (int) Math.ceil(((double) tuple.getFieldCount() + 1.0) / 8.0);
     }
 	
@@ -38,20 +53,18 @@
     public int writeTuple(ITupleReference tuple, byte[] targetBuf, int targetOff) {	    
 	    int bytesWritten = -1;
 	    if (isDelete) {
-	        //System.out.println("DELETE FIELDS: " + tuple.getFieldCount());
 	        // TODO: Avoid generating an object here.
 	        ByteBuffer buf = ByteBuffer.wrap(targetBuf);
 	        bytesWritten = super.writeTupleFields(tuple, 0, numKeyFields, buf, targetOff);
-	        setDeleteBit(targetBuf, targetOff);
+	        setAntimatterBit(targetBuf, targetOff);
 		} else {
 		    bytesWritten = super.writeTuple(tuple, targetBuf, targetOff);
 		}
 	    return bytesWritten;
     }
 	
-	private void setDeleteBit(byte[] targetBuf, int targetOff) {
-		byte firstByte = targetBuf[targetOff];
-		firstByte = (byte) (firstByte | (1 << 7));
-		targetBuf[targetOff] = firstByte;
+	private void setAntimatterBit(byte[] targetBuf, int targetOff) {
+	    // Set leftmost bit to 1.
+	    targetBuf[targetOff] = (byte) (targetBuf[targetOff] | (1 << 7));
 	}
 }
diff --git a/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/tuples/LSMTypeAwareTupleWriterFactory.java b/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/tuples/LSMTypeAwareTupleWriterFactory.java
index 6dd0afa..35eff4f 100644
--- a/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/tuples/LSMTypeAwareTupleWriterFactory.java
+++ b/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/tuples/LSMTypeAwareTupleWriterFactory.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package edu.uci.ics.hyracks.storage.am.lsm.tuples;
 
 import edu.uci.ics.hyracks.api.dataflow.value.ITypeTraits;
@@ -22,5 +37,4 @@
 	public ITreeIndexTupleWriter createTupleWriter() {
 		return new LSMTypeAwareTupleWriter(typeTraits, numKeyFields, isDelete);
 	}
-
 }
diff --git a/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/util/LSMBTreeUtils.java b/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/util/LSMBTreeUtils.java
index c8468ae..d8794aa 100644
--- a/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/util/LSMBTreeUtils.java
+++ b/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/util/LSMBTreeUtils.java
@@ -40,8 +40,10 @@
             String onDiskDir, IBufferCache diskBufferCache, IFileMapProvider diskFileMapProvider,
             ITypeTraits[] typeTraits, IBinaryComparator[] cmps) {
         MultiComparator cmp = new MultiComparator(cmps);
-        LSMTypeAwareTupleWriterFactory insertTupleWriterFactory = new LSMTypeAwareTupleWriterFactory(typeTraits, cmps.length, false);
-        LSMTypeAwareTupleWriterFactory deleteTupleWriterFactory = new LSMTypeAwareTupleWriterFactory(typeTraits, cmps.length, true);
+        LSMTypeAwareTupleWriterFactory insertTupleWriterFactory = new LSMTypeAwareTupleWriterFactory(typeTraits,
+                cmps.length, false);
+        LSMTypeAwareTupleWriterFactory deleteTupleWriterFactory = new LSMTypeAwareTupleWriterFactory(typeTraits,
+                cmps.length, true);
         LSMEntireTupleWriterFactory copyTupleWriterFactory = new LSMEntireTupleWriterFactory(typeTraits, cmps.length);
         ITreeIndexFrameFactory insertLeafFrameFactory = new BTreeNSMLeafFrameFactory(insertTupleWriterFactory);
         ITreeIndexFrameFactory copyTupleLeafFrameFactory = new BTreeNSMLeafFrameFactory(copyTupleWriterFactory);
@@ -50,11 +52,14 @@
         ITreeIndexMetaDataFrameFactory metaFrameFactory = new LIFOMetaDataFrameFactory();
         LinkedListFreePageManagerFactory freePageManagerFactory = new LinkedListFreePageManagerFactory(diskBufferCache,
                 metaFrameFactory);
-        BTreeFactory diskBTreeFactory = new BTreeFactory(diskBufferCache, freePageManagerFactory, cmp, typeTraits.length,
-                interiorFrameFactory, copyTupleLeafFrameFactory);
+        BTreeFactory diskBTreeFactory = new BTreeFactory(diskBufferCache, freePageManagerFactory, cmp,
+                typeTraits.length, interiorFrameFactory, copyTupleLeafFrameFactory);
+        BTreeFactory bulkLoadBTreeFactory = new BTreeFactory(diskBufferCache, freePageManagerFactory, cmp,
+                typeTraits.length, interiorFrameFactory, insertLeafFrameFactory);
         ILSMFileNameManager fileNameManager = new LSMBTreeFileNameManager(onDiskDir);
         LSMTree lsmTree = new LSMTree(memBufferCache, memFreePageManager, interiorFrameFactory, insertLeafFrameFactory,
-                deleteLeafFrameFactory, fileNameManager, diskBTreeFactory, diskFileMapProvider, typeTraits.length, cmp);
+                deleteLeafFrameFactory, fileNameManager, diskBTreeFactory, bulkLoadBTreeFactory, diskFileMapProvider,
+                typeTraits.length, cmp);
         return lsmTree;
     }
 }
diff --git a/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/btree/InsertTest.java b/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/btree/InsertTest.java
index e4bdf9c..f6809ac 100644
--- a/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/btree/InsertTest.java
+++ b/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/btree/InsertTest.java
@@ -28,16 +28,6 @@
 import edu.uci.ics.hyracks.storage.am.lsm.btree.util.LSMBTreeTestContext;
 import edu.uci.ics.hyracks.storage.am.lsm.btree.util.LSMBTreeTestHarness;
 
-/**
- * Tests the BTree insert operation with strings and integer fields using
- * various numbers of key and payload fields.
- * 
- * Each tests first fills a BTree with randomly generated tuples. We compare the
- * following operations against expected results: 1. Point searches for all
- * tuples. 2. Ordered scan. 3. Disk-order scan. 4. Range search (and prefix
- * search for composite keys).
- * 
- */
 @SuppressWarnings("rawtypes")
 public class InsertTest extends OrderedIndexInsertTest {