completed bulk loading with compression and modified cursors to provide a fielditerator to hide compression details
git-svn-id: https://hyracks.googlecode.com/svn/trunk/hyracks@108 123451ca-8445-de46-9d55-352943316053
diff --git a/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/btree/BTreeOperatorsTest.java b/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/btree/BTreeOperatorsTest.java
index 646795f..43b97d1 100644
--- a/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/btree/BTreeOperatorsTest.java
+++ b/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/btree/BTreeOperatorsTest.java
@@ -1,7 +1,23 @@
+/*
+ * 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.tests.btree;
import java.io.DataOutputStream;
import java.io.File;
+import java.io.RandomAccessFile;
import org.junit.Test;
@@ -28,6 +44,7 @@
import edu.uci.ics.hyracks.dataflow.std.file.FileScanOperatorDescriptor;
import edu.uci.ics.hyracks.dataflow.std.file.FileSplit;
import edu.uci.ics.hyracks.dataflow.std.file.IFileSplitProvider;
+import edu.uci.ics.hyracks.dataflow.std.misc.NullSinkOperatorDescriptor;
import edu.uci.ics.hyracks.dataflow.std.misc.PrinterOperatorDescriptor;
import edu.uci.ics.hyracks.dataflow.std.sort.InMemorySortOperatorDescriptor;
import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeCursor;
@@ -35,20 +52,28 @@
import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeLeafFrameFactory;
import edu.uci.ics.hyracks.storage.am.btree.api.IFieldAccessor;
import edu.uci.ics.hyracks.storage.am.btree.api.IFieldAccessorFactory;
+import edu.uci.ics.hyracks.storage.am.btree.api.IFieldIterator;
import edu.uci.ics.hyracks.storage.am.btree.dataflow.BTreeBulkLoadOperatorDescriptor;
+import edu.uci.ics.hyracks.storage.am.btree.dataflow.BTreeInsertUpdateDeleteOperatorDescriptor;
+import edu.uci.ics.hyracks.storage.am.btree.dataflow.BTreeRegistry;
import edu.uci.ics.hyracks.storage.am.btree.dataflow.BTreeRegistryProvider;
import edu.uci.ics.hyracks.storage.am.btree.dataflow.BTreeSearchOperatorDescriptor;
import edu.uci.ics.hyracks.storage.am.btree.dataflow.BufferCacheProvider;
import edu.uci.ics.hyracks.storage.am.btree.dataflow.IBTreeRegistryProvider;
import edu.uci.ics.hyracks.storage.am.btree.dataflow.IBufferCacheProvider;
+import edu.uci.ics.hyracks.storage.am.btree.frames.MetaDataFrame;
import edu.uci.ics.hyracks.storage.am.btree.frames.NSMInteriorFrameFactory;
import edu.uci.ics.hyracks.storage.am.btree.frames.NSMLeafFrameFactory;
import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
+import edu.uci.ics.hyracks.storage.am.btree.impls.BTreeOp;
import edu.uci.ics.hyracks.storage.am.btree.impls.MultiComparator;
import edu.uci.ics.hyracks.storage.am.btree.impls.RangePredicate;
import edu.uci.ics.hyracks.storage.am.btree.impls.RangeSearchCursor;
import edu.uci.ics.hyracks.storage.am.btree.types.Int32AccessorFactory;
import edu.uci.ics.hyracks.storage.am.btree.types.UTF8StringAccessorFactory;
+import edu.uci.ics.hyracks.storage.common.buffercache.IBufferCache;
+import edu.uci.ics.hyracks.storage.common.file.FileInfo;
+import edu.uci.ics.hyracks.storage.common.file.FileManager;
import edu.uci.ics.hyracks.tests.integration.AbstractIntegrationTest;
public class BTreeOperatorsTest extends AbstractIntegrationTest {
@@ -77,7 +102,7 @@
new AbsoluteLocationConstraint(NC1_ID) });
ordScanner.setPartitionConstraint(ordersPartitionConstraint);
- InMemorySortOperatorDescriptor sorter = new InMemorySortOperatorDescriptor(spec, new int[] { 1 },
+ InMemorySortOperatorDescriptor sorter = new InMemorySortOperatorDescriptor(spec, new int[] { 0 },
new IBinaryComparatorFactory[] { UTF8StringBinaryComparatorFactory.INSTANCE }, ordersDesc);
PartitionConstraint sortersPartitionConstraint = new ExplicitPartitionConstraint(new LocationConstraint[] {
new AbsoluteLocationConstraint(NC1_ID) });
@@ -89,7 +114,6 @@
IBufferCacheProvider bufferCacheProvider = new BufferCacheProvider();
IBTreeRegistryProvider btreeRegistryProvider = new BTreeRegistryProvider();
- // build first bulk load operator
IFieldAccessorFactory[] fieldAccessorFactories = new IFieldAccessorFactory[3];
fieldAccessorFactories[0] = new UTF8StringAccessorFactory(); // key
fieldAccessorFactories[1] = new UTF8StringAccessorFactory(); // payload
@@ -99,7 +123,7 @@
IBinaryComparatorFactory[] comparatorFactories = new IBinaryComparatorFactory[keyLen];
comparatorFactories[0] = UTF8StringBinaryComparatorFactory.INSTANCE;
- int[] keyFields = { 1 };
+ int[] keyFields = { 0 };
int[] payloadFields = { 4, 5 };
int btreeFileId = 0;
@@ -125,7 +149,7 @@
comparators[i] = comparatorFactories[i].createBinaryComparator();
}
- MultiComparator cmpA = new MultiComparator(comparators, fields);
+ MultiComparator cmp = new MultiComparator(comparators, fields);
// try an ordered scan on the bulk-loaded btree
BTree btreeA = btreeRegistryProvider.getBTreeRegistry().get(btreeFileId);
@@ -135,10 +159,9 @@
try {
while (scanCursor.hasNext()) {
scanCursor.next();
- byte[] array = scanCursor.getPage().getBuffer().array();
- int recOffset = scanCursor.getOffset();
- String rec = cmpA.printRecord(array, recOffset);
- System.out.println(rec);
+ IFieldIterator fieldIter = scanCursor.getFieldIterator();
+ String rec = cmp.printRecord(fieldIter);
+ System.out.println(rec);
}
} catch (Exception e) {
e.printStackTrace();
@@ -146,7 +169,7 @@
scanCursor.close();
}
}
-
+
@Test
public void btreeSearchTest() throws Exception {
JobSpecification spec = new JobSpecification();
@@ -199,4 +222,220 @@
spec.addRoot(printer);
runTest(spec);
}
+
+ @Test
+ public void insertTest() throws Exception {
+ JobSpecification spec = new JobSpecification();
+
+ FileSplit[] ordersSplits = new FileSplit[] {
+ new FileSplit(NC1_ID, new File("data/tpch0.001/orders-part1.tbl")) };
+ IFileSplitProvider ordersSplitProvider = new ConstantFileSplitProvider(ordersSplits);
+ RecordDescriptor ordersDesc = new RecordDescriptor(new ISerializerDeserializer[] {
+ UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE,
+ UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE,
+ UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE,
+ UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE,
+ UTF8StringSerializerDeserializer.INSTANCE });
+
+ FileScanOperatorDescriptor ordScanner = new FileScanOperatorDescriptor(spec, ordersSplitProvider,
+ new DelimitedDataTupleParserFactory(new IValueParserFactory[] { UTF8StringParserFactory.INSTANCE,
+ UTF8StringParserFactory.INSTANCE, UTF8StringParserFactory.INSTANCE,
+ UTF8StringParserFactory.INSTANCE, UTF8StringParserFactory.INSTANCE,
+ UTF8StringParserFactory.INSTANCE, UTF8StringParserFactory.INSTANCE,
+ UTF8StringParserFactory.INSTANCE, UTF8StringParserFactory.INSTANCE }, '|'), ordersDesc);
+ PartitionConstraint ordersPartitionConstraint = new ExplicitPartitionConstraint(new LocationConstraint[] {
+ new AbsoluteLocationConstraint(NC1_ID) });
+ ordScanner.setPartitionConstraint(ordersPartitionConstraint);
+
+ IBTreeInteriorFrameFactory interiorFrameFactory = new NSMInteriorFrameFactory();
+ IBTreeLeafFrameFactory leafFrameFactory = new NSMLeafFrameFactory();
+
+ IBufferCacheProvider bufferCacheProvider = new BufferCacheProvider();
+ IBTreeRegistryProvider btreeRegistryProvider = new BTreeRegistryProvider();
+
+ // we will create a primary index and 2 secondary indexes
+ // first create fieldaccessors and comparators for primary index
+ IFieldAccessorFactory[] primaryFieldAccessorFactories = new IFieldAccessorFactory[6];
+ primaryFieldAccessorFactories[0] = new UTF8StringAccessorFactory(); // key
+ primaryFieldAccessorFactories[1] = new UTF8StringAccessorFactory(); // payload
+ primaryFieldAccessorFactories[2] = new UTF8StringAccessorFactory(); // payload
+ primaryFieldAccessorFactories[3] = new UTF8StringAccessorFactory(); // payload
+ primaryFieldAccessorFactories[4] = new UTF8StringAccessorFactory(); // payload
+ primaryFieldAccessorFactories[5] = new UTF8StringAccessorFactory(); // payload
+
+ int primaryKeyLen = 1;
+ IBinaryComparatorFactory[] primaryComparatorFactories = new IBinaryComparatorFactory[primaryKeyLen];
+ primaryComparatorFactories[0] = UTF8StringBinaryComparatorFactory.INSTANCE;
+
+ // construct a multicomparator for the primary index
+ IFieldAccessor[] primaryFields = new IFieldAccessor[primaryFieldAccessorFactories.length];
+ for(int i = 0; i < primaryFieldAccessorFactories.length; i++) {
+ primaryFields[i] = primaryFieldAccessorFactories[i].getFieldAccessor();
+ }
+
+ IBinaryComparator[] primaryComparators = new IBinaryComparator[primaryComparatorFactories.length];
+ for(int i = 0; i < primaryComparatorFactories.length; i++) {
+ primaryComparators[i] = primaryComparatorFactories[i].createBinaryComparator();
+ }
+
+ MultiComparator primaryCmp = new MultiComparator(primaryComparators, primaryFields);
+
+
+ // now create fieldaccessors and comparators for secondary indexes
+ IFieldAccessorFactory[] secondaryFieldAccessorFactories = new IFieldAccessorFactory[2];
+ secondaryFieldAccessorFactories[0] = new UTF8StringAccessorFactory(); // key
+ secondaryFieldAccessorFactories[1] = new UTF8StringAccessorFactory(); // key (key in primary index)
+
+ int secondaryKeyLen = 2;
+ IBinaryComparatorFactory[] secondaryComparatorFactories = new IBinaryComparatorFactory[secondaryKeyLen];
+ secondaryComparatorFactories[0] = UTF8StringBinaryComparatorFactory.INSTANCE;
+ secondaryComparatorFactories[1] = UTF8StringBinaryComparatorFactory.INSTANCE;
+
+ // construct a multicomparator for the secondary indexes
+ IFieldAccessor[] secondaryFields = new IFieldAccessor[secondaryFieldAccessorFactories.length];
+ for(int i = 0; i < secondaryFieldAccessorFactories.length; i++) {
+ secondaryFields[i] = secondaryFieldAccessorFactories[i].getFieldAccessor();
+ }
+
+ IBinaryComparator[] secondaryComparators = new IBinaryComparator[secondaryComparatorFactories.length];
+ for(int i = 0; i < secondaryComparatorFactories.length; i++) {
+ secondaryComparators[i] = secondaryComparatorFactories[i].createBinaryComparator();
+ }
+
+ MultiComparator secondaryCmp = new MultiComparator(secondaryComparators, secondaryFields);
+
+ // we create and register 3 btrees for in an insert pipeline being fed from a filescan op
+ IBufferCache bufferCache = bufferCacheProvider.getBufferCache();
+ BTreeRegistry btreeRegistry = btreeRegistryProvider.getBTreeRegistry();
+ FileManager fileManager = bufferCacheProvider.getFileManager();
+
+ // primary index
+ int fileIdA = 3;
+ File fA = new File("/tmp/btreetestA.ix");
+ RandomAccessFile rafA = new RandomAccessFile(fA, "rw");
+ FileInfo fiA = new FileInfo(fileIdA, rafA);
+ fileManager.registerFile(fiA);
+ BTree btreeA = new BTree(bufferCache, interiorFrameFactory, leafFrameFactory, primaryCmp);
+ btreeA.create(fileIdA, leafFrameFactory.getFrame(), new MetaDataFrame());
+ btreeA.open(fileIdA);
+ btreeRegistry.register(fileIdA, btreeA);
+
+ // first secondary index
+ int fileIdB = 4;
+ File fB = new File("/tmp/btreetestB.ix");
+ RandomAccessFile rafB = new RandomAccessFile(fB, "rw");
+ FileInfo fiB = new FileInfo(fileIdB, rafB);
+ fileManager.registerFile(fiB);
+ BTree btreeB = new BTree(bufferCache, interiorFrameFactory, leafFrameFactory, secondaryCmp);
+ btreeB.create(fileIdB, leafFrameFactory.getFrame(), new MetaDataFrame());
+ btreeB.open(fileIdB);
+ btreeRegistry.register(fileIdB, btreeB);
+
+ // second secondary index
+ int fileIdC = 5;
+ File fC = new File("/tmp/btreetestC.ix");
+ RandomAccessFile rafC = new RandomAccessFile(fC, "rw");
+ FileInfo fiC = new FileInfo(fileIdC, rafC);
+ fileManager.registerFile(fiC);
+ BTree btreeC = new BTree(bufferCache, interiorFrameFactory, leafFrameFactory, secondaryCmp);
+ btreeC.create(fileIdC, leafFrameFactory.getFrame(), new MetaDataFrame());
+ btreeC.open(fileIdC);
+ btreeRegistry.register(fileIdC, btreeC);
+
+
+ // create insert operators
+
+ // primary index
+ int[] keyFieldsA = { 0 };
+ int[] payloadFieldsA = { 1,2,3,4,5 };
+ BTreeInsertUpdateDeleteOperatorDescriptor insertOpA = new BTreeInsertUpdateDeleteOperatorDescriptor(spec, ordersSplitProvider, ordersDesc, bufferCacheProvider, btreeRegistryProvider, fileIdA, "/tmp/btreetestA.ix", interiorFrameFactory, leafFrameFactory, primaryFieldAccessorFactories, primaryComparatorFactories, keyFieldsA, payloadFieldsA, BTreeOp.BTO_INSERT);
+ PartitionConstraint insertPartitionConstraintA = new ExplicitPartitionConstraint(new LocationConstraint[] { new AbsoluteLocationConstraint(NC1_ID) });
+ insertOpA.setPartitionConstraint(insertPartitionConstraintA);
+
+ // first secondary index
+ int[] keyFieldsB = { 3, 0 };
+ int[] payloadFieldsB = { };
+ BTreeInsertUpdateDeleteOperatorDescriptor insertOpB = new BTreeInsertUpdateDeleteOperatorDescriptor(spec, ordersSplitProvider, ordersDesc, bufferCacheProvider, btreeRegistryProvider, fileIdB, "/tmp/btreetestB.ix", interiorFrameFactory, leafFrameFactory, secondaryFieldAccessorFactories, secondaryComparatorFactories, keyFieldsB, payloadFieldsB, BTreeOp.BTO_INSERT);
+ PartitionConstraint insertPartitionConstraintB = new ExplicitPartitionConstraint(new LocationConstraint[] { new AbsoluteLocationConstraint(NC1_ID) });
+ insertOpB.setPartitionConstraint(insertPartitionConstraintB);
+
+ // second secondary index
+ int[] keyFieldsC = { 4, 0 };
+ int[] payloadFieldsC = { };
+ BTreeInsertUpdateDeleteOperatorDescriptor insertOpC = new BTreeInsertUpdateDeleteOperatorDescriptor(spec, ordersSplitProvider, ordersDesc, bufferCacheProvider, btreeRegistryProvider, fileIdC, "/tmp/btreetestC.ix", interiorFrameFactory, leafFrameFactory, secondaryFieldAccessorFactories, secondaryComparatorFactories, keyFieldsC, payloadFieldsC, BTreeOp.BTO_INSERT);
+ PartitionConstraint insertPartitionConstraintC = new ExplicitPartitionConstraint(new LocationConstraint[] { new AbsoluteLocationConstraint(NC1_ID) });
+ insertOpC.setPartitionConstraint(insertPartitionConstraintC);
+
+ NullSinkOperatorDescriptor nullSink = new NullSinkOperatorDescriptor(spec);
+ PartitionConstraint nullSinkPartitionConstraint = new ExplicitPartitionConstraint(new LocationConstraint[] { new AbsoluteLocationConstraint(NC1_ID) });
+ nullSink.setPartitionConstraint(nullSinkPartitionConstraint);
+
+ spec.connect(new OneToOneConnectorDescriptor(spec), ordScanner, 0, insertOpA, 0);
+
+ spec.connect(new OneToOneConnectorDescriptor(spec), insertOpA, 0, insertOpB, 0);
+
+ spec.connect(new OneToOneConnectorDescriptor(spec), insertOpB, 0, insertOpC, 0);
+
+ spec.connect(new OneToOneConnectorDescriptor(spec), insertOpC, 0, nullSink, 0);
+
+ spec.addRoot(nullSink);
+ runTest(spec);
+
+ // scan primary index
+ System.out.println("PRINTING PRIMARY INDEX");
+ IBTreeCursor scanCursorA = new RangeSearchCursor(leafFrameFactory.getFrame());
+ RangePredicate nullPredA = new RangePredicate(true, null, null, null);
+ btreeA.search(scanCursorA, nullPredA, leafFrameFactory.getFrame(), interiorFrameFactory.getFrame());
+ try {
+ while (scanCursorA.hasNext()) {
+ scanCursorA.next();
+ IFieldIterator fieldIter = scanCursorA.getFieldIterator();
+ String rec = primaryCmp.printRecord(fieldIter);
+ System.out.println(rec);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ scanCursorA.close();
+ }
+ System.out.println();
+
+ // scan first secondary index
+ System.out.println("PRINTING FIRST SECONDARY INDEX");
+ IBTreeCursor scanCursorB = new RangeSearchCursor(leafFrameFactory.getFrame());
+ RangePredicate nullPredB = new RangePredicate(true, null, null, null);
+ btreeB.search(scanCursorB, nullPredB, leafFrameFactory.getFrame(), interiorFrameFactory.getFrame());
+ try {
+ while (scanCursorB.hasNext()) {
+ scanCursorB.next();
+ IFieldIterator fieldIter = scanCursorB.getFieldIterator();
+ String rec = secondaryCmp.printRecord(fieldIter);
+ System.out.println(rec);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ scanCursorB.close();
+ }
+ System.out.println();
+
+ // scan second secondary index
+ System.out.println("PRINTING SECOND SECONDARY INDEX");
+ IBTreeCursor scanCursorC = new RangeSearchCursor(leafFrameFactory.getFrame());
+ RangePredicate nullPredC = new RangePredicate(true, null, null, null);
+ btreeC.search(scanCursorC, nullPredC, leafFrameFactory.getFrame(), interiorFrameFactory.getFrame());
+ try {
+ while (scanCursorC.hasNext()) {
+ scanCursorC.next();
+ IFieldIterator fieldIter = scanCursorC.getFieldIterator();
+ String rec = secondaryCmp.printRecord(fieldIter);
+ System.out.println(rec);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ scanCursorC.close();
+ }
+ System.out.println();
+ }
}
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/api/IBTreeCursor.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/api/IBTreeCursor.java
index 78767d1..74e6478 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/api/IBTreeCursor.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/api/IBTreeCursor.java
@@ -21,11 +21,11 @@
public interface IBTreeCursor {
public void reset();
public boolean hasNext() throws Exception;
- public int getOffset();
public void next() throws Exception;
public void open(ICachedPage page, ISearchPredicate searchPred) throws Exception;
public ICachedPage getPage();
public void close() throws Exception;
public void setBufferCache(IBufferCache bufferCache);
public void setFileId(int fileId);
+ public IFieldIterator getFieldIterator();
}
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/api/IBTreeFrame.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/api/IBTreeFrame.java
index da5a39a..aabd005 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/api/IBTreeFrame.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/api/IBTreeFrame.java
@@ -68,12 +68,15 @@
public boolean getSmFlag(); // structure modification flag
public void setSmFlag(boolean smFlag);
- //public int getNumPrefixRecords();
- //public void setNumPrefixRecords(int numPrefixRecords);
-
public void insertSorted(byte[] data, MultiComparator cmp) throws Exception;
+ public int getSlotSize();
+
+ public IFieldIterator createFieldIterator();
+
// for debugging
public int getFreeSpaceOff();
public void setFreeSpaceOff(int freeSpace);
+
+
}
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/api/IFieldIterator.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/api/IFieldIterator.java
new file mode 100644
index 0000000..65702b2
--- /dev/null
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/api/IFieldIterator.java
@@ -0,0 +1,40 @@
+/*
+ * 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.btree.api;
+
+import java.nio.ByteBuffer;
+
+public interface IFieldIterator {
+ public void setFrame(IBTreeFrame frame);
+
+ public void setFields(IFieldAccessor[] fields);
+
+ public void openRecSlotNum(int recSlotNum);
+
+ public void openRecSlotOff(int recSlotOff);
+
+ public void reset();
+
+ public void nextField();
+
+ public int getFieldOff();
+
+ public int getFieldSize();
+
+ public int copyFields(int startField, int endField, byte[] dest, int destOff);
+
+ public ByteBuffer getBuffer();
+}
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/api/IPrefixSlotManager.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/api/IPrefixSlotManager.java
index 3599933..7792fa0 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/api/IPrefixSlotManager.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/api/IPrefixSlotManager.java
@@ -15,8 +15,6 @@
package edu.uci.ics.hyracks.storage.am.btree.api;
-import java.nio.ByteBuffer;
-
import edu.uci.ics.hyracks.storage.am.btree.frames.FieldPrefixNSMLeafFrame;
import edu.uci.ics.hyracks.storage.am.btree.impls.MultiComparator;
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/compressors/FieldPrefixCompressor.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/compressors/FieldPrefixCompressor.java
index 27a8952..a0f0258 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/compressors/FieldPrefixCompressor.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/compressors/FieldPrefixCompressor.java
@@ -25,7 +25,7 @@
import edu.uci.ics.hyracks.storage.am.btree.api.IFrameCompressor;
import edu.uci.ics.hyracks.storage.am.btree.api.IPrefixSlotManager;
import edu.uci.ics.hyracks.storage.am.btree.frames.FieldPrefixNSMLeafFrame;
-import edu.uci.ics.hyracks.storage.am.btree.impls.FieldIterator;
+import edu.uci.ics.hyracks.storage.am.btree.impls.FieldPrefixFieldIterator;
import edu.uci.ics.hyracks.storage.am.btree.impls.FieldPrefixSlotManager;
import edu.uci.ics.hyracks.storage.am.btree.impls.MultiComparator;
@@ -48,13 +48,13 @@
if(numRecords <= 0) {
frame.setNumPrefixRecords(0);
frame.setFreeSpaceOff(frame.getOrigFreeSpaceOff());
- frame.setTotalFreeSpace(frame.getOrigTotalFreeSpace());
+ frame.setTotalFreeSpace(frame.getOrigTotalFreeSpace());
return false;
}
-
+
int numUncompressedRecords = frame.getNumUncompressedRecords();
float ratio = (float)numUncompressedRecords / (float)numRecords;
- if(ratio < ratioThreshold) return false;
+ if(ratio < ratioThreshold) return false;
IBinaryComparator[] cmps = cmp.getComparators();
IFieldAccessor[] fields = cmp.getFields();
@@ -65,7 +65,7 @@
// perform analysis pass
ArrayList<KeyPartition> keyPartitions = getKeyPartitions(frame, cmp, occurrenceThreshold);
- if(keyPartitions.size() == 0) return false;
+ if(keyPartitions.size() == 0) return false;
// for each keyPartition, determine the best prefix length for compression, and count how many prefix records we would need in total
int totalSlotsNeeded = 0;
@@ -143,7 +143,7 @@
int recSlotNum = 0;
int prefixSlotNum = 0;
numUncompressedRecords = 0;
- FieldIterator recToWrite = new FieldIterator(fields, frame);
+ FieldPrefixFieldIterator recToWrite = new FieldPrefixFieldIterator(fields, frame);
while(recSlotNum < numRecords) {
if(kpIndex < keyPartitions.size()) {
@@ -157,8 +157,8 @@
//System.out.println("PROCESSING KEYPARTITION: " + kpIndex + " RANGE: " + keyPartitions.get(kpIndex).firstRecSlotNum + " " + keyPartitions.get(kpIndex).lastRecSlotNum + " FIELDSTOCOMPRESS: " + numFieldsToCompress);
- FieldIterator prevRec = new FieldIterator(fields, frame);
- FieldIterator rec = new FieldIterator(fields, frame);
+ FieldPrefixFieldIterator prevRec = new FieldPrefixFieldIterator(fields, frame);
+ FieldPrefixFieldIterator rec = new FieldPrefixFieldIterator(fields, frame);
for(int i = recSlotNum + 1; i <= keyPartitions.get(kpIndex).lastRecSlotNum; i++) {
prevRec.openRecSlotNum(i - 1);
@@ -312,8 +312,8 @@
KeyPartition kp = new KeyPartition(maxCmps);
keyPartitions.add(kp);
- FieldIterator prevRec = new FieldIterator(fields, frame);
- FieldIterator rec = new FieldIterator(fields, frame);
+ FieldPrefixFieldIterator prevRec = new FieldPrefixFieldIterator(fields, frame);
+ FieldPrefixFieldIterator rec = new FieldPrefixFieldIterator(fields, frame);
kp.firstRecSlotNum = 0;
int numRecords = frame.getNumRecords();
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/AbstractBTreeOperatorDescriptor.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/AbstractBTreeOperatorDescriptor.java
index 0a1efa5..d1ade0c 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/AbstractBTreeOperatorDescriptor.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/AbstractBTreeOperatorDescriptor.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.btree.dataflow;
import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparatorFactory;
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/AbstractBTreeOperatorNodePushable.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/AbstractBTreeOperatorNodePushable.java
index af7c3c6..1949651 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/AbstractBTreeOperatorNodePushable.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/AbstractBTreeOperatorNodePushable.java
@@ -1,8 +1,22 @@
+/*
+ * 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.btree.dataflow;
import java.io.DataOutputStream;
import java.io.File;
-import java.io.FileNotFoundException;
import java.io.RandomAccessFile;
import java.util.Random;
@@ -32,18 +46,25 @@
protected AbstractBTreeOperatorDescriptor opDesc;
protected IHyracksContext ctx;
- public AbstractBTreeOperatorNodePushable(AbstractBTreeOperatorDescriptor opDesc, final IHyracksContext ctx) {
+ protected boolean createBTree;
+
+ public AbstractBTreeOperatorNodePushable(AbstractBTreeOperatorDescriptor opDesc, final IHyracksContext ctx, boolean createBTree) {
this.opDesc = opDesc;
this.ctx = ctx;
+ this.createBTree = createBTree;
}
- public void init() throws FileNotFoundException {
+ public void init() throws Exception {
IBufferCache bufferCache = opDesc.getBufferCacheProvider().getBufferCache();
FileManager fileManager = opDesc.getBufferCacheProvider().getFileManager();
File f = new File(opDesc.getBtreeFileName());
RandomAccessFile raf = new RandomAccessFile(f, "rw");
+ if(!f.exists() && !createBTree) {
+ throw new Exception("Trying to open btree from file " + opDesc.getBtreeFileName() + " but file doesn't exist.");
+ }
+
try {
FileInfo fi = new FileInfo(opDesc.getBtreeFileId(), raf);
fileManager.registerFile(fi);
@@ -51,6 +72,9 @@
catch (Exception e) {
}
+ interiorFrame = opDesc.getInteriorFactory().getFrame();
+ leafFrame = opDesc.getLeafFactory().getFrame();
+
BTreeRegistry btreeRegistry = opDesc.getBtreeRegistryProvider().getBTreeRegistry();
btree = btreeRegistry.get(opDesc.getBtreeFileId());
if(btree == null) {
@@ -77,23 +101,24 @@
MultiComparator cmp = new MultiComparator(comparators, fields);
btree = new BTree(bufferCache, opDesc.getInteriorFactory(), opDesc.getLeafFactory(), cmp);
- btree.open(opDesc.getBtreeFileId());
+ if(createBTree) {
+ MetaDataFrame metaFrame = new MetaDataFrame();
+ btree.create(opDesc.getBtreeFileId(), leafFrame, metaFrame);
+ }
+ btree.open(opDesc.getBtreeFileId());
btreeRegistry.register(opDesc.getBtreeFileId(), btree);
}
}
finally {
btreeRegistry.unlock();
}
- }
-
- interiorFrame = opDesc.getInteriorFactory().getFrame();
- leafFrame = opDesc.getLeafFactory().getFrame();
+ }
}
// debug
protected void fill() throws Exception {
- MetaDataFrame metaFrame = new MetaDataFrame();
+ MetaDataFrame metaFrame = new MetaDataFrame();
btree.create(opDesc.getBtreeFileId(), leafFrame, metaFrame);
Random rnd = new Random();
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeBulkLoadOperatorDescriptor.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeBulkLoadOperatorDescriptor.java
index 221adab..0df2581 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeBulkLoadOperatorDescriptor.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeBulkLoadOperatorDescriptor.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.btree.dataflow;
import edu.uci.ics.hyracks.api.context.IHyracksContext;
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeBulkLoadOperatorNodePushable.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeBulkLoadOperatorNodePushable.java
index d6b0036..8376260 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeBulkLoadOperatorNodePushable.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeBulkLoadOperatorNodePushable.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.btree.dataflow;
import java.nio.ByteBuffer;
@@ -24,7 +39,7 @@
private IRecordDescriptorProvider recordDescProvider;
public BTreeBulkLoadOperatorNodePushable(AbstractBTreeOperatorDescriptor opDesc, IHyracksContext ctx, int[] keyFields, int[] payloadFields, float fillFactor, IRecordDescriptorProvider recordDescProvider) {
- super(opDesc, ctx);
+ super(opDesc, ctx, true);
this.keyFields = keyFields;
this.payloadFields = payloadFields;
this.fillFactor = fillFactor;
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeDiskOrderScanOperatorDescriptor.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeDiskOrderScanOperatorDescriptor.java
index 4509d8c..8b1da5a 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeDiskOrderScanOperatorDescriptor.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeDiskOrderScanOperatorDescriptor.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.btree.dataflow;
import edu.uci.ics.hyracks.api.context.IHyracksContext;
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeDiskOrderScanOperatorNodePushable.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeDiskOrderScanOperatorNodePushable.java
index 74c878a..373a27d 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeDiskOrderScanOperatorNodePushable.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeDiskOrderScanOperatorNodePushable.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.btree.dataflow;
import java.io.DataOutput;
@@ -11,6 +26,7 @@
import edu.uci.ics.hyracks.dataflow.common.comm.util.FrameUtils;
import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeLeafFrame;
import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeMetaDataFrame;
+import edu.uci.ics.hyracks.storage.am.btree.api.IFieldIterator;
import edu.uci.ics.hyracks.storage.am.btree.frames.MetaDataFrame;
import edu.uci.ics.hyracks.storage.am.btree.impls.DiskOrderScanCursor;
import edu.uci.ics.hyracks.storage.am.btree.impls.MultiComparator;
@@ -18,7 +34,7 @@
public class BTreeDiskOrderScanOperatorNodePushable extends AbstractBTreeOperatorNodePushable {
public BTreeDiskOrderScanOperatorNodePushable(AbstractBTreeOperatorDescriptor opDesc, IHyracksContext ctx) {
- super(opDesc, ctx);
+ super(opDesc, ctx, false);
}
@Override
@@ -50,15 +66,13 @@
tb.reset();
cursor.next();
- int recRunner = cursor.getOffset();
- byte[] array = cursor.getPage().getBuffer().array();
- for(int i = 0; i < cmp.getFields().length; i++) {
- int fieldLen = cmp.getFields()[i].getLength(array, recRunner);
- dos.write(array, recRunner, fieldLen);
- recRunner += fieldLen;
+ IFieldIterator fieldIter = cursor.getFieldIterator();
+ for(int i = 0; i < cmp.getFields().length; i++) {
+ int fieldLen = fieldIter.getFieldSize();
+ dos.write(fieldIter.getBuffer().array(), fieldIter.getFieldOff(), fieldLen);
tb.addFieldEndOffset();
}
-
+
if (!appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize())) {
FrameUtils.flushFrame(frame, writer);
appender.reset(frame, true);
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeInsertOperatorNodePushable.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeInsertOperatorNodePushable.java
deleted file mode 100644
index eddbbfa..0000000
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeInsertOperatorNodePushable.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package edu.uci.ics.hyracks.storage.am.btree.dataflow;
-
-import java.nio.ByteBuffer;
-
-import edu.uci.ics.hyracks.api.context.IHyracksContext;
-import edu.uci.ics.hyracks.api.dataflow.value.IRecordDescriptorProvider;
-import edu.uci.ics.hyracks.api.dataflow.value.RecordDescriptor;
-import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
-import edu.uci.ics.hyracks.dataflow.common.comm.io.FrameTupleAccessor;
-import edu.uci.ics.hyracks.dataflow.common.comm.util.FrameUtils;
-import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeMetaDataFrame;
-import edu.uci.ics.hyracks.storage.am.btree.frames.MetaDataFrame;
-
-public class BTreeInsertOperatorNodePushable extends AbstractBTreeOperatorNodePushable {
-
- private final int[] keyFields;
- private final int[] payloadFields;
-
- private FrameTupleAccessor accessor;
-
- private IRecordDescriptorProvider recordDescProvider;
-
- private IBTreeMetaDataFrame metaFrame;
-
- public BTreeInsertOperatorNodePushable(AbstractBTreeOperatorDescriptor opDesc, IHyracksContext ctx, int[] keyFields, int[] payloadFields, IRecordDescriptorProvider recordDescProvider) {
- super(opDesc, ctx);
- this.keyFields = keyFields;
- this.payloadFields = payloadFields;
- this.recordDescProvider = recordDescProvider;
- }
-
- @Override
- public void close() throws HyracksDataException {
- writer.close();
- }
-
- @Override
- public void nextFrame(ByteBuffer buffer) throws HyracksDataException {
- accessor.reset(buffer);
-
- int tupleCount = accessor.getTupleCount();
- for(int i = 0; i < tupleCount; i++) {
- byte[] btreeRecord = buildBTreeRecordFromHyraxRecord(accessor, i, keyFields, payloadFields);
- try {
- btree.insert(btreeRecord, leafFrame, interiorFrame, metaFrame);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- // pass a copy of the frame to next op
- FrameUtils.flushFrame(buffer.duplicate(), writer);
- }
-
- @Override
- public void open() throws HyracksDataException {
- RecordDescriptor recDesc = recordDescProvider.getInputRecordDescriptor(opDesc.getOperatorId(), 0);
- accessor = new FrameTupleAccessor(ctx, recDesc);
- try {
- init();
- btree.open(opDesc.getBtreeFileId());
- metaFrame = new MetaDataFrame();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- @Override
- public void flush() throws HyracksDataException {
- }
-}
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeInsertOperatorDescriptor.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeInsertUpdateDeleteOperatorDescriptor.java
similarity index 62%
rename from hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeInsertOperatorDescriptor.java
rename to hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeInsertUpdateDeleteOperatorDescriptor.java
index 80066be..e88b633 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeInsertOperatorDescriptor.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeInsertUpdateDeleteOperatorDescriptor.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.btree.dataflow;
import edu.uci.ics.hyracks.api.context.IHyracksContext;
@@ -11,27 +26,31 @@
import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeInteriorFrameFactory;
import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeLeafFrameFactory;
import edu.uci.ics.hyracks.storage.am.btree.api.IFieldAccessorFactory;
+import edu.uci.ics.hyracks.storage.am.btree.impls.BTreeOp;
-public class BTreeInsertOperatorDescriptor extends AbstractBTreeOperatorDescriptor {
+public class BTreeInsertUpdateDeleteOperatorDescriptor extends AbstractBTreeOperatorDescriptor {
private static final long serialVersionUID = 1L;
private final int[] keyFields;
private final int[] payloadFields;
- public BTreeInsertOperatorDescriptor(JobSpecification spec,
+ private BTreeOp op;
+
+ public BTreeInsertUpdateDeleteOperatorDescriptor(JobSpecification spec,
IFileSplitProvider fileSplitProvider, RecordDescriptor recDesc,
IBufferCacheProvider bufferCacheProvider,
IBTreeRegistryProvider btreeRegistryProvider, int btreeFileId,
String btreeFileName, IBTreeInteriorFrameFactory interiorFactory,
IBTreeLeafFrameFactory leafFactory, IFieldAccessorFactory[] fieldAccessorFactories,
IBinaryComparatorFactory[] comparatorFactories,
- int[] keyFields, int[] payloadFields) {
+ int[] keyFields, int[] payloadFields, BTreeOp op) {
super(spec, 1, 1, fileSplitProvider, recDesc, bufferCacheProvider,
btreeRegistryProvider, btreeFileId, btreeFileName, interiorFactory,
leafFactory, fieldAccessorFactories, comparatorFactories);
this.keyFields = keyFields;
this.payloadFields = payloadFields;
+ this.op = op;
}
@Override
@@ -39,7 +58,7 @@
IOperatorEnvironment env,
IRecordDescriptorProvider recordDescProvider, int partition,
int nPartitions) {
- return new BTreeInsertOperatorNodePushable(this, ctx, keyFields, payloadFields, recordDescProvider);
+ return new BTreeInsertUpdateDeleteOperatorNodePushable(this, ctx, keyFields, payloadFields, recordDescProvider, op);
}
}
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeInsertUpdateDeleteOperatorNodePushable.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeInsertUpdateDeleteOperatorNodePushable.java
new file mode 100644
index 0000000..f578538
--- /dev/null
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeInsertUpdateDeleteOperatorNodePushable.java
@@ -0,0 +1,106 @@
+/*
+ * 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.btree.dataflow;
+
+import java.nio.ByteBuffer;
+
+import edu.uci.ics.hyracks.api.context.IHyracksContext;
+import edu.uci.ics.hyracks.api.dataflow.value.IRecordDescriptorProvider;
+import edu.uci.ics.hyracks.api.dataflow.value.RecordDescriptor;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.comm.io.FrameTupleAccessor;
+import edu.uci.ics.hyracks.dataflow.common.comm.util.FrameUtils;
+import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeMetaDataFrame;
+import edu.uci.ics.hyracks.storage.am.btree.frames.MetaDataFrame;
+import edu.uci.ics.hyracks.storage.am.btree.impls.BTreeOp;
+
+public class BTreeInsertUpdateDeleteOperatorNodePushable extends AbstractBTreeOperatorNodePushable {
+
+ private final int[] keyFields;
+ private final int[] payloadFields;
+
+ private FrameTupleAccessor accessor;
+
+ private IRecordDescriptorProvider recordDescProvider;
+
+ private IBTreeMetaDataFrame metaFrame;
+
+ private BTreeOp op;
+
+ public BTreeInsertUpdateDeleteOperatorNodePushable(AbstractBTreeOperatorDescriptor opDesc, IHyracksContext ctx, int[] keyFields, int[] payloadFields, IRecordDescriptorProvider recordDescProvider, BTreeOp op) {
+ super(opDesc, ctx, false);
+ this.keyFields = keyFields;
+ this.payloadFields = payloadFields;
+ this.recordDescProvider = recordDescProvider;
+ this.op = op;
+ }
+
+ @Override
+ public void close() throws HyracksDataException {
+ writer.close();
+ }
+
+ @Override
+ public void nextFrame(ByteBuffer buffer) throws HyracksDataException {
+ accessor.reset(buffer);
+
+ int tupleCount = accessor.getTupleCount();
+ for(int i = 0; i < tupleCount; i++) {
+ byte[] btreeRecord = buildBTreeRecordFromHyraxRecord(accessor, i, keyFields, payloadFields);
+ try {
+
+ switch(op) {
+
+ case BTO_INSERT: {
+ btree.insert(btreeRecord, leafFrame, interiorFrame, metaFrame);
+ } break;
+
+ case BTO_DELETE: {
+ btree.delete(btreeRecord, leafFrame, interiorFrame, metaFrame);
+ } break;
+
+ default: {
+ throw new HyracksDataException("Unsupported operation " + op + " in BTree InsertUpdateDelete operator");
+ }
+
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ // pass a copy of the frame to next op
+ FrameUtils.flushFrame(buffer.duplicate(), writer);
+ }
+
+ @Override
+ public void open() throws HyracksDataException {
+ RecordDescriptor recDesc = recordDescProvider.getInputRecordDescriptor(opDesc.getOperatorId(), 0);
+ accessor = new FrameTupleAccessor(ctx, recDesc);
+ try {
+ init();
+ btree.open(opDesc.getBtreeFileId());
+ metaFrame = new MetaDataFrame();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void flush() throws HyracksDataException {
+ }
+}
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeRegistry.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeRegistry.java
index 4ef4789..7f551d0 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeRegistry.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeRegistry.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.btree.dataflow;
import java.util.HashMap;
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeRegistryProvider.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeRegistryProvider.java
index c07bd8b..677d4d4 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeRegistryProvider.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeRegistryProvider.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.btree.dataflow;
public class BTreeRegistryProvider implements IBTreeRegistryProvider {
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeSearchOperatorDescriptor.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeSearchOperatorDescriptor.java
index b30c6e2..ce5795b 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeSearchOperatorDescriptor.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeSearchOperatorDescriptor.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.btree.dataflow;
import edu.uci.ics.hyracks.api.context.IHyracksContext;
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeSearchOperatorNodePushable.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeSearchOperatorNodePushable.java
index e360be2..67a4ff2 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeSearchOperatorNodePushable.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeSearchOperatorNodePushable.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.btree.dataflow;
import java.io.DataOutput;
@@ -12,6 +27,7 @@
import edu.uci.ics.hyracks.dataflow.common.comm.util.FrameUtils;
import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeCursor;
import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeLeafFrame;
+import edu.uci.ics.hyracks.storage.am.btree.api.IFieldIterator;
import edu.uci.ics.hyracks.storage.am.btree.impls.MultiComparator;
import edu.uci.ics.hyracks.storage.am.btree.impls.RangePredicate;
import edu.uci.ics.hyracks.storage.am.btree.impls.RangeSearchCursor;
@@ -24,7 +40,7 @@
private int searchKeyFields;
public BTreeSearchOperatorNodePushable(AbstractBTreeOperatorDescriptor opDesc, IHyracksContext ctx, boolean isForward, byte[] lowKey, byte[] highKey, int searchKeyFields) {
- super(opDesc, ctx);
+ super(opDesc, ctx, false);
this.isForward = isForward;
this.lowKey = lowKey;
this.highKey = highKey;
@@ -68,13 +84,11 @@
while(cursor.hasNext()) {
tb.reset();
cursor.next();
-
- int recRunner = cursor.getOffset();
- byte[] array = cursor.getPage().getBuffer().array();
- for(int i = 0; i < cmp.getFields().length; i++) {
- int fieldLen = cmp.getFields()[i].getLength(array, recRunner);
- dos.write(array, recRunner, fieldLen);
- recRunner += fieldLen;
+
+ IFieldIterator fieldIter = cursor.getFieldIterator();
+ for(int i = 0; i < cmp.getFields().length; i++) {
+ int fieldLen = fieldIter.getFieldSize();
+ dos.write(fieldIter.getBuffer().array(), fieldIter.getFieldOff(), fieldLen);
tb.addFieldEndOffset();
}
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BufferCacheProvider.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BufferCacheProvider.java
index 66f062e..bc64d81 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BufferCacheProvider.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BufferCacheProvider.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.btree.dataflow;
import java.nio.ByteBuffer;
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/IBTreeOperatorDescriptor.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/IBTreeOperatorDescriptor.java
index b25aec2..707d20e 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/IBTreeOperatorDescriptor.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/IBTreeOperatorDescriptor.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.btree.dataflow;
import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeInteriorFrameFactory;
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/IBTreeRegistryProvider.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/IBTreeRegistryProvider.java
index ec9a007..128af09 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/IBTreeRegistryProvider.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/IBTreeRegistryProvider.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.btree.dataflow;
import java.io.Serializable;
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/IBufferCacheProvider.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/IBufferCacheProvider.java
index 6f0edc6..c1a0eb4 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/IBufferCacheProvider.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/IBufferCacheProvider.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.btree.dataflow;
import java.io.Serializable;
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/FieldPrefixNSMLeafFrame.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/FieldPrefixNSMLeafFrame.java
index 7627055..96884e4 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/FieldPrefixNSMLeafFrame.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/FieldPrefixNSMLeafFrame.java
@@ -23,12 +23,13 @@
import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeFrame;
import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeLeafFrame;
import edu.uci.ics.hyracks.storage.am.btree.api.IFieldAccessor;
+import edu.uci.ics.hyracks.storage.am.btree.api.IFieldIterator;
import edu.uci.ics.hyracks.storage.am.btree.api.IFrameCompressor;
import edu.uci.ics.hyracks.storage.am.btree.api.IPrefixSlotManager;
import edu.uci.ics.hyracks.storage.am.btree.api.ISlotManager;
import edu.uci.ics.hyracks.storage.am.btree.compressors.FieldPrefixCompressor;
import edu.uci.ics.hyracks.storage.am.btree.impls.BTreeException;
-import edu.uci.ics.hyracks.storage.am.btree.impls.FieldIterator;
+import edu.uci.ics.hyracks.storage.am.btree.impls.FieldPrefixFieldIterator;
import edu.uci.ics.hyracks.storage.am.btree.impls.FieldPrefixSlotManager;
import edu.uci.ics.hyracks.storage.am.btree.impls.MultiComparator;
import edu.uci.ics.hyracks.storage.am.btree.impls.SlotOffRecOff;
@@ -164,7 +165,7 @@
if(exactDelete) {
IBinaryComparator[] cmps = cmp.getComparators();
IFieldAccessor[] fields = cmp.getFields();
- FieldIterator fieldIter = new FieldIterator(fields, this);
+ FieldPrefixFieldIterator fieldIter = new FieldPrefixFieldIterator(fields, this);
fieldIter.openRecSlotOff(recSlotOff);
int dataRunner = 0;
@@ -190,10 +191,11 @@
// maintain space information, get size of record suffix (suffix could be entire record)
int recSize = 0;
int suffixFieldStart = 0;
- FieldIterator fieldIter = new FieldIterator(cmp.getFields(), this);
+ FieldPrefixFieldIterator fieldIter = new FieldPrefixFieldIterator(cmp.getFields(), this);
fieldIter.openRecSlotOff(recSlotOff);
if(prefixSlotNum == FieldPrefixSlotManager.RECORD_UNCOMPRESSED) {
suffixFieldStart = 0;
+ buf.putInt(numUncompressedRecordsOff, buf.getInt(numUncompressedRecordsOff) - 1);
}
else {
int prefixSlot = buf.getInt(slotManager.getPrefixSlotOff(prefixSlotNum));
@@ -355,13 +357,13 @@
}
public ISlotManager getSlotManager() {
- return null; // TODO: dummy
+ return null;
}
@Override
public String printKeys(MultiComparator cmp) {
StringBuilder strBuilder = new StringBuilder();
- FieldIterator rec = new FieldIterator(cmp.getFields(), this);
+ FieldPrefixFieldIterator rec = new FieldPrefixFieldIterator(cmp.getFields(), this);
int numRecords = buf.getInt(numRecordsOff);
for(int i = 0; i < numRecords; i++) {
rec.openRecSlotNum(i);
@@ -378,7 +380,9 @@
@Override
public int getRecordOffset(int slotNum) {
- return slotManager.getRecSlotOff(slotNum);
+ int recSlotOff = slotManager.getRecSlotOff(slotNum);
+ int recSlot = buf.getInt(recSlotOff);
+ return slotManager.decodeSecondSlotField(recSlot);
}
@Override
@@ -433,9 +437,40 @@
}
@Override
- public void insertSorted(byte[] data, MultiComparator cmp) throws Exception {
- // TODO Auto-generated method stub
-
+ public void insertSorted(byte[] data, MultiComparator cmp) throws Exception {
+ int freeSpace = buf.getInt(freeSpaceOff);
+ int fieldsToTruncate = 0;
+ if(buf.getInt(numPrefixRecordsOff) > 0) {
+ // check if record matches last prefix record
+ int prefixSlotOff = slotManager.getPrefixSlotOff(buf.getInt(numPrefixRecordsOff)-1);
+ int prefixSlot = buf.getInt(prefixSlotOff);
+ int numPrefixFields = slotManager.decodeFirstSlotField(prefixSlot);
+ int prefixRecOff = slotManager.decodeSecondSlotField(prefixSlot);
+
+ if(cmp.fieldRangeCompare(data, 0, buf.array(), prefixRecOff, 0, numPrefixFields) == 0) {
+ fieldsToTruncate = numPrefixFields;
+ }
+ }
+
+ // copy truncated record
+ int recStart = 0;
+ for(int i = 0; i < fieldsToTruncate; i++) {
+ recStart += cmp.getFields()[i].getLength(data, recStart);
+ }
+ int recLen = data.length - recStart;
+ System.arraycopy(data, recStart, buf.array(), freeSpace, recLen);
+
+ // insert slot
+ int prefixSlotNum = FieldPrefixSlotManager.RECORD_UNCOMPRESSED;
+ if(fieldsToTruncate > 0) prefixSlotNum = buf.getInt(numPrefixRecordsOff)-1;
+ else buf.putInt(numUncompressedRecordsOff, buf.getInt(numUncompressedRecordsOff) + 1);
+ int insSlot = slotManager.encodeSlotFields(prefixSlotNum, FieldPrefixSlotManager.GREATEST_SLOT);
+ slotManager.insertSlot(insSlot, freeSpace);
+
+ // update page metadata
+ buf.putInt(numRecordsOff, buf.getInt(numRecordsOff) + 1);
+ buf.putInt(freeSpaceOff, buf.getInt(freeSpaceOff) + recLen);
+ buf.putInt(totalFreeSpaceOff, buf.getInt(totalFreeSpaceOff) - recLen - slotManager.getSlotSize());
}
@Override
@@ -579,7 +614,7 @@
int splitKeyRecSlotOff = slotManager.getRecSlotEndOff();
int keySize = 0;
- FieldIterator fieldIter = new FieldIterator(cmp.getFields(), this);
+ FieldPrefixFieldIterator fieldIter = new FieldPrefixFieldIterator(cmp.getFields(), this);
fieldIter.openRecSlotOff(splitKeyRecSlotOff);
for(int i = 0; i < cmp.getKeyLength(); i++) {
keySize += fieldIter.getFieldSize();
@@ -632,4 +667,14 @@
public void setNumUncompressedRecords(int numUncompressedRecords) {
buf.putInt(numUncompressedRecordsOff, numUncompressedRecords);
}
+
+ @Override
+ public int getSlotSize() {
+ return slotManager.getSlotSize();
+ }
+
+ @Override
+ public IFieldIterator createFieldIterator() {
+ return new FieldPrefixFieldIterator();
+ }
}
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/NSMFrame.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/NSMFrame.java
index 20a3e19..cca5268 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/NSMFrame.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/NSMFrame.java
@@ -20,9 +20,11 @@
import java.util.Collections;
import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeFrame;
+import edu.uci.ics.hyracks.storage.am.btree.api.IFieldIterator;
import edu.uci.ics.hyracks.storage.am.btree.api.ISlotManager;
import edu.uci.ics.hyracks.storage.am.btree.impls.BTreeException;
import edu.uci.ics.hyracks.storage.am.btree.impls.MultiComparator;
+import edu.uci.ics.hyracks.storage.am.btree.impls.NSMFieldIterator;
import edu.uci.ics.hyracks.storage.am.btree.impls.OrderedSlotManager;
import edu.uci.ics.hyracks.storage.am.btree.impls.SlotOffRecOff;
import edu.uci.ics.hyracks.storage.am.btree.impls.SpaceStatus;
@@ -263,4 +265,14 @@
public boolean compress(MultiComparator cmp) {
return false;
}
+
+ @Override
+ public int getSlotSize() {
+ return slotManager.getSlotSize();
+ }
+
+ @Override
+ public IFieldIterator createFieldIterator() {
+ return new NSMFieldIterator();
+ }
}
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/NSMInteriorFrame.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/NSMInteriorFrame.java
index 773400a..a3af5b2 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/NSMInteriorFrame.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/NSMInteriorFrame.java
@@ -103,7 +103,7 @@
buf.putInt(numRecordsOff, buf.getInt(numRecordsOff) + 1);
buf.putInt(freeSpaceOff, buf.getInt(freeSpaceOff) + recSize);
buf.putInt(totalFreeSpaceOff, buf.getInt(totalFreeSpaceOff) - recSize - slotManager.getSlotSize());
- System.arraycopy(data, recSize, buf.array(), rightLeafOff, childPtrSize);
+ System.arraycopy(data, recSize, buf.array(), rightLeafOff, childPtrSize);
}
@Override
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/NSMInteriorFrameFactory.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/NSMInteriorFrameFactory.java
index f772761..81a6e34 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/NSMInteriorFrameFactory.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/NSMInteriorFrameFactory.java
@@ -19,6 +19,9 @@
import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeInteriorFrameFactory;
public class NSMInteriorFrameFactory implements IBTreeInteriorFrameFactory {
+
+ private static final long serialVersionUID = 1L;
+
@Override
public IBTreeInteriorFrame getFrame() {
return new NSMInteriorFrame();
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/NSMLeafFrame.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/NSMLeafFrame.java
index 3d51f05c..c41106d 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/NSMLeafFrame.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/NSMLeafFrame.java
@@ -90,7 +90,7 @@
buf.putInt(freeSpaceOff, buf.getInt(freeSpaceOff) + data.length);
buf.putInt(totalFreeSpaceOff, buf.getInt(totalFreeSpaceOff) - data.length - slotManager.getSlotSize());
}
-
+
@Override
public int split(IBTreeFrame rightFrame, byte[] data, MultiComparator cmp, SplitKey splitKey) throws Exception {
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/NSMLeafFrameFactory.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/NSMLeafFrameFactory.java
index 7ef1c8f..169327b 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/NSMLeafFrameFactory.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/NSMLeafFrameFactory.java
@@ -19,6 +19,9 @@
import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeLeafFrameFactory;
public class NSMLeafFrameFactory implements IBTreeLeafFrameFactory {
+
+ private static final long serialVersionUID = 1L;
+
@Override
public IBTreeLeafFrame getFrame() {
return new NSMLeafFrame();
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/BTree.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/BTree.java
index 74e67af..42d375c 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/BTree.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/BTree.java
@@ -20,6 +20,7 @@
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeCursor;
import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeFrame;
import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeInteriorFrame;
@@ -33,7 +34,7 @@
import edu.uci.ics.hyracks.storage.common.file.FileInfo;
public class BTree {
-
+
private final static int RESTART_OP = Integer.MIN_VALUE;
private final static int MAX_RESTARTS = 10;
@@ -42,13 +43,14 @@
private final int rootPage = 1; // the root page never changes
private boolean created = false;
-
+
private final IBufferCache bufferCache;
private int fileId;
private final IBTreeInteriorFrameFactory interiorFrameFactory;
private final IBTreeLeafFrameFactory leafFrameFactory;
private final MultiComparator cmp;
- private final ReadWriteLock treeLatch;
+ private final ReadWriteLock treeLatch;
+ private final RangePredicate diskOrderScanPredicate;
public int rootSplits = 0;
public int[] splitsByLevel = new int[500];
@@ -93,6 +95,7 @@
this.leafFrameFactory = leafFrameFactory;
this.cmp = cmp;
this.treeLatch = new ReentrantReadWriteLock(true);
+ this.diskOrderScanPredicate = new RangePredicate(true, null, null, cmp);
}
public void create(int fileId, IBTreeLeafFrame leafFrame, IBTreeMetaDataFrame metaFrame) throws Exception {
@@ -102,7 +105,7 @@
treeLatch.writeLock().lock();
try {
- // check if another thread bet us to it
+ // check if another thread beat us to it
if(created) return;
// initialize meta data page
@@ -285,6 +288,26 @@
}
}
+ public int getMaxPage(IBTreeMetaDataFrame metaFrame) throws HyracksDataException {
+ ICachedPage metaNode = bufferCache.pin(FileInfo.getDiskPageId(fileId, metaDataPage), false);
+ pins++;
+
+ metaNode.acquireWriteLatch();
+ writeLatchesAcquired++;
+ int maxPage = -1;
+ try {
+ metaFrame.setPage(metaNode);
+ maxPage = metaFrame.getMaxPage();
+ } finally {
+ metaNode.releaseWriteLatch();
+ writeLatchesReleased++;
+ bufferCache.unpin(metaNode);
+ unpins++;
+ }
+
+ return maxPage;
+ }
+
public void printTree(IBTreeLeafFrame leafFrame, IBTreeInteriorFrame interiorFrame) throws Exception {
printTree(rootPage, null, false, leafFrame, interiorFrame);
}
@@ -393,7 +416,7 @@
cursor.setFileId(fileId);
cursor.setCurrentPageId(currentPageId);
cursor.setMaxPageId(maxPageId);
- cursor.open(page, null);
+ cursor.open(page, diskOrderScanPredicate);
}
public void search(IBTreeCursor cursor, RangePredicate pred, IBTreeLeafFrame leafFrame,
@@ -1179,13 +1202,13 @@
interiorFrame.setPage(leafFrontier.page);
interiorFrame.initBuffer((byte) 0);
- interiorMaxBytes = (int) ((float) interiorFrame.getTotalFreeSpace() * fillFactor);
-
+ interiorMaxBytes = (int) ((float) interiorFrame.getBuffer().capacity() * fillFactor);
+
leafFrame.setPage(leafFrontier.page);
leafFrame.initBuffer((byte) 0);
- leafMaxBytes = (int) ((float) leafFrame.getTotalFreeSpace() * fillFactor);
-
- slotSize = leafFrame.getSlotManager().getSlotSize();
+ leafMaxBytes = (int) ((float) leafFrame.getBuffer().capacity() * fillFactor);
+
+ slotSize = leafFrame.getSlotSize();
this.leafFrame = leafFrame;
this.interiorFrame = interiorFrame;
@@ -1196,7 +1219,6 @@
private void addLevel() throws Exception {
NodeFrontier frontier = new NodeFrontier();
- frontier.bytesInserted = 0;
frontier.pageId = getFreePage(metaFrame);
frontier.page = bufferCache.pin(FileInfo.getDiskPageId(fileId, frontier.pageId), bulkNewPage);
frontier.page.acquireWriteLatch();
@@ -1218,10 +1240,9 @@
ctx.interiorFrame.setPage(frontier.page);
byte[] insBytes = ctx.splitKey.getData();
int keySize = cmp.getKeySize(insBytes, 0);
- int spaceNeeded = keySize + ctx.slotSize + 4; // TODO: this is a dirty
- // constant for the size
- // of a child pointer
- if (frontier.bytesInserted + spaceNeeded > ctx.interiorMaxBytes) {
+ int spaceNeeded = keySize + ctx.slotSize + 4; // TODO: this is a dirty constant for the size of a child pointer
+ int spaceUsed = ctx.interiorFrame.getBuffer().capacity() - ctx.interiorFrame.getTotalFreeSpace();
+ if (spaceUsed + spaceNeeded > ctx.interiorMaxBytes) {
ctx.interiorFrame.deleteGreatest(cmp);
int splitKeySize = cmp.getKeySize(frontier.lastRecord, 0);
ctx.splitKey.initData(splitKeySize);
@@ -1239,11 +1260,9 @@
frontier.page.acquireWriteLatch();
ctx.interiorFrame.setPage(frontier.page);
ctx.interiorFrame.initBuffer((byte) level);
- frontier.bytesInserted = 0;
}
ctx.interiorFrame.insertSorted(insBytes, cmp);
frontier.lastRecord = insBytes;
- frontier.bytesInserted += spaceNeeded;
}
// assumes btree has been created and opened
@@ -1257,7 +1276,15 @@
IBTreeLeafFrame leafFrame = ctx.leafFrame;
int spaceNeeded = record.length + ctx.slotSize;
- if (leafFrontier.bytesInserted + spaceNeeded > ctx.leafMaxBytes) {
+ int spaceUsed = leafFrame.getBuffer().capacity() - leafFrame.getTotalFreeSpace();
+
+ // try to free space by compression
+ if (spaceUsed + spaceNeeded > ctx.leafMaxBytes) {
+ leafFrame.compress(cmp);
+ spaceUsed = leafFrame.getBuffer().capacity() - leafFrame.getTotalFreeSpace();
+ }
+
+ if (spaceUsed + spaceNeeded > ctx.leafMaxBytes) {
int splitKeySize = cmp.getKeySize(leafFrontier.lastRecord, 0);
ctx.splitKey.initData(splitKeySize);
System.arraycopy(leafFrontier.lastRecord, 0, ctx.splitKey.getData(), 0, splitKeySize);
@@ -1276,13 +1303,11 @@
leafFrame.setPage(leafFrontier.page);
leafFrame.initBuffer((byte) 0);
leafFrame.setPrevLeaf(prevPageId);
- leafFrontier.bytesInserted = 0;
}
leafFrame.setPage(leafFrontier.page);
leafFrame.insertSorted(record, cmp);
leafFrontier.lastRecord = record;
- leafFrontier.bytesInserted += spaceNeeded;
}
public void endBulkLoad(BulkLoadContext ctx) throws Exception {
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/BTreeOp.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/BTreeOp.java
index b1909a9..4c0ef81 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/BTreeOp.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/BTreeOp.java
@@ -18,5 +18,6 @@
public enum BTreeOp {
BTO_INSERT,
BTO_DELETE,
- BTO_SEARCH
+ BTO_UPDATE,
+ BTO_SEARCH
}
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/DiskOrderScanCursor.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/DiskOrderScanCursor.java
index 441ea02..443cf2a 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/DiskOrderScanCursor.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/DiskOrderScanCursor.java
@@ -17,6 +17,7 @@
import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeCursor;
import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeLeafFrame;
+import edu.uci.ics.hyracks.storage.am.btree.api.IFieldIterator;
import edu.uci.ics.hyracks.storage.am.btree.api.ISearchPredicate;
import edu.uci.ics.hyracks.storage.common.buffercache.IBufferCache;
import edu.uci.ics.hyracks.storage.common.buffercache.ICachedPage;
@@ -27,7 +28,6 @@
// TODO: might want to return records in physical order, not logical order to speed up access
private int recordNum = 0;
- private int recordOffset = -1;
private int fileId = -1;
int currentPageId = -1;
int maxPageId = -1; // TODO: figure out how to scan to the end of file, this is dirty and may not with concurrent updates
@@ -35,8 +35,12 @@
private IBTreeLeafFrame frame = null;
private IBufferCache bufferCache = null;
+ private IFieldIterator fieldIter;
+
public DiskOrderScanCursor(IBTreeLeafFrame frame) {
this.frame = frame;
+ this.fieldIter = frame.createFieldIterator();
+ this.fieldIter.setFrame(frame);
}
@Override
@@ -45,12 +49,13 @@
bufferCache.unpin(page);
page = null;
}
-
+
@Override
- public int getOffset() {
- return recordOffset;
- }
-
+ public IFieldIterator getFieldIterator() {
+ fieldIter.reset();
+ return fieldIter;
+ }
+
@Override
public ICachedPage getPage() {
return page;
@@ -80,7 +85,7 @@
if(recordNum >= frame.getNumRecords()) {
boolean nextLeafExists = positionToNextLeaf(true);
if(nextLeafExists) {
- recordOffset = frame.getRecordOffset(recordNum);
+ fieldIter.openRecSlotNum(recordNum);
return true;
}
else {
@@ -88,7 +93,7 @@
}
}
- recordOffset = frame.getRecordOffset(recordNum);
+ fieldIter.openRecSlotNum(recordNum);
return true;
}
@@ -108,6 +113,9 @@
this.page = page;
recordNum = 0;
frame.setPage(page);
+ RangePredicate pred = (RangePredicate)searchPred;
+ MultiComparator cmp = pred.getComparator();
+ this.fieldIter.setFields(cmp.getFields());
boolean leafExists = positionToNextLeaf(false);
if(!leafExists) {
throw new Exception("Failed to open disk-order scan cursor for B-tree. Traget B-tree has no leaves.");
@@ -117,7 +125,6 @@
@Override
public void reset() {
recordNum = 0;
- recordOffset = 0;
currentPageId = -1;
maxPageId = -1;
page = null;
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/FieldIterator.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/FieldPrefixFieldIterator.java
similarity index 87%
rename from hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/FieldIterator.java
rename to hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/FieldPrefixFieldIterator.java
index 8132199..f0fdf1d 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/FieldIterator.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/FieldPrefixFieldIterator.java
@@ -15,11 +15,15 @@
package edu.uci.ics.hyracks.storage.am.btree.impls;
+import java.nio.ByteBuffer;
+
+import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeFrame;
import edu.uci.ics.hyracks.storage.am.btree.api.IFieldAccessor;
+import edu.uci.ics.hyracks.storage.am.btree.api.IFieldIterator;
import edu.uci.ics.hyracks.storage.am.btree.frames.FieldPrefixNSMLeafFrame;
-//TODO: make members private, only for debugging now
-public class FieldIterator {
+// TODO: make members private, only for debugging now
+public class FieldPrefixFieldIterator implements IFieldIterator {
public int recSlotOff = -1;
public int recOff = -1;
public int prefixSlotNum = FieldPrefixSlotManager.RECORD_UNCOMPRESSED;
@@ -30,13 +34,16 @@
public int currentField = -1;
public int recOffRunner = -1;
- public FieldIterator(IFieldAccessor[] fields, FieldPrefixNSMLeafFrame frame) {
+ public FieldPrefixFieldIterator() {
+ }
+
+ public FieldPrefixFieldIterator(IFieldAccessor[] fields, FieldPrefixNSMLeafFrame frame) {
this.fields = fields;
this.frame = frame;
}
- public void setFrame(FieldPrefixNSMLeafFrame frame) {
- this.frame = frame;
+ public void setFrame(IBTreeFrame frame) {
+ this.frame = (FieldPrefixNSMLeafFrame)frame;
}
public void setFields(IFieldAccessor[] fields) {
@@ -121,4 +128,8 @@
return bytesWritten;
}
+ @Override
+ public ByteBuffer getBuffer() {
+ return frame.getBuffer();
+ }
}
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/FieldPrefixSlotManager.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/FieldPrefixSlotManager.java
index de4c913..e6d28bd 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/FieldPrefixSlotManager.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/FieldPrefixSlotManager.java
@@ -30,7 +30,7 @@
private ByteBuffer buf;
private FieldPrefixNSMLeafFrame frame;
- FieldIterator fieldIter = new FieldIterator(null, null);
+ FieldPrefixFieldIterator fieldIter = new FieldPrefixFieldIterator(null, null);
public int decodeFirstSlotField(int slot) {
return (slot & 0xFF000000) >>> 24;
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/MultiComparator.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/MultiComparator.java
index 659cfbf..6dbd9c5 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/MultiComparator.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/MultiComparator.java
@@ -17,6 +17,7 @@
import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparator;
import edu.uci.ics.hyracks.storage.am.btree.api.IFieldAccessor;
+import edu.uci.ics.hyracks.storage.am.btree.api.IFieldIterator;
public class MultiComparator {
@@ -69,6 +70,24 @@
return 0;
}
+ public int compare(byte[] data, int recOff, IFieldIterator fieldIter) {
+ fieldIter.reset();
+
+ int recRunner = 0;
+ int cmp = 0;
+ for(int i = 0; i < cmps.length; i++) {
+ int recFieldLen = fields[i].getLength(data, recRunner);
+ cmp = cmps[i].compare(data, recRunner, recFieldLen, fieldIter.getBuffer().array(), fieldIter.getFieldOff(), fieldIter.getFieldSize());
+ if(cmp < 0) return -1;
+ else if(cmp > 0) return 1;
+ fieldIter.nextField();
+ recRunner += recFieldLen;
+ }
+
+ fieldIter.reset();
+ return 0;
+ }
+
public int fieldRangeCompare(byte[] dataA, int recOffA, byte[] dataB, int recOffB, int startFieldIndex, int numFields) {
int lenA;
int lenB;
@@ -100,6 +119,16 @@
return runner - recOff;
}
+ public String printRecord(IFieldIterator fieldIter) {
+ StringBuilder strBuilder = new StringBuilder();
+ fieldIter.reset();
+ for(int i = 0; i < fields.length; i++) {
+ strBuilder.append(fields[i].print(fieldIter.getBuffer().array(), fieldIter.getFieldOff()) + " ");
+ fieldIter.nextField();
+ }
+ return strBuilder.toString();
+ }
+
public String printRecord(byte[] data, int recOff) {
StringBuilder strBuilder = new StringBuilder();
int runner = recOff;
@@ -109,7 +138,7 @@
}
return strBuilder.toString();
}
-
+
public String printKey(byte[] data, int recOff) {
StringBuilder strBuilder = new StringBuilder();
int runner = recOff;
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/NSMFieldIterator.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/NSMFieldIterator.java
new file mode 100644
index 0000000..760fa8a
--- /dev/null
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/NSMFieldIterator.java
@@ -0,0 +1,91 @@
+/*
+ * 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.btree.impls;
+
+import java.nio.ByteBuffer;
+
+import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeFrame;
+import edu.uci.ics.hyracks.storage.am.btree.api.IFieldAccessor;
+import edu.uci.ics.hyracks.storage.am.btree.api.IFieldIterator;
+import edu.uci.ics.hyracks.storage.am.btree.frames.NSMFrame;
+
+public class NSMFieldIterator implements IFieldIterator {
+ public int recOff = -1;
+ public IFieldAccessor[] fields;
+ public NSMFrame frame;
+
+ public int currentField = -1;
+ public int recOffRunner = -1;
+
+ public NSMFieldIterator() {
+ }
+
+ public NSMFieldIterator(IFieldAccessor[] fields, NSMFrame frame) {
+ this.fields = fields;
+ this.frame = frame;
+ }
+
+ public void setFrame(NSMFrame frame) {
+ this.frame = frame;
+ }
+
+ public void setFields(IFieldAccessor[] fields) {
+ this.fields = fields;
+ }
+
+ public void openRecSlotNum(int recSlotNum) {
+ int recSlotOff = frame.getSlotManager().getSlotOff(recSlotNum);
+ openRecSlotOff(recSlotOff);
+ }
+
+ public void openRecSlotOff(int recSlotOff) {
+ recOff = frame.getSlotManager().getRecOff(recSlotOff);
+ reset();
+ }
+
+ // re-position to first field
+ public void reset() {
+ currentField = 0;
+ recOffRunner = recOff;
+ }
+
+ public void nextField() {
+ recOffRunner += fields[currentField].getLength(frame.getBuffer().array(), recOffRunner);
+ }
+
+ public int getFieldOff() {
+ return recOffRunner;
+ }
+
+ public int getFieldSize() {
+ return fields[currentField].getLength(frame.getBuffer().array(), recOffRunner);
+ }
+
+ public int copyFields(int startField, int endField, byte[] dest, int destOff) {
+
+ return 0;
+ }
+
+ @Override
+ public void setFrame(IBTreeFrame frame) {
+ this.frame = (NSMFrame)frame;
+ }
+
+ @Override
+ public ByteBuffer getBuffer() {
+ return frame.getBuffer();
+ }
+}
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/NodeFrontier.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/NodeFrontier.java
index df5f064..6dcafb4 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/NodeFrontier.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/NodeFrontier.java
@@ -18,7 +18,6 @@
import edu.uci.ics.hyracks.storage.common.buffercache.ICachedPage;
public class NodeFrontier {
- public int bytesInserted;
public ICachedPage page;
public int pageId;
public byte[] lastRecord;
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/RangePredicate.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/RangePredicate.java
index 68d7ad2..d71019f 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/RangePredicate.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/RangePredicate.java
@@ -25,7 +25,7 @@
protected byte[] lowKeys = null;
protected byte[] highKeys = null;
protected MultiComparator cmp;
-
+
public RangePredicate() {
}
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/RangeSearchCursor.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/RangeSearchCursor.java
index 99784bc..b6234fb 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/RangeSearchCursor.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/RangeSearchCursor.java
@@ -17,6 +17,7 @@
import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeCursor;
import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeLeafFrame;
+import edu.uci.ics.hyracks.storage.am.btree.api.IFieldIterator;
import edu.uci.ics.hyracks.storage.am.btree.api.ISearchPredicate;
import edu.uci.ics.hyracks.storage.common.buffercache.IBufferCache;
import edu.uci.ics.hyracks.storage.common.buffercache.ICachedPage;
@@ -32,8 +33,12 @@
private IBTreeLeafFrame frame = null;
private IBufferCache bufferCache = null;
+ private IFieldIterator fieldIter;
+
public RangeSearchCursor(IBTreeLeafFrame frame) {
- this.frame = frame;
+ this.frame = frame;
+ this.fieldIter = frame.createFieldIterator();
+ this.fieldIter.setFrame(frame);
}
@Override
@@ -42,12 +47,12 @@
bufferCache.unpin(page);
page = null;
}
-
- @Override
- public int getOffset() {
- return recordOffset;
+
+ public IFieldIterator getFieldIterator() {
+ fieldIter.reset();
+ return fieldIter;
}
-
+
@Override
public ICachedPage getPage() {
return page;
@@ -86,10 +91,12 @@
MultiComparator cmp = pred.getComparator();
if(searchPred.isForward()) {
byte[] highKeys = pred.getHighKeys();
- recordOffset = frame.getRecordOffset(recordNum);
+ fieldIter.openRecSlotNum(recordNum);
+ //recordOffset = frame.getRecordOffset(recordNum);
- if(highKeys == null) return true;
- if(cmp.compare(highKeys, 0, page.getBuffer().array(), recordOffset) < 0) {
+ if(highKeys == null) return true;
+ //if(cmp.compare(highKeys, 0, page.getBuffer().array(), recordOffset) < 0) {
+ if(cmp.compare(highKeys, 0, fieldIter) < 0) {
return false;
}
else {
@@ -111,7 +118,7 @@
}
@Override
- public void next() throws Exception {
+ public void next() throws Exception {
recordNum++;
}
@@ -122,35 +129,40 @@
this.page.releaseReadLatch();
bufferCache.unpin(this.page);
}
-
+
this.searchPred = searchPred;
this.page = page;
- frame.setPage(page);
+ frame.setPage(page);
// position recordNum to the first appropriate key
// TODO: can be done more efficiently with binary search but this needs some thinking/refactoring
RangePredicate pred = (RangePredicate)searchPred;
MultiComparator cmp = pred.getComparator();
+ this.fieldIter.setFields(cmp.getFields());
if(searchPred.isForward()) {
byte[] lowKeys = pred.getLowKeys();
- recordOffset = frame.getRecordOffset(recordNum);
+ //recordOffset = frame.getRecordOffset(recordNum);
+ fieldIter.openRecSlotNum(recordNum);
if(lowKeys == null) return; // null means -infinity
-
- while(cmp.compare(lowKeys, 0, page.getBuffer().array(), recordOffset) > 0 && recordNum < frame.getNumRecords()) {
+
+ while(cmp.compare(lowKeys, 0, fieldIter) > 0 && recordNum < frame.getNumRecords()) {
+ //while(cmp.compare(lowKeys, 0, page.getBuffer().array(), recordOffset) > 0 && recordNum < frame.getNumRecords()) {
recordNum++;
- recordOffset = frame.getRecordOffset(recordNum);
- }
+ fieldIter.openRecSlotNum(recordNum);
+ }
}
else {
byte[] highKeys = pred.getHighKeys();
- recordOffset = frame.getRecordOffset(frame.getNumRecords() - recordNum - 1);
+ //recordOffset = frame.getRecordOffset(frame.getNumRecords() - recordNum - 1);
+ fieldIter.openRecSlotNum(recordNum);
if(highKeys != null) return; // null means +infinity
while(cmp.compare(highKeys, 0, page.getBuffer().array(), recordOffset) < 0 && recordNum < frame.getNumRecords()) {
recordNum++;
- recordOffset = frame.getRecordOffset(frame.getNumRecords() - recordNum - 1);
+ fieldIter.openRecSlotNum(recordNum);
+ //recordOffset = frame.getRecordOffset(frame.getNumRecords() - recordNum - 1);
}
}
}
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/types/Int32AccessorFactory.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/types/Int32AccessorFactory.java
index b8607c0..4eceeb2 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/types/Int32AccessorFactory.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/types/Int32AccessorFactory.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.btree.types;
import edu.uci.ics.hyracks.storage.am.btree.api.IFieldAccessor;
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/types/UTF8StringAccessorFactory.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/types/UTF8StringAccessorFactory.java
index e2d8053..1359190 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/types/UTF8StringAccessorFactory.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/types/UTF8StringAccessorFactory.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.btree.types;
import edu.uci.ics.hyracks.storage.am.btree.api.IFieldAccessor;
diff --git a/hyracks-storage-am-btree/src/test/java/edu/uci/ics/hyracks/storage/am/btree/BTreeTest.java b/hyracks-storage-am-btree/src/test/java/edu/uci/ics/hyracks/storage/am/btree/BTreeTest.java
index 1fb08e4..3caba23 100644
--- a/hyracks-storage-am-btree/src/test/java/edu/uci/ics/hyracks/storage/am/btree/BTreeTest.java
+++ b/hyracks-storage-am-btree/src/test/java/edu/uci/ics/hyracks/storage/am/btree/BTreeTest.java
@@ -37,6 +37,7 @@
import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeMetaDataFrame;
import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeMetaDataFrameFactory;
import edu.uci.ics.hyracks.storage.am.btree.api.IFieldAccessor;
+import edu.uci.ics.hyracks.storage.am.btree.api.IFieldIterator;
import edu.uci.ics.hyracks.storage.am.btree.frames.MetaDataFrameFactory;
import edu.uci.ics.hyracks.storage.am.btree.frames.NSMInteriorFrameFactory;
import edu.uci.ics.hyracks.storage.am.btree.frames.NSMLeafFrameFactory;
@@ -56,6 +57,7 @@
import edu.uci.ics.hyracks.storage.common.file.FileManager;
public class BTreeTest {
+
private static final int PAGE_SIZE = 128;
// private static final int PAGE_SIZE = 8192;
private static final int NUM_PAGES = 10;
@@ -169,9 +171,8 @@
try {
while (scanCursor.hasNext()) {
scanCursor.next();
- byte[] array = scanCursor.getPage().getBuffer().array();
- int recOffset = scanCursor.getOffset();
- String rec = cmp.printRecord(array, recOffset);
+ IFieldIterator fieldIter = scanCursor.getFieldIterator();
+ String rec = cmp.printRecord(fieldIter);
print(rec + "\n");
}
} catch (Exception e) {
@@ -187,9 +188,8 @@
try {
while (diskOrderCursor.hasNext()) {
diskOrderCursor.next();
- byte[] array = diskOrderCursor.getPage().getBuffer().array();
- int recOffset = diskOrderCursor.getOffset();
- String rec = cmp.printRecord(array, recOffset);
+ IFieldIterator fieldIter = diskOrderCursor.getFieldIterator();
+ String rec = cmp.printRecord(fieldIter);
print(rec + "\n");
}
} catch (Exception e) {
@@ -224,10 +224,9 @@
try {
while (rangeCursor.hasNext()) {
rangeCursor.next();
- byte[] array = rangeCursor.getPage().getBuffer().array();
- int recOffset = rangeCursor.getOffset();
- String rec = cmp.printRecord(array, recOffset);
- print(rec + "\n");
+ IFieldIterator fieldIter = rangeCursor.getFieldIterator();
+ String rec = cmp.printRecord(fieldIter);
+ print(rec + "\n");
}
} catch (Exception e) {
e.printStackTrace();
@@ -329,10 +328,9 @@
try {
while (scanCursor.hasNext()) {
scanCursor.next();
- byte[] array = scanCursor.getPage().getBuffer().array();
- int recOffset = scanCursor.getOffset();
- String rec = cmp.printRecord(array, recOffset);
- print(rec + "\n");
+ IFieldIterator fieldIter = scanCursor.getFieldIterator();
+ String rec = cmp.printRecord(fieldIter);
+ print(rec + "\n");
}
} catch (Exception e) {
e.printStackTrace();
@@ -365,10 +363,9 @@
try {
while (rangeCursor.hasNext()) {
rangeCursor.next();
- byte[] array = rangeCursor.getPage().getBuffer().array();
- int recOffset = rangeCursor.getOffset();
- String rec = cmp.printRecord(array, recOffset);
- print(rec + "\n");
+ IFieldIterator fieldIter = rangeCursor.getFieldIterator();
+ String rec = cmp.printRecord(fieldIter);
+ print(rec + "\n");
}
} catch (Exception e) {
e.printStackTrace();
@@ -461,10 +458,9 @@
try {
while (scanCursor.hasNext()) {
scanCursor.next();
- byte[] array = scanCursor.getPage().getBuffer().array();
- int recOffset = scanCursor.getOffset();
- String rec = cmp.printRecord(array, recOffset);
- print(rec + "\n");
+ IFieldIterator fieldIter = scanCursor.getFieldIterator();
+ String rec = cmp.printRecord(fieldIter);
+ print(rec + "\n");
}
} catch (Exception e) {
e.printStackTrace();
@@ -498,10 +494,9 @@
try {
while (rangeCursor.hasNext()) {
rangeCursor.next();
- byte[] array = rangeCursor.getPage().getBuffer().array();
- int recOffset = rangeCursor.getOffset();
- String rec = cmp.printRecord(array, recOffset);
- print(rec + "\n");
+ IFieldIterator fieldIter = rangeCursor.getFieldIterator();
+ String rec = cmp.printRecord(fieldIter);
+ print(rec + "\n");
}
} catch (Exception e) {
e.printStackTrace();
@@ -736,15 +731,15 @@
searchCmps[0] = IntegerBinaryComparatorFactory.INSTANCE.createBinaryComparator();
MultiComparator searchCmp = new MultiComparator(searchCmps, fields);
- RangePredicate rangePred = new RangePredicate(false, lowKey, highKey, searchCmp);
+ // TODO: check when searching backwards
+ RangePredicate rangePred = new RangePredicate(true, lowKey, highKey, searchCmp);
btree.search(rangeCursor, rangePred, leafFrame, interiorFrame);
try {
while (rangeCursor.hasNext()) {
rangeCursor.next();
- byte[] array = rangeCursor.getPage().getBuffer().array();
- int recOffset = rangeCursor.getOffset();
- String rec = cmp.printRecord(array, recOffset);
+ IFieldIterator fieldIter = rangeCursor.getFieldIterator();
+ String rec = cmp.printRecord(fieldIter);
print(rec + "\n");
}
} catch (Exception e) {
@@ -881,9 +876,8 @@
try {
while (scanCursor.hasNext()) {
scanCursor.next();
- byte[] array = scanCursor.getPage().getBuffer().array();
- int recOffset = scanCursor.getOffset();
- String rec = cmp.printRecord(array, recOffset);
+ IFieldIterator fieldIter = scanCursor.getFieldIterator();
+ String rec = cmp.printRecord(fieldIter);
print(rec + "\n");
}
} catch (Exception e) {
@@ -922,9 +916,8 @@
try {
while (rangeCursor.hasNext()) {
rangeCursor.next();
- byte[] array = rangeCursor.getPage().getBuffer().array();
- int recOffset = rangeCursor.getOffset();
- String rec = cmp.printRecord(array, recOffset);
+ IFieldIterator fieldIter = rangeCursor.getFieldIterator();
+ String rec = cmp.printRecord(fieldIter);
print(rec + "\n");
}
} catch (Exception e) {