Changed the btree page split to use tuples sizes in order to determine which tuples are going to move to the new page and added a test case.

git-svn-id: https://hyracks.googlecode.com/svn/branches/hyracks_lsm_tree@2355 123451ca-8445-de46-9d55-352943316053
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/BTreeNSMInteriorFrame.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/BTreeNSMInteriorFrame.java
index ef47a64..61fed72 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/BTreeNSMInteriorFrame.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/BTreeNSMInteriorFrame.java
@@ -180,14 +180,28 @@
         ByteBuffer right = rightFrame.getBuffer();
         int tupleCount = getTupleCount();
 
-        // Find split point, and determine into which frame the new tuple should be inserted into.
-        int tuplesToLeft = (tupleCount / 2) + (tupleCount % 2);
+        // Find split point, and determine into which frame the new tuple should
+        // be inserted into.
+        int tuplesToLeft;
         ITreeIndexFrame targetFrame = null;
-        frameTuple.resetByTupleIndex(this, tuplesToLeft - 1);
-        if (cmp.compare(tuple, frameTuple) <= 0) {
-            targetFrame = this;
-        } else {
+
+        int totalSize = 0;
+        int halfPageSize = buf.capacity() / 2 - getPageHeaderSize();
+        int i;
+        for (i = 0; i < tupleCount; ++i) {
+            frameTuple.resetByTupleIndex(this, i);
+            totalSize += tupleWriter.bytesRequired(frameTuple) + slotManager.getSlotSize();
+            if (totalSize >= halfPageSize) {
+                break;
+            }
+        }
+
+        if (cmp.compare(tuple, frameTuple) > 0) {
+            tuplesToLeft = i;
             targetFrame = rightFrame;
+        } else {
+            tuplesToLeft = i + 1;
+            targetFrame = this;
         }
         int tuplesToRight = tupleCount - tuplesToLeft;
 
@@ -208,7 +222,8 @@
 
         // Copy the split key to be inserted.
         // We must do so because setting the new split key will overwrite the
-        // old split key, and we cannot insert the existing split key at this point.
+        // old split key, and we cannot insert the existing split key at this
+        // point.
         ISplitKey savedSplitKey = splitKey.duplicate(tupleWriter.createTupleReference());
 
         // Set split key to be highest value in left page.
@@ -230,7 +245,8 @@
 
         // Insert the saved split key.
         int targetTupleIndex;
-        // it's safe to catch this exception since it will have been caught before reaching here
+        // it's safe to catch this exception since it will have been caught
+        // before reaching here
         try {
             targetTupleIndex = ((BTreeNSMInteriorFrame) targetFrame).findInsertTupleIndex(savedSplitKey.getTuple());
         } catch (TreeIndexException e) {
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/BTreeNSMLeafFrame.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/BTreeNSMLeafFrame.java
index a493226..3883b80 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/BTreeNSMLeafFrame.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/BTreeNSMLeafFrame.java
@@ -87,7 +87,8 @@
     public int findUpsertTupleIndex(ITupleReference tuple) throws TreeIndexException {
         int tupleIndex = slotManager.findTupleIndex(tuple, frameTuple, cmp, FindTupleMode.INCLUSIVE,
                 FindTupleNoExactMatchPolicy.HIGHER_KEY);
-        // Just return the found tupleIndex. The caller will make the final decision whether to insert or update.
+        // Just return the found tupleIndex. The caller will make the final
+        // decision whether to insert or update.
         return tupleIndex;
     }
 
@@ -95,14 +96,16 @@
     public ITupleReference getMatchingKeyTuple(ITupleReference searchTuple, int targetTupleIndex) {
         // Examine the tuple index to determine whether it is valid or not.
         if (targetTupleIndex != slotManager.getGreatestKeyIndicator()) {
-            // We need to check the key to determine whether it's an insert or an update/delete
+            // We need to check the key to determine whether it's an insert or
+            // an update/delete
             frameTuple.resetByTupleIndex(this, targetTupleIndex);
             if (cmp.compare(searchTuple, frameTuple) == 0) {
                 // The keys match, it's an update/delete
                 return frameTuple;
             }
         }
-        // Either the tuple index is a special indicator, or the keys don't match.
+        // Either the tuple index is a special indicator, or the keys don't
+        // match.
         // In those cases, we are definitely dealing with an insert.
         return null;
     }
@@ -138,17 +141,26 @@
         ByteBuffer right = rightFrame.getBuffer();
         int tupleCount = getTupleCount();
 
-        // Find split point, and determine into which frame the new tuple should be inserted into.
+        // Find split point, and determine into which frame the new tuple should
+        // be inserted into.
         int tuplesToLeft;
-        int mid = tupleCount / 2;
         ITreeIndexFrame targetFrame = null;
-        int tupleOff = slotManager.getTupleOff(slotManager.getSlotEndOff() + slotManager.getSlotSize() * mid);
-        frameTuple.resetByTupleOffset(buf, tupleOff);
+        int totalSize = 0;
+        int halfPageSize = buf.capacity() / 2 - getPageHeaderSize();
+        int i;
+        for (i = 0; i < tupleCount; ++i) {
+            frameTuple.resetByTupleIndex(this, i);
+            totalSize += tupleWriter.getCopySpaceRequired(frameTuple) + slotManager.getSlotSize();
+            if (totalSize >= halfPageSize) {
+                break;
+            }
+        }
+
         if (cmp.compare(tuple, frameTuple) >= 0) {
-            tuplesToLeft = mid + (tupleCount % 2);
+            tuplesToLeft = i + 1;
             targetFrame = rightFrame;
         } else {
-            tuplesToLeft = mid;
+            tuplesToLeft = i;
             targetFrame = this;
         }
         int tuplesToRight = tupleCount - tuplesToLeft;
@@ -173,7 +185,8 @@
 
         // Insert the new tuple.
         int targetTupleIndex;
-        // it's safe to catch this exception since it will have been caught before reaching here
+        // it's safe to catch this exception since it will have been caught
+        // before reaching here
         try {
             targetTupleIndex = ((BTreeNSMLeafFrame) targetFrame).findInsertTupleIndex(tuple);
         } catch (TreeIndexException e) {
@@ -182,8 +195,12 @@
         targetFrame.insert(tuple, targetTupleIndex);
 
         // Set the split key to be highest key in the left page.
-        tupleOff = slotManager.getTupleOff(slotManager.getSlotEndOff());
+        int tupleOff = slotManager.getTupleOff(slotManager.getSlotEndOff());
+        try {
         frameTuple.resetByTupleOffset(buf, tupleOff);
+        } catch (Exception e) {
+            throw new IllegalStateException(e);
+        }
         int splitKeySize = tupleWriter.bytesRequired(frameTuple, 0, cmp.getKeyFieldCount());
         splitKey.initData(splitKeySize);
         tupleWriter.writeTupleFields(frameTuple, 0, cmp.getKeyFieldCount(), splitKey.getBuffer().array(), 0);
diff --git a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/ITreeIndexTupleWriter.java b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/ITreeIndexTupleWriter.java
index 30e8f39..069ede8 100644
--- a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/ITreeIndexTupleWriter.java
+++ b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/ITreeIndexTupleWriter.java
@@ -36,4 +36,9 @@
     // the main idea is that the format of the written tuple may not be the same
     // as the format written by this writer
     public ITreeIndexTupleReference createTupleReference();
+    
+    // This method is only used by the BTree leaf frame split method since tuples
+    // in the LSM-BTree can be either matter or anti-matter tuple and we want to
+    // to calculate the size of all tuples in the frame.
+    public int getCopySpaceRequired(ITupleReference tuple);
 }
diff --git a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/tuples/SimpleTupleWriter.java b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/tuples/SimpleTupleWriter.java
index f5ec5f3..8cd8d98 100644
--- a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/tuples/SimpleTupleWriter.java
+++ b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/tuples/SimpleTupleWriter.java
@@ -23,12 +23,12 @@
 
 public class SimpleTupleWriter implements ITreeIndexTupleWriter {
 
-	// Write short in little endian to target byte array at given offset.
-	private static void writeShortL(short s, byte[] buf, int targetOff) {
-		buf[targetOff] = (byte)(s >> 8);
-		buf[targetOff + 1] = (byte)(s >> 0);
-	}
-	
+    // Write short in little endian to target byte array at given offset.
+    private static void writeShortL(short s, byte[] buf, int targetOff) {
+        buf[targetOff] = (byte) (s >> 8);
+        buf[targetOff + 1] = (byte) (s >> 0);
+    }
+
     @Override
     public int bytesRequired(ITupleReference tuple) {
         int bytes = getNullFlagsBytes(tuple) + getFieldSlotsBytes(tuple);
@@ -56,10 +56,10 @@
     public int writeTuple(ITupleReference tuple, ByteBuffer targetBuf, int targetOff) {
         return writeTuple(tuple, targetBuf.array(), targetOff);
     }
-    
+
     @Override
-	public int writeTuple(ITupleReference tuple, byte[] targetBuf, int targetOff) {
-    	int runner = targetOff;
+    public int writeTuple(ITupleReference tuple, byte[] targetBuf, int targetOff) {
+        int runner = targetOff;
         int nullFlagsBytes = getNullFlagsBytes(tuple);
         int fieldSlotsBytes = getFieldSlotsBytes(tuple);
         for (int i = 0; i < nullFlagsBytes; i++) {
@@ -68,18 +68,16 @@
         runner += fieldSlotsBytes;
         int fieldEndOff = 0;
         for (int i = 0; i < tuple.getFieldCount(); i++) {
-            System.arraycopy(tuple.getFieldData(i), tuple.getFieldStart(i), targetBuf, runner,
-                    tuple.getFieldLength(i));
+            System.arraycopy(tuple.getFieldData(i), tuple.getFieldStart(i), targetBuf, runner, tuple.getFieldLength(i));
             fieldEndOff += tuple.getFieldLength(i);
             runner += tuple.getFieldLength(i);
             writeShortL((short) fieldEndOff, targetBuf, targetOff + nullFlagsBytes + i * 2);
         }
         return runner - targetOff;
-	}
+    }
 
     @Override
-    public int writeTupleFields(ITupleReference tuple, int startField, int numFields, byte[] targetBuf,
-            int targetOff) {
+    public int writeTupleFields(ITupleReference tuple, int startField, int numFields, byte[] targetBuf, int targetOff) {
         int runner = targetOff;
         int nullFlagsBytes = getNullFlagsBytes(tuple, startField, numFields);
         for (int i = 0; i < nullFlagsBytes; i++) {
@@ -90,10 +88,9 @@
         int fieldEndOff = 0;
         int fieldCounter = 0;
         for (int i = startField; i < startField + numFields; i++) {
-            System.arraycopy(tuple.getFieldData(i), tuple.getFieldStart(i), targetBuf, runner,
-                    tuple.getFieldLength(i));
+            System.arraycopy(tuple.getFieldData(i), tuple.getFieldStart(i), targetBuf, runner, tuple.getFieldLength(i));
             fieldEndOff += tuple.getFieldLength(i);
-            runner += tuple.getFieldLength(i);            
+            runner += tuple.getFieldLength(i);
             writeShortL((short) fieldEndOff, targetBuf, targetOff + nullFlagsBytes + fieldCounter * 2);
             fieldCounter++;
         }
@@ -115,5 +112,9 @@
 
     protected int getFieldSlotsBytes(ITupleReference tuple, int startField, int numFields) {
         return numFields * 2;
-    }	
+    }
+
+    public int getCopySpaceRequired(ITupleReference tuple) {
+        return bytesRequired(tuple);
+    }
 }
diff --git a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/tuples/TypeAwareTupleWriter.java b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/tuples/TypeAwareTupleWriter.java
index 9730346..ab14441 100644
--- a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/tuples/TypeAwareTupleWriter.java
+++ b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/tuples/TypeAwareTupleWriter.java
@@ -87,8 +87,7 @@
     }
 
     @Override
-    public int writeTupleFields(ITupleReference tuple, int startField, int numFields, byte[] targetBuf,
-            int targetOff) {
+    public int writeTupleFields(ITupleReference tuple, int startField, int numFields, byte[] targetBuf, int targetOff) {
         int runner = targetOff;
         int nullFlagsBytes = getNullFlagsBytes(numFields);
         // write null indicator bits
@@ -106,8 +105,7 @@
         runner = encDec.getPos();
 
         for (int i = startField; i < startField + numFields; i++) {
-            System.arraycopy(tuple.getFieldData(i), tuple.getFieldStart(i), targetBuf, runner,
-                    tuple.getFieldLength(i));
+            System.arraycopy(tuple.getFieldData(i), tuple.getFieldStart(i), targetBuf, runner, tuple.getFieldLength(i));
             runner += tuple.getFieldLength(i);
         }
 
@@ -149,4 +147,8 @@
     public void setTypeTraits(ITypeTraits[] typeTraits) {
         this.typeTraits = typeTraits;
     }
+
+    public int getCopySpaceRequired(ITupleReference tuple) {
+        return bytesRequired(tuple);
+    }
 }
diff --git a/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/btree/tuples/LSMBTreeTupleWriter.java b/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/btree/tuples/LSMBTreeTupleWriter.java
index dd8d2b9..5943a82 100644
--- a/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/btree/tuples/LSMBTreeTupleWriter.java
+++ b/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/btree/tuples/LSMBTreeTupleWriter.java
@@ -41,6 +41,11 @@
     }
 	
 	@Override
+	public int getCopySpaceRequired(ITupleReference tuple) {
+        return super.bytesRequired(tuple);
+    }
+	
+	@Override
     public ITreeIndexTupleReference createTupleReference() {
         return new LSMBTreeTupleReference(typeTraits, numKeyFields);
     }
diff --git a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/btree/OrderedIndexExamplesTest.java b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/btree/OrderedIndexExamplesTest.java
index 3962d06..759a292 100644
--- a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/btree/OrderedIndexExamplesTest.java
+++ b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/btree/OrderedIndexExamplesTest.java
@@ -38,7 +38,6 @@
 import edu.uci.ics.hyracks.storage.am.btree.impls.RangePredicate;
 import edu.uci.ics.hyracks.storage.am.btree.util.BTreeUtils;
 import edu.uci.ics.hyracks.storage.am.common.TestOperationCallback;
-import edu.uci.ics.hyracks.storage.am.common.api.UnsortedInputException;
 import edu.uci.ics.hyracks.storage.am.common.api.IIndexAccessor;
 import edu.uci.ics.hyracks.storage.am.common.api.IIndexBulkLoader;
 import edu.uci.ics.hyracks.storage.am.common.api.IIndexCursor;
@@ -46,6 +45,7 @@
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexAccessor;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexCursor;
 import edu.uci.ics.hyracks.storage.am.common.api.TreeIndexException;
+import edu.uci.ics.hyracks.storage.am.common.api.UnsortedInputException;
 import edu.uci.ics.hyracks.storage.am.common.impls.TreeIndexDiskOrderScanCursor;
 import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
 
@@ -58,10 +58,9 @@
             throws TreeIndexException;
 
     /**
-     * Fixed-Length Key,Value Example.
-     * Create a tree index with one fixed-length key field and one fixed-length value
-     * field. Fill index with random values using insertions (not bulk load).
-     * Perform scans and range search.
+     * Fixed-Length Key,Value Example. Create a tree index with one fixed-length
+     * key field and one fixed-length value field. Fill index with random values
+     * using insertions (not bulk load). Perform scans and range search.
      */
     @Test
     public void fixedLengthKeyValueExample() throws Exception {
@@ -136,10 +135,79 @@
     }
 
     /**
-     * Composite Key Example (Non-Unique Index).
-     * Create a tree index with two fixed-length key fields and one fixed-length
-     * value field. Fill index with random values using insertions (not bulk
-     * load) Perform scans and range search.
+     * This test the btree page split. Originally this test didn't pass since
+     * the btree was spliting by cardinality and not size. Now, it split page by
+     * size.
+     */
+    @Test
+    public void pageSplitTestExample() throws Exception {
+        if (LOGGER.isLoggable(Level.INFO)) {
+            LOGGER.info("BTree page split test.");
+        }
+
+        // Declare fields.
+        int fieldCount = 2;
+        ITypeTraits[] typeTraits = new ITypeTraits[fieldCount];
+        typeTraits[0] = UTF8StringPointable.TYPE_TRAITS;
+        typeTraits[1] = UTF8StringPointable.TYPE_TRAITS;
+        // Declare field serdes.
+        ISerializerDeserializer[] fieldSerdes = { UTF8StringSerializerDeserializer.INSTANCE,
+                UTF8StringSerializerDeserializer.INSTANCE };
+
+        // Declare keys.
+        int keyFieldCount = 1;
+        IBinaryComparatorFactory[] cmpFactories = new IBinaryComparatorFactory[keyFieldCount];
+        cmpFactories[0] = PointableBinaryComparatorFactory.of(UTF8StringPointable.FACTORY);
+
+        ITreeIndex treeIndex = createTreeIndex(typeTraits, cmpFactories);
+        treeIndex.create();
+        treeIndex.activate();
+
+        ArrayTupleBuilder tb = new ArrayTupleBuilder(fieldCount);
+        ArrayTupleReference tuple = new ArrayTupleReference();
+        IIndexAccessor indexAccessor = (IIndexAccessor) treeIndex.createAccessor(TestOperationCallback.INSTANCE,
+                TestOperationCallback.INSTANCE);
+
+        String key = "111";
+        String data = "XXX";
+        TupleUtils.createTuple(tb, tuple, fieldSerdes, key, data);
+        indexAccessor.insert(tuple);
+
+        key = "222";
+        data = "XXX";
+        TupleUtils.createTuple(tb, tuple, fieldSerdes, key, data);
+        indexAccessor.insert(tuple);
+
+        key = "333";
+        data = "XXX";
+        TupleUtils.createTuple(tb, tuple, fieldSerdes, key, data);
+        indexAccessor.insert(tuple);
+
+        key = "444";
+        data = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
+        TupleUtils.createTuple(tb, tuple, fieldSerdes, key, data);
+        indexAccessor.insert(tuple);
+
+        key = "555";
+        data = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
+        TupleUtils.createTuple(tb, tuple, fieldSerdes, key, data);
+        indexAccessor.insert(tuple);
+
+        key = "666";
+        data = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
+        TupleUtils.createTuple(tb, tuple, fieldSerdes, key, data);
+        indexAccessor.insert(tuple);
+
+        treeIndex.validate();
+        treeIndex.deactivate();
+        treeIndex.destroy();
+    }
+
+    /**
+     * Composite Key Example (Non-Unique Index). Create a tree index with two
+     * fixed-length key fields and one fixed-length value field. Fill index with
+     * random values using insertions (not bulk load) Perform scans and range
+     * search.
      */
     @Test
     public void twoFixedLengthKeysOneFixedLengthValueExample() throws Exception {
@@ -297,10 +365,10 @@
     }
 
     /**
-     * Deletion Example.
-     * Create a BTree with one variable-length key field and one variable-length
-     * value field. Fill B-tree with random values using insertions, then delete
-     * entries one-by-one. Repeat procedure a few times on same BTree.
+     * Deletion Example. Create a BTree with one variable-length key field and
+     * one variable-length 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
     public void deleteExample() throws Exception {
@@ -399,10 +467,10 @@
     }
 
     /**
-     * Update example.
-     * Create a BTree with one variable-length key field and one variable-length
-     * value field. Fill B-tree with random values using insertions, then update
-     * entries one-by-one. Repeat procedure a few times on same BTree.
+     * Update example. Create a BTree with one variable-length key field and one
+     * variable-length 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
     public void updateExample() throws Exception {
@@ -486,9 +554,8 @@
     }
 
     /**
-     * Bulk load example.
-     * Load a tree with 100,000 tuples. BTree has a composite key to "simulate"
-     * non-unique index creation.
+     * Bulk load example. Load a tree with 100,000 tuples. BTree has a composite
+     * key to "simulate" non-unique index creation.
      */
     @Test
     public void bulkLoadExample() throws Exception {
@@ -554,11 +621,11 @@
         treeIndex.deactivate();
         treeIndex.destroy();
     }
-    
+
     /**
-     * Bulk load failure example.
-     * Repeatedly loads a tree with 1,000 tuples, of which one tuple at each possible position
-     * does not conform to the expected order. We expect the bulk load to fail with an exception.
+     * Bulk load failure example. Repeatedly loads a tree with 1,000 tuples, of
+     * which one tuple at each possible position does not conform to the
+     * expected order. We expect the bulk load to fail with an exception.
      */
     @Test
     public void bulkOrderVerificationExample() throws Exception {
@@ -581,38 +648,38 @@
         ArrayTupleReference tuple = new ArrayTupleReference();
         int ins = 1000;
         for (int i = 1; i < ins; i++) {
-        	ITreeIndex treeIndex = createTreeIndex(typeTraits, cmpFactories);
+            ITreeIndex treeIndex = createTreeIndex(typeTraits, cmpFactories);
             treeIndex.create();
             treeIndex.activate();
 
             // Load sorted records, and expect to fail at tuple i.
             IIndexBulkLoader bulkLoader = treeIndex.createBulkLoader(0.7f, true);
             for (int j = 0; j < ins; j++) {
-            	if (j > i) {
-            		fail("Bulk load failure test unexpectedly succeeded past tuple: " + j);
-            	}
-            	int key = j;
-            	if (j == i) {
-            		int swapElementCase = Math.abs(rnd.nextInt()) % 2;
-            		if (swapElementCase == 0) {
-            			// Element equal to previous element.
-            			key--;
-            		} else {
-            			// Element smaller than previous element.
-            			key -= Math.abs(Math.random() % (ins-1)) + 1;
-            		}
-            	}
-            	TupleUtils.createIntegerTuple(tb, tuple, key, 5);
-            	try {
-            		bulkLoader.add(tuple);
-            	} catch (UnsortedInputException e) {
-            		if (j != i) {
-            			fail("Unexpected exception: " + e.getMessage());
-            		}
-            		// Success.
-            		break;
-            	}
-            }            
+                if (j > i) {
+                    fail("Bulk load failure test unexpectedly succeeded past tuple: " + j);
+                }
+                int key = j;
+                if (j == i) {
+                    int swapElementCase = Math.abs(rnd.nextInt()) % 2;
+                    if (swapElementCase == 0) {
+                        // Element equal to previous element.
+                        key--;
+                    } else {
+                        // Element smaller than previous element.
+                        key -= Math.abs(Math.random() % (ins - 1)) + 1;
+                    }
+                }
+                TupleUtils.createIntegerTuple(tb, tuple, key, 5);
+                try {
+                    bulkLoader.add(tuple);
+                } catch (UnsortedInputException e) {
+                    if (j != i) {
+                        fail("Unexpected exception: " + e.getMessage());
+                    }
+                    // Success.
+                    break;
+                }
+            }
 
             treeIndex.deactivate();
             treeIndex.destroy();