Reintegrated hyracks_rtree_bulkload.
git-svn-id: https://hyracks.googlecode.com/svn/branches/hyracks_lsm_tree@1585 123451ca-8445-de46-9d55-352943316053
diff --git a/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/btree/tuples/ILSMBTreeTupleReference.java b/hyracks-api/src/main/java/edu/uci/ics/hyracks/api/dataflow/value/ILinearizeComparator.java
similarity index 71%
copy from hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/btree/tuples/ILSMBTreeTupleReference.java
copy to hyracks-api/src/main/java/edu/uci/ics/hyracks/api/dataflow/value/ILinearizeComparator.java
index cfc71fc..51a8cfe 100644
--- a/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/btree/tuples/ILSMBTreeTupleReference.java
+++ b/hyracks-api/src/main/java/edu/uci/ics/hyracks/api/dataflow/value/ILinearizeComparator.java
@@ -12,11 +12,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package edu.uci.ics.hyracks.api.dataflow.value;
-package edu.uci.ics.hyracks.storage.am.lsm.btree.tuples;
+public interface ILinearizeComparator extends IBinaryComparator {
+ public int getDimensions();
-import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexTupleReference;
-
-public interface ILSMBTreeTupleReference extends ITreeIndexTupleReference {
- public boolean isAntimatter();
-}
+}
\ No newline at end of file
diff --git a/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/btree/tuples/ILSMBTreeTupleReference.java b/hyracks-api/src/main/java/edu/uci/ics/hyracks/api/dataflow/value/ILinearizeComparatorFactory.java
similarity index 71%
copy from hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/btree/tuples/ILSMBTreeTupleReference.java
copy to hyracks-api/src/main/java/edu/uci/ics/hyracks/api/dataflow/value/ILinearizeComparatorFactory.java
index cfc71fc..49a661f 100644
--- a/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/btree/tuples/ILSMBTreeTupleReference.java
+++ b/hyracks-api/src/main/java/edu/uci/ics/hyracks/api/dataflow/value/ILinearizeComparatorFactory.java
@@ -12,11 +12,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package edu.uci.ics.hyracks.api.dataflow.value;
-package edu.uci.ics.hyracks.storage.am.lsm.btree.tuples;
+import java.io.Serializable;
-import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexTupleReference;
-
-public interface ILSMBTreeTupleReference extends ITreeIndexTupleReference {
- public boolean isAntimatter();
-}
+public interface ILinearizeComparatorFactory extends IBinaryComparatorFactory {
+ public ILinearizeComparator createBinaryComparator();
+}
\ No newline at end of file
diff --git a/hyracks-data/hyracks-data-std/src/main/java/edu/uci/ics/hyracks/data/std/api/IPointable.java b/hyracks-data/hyracks-data-std/src/main/java/edu/uci/ics/hyracks/data/std/api/IPointable.java
index d3accba..8808d95 100644
--- a/hyracks-data/hyracks-data-std/src/main/java/edu/uci/ics/hyracks/data/std/api/IPointable.java
+++ b/hyracks-data/hyracks-data-std/src/main/java/edu/uci/ics/hyracks/data/std/api/IPointable.java
@@ -18,4 +18,13 @@
public void set(byte[] bytes, int start, int length);
public void set(IValueReference pointer);
+
+ @Override
+ public byte[] getByteArray();
+
+ @Override
+ public int getStartOffset();
+
+ @Override
+ public int getLength();
}
\ No newline at end of file
diff --git a/hyracks-data/hyracks-data-std/src/main/java/edu/uci/ics/hyracks/data/std/primitive/DoublePointable.java b/hyracks-data/hyracks-data-std/src/main/java/edu/uci/ics/hyracks/data/std/primitive/DoublePointable.java
index 5267086..543031d 100644
--- a/hyracks-data/hyracks-data-std/src/main/java/edu/uci/ics/hyracks/data/std/primitive/DoublePointable.java
+++ b/hyracks-data/hyracks-data-std/src/main/java/edu/uci/ics/hyracks/data/std/primitive/DoublePointable.java
@@ -23,6 +23,17 @@
import edu.uci.ics.hyracks.data.std.api.IPointableFactory;
public final class DoublePointable extends AbstractPointable implements IHashable, IComparable, INumeric {
+ private final static double machineEpsilon;
+ static {
+ float epsilon = 1.0f;
+
+ do {
+ epsilon /= 2.0f;
+ }
+ while ((float)(1.0 + (epsilon/2.0)) != 1.0);
+ machineEpsilon = epsilon;
+ }
+
public static final ITypeTraits TYPE_TRAITS = new ITypeTraits() {
private static final long serialVersionUID = 1L;
@@ -134,4 +145,8 @@
public double doubleValue() {
return getDouble();
}
+
+ public static double getEpsilon() {
+ return machineEpsilon;
+ }
}
\ No newline at end of file
diff --git a/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/lsm/rtree/LSMRTreeOperatorTestHelper.java b/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/lsm/rtree/LSMRTreeOperatorTestHelper.java
index daa3381..f1652a5 100644
--- a/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/lsm/rtree/LSMRTreeOperatorTestHelper.java
+++ b/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/lsm/rtree/LSMRTreeOperatorTestHelper.java
@@ -23,6 +23,7 @@
import edu.uci.ics.hyracks.storage.am.lsm.common.impls.ImmediateFlushPolicyProvider;
import edu.uci.ics.hyracks.storage.am.lsm.common.impls.SequentialSchedulerProvider;
import edu.uci.ics.hyracks.storage.am.lsm.rtree.dataflow.LSMRTreeDataflowHelperFactory;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
import edu.uci.ics.hyracks.tests.am.common.LSMTreeOperatorTestHelper;
public class LSMRTreeOperatorTestHelper extends LSMTreeOperatorTestHelper {
@@ -34,8 +35,9 @@
}
public IIndexDataflowHelperFactory createDataFlowHelperFactory(
- IPrimitiveValueProviderFactory[] valueProviderFactories, IBinaryComparatorFactory[] btreeComparatorFactories) {
- return new LSMRTreeDataflowHelperFactory(valueProviderFactories, btreeComparatorFactories,
+ IPrimitiveValueProviderFactory[] valueProviderFactories, RTreePolicyType rtreePolicyType,
+ IBinaryComparatorFactory[] btreeComparatorFactories) {
+ return new LSMRTreeDataflowHelperFactory(valueProviderFactories, rtreePolicyType, btreeComparatorFactories,
new ImmediateFlushPolicyProvider(SequentialSchedulerProvider.INSTANCE),
new ConstantMergePolicyProvider(SequentialSchedulerProvider.INSTANCE, MERGE_THRESHOLD));
}
diff --git a/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/lsm/rtree/LSMRTreeSecondaryIndexInsertOperatorTest.java b/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/lsm/rtree/LSMRTreeSecondaryIndexInsertOperatorTest.java
index bbdb905..5778f9b 100644
--- a/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/lsm/rtree/LSMRTreeSecondaryIndexInsertOperatorTest.java
+++ b/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/lsm/rtree/LSMRTreeSecondaryIndexInsertOperatorTest.java
@@ -19,6 +19,7 @@
import edu.uci.ics.hyracks.api.exceptions.HyracksException;
import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexDataflowHelperFactory;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
import edu.uci.ics.hyracks.test.support.TestStorageManagerComponentHolder;
import edu.uci.ics.hyracks.tests.am.common.ITreeIndexOperatorTestHelper;
import edu.uci.ics.hyracks.tests.am.rtree.RTreeSecondaryIndexInsertOperatorTest;
@@ -30,9 +31,9 @@
@Override
protected IIndexDataflowHelperFactory createDataFlowHelperFactory(
- IPrimitiveValueProviderFactory[] secondaryValueProviderFactories,
+ IPrimitiveValueProviderFactory[] secondaryValueProviderFactories, RTreePolicyType rtreePolicyType,
IBinaryComparatorFactory[] btreeComparatorFactories) {
return ((LSMRTreeOperatorTestHelper) testHelper).createDataFlowHelperFactory(secondaryValueProviderFactories,
- btreeComparatorFactories);
+ rtreePolicyType, btreeComparatorFactories);
}
}
\ No newline at end of file
diff --git a/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/lsm/rtree/LSMRTreeSecondaryIndexSearchOperatorTest.java b/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/lsm/rtree/LSMRTreeSecondaryIndexSearchOperatorTest.java
index bb4f61d..0bb8711 100644
--- a/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/lsm/rtree/LSMRTreeSecondaryIndexSearchOperatorTest.java
+++ b/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/lsm/rtree/LSMRTreeSecondaryIndexSearchOperatorTest.java
@@ -19,6 +19,7 @@
import edu.uci.ics.hyracks.api.exceptions.HyracksException;
import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexDataflowHelperFactory;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
import edu.uci.ics.hyracks.test.support.TestStorageManagerComponentHolder;
import edu.uci.ics.hyracks.tests.am.common.ITreeIndexOperatorTestHelper;
import edu.uci.ics.hyracks.tests.am.rtree.RTreeSecondaryIndexSearchOperatorTest;
@@ -30,9 +31,9 @@
@Override
protected IIndexDataflowHelperFactory createDataFlowHelperFactory(
- IPrimitiveValueProviderFactory[] secondaryValueProviderFactories,
+ IPrimitiveValueProviderFactory[] secondaryValueProviderFactories, RTreePolicyType rtreePolicyType,
IBinaryComparatorFactory[] btreeComparatorFactories) {
return ((LSMRTreeOperatorTestHelper) testHelper).createDataFlowHelperFactory(secondaryValueProviderFactories,
- btreeComparatorFactories);
+ rtreePolicyType, btreeComparatorFactories);
}
}
\ No newline at end of file
diff --git a/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/lsm/rtree/LSMRTreeWithAntiMatterTuplesOperatorTestHelper.java b/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/lsm/rtree/LSMRTreeWithAntiMatterTuplesOperatorTestHelper.java
new file mode 100644
index 0000000..bba4e2b
--- /dev/null
+++ b/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/lsm/rtree/LSMRTreeWithAntiMatterTuplesOperatorTestHelper.java
@@ -0,0 +1,45 @@
+/*
+ * 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.am.lsm.rtree;
+
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparatorFactory;
+import edu.uci.ics.hyracks.control.nc.io.IOManager;
+import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexDataflowHelperFactory;
+import edu.uci.ics.hyracks.storage.am.lsm.common.impls.ConstantMergePolicyProvider;
+import edu.uci.ics.hyracks.storage.am.lsm.common.impls.ImmediateFlushPolicyProvider;
+import edu.uci.ics.hyracks.storage.am.lsm.common.impls.SequentialSchedulerProvider;
+import edu.uci.ics.hyracks.storage.am.lsm.rtree.dataflow.LSMRTreeWithAntiMatterTuplesDataflowHelperFactory;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
+import edu.uci.ics.hyracks.tests.am.common.LSMTreeOperatorTestHelper;
+
+public class LSMRTreeWithAntiMatterTuplesOperatorTestHelper extends LSMTreeOperatorTestHelper {
+
+ private static final int MERGE_THRESHOLD = 3;
+
+ public LSMRTreeWithAntiMatterTuplesOperatorTestHelper(IOManager ioManager) {
+ super(ioManager);
+ }
+
+ public IIndexDataflowHelperFactory createDataFlowHelperFactory(
+ IPrimitiveValueProviderFactory[] valueProviderFactories, RTreePolicyType rtreePolicyType,
+ IBinaryComparatorFactory[] btreeComparatorFactories) {
+ return new LSMRTreeWithAntiMatterTuplesDataflowHelperFactory(valueProviderFactories, rtreePolicyType,
+ btreeComparatorFactories, new ImmediateFlushPolicyProvider(SequentialSchedulerProvider.INSTANCE),
+ new ConstantMergePolicyProvider(SequentialSchedulerProvider.INSTANCE, MERGE_THRESHOLD));
+ }
+
+}
diff --git a/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/lsm/rtree/LSMRTreeWithAntiMatterTuplesSecondaryIndexInsertOperatorTest.java b/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/lsm/rtree/LSMRTreeWithAntiMatterTuplesSecondaryIndexInsertOperatorTest.java
new file mode 100644
index 0000000..9fd8895
--- /dev/null
+++ b/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/lsm/rtree/LSMRTreeWithAntiMatterTuplesSecondaryIndexInsertOperatorTest.java
@@ -0,0 +1,39 @@
+/*
+ * 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.am.lsm.rtree;
+
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparatorFactory;
+import edu.uci.ics.hyracks.api.exceptions.HyracksException;
+import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexDataflowHelperFactory;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
+import edu.uci.ics.hyracks.test.support.TestStorageManagerComponentHolder;
+import edu.uci.ics.hyracks.tests.am.common.ITreeIndexOperatorTestHelper;
+import edu.uci.ics.hyracks.tests.am.rtree.RTreeSecondaryIndexInsertOperatorTest;
+
+public class LSMRTreeWithAntiMatterTuplesSecondaryIndexInsertOperatorTest extends RTreeSecondaryIndexInsertOperatorTest {
+ protected ITreeIndexOperatorTestHelper createTestHelper() throws HyracksException {
+ return new LSMRTreeWithAntiMatterTuplesOperatorTestHelper(TestStorageManagerComponentHolder.getIOManager());
+ }
+
+ @Override
+ protected IIndexDataflowHelperFactory createDataFlowHelperFactory(
+ IPrimitiveValueProviderFactory[] secondaryValueProviderFactories, RTreePolicyType rtreePolicyType,
+ IBinaryComparatorFactory[] btreeComparatorFactories) {
+ return ((LSMRTreeWithAntiMatterTuplesOperatorTestHelper) testHelper).createDataFlowHelperFactory(
+ secondaryValueProviderFactories, rtreePolicyType, btreeComparatorFactories);
+ }
+}
\ No newline at end of file
diff --git a/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/lsm/rtree/LSMRTreeWithAntiMatterTuplesSecondaryIndexSearchOperatorTest.java b/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/lsm/rtree/LSMRTreeWithAntiMatterTuplesSecondaryIndexSearchOperatorTest.java
new file mode 100644
index 0000000..0ff6ff0
--- /dev/null
+++ b/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/lsm/rtree/LSMRTreeWithAntiMatterTuplesSecondaryIndexSearchOperatorTest.java
@@ -0,0 +1,39 @@
+/*
+ * 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.am.lsm.rtree;
+
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparatorFactory;
+import edu.uci.ics.hyracks.api.exceptions.HyracksException;
+import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexDataflowHelperFactory;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
+import edu.uci.ics.hyracks.test.support.TestStorageManagerComponentHolder;
+import edu.uci.ics.hyracks.tests.am.common.ITreeIndexOperatorTestHelper;
+import edu.uci.ics.hyracks.tests.am.rtree.RTreeSecondaryIndexSearchOperatorTest;
+
+public class LSMRTreeWithAntiMatterTuplesSecondaryIndexSearchOperatorTest extends RTreeSecondaryIndexSearchOperatorTest {
+ protected ITreeIndexOperatorTestHelper createTestHelper() throws HyracksException {
+ return new LSMRTreeWithAntiMatterTuplesOperatorTestHelper(TestStorageManagerComponentHolder.getIOManager());
+ }
+
+ @Override
+ protected IIndexDataflowHelperFactory createDataFlowHelperFactory(
+ IPrimitiveValueProviderFactory[] secondaryValueProviderFactories, RTreePolicyType rtreePolicyType,
+ IBinaryComparatorFactory[] btreeComparatorFactories) {
+ return ((LSMRTreeWithAntiMatterTuplesOperatorTestHelper) testHelper).createDataFlowHelperFactory(
+ secondaryValueProviderFactories, rtreePolicyType, btreeComparatorFactories);
+ }
+}
\ No newline at end of file
diff --git a/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/rtree/AbstractRTreeOperatorTest.java b/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/rtree/AbstractRTreeOperatorTest.java
index 6aa4da8..10f6a16 100644
--- a/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/rtree/AbstractRTreeOperatorTest.java
+++ b/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/rtree/AbstractRTreeOperatorTest.java
@@ -50,6 +50,7 @@
import edu.uci.ics.hyracks.storage.am.btree.dataflow.BTreeDataflowHelperFactory;
import edu.uci.ics.hyracks.storage.am.btree.dataflow.BTreeSearchOperatorDescriptor;
import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
+import edu.uci.ics.hyracks.storage.am.common.api.TreeIndexException;
import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndex;
import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexArtifactMapProvider;
import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexDataflowHelperFactory;
@@ -59,6 +60,7 @@
import edu.uci.ics.hyracks.storage.am.common.dataflow.TreeIndexInsertUpdateDeleteOperatorDescriptor;
import edu.uci.ics.hyracks.storage.am.common.impls.NoOpOperationCallbackProvider;
import edu.uci.ics.hyracks.storage.am.common.ophelpers.IndexOp;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
import edu.uci.ics.hyracks.storage.am.rtree.util.RTreeUtils;
import edu.uci.ics.hyracks.storage.common.IStorageManagerInterface;
import edu.uci.ics.hyracks.test.support.TestIndexArtifactMapProvider;
@@ -167,13 +169,13 @@
.createPrimitiveValueProviderFactories(secondaryComparatorFactories.length, DoublePointable.FACTORY);
rtreeDataflowHelperFactory = createDataFlowHelperFactory(secondaryValueProviderFactories,
- btreeComparatorFactories);
+ RTreePolicyType.RSTARTREE, btreeComparatorFactories);
}
protected abstract IIndexDataflowHelperFactory createDataFlowHelperFactory(
- IPrimitiveValueProviderFactory[] secondaryValueProviderFactories,
- IBinaryComparatorFactory[] btreeComparatorFactories);
+ IPrimitiveValueProviderFactory[] secondaryValueProviderFactories, RTreePolicyType rtreePolicyType,
+ IBinaryComparatorFactory[] btreeComparatorFactories) throws TreeIndexException;
protected void createPrimaryIndex() throws Exception {
JobSpecification spec = new JobSpecification();
diff --git a/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/rtree/RTreeOperatorTestHelper.java b/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/rtree/RTreeOperatorTestHelper.java
index f59b597..85abcb1 100644
--- a/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/rtree/RTreeOperatorTestHelper.java
+++ b/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/rtree/RTreeOperatorTestHelper.java
@@ -19,13 +19,15 @@
import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexDataflowHelperFactory;
import edu.uci.ics.hyracks.storage.am.rtree.dataflow.RTreeDataflowHelperFactory;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
import edu.uci.ics.hyracks.tests.am.common.TreeOperatorTestHelper;
public class RTreeOperatorTestHelper extends TreeOperatorTestHelper {
public IIndexDataflowHelperFactory createDataFlowHelperFactory(
- IPrimitiveValueProviderFactory[] valueProviderFactories, IBinaryComparatorFactory[] btreeComparatorFactories) {
- return new RTreeDataflowHelperFactory(valueProviderFactories);
+ IPrimitiveValueProviderFactory[] valueProviderFactories, RTreePolicyType rtreePolicyType,
+ IBinaryComparatorFactory[] btreeComparatorFactories) {
+ return new RTreeDataflowHelperFactory(valueProviderFactories, rtreePolicyType);
}
}
diff --git a/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/rtree/RTreeSecondaryIndexInsertOperatorTest.java b/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/rtree/RTreeSecondaryIndexInsertOperatorTest.java
index 84d9686..ab20fff 100644
--- a/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/rtree/RTreeSecondaryIndexInsertOperatorTest.java
+++ b/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/rtree/RTreeSecondaryIndexInsertOperatorTest.java
@@ -36,9 +36,11 @@
import edu.uci.ics.hyracks.dataflow.std.misc.ConstantTupleSourceOperatorDescriptor;
import edu.uci.ics.hyracks.storage.am.btree.dataflow.BTreeSearchOperatorDescriptor;
import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
+import edu.uci.ics.hyracks.storage.am.common.api.TreeIndexException;
import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexDataflowHelperFactory;
import edu.uci.ics.hyracks.storage.am.common.impls.NoOpOperationCallbackProvider;
import edu.uci.ics.hyracks.storage.am.rtree.dataflow.RTreeSearchOperatorDescriptor;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
public class RTreeSecondaryIndexInsertOperatorTest extends AbstractRTreeOperatorTest {
@@ -114,9 +116,9 @@
@Override
protected IIndexDataflowHelperFactory createDataFlowHelperFactory(
- IPrimitiveValueProviderFactory[] secondaryValueProviderFactories,
- IBinaryComparatorFactory[] btreeComparatorFactories) {
- return ((RTreeOperatorTestHelper) testHelper)
- .createDataFlowHelperFactory(secondaryValueProviderFactories, null);
+ IPrimitiveValueProviderFactory[] secondaryValueProviderFactories, RTreePolicyType rtreePolicyType,
+ IBinaryComparatorFactory[] btreeComparatorFactories) throws TreeIndexException {
+ return ((RTreeOperatorTestHelper) testHelper).createDataFlowHelperFactory(secondaryValueProviderFactories,
+ rtreePolicyType, null);
}
}
\ No newline at end of file
diff --git a/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/rtree/RTreeSecondaryIndexScanOperatorTest.java b/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/rtree/RTreeSecondaryIndexScanOperatorTest.java
index c625d9f..55d7367 100644
--- a/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/rtree/RTreeSecondaryIndexScanOperatorTest.java
+++ b/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/rtree/RTreeSecondaryIndexScanOperatorTest.java
@@ -38,6 +38,7 @@
import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexDataflowHelperFactory;
import edu.uci.ics.hyracks.storage.am.common.impls.NoOpOperationCallbackProvider;
import edu.uci.ics.hyracks.storage.am.rtree.dataflow.RTreeSearchOperatorDescriptor;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
public class RTreeSecondaryIndexScanOperatorTest extends AbstractRTreeOperatorTest {
@@ -99,9 +100,9 @@
@Override
protected IIndexDataflowHelperFactory createDataFlowHelperFactory(
- IPrimitiveValueProviderFactory[] secondaryValueProviderFactories,
+ IPrimitiveValueProviderFactory[] secondaryValueProviderFactories, RTreePolicyType rtreePolicyType,
IBinaryComparatorFactory[] btreeComparatorFactories) {
- return ((RTreeOperatorTestHelper) testHelper)
- .createDataFlowHelperFactory(secondaryValueProviderFactories, null);
+ return ((RTreeOperatorTestHelper) testHelper).createDataFlowHelperFactory(secondaryValueProviderFactories,
+ rtreePolicyType, null);
}
}
\ No newline at end of file
diff --git a/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/rtree/RTreeSecondaryIndexSearchOperatorTest.java b/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/rtree/RTreeSecondaryIndexSearchOperatorTest.java
index 21a0993..73a4a2d 100644
--- a/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/rtree/RTreeSecondaryIndexSearchOperatorTest.java
+++ b/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/rtree/RTreeSecondaryIndexSearchOperatorTest.java
@@ -36,9 +36,11 @@
import edu.uci.ics.hyracks.dataflow.std.misc.ConstantTupleSourceOperatorDescriptor;
import edu.uci.ics.hyracks.storage.am.btree.dataflow.BTreeSearchOperatorDescriptor;
import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
+import edu.uci.ics.hyracks.storage.am.common.api.TreeIndexException;
import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexDataflowHelperFactory;
import edu.uci.ics.hyracks.storage.am.common.impls.NoOpOperationCallbackProvider;
import edu.uci.ics.hyracks.storage.am.rtree.dataflow.RTreeSearchOperatorDescriptor;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
public class RTreeSecondaryIndexSearchOperatorTest extends AbstractRTreeOperatorTest {
@@ -113,9 +115,9 @@
@Override
protected IIndexDataflowHelperFactory createDataFlowHelperFactory(
- IPrimitiveValueProviderFactory[] secondaryValueProviderFactories,
- IBinaryComparatorFactory[] btreeComparatorFactories) {
- return ((RTreeOperatorTestHelper) testHelper)
- .createDataFlowHelperFactory(secondaryValueProviderFactories, null);
+ IPrimitiveValueProviderFactory[] secondaryValueProviderFactories, RTreePolicyType rtreePolicyType,
+ IBinaryComparatorFactory[] btreeComparatorFactories) throws TreeIndexException {
+ return ((RTreeOperatorTestHelper) testHelper).createDataFlowHelperFactory(secondaryValueProviderFactories,
+ rtreePolicyType, null);
}
}
\ No newline at end of file
diff --git a/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/rtree/RTreeSecondaryIndexStatsOperatorTest.java b/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/rtree/RTreeSecondaryIndexStatsOperatorTest.java
index 402bf80..3d358be 100644
--- a/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/rtree/RTreeSecondaryIndexStatsOperatorTest.java
+++ b/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/rtree/RTreeSecondaryIndexStatsOperatorTest.java
@@ -31,6 +31,7 @@
import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexDataflowHelperFactory;
import edu.uci.ics.hyracks.storage.am.common.dataflow.TreeIndexStatsOperatorDescriptor;
import edu.uci.ics.hyracks.storage.am.common.impls.NoOpOperationCallbackProvider;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
public class RTreeSecondaryIndexStatsOperatorTest extends AbstractRTreeOperatorTest {
@@ -63,9 +64,9 @@
@Override
protected IIndexDataflowHelperFactory createDataFlowHelperFactory(
- IPrimitiveValueProviderFactory[] secondaryValueProviderFactories,
+ IPrimitiveValueProviderFactory[] secondaryValueProviderFactories, RTreePolicyType rtreePolicyType,
IBinaryComparatorFactory[] btreeComparatorFactories) {
- return ((RTreeOperatorTestHelper) testHelper)
- .createDataFlowHelperFactory(secondaryValueProviderFactories, null);
+ return ((RTreeOperatorTestHelper) testHelper).createDataFlowHelperFactory(secondaryValueProviderFactories,
+ rtreePolicyType, null);
}
}
\ No newline at end of file
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 7a61d09..cfa622d 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
@@ -27,5 +27,4 @@
public void insertSorted(ITupleReference tuple);
public boolean getSmFlag();
public void setSmFlag(boolean smFlag);
- public void setMultiComparator(MultiComparator cmp);
}
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 000cd4d..3026630 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
@@ -16,8 +16,6 @@
package edu.uci.ics.hyracks.storage.am.btree.impls;
import java.util.ArrayList;
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparatorFactory;
import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
@@ -31,21 +29,21 @@
import edu.uci.ics.hyracks.storage.am.btree.exceptions.BTreeNotUpdateableException;
import edu.uci.ics.hyracks.storage.am.btree.frames.BTreeNSMInteriorFrame;
import edu.uci.ics.hyracks.storage.am.common.api.IFreePageManager;
-import edu.uci.ics.hyracks.storage.am.common.api.IIndexBulkLoadContext;
import edu.uci.ics.hyracks.storage.am.common.api.IIndexCursor;
import edu.uci.ics.hyracks.storage.am.common.api.IModificationOperationCallback;
import edu.uci.ics.hyracks.storage.am.common.api.ISearchOperationCallback;
import edu.uci.ics.hyracks.storage.am.common.api.ISearchPredicate;
-import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
+import edu.uci.ics.hyracks.storage.am.common.api.ISplitKey;
import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexAccessor;
import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexCursor;
import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrame;
import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrameFactory;
import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexMetaDataFrame;
-import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexTupleWriter;
import edu.uci.ics.hyracks.storage.am.common.api.IndexType;
import edu.uci.ics.hyracks.storage.am.common.api.TreeIndexException;
import edu.uci.ics.hyracks.storage.am.common.frames.FrameOpSpaceStatus;
+import edu.uci.ics.hyracks.storage.am.common.impls.AbstractTreeIndex;
+import edu.uci.ics.hyracks.storage.am.common.impls.NodeFrontier;
import edu.uci.ics.hyracks.storage.am.common.impls.TreeDiskOrderScanCursor;
import edu.uci.ics.hyracks.storage.am.common.ophelpers.IndexOp;
import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
@@ -54,33 +52,17 @@
import edu.uci.ics.hyracks.storage.common.buffercache.ICachedPage;
import edu.uci.ics.hyracks.storage.common.file.BufferedFileHandle;
-public class BTree implements ITreeIndex {
+public class BTree extends AbstractTreeIndex {
public static final float DEFAULT_FILL_FACTOR = 0.7f;
private final static long RESTART_OP = Long.MIN_VALUE;
private final static int MAX_RESTARTS = 10;
- private final static int rootPage = 1;
-
- private final IFreePageManager freePageManager;
- private final IBufferCache bufferCache;
- private final ITreeIndexFrameFactory interiorFrameFactory;
- private final ITreeIndexFrameFactory leafFrameFactory;
- private final int fieldCount;
- private final IBinaryComparatorFactory[] cmpFactories;
- private final ReadWriteLock treeLatch;
- private int fileId;
public BTree(IBufferCache bufferCache, int fieldCount, IBinaryComparatorFactory[] cmpFactories,
IFreePageManager freePageManager, ITreeIndexFrameFactory interiorFrameFactory,
ITreeIndexFrameFactory leafFrameFactory) {
- this.bufferCache = bufferCache;
- this.fieldCount = fieldCount;
- this.cmpFactories = cmpFactories;
- this.interiorFrameFactory = interiorFrameFactory;
- this.leafFrameFactory = leafFrameFactory;
- this.freePageManager = freePageManager;
- this.treeLatch = new ReentrantReadWriteLock(true);
+ super(bufferCache, fieldCount, cmpFactories, freePageManager, interiorFrameFactory, leafFrameFactory);
}
@Override
@@ -98,18 +80,6 @@
}
}
- @Override
- public void open(int fileId) {
- this.fileId = fileId;
- freePageManager.open(fileId);
- }
-
- @Override
- public void close() {
- fileId = -1;
- freePageManager.close();
- }
-
private void diskOrderScan(ITreeIndexCursor icursor, BTreeOpContext ctx) throws HyracksDataException {
TreeDiskOrderScanCursor cursor = (TreeDiskOrderScanCursor) icursor;
ctx.reset();
@@ -670,6 +640,7 @@
case SEARCH: {
ctx.cursorInitialState.setSearchOperationCallback(ctx.searchCallback);
ctx.cursorInitialState.setPage(node);
+ ctx.cursorInitialState.setPageId(pageId);
ctx.cursor.open(ctx.cursorInitialState, ctx.pred);
break;
}
@@ -712,272 +683,20 @@
}
}
- public class BulkLoadContext implements IIndexBulkLoadContext {
- public final MultiComparator cmp;
- public final int slotSize;
- public final int leafMaxBytes;
- public final int interiorMaxBytes;
- public final BTreeSplitKey splitKey;
- // we maintain a frontier of nodes for each level
- private final ArrayList<NodeFrontier> nodeFrontiers = new ArrayList<NodeFrontier>();
- private final IBTreeLeafFrame leafFrame;
- private final IBTreeInteriorFrame interiorFrame;
- private final ITreeIndexMetaDataFrame metaFrame;
- private final ITreeIndexTupleWriter tupleWriter;
-
- public BulkLoadContext(float fillFactor, IBTreeLeafFrame leafFrame, IBTreeInteriorFrame interiorFrame,
- ITreeIndexMetaDataFrame metaFrame, IBinaryComparatorFactory[] cmpFactories) throws HyracksDataException {
- this.cmp = MultiComparator.create(cmpFactories);
-
- leafFrame.setMultiComparator(cmp);
- interiorFrame.setMultiComparator(cmp);
-
- splitKey = new BTreeSplitKey(leafFrame.getTupleWriter().createTupleReference());
- tupleWriter = leafFrame.getTupleWriter();
-
- NodeFrontier leafFrontier = new NodeFrontier(leafFrame.createTupleReference());
- leafFrontier.pageId = freePageManager.getFreePage(metaFrame);
- leafFrontier.page = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, leafFrontier.pageId), true);
- leafFrontier.page.acquireWriteLatch();
-
- interiorFrame.setPage(leafFrontier.page);
- interiorFrame.initBuffer((byte) 0);
- interiorMaxBytes = (int) ((float) interiorFrame.getBuffer().capacity() * fillFactor);
-
- leafFrame.setPage(leafFrontier.page);
- leafFrame.initBuffer((byte) 0);
- leafMaxBytes = (int) ((float) leafFrame.getBuffer().capacity() * fillFactor);
-
- slotSize = leafFrame.getSlotSize();
-
- this.leafFrame = leafFrame;
- this.interiorFrame = interiorFrame;
- this.metaFrame = metaFrame;
-
- nodeFrontiers.add(leafFrontier);
- }
-
- private void addLevel() throws HyracksDataException {
- NodeFrontier frontier = new NodeFrontier(tupleWriter.createTupleReference());
- frontier.pageId = freePageManager.getFreePage(metaFrame);
- frontier.page = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, frontier.pageId), true);
- frontier.page.acquireWriteLatch();
- frontier.lastTuple.setFieldCount(cmp.getKeyFieldCount());
- interiorFrame.setPage(frontier.page);
- interiorFrame.initBuffer((byte) nodeFrontiers.size());
- nodeFrontiers.add(frontier);
- }
- }
-
- private void propagateBulk(BulkLoadContext ctx, int level) throws HyracksDataException {
-
- if (ctx.splitKey.getBuffer() == null)
- return;
-
- if (level >= ctx.nodeFrontiers.size())
- ctx.addLevel();
-
- NodeFrontier frontier = ctx.nodeFrontiers.get(level);
- ctx.interiorFrame.setPage(frontier.page);
-
- ITupleReference tuple = ctx.splitKey.getTuple();
- int spaceNeeded = ctx.tupleWriter.bytesRequired(tuple, 0, ctx.cmp.getKeyFieldCount()) + ctx.slotSize + 4;
- int spaceUsed = ctx.interiorFrame.getBuffer().capacity() - ctx.interiorFrame.getTotalFreeSpace();
- if (spaceUsed + spaceNeeded > ctx.interiorMaxBytes) {
-
- BTreeSplitKey copyKey = ctx.splitKey.duplicate(ctx.leafFrame.getTupleWriter().createTupleReference());
- tuple = copyKey.getTuple();
-
- frontier.lastTuple.resetByTupleIndex(ctx.interiorFrame, ctx.interiorFrame.getTupleCount() - 1);
- int splitKeySize = ctx.tupleWriter.bytesRequired(frontier.lastTuple, 0, ctx.cmp.getKeyFieldCount());
- ctx.splitKey.initData(splitKeySize);
- ctx.tupleWriter.writeTupleFields(frontier.lastTuple, 0, ctx.cmp.getKeyFieldCount(), ctx.splitKey
- .getBuffer().array(), 0);
- ctx.splitKey.getTuple().resetByTupleOffset(ctx.splitKey.getBuffer(), 0);
- ctx.splitKey.setLeftPage(frontier.pageId);
-
- ctx.interiorFrame.deleteGreatest();
-
- frontier.page.releaseWriteLatch();
- bufferCache.unpin(frontier.page);
- frontier.pageId = freePageManager.getFreePage(ctx.metaFrame);
-
- ctx.splitKey.setRightPage(frontier.pageId);
- propagateBulk(ctx, level + 1);
-
- frontier.page = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, frontier.pageId), true);
- frontier.page.acquireWriteLatch();
- ctx.interiorFrame.setPage(frontier.page);
- ctx.interiorFrame.initBuffer((byte) level);
- }
- ctx.interiorFrame.insertSorted(tuple);
- }
-
- // assumes btree has been created and opened
- @Override
- public IIndexBulkLoadContext beginBulkLoad(float fillFactor) throws TreeIndexException, HyracksDataException {
- IBTreeLeafFrame leafFrame = (IBTreeLeafFrame) leafFrameFactory.createFrame();
- if (!isEmptyTree(leafFrame)) {
- throw new BTreeException("Trying to Bulk-load a non-empty BTree.");
- }
-
- BulkLoadContext ctx = new BulkLoadContext(fillFactor, leafFrame,
- (IBTreeInteriorFrame) interiorFrameFactory.createFrame(), freePageManager.getMetaDataFrameFactory()
- .createFrame(), cmpFactories);
- ctx.splitKey.getTuple().setFieldCount(ctx.cmp.getKeyFieldCount());
- return ctx;
- }
-
- @Override
- public void bulkLoadAddTuple(ITupleReference tuple, IIndexBulkLoadContext ictx) throws HyracksDataException {
- BulkLoadContext ctx = (BulkLoadContext) ictx;
- NodeFrontier leafFrontier = ctx.nodeFrontiers.get(0);
- IBTreeLeafFrame leafFrame = ctx.leafFrame;
-
- int spaceNeeded = ctx.tupleWriter.bytesRequired(tuple) + ctx.slotSize;
- int spaceUsed = leafFrame.getBuffer().capacity() - leafFrame.getTotalFreeSpace();
-
- // try to free space by compression
- if (spaceUsed + spaceNeeded > ctx.leafMaxBytes) {
- leafFrame.compress();
- spaceUsed = leafFrame.getBuffer().capacity() - leafFrame.getTotalFreeSpace();
- }
-
- if (spaceUsed + spaceNeeded > ctx.leafMaxBytes) {
- leafFrontier.lastTuple.resetByTupleIndex(leafFrame, leafFrame.getTupleCount() - 1);
- int splitKeySize = ctx.tupleWriter.bytesRequired(leafFrontier.lastTuple, 0, ctx.cmp.getKeyFieldCount());
- ctx.splitKey.initData(splitKeySize);
- ctx.tupleWriter.writeTupleFields(leafFrontier.lastTuple, 0, ctx.cmp.getKeyFieldCount(), ctx.splitKey
- .getBuffer().array(), 0);
- ctx.splitKey.getTuple().resetByTupleOffset(ctx.splitKey.getBuffer(), 0);
- ctx.splitKey.setLeftPage(leafFrontier.pageId);
- leafFrontier.pageId = freePageManager.getFreePage(ctx.metaFrame);
-
- leafFrame.setNextLeaf(leafFrontier.pageId);
- leafFrontier.page.releaseWriteLatch();
- bufferCache.unpin(leafFrontier.page);
-
- ctx.splitKey.setRightPage(leafFrontier.pageId);
- propagateBulk(ctx, 1);
-
- leafFrontier.page = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, leafFrontier.pageId), true);
- leafFrontier.page.acquireWriteLatch();
- leafFrame.setPage(leafFrontier.page);
- leafFrame.initBuffer((byte) 0);
- }
-
- leafFrame.setPage(leafFrontier.page);
- leafFrame.insertSorted(tuple);
- }
-
- @Override
- public void endBulkLoad(IIndexBulkLoadContext ictx) throws HyracksDataException {
- // copy root
- BulkLoadContext ctx = (BulkLoadContext) ictx;
- ICachedPage rootNode = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, rootPage), true);
- rootNode.acquireWriteLatch();
- NodeFrontier lastNodeFrontier = ctx.nodeFrontiers.get(ctx.nodeFrontiers.size() - 1);
- IBTreeInteriorFrame interiorFrame = ctx.interiorFrame;
- try {
- ICachedPage toBeRoot = lastNodeFrontier.page;
- System.arraycopy(toBeRoot.getBuffer().array(), 0, rootNode.getBuffer().array(), 0, toBeRoot.getBuffer()
- .capacity());
- } finally {
- rootNode.releaseWriteLatch();
- bufferCache.unpin(rootNode);
-
- // register old root as free page
- freePageManager.addFreePage(ctx.metaFrame, lastNodeFrontier.pageId);
-
- // make old root a free page
- interiorFrame.setPage(lastNodeFrontier.page);
- interiorFrame.initBuffer(freePageManager.getFreePageLevelIndicator());
-
- // cleanup
- for (int i = 0; i < ctx.nodeFrontiers.size(); i++) {
- ctx.nodeFrontiers.get(i).page.releaseWriteLatch();
- bufferCache.unpin(ctx.nodeFrontiers.get(i).page);
- }
- }
- }
-
private BTreeOpContext createOpContext(IModificationOperationCallback modificationCallback,
ISearchOperationCallback searchCallback) {
return new BTreeOpContext(leafFrameFactory, interiorFrameFactory, freePageManager.getMetaDataFrameFactory()
.createFrame(), cmpFactories, modificationCallback, searchCallback);
}
- public ITreeIndexFrameFactory getInteriorFrameFactory() {
- return interiorFrameFactory;
- }
-
- public ITreeIndexFrameFactory getLeafFrameFactory() {
- return leafFrameFactory;
- }
-
- public IBinaryComparatorFactory[] getComparatorFactories() {
- return cmpFactories;
- }
-
- public IFreePageManager getFreePageManager() {
- return freePageManager;
- }
-
- public int getRootPageId() {
- return rootPage;
- }
-
- @Override
- public int getFieldCount() {
- return fieldCount;
- }
-
@Override
public IndexType getIndexType() {
return IndexType.BTREE;
}
- @Override
- public int getFileId() {
- return fileId;
- }
-
- @Override
- public IBufferCache getBufferCache() {
- return bufferCache;
- }
-
- public byte getTreeHeight(IBTreeLeafFrame leafFrame) throws HyracksDataException {
- ICachedPage rootNode = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, rootPage), false);
- rootNode.acquireReadLatch();
- try {
- leafFrame.setPage(rootNode);
- return leafFrame.getLevel();
- } finally {
- rootNode.releaseReadLatch();
- bufferCache.unpin(rootNode);
- }
- }
-
- public boolean isEmptyTree(IBTreeLeafFrame leafFrame) throws HyracksDataException {
- ICachedPage rootNode = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, rootPage), false);
- rootNode.acquireReadLatch();
- try {
- leafFrame.setPage(rootNode);
- if (leafFrame.getLevel() == 0 && leafFrame.getTupleCount() == 0) {
- return true;
- } else {
- return false;
- }
- } finally {
- rootNode.releaseReadLatch();
- bufferCache.unpin(rootNode);
- }
- }
-
- @SuppressWarnings("rawtypes")
- public String printTree(IBTreeLeafFrame leafFrame, IBTreeInteriorFrame interiorFrame,
- ISerializerDeserializer[] keySerdes) throws Exception {
+ @SuppressWarnings("rawtypes")
+ public String printTree(IBTreeLeafFrame leafFrame, IBTreeInteriorFrame interiorFrame, ISerializerDeserializer[] keySerdes)
+ throws Exception {
MultiComparator cmp = MultiComparator.create(cmpFactories);
byte treeHeight = getTreeHeight(leafFrame);
StringBuilder strBuilder = new StringBuilder();
@@ -1104,4 +823,109 @@
return ctx;
}
}
+
+ @Override
+ public AbstractTreeIndexBulkLoader createBulkLoader(float fillFactor) throws TreeIndexException {
+ try {
+ return new BTreeBulkLoader(fillFactor);
+ } catch (HyracksDataException e) {
+ throw new TreeIndexException(e);
+ }
+ }
+
+ public class BTreeBulkLoader extends AbstractTreeIndex.AbstractTreeIndexBulkLoader {
+ protected final ISplitKey splitKey;
+
+ public BTreeBulkLoader(float fillFactor) throws TreeIndexException,
+ HyracksDataException {
+ super(fillFactor);
+ splitKey = new BTreeSplitKey(leafFrame.getTupleWriter().createTupleReference());
+ splitKey.getTuple().setFieldCount(cmp.getKeyFieldCount());
+ }
+
+ @Override
+ public void add(ITupleReference tuple) throws HyracksDataException {
+ NodeFrontier leafFrontier = nodeFrontiers.get(0);
+
+ int spaceNeeded = tupleWriter.bytesRequired(tuple) + slotSize;
+ int spaceUsed = leafFrame.getBuffer().capacity() - leafFrame.getTotalFreeSpace();
+
+ // try to free space by compression
+ if (spaceUsed + spaceNeeded > leafMaxBytes) {
+ leafFrame.compress();
+ spaceUsed = leafFrame.getBuffer().capacity() - leafFrame.getTotalFreeSpace();
+ }
+
+ if (spaceUsed + spaceNeeded > leafMaxBytes) {
+ leafFrontier.lastTuple.resetByTupleIndex(leafFrame, leafFrame.getTupleCount() - 1);
+ int splitKeySize = tupleWriter.bytesRequired(leafFrontier.lastTuple, 0, cmp.getKeyFieldCount());
+ splitKey.initData(splitKeySize);
+ tupleWriter.writeTupleFields(leafFrontier.lastTuple, 0, cmp.getKeyFieldCount(),
+ splitKey.getBuffer().array(), 0);
+ splitKey.getTuple().resetByTupleOffset(splitKey.getBuffer(), 0);
+ splitKey.setLeftPage(leafFrontier.pageId);
+ leafFrontier.pageId = freePageManager.getFreePage(metaFrame);
+
+ ((IBTreeLeafFrame) leafFrame).setNextLeaf(leafFrontier.pageId);
+ leafFrontier.page.releaseWriteLatch();
+ bufferCache.unpin(leafFrontier.page);
+
+ splitKey.setRightPage(leafFrontier.pageId);
+ propagateBulk(1);
+
+ leafFrontier.page = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, leafFrontier.pageId),
+ true);
+ leafFrontier.page.acquireWriteLatch();
+ leafFrame.setPage(leafFrontier.page);
+ leafFrame.initBuffer((byte) 0);
+ }
+
+ leafFrame.setPage(leafFrontier.page);
+ ((IBTreeLeafFrame) leafFrame).insertSorted(tuple);
+ }
+
+ protected void propagateBulk(int level) throws HyracksDataException {
+ if (splitKey.getBuffer() == null)
+ return;
+
+ if (level >= nodeFrontiers.size())
+ addLevel();
+
+ NodeFrontier frontier = nodeFrontiers.get(level);
+ interiorFrame.setPage(frontier.page);
+
+ ITupleReference tuple = splitKey.getTuple();
+ int spaceNeeded = tupleWriter.bytesRequired(tuple, 0, cmp.getKeyFieldCount()) + slotSize + 4;
+ int spaceUsed = interiorFrame.getBuffer().capacity() - interiorFrame.getTotalFreeSpace();
+ if (spaceUsed + spaceNeeded > interiorMaxBytes) {
+
+ ISplitKey copyKey = splitKey.duplicate(leafFrame.getTupleWriter().createTupleReference());
+ tuple = copyKey.getTuple();
+
+ frontier.lastTuple.resetByTupleIndex(interiorFrame, interiorFrame.getTupleCount() - 1);
+ int splitKeySize = tupleWriter.bytesRequired(frontier.lastTuple, 0, cmp.getKeyFieldCount());
+ splitKey.initData(splitKeySize);
+ tupleWriter
+ .writeTupleFields(frontier.lastTuple, 0, cmp.getKeyFieldCount(), splitKey.getBuffer().array(), 0);
+ splitKey.getTuple().resetByTupleOffset(splitKey.getBuffer(), 0);
+ splitKey.setLeftPage(frontier.pageId);
+
+ ((IBTreeInteriorFrame) interiorFrame).deleteGreatest();
+
+ frontier.page.releaseWriteLatch();
+ bufferCache.unpin(frontier.page);
+ frontier.pageId = freePageManager.getFreePage(metaFrame);
+
+ splitKey.setRightPage(frontier.pageId);
+ propagateBulk(level + 1);
+
+ frontier.page = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, frontier.pageId), true);
+ frontier.page.acquireWriteLatch();
+ interiorFrame.setPage(frontier.page);
+ interiorFrame.initBuffer((byte) level);
+ }
+ ((IBTreeInteriorFrame) interiorFrame).insertSorted(tuple);
+ }
+
+ }
}
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/BTreeCursorInitialState.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/BTreeCursorInitialState.java
index c7f4c0c..d88600a 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/BTreeCursorInitialState.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/BTreeCursorInitialState.java
@@ -7,6 +7,9 @@
public class BTreeCursorInitialState implements ICursorInitialState {
private ICachedPage page;
+
+ // This is only used by the LSM-RTree
+ private int pageId;
private ISearchOperationCallback searchCallback;
@@ -22,6 +25,14 @@
this.page = page;
}
+ public int getPageId() {
+ return pageId;
+ }
+
+ public void setPageId(int pageId) {
+ this.pageId = pageId;
+ }
+
@Override
public ISearchOperationCallback getSearchOperationCallback() {
return searchCallback;
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/BTreeRangeSearchCursor.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/BTreeRangeSearchCursor.java
index 8d475e3..968b9bb 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/BTreeRangeSearchCursor.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/BTreeRangeSearchCursor.java
@@ -56,6 +56,11 @@
private ITupleReference lowKey;
private ITupleReference highKey;
+ // This is only used by the LSM-RTree
+ private int pageId = -1;
+ // TODO(ALEX): How this is different tupleIndex? Why do we need it?
+ private int currentTupleIndex = 0;
+
private ISearchOperationCallback searchCallback;
public BTreeRangeSearchCursor(IBTreeLeafFrame frame, boolean exclusiveLatchNodes) {
@@ -88,6 +93,14 @@
return page;
}
+ public int getTupleOffset() {
+ return frame.getTupleOffset(currentTupleIndex);
+ }
+
+ public int getPageId() {
+ return pageId;
+ }
+
private void fetchNextLeafPage(int nextLeafPage) throws HyracksDataException {
do {
ICachedPage nextLeaf = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, nextLeafPage), false);
@@ -101,6 +114,10 @@
bufferCache.unpin(page);
page = nextLeaf;
frame.setPage(page);
+
+ // This is only needed for the LSMRTree flush operation
+ pageId = nextLeafPage;
+
nextLeafPage = frame.getNextLeaf();
} while (frame.getTupleCount() == 0 && nextLeafPage > 0);
}
@@ -122,6 +139,10 @@
}
frameTuple.resetByTupleIndex(frame, tupleIndex);
+
+ // This is only needed for the LSMRTree flush operation
+ currentTupleIndex = tupleIndex;
+
if (highKey == null || tupleIndex <= stopTupleIndex) {
return true;
} else {
@@ -179,6 +200,8 @@
page = initialState.getPage();
frame.setPage(page);
+ pageId = ((BTreeCursorInitialState) initialState).getPageId();
+
pred = (RangePredicate) searchPred;
lowKeyCmp = pred.getLowKeyComparator();
highKeyCmp = pred.getHighKeyComparator();
diff --git a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/IIndexCursor.java b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/IIndexCursor.java
index d29fd73..0a53cf6 100644
--- a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/IIndexCursor.java
+++ b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/IIndexCursor.java
@@ -28,7 +28,7 @@
public void close() throws HyracksDataException;
- public void reset();
+ public void reset() throws HyracksDataException;
public ITupleReference getTuple();
}
diff --git a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/ITreeIndex.java b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/ITreeIndex.java
index 52626cf..2c96a22 100644
--- a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/ITreeIndex.java
+++ b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/ITreeIndex.java
@@ -59,4 +59,11 @@
* @return Comparator factories.
*/
public IBinaryComparatorFactory[] getComparatorFactories();
+
+ /**
+ * @param fillFactor
+ * @throws TreeIndexException if the user tries to instantiate a second bulk
+ * loader
+ */
+ public ITreeIndexBulkLoader createBulkLoader(float fillFactor) throws TreeIndexException;
}
diff --git a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/ITreeIndexBulkLoader.java b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/ITreeIndexBulkLoader.java
new file mode 100644
index 0000000..3e2da28
--- /dev/null
+++ b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/ITreeIndexBulkLoader.java
@@ -0,0 +1,27 @@
+package edu.uci.ics.hyracks.storage.am.common.api;
+
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
+
+public interface ITreeIndexBulkLoader {
+ /**
+ * Append a tuple to the index in the context of a bulk load.
+ *
+ * @param tuple
+ * Tuple to be inserted.
+ * @throws HyracksDataException
+ * If the BufferCache throws while un/pinning or un/latching.
+ */
+ public void add(ITupleReference tuple)
+ throws HyracksDataException;
+
+ /**
+ * Finalize the bulk loading operation in the given context.
+ *
+ * @throws HyracksDataException
+ * If the BufferCache throws while un/pinning or un/latching.
+ */
+ public void end()
+ throws HyracksDataException;
+
+}
diff --git a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/ITreeIndexFrame.java b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/ITreeIndexFrame.java
index f11ee82..bfec3a9 100644
--- a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/ITreeIndexFrame.java
+++ b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/ITreeIndexFrame.java
@@ -20,6 +20,7 @@
import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
import edu.uci.ics.hyracks.storage.am.common.frames.FrameOpSpaceStatus;
+import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
import edu.uci.ics.hyracks.storage.common.buffercache.ICachedPage;
public interface ITreeIndexFrame {
@@ -89,4 +90,7 @@
public int getPageHeaderSize();
public ITreeIndexTupleReference createTupleReference();
+
+ public void setMultiComparator(MultiComparator cmp);
+
}
diff --git a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/datagen/DataGenUtils.java b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/datagen/DataGenUtils.java
index fdbaa3e..d4696df 100644
--- a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/datagen/DataGenUtils.java
+++ b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/datagen/DataGenUtils.java
@@ -32,7 +32,6 @@
} else if (serde instanceof UTF8StringSerializerDeserializer) {
return new StringFieldValueGenerator(20, rnd);
}
- System.out.println("NULL");
return null;
}
diff --git a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/frames/TreeIndexNSMFrame.java b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/frames/TreeIndexNSMFrame.java
index e2e28fd..31ce573 100644
--- a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/frames/TreeIndexNSMFrame.java
+++ b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/frames/TreeIndexNSMFrame.java
@@ -111,7 +111,7 @@
resetSpaceParams();
int tupleCount = buf.getInt(tupleCountOff);
int freeSpace = buf.getInt(freeSpaceOff);
- // Sort the slots by the tuple offset they point to.
+ // Sort the slots by the tuple offset they point to.
ArrayList<SlotOffTupleOff> sortedTupleOffs = new ArrayList<SlotOffTupleOff>();
sortedTupleOffs.ensureCapacity(tupleCount);
for (int i = 0; i < tupleCount; i++) {
@@ -121,7 +121,7 @@
}
Collections.sort(sortedTupleOffs);
// Iterate over the sorted slots, and move their corresponding tuples to
- // the left, reclaiming free space.
+ // the left, reclaiming free space.
for (int i = 0; i < sortedTupleOffs.size(); i++) {
int tupleOff = sortedTupleOffs.get(i).tupleOff;
frameTuple.resetByTupleOffset(buf, tupleOff);
@@ -132,7 +132,7 @@
slotManager.setSlot(sortedTupleOffs.get(i).slotOff, freeSpace);
freeSpace += tupleLength;
}
- // Update contiguous free space pointer and total free space indicator.
+ // Update contiguous free space pointer and total free space indicator.
buf.putInt(freeSpaceOff, freeSpace);
buf.putInt(totalFreeSpaceOff, buf.capacity() - freeSpace - tupleCount * slotManager.getSlotSize());
return false;
@@ -159,7 +159,7 @@
public FrameOpSpaceStatus hasSpaceInsert(ITupleReference tuple) {
int bytesRequired = tupleWriter.bytesRequired(tuple);
// Enough space in the contiguous space region?
- if (bytesRequired + slotManager.getSlotSize() <= buf.capacity() - buf.getInt(freeSpaceOff)
+ if (bytesRequired + slotManager.getSlotSize() <= buf.capacity() - buf.getInt(freeSpaceOff)
- (buf.getInt(tupleCountOff) * slotManager.getSlotSize())) {
return FrameOpSpaceStatus.SUFFICIENT_CONTIGUOUS_SPACE;
}
@@ -172,23 +172,24 @@
@Override
public FrameOpSpaceStatus hasSpaceUpdate(ITupleReference newTuple, int oldTupleIndex) {
- frameTuple.resetByTupleIndex(this, oldTupleIndex);
- int oldTupleBytes = frameTuple.getTupleSize();
- int newTupleBytes = tupleWriter.bytesRequired(newTuple);
- int additionalBytesRequired = newTupleBytes - oldTupleBytes;
- // Enough space for an in-place update?
- if (additionalBytesRequired <= 0) {
- return FrameOpSpaceStatus.SUFFICIENT_INPLACE_SPACE;
- }
- // Enough space if we delete the old tuple and insert the new one without compaction?
- if (newTupleBytes <= buf.capacity() - buf.getInt(freeSpaceOff)
+ frameTuple.resetByTupleIndex(this, oldTupleIndex);
+ int oldTupleBytes = frameTuple.getTupleSize();
+ int newTupleBytes = tupleWriter.bytesRequired(newTuple);
+ int additionalBytesRequired = newTupleBytes - oldTupleBytes;
+ // Enough space for an in-place update?
+ if (additionalBytesRequired <= 0) {
+ return FrameOpSpaceStatus.SUFFICIENT_INPLACE_SPACE;
+ }
+ // Enough space if we delete the old tuple and insert the new one
+ // without compaction?
+ if (newTupleBytes <= buf.capacity() - buf.getInt(freeSpaceOff)
- (buf.getInt(tupleCountOff) * slotManager.getSlotSize())) {
- return FrameOpSpaceStatus.SUFFICIENT_CONTIGUOUS_SPACE;
- }
- // Enough space if we delete the old tuple and compact?
- if (additionalBytesRequired <= buf.getInt(totalFreeSpaceOff)) {
- return FrameOpSpaceStatus.SUFFICIENT_SPACE;
- }
+ return FrameOpSpaceStatus.SUFFICIENT_CONTIGUOUS_SPACE;
+ }
+ // Enough space if we delete the old tuple and compact?
+ if (additionalBytesRequired <= buf.getInt(totalFreeSpaceOff)) {
+ return FrameOpSpaceStatus.SUFFICIENT_SPACE;
+ }
return FrameOpSpaceStatus.INSUFFICIENT_SPACE;
}
@@ -208,35 +209,36 @@
@Override
public void update(ITupleReference newTuple, int oldTupleIndex, boolean inPlace) {
- frameTuple.resetByTupleIndex(this, oldTupleIndex);
- int oldTupleBytes = frameTuple.getTupleSize();
- int slotOff = slotManager.getSlotOff(oldTupleIndex);
- int bytesWritten = 0;
- if (inPlace) {
- // Overwrite the old tuple in place.
- bytesWritten = tupleWriter.writeTuple(newTuple, buf.array(), buf.getInt(slotOff));
- } else {
- // Insert the new tuple at the end of the free space, and change the slot value (effectively "deleting" the old tuple).
- int newTupleOff = buf.getInt(freeSpaceOff);
- bytesWritten = tupleWriter.writeTuple(newTuple, buf.array(), newTupleOff);
- // Update slot value.
- buf.putInt(slotOff, newTupleOff);
- // Update contiguous free space pointer.
- buf.putInt(freeSpaceOff, newTupleOff + bytesWritten);
- }
- buf.putInt(totalFreeSpaceOff, buf.getInt(totalFreeSpaceOff) + oldTupleBytes - bytesWritten);
+ frameTuple.resetByTupleIndex(this, oldTupleIndex);
+ int oldTupleBytes = frameTuple.getTupleSize();
+ int slotOff = slotManager.getSlotOff(oldTupleIndex);
+ int bytesWritten = 0;
+ if (inPlace) {
+ // Overwrite the old tuple in place.
+ bytesWritten = tupleWriter.writeTuple(newTuple, buf.array(), buf.getInt(slotOff));
+ } else {
+ // Insert the new tuple at the end of the free space, and change the
+ // slot value (effectively "deleting" the old tuple).
+ int newTupleOff = buf.getInt(freeSpaceOff);
+ bytesWritten = tupleWriter.writeTuple(newTuple, buf.array(), newTupleOff);
+ // Update slot value.
+ buf.putInt(slotOff, newTupleOff);
+ // Update contiguous free space pointer.
+ buf.putInt(freeSpaceOff, newTupleOff + bytesWritten);
+ }
+ buf.putInt(totalFreeSpaceOff, buf.getInt(totalFreeSpaceOff) + oldTupleBytes - bytesWritten);
}
@Override
public String printHeader() {
- StringBuilder strBuilder = new StringBuilder();
- strBuilder.append("pageLsnOff: " + pageLsnOff + "\n");
- strBuilder.append("tupleCountOff: " + tupleCountOff + "\n");
- strBuilder.append("freeSpaceOff: " + freeSpaceOff + "\n");
- strBuilder.append("totalFreeSpaceOff: " + totalFreeSpaceOff + "\n");
- strBuilder.append("levelOff: " + levelOff + "\n");
- strBuilder.append("smFlagOff: " + smFlagOff + "\n");
- return strBuilder.toString();
+ StringBuilder strBuilder = new StringBuilder();
+ strBuilder.append("pageLsnOff: " + pageLsnOff + "\n");
+ strBuilder.append("tupleCountOff: " + tupleCountOff + "\n");
+ strBuilder.append("freeSpaceOff: " + freeSpaceOff + "\n");
+ strBuilder.append("totalFreeSpaceOff: " + totalFreeSpaceOff + "\n");
+ strBuilder.append("levelOff: " + levelOff + "\n");
+ strBuilder.append("smFlagOff: " + smFlagOff + "\n");
+ return strBuilder.toString();
}
@Override
@@ -282,14 +284,13 @@
public ITreeIndexTupleWriter getTupleWriter() {
return tupleWriter;
}
-
+
@Override
public ITreeIndexTupleReference createTupleReference() {
- return tupleWriter.createTupleReference();
+ return tupleWriter.createTupleReference();
}
-
- public int getFreeContiguousSpace() {
- return buf.capacity() - getFreeSpaceOff()
- - (getTupleCount() * slotManager.getSlotSize());
- }
+
+ public int getFreeContiguousSpace() {
+ return buf.capacity() - getFreeSpaceOff() - (getTupleCount() * slotManager.getSlotSize());
+ }
}
diff --git a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/impls/AbstractTreeIndex.java b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/impls/AbstractTreeIndex.java
new file mode 100644
index 0000000..bf563b1
--- /dev/null
+++ b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/impls/AbstractTreeIndex.java
@@ -0,0 +1,264 @@
+package edu.uci.ics.hyracks.storage.am.common.impls;
+
+import java.util.ArrayList;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparatorFactory;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
+import edu.uci.ics.hyracks.storage.am.common.api.IFreePageManager;
+import edu.uci.ics.hyracks.storage.am.common.api.IIndexBulkLoadContext;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexAccessor;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexBulkLoader;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrame;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrameFactory;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexMetaDataFrame;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexTupleWriter;
+import edu.uci.ics.hyracks.storage.am.common.api.IndexException;
+import edu.uci.ics.hyracks.storage.am.common.api.TreeIndexException;
+import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
+import edu.uci.ics.hyracks.storage.common.buffercache.IBufferCache;
+import edu.uci.ics.hyracks.storage.common.buffercache.ICachedPage;
+import edu.uci.ics.hyracks.storage.common.file.BufferedFileHandle;
+
+public abstract class AbstractTreeIndex implements ITreeIndex {
+
+ protected final static int rootPage = 1;
+
+ protected final ITreeIndexFrameFactory interiorFrameFactory;
+ protected final ITreeIndexFrameFactory leafFrameFactory;
+ protected final IFreePageManager freePageManager;
+ protected final IBufferCache bufferCache;
+ protected final int fieldCount;
+ protected final IBinaryComparatorFactory[] cmpFactories;
+ protected final ReadWriteLock treeLatch;
+ protected int fileId;
+
+ public AbstractTreeIndex(IBufferCache bufferCache, int fieldCount, IBinaryComparatorFactory[] cmpFactories, IFreePageManager freePageManager,
+ ITreeIndexFrameFactory interiorFrameFactory, ITreeIndexFrameFactory leafFrameFactory) {
+ this.bufferCache = bufferCache;
+ this.fieldCount = fieldCount;
+ this.cmpFactories = cmpFactories;
+ this.freePageManager = freePageManager;
+ this.treeLatch = new ReentrantReadWriteLock(true);
+ this.interiorFrameFactory = interiorFrameFactory;
+ this.leafFrameFactory = leafFrameFactory;
+ }
+
+ public boolean isEmptyTree(ITreeIndexFrame leafFrame) throws HyracksDataException {
+ ICachedPage rootNode = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, rootPage), false);
+ rootNode.acquireReadLatch();
+ try {
+ leafFrame.setPage(rootNode);
+ if (leafFrame.getLevel() == 0 && leafFrame.getTupleCount() == 0) {
+ return true;
+ } else {
+ return false;
+ }
+ } finally {
+ rootNode.releaseReadLatch();
+ bufferCache.unpin(rootNode);
+ }
+ }
+
+ public void open(int fileId) {
+ this.fileId = fileId;
+ freePageManager.open(fileId);
+ }
+
+ public void close() {
+ fileId = -1;
+ freePageManager.close();
+ }
+
+ public int getFileId() {
+ return fileId;
+ }
+
+ public IBufferCache getBufferCache() {
+ return bufferCache;
+ }
+
+ public byte getTreeHeight(ITreeIndexFrame leafFrame) throws HyracksDataException {
+ ICachedPage rootNode = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, rootPage), false);
+ rootNode.acquireReadLatch();
+ try {
+ leafFrame.setPage(rootNode);
+ return leafFrame.getLevel();
+ } finally {
+ rootNode.releaseReadLatch();
+ bufferCache.unpin(rootNode);
+ }
+ }
+
+ public ITreeIndexFrameFactory getInteriorFrameFactory() {
+ return interiorFrameFactory;
+ }
+
+ public ITreeIndexFrameFactory getLeafFrameFactory() {
+ return leafFrameFactory;
+ }
+
+ public IBinaryComparatorFactory[] getComparatorFactories() {
+ return cmpFactories;
+ }
+
+ public IFreePageManager getFreePageManager() {
+ return freePageManager;
+ }
+
+ public int getRootPageId() {
+ return rootPage;
+ }
+
+ public int getFieldCount() {
+ return fieldCount;
+ }
+
+ public abstract AbstractTreeIndexBulkLoader createBulkLoader(float fillFactor) throws TreeIndexException;
+
+ public TreeIndexInsertBulkLoader createInsertBulkLoader() throws TreeIndexException {
+ final Logger LOGGER = Logger.getLogger(TreeIndexInsertBulkLoader.class.getName());
+
+ if (LOGGER.isLoggable(Level.INFO)) {
+ LOGGER.info("Using insert bulkload. This might negatively impact your performance.");
+ }
+
+ return new TreeIndexInsertBulkLoader();
+ }
+
+
+ public abstract class AbstractTreeIndexBulkLoader implements ITreeIndexBulkLoader {
+ protected final MultiComparator cmp;
+ protected final int slotSize;
+ protected final int leafMaxBytes;
+ protected final int interiorMaxBytes;
+ // we maintain a frontier of nodes for each level
+ protected final ArrayList<NodeFrontier> nodeFrontiers = new ArrayList<NodeFrontier>();
+ protected final ITreeIndexMetaDataFrame metaFrame;
+ protected final ITreeIndexTupleWriter tupleWriter;
+
+ protected ITreeIndexFrame leafFrame, interiorFrame;
+
+ public AbstractTreeIndexBulkLoader(float fillFactor) throws TreeIndexException, HyracksDataException {
+ leafFrame = leafFrameFactory.createFrame();
+ interiorFrame = interiorFrameFactory.createFrame();
+ metaFrame = freePageManager.getMetaDataFrameFactory().createFrame();
+
+ if (!isEmptyTree(leafFrame)) {
+ throw new TreeIndexException("Trying to Bulk-load a non-empty tree.");
+ }
+
+ this.cmp = MultiComparator.create(cmpFactories);
+
+ leafFrame.setMultiComparator(cmp);
+ interiorFrame.setMultiComparator(cmp);
+
+ tupleWriter = leafFrame.getTupleWriter();
+
+ NodeFrontier leafFrontier = new NodeFrontier(leafFrame.createTupleReference());
+ leafFrontier.pageId = freePageManager.getFreePage(metaFrame);
+ leafFrontier.page = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, leafFrontier.pageId),
+ true);
+ leafFrontier.page.acquireWriteLatch();
+
+ interiorFrame.setPage(leafFrontier.page);
+ interiorFrame.initBuffer((byte) 0);
+ interiorMaxBytes = (int) ((float) interiorFrame.getBuffer().capacity() * fillFactor);
+
+ leafFrame.setPage(leafFrontier.page);
+ leafFrame.initBuffer((byte) 0);
+ leafMaxBytes = (int) ((float) leafFrame.getBuffer().capacity() * fillFactor);
+
+ slotSize = leafFrame.getSlotSize();
+
+ nodeFrontiers.add(leafFrontier);
+ }
+
+ public abstract void add(ITupleReference tuple) throws HyracksDataException;
+
+ @Override
+ public void end() throws HyracksDataException {
+ // copy root
+ ICachedPage rootNode = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, rootPage), true);
+ rootNode.acquireWriteLatch();
+ NodeFrontier lastNodeFrontier = nodeFrontiers.get(nodeFrontiers.size() - 1);
+ try {
+ ICachedPage toBeRoot = lastNodeFrontier.page;
+ System.arraycopy(toBeRoot.getBuffer().array(), 0, rootNode.getBuffer().array(), 0, toBeRoot.getBuffer()
+ .capacity());
+ } finally {
+ rootNode.releaseWriteLatch();
+ bufferCache.unpin(rootNode);
+
+ // register old root as free page
+ freePageManager.addFreePage(metaFrame, lastNodeFrontier.pageId);
+
+ // make old root a free page
+ interiorFrame.setPage(lastNodeFrontier.page);
+ interiorFrame.initBuffer(freePageManager.getFreePageLevelIndicator());
+
+ // cleanup
+ for (int i = 0; i < nodeFrontiers.size(); i++) {
+ nodeFrontiers.get(i).page.releaseWriteLatch();
+ bufferCache.unpin(nodeFrontiers.get(i).page);
+ }
+ }
+ }
+
+ protected void addLevel() throws HyracksDataException {
+ NodeFrontier frontier = new NodeFrontier(tupleWriter.createTupleReference());
+ frontier.pageId = freePageManager.getFreePage(metaFrame);
+ frontier.page = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, frontier.pageId), true);
+ frontier.page.acquireWriteLatch();
+ frontier.lastTuple.setFieldCount(cmp.getKeyFieldCount());
+ interiorFrame.setPage(frontier.page);
+ interiorFrame.initBuffer((byte) nodeFrontiers.size());
+ nodeFrontiers.add(frontier);
+ }
+ }
+
+ public class TreeIndexInsertBulkLoader implements ITreeIndexBulkLoader {
+ // TODO: What callback to pass here?
+ ITreeIndexAccessor accessor = (ITreeIndexAccessor) createAccessor(
+ NoOpOperationCallback.INSTANCE, NoOpOperationCallback.INSTANCE);
+
+ @Override
+ public void add(ITupleReference tuple) throws HyracksDataException {
+ try {
+ accessor.insert(tuple);
+ } catch (IndexException e) {
+ throw new HyracksDataException(e);
+ }
+ }
+
+ @Override
+ public void end() throws HyracksDataException {
+ // do nothing
+ }
+
+ }
+
+ @Deprecated
+ protected ITreeIndexBulkLoader bulkloader;
+
+ @Deprecated
+ public IIndexBulkLoadContext beginBulkLoad(float fillFactor) throws HyracksDataException, TreeIndexException {
+ if(this.bulkloader == null) this.bulkloader = this.createBulkLoader(fillFactor);
+ return null;
+ }
+
+ @Deprecated
+ public void bulkLoadAddTuple(ITupleReference tuple, IIndexBulkLoadContext ictx) throws HyracksDataException {
+ this.bulkloader.add(tuple);
+ }
+
+ @Deprecated
+ public void endBulkLoad(IIndexBulkLoadContext ictx) throws HyracksDataException {
+ this.bulkloader.end();
+ }
+}
diff --git a/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/btree/tuples/ILSMBTreeTupleReference.java b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/impls/NodeFrontier.java
similarity index 66%
copy from hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/btree/tuples/ILSMBTreeTupleReference.java
copy to hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/impls/NodeFrontier.java
index cfc71fc..56f5fdb 100644
--- a/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/btree/tuples/ILSMBTreeTupleReference.java
+++ b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/impls/NodeFrontier.java
@@ -13,10 +13,17 @@
* limitations under the License.
*/
-package edu.uci.ics.hyracks.storage.am.lsm.btree.tuples;
+package edu.uci.ics.hyracks.storage.am.common.impls;
import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexTupleReference;
+import edu.uci.ics.hyracks.storage.common.buffercache.ICachedPage;
-public interface ILSMBTreeTupleReference extends ITreeIndexTupleReference {
- public boolean isAntimatter();
+public class NodeFrontier {
+ public ICachedPage page;
+ public int pageId;
+ public ITreeIndexTupleReference lastTuple;
+
+ public NodeFrontier(ITreeIndexTupleReference lastTuple) {
+ this.lastTuple = lastTuple;
+ }
}
diff --git a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/ophelpers/DoubleArrayList.java b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/ophelpers/DoubleArrayList.java
new file mode 100644
index 0000000..318a102
--- /dev/null
+++ b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/ophelpers/DoubleArrayList.java
@@ -0,0 +1,98 @@
+/*
+ * 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.common.ophelpers;
+
+public class DoubleArrayList {
+ private double[] data;
+ private int size;
+ private int first;
+ private final int growth;
+
+ public DoubleArrayList(int initialCapacity, int growth) {
+ data = new double[initialCapacity];
+ size = 0;
+ first = 0;
+ this.growth = growth;
+ }
+
+ public int size() {
+ return size;
+ }
+
+ public int first() {
+ return first;
+ }
+
+ public void add(double i) {
+ if (size == data.length) {
+ double[] newData = new double[data.length + growth];
+ System.arraycopy(data, 0, newData, 0, data.length);
+ data = newData;
+ }
+
+ data[size++] = i;
+ }
+
+ public void addFirst(double i) {
+ double[] newData = new double[data.length + 1];
+ System.arraycopy(data, 0, newData, 0, first);
+ System.arraycopy(data, first, newData, first + 1, size - first);
+ data = newData;
+ data[first] = i;
+ size++;
+ }
+
+ public void removeLast() {
+ if (size > 0)
+ size--;
+ }
+
+ // WARNING: caller is responsible for checking size > 0
+ public double getLast() {
+ return data[size - 1];
+ }
+
+ public double get(int i) {
+ return data[i];
+ }
+
+ // WARNING: caller is responsible for checking i < size
+ public void set(int i, int value) {
+ data[i] = value;
+
+ }
+
+ public double getFirst() {
+ return data[first];
+ }
+
+ public void moveFirst() {
+ first++;
+ }
+
+ public void clear() {
+ size = 0;
+ first = 0;
+ }
+
+ public boolean isLast() {
+ return size == first;
+ }
+
+ public boolean isEmpty() {
+ return size == 0;
+ }
+}
diff --git a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/ophelpers/MultiComparator.java b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/ophelpers/MultiComparator.java
index 91db6ff..e7be912 100644
--- a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/ophelpers/MultiComparator.java
+++ b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/ophelpers/MultiComparator.java
@@ -21,49 +21,57 @@
public class MultiComparator {
- private final IBinaryComparator[] cmps;
+ private final IBinaryComparator[] cmps;
- public MultiComparator(IBinaryComparator[] cmps) {
- this.cmps = cmps;
- }
+ public MultiComparator(IBinaryComparator[] cmps) {
+ this.cmps = cmps;
+ }
- public int compare(ITupleReference tupleA, ITupleReference tupleB) {
- for (int i = 0; i < cmps.length; i++) {
- int cmp = cmps[i].compare(tupleA.getFieldData(i),
- tupleA.getFieldStart(i), tupleA.getFieldLength(i),
- tupleB.getFieldData(i), tupleB.getFieldStart(i),
- tupleB.getFieldLength(i));
- if (cmp < 0)
- return -1;
- else if (cmp > 0)
- return 1;
- }
- return 0;
- }
+ public int compare(ITupleReference tupleA, ITupleReference tupleB) {
+ for (int i = 0; i < cmps.length; i++) {
+ int cmp = cmps[i].compare(tupleA.getFieldData(i), tupleA.getFieldStart(i), tupleA.getFieldLength(i),
+ tupleB.getFieldData(i), tupleB.getFieldStart(i), tupleB.getFieldLength(i));
+ if (cmp < 0)
+ return -1;
+ else if (cmp > 0)
+ return 1;
+ }
+ return 0;
+ }
- public int fieldRangeCompare(ITupleReference tupleA,
- ITupleReference tupleB, int startFieldIndex, int numFields) {
- for (int i = startFieldIndex; i < startFieldIndex + numFields; i++) {
- int cmp = cmps[i].compare(tupleA.getFieldData(i),
- tupleA.getFieldStart(i), tupleA.getFieldLength(i),
- tupleB.getFieldData(i), tupleB.getFieldStart(i),
- tupleB.getFieldLength(i));
- if (cmp < 0)
- return -1;
- else if (cmp > 0)
- return 1;
- }
- return 0;
- }
+ public int selectiveFieldCompare(ITupleReference tupleA, ITupleReference tupleB, int[] fields) {
+ for (int j = 0; j < cmps.length; j++) {
+ int i = fields[j];
+ int cmp = cmps[j].compare(tupleA.getFieldData(i), tupleA.getFieldStart(i), tupleA.getFieldLength(i),
+ tupleB.getFieldData(i), tupleB.getFieldStart(i), tupleB.getFieldLength(i));
+ if (cmp < 0)
+ return -1;
+ else if (cmp > 0)
+ return 1;
+ }
+ return 0;
+ }
- public IBinaryComparator[] getComparators() {
- return cmps;
- }
+ public int fieldRangeCompare(ITupleReference tupleA, ITupleReference tupleB, int startFieldIndex, int numFields) {
+ for (int i = startFieldIndex; i < startFieldIndex + numFields; i++) {
+ int cmp = cmps[i].compare(tupleA.getFieldData(i), tupleA.getFieldStart(i), tupleA.getFieldLength(i),
+ tupleB.getFieldData(i), tupleB.getFieldStart(i), tupleB.getFieldLength(i));
+ if (cmp < 0)
+ return -1;
+ else if (cmp > 0)
+ return 1;
+ }
+ return 0;
+ }
+
+ public IBinaryComparator[] getComparators() {
+ return cmps;
+ }
public int getKeyFieldCount() {
- return cmps.length;
- }
-
+ return cmps.length;
+ }
+
public static MultiComparator create(IBinaryComparatorFactory[] cmpFactories) {
IBinaryComparator[] cmps = new IBinaryComparator[cmpFactories.length];
for (int i = 0; i < cmpFactories.length; i++) {
diff --git a/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/btree/impls/LSMBTree.java b/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/btree/impls/LSMBTree.java
index f19457b..8e9bf36 100644
--- a/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/btree/impls/LSMBTree.java
+++ b/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/btree/impls/LSMBTree.java
@@ -27,6 +27,7 @@
import edu.uci.ics.hyracks.api.io.FileReference;
import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
+import edu.uci.ics.hyracks.storage.am.btree.impls.BTree.BTreeBulkLoader;
import edu.uci.ics.hyracks.storage.am.btree.impls.RangePredicate;
import edu.uci.ics.hyracks.storage.am.common.api.IFreePageManager;
import edu.uci.ics.hyracks.storage.am.common.api.IIndexAccessor;
@@ -38,6 +39,7 @@
import edu.uci.ics.hyracks.storage.am.common.api.ISearchPredicate;
import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexAccessor;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexBulkLoader;
import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexCursor;
import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrameFactory;
import edu.uci.ics.hyracks.storage.am.common.api.IndexException;
@@ -346,46 +348,55 @@
return diskBTrees;
}
- public class LSMTreeBulkLoadContext implements IIndexBulkLoadContext {
- private final BTree btree;
- private IIndexBulkLoadContext bulkLoadCtx;
+ @Override
+ public ITreeIndexBulkLoader createBulkLoader(float fillLevel)
+ throws TreeIndexException {
+ return new LSMBTreeBulkLoader(fillLevel);
+ }
+
+ public class LSMBTreeBulkLoader implements ITreeIndexBulkLoader {
+ private final BTree diskBTree;
+ private final BTreeBulkLoader bulkLoader;
- public LSMTreeBulkLoadContext(BTree btree) {
- this.btree = btree;
- }
+ public LSMBTreeBulkLoader(float fillFactor) throws TreeIndexException {
+ try {
+ diskBTree = createBulkLoadTarget();
+ } catch (HyracksDataException e) {
+ throw new TreeIndexException(e);
+ }
+ bulkLoader = (BTreeBulkLoader) diskBTree.createBulkLoader(0.7f);
+ }
- public void beginBulkLoad(float fillFactor) throws HyracksDataException, TreeIndexException {
- bulkLoadCtx = btree.beginBulkLoad(fillFactor);
- }
+ @Override
+ public void add(ITupleReference tuple) throws HyracksDataException {
+ bulkLoader.add(tuple);
+ }
- public BTree getBTree() {
- return btree;
- }
+ @Override
+ public void end() throws HyracksDataException {
+ bulkLoader.end();
+ lsmHarness.addBulkLoadedComponent(diskBTree);
+ }
+
+ }
- public IIndexBulkLoadContext getBulkLoadCtx() {
- return bulkLoadCtx;
- }
- }
-
+ @Deprecated
+ private ITreeIndexBulkLoader bulkloader;
+
@Override
public IIndexBulkLoadContext beginBulkLoad(float fillFactor) throws TreeIndexException, HyracksDataException {
- BTree diskBTree = createBulkLoadTarget();
- LSMTreeBulkLoadContext bulkLoadCtx = new LSMTreeBulkLoadContext(diskBTree);
- bulkLoadCtx.beginBulkLoad(fillFactor);
- return bulkLoadCtx;
+ bulkloader = createBulkLoader(fillFactor);
+ return null;
}
@Override
public void bulkLoadAddTuple(ITupleReference tuple, IIndexBulkLoadContext ictx) throws HyracksDataException {
- LSMTreeBulkLoadContext bulkLoadCtx = (LSMTreeBulkLoadContext) ictx;
- bulkLoadCtx.getBTree().bulkLoadAddTuple(tuple, bulkLoadCtx.getBulkLoadCtx());
+ bulkloader.add(tuple);
}
@Override
public void endBulkLoad(IIndexBulkLoadContext ictx) throws HyracksDataException {
- LSMTreeBulkLoadContext bulkLoadCtx = (LSMTreeBulkLoadContext) ictx;
- bulkLoadCtx.getBTree().endBulkLoad(bulkLoadCtx.getBulkLoadCtx());
- lsmHarness.addBulkLoadedComponent(bulkLoadCtx.getBTree());
+ bulkloader.end();
}
@Override
diff --git a/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/btree/impls/LSMBTreeRangeSearchCursor.java b/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/btree/impls/LSMBTreeRangeSearchCursor.java
index ef0a9cd..8333a95 100644
--- a/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/btree/impls/LSMBTreeRangeSearchCursor.java
+++ b/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/btree/impls/LSMBTreeRangeSearchCursor.java
@@ -17,7 +17,6 @@
import java.util.Comparator;
import java.util.PriorityQueue;
-import java.util.concurrent.atomic.AtomicInteger;
import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
@@ -26,24 +25,11 @@
import edu.uci.ics.hyracks.storage.am.common.api.ICursorInitialState;
import edu.uci.ics.hyracks.storage.am.common.api.ISearchOperationCallback;
import edu.uci.ics.hyracks.storage.am.common.api.ISearchPredicate;
-import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexCursor;
import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
-import edu.uci.ics.hyracks.storage.am.lsm.btree.tuples.LSMBTreeTupleReference;
-import edu.uci.ics.hyracks.storage.am.lsm.common.impls.LSMHarness;
-import edu.uci.ics.hyracks.storage.common.buffercache.IBufferCache;
-import edu.uci.ics.hyracks.storage.common.buffercache.ICachedPage;
+import edu.uci.ics.hyracks.storage.am.lsm.common.impls.LSMTreeSearchCursor;
-public class LSMBTreeRangeSearchCursor implements ITreeIndexCursor {
- private BTreeRangeSearchCursor[] rangeCursors;
- private PriorityQueue<PriorityQueueElement> outputPriorityQueue;
- private MultiComparator cmp;
+public class LSMBTreeRangeSearchCursor extends LSMTreeSearchCursor {
private PriorityQueueComparator pqCmp;
- private PriorityQueueElement outputElement;
- private PriorityQueueElement reusedElement;
- private boolean needPush;
- private boolean includeMemComponent;
- private AtomicInteger searcherfRefCount;
- private LSMHarness lsmHarness;
private ISearchOperationCallback searchCallback;
public LSMBTreeRangeSearchCursor() {
@@ -65,31 +51,6 @@
checkPriorityQueue();
}
- public BTreeRangeSearchCursor getCursor(int cursorIndex) {
- return rangeCursors[cursorIndex];
- }
-
- @Override
- public void reset() {
- outputElement = null;
- needPush = false;
- }
-
- @Override
- public boolean hasNext() throws HyracksDataException {
- checkPriorityQueue();
- return !outputPriorityQueue.isEmpty();
- }
-
- @Override
- public void next() throws HyracksDataException {
- outputElement = outputPriorityQueue.poll();
- needPush = true;
- if (outputElement == null) {
- throw new HyracksDataException("The outputPriorityQueue is empty");
- }
- }
-
@Override
public void open(ICursorInitialState initialState, ISearchPredicate searchPred) throws HyracksDataException {
LSMBTreeCursorInitialState lsmInitialState = (LSMBTreeCursorInitialState) initialState;
@@ -107,111 +68,13 @@
setPriorityQueueComparator();
}
- private void setPriorityQueueComparator() {
+ @Override
+ protected void setPriorityQueueComparator() {
if (pqCmp == null || cmp != pqCmp.getMultiComparator()) {
pqCmp = new PriorityQueueComparator(cmp);
}
}
- @Override
- public ICachedPage getPage() {
- // do nothing
- return null;
- }
-
- @Override
- public void close() throws HyracksDataException {
- try {
- outputPriorityQueue.clear();
- for (int i = 0; i < rangeCursors.length; i++) {
- rangeCursors[i].close();
- }
- rangeCursors = null;
- } finally {
- lsmHarness.closeSearchCursor(searcherfRefCount, includeMemComponent);
- }
- }
-
- @Override
- public void setBufferCache(IBufferCache bufferCache) {
- // do nothing
- }
-
- @Override
- public void setFileId(int fileId) {
- // do nothing
- }
-
- @Override
- public ITupleReference getTuple() {
- return (ITupleReference) outputElement.getTuple();
- }
-
- private void pushIntoPriorityQueue(int cursorIndex) throws HyracksDataException {
- if (rangeCursors[cursorIndex].hasNext()) {
- rangeCursors[cursorIndex].next();
- reusedElement.reset(rangeCursors[cursorIndex].getTuple(), cursorIndex);
- outputPriorityQueue.offer(reusedElement);
- }
- }
-
- private void checkPriorityQueue() throws HyracksDataException {
- while (!outputPriorityQueue.isEmpty() || needPush == true) {
- if (!outputPriorityQueue.isEmpty()) {
- PriorityQueueElement checkElement = outputPriorityQueue.peek();
- // If there is no previous tuple or the previous tuple can be
- // ignored
- if (outputElement == null) {
- // Test the tuple is a delete tuple or not
- if (((LSMBTreeTupleReference) checkElement.getTuple()).isAntimatter() == true) {
- // If the tuple is a delete tuple then pop it and mark
- // it "needPush"
- // Cannot push at this time because the tuple may be
- // modified if "hasNext" is called
- outputElement = outputPriorityQueue.poll();
- needPush = true;
- } else {
- break;
- }
- } else {
- // Compare the previous tuple and the head tuple in the PQ
- if (cmp.compare(outputElement.getTuple(), checkElement.getTuple()) == 0) {
- // If the previous tuple and the head tuple are
- // identical
- // then pop the head tuple and push the next tuple from
- // the tree of head tuple
-
- // the head element of PQ is useless now
- reusedElement = outputPriorityQueue.poll();
- // int treeNum = reusedElement.getTreeNum();
- pushIntoPriorityQueue(reusedElement.getCursorIndex());
- } else {
- // If the previous tuple and the head tuple are
- // different
- // the info of previous tuple is useless
- if (needPush == true) {
- reusedElement = outputElement;
- pushIntoPriorityQueue(outputElement.getCursorIndex());
- needPush = false;
- }
- outputElement = null;
- }
- }
- } else {
- // the priority queue is empty and needPush
- reusedElement = outputElement;
- pushIntoPriorityQueue(outputElement.getCursorIndex());
- needPush = false;
- outputElement = null;
- }
- }
- }
-
- @Override
- public boolean exclusiveLatchNodes() {
- return false;
- }
-
public class PriorityQueueComparator implements Comparator<PriorityQueueElement> {
private final MultiComparator cmp;
@@ -238,25 +101,8 @@
}
}
- public class PriorityQueueElement {
- private ITupleReference tuple;
- private int cursorIndex;
-
- public PriorityQueueElement(ITupleReference tuple, int cursorIndex) {
- reset(tuple, cursorIndex);
- }
-
- public ITupleReference getTuple() {
- return tuple;
- }
-
- public int getCursorIndex() {
- return cursorIndex;
- }
-
- public void reset(ITupleReference tuple, int cursorIndex) {
- this.tuple = tuple;
- this.cursorIndex = cursorIndex;
- }
+ @Override
+ protected int compare(MultiComparator cmp, ITupleReference tupleA, ITupleReference tupleB) {
+ return cmp.compare(tupleA, tupleB);
}
}
diff --git a/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/btree/tuples/LSMBTreeTupleReference.java b/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/btree/tuples/LSMBTreeTupleReference.java
index 5c8acba..2c55792 100644
--- a/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/btree/tuples/LSMBTreeTupleReference.java
+++ b/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/btree/tuples/LSMBTreeTupleReference.java
@@ -20,8 +20,9 @@
import edu.uci.ics.hyracks.api.dataflow.value.ITypeTraits;
import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrame;
import edu.uci.ics.hyracks.storage.am.common.tuples.TypeAwareTupleReference;
+import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMTreeTupleReference;
-public class LSMBTreeTupleReference extends TypeAwareTupleReference implements ILSMBTreeTupleReference {
+public class LSMBTreeTupleReference extends TypeAwareTupleReference implements ILSMTreeTupleReference {
// Indicates whether the last call to setFieldCount() was initiated by
// by the outside or whether it was called internally to set up an
diff --git a/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/btree/tuples/ILSMBTreeTupleReference.java b/hyracks-storage-am-lsm-common/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/common/api/ILSMTreeTupleReference.java
similarity index 80%
rename from hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/btree/tuples/ILSMBTreeTupleReference.java
rename to hyracks-storage-am-lsm-common/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/common/api/ILSMTreeTupleReference.java
index cfc71fc..8d82673 100644
--- a/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/btree/tuples/ILSMBTreeTupleReference.java
+++ b/hyracks-storage-am-lsm-common/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/common/api/ILSMTreeTupleReference.java
@@ -13,10 +13,10 @@
* limitations under the License.
*/
-package edu.uci.ics.hyracks.storage.am.lsm.btree.tuples;
+package edu.uci.ics.hyracks.storage.am.lsm.common.api;
import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexTupleReference;
-public interface ILSMBTreeTupleReference extends ITreeIndexTupleReference {
- public boolean isAntimatter();
+public interface ILSMTreeTupleReference extends ITreeIndexTupleReference {
+ public boolean isAntimatter();
}
diff --git a/hyracks-storage-am-lsm-common/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/common/impls/LSMTreeSearchCursor.java b/hyracks-storage-am-lsm-common/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/common/impls/LSMTreeSearchCursor.java
new file mode 100644
index 0000000..a8e0873
--- /dev/null
+++ b/hyracks-storage-am-lsm-common/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/common/impls/LSMTreeSearchCursor.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package edu.uci.ics.hyracks.storage.am.lsm.common.impls;
+
+import java.util.PriorityQueue;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexCursor;
+import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
+import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMTreeTupleReference;
+import edu.uci.ics.hyracks.storage.common.buffercache.IBufferCache;
+import edu.uci.ics.hyracks.storage.common.buffercache.ICachedPage;
+
+public abstract class LSMTreeSearchCursor implements ITreeIndexCursor {
+ protected ITreeIndexCursor[] rangeCursors;
+ protected PriorityQueue<PriorityQueueElement> outputPriorityQueue;
+ protected MultiComparator cmp;
+
+ protected PriorityQueueElement outputElement;
+ protected PriorityQueueElement reusedElement;
+ protected boolean needPush;
+ protected boolean includeMemComponent;
+ protected AtomicInteger searcherfRefCount;
+ protected LSMHarness lsmHarness;
+
+ public LSMTreeSearchCursor() {
+ outputElement = null;
+ needPush = false;
+ }
+
+ public ITreeIndexCursor getCursor(int cursorIndex) {
+ return rangeCursors[cursorIndex];
+ }
+
+ @Override
+ public void reset() {
+ outputElement = null;
+ needPush = false;
+ }
+
+ @Override
+ public boolean hasNext() throws HyracksDataException {
+ checkPriorityQueue();
+ return !outputPriorityQueue.isEmpty();
+ }
+
+ @Override
+ public void next() throws HyracksDataException {
+ outputElement = outputPriorityQueue.poll();
+ needPush = true;
+ if (outputElement == null) {
+ throw new HyracksDataException("The outputPriorityQueue is empty");
+ }
+ }
+
+ protected abstract void setPriorityQueueComparator();
+
+ @Override
+ public ICachedPage getPage() {
+ // do nothing
+ return null;
+ }
+
+ @Override
+ public void close() throws HyracksDataException {
+ try {
+ outputPriorityQueue.clear();
+ for (int i = 0; i < rangeCursors.length; i++) {
+ rangeCursors[i].close();
+ }
+ rangeCursors = null;
+ } finally {
+ lsmHarness.closeSearchCursor(searcherfRefCount, includeMemComponent);
+ }
+ }
+
+ @Override
+ public void setBufferCache(IBufferCache bufferCache) {
+ // do nothing
+ }
+
+ @Override
+ public void setFileId(int fileId) {
+ // do nothing
+ }
+
+ @Override
+ public ITupleReference getTuple() {
+ return (ITupleReference) outputElement.getTuple();
+ }
+
+ protected void pushIntoPriorityQueue(int cursorIndex) throws HyracksDataException {
+ if (rangeCursors[cursorIndex].hasNext()) {
+ rangeCursors[cursorIndex].next();
+ reusedElement.reset(rangeCursors[cursorIndex].getTuple(), cursorIndex);
+ outputPriorityQueue.offer(reusedElement);
+ }
+ }
+
+ protected abstract int compare(MultiComparator cmp, ITupleReference tupleA, ITupleReference tupleB);
+
+ protected void checkPriorityQueue() throws HyracksDataException {
+ while (!outputPriorityQueue.isEmpty() || needPush == true) {
+ if (!outputPriorityQueue.isEmpty()) {
+ PriorityQueueElement checkElement = outputPriorityQueue.peek();
+ // If there is no previous tuple or the previous tuple can be
+ // ignored
+ if (outputElement == null) {
+ // Test the tuple is a delete tuple or not
+ if (((ILSMTreeTupleReference) checkElement.getTuple()).isAntimatter() == true) {
+ // If the tuple is a delete tuple then pop it and mark
+ // it "needPush"
+ // Cannot push at this time because the tuple may be
+ // modified if "hasNext" is called
+ outputElement = outputPriorityQueue.poll();
+ needPush = true;
+ } else {
+ break;
+ }
+ } else {
+ // Compare the previous tuple and the head tuple in the PQ
+ if (compare(cmp, outputElement.getTuple(), checkElement.getTuple()) == 0) {
+ // If the previous tuple and the head tuple are
+ // identical
+ // then pop the head tuple and push the next tuple from
+ // the tree of head tuple
+
+ // the head element of PQ is useless now
+ reusedElement = outputPriorityQueue.poll();
+ // int treeNum = reusedElement.getTreeNum();
+ pushIntoPriorityQueue(reusedElement.getCursorIndex());
+ } else {
+ // If the previous tuple and the head tuple are
+ // different
+ // the info of previous tuple is useless
+ if (needPush == true) {
+ reusedElement = outputElement;
+ pushIntoPriorityQueue(outputElement.getCursorIndex());
+ needPush = false;
+ }
+ outputElement = null;
+ }
+ }
+ } else {
+ // the priority queue is empty and needPush
+ reusedElement = outputElement;
+ pushIntoPriorityQueue(outputElement.getCursorIndex());
+ needPush = false;
+ outputElement = null;
+ }
+ }
+ }
+
+ @Override
+ public boolean exclusiveLatchNodes() {
+ return false;
+ }
+
+ public class PriorityQueueElement {
+ private ITupleReference tuple;
+ private int cursorIndex;
+
+ public PriorityQueueElement(ITupleReference tuple, int cursorIndex) {
+ reset(tuple, cursorIndex);
+ }
+
+ public ITupleReference getTuple() {
+ return tuple;
+ }
+
+ public int getCursorIndex() {
+ return cursorIndex;
+ }
+
+ public void reset(ITupleReference tuple, int cursorIndex) {
+ this.tuple = tuple;
+ this.cursorIndex = cursorIndex;
+ }
+ }
+}
diff --git a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/dataflow/AbstractLSMRTreeDataflowHelper.java b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/dataflow/AbstractLSMRTreeDataflowHelper.java
new file mode 100644
index 0000000..d96aea9
--- /dev/null
+++ b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/dataflow/AbstractLSMRTreeDataflowHelper.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package edu.uci.ics.hyracks.storage.am.lsm.rtree.dataflow;
+
+import edu.uci.ics.hyracks.api.context.IHyracksTaskContext;
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparatorFactory;
+import edu.uci.ics.hyracks.api.dataflow.value.ITypeTraits;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.api.io.FileReference;
+import edu.uci.ics.hyracks.api.io.IIOManager;
+import edu.uci.ics.hyracks.dataflow.std.file.IFileSplitProvider;
+import edu.uci.ics.hyracks.storage.am.common.api.IOperationCallbackProvider;
+import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexMetaDataFrameFactory;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexOperatorDescriptor;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.TreeIndexDataflowHelper;
+import edu.uci.ics.hyracks.storage.am.common.frames.LIFOMetaDataFrameFactory;
+import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMFlushPolicy;
+import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMMergePolicy;
+import edu.uci.ics.hyracks.storage.am.lsm.common.freepage.InMemoryBufferCache;
+import edu.uci.ics.hyracks.storage.am.lsm.common.freepage.InMemoryFreePageManager;
+import edu.uci.ics.hyracks.storage.am.lsm.rtree.impls.LSMRTreeInMemoryBufferCache;
+import edu.uci.ics.hyracks.storage.am.lsm.rtree.impls.LSMRTreeInMemoryFreePageManager;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
+import edu.uci.ics.hyracks.storage.common.buffercache.HeapBufferAllocator;
+import edu.uci.ics.hyracks.storage.common.buffercache.IBufferCache;
+import edu.uci.ics.hyracks.storage.common.file.IFileMapProvider;
+
+public abstract class AbstractLSMRTreeDataflowHelper extends TreeIndexDataflowHelper {
+ private static int DEFAULT_MEM_PAGE_SIZE = 32768;
+ private static int DEFAULT_MEM_NUM_PAGES = 1000;
+
+ private final int memPageSize;
+ private final int memNumPages;
+
+ protected final IBinaryComparatorFactory[] btreeComparatorFactories;
+ protected final IPrimitiveValueProviderFactory[] valueProviderFactories;
+ protected final RTreePolicyType rtreePolicyType;
+ protected final ILSMFlushPolicy flushPolicy;
+ protected final ILSMMergePolicy mergePolicy;
+
+ public AbstractLSMRTreeDataflowHelper(IIndexOperatorDescriptor opDesc, IHyracksTaskContext ctx, int partition,
+ IBinaryComparatorFactory[] btreeComparatorFactories,
+ IPrimitiveValueProviderFactory[] valueProviderFactories, RTreePolicyType rtreePolicyType,
+ ILSMFlushPolicy flushPolicy, ILSMMergePolicy mergePolicy) {
+ super(opDesc, ctx, partition);
+ memPageSize = DEFAULT_MEM_PAGE_SIZE;
+ memNumPages = DEFAULT_MEM_NUM_PAGES;
+ this.btreeComparatorFactories = btreeComparatorFactories;
+ this.valueProviderFactories = valueProviderFactories;
+ this.rtreePolicyType = rtreePolicyType;
+ this.flushPolicy = flushPolicy;
+ this.mergePolicy = mergePolicy;
+ }
+
+ public AbstractLSMRTreeDataflowHelper(IIndexOperatorDescriptor opDesc, IHyracksTaskContext ctx,
+ IOperationCallbackProvider opCallbackProvider, int partition, boolean createIfNotExists, int memPageSize,
+ int memNumPages, IBinaryComparatorFactory[] btreeComparatorFactories,
+ IPrimitiveValueProviderFactory[] valueProviderFactories, RTreePolicyType rtreePolicyType,
+ ILSMFlushPolicy flushPolicy, ILSMMergePolicy mergePolicy) {
+ super(opDesc, ctx, partition);
+ this.memPageSize = memPageSize;
+ this.memNumPages = memNumPages;
+ this.btreeComparatorFactories = btreeComparatorFactories;
+ this.valueProviderFactories = valueProviderFactories;
+ this.rtreePolicyType = rtreePolicyType;
+ this.flushPolicy = flushPolicy;
+ this.mergePolicy = mergePolicy;
+ }
+
+ @Override
+ public ITreeIndex createIndexInstance() throws HyracksDataException {
+ ITreeIndexMetaDataFrameFactory metaDataFrameFactory = new LIFOMetaDataFrameFactory();
+ InMemoryBufferCache memBufferCache = new LSMRTreeInMemoryBufferCache(new HeapBufferAllocator(), memPageSize,
+ memNumPages);
+ IFileSplitProvider fileSplitProvider = opDesc.getFileSplitProvider();
+ FileReference file = fileSplitProvider.getFileSplits()[partition].getLocalFile();
+ if (file.getFile().exists() && !file.getFile().isDirectory()) {
+ file.delete();
+ }
+ InMemoryFreePageManager memFreePageManager = new LSMRTreeInMemoryFreePageManager(memNumPages,
+ metaDataFrameFactory);
+
+ return createLSMTree(memBufferCache, memFreePageManager, ctx.getIOManager(), file.getFile().getPath(), opDesc
+ .getStorageManager().getBufferCache(ctx), opDesc.getStorageManager().getFileMapProvider(ctx),
+ treeOpDesc.getTreeIndexTypeTraits(), treeOpDesc.getTreeIndexComparatorFactories(),
+ btreeComparatorFactories, valueProviderFactories, rtreePolicyType);
+
+ }
+
+ protected abstract ITreeIndex createLSMTree(IBufferCache memBufferCache,
+ InMemoryFreePageManager memFreePageManager, IIOManager ioManager, String onDiskDir,
+ IBufferCache diskBufferCache, IFileMapProvider diskFileMapProvider, ITypeTraits[] typeTraits,
+ IBinaryComparatorFactory[] rtreeCmpFactories, IBinaryComparatorFactory[] btreeCmpFactories,
+ IPrimitiveValueProviderFactory[] valueProviderFactories, RTreePolicyType rtreePolicyType)
+ throws HyracksDataException;
+}
diff --git a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/dataflow/LSMRTreeDataflowHelper.java b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/dataflow/LSMRTreeDataflowHelper.java
index 0f283a7..5a09621 100644
--- a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/dataflow/LSMRTreeDataflowHelper.java
+++ b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/dataflow/LSMRTreeDataflowHelper.java
@@ -17,73 +17,53 @@
import edu.uci.ics.hyracks.api.context.IHyracksTaskContext;
import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparatorFactory;
+import edu.uci.ics.hyracks.api.dataflow.value.ITypeTraits;
import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
-import edu.uci.ics.hyracks.api.io.FileReference;
-import edu.uci.ics.hyracks.dataflow.std.file.IFileSplitProvider;
+import edu.uci.ics.hyracks.api.io.IIOManager;
+import edu.uci.ics.hyracks.storage.am.common.api.IOperationCallbackProvider;
import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
-import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexMetaDataFrameFactory;
+import edu.uci.ics.hyracks.storage.am.common.api.TreeIndexException;
import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexOperatorDescriptor;
-import edu.uci.ics.hyracks.storage.am.common.dataflow.TreeIndexDataflowHelper;
-import edu.uci.ics.hyracks.storage.am.common.frames.LIFOMetaDataFrameFactory;
import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMFlushPolicy;
import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMMergePolicy;
-import edu.uci.ics.hyracks.storage.am.lsm.common.freepage.InMemoryBufferCache;
import edu.uci.ics.hyracks.storage.am.lsm.common.freepage.InMemoryFreePageManager;
-import edu.uci.ics.hyracks.storage.am.lsm.rtree.impls.LSMRTreeInMemoryBufferCache;
-import edu.uci.ics.hyracks.storage.am.lsm.rtree.impls.LSMRTreeInMemoryFreePageManager;
import edu.uci.ics.hyracks.storage.am.lsm.rtree.utils.LSMRTreeUtils;
-import edu.uci.ics.hyracks.storage.common.buffercache.HeapBufferAllocator;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
+import edu.uci.ics.hyracks.storage.common.buffercache.IBufferCache;
+import edu.uci.ics.hyracks.storage.common.file.IFileMapProvider;
-public class LSMRTreeDataflowHelper extends TreeIndexDataflowHelper {
- private static int DEFAULT_MEM_PAGE_SIZE = 32768;
- private static int DEFAULT_MEM_NUM_PAGES = 1000;
-
- private final int memPageSize;
- private final int memNumPages;
-
- private final IBinaryComparatorFactory[] btreeComparatorFactories;
- private final IPrimitiveValueProviderFactory[] valueProviderFactories;
- private final ILSMFlushPolicy flushPolicy;
- private final ILSMMergePolicy mergePolicy;
+public class LSMRTreeDataflowHelper extends AbstractLSMRTreeDataflowHelper {
public LSMRTreeDataflowHelper(IIndexOperatorDescriptor opDesc, IHyracksTaskContext ctx, int partition,
IBinaryComparatorFactory[] btreeComparatorFactories,
- IPrimitiveValueProviderFactory[] valueProviderFactories, ILSMFlushPolicy flushPolicy,
- ILSMMergePolicy mergePolicy) {
- this(opDesc, ctx, partition, DEFAULT_MEM_PAGE_SIZE, DEFAULT_MEM_NUM_PAGES, btreeComparatorFactories,
- valueProviderFactories, flushPolicy, mergePolicy);
+ IPrimitiveValueProviderFactory[] valueProviderFactories, RTreePolicyType rtreePolicyType,
+ ILSMFlushPolicy flushPolicy, ILSMMergePolicy mergePolicy) {
+ super(opDesc, ctx, partition, btreeComparatorFactories, valueProviderFactories, rtreePolicyType, flushPolicy,
+ mergePolicy);
}
- public LSMRTreeDataflowHelper(IIndexOperatorDescriptor opDesc, IHyracksTaskContext ctx, int partition,
- int memPageSize, int memNumPages, IBinaryComparatorFactory[] btreeComparatorFactories,
- IPrimitiveValueProviderFactory[] valueProviderFactories, ILSMFlushPolicy flushPolicy,
- ILSMMergePolicy mergePolicy) {
- super(opDesc, ctx, partition);
- this.memPageSize = memPageSize;
- this.memNumPages = memNumPages;
- this.btreeComparatorFactories = btreeComparatorFactories;
- this.valueProviderFactories = valueProviderFactories;
- this.flushPolicy = flushPolicy;
- this.mergePolicy = mergePolicy;
+ public LSMRTreeDataflowHelper(IIndexOperatorDescriptor opDesc, IHyracksTaskContext ctx,
+ IOperationCallbackProvider opCallbackProvider, int partition, boolean createIfNotExists, int memPageSize,
+ int memNumPages, IBinaryComparatorFactory[] btreeComparatorFactories,
+ IPrimitiveValueProviderFactory[] valueProviderFactories, RTreePolicyType rtreePolicyType,
+ ILSMFlushPolicy flushPolicy, ILSMMergePolicy mergePolicy) {
+ super(opDesc, ctx, opCallbackProvider, partition, createIfNotExists, memPageSize, memNumPages,
+ btreeComparatorFactories, valueProviderFactories, rtreePolicyType, flushPolicy, mergePolicy);
}
@Override
- public ITreeIndex createIndexInstance() throws HyracksDataException {
- ITreeIndexMetaDataFrameFactory metaDataFrameFactory = new LIFOMetaDataFrameFactory();
- InMemoryBufferCache memBufferCache = new LSMRTreeInMemoryBufferCache(new HeapBufferAllocator(), memPageSize,
- memNumPages);
- IFileSplitProvider fileSplitProvider = opDesc.getFileSplitProvider();
- FileReference file = fileSplitProvider.getFileSplits()[partition].getLocalFile();
- if (file.getFile().exists() && !file.getFile().isDirectory()) {
- file.delete();
+ protected ITreeIndex createLSMTree(IBufferCache memBufferCache, InMemoryFreePageManager memFreePageManager,
+ IIOManager ioManager, String onDiskDir, IBufferCache diskBufferCache, IFileMapProvider diskFileMapProvider,
+ ITypeTraits[] typeTraits, IBinaryComparatorFactory[] rtreeCmpFactories,
+ IBinaryComparatorFactory[] btreeCmpFactories, IPrimitiveValueProviderFactory[] valueProviderFactories,
+ RTreePolicyType rtreePolicyType) throws HyracksDataException {
+ try {
+ return LSMRTreeUtils.createLSMTree(memBufferCache, memFreePageManager, ioManager, onDiskDir,
+ diskBufferCache, diskFileMapProvider, typeTraits, rtreeCmpFactories, btreeCmpFactories,
+ valueProviderFactories, rtreePolicyType, flushPolicy, mergePolicy);
+ } catch (TreeIndexException e) {
+ throw new HyracksDataException(e);
}
- InMemoryFreePageManager memFreePageManager = new LSMRTreeInMemoryFreePageManager(memNumPages,
- metaDataFrameFactory);
- return LSMRTreeUtils.createLSMTree(memBufferCache, memFreePageManager, ctx.getIOManager(), file.getFile()
- .getPath(), opDesc.getStorageManager().getBufferCache(ctx), opDesc.getStorageManager()
- .getFileMapProvider(ctx), treeOpDesc.getTreeIndexTypeTraits(), treeOpDesc
- .getTreeIndexComparatorFactories(), btreeComparatorFactories, valueProviderFactories, flushPolicy,
- mergePolicy);
}
}
diff --git a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/dataflow/LSMRTreeDataflowHelperFactory.java b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/dataflow/LSMRTreeDataflowHelperFactory.java
index 47bd7bf..91ff2cb 100644
--- a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/dataflow/LSMRTreeDataflowHelperFactory.java
+++ b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/dataflow/LSMRTreeDataflowHelperFactory.java
@@ -23,6 +23,7 @@
import edu.uci.ics.hyracks.storage.am.common.dataflow.IndexDataflowHelper;
import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMFlushPolicyProvider;
import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMMergePolicyProvider;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
public class LSMRTreeDataflowHelperFactory implements IIndexDataflowHelperFactory {
@@ -30,14 +31,17 @@
private final IBinaryComparatorFactory[] btreeComparatorFactories;
private final IPrimitiveValueProviderFactory[] valueProviderFactories;
+ private final RTreePolicyType rtreePolicyType;
private final ILSMFlushPolicyProvider flushPolicyProvider;
private final ILSMMergePolicyProvider mergePolicyProvider;
public LSMRTreeDataflowHelperFactory(IPrimitiveValueProviderFactory[] valueProviderFactories,
- IBinaryComparatorFactory[] btreeComparatorFactories, ILSMFlushPolicyProvider flushPolicyProvider,
+ RTreePolicyType rtreePolicyType, IBinaryComparatorFactory[] btreeComparatorFactories,
+ ILSMFlushPolicyProvider flushPolicyProvider,
ILSMMergePolicyProvider mergePolicyProvider) {
this.btreeComparatorFactories = btreeComparatorFactories;
this.valueProviderFactories = valueProviderFactories;
+ this.rtreePolicyType = rtreePolicyType;
this.flushPolicyProvider = flushPolicyProvider;
this.mergePolicyProvider = mergePolicyProvider;
}
@@ -46,6 +50,6 @@
public IndexDataflowHelper createIndexDataflowHelper(IIndexOperatorDescriptor opDesc, IHyracksTaskContext ctx,
int partition) {
return new LSMRTreeDataflowHelper(opDesc, ctx, partition, btreeComparatorFactories, valueProviderFactories,
- flushPolicyProvider.getFlushPolicy(), mergePolicyProvider.getMergePolicy());
+ rtreePolicyType, flushPolicyProvider.getFlushPolicy(), mergePolicyProvider.getMergePolicy());
}
}
diff --git a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/dataflow/LSMRTreeWithAntiMatterTuplesDataflowHelper.java b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/dataflow/LSMRTreeWithAntiMatterTuplesDataflowHelper.java
new file mode 100644
index 0000000..f8b9dfa
--- /dev/null
+++ b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/dataflow/LSMRTreeWithAntiMatterTuplesDataflowHelper.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package edu.uci.ics.hyracks.storage.am.lsm.rtree.dataflow;
+
+import edu.uci.ics.hyracks.api.context.IHyracksTaskContext;
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparatorFactory;
+import edu.uci.ics.hyracks.api.dataflow.value.ITypeTraits;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.api.io.IIOManager;
+import edu.uci.ics.hyracks.storage.am.common.api.IOperationCallbackProvider;
+import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
+import edu.uci.ics.hyracks.storage.am.common.api.TreeIndexException;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexOperatorDescriptor;
+import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMFlushPolicy;
+import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMMergePolicy;
+import edu.uci.ics.hyracks.storage.am.lsm.common.freepage.InMemoryFreePageManager;
+import edu.uci.ics.hyracks.storage.am.lsm.rtree.utils.LSMRTreeUtils;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
+import edu.uci.ics.hyracks.storage.common.buffercache.IBufferCache;
+import edu.uci.ics.hyracks.storage.common.file.IFileMapProvider;
+
+public class LSMRTreeWithAntiMatterTuplesDataflowHelper extends AbstractLSMRTreeDataflowHelper {
+ public LSMRTreeWithAntiMatterTuplesDataflowHelper(IIndexOperatorDescriptor opDesc, IHyracksTaskContext ctx,
+ int partition, IBinaryComparatorFactory[] btreeComparatorFactories,
+ IPrimitiveValueProviderFactory[] valueProviderFactories, RTreePolicyType rtreePolicyType,
+ ILSMFlushPolicy flushPolicy, ILSMMergePolicy mergePolicy) {
+ super(opDesc, ctx, partition, btreeComparatorFactories, valueProviderFactories, rtreePolicyType, flushPolicy, mergePolicy);
+ }
+
+ public LSMRTreeWithAntiMatterTuplesDataflowHelper(IIndexOperatorDescriptor opDesc, IHyracksTaskContext ctx,
+ IOperationCallbackProvider opCallbackProvider, int partition, boolean createIfNotExists, int memPageSize,
+ int memNumPages, IBinaryComparatorFactory[] btreeComparatorFactories,
+ IPrimitiveValueProviderFactory[] valueProviderFactories, RTreePolicyType rtreePolicyType,
+ ILSMFlushPolicy flushPolicy, ILSMMergePolicy mergePolicy) {
+ super(opDesc, ctx, opCallbackProvider, partition, createIfNotExists, memPageSize, memNumPages,
+ btreeComparatorFactories, valueProviderFactories, rtreePolicyType, flushPolicy, mergePolicy);
+ }
+
+ @Override
+ protected ITreeIndex createLSMTree(IBufferCache memBufferCache, InMemoryFreePageManager memFreePageManager,
+ IIOManager ioManager, String onDiskDir, IBufferCache diskBufferCache, IFileMapProvider diskFileMapProvider,
+ ITypeTraits[] typeTraits, IBinaryComparatorFactory[] rtreeCmpFactories,
+ IBinaryComparatorFactory[] btreeCmpFactories, IPrimitiveValueProviderFactory[] valueProviderFactories,
+ RTreePolicyType rtreePolicyType) throws HyracksDataException {
+ try {
+ return LSMRTreeUtils.createLSMTreeWithAntiMatterTuples(memBufferCache, memFreePageManager, ioManager,
+ onDiskDir, diskBufferCache, diskFileMapProvider, typeTraits, rtreeCmpFactories, btreeCmpFactories,
+ valueProviderFactories, rtreePolicyType, flushPolicy, mergePolicy);
+ } catch (TreeIndexException e) {
+ throw new HyracksDataException(e);
+ }
+ }
+}
diff --git a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/dataflow/LSMRTreeWithAntiMatterTuplesDataflowHelperFactory.java b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/dataflow/LSMRTreeWithAntiMatterTuplesDataflowHelperFactory.java
new file mode 100644
index 0000000..5fc49a9
--- /dev/null
+++ b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/dataflow/LSMRTreeWithAntiMatterTuplesDataflowHelperFactory.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package edu.uci.ics.hyracks.storage.am.lsm.rtree.dataflow;
+
+import edu.uci.ics.hyracks.api.context.IHyracksTaskContext;
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparatorFactory;
+import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexDataflowHelperFactory;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexOperatorDescriptor;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IndexDataflowHelper;
+import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMFlushPolicyProvider;
+import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMMergePolicyProvider;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
+
+public class LSMRTreeWithAntiMatterTuplesDataflowHelperFactory implements IIndexDataflowHelperFactory {
+
+ private static final long serialVersionUID = 1L;
+
+ private final IBinaryComparatorFactory[] btreeComparatorFactories;
+ private final IPrimitiveValueProviderFactory[] valueProviderFactories;
+ private final RTreePolicyType rtreePolicyType;
+ private final ILSMFlushPolicyProvider flushPolicyProvider;
+ private final ILSMMergePolicyProvider mergePolicyProvider;
+
+ public LSMRTreeWithAntiMatterTuplesDataflowHelperFactory(IPrimitiveValueProviderFactory[] valueProviderFactories,
+ RTreePolicyType rtreePolicyType, IBinaryComparatorFactory[] btreeComparatorFactories,
+ ILSMFlushPolicyProvider flushPolicyProvider,
+ ILSMMergePolicyProvider mergePolicyProvider) {
+ this.btreeComparatorFactories = btreeComparatorFactories;
+ this.valueProviderFactories = valueProviderFactories;
+ this.rtreePolicyType = rtreePolicyType;
+ this.flushPolicyProvider = flushPolicyProvider;
+ this.mergePolicyProvider = mergePolicyProvider;
+ }
+
+ @Override
+ public IndexDataflowHelper createIndexDataflowHelper(IIndexOperatorDescriptor opDesc, IHyracksTaskContext ctx,
+ int partition) {
+ return new LSMRTreeWithAntiMatterTuplesDataflowHelper(opDesc, ctx, partition, btreeComparatorFactories,
+ valueProviderFactories, rtreePolicyType, flushPolicyProvider.getFlushPolicy(), mergePolicyProvider.getMergePolicy());
+ }
+}
diff --git a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/AbstractLSMRTree.java b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/AbstractLSMRTree.java
new file mode 100644
index 0000000..7e61d2e
--- /dev/null
+++ b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/AbstractLSMRTree.java
@@ -0,0 +1,345 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package edu.uci.ics.hyracks.storage.am.lsm.rtree.impls;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparatorFactory;
+import edu.uci.ics.hyracks.api.dataflow.value.ILinearizeComparatorFactory;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.api.io.FileReference;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
+import edu.uci.ics.hyracks.storage.am.btree.exceptions.BTreeDuplicateKeyException;
+import edu.uci.ics.hyracks.storage.am.btree.exceptions.BTreeNonExistentKeyException;
+import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
+import edu.uci.ics.hyracks.storage.am.btree.impls.RangePredicate;
+import edu.uci.ics.hyracks.storage.am.common.api.IFreePageManager;
+import edu.uci.ics.hyracks.storage.am.common.api.IIndexBulkLoadContext;
+import edu.uci.ics.hyracks.storage.am.common.api.IIndexOpContext;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexBulkLoader;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexCursor;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrameFactory;
+import edu.uci.ics.hyracks.storage.am.common.api.IndexType;
+import edu.uci.ics.hyracks.storage.am.common.api.TreeIndexException;
+import edu.uci.ics.hyracks.storage.am.common.impls.NoOpOperationCallback;
+import edu.uci.ics.hyracks.storage.am.common.ophelpers.IndexOp;
+import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMComponentFinalizer;
+import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMFileManager;
+import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMFlushPolicy;
+import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMIndex;
+import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMMergePolicy;
+import edu.uci.ics.hyracks.storage.am.lsm.common.freepage.InMemoryFreePageManager;
+import edu.uci.ics.hyracks.storage.am.lsm.common.impls.LSMHarness;
+import edu.uci.ics.hyracks.storage.am.lsm.common.impls.TreeFactory;
+import edu.uci.ics.hyracks.storage.am.rtree.api.IRTreeInteriorFrame;
+import edu.uci.ics.hyracks.storage.am.rtree.api.IRTreeLeafFrame;
+import edu.uci.ics.hyracks.storage.am.rtree.impls.RTree;
+import edu.uci.ics.hyracks.storage.common.buffercache.IBufferCache;
+import edu.uci.ics.hyracks.storage.common.file.IFileMapProvider;
+
+public abstract class AbstractLSMRTree implements ILSMIndex, ITreeIndex {
+
+ public class LSMRTreeComponent {
+ private final RTree rtree;
+ private final BTree btree;
+
+ LSMRTreeComponent(RTree rtree, BTree btree) {
+ this.rtree = rtree;
+ this.btree = btree;
+ }
+
+ public RTree getRTree() {
+ return rtree;
+ }
+
+ public BTree getBTree() {
+ return btree;
+ }
+ }
+
+ protected final LSMHarness lsmHarness;
+
+ protected final ILinearizeComparatorFactory linearizer;
+ protected final int[] comparatorFields;
+ protected final IBinaryComparatorFactory[] linearizerArray;
+
+ // In-memory components.
+ protected final LSMRTreeComponent memComponent;
+ protected final InMemoryFreePageManager memFreePageManager;
+ protected final static int MEM_RTREE_FILE_ID = 0;
+ protected final static int MEM_BTREE_FILE_ID = 1;
+
+ // This is used to estimate number of tuples in the memory RTree and BTree
+ // for efficient memory allocation in the sort operation prior to flushing
+ protected int memRTreeTuples = 0;
+ protected int memBTreeTuples = 0;
+ protected TreeTupleSorter rTreeTupleSorter = null;
+
+ // On-disk components.
+ protected final ILSMFileManager fileManager;
+ protected final IBufferCache diskBufferCache;
+ protected final IFileMapProvider diskFileMapProvider;
+ // For creating RTree's used in flush and merge.
+ protected final RTreeFactory diskRTreeFactory;
+ // List of LSMRTreeComponent instances. Using Object for better sharing via
+ // ILSMTree + LSMHarness.
+ protected final LinkedList<Object> diskComponents = new LinkedList<Object>();
+ // Helps to guarantees physical consistency of LSM components.
+ protected final ILSMComponentFinalizer componentFinalizer;
+
+ private IBinaryComparatorFactory[] btreeCmpFactories;
+ private IBinaryComparatorFactory[] rtreeCmpFactories;
+
+ // Common for in-memory and on-disk components.
+ protected final ITreeIndexFrameFactory rtreeInteriorFrameFactory;
+ protected final ITreeIndexFrameFactory btreeInteriorFrameFactory;
+ protected final ITreeIndexFrameFactory rtreeLeafFrameFactory;
+ protected final ITreeIndexFrameFactory btreeLeafFrameFactory;
+
+ public AbstractLSMRTree(IBufferCache memBufferCache, InMemoryFreePageManager memFreePageManager,
+ ITreeIndexFrameFactory rtreeInteriorFrameFactory, ITreeIndexFrameFactory rtreeLeafFrameFactory,
+ ITreeIndexFrameFactory btreeInteriorFrameFactory, ITreeIndexFrameFactory btreeLeafFrameFactory,
+ ILSMFileManager fileManager, RTreeFactory diskRTreeFactory, IFileMapProvider diskFileMapProvider,
+ ILSMComponentFinalizer componentFinalizer, int fieldCount, IBinaryComparatorFactory[] rtreeCmpFactories,
+ IBinaryComparatorFactory[] btreeCmpFactories, ILinearizeComparatorFactory linearizer,
+ int[] comparatorFields, IBinaryComparatorFactory[] linearizerArray, ILSMFlushPolicy flushPolicy, ILSMMergePolicy mergePolicy) {
+ RTree memRTree = new RTree(memBufferCache, fieldCount, rtreeCmpFactories, memFreePageManager,
+ rtreeInteriorFrameFactory, rtreeLeafFrameFactory);
+ // TODO: Do we need another operation callback here?
+ BTree memBTree = new BTree(memBufferCache, fieldCount, btreeCmpFactories,
+ memFreePageManager, btreeInteriorFrameFactory, btreeLeafFrameFactory);
+ memComponent = new LSMRTreeComponent(memRTree, memBTree);
+ this.memFreePageManager = memFreePageManager;
+ this.diskBufferCache = diskRTreeFactory.getBufferCache();
+ this.diskFileMapProvider = diskFileMapProvider;
+ this.fileManager = fileManager;
+ this.rtreeInteriorFrameFactory = rtreeInteriorFrameFactory;
+ this.rtreeLeafFrameFactory = rtreeLeafFrameFactory;
+ this.btreeInteriorFrameFactory = btreeInteriorFrameFactory;
+ this.btreeLeafFrameFactory = btreeLeafFrameFactory;
+ this.diskRTreeFactory = diskRTreeFactory;
+ this.btreeCmpFactories = btreeCmpFactories;
+ this.rtreeCmpFactories = rtreeCmpFactories;
+ this.lsmHarness = new LSMHarness(this, flushPolicy, mergePolicy);
+ this.componentFinalizer = componentFinalizer;
+ this.linearizer = linearizer;
+ this.comparatorFields = comparatorFields;
+ this.linearizerArray = linearizerArray;
+ }
+
+ @Override
+ public void create(int indexFileId) throws HyracksDataException {
+ memComponent.getRTree().create(MEM_RTREE_FILE_ID);
+ memComponent.getBTree().create(MEM_BTREE_FILE_ID);
+ fileManager.createDirs();
+ }
+
+ @Override
+ public void open(int indexFileId) throws HyracksDataException {
+ memComponent.getRTree().open(MEM_RTREE_FILE_ID);
+ memComponent.getBTree().open(MEM_BTREE_FILE_ID);
+ }
+
+ @Override
+ public void close() throws HyracksDataException {
+ memComponent.getRTree().close();
+ memComponent.getBTree().close();
+ }
+
+ @SuppressWarnings("rawtypes")
+ protected ITreeIndex createDiskTree(TreeFactory diskTreeFactory, FileReference fileRef, boolean createTree)
+ throws HyracksDataException {
+ // File will be deleted during cleanup of merge().
+ diskBufferCache.createFile(fileRef);
+ int diskTreeFileId = diskFileMapProvider.lookupFileId(fileRef);
+ // File will be closed during cleanup of merge().
+ diskBufferCache.openFile(diskTreeFileId);
+ // Create new tree instance.
+ ITreeIndex diskTree = diskTreeFactory.createIndexInstance();
+ if (createTree) {
+ diskTree.create(diskTreeFileId);
+ }
+ // Tree will be closed during cleanup of merge().
+ diskTree.open(diskTreeFileId);
+ return diskTree;
+ }
+
+ @Deprecated
+ private ITreeIndexBulkLoader bulkloader;
+
+ @Override
+ public IIndexBulkLoadContext beginBulkLoad(float fillFactor) throws TreeIndexException, HyracksDataException {
+ bulkloader = createBulkLoader(fillFactor);
+ return null;
+ }
+
+ @Override
+ public void bulkLoadAddTuple(ITupleReference tuple, IIndexBulkLoadContext ictx) throws HyracksDataException {
+ bulkloader.add(tuple);
+ }
+
+ @Override
+ public void endBulkLoad(IIndexBulkLoadContext ictx) throws HyracksDataException {
+ bulkloader.end();
+ }
+
+ @Override
+ public ITreeIndexFrameFactory getLeafFrameFactory() {
+ return memComponent.getRTree().getLeafFrameFactory();
+ }
+
+ @Override
+ public ITreeIndexFrameFactory getInteriorFrameFactory() {
+ return memComponent.getRTree().getInteriorFrameFactory();
+ }
+
+ @Override
+ public IFreePageManager getFreePageManager() {
+ return memComponent.getRTree().getFreePageManager();
+ }
+
+ @Override
+ public int getFieldCount() {
+ return memComponent.getRTree().getFieldCount();
+ }
+
+ @Override
+ public int getRootPageId() {
+ return memComponent.getRTree().getRootPageId();
+ }
+
+ @Override
+ public IndexType getIndexType() {
+ return memComponent.getRTree().getIndexType();
+ }
+
+ @Override
+ public int getFileId() {
+ return memComponent.getRTree().getFileId();
+ }
+
+ public boolean insertUpdateOrDelete(ITupleReference tuple, IIndexOpContext ictx) throws HyracksDataException,
+ TreeIndexException {
+ LSMRTreeOpContext ctx = (LSMRTreeOpContext) ictx;
+ if (ctx.getIndexOp() == IndexOp.PHYSICALDELETE) {
+ throw new UnsupportedOperationException("Physical delete not yet supported in LSM R-tree");
+ }
+
+ if (ctx.getIndexOp() == IndexOp.INSERT) {
+ // Before each insert, we must check whether there exist a killer
+ // tuple in the memBTree. If we find a killer tuple, we must truly
+ // delete the existing tuple from the BTree, and then insert it to
+ // memRTree. Otherwise, the old killer tuple will kill the newly
+ // added RTree tuple.
+ RangePredicate btreeRangePredicate = new RangePredicate(tuple, tuple, true, true,
+ ctx.getBTreeMultiComparator(), ctx.getBTreeMultiComparator());
+ ITreeIndexCursor cursor = ctx.memBTreeAccessor.createSearchCursor();
+ ctx.memBTreeAccessor.search(cursor, btreeRangePredicate);
+ boolean foundTupleInMemoryBTree = false;
+ try {
+ if (cursor.hasNext()) {
+ foundTupleInMemoryBTree = true;
+ }
+ } finally {
+ cursor.close();
+ }
+ if (foundTupleInMemoryBTree) {
+ try {
+ ctx.memBTreeAccessor.delete(tuple);
+ memBTreeTuples--;
+ } catch (BTreeNonExistentKeyException e) {
+ // Tuple has been deleted in the meantime. Do nothing.
+ // This normally shouldn't happen if we are dealing with
+ // good citizens since LSMRTree is used as a secondary
+ // index and a tuple shouldn't be deleted twice without
+ // insert between them.
+ }
+ } else {
+ ctx.memRTreeAccessor.insert(tuple);
+ memRTreeTuples++;
+ }
+
+ } else {
+ try {
+ ctx.memBTreeAccessor.insert(tuple);
+ memBTreeTuples++;
+ } catch (BTreeDuplicateKeyException e) {
+ // Do nothing, because one delete tuple is enough to indicate
+ // that all the corresponding insert tuples are deleted
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public void addMergedComponent(Object newComponent, List<Object> mergedComponents) {
+ diskComponents.removeAll(mergedComponents);
+ diskComponents.addLast(newComponent);
+ }
+
+ @Override
+ public void addFlushedComponent(Object index) {
+ diskComponents.addFirst(index);
+ }
+
+ @Override
+ public InMemoryFreePageManager getInMemoryFreePageManager() {
+ return memFreePageManager;
+ }
+
+ @Override
+ public void resetInMemoryComponent() throws HyracksDataException {
+ memComponent.getRTree().create(MEM_RTREE_FILE_ID);
+ memComponent.getBTree().create(MEM_BTREE_FILE_ID);
+ memFreePageManager.reset();
+ memRTreeTuples = 0;
+ memBTreeTuples = 0;
+ }
+
+ @Override
+ public List<Object> getDiskComponents() {
+ return diskComponents;
+ }
+
+ protected LSMRTreeOpContext createOpContext() {
+ return new LSMRTreeOpContext((RTree.RTreeAccessor) memComponent.getRTree().createAccessor(
+ NoOpOperationCallback.INSTANCE, NoOpOperationCallback.INSTANCE),
+ (IRTreeLeafFrame) rtreeLeafFrameFactory.createFrame(),
+ (IRTreeInteriorFrame) rtreeInteriorFrameFactory.createFrame(), memFreePageManager
+ .getMetaDataFrameFactory().createFrame(), 8, (BTree.BTreeAccessor) memComponent.getBTree()
+ .createAccessor(NoOpOperationCallback.INSTANCE, NoOpOperationCallback.INSTANCE),
+ btreeLeafFrameFactory, btreeInteriorFrameFactory, memFreePageManager.getMetaDataFrameFactory()
+ .createFrame(), rtreeCmpFactories, btreeCmpFactories, null, null);
+ }
+
+ @Override
+ public IBinaryComparatorFactory[] getComparatorFactories() {
+ return rtreeCmpFactories;
+ }
+
+ @Override
+ public IBufferCache getBufferCache() {
+ return diskBufferCache;
+ }
+
+ @Override
+ public ILSMComponentFinalizer getComponentFinalizer() {
+ return componentFinalizer;
+ }
+
+}
diff --git a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTree.java b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTree.java
index 2f9f954..2528d3d 100644
--- a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTree.java
+++ b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTree.java
@@ -16,20 +16,17 @@
package edu.uci.ics.hyracks.storage.am.lsm.rtree.impls;
import java.io.File;
-import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.concurrent.atomic.AtomicInteger;
import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparatorFactory;
+import edu.uci.ics.hyracks.api.dataflow.value.ILinearizeComparatorFactory;
import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
import edu.uci.ics.hyracks.api.io.FileReference;
import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
-import edu.uci.ics.hyracks.storage.am.btree.exceptions.BTreeDuplicateKeyException;
-import edu.uci.ics.hyracks.storage.am.btree.exceptions.BTreeNonExistentKeyException;
import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
import edu.uci.ics.hyracks.storage.am.btree.impls.RangePredicate;
-import edu.uci.ics.hyracks.storage.am.common.api.IFreePageManager;
import edu.uci.ics.hyracks.storage.am.common.api.IIndexAccessor;
import edu.uci.ics.hyracks.storage.am.common.api.IIndexBulkLoadContext;
import edu.uci.ics.hyracks.storage.am.common.api.IIndexCursor;
@@ -37,124 +34,47 @@
import edu.uci.ics.hyracks.storage.am.common.api.IModificationOperationCallback;
import edu.uci.ics.hyracks.storage.am.common.api.ISearchOperationCallback;
import edu.uci.ics.hyracks.storage.am.common.api.ISearchPredicate;
-import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexAccessor;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexBulkLoader;
import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexCursor;
import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrameFactory;
import edu.uci.ics.hyracks.storage.am.common.api.IndexException;
-import edu.uci.ics.hyracks.storage.am.common.api.IndexType;
import edu.uci.ics.hyracks.storage.am.common.api.TreeIndexException;
import edu.uci.ics.hyracks.storage.am.common.impls.NoOpOperationCallback;
-import edu.uci.ics.hyracks.storage.am.common.ophelpers.IndexOp;
import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
-import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMComponentFinalizer;
import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMFileManager;
import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMFlushPolicy;
-import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMIndex;
import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMMergePolicy;
import edu.uci.ics.hyracks.storage.am.lsm.common.freepage.InMemoryFreePageManager;
import edu.uci.ics.hyracks.storage.am.lsm.common.impls.BTreeFactory;
import edu.uci.ics.hyracks.storage.am.lsm.common.impls.LSMHarness;
import edu.uci.ics.hyracks.storage.am.lsm.common.impls.LSMTreeIndexAccessor;
-import edu.uci.ics.hyracks.storage.am.lsm.common.impls.TreeFactory;
import edu.uci.ics.hyracks.storage.am.lsm.rtree.impls.LSMRTreeFileManager.LSMRTreeFileNameComponent;
-import edu.uci.ics.hyracks.storage.am.rtree.api.IRTreeInteriorFrame;
-import edu.uci.ics.hyracks.storage.am.rtree.api.IRTreeLeafFrame;
import edu.uci.ics.hyracks.storage.am.rtree.impls.RTree;
+import edu.uci.ics.hyracks.storage.am.rtree.impls.RTree.RTreeBulkLoader;
import edu.uci.ics.hyracks.storage.am.rtree.impls.RTreeSearchCursor;
import edu.uci.ics.hyracks.storage.am.rtree.impls.SearchPredicate;
import edu.uci.ics.hyracks.storage.common.buffercache.IBufferCache;
import edu.uci.ics.hyracks.storage.common.file.IFileMapProvider;
-public class LSMRTree implements ILSMIndex, ITreeIndex {
-
- public class LSMRTreeComponent {
- private final RTree rtree;
- private final BTree btree;
-
- LSMRTreeComponent(RTree rtree, BTree btree) {
- this.rtree = rtree;
- this.btree = btree;
- }
-
- public RTree getRTree() {
- return rtree;
- }
-
- public BTree getBTree() {
- return btree;
- }
- }
-
- private final LSMHarness lsmHarness;
-
- // In-memory components.
- private final LSMRTreeComponent memComponent;
- protected final InMemoryFreePageManager memFreePageManager;
- private final static int MEM_RTREE_FILE_ID = 0;
- private final static int MEM_BTREE_FILE_ID = 1;
-
- // This is used to estimate number of tuples in the memory RTree for
- // efficient memory allocation in the sort operation prior to flushing
- private int memRTreeTuples = 0;
- private RTreeTupleSorter rTreeTupleSorter = null;
+public class LSMRTree extends AbstractLSMRTree {
// On-disk components.
- private final ILSMFileManager fileManager;
- protected final IBufferCache diskBufferCache;
- protected final IFileMapProvider diskFileMapProvider;
- // For creating RTree's used in flush and merge.
- private final RTreeFactory diskRTreeFactory;
// For creating BTree's used in flush and merge.
private final BTreeFactory diskBTreeFactory;
- // List of LSMRTreeComponent instances. Using Object for better sharing via
- // ILSMTree + LSMHarness.
- private final LinkedList<Object> diskComponents = new LinkedList<Object>();
- // Helps to guarantees physical consistency of LSM components.
- private final ILSMComponentFinalizer componentFinalizer;
-
- private IBinaryComparatorFactory[] btreeCmpFactories;
- private IBinaryComparatorFactory[] rtreeCmpFactories;
-
- // Common for in-memory and on-disk components.
- private final ITreeIndexFrameFactory rtreeInteriorFrameFactory;
- private final ITreeIndexFrameFactory btreeInteriorFrameFactory;
- private final ITreeIndexFrameFactory rtreeLeafFrameFactory;
- private final ITreeIndexFrameFactory btreeLeafFrameFactory;
public LSMRTree(IBufferCache memBufferCache, InMemoryFreePageManager memFreePageManager,
ITreeIndexFrameFactory rtreeInteriorFrameFactory, ITreeIndexFrameFactory rtreeLeafFrameFactory,
ITreeIndexFrameFactory btreeInteriorFrameFactory, ITreeIndexFrameFactory btreeLeafFrameFactory,
ILSMFileManager fileManager, RTreeFactory diskRTreeFactory, BTreeFactory diskBTreeFactory,
IFileMapProvider diskFileMapProvider, int fieldCount, IBinaryComparatorFactory[] rtreeCmpFactories,
- IBinaryComparatorFactory[] btreeCmpFactories, ILSMFlushPolicy flushPolicy, ILSMMergePolicy mergePolicy) {
- RTree memRTree = new RTree(memBufferCache, fieldCount, rtreeCmpFactories, memFreePageManager,
- rtreeInteriorFrameFactory, rtreeLeafFrameFactory);
- // TODO: Do we need another operation callback here?
- BTree memBTree = new BTree(memBufferCache, fieldCount, btreeCmpFactories, memFreePageManager,
- btreeInteriorFrameFactory, btreeLeafFrameFactory);
- memComponent = new LSMRTreeComponent(memRTree, memBTree);
- this.memFreePageManager = memFreePageManager;
- this.diskBufferCache = diskBTreeFactory.getBufferCache();
- this.diskFileMapProvider = diskFileMapProvider;
+ IBinaryComparatorFactory[] btreeCmpFactories, ILinearizeComparatorFactory linearizer,
+ int[] comparatorFields, IBinaryComparatorFactory[] linearizerArray, ILSMFlushPolicy flushPolicy, ILSMMergePolicy mergePolicy) {
+ super(memBufferCache, memFreePageManager, rtreeInteriorFrameFactory, rtreeLeafFrameFactory,
+ btreeInteriorFrameFactory, btreeLeafFrameFactory, fileManager, diskRTreeFactory, diskFileMapProvider,
+ new LSMRTreeComponentFinalizer(diskFileMapProvider), fieldCount, rtreeCmpFactories, btreeCmpFactories,
+ linearizer, comparatorFields, linearizerArray, flushPolicy, mergePolicy);
this.diskBTreeFactory = diskBTreeFactory;
- this.fileManager = fileManager;
- this.rtreeInteriorFrameFactory = rtreeInteriorFrameFactory;
- this.rtreeLeafFrameFactory = rtreeLeafFrameFactory;
- this.btreeInteriorFrameFactory = btreeInteriorFrameFactory;
- this.btreeLeafFrameFactory = btreeLeafFrameFactory;
- this.diskRTreeFactory = diskRTreeFactory;
- this.btreeCmpFactories = btreeCmpFactories;
- this.rtreeCmpFactories = rtreeCmpFactories;
- this.lsmHarness = new LSMHarness(this, flushPolicy, mergePolicy);
- componentFinalizer = new LSMRTreeComponentFinalizer(diskFileMapProvider);
- }
-
- @Override
- public void create(int indexFileId) throws HyracksDataException {
- memComponent.getRTree().create(MEM_RTREE_FILE_ID);
- memComponent.getBTree().create(MEM_BTREE_FILE_ID);
- fileManager.createDirs();
}
/**
@@ -167,8 +87,7 @@
*/
@Override
public void open(int indexFileId) throws HyracksDataException {
- memComponent.getRTree().open(MEM_RTREE_FILE_ID);
- memComponent.getBTree().open(MEM_BTREE_FILE_ID);
+ super.open(indexFileId);
RTree dummyRTree = diskRTreeFactory.createIndexInstance();
BTree dummyBTree = diskBTreeFactory.createIndexInstance();
LSMRTreeComponent dummyComponent = new LSMRTreeComponent(dummyRTree, dummyBTree);
@@ -198,8 +117,7 @@
btree.close();
}
diskComponents.clear();
- memComponent.getRTree().close();
- memComponent.getBTree().close();
+ super.close();
}
private LSMRTreeFileNameComponent getMergeTargetFileName(List<Object> mergingDiskTrees) throws HyracksDataException {
@@ -212,151 +130,6 @@
return component;
}
- @SuppressWarnings("rawtypes")
- protected ITreeIndex createDiskTree(TreeFactory diskTreeFactory, FileReference fileRef, boolean createTree)
- throws HyracksDataException {
- // File will be deleted during cleanup of merge().
- diskBufferCache.createFile(fileRef);
- int diskTreeFileId = diskFileMapProvider.lookupFileId(fileRef);
- // File will be closed during cleanup of merge().
- diskBufferCache.openFile(diskTreeFileId);
- // Create new tree instance.
- ITreeIndex diskTree = diskTreeFactory.createIndexInstance();
- if (createTree) {
- diskTree.create(diskTreeFileId);
- }
- // Tree will be closed during cleanup of merge().
- diskTree.open(diskTreeFileId);
- return diskTree;
- }
-
- @Override
- public IIndexBulkLoadContext beginBulkLoad(float fillFactor) throws TreeIndexException, HyracksDataException {
- // Note that by using a flush target file name, we state that the new
- // bulk loaded tree is "newer" than any other merged tree.
- LSMRTreeFileNameComponent fileNames = (LSMRTreeFileNameComponent) fileManager.getRelFlushFileName();
- FileReference rtreeFile = fileManager.createFlushFile(fileNames.getRTreeFileName());
- RTree diskRTree = (RTree) createDiskTree(diskRTreeFactory, rtreeFile, true);
- // For each RTree, we require to have a buddy BTree. thus, we create an
- // empty BTree.
- FileReference btreeFile = fileManager.createFlushFile(fileNames.getBTreeFileName());
- BTree diskBTree = (BTree) createDiskTree(diskBTreeFactory, btreeFile, true);
- LSMRTreeBulkLoadContext bulkLoadCtx = new LSMRTreeBulkLoadContext(diskRTree, diskBTree);
- bulkLoadCtx.beginBulkLoad(fillFactor);
- return bulkLoadCtx;
- }
-
- @Override
- public void bulkLoadAddTuple(ITupleReference tuple, IIndexBulkLoadContext ictx) throws HyracksDataException {
- LSMRTreeBulkLoadContext bulkLoadCtx = (LSMRTreeBulkLoadContext) ictx;
- bulkLoadCtx.getRTree().bulkLoadAddTuple(tuple, bulkLoadCtx.getBulkLoadCtx());
- }
-
- @Override
- public void endBulkLoad(IIndexBulkLoadContext ictx) throws HyracksDataException {
- LSMRTreeBulkLoadContext bulkLoadCtx = (LSMRTreeBulkLoadContext) ictx;
- bulkLoadCtx.getRTree().endBulkLoad(bulkLoadCtx.getBulkLoadCtx());
- LSMRTreeComponent diskComponent = new LSMRTreeComponent(bulkLoadCtx.getRTree(), bulkLoadCtx.getBTree());
- lsmHarness.addBulkLoadedComponent(diskComponent);
- }
-
- @Override
- public ITreeIndexFrameFactory getLeafFrameFactory() {
- return memComponent.getRTree().getLeafFrameFactory();
- }
-
- @Override
- public ITreeIndexFrameFactory getInteriorFrameFactory() {
- return memComponent.getRTree().getInteriorFrameFactory();
- }
-
- @Override
- public IFreePageManager getFreePageManager() {
- return memComponent.getRTree().getFreePageManager();
- }
-
- @Override
- public int getFieldCount() {
- return memComponent.getRTree().getFieldCount();
- }
-
- @Override
- public int getRootPageId() {
- return memComponent.getRTree().getRootPageId();
- }
-
- @Override
- public IndexType getIndexType() {
- return memComponent.getRTree().getIndexType();
- }
-
- @Override
- public int getFileId() {
- return memComponent.getRTree().getFileId();
- }
-
- public boolean insertUpdateOrDelete(ITupleReference tuple, IIndexOpContext ictx) throws HyracksDataException,
- TreeIndexException {
- LSMRTreeOpContext ctx = (LSMRTreeOpContext) ictx;
- if (ctx.getIndexOp() == IndexOp.PHYSICALDELETE) {
- throw new UnsupportedOperationException("Physical delete not yet supported in LSM R-tree");
- }
-
- if (ctx.getIndexOp() == IndexOp.INSERT) {
- // Before each insert, we must check whether there exist a killer
- // tuple in the memBTree. If we find a killer tuple, we must truly
- // delete the existing tuple from the BTree, and then insert it to
- // memRTree. Otherwise, the old killer tuple will kill the newly
- // added RTree tuple.
- RangePredicate btreeRangePredicate = new RangePredicate(tuple, tuple, true, true,
- ctx.getBTreeMultiComparator(), ctx.getBTreeMultiComparator());
- ITreeIndexCursor cursor = ctx.memBTreeAccessor.createSearchCursor();
- ctx.memBTreeAccessor.search(cursor, btreeRangePredicate);
- boolean foundTupleInMemoryBTree = false;
- try {
- if (cursor.hasNext()) {
- foundTupleInMemoryBTree = true;
- }
- } finally {
- cursor.close();
- }
- if (foundTupleInMemoryBTree) {
- try {
- ctx.memBTreeAccessor.delete(tuple);
- } catch (BTreeNonExistentKeyException e) {
- // Tuple has been deleted in the meantime. Do nothing.
- // This normally shouldn't happen if we are dealing with
- // good citizens since LSMRTree is used as a secondary
- // index and a tuple shouldn't be deleted twice without
- // insert between them.
- }
- }
- ctx.memRTreeAccessor.insert(tuple);
- memRTreeTuples++;
-
- } else {
- // For each delete operation, we make sure that we run a true
- // in-memory RTree delete operation besides from inserting a delete
- // tuple in the in-memory BTree. The reason for running the RTree
- // delete operation is that to avoid the following scenario:
- // 1) Inserter inserts tupleA to the in-memory RTree.
- // 2) Deleter inserts tupleA to the in-memory BTree.
- // 3) Inserter inserts tupleA to the in-memory RTree.
- // Note that all the above operations happened before flushing the
- // in-memory trees Now, when we search using the LSMRTree search
- // cursor, it will return tupleA twice! which is not correct! Thus
- // we run a true RTree delete operation.
- ctx.memRTreeAccessor.delete(tuple);
- try {
- ctx.memBTreeAccessor.insert(tuple);
- } catch (BTreeDuplicateKeyException e) {
- // Do nothing, because one delete tuple is enough to indicate
- // that all the corresponding insert tuples are deleted
- }
- }
- return true;
- }
-
public void search(IIndexCursor cursor, List<Object> diskComponents, ISearchPredicate pred, IIndexOpContext ictx,
boolean includeMemComponent, AtomicInteger searcherRefCount) throws HyracksDataException, IndexException {
LSMRTreeOpContext ctx = (LSMRTreeOpContext) ictx;
@@ -384,11 +157,10 @@
diskTreeIx++;
}
- LSMRTreeSearchCursor lsmRTreeCursor = (LSMRTreeSearchCursor) cursor;
LSMRTreeCursorInitialState initialState = new LSMRTreeCursorInitialState(numTrees, rtreeLeafFrameFactory,
rtreeInteriorFrameFactory, btreeLeafFrameFactory, ctx.getBTreeMultiComparator(), rTreeAccessors,
- bTreeAccessors, searcherRefCount, includeMemComponent, lsmHarness, ctx.searchCallback);
- lsmRTreeCursor.open(initialState, pred);
+ bTreeAccessors, searcherRefCount, includeMemComponent, lsmHarness, comparatorFields, linearizerArray, ctx.searchCallback);
+ cursor.open(initialState, pred);
}
@Override
@@ -406,18 +178,25 @@
LSMRTreeFileNameComponent fileNames = (LSMRTreeFileNameComponent) fileManager.getRelFlushFileName();
FileReference rtreeFile = fileManager.createFlushFile(fileNames.getRTreeFileName());
RTree diskRTree = (RTree) createDiskTree(diskRTreeFactory, rtreeFile, true);
+ ITreeIndexBulkLoader rTreeBulkloader;
+ ITreeIndexCursor cursor;
+
+ IBinaryComparatorFactory[] linearizerArray = { linearizer };
if (rTreeTupleSorter == null) {
- // TODO: Pass the Hilbert cmps here
- rTreeTupleSorter = new RTreeTupleSorter(memRTreeTuples, MEM_RTREE_FILE_ID, rtreeCmpFactories,
+ rTreeTupleSorter = new TreeTupleSorter(memRTreeTuples, MEM_RTREE_FILE_ID, linearizerArray,
rtreeLeafFrameFactory.createFrame(), rtreeLeafFrameFactory.createFrame(), memComponent.getRTree()
- .getBufferCache());
+ .getBufferCache(), comparatorFields);
} else {
rTreeTupleSorter.reset();
}
- // BulkLoad the tuples from the in-memory tree into the new disk RTree.
- IIndexBulkLoadContext rtreeBulkLoadCtx = diskRTree.beginBulkLoad(1.0f);
+ // BulkLoad the tuples from the in-memory tree into the new disk
+ // RTree.
+ boolean isEmpty = true;
+ if (rtreeScanCursor.hasNext()) {
+ isEmpty = false;
+ }
try {
while (rtreeScanCursor.hasNext()) {
rtreeScanCursor.next();
@@ -426,18 +205,22 @@
} finally {
rtreeScanCursor.close();
}
- rTreeTupleSorter.sort();
+ if (!isEmpty) {
+ rTreeTupleSorter.sort();
+ }
+ rTreeBulkloader = diskRTree.createBulkLoader(1.0f);
+ cursor = rTreeTupleSorter;
try {
- while (rTreeTupleSorter.hasNext()) {
- rTreeTupleSorter.next();
- ITupleReference frameTuple = rTreeTupleSorter.getTuple();
- diskRTree.bulkLoadAddTuple(frameTuple, rtreeBulkLoadCtx);
+ while (cursor.hasNext()) {
+ cursor.next();
+ ITupleReference frameTuple = cursor.getTuple();
+ rTreeBulkloader.add(frameTuple);
}
} finally {
- rtreeScanCursor.close();
+ cursor.close();
}
- diskRTree.endBulkLoad(rtreeBulkLoadCtx);
+ rTreeBulkloader.end();
// scan the memory BTree
ITreeIndexAccessor memBTreeAccessor = memComponent.getBTree().createAccessor(NoOpOperationCallback.INSTANCE,
@@ -449,17 +232,17 @@
BTree diskBTree = (BTree) createDiskTree(diskBTreeFactory, btreeFile, true);
// BulkLoad the tuples from the in-memory tree into the new disk BTree.
- IIndexBulkLoadContext btreeBulkLoadCtx = diskBTree.beginBulkLoad(1.0f);
+ ITreeIndexBulkLoader bTreeBulkloader = diskBTree.createBulkLoader(1.0f);
try {
while (btreeScanCursor.hasNext()) {
btreeScanCursor.next();
ITupleReference frameTuple = btreeScanCursor.getTuple();
- diskBTree.bulkLoadAddTuple(frameTuple, btreeBulkLoadCtx);
+ bTreeBulkloader.add(frameTuple);
}
} finally {
btreeScanCursor.close();
}
- diskBTree.endBulkLoad(btreeBulkLoadCtx);
+ bTreeBulkloader.end();
return new LSMRTreeComponent(diskRTree, diskBTree);
}
@@ -470,7 +253,8 @@
// The RTree should be renamed before the BTree.
IIndexOpContext ctx = createOpContext();
- ITreeIndexCursor cursor = new LSMRTreeSearchCursor();
+ ITreeIndexCursor cursor;
+ cursor = new LSMRTreeSortedCursor(linearizer);
ISearchPredicate rtreeSearchPred = new SearchPredicate(null, null);
// Scan the RTrees, ignoring the in-memory RTree.
List<Object> mergingComponents = lsmHarness.search(cursor, rtreeSearchPred, ctx, false);
@@ -489,17 +273,17 @@
RTree mergedRTree = (RTree) createDiskTree(diskRTreeFactory, rtreeFile, true);
BTree mergedBTree = (BTree) createDiskTree(diskBTreeFactory, btreeFile, true);
- IIndexBulkLoadContext bulkLoadCtx = mergedRTree.beginBulkLoad(1.0f);
+ ITreeIndexBulkLoader bulkloader = mergedRTree.createBulkLoader(1.0f);
try {
while (cursor.hasNext()) {
cursor.next();
ITupleReference frameTuple = cursor.getTuple();
- mergedRTree.bulkLoadAddTuple(frameTuple, bulkLoadCtx);
+ bulkloader.add(frameTuple);
}
} finally {
cursor.close();
}
- mergedRTree.endBulkLoad(bulkLoadCtx);
+ bulkloader.end();
// Load an empty BTree tree.
IIndexBulkLoadContext btreeBulkLoadCtx = mergedBTree.beginBulkLoad(1.0f);
@@ -509,12 +293,6 @@
}
@Override
- public void addMergedComponent(Object newComponent, List<Object> mergedComponents) {
- diskComponents.removeAll(mergedComponents);
- diskComponents.addLast((LSMRTreeComponent) newComponent);
- }
-
- @Override
public void cleanUpAfterMerge(List<Object> mergedComponents) throws HyracksDataException {
for (Object o : mergedComponents) {
LSMRTreeComponent component = (LSMRTreeComponent) o;
@@ -534,40 +312,6 @@
}
@Override
- public void addFlushedComponent(Object index) {
- diskComponents.addFirst((LSMRTreeComponent) index);
- }
-
- @Override
- public InMemoryFreePageManager getInMemoryFreePageManager() {
- return memFreePageManager;
- }
-
- @Override
- public void resetInMemoryComponent() throws HyracksDataException {
- memComponent.getRTree().create(MEM_RTREE_FILE_ID);
- memComponent.getBTree().create(MEM_BTREE_FILE_ID);
- memFreePageManager.reset();
- memRTreeTuples = 0;
- }
-
- @Override
- public List<Object> getDiskComponents() {
- return diskComponents;
- }
-
- protected LSMRTreeOpContext createOpContext() {
- return new LSMRTreeOpContext((RTree.RTreeAccessor) memComponent.getRTree().createAccessor(
- NoOpOperationCallback.INSTANCE, NoOpOperationCallback.INSTANCE),
- (IRTreeLeafFrame) rtreeLeafFrameFactory.createFrame(),
- (IRTreeInteriorFrame) rtreeInteriorFrameFactory.createFrame(), memFreePageManager
- .getMetaDataFrameFactory().createFrame(), 8, (BTree.BTreeAccessor) memComponent.getBTree()
- .createAccessor(NoOpOperationCallback.INSTANCE, NoOpOperationCallback.INSTANCE),
- btreeLeafFrameFactory, btreeInteriorFrameFactory, memFreePageManager.getMetaDataFrameFactory()
- .createFrame(), rtreeCmpFactories, btreeCmpFactories, null, null);
- }
-
- @Override
public IIndexAccessor createAccessor(IModificationOperationCallback modificationCallback,
ISearchOperationCallback searchCallback) {
return new LSMRTreeAccessor(lsmHarness, createOpContext());
@@ -590,17 +334,45 @@
}
@Override
- public IBinaryComparatorFactory[] getComparatorFactories() {
- return rtreeCmpFactories;
+ public ITreeIndexBulkLoader createBulkLoader(float fillLevel) throws TreeIndexException {
+ return new LSMRTreeBulkLoader(fillLevel);
}
- @Override
- public IBufferCache getBufferCache() {
- return diskBufferCache;
- }
+ public class LSMRTreeBulkLoader implements ITreeIndexBulkLoader {
+ private final RTree diskRTree;
+ private final BTree diskBTree;
+ private final RTreeBulkLoader bulkLoader;
- @Override
- public ILSMComponentFinalizer getComponentFinalizer() {
- return componentFinalizer;
+ public LSMRTreeBulkLoader(float fillFactor) throws TreeIndexException {
+ // Note that by using a flush target file name, we state that the
+ // new bulk loaded tree is "newer" than any other merged tree.
+ try {
+ LSMRTreeFileNameComponent fileNames = (LSMRTreeFileNameComponent) fileManager.getRelFlushFileName();
+ FileReference rtreeFile = fileManager.createFlushFile(fileNames.getRTreeFileName());
+ diskRTree = (RTree) createDiskTree(diskRTreeFactory, rtreeFile, true);
+ // For each RTree, we require to have a buddy BTree. thus, we
+ // create an
+ // empty BTree.
+ FileReference btreeFile = fileManager.createFlushFile(fileNames.getBTreeFileName());
+ diskBTree = (BTree) createDiskTree(diskBTreeFactory, btreeFile, true);
+ } catch (HyracksDataException e) {
+ throw new TreeIndexException(e);
+ }
+
+ bulkLoader = (RTreeBulkLoader) diskRTree.createBulkLoader(fillFactor);
+ }
+
+ @Override
+ public void add(ITupleReference tuple) throws HyracksDataException {
+ bulkLoader.add(tuple);
+ }
+
+ @Override
+ public void end() throws HyracksDataException {
+ bulkLoader.end();
+ LSMRTreeComponent diskComponent = new LSMRTreeComponent(diskRTree, diskBTree);
+ lsmHarness.addBulkLoadedComponent(diskComponent);
+ }
+
}
}
diff --git a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeAbstractCursor.java b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeAbstractCursor.java
new file mode 100644
index 0000000..93834f9
--- /dev/null
+++ b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeAbstractCursor.java
@@ -0,0 +1,112 @@
+package edu.uci.ics.hyracks.storage.am.lsm.rtree.impls;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
+import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeLeafFrame;
+import edu.uci.ics.hyracks.storage.am.btree.impls.BTreeRangeSearchCursor;
+import edu.uci.ics.hyracks.storage.am.btree.impls.RangePredicate;
+import edu.uci.ics.hyracks.storage.am.common.api.ICursorInitialState;
+import edu.uci.ics.hyracks.storage.am.common.api.ISearchPredicate;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexAccessor;
+import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
+import edu.uci.ics.hyracks.storage.am.lsm.common.impls.LSMHarness;
+import edu.uci.ics.hyracks.storage.am.rtree.api.IRTreeInteriorFrame;
+import edu.uci.ics.hyracks.storage.am.rtree.api.IRTreeLeafFrame;
+import edu.uci.ics.hyracks.storage.am.rtree.impls.RTreeSearchCursor;
+import edu.uci.ics.hyracks.storage.am.rtree.impls.SearchPredicate;
+import edu.uci.ics.hyracks.storage.common.buffercache.IBufferCache;
+import edu.uci.ics.hyracks.storage.common.buffercache.ICachedPage;
+
+public abstract class LSMRTreeAbstractCursor {
+
+ protected RTreeSearchCursor[] rtreeCursors;
+
+ public abstract void next() throws HyracksDataException;
+
+ public abstract boolean hasNext() throws HyracksDataException;
+
+ public abstract void reset() throws HyracksDataException;
+
+ protected BTreeRangeSearchCursor[] btreeCursors;
+ protected ITreeIndexAccessor[] diskRTreeAccessors;
+ protected ITreeIndexAccessor[] diskBTreeAccessors;
+ private MultiComparator btreeCmp;
+ protected int numberOfTrees;
+ protected SearchPredicate rtreeSearchPredicate;
+ protected RangePredicate btreeRangePredicate;
+ protected ITupleReference frameTuple;
+ private AtomicInteger searcherRefCount;
+ private boolean includeMemRTree;
+ private LSMHarness lsmHarness;
+ protected boolean foundNext;
+
+ public LSMRTreeAbstractCursor() {
+ super();
+ }
+
+ public RTreeSearchCursor getCursor(int cursorIndex) {
+ return rtreeCursors[cursorIndex];
+ }
+
+ public void open(ICursorInitialState initialState, ISearchPredicate searchPred) throws HyracksDataException {
+ LSMRTreeCursorInitialState lsmInitialState = (LSMRTreeCursorInitialState) initialState;
+ btreeCmp = lsmInitialState.getBTreeCmp();
+ searcherRefCount = lsmInitialState.getSearcherRefCount();
+ includeMemRTree = lsmInitialState.getIncludeMemComponent();
+ lsmHarness = lsmInitialState.getLSMHarness();
+ numberOfTrees = lsmInitialState.getNumberOfTrees();
+ diskRTreeAccessors = lsmInitialState.getRTreeAccessors();
+ diskBTreeAccessors = lsmInitialState.getBTreeAccessors();
+
+ rtreeCursors = new RTreeSearchCursor[numberOfTrees];
+ btreeCursors = new BTreeRangeSearchCursor[numberOfTrees];
+
+ for (int i = 0; i < numberOfTrees; i++) {
+ rtreeCursors[i] = new RTreeSearchCursor((IRTreeInteriorFrame) lsmInitialState
+ .getRTreeInteriorFrameFactory().createFrame(), (IRTreeLeafFrame) lsmInitialState
+ .getRTreeLeafFrameFactory().createFrame());
+
+ btreeCursors[i] = new BTreeRangeSearchCursor((IBTreeLeafFrame) lsmInitialState.getBTreeLeafFrameFactory()
+ .createFrame(), false);
+ }
+ rtreeSearchPredicate = (SearchPredicate) searchPred;
+ btreeRangePredicate = new RangePredicate(null, null, true, true, btreeCmp, btreeCmp);
+ }
+
+ public ICachedPage getPage() {
+ // do nothing
+ return null;
+ }
+
+ public void close() throws HyracksDataException {
+ try {
+ for (int i = 0; i < numberOfTrees; i++) {
+ rtreeCursors[i].close();
+ btreeCursors[i].close();
+ }
+ rtreeCursors = null;
+ btreeCursors = null;
+ } finally {
+ lsmHarness.closeSearchCursor(searcherRefCount, includeMemRTree);
+ }
+ }
+
+ public void setBufferCache(IBufferCache bufferCache) {
+ // do nothing
+ }
+
+ public void setFileId(int fileId) {
+ // do nothing
+ }
+
+ public ITupleReference getTuple() {
+ return frameTuple;
+ }
+
+ public boolean exclusiveLatchNodes() {
+ return false;
+ }
+
+}
\ No newline at end of file
diff --git a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeComponentFinalizer.java b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeComponentFinalizer.java
index b3fbce7..1d83e00 100644
--- a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeComponentFinalizer.java
+++ b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeComponentFinalizer.java
@@ -17,7 +17,7 @@
import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
import edu.uci.ics.hyracks.storage.am.lsm.common.impls.TreeIndexComponentFinalizer;
-import edu.uci.ics.hyracks.storage.am.lsm.rtree.impls.LSMRTree.LSMRTreeComponent;
+import edu.uci.ics.hyracks.storage.am.lsm.rtree.impls.AbstractLSMRTree.LSMRTreeComponent;
import edu.uci.ics.hyracks.storage.common.file.IFileMapProvider;
public class LSMRTreeComponentFinalizer extends TreeIndexComponentFinalizer {
diff --git a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeCursorInitialState.java b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeCursorInitialState.java
index 2d1f744..e33795e 100644
--- a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeCursorInitialState.java
+++ b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeCursorInitialState.java
@@ -17,6 +17,7 @@
import java.util.concurrent.atomic.AtomicInteger;
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparatorFactory;
import edu.uci.ics.hyracks.storage.am.common.api.ICursorInitialState;
import edu.uci.ics.hyracks.storage.am.common.api.ISearchOperationCallback;
import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexAccessor;
@@ -32,19 +33,21 @@
private ITreeIndexFrameFactory rtreeLeafFrameFactory;
private ITreeIndexFrameFactory btreeLeafFrameFactory;
private MultiComparator btreeCmp;
+ private MultiComparator hilbertCmp;
private ITreeIndexAccessor[] rTreeAccessors;
private ITreeIndexAccessor[] bTreeAccessors;
private AtomicInteger searcherRefCount;
private final boolean includeMemRTree;
private final LSMHarness lsmHarness;
+ private final int[] comparatorFields;
private ISearchOperationCallback searchCallback;
public LSMRTreeCursorInitialState(int numberOfTrees, ITreeIndexFrameFactory rtreeLeafFrameFactory,
ITreeIndexFrameFactory rtreeInteriorFrameFactory, ITreeIndexFrameFactory btreeLeafFrameFactory,
MultiComparator btreeCmp, ITreeIndexAccessor[] rTreeAccessors, ITreeIndexAccessor[] bTreeAccessors,
- AtomicInteger searcherRefCount, boolean includeMemRTree, LSMHarness lsmHarness,
- ISearchOperationCallback searchCallback) {
+ AtomicInteger searcherRefCount, boolean includeMemRTree, LSMHarness lsmHarness, int[] comparatorFields,
+ IBinaryComparatorFactory[] linearizerArray, ISearchOperationCallback searchCallback) {
this.numberOfTrees = numberOfTrees;
this.rtreeLeafFrameFactory = rtreeLeafFrameFactory;
this.rtreeInteriorFrameFactory = rtreeInteriorFrameFactory;
@@ -55,9 +58,19 @@
this.searcherRefCount = searcherRefCount;
this.includeMemRTree = includeMemRTree;
this.lsmHarness = lsmHarness;
+ this.comparatorFields = comparatorFields;
+ this.hilbertCmp = MultiComparator.create(linearizerArray);
this.searchCallback = searchCallback;
}
+ public MultiComparator getHilbertCmp() {
+ return hilbertCmp;
+ }
+
+ public int[] getComparatorFields() {
+ return comparatorFields;
+ }
+
public int getNumberOfTrees() {
return numberOfTrees;
}
@@ -95,7 +108,7 @@
return bTreeAccessors;
}
- public boolean getIncludeMemRTree() {
+ public boolean getIncludeMemComponent() {
return includeMemRTree;
}
diff --git a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeFileManager.java b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeFileManager.java
index 0d1f8c3..6487397 100644
--- a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeFileManager.java
+++ b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeFileManager.java
@@ -28,7 +28,7 @@
import edu.uci.ics.hyracks.api.io.IODeviceHandle;
import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMComponentFinalizer;
import edu.uci.ics.hyracks.storage.am.lsm.common.impls.LSMTreeFileManager;
-import edu.uci.ics.hyracks.storage.am.lsm.rtree.impls.LSMRTree.LSMRTreeComponent;
+import edu.uci.ics.hyracks.storage.am.lsm.rtree.impls.AbstractLSMRTree.LSMRTreeComponent;
import edu.uci.ics.hyracks.storage.common.file.IFileMapProvider;
public class LSMRTreeFileManager extends LSMTreeFileManager {
diff --git a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeFlushCursor.java b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeFlushCursor.java
new file mode 100644
index 0000000..65f3f4b
--- /dev/null
+++ b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeFlushCursor.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package edu.uci.ics.hyracks.storage.am.lsm.rtree.impls;
+
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparatorFactory;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
+import edu.uci.ics.hyracks.storage.am.common.api.ICursorInitialState;
+import edu.uci.ics.hyracks.storage.am.common.api.ISearchPredicate;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexCursor;
+import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
+import edu.uci.ics.hyracks.storage.common.buffercache.IBufferCache;
+import edu.uci.ics.hyracks.storage.common.buffercache.ICachedPage;
+
+public class LSMRTreeFlushCursor implements ITreeIndexCursor {
+ private final TreeTupleSorter rTreeTupleSorter;
+ private final TreeTupleSorter bTreeTupleSorter;
+ private final int[] comparatorFields;
+ private final MultiComparator cmp;
+ private ITupleReference frameTuple;
+ private ITupleReference leftOverTuple;
+ private ITupleReference rtreeTuple;
+ private ITupleReference btreeTuple;
+ private boolean foundNext = false;
+
+ public LSMRTreeFlushCursor(TreeTupleSorter rTreeTupleSorter, TreeTupleSorter bTreeTupleSorter,
+ int[] comparatorFields, IBinaryComparatorFactory[] comparatorFactories) {
+ this.rTreeTupleSorter = rTreeTupleSorter;
+ this.bTreeTupleSorter = bTreeTupleSorter;
+ this.comparatorFields = comparatorFields;
+ cmp = MultiComparator.create(comparatorFactories);
+ }
+
+ @Override
+ public void open(ICursorInitialState initialState, ISearchPredicate searchPred) throws HyracksDataException {
+
+ }
+
+ @Override
+ public boolean hasNext() throws HyracksDataException {
+ if (foundNext) {
+ return true;
+ }
+ while (true) {
+ if (leftOverTuple != null && leftOverTuple == rtreeTuple) {
+ if (bTreeTupleSorter.hasNext()) {
+ bTreeTupleSorter.next();
+ btreeTuple = bTreeTupleSorter.getTuple();
+ } else {
+ frameTuple = rtreeTuple;
+ foundNext = true;
+ leftOverTuple = null;
+ return true;
+ }
+ } else if (leftOverTuple != null && leftOverTuple == btreeTuple) {
+ if (rTreeTupleSorter.hasNext()) {
+ rTreeTupleSorter.next();
+ rtreeTuple = rTreeTupleSorter.getTuple();
+ } else {
+ frameTuple = btreeTuple;
+ foundNext = true;
+ leftOverTuple = null;
+ return true;
+ }
+ } else {
+ if (rTreeTupleSorter.hasNext() && bTreeTupleSorter.hasNext()) {
+ rTreeTupleSorter.next();
+ bTreeTupleSorter.next();
+ rtreeTuple = rTreeTupleSorter.getTuple();
+ btreeTuple = bTreeTupleSorter.getTuple();
+ } else if (rTreeTupleSorter.hasNext()) {
+ rTreeTupleSorter.next();
+ rtreeTuple = rTreeTupleSorter.getTuple();
+ frameTuple = rtreeTuple;
+ leftOverTuple = null;
+ foundNext = true;
+ return true;
+ } else if (bTreeTupleSorter.hasNext()) {
+ bTreeTupleSorter.next();
+ btreeTuple = bTreeTupleSorter.getTuple();
+ frameTuple = btreeTuple;
+ leftOverTuple = null;
+ foundNext = true;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ int c = cmp.selectiveFieldCompare(rtreeTuple, btreeTuple, comparatorFields);
+ if (c == 0) {
+ leftOverTuple = null;
+ continue;
+ } else if (c < 0) {
+ frameTuple = rtreeTuple;
+ leftOverTuple = btreeTuple;
+ foundNext = true;
+ return true;
+ } else {
+ frameTuple = btreeTuple;
+ leftOverTuple = rtreeTuple;
+ foundNext = true;
+ return true;
+ }
+ }
+ }
+
+ @Override
+ public void next() throws HyracksDataException {
+ foundNext = false;
+
+ }
+
+ @Override
+ public void close() throws HyracksDataException {
+ }
+
+ @Override
+ public void reset() throws HyracksDataException {
+
+ }
+
+ @Override
+ public ITupleReference getTuple() {
+ return frameTuple;
+ }
+
+ @Override
+ public ICachedPage getPage() {
+ return null;
+ }
+
+ @Override
+ public void setBufferCache(IBufferCache bufferCache) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void setFileId(int fileId) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public boolean exclusiveLatchNodes() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+}
diff --git a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeSearchCursor.java b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeSearchCursor.java
index 6e77eaf..c578902 100644
--- a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeSearchCursor.java
+++ b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeSearchCursor.java
@@ -15,54 +15,23 @@
package edu.uci.ics.hyracks.storage.am.lsm.rtree.impls;
-import java.util.concurrent.atomic.AtomicInteger;
-
import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
-import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeLeafFrame;
-import edu.uci.ics.hyracks.storage.am.btree.impls.BTreeRangeSearchCursor;
-import edu.uci.ics.hyracks.storage.am.btree.impls.RangePredicate;
import edu.uci.ics.hyracks.storage.am.common.api.ICursorInitialState;
import edu.uci.ics.hyracks.storage.am.common.api.ISearchOperationCallback;
import edu.uci.ics.hyracks.storage.am.common.api.ISearchPredicate;
-import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexAccessor;
import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexCursor;
import edu.uci.ics.hyracks.storage.am.common.api.IndexException;
-import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
-import edu.uci.ics.hyracks.storage.am.lsm.common.impls.LSMHarness;
-import edu.uci.ics.hyracks.storage.am.rtree.api.IRTreeInteriorFrame;
-import edu.uci.ics.hyracks.storage.am.rtree.api.IRTreeLeafFrame;
-import edu.uci.ics.hyracks.storage.am.rtree.impls.RTreeSearchCursor;
-import edu.uci.ics.hyracks.storage.am.rtree.impls.SearchPredicate;
-import edu.uci.ics.hyracks.storage.common.buffercache.IBufferCache;
-import edu.uci.ics.hyracks.storage.common.buffercache.ICachedPage;
-public class LSMRTreeSearchCursor implements ITreeIndexCursor {
+public class LSMRTreeSearchCursor extends LSMRTreeAbstractCursor implements ITreeIndexCursor {
- private RTreeSearchCursor[] rtreeCursors;
- private BTreeRangeSearchCursor[] btreeCursors;
- private ITreeIndexAccessor[] diskRTreeAccessors;
- private ITreeIndexAccessor[] diskBTreeAccessors;
private int currentCursror;
- private MultiComparator btreeCmp;
- private int numberOfTrees;
- private SearchPredicate rtreeSearchPredicate;
- private RangePredicate btreeRangePredicate;
- private ITupleReference frameTuple;
- private AtomicInteger searcherRefCount;
- private boolean includeMemRTree;
- private LSMHarness lsmHarness;
- private boolean foundNext = false;
private ISearchOperationCallback searchCallback;
public LSMRTreeSearchCursor() {
currentCursror = 0;
}
- public RTreeSearchCursor getCursor(int cursorIndex) {
- return rtreeCursors[cursorIndex];
- }
-
@Override
public void reset() {
currentCursror = 0;
@@ -129,69 +98,8 @@
@Override
public void open(ICursorInitialState initialState, ISearchPredicate searchPred) throws HyracksDataException {
- LSMRTreeCursorInitialState lsmInitialState = (LSMRTreeCursorInitialState) initialState;
- searchCallback = lsmInitialState.getSearchOperationCallback();
- btreeCmp = lsmInitialState.getBTreeCmp();
- searcherRefCount = lsmInitialState.getSearcherRefCount();
- includeMemRTree = lsmInitialState.getIncludeMemRTree();
- lsmHarness = lsmInitialState.getLSMHarness();
- numberOfTrees = lsmInitialState.getNumberOfTrees();
- diskRTreeAccessors = lsmInitialState.getRTreeAccessors();
- diskBTreeAccessors = lsmInitialState.getBTreeAccessors();
-
- rtreeCursors = new RTreeSearchCursor[numberOfTrees];
- btreeCursors = new BTreeRangeSearchCursor[numberOfTrees];
-
- for (int i = 0; i < numberOfTrees; i++) {
- rtreeCursors[i] = new RTreeSearchCursor((IRTreeInteriorFrame) lsmInitialState
- .getRTreeInteriorFrameFactory().createFrame(), (IRTreeLeafFrame) lsmInitialState
- .getRTreeLeafFrameFactory().createFrame());
-
- btreeCursors[i] = new BTreeRangeSearchCursor((IBTreeLeafFrame) lsmInitialState.getBTreeLeafFrameFactory()
- .createFrame(), false);
- }
- rtreeSearchPredicate = (SearchPredicate) searchPred;
- btreeRangePredicate = new RangePredicate(null, null, true, true, btreeCmp, btreeCmp);
+ super.open(initialState, searchPred);
searchNextCursor();
}
- @Override
- public ICachedPage getPage() {
- // do nothing
- return null;
- }
-
- @Override
- public void close() throws HyracksDataException {
- try {
- for (int i = 0; i < numberOfTrees; i++) {
- rtreeCursors[i].close();
- btreeCursors[i].close();
- }
- rtreeCursors = null;
- btreeCursors = null;
- } finally {
- lsmHarness.closeSearchCursor(searcherRefCount, includeMemRTree);
- }
- }
-
- @Override
- public void setBufferCache(IBufferCache bufferCache) {
- // do nothing
- }
-
- @Override
- public void setFileId(int fileId) {
- // do nothing
- }
-
- @Override
- public ITupleReference getTuple() {
- return frameTuple;
- }
-
- @Override
- public boolean exclusiveLatchNodes() {
- return false;
- }
}
\ No newline at end of file
diff --git a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeSortedCursor.java b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeSortedCursor.java
new file mode 100644
index 0000000..1e0916a
--- /dev/null
+++ b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeSortedCursor.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package edu.uci.ics.hyracks.storage.am.lsm.rtree.impls;
+
+import edu.uci.ics.hyracks.api.dataflow.value.ILinearizeComparator;
+import edu.uci.ics.hyracks.api.dataflow.value.ILinearizeComparatorFactory;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.storage.am.common.api.ICursorInitialState;
+import edu.uci.ics.hyracks.storage.am.common.api.ISearchPredicate;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexCursor;
+import edu.uci.ics.hyracks.storage.am.common.api.IndexException;
+
+public class LSMRTreeSortedCursor extends LSMRTreeAbstractCursor implements ITreeIndexCursor {
+
+ private ILinearizeComparator linearizeCmp;
+ private boolean[] depletedRtreeCursors;
+ private int foundIn = -1;
+
+ public LSMRTreeSortedCursor(ILinearizeComparatorFactory linearizer) throws HyracksDataException {
+ super();
+ this.linearizeCmp = linearizer.createBinaryComparator();
+ reset();
+ }
+
+ @Override
+ public void reset() throws HyracksDataException {
+ depletedRtreeCursors = new boolean[numberOfTrees];
+ foundNext = false;
+ for (int i = 0; i < numberOfTrees; i++) {
+ rtreeCursors[i].reset();
+ try {
+ diskRTreeAccessors[i].search(rtreeCursors[i], rtreeSearchPredicate);
+ } catch (IndexException e) {
+ throw new HyracksDataException(e);
+ }
+ if (rtreeCursors[i].hasNext()) {
+ rtreeCursors[i].next();
+ } else {
+ depletedRtreeCursors[i] = true;
+ }
+ }
+ }
+
+ @Override
+ public boolean hasNext() throws HyracksDataException {
+ while (!foundNext) {
+ frameTuple = null;
+
+ if (foundIn != -1) {
+ if (rtreeCursors[foundIn].hasNext()) {
+ rtreeCursors[foundIn].next();
+ } else {
+ depletedRtreeCursors[foundIn] = true;
+ }
+ }
+
+ foundIn = -1;
+ for (int i = 0; i < numberOfTrees; i++) {
+ if (depletedRtreeCursors[i])
+ continue;
+
+ if (frameTuple == null) {
+ frameTuple = rtreeCursors[i].getTuple();
+ foundIn = i;
+ continue;
+ }
+
+ if (linearizeCmp.compare(frameTuple.getFieldData(0), frameTuple.getFieldStart(0),
+ frameTuple.getFieldLength(0) * linearizeCmp.getDimensions(), rtreeCursors[i].getTuple()
+ .getFieldData(0), rtreeCursors[i].getTuple().getFieldStart(0), rtreeCursors[i]
+ .getTuple().getFieldLength(0) * linearizeCmp.getDimensions()) <= 0) {
+ frameTuple = rtreeCursors[i].getTuple();
+ foundIn = i;
+ }
+ }
+
+ if (foundIn == -1)
+ return false;
+
+ boolean killed = false;
+ for (int i = 0; i < foundIn; i++) {
+ try {
+ btreeCursors[i].reset();
+ btreeRangePredicate.setHighKey(frameTuple, true);
+ btreeRangePredicate.setLowKey(frameTuple, true);
+ diskBTreeAccessors[i].search(btreeCursors[i], btreeRangePredicate);
+ } catch (IndexException e) {
+ throw new HyracksDataException(e);
+ }
+ try {
+ if (btreeCursors[i].hasNext()) {
+ killed = true;
+ break;
+ }
+ } finally {
+ btreeCursors[i].close();
+ }
+ }
+ if (!killed) {
+ foundNext = true;
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ public void next() throws HyracksDataException {
+ foundNext = false;
+ }
+
+ @Override
+ public void open(ICursorInitialState initialState, ISearchPredicate searchPred) throws HyracksDataException {
+ super.open(initialState, searchPred);
+ reset();
+ }
+}
\ No newline at end of file
diff --git a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeWithAntiMatterTuples.java b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeWithAntiMatterTuples.java
new file mode 100644
index 0000000..f83ac35
--- /dev/null
+++ b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeWithAntiMatterTuples.java
@@ -0,0 +1,368 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package edu.uci.ics.hyracks.storage.am.lsm.rtree.impls;
+
+import java.io.File;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparatorFactory;
+import edu.uci.ics.hyracks.api.dataflow.value.ILinearizeComparatorFactory;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.api.io.FileReference;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
+import edu.uci.ics.hyracks.storage.am.btree.impls.BTreeRangeSearchCursor;
+import edu.uci.ics.hyracks.storage.am.btree.impls.RangePredicate;
+import edu.uci.ics.hyracks.storage.am.common.api.IIndexAccessor;
+import edu.uci.ics.hyracks.storage.am.common.api.IIndexCursor;
+import edu.uci.ics.hyracks.storage.am.common.api.IIndexOpContext;
+import edu.uci.ics.hyracks.storage.am.common.api.IModificationOperationCallback;
+import edu.uci.ics.hyracks.storage.am.common.api.ISearchOperationCallback;
+import edu.uci.ics.hyracks.storage.am.common.api.ISearchPredicate;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexAccessor;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexBulkLoader;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexCursor;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrameFactory;
+import edu.uci.ics.hyracks.storage.am.common.api.IndexException;
+import edu.uci.ics.hyracks.storage.am.common.api.TreeIndexException;
+import edu.uci.ics.hyracks.storage.am.common.impls.NoOpOperationCallback;
+import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
+import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMFileManager;
+import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMFlushPolicy;
+import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMMergePolicy;
+import edu.uci.ics.hyracks.storage.am.lsm.common.freepage.InMemoryFreePageManager;
+import edu.uci.ics.hyracks.storage.am.lsm.common.impls.LSMHarness;
+import edu.uci.ics.hyracks.storage.am.lsm.common.impls.LSMTreeIndexAccessor;
+import edu.uci.ics.hyracks.storage.am.lsm.common.impls.TreeIndexComponentFinalizer;
+import edu.uci.ics.hyracks.storage.am.rtree.impls.RTree;
+import edu.uci.ics.hyracks.storage.am.rtree.impls.RTree.RTreeBulkLoader;
+import edu.uci.ics.hyracks.storage.am.rtree.impls.RTreeSearchCursor;
+import edu.uci.ics.hyracks.storage.am.rtree.impls.SearchPredicate;
+import edu.uci.ics.hyracks.storage.common.buffercache.IBufferCache;
+import edu.uci.ics.hyracks.storage.common.file.IFileMapProvider;
+
+public class LSMRTreeWithAntiMatterTuples extends AbstractLSMRTree {
+
+ private TreeTupleSorter bTreeTupleSorter = null;
+
+ // On-disk components.
+ // For creating RTree's used in bulk load. Different from diskRTreeFactory
+ // because it should have a different tuple writer in it's leaf frames.
+ private final RTreeFactory bulkLoadRTreeFactory;
+
+ public LSMRTreeWithAntiMatterTuples(IBufferCache memBufferCache, InMemoryFreePageManager memFreePageManager,
+ ITreeIndexFrameFactory rtreeInteriorFrameFactory, ITreeIndexFrameFactory rtreeLeafFrameFactory,
+ ITreeIndexFrameFactory btreeInteriorFrameFactory, ITreeIndexFrameFactory btreeLeafFrameFactory,
+ ILSMFileManager fileManager, RTreeFactory diskRTreeFactory, RTreeFactory bulkLoadRTreeFactory,
+ IFileMapProvider diskFileMapProvider, int fieldCount, IBinaryComparatorFactory[] rtreeCmpFactories,
+ IBinaryComparatorFactory[] btreeCmpFactories, ILinearizeComparatorFactory linearizer,
+ int[] comparatorFields, IBinaryComparatorFactory[] linearizerArray, ILSMFlushPolicy flushPolicy, ILSMMergePolicy mergePolicy) {
+ super(memBufferCache, memFreePageManager, rtreeInteriorFrameFactory, rtreeLeafFrameFactory,
+ btreeInteriorFrameFactory, btreeLeafFrameFactory, fileManager, diskRTreeFactory, diskFileMapProvider,
+ new TreeIndexComponentFinalizer(diskFileMapProvider), fieldCount, rtreeCmpFactories, btreeCmpFactories,
+ linearizer, comparatorFields, linearizerArray, flushPolicy, mergePolicy);
+ this.bulkLoadRTreeFactory = bulkLoadRTreeFactory;
+
+ }
+
+ /**
+ * Opens LSMRTree, cleaning up invalid files from base dir, and registering
+ * all valid files as on-disk RTrees and BTrees.
+ *
+ * @param indexFileId
+ * Dummy file id.
+ * @throws HyracksDataException
+ */
+ @Override
+ public void open(int indexFileId) throws HyracksDataException {
+ super.open(indexFileId);
+ RTree dummyRTree = diskRTreeFactory.createIndexInstance();
+ List<Object> validFileNames = fileManager.cleanupAndGetValidFiles(dummyRTree, componentFinalizer);
+ for (Object o : validFileNames) {
+ String fileName = (String) o;
+ FileReference fileRef = new FileReference(new File(fileName));
+ RTree rtree = (RTree) createDiskTree(diskRTreeFactory, fileRef, false);
+ diskComponents.add(rtree);
+ }
+ }
+
+ @Override
+ public void close() throws HyracksDataException {
+ for (Object o : diskComponents) {
+ RTree rtree = (RTree) o;
+ diskBufferCache.closeFile(rtree.getFileId());
+ diskBufferCache.deleteFile(rtree.getFileId(), false);
+ rtree.close();
+ }
+ diskComponents.clear();
+ super.close();
+ }
+
+ private RTree createFlushTarget() throws HyracksDataException {
+ String relFlushFileName = (String) fileManager.getRelFlushFileName();
+ FileReference fileRef = fileManager.createFlushFile(relFlushFileName);
+ return (RTree) createDiskTree(diskRTreeFactory, fileRef, true);
+ }
+
+ private RTree createMergeTarget(List<Object> mergingDiskRTrees) throws HyracksDataException {
+ RTree firstRTree = (RTree) mergingDiskRTrees.get(0);
+ RTree lastRTree = (RTree) mergingDiskRTrees.get(mergingDiskRTrees.size() - 1);
+ FileReference firstFile = diskFileMapProvider.lookupFileName(firstRTree.getFileId());
+ FileReference lastFile = diskFileMapProvider.lookupFileName(lastRTree.getFileId());
+ String relMergeFileName = (String) fileManager.getRelMergeFileName(firstFile.getFile().getName(), lastFile
+ .getFile().getName());
+ FileReference fileRef = fileManager.createMergeFile(relMergeFileName);
+ return (RTree) createDiskTree(diskRTreeFactory, fileRef, true);
+ }
+
+ public void search(IIndexCursor cursor, List<Object> diskComponents, ISearchPredicate pred, IIndexOpContext ictx,
+ boolean includeMemComponent, AtomicInteger searcherRefCount) throws HyracksDataException, IndexException {
+ LSMRTreeOpContext ctx = (LSMRTreeOpContext) ictx;
+ LSMRTreeWithAntiMatterTuplesSearchCursor lsmTreeCursor = (LSMRTreeWithAntiMatterTuplesSearchCursor) cursor;
+ int numDiskRTrees = diskComponents.size();
+
+ LSMRTreeCursorInitialState initialState;
+ ITreeIndexAccessor[] bTreeAccessors = null;
+ if (includeMemComponent) {
+ // Only in-memory BTree
+ bTreeAccessors = new ITreeIndexAccessor[1];
+ bTreeAccessors[0] = ctx.memBTreeAccessor;
+ }
+
+ initialState = new LSMRTreeCursorInitialState(numDiskRTrees, rtreeLeafFrameFactory, rtreeInteriorFrameFactory,
+ btreeLeafFrameFactory, ctx.getBTreeMultiComparator(), null, bTreeAccessors, searcherRefCount,
+ includeMemComponent, lsmHarness, comparatorFields, linearizerArray, ctx.searchCallback);
+
+ lsmTreeCursor.open(initialState, pred);
+
+ if (includeMemComponent) {
+ // Open cursor of in-memory RTree
+ ctx.memRTreeAccessor.search(lsmTreeCursor.getMemRTreeCursor(), pred);
+ }
+
+ // Open cursors of on-disk RTrees.
+ ITreeIndexAccessor[] diskRTreeAccessors = new ITreeIndexAccessor[numDiskRTrees];
+ int diskRTreeIx = 0;
+ ListIterator<Object> diskRTreesIter = diskComponents.listIterator();
+ while (diskRTreesIter.hasNext()) {
+ RTree diskRTree = (RTree) diskRTreesIter.next();
+ diskRTreeAccessors[diskRTreeIx] = diskRTree.createAccessor(NoOpOperationCallback.INSTANCE,
+ NoOpOperationCallback.INSTANCE);
+ diskRTreeAccessors[diskRTreeIx].search(lsmTreeCursor.getCursor(diskRTreeIx), pred);
+ diskRTreeIx++;
+ }
+ lsmTreeCursor.initPriorityQueue();
+ }
+
+ @Override
+ public ITreeIndex flush() throws HyracksDataException, IndexException {
+ // Renaming order is critical because we use assume ordering when we
+ // read the file names when we open the tree.
+ // The RTree should be renamed before the BTree.
+
+ // scan the memory RTree
+ ITreeIndexAccessor memRTreeAccessor = memComponent.getRTree().createAccessor(NoOpOperationCallback.INSTANCE,
+ NoOpOperationCallback.INSTANCE);
+ RTreeSearchCursor rtreeScanCursor = (RTreeSearchCursor) memRTreeAccessor.createSearchCursor();
+ SearchPredicate rtreeNullPredicate = new SearchPredicate(null, null);
+ memRTreeAccessor.search(rtreeScanCursor, rtreeNullPredicate);
+ RTree diskRTree = createFlushTarget();
+
+ // scan the memory BTree
+ ITreeIndexAccessor memBTreeAccessor = memComponent.getBTree().createAccessor(NoOpOperationCallback.INSTANCE,
+ NoOpOperationCallback.INSTANCE);
+ BTreeRangeSearchCursor btreeScanCursor = (BTreeRangeSearchCursor) memBTreeAccessor.createSearchCursor();
+ RangePredicate btreeNullPredicate = new RangePredicate(null, null, true, true, null, null);
+ memBTreeAccessor.search(btreeScanCursor, btreeNullPredicate);
+
+ // Since the LSM-RTree is used as a secondary assumption, the
+ // primary key will be the last comparator in the BTree comparators
+ if (rTreeTupleSorter == null) {
+ rTreeTupleSorter = new TreeTupleSorter(memRTreeTuples, MEM_RTREE_FILE_ID, linearizerArray,
+ rtreeLeafFrameFactory.createFrame(), rtreeLeafFrameFactory.createFrame(), memComponent.getRTree()
+ .getBufferCache(), comparatorFields);
+
+ bTreeTupleSorter = new TreeTupleSorter(memBTreeTuples, MEM_BTREE_FILE_ID, linearizerArray,
+ btreeLeafFrameFactory.createFrame(), btreeLeafFrameFactory.createFrame(), memComponent.getBTree()
+ .getBufferCache(), comparatorFields);
+ } else {
+ rTreeTupleSorter.reset();
+ bTreeTupleSorter.reset();
+ }
+ // BulkLoad the tuples from the in-memory tree into the new disk
+ // RTree.
+
+ boolean isEmpty = true;
+ if (rtreeScanCursor.hasNext()) {
+ isEmpty = false;
+ }
+ try {
+ while (rtreeScanCursor.hasNext()) {
+ rtreeScanCursor.next();
+ rTreeTupleSorter.insertTupleEntry(rtreeScanCursor.getPageId(), rtreeScanCursor.getTupleOffset());
+ }
+ } finally {
+ rtreeScanCursor.close();
+ }
+ if (!isEmpty) {
+ rTreeTupleSorter.sort();
+ }
+
+ isEmpty = true;
+ if (btreeScanCursor.hasNext()) {
+ isEmpty = false;
+ }
+ try {
+ while (btreeScanCursor.hasNext()) {
+ btreeScanCursor.next();
+ bTreeTupleSorter.insertTupleEntry(btreeScanCursor.getPageId(), btreeScanCursor.getTupleOffset());
+ }
+ } finally {
+ btreeScanCursor.close();
+ }
+ if (!isEmpty) {
+ bTreeTupleSorter.sort();
+ }
+
+ ITreeIndexBulkLoader rTreeBulkloader = diskRTree.createBulkLoader(1.0f);
+ LSMRTreeFlushCursor cursor = new LSMRTreeFlushCursor(rTreeTupleSorter, bTreeTupleSorter, comparatorFields,
+ linearizerArray);
+ cursor.open(null, null);
+
+ try {
+ while (cursor.hasNext()) {
+ cursor.next();
+ ITupleReference frameTuple = cursor.getTuple();
+
+ rTreeBulkloader.add(frameTuple);
+ }
+ } finally {
+ cursor.close();
+ }
+
+ rTreeBulkloader.end();
+
+ return diskRTree;
+ }
+
+ @Override
+ public ITreeIndex merge(List<Object> mergedComponents) throws HyracksDataException, IndexException {
+ LSMRTreeOpContext ctx = createOpContext();
+ ITreeIndexCursor cursor = new LSMRTreeWithAntiMatterTuplesSearchCursor();
+ ISearchPredicate rtreeSearchPred = new SearchPredicate(null, null);
+ // Ordered scan, ignoring the in-memory RTree.
+ // We get back a snapshot of the on-disk RTrees that are going to be
+ // merged now, so we can clean them up after the merge has completed.
+ List<Object> mergingDiskRTrees = lsmHarness.search(cursor, (SearchPredicate) rtreeSearchPred, ctx, false);
+ mergedComponents.addAll(mergingDiskRTrees);
+
+ // Nothing to merge.
+ if (mergedComponents.size() <= 1) {
+ cursor.close();
+ return null;
+ }
+
+ // Bulk load the tuples from all on-disk RTrees into the new RTree.
+ RTree mergedRTree = createMergeTarget(mergingDiskRTrees);
+ ITreeIndexBulkLoader bulkloader = mergedRTree.createBulkLoader(1.0f);
+ try {
+ while (cursor.hasNext()) {
+ cursor.next();
+ ITupleReference frameTuple = cursor.getTuple();
+ bulkloader.add(frameTuple);
+ }
+ } finally {
+ cursor.close();
+ }
+ bulkloader.end();
+ return mergedRTree;
+ }
+
+ @Override
+ public void cleanUpAfterMerge(List<Object> mergedComponents) throws HyracksDataException {
+ for (Object o : mergedComponents) {
+ RTree oldRTree = (RTree) o;
+ FileReference fileRef = diskFileMapProvider.lookupFileName(oldRTree.getFileId());
+ diskBufferCache.closeFile(oldRTree.getFileId());
+ diskBufferCache.deleteFile(oldRTree.getFileId(), false);
+ oldRTree.close();
+ fileRef.getFile().delete();
+ }
+ }
+
+ @Override
+ public IIndexAccessor createAccessor(IModificationOperationCallback modificationCallback,
+ ISearchOperationCallback searchCallback) {
+ return new LSMRTreeWithAntiMatterTuplesAccessor(lsmHarness, createOpContext());
+ }
+
+ public class LSMRTreeWithAntiMatterTuplesAccessor extends LSMTreeIndexAccessor {
+ public LSMRTreeWithAntiMatterTuplesAccessor(LSMHarness lsmHarness, IIndexOpContext ctx) {
+ super(lsmHarness, ctx);
+ }
+
+ @Override
+ public ITreeIndexCursor createSearchCursor() {
+ return new LSMRTreeWithAntiMatterTuplesSearchCursor();
+ }
+
+ public MultiComparator getMultiComparator() {
+ LSMRTreeOpContext concreteCtx = (LSMRTreeOpContext) ctx;
+ return concreteCtx.rtreeOpContext.cmp;
+ }
+ }
+
+ @Override
+ public ITreeIndexBulkLoader createBulkLoader(float fillLevel) throws TreeIndexException {
+ return new LSMRTreeWithAntiMatterTuplesBulkLoader(fillLevel);
+ }
+
+ private RTree createBulkLoadTarget() throws HyracksDataException {
+ String relFlushFileName = (String) fileManager.getRelFlushFileName();
+ FileReference fileRef = fileManager.createFlushFile(relFlushFileName);
+ return (RTree) createDiskTree(bulkLoadRTreeFactory, fileRef, true);
+ }
+
+ public class LSMRTreeWithAntiMatterTuplesBulkLoader implements ITreeIndexBulkLoader {
+ private final RTree diskRTree;
+ private final RTreeBulkLoader bulkLoader;
+
+ public LSMRTreeWithAntiMatterTuplesBulkLoader(float fillFactor) throws TreeIndexException {
+ // Note that by using a flush target file name, we state that the
+ // new bulk loaded tree is "newer" than any other merged tree.
+ try {
+ diskRTree = createBulkLoadTarget();
+ } catch (HyracksDataException e) {
+ throw new TreeIndexException(e);
+ }
+ bulkLoader = (RTreeBulkLoader) diskRTree.createBulkLoader(fillFactor);
+ }
+
+ @Override
+ public void add(ITupleReference tuple) throws HyracksDataException {
+ bulkLoader.add(tuple);
+ }
+
+ @Override
+ public void end() throws HyracksDataException {
+ bulkLoader.end();
+ lsmHarness.addBulkLoadedComponent(diskRTree);
+ }
+
+ }
+}
diff --git a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeWithAntiMatterTuplesSearchCursor.java b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeWithAntiMatterTuplesSearchCursor.java
new file mode 100644
index 0000000..9556230
--- /dev/null
+++ b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeWithAntiMatterTuplesSearchCursor.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package edu.uci.ics.hyracks.storage.am.lsm.rtree.impls;
+
+import java.util.Comparator;
+import java.util.PriorityQueue;
+
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
+import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeLeafFrame;
+import edu.uci.ics.hyracks.storage.am.btree.impls.BTreeRangeSearchCursor;
+import edu.uci.ics.hyracks.storage.am.btree.impls.RangePredicate;
+import edu.uci.ics.hyracks.storage.am.common.api.ICursorInitialState;
+import edu.uci.ics.hyracks.storage.am.common.api.ISearchPredicate;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexAccessor;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexCursor;
+import edu.uci.ics.hyracks.storage.am.common.api.IndexException;
+import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
+import edu.uci.ics.hyracks.storage.am.lsm.common.impls.LSMTreeSearchCursor;
+import edu.uci.ics.hyracks.storage.am.rtree.api.IRTreeInteriorFrame;
+import edu.uci.ics.hyracks.storage.am.rtree.api.IRTreeLeafFrame;
+import edu.uci.ics.hyracks.storage.am.rtree.impls.RTreeSearchCursor;
+
+public class LSMRTreeWithAntiMatterTuplesSearchCursor extends LSMTreeSearchCursor {
+ private RTreeSearchCursor memRTreeCursor;
+ private BTreeRangeSearchCursor memBTreeCursor;
+ private RangePredicate btreeRangePredicate;
+ private ITreeIndexAccessor memBTreeAccessor;
+ protected PriorityQueueHilbertComparator pqCmp;
+ private boolean foundNext;
+ private ITupleReference frameTuple;
+ private int[] comparatorFields;
+ private MultiComparator btreeCmp;
+
+ public void initPriorityQueue() throws HyracksDataException {
+ int pqInitSize = (rangeCursors.length > 0) ? rangeCursors.length : 1;
+ outputPriorityQueue = new PriorityQueue<PriorityQueueElement>(pqInitSize, pqCmp);
+ for (int i = 0; i < rangeCursors.length; i++) {
+ PriorityQueueElement element;
+ if (rangeCursors[i].hasNext()) {
+ rangeCursors[i].next();
+ element = new PriorityQueueElement(rangeCursors[i].getTuple(), i);
+ outputPriorityQueue.offer(element);
+ }
+ }
+ checkPriorityQueue();
+ }
+
+ @Override
+ public void open(ICursorInitialState initialState, ISearchPredicate searchPred) throws HyracksDataException {
+ LSMRTreeCursorInitialState lsmInitialState = (LSMRTreeCursorInitialState) initialState;
+ cmp = lsmInitialState.getHilbertCmp();
+ btreeCmp = lsmInitialState.getBTreeCmp();
+ int numDiskRTrees = lsmInitialState.getNumberOfTrees();
+ rangeCursors = new RTreeSearchCursor[numDiskRTrees];
+ for (int i = 0; i < numDiskRTrees; i++) {
+ rangeCursors[i] = new RTreeSearchCursor((IRTreeInteriorFrame) lsmInitialState
+ .getRTreeInteriorFrameFactory().createFrame(), (IRTreeLeafFrame) lsmInitialState
+ .getRTreeLeafFrameFactory().createFrame());
+ }
+ includeMemComponent = lsmInitialState.getIncludeMemComponent();
+ if (includeMemComponent) {
+ memRTreeCursor = new RTreeSearchCursor((IRTreeInteriorFrame) lsmInitialState.getRTreeInteriorFrameFactory()
+ .createFrame(), (IRTreeLeafFrame) lsmInitialState.getRTreeLeafFrameFactory().createFrame());
+ memBTreeCursor = new BTreeRangeSearchCursor((IBTreeLeafFrame) lsmInitialState.getBTreeLeafFrameFactory()
+ .createFrame(), false);
+ memBTreeAccessor = lsmInitialState.getBTreeAccessors()[0];
+ btreeRangePredicate = new RangePredicate(null, null, true, true, btreeCmp, btreeCmp);
+ }
+ searcherfRefCount = lsmInitialState.getSearcherRefCount();
+ lsmHarness = lsmInitialState.getLSMHarness();
+ comparatorFields = lsmInitialState.getComparatorFields();
+ setPriorityQueueComparator();
+ }
+
+ @Override
+ public boolean hasNext() throws HyracksDataException {
+ if (includeMemComponent) {
+ if (foundNext) {
+ return true;
+ }
+ while (memRTreeCursor.hasNext()) {
+ memRTreeCursor.next();
+ ITupleReference memRTreeTuple = memRTreeCursor.getTuple();
+ if (searchMemBTree(memRTreeTuple)) {
+ foundNext = true;
+ frameTuple = memRTreeTuple;
+ return true;
+ }
+ }
+ while (super.hasNext()) {
+ super.next();
+ ITupleReference diskRTreeTuple = super.getTuple();
+ if (searchMemBTree(diskRTreeTuple)) {
+ foundNext = true;
+ frameTuple = diskRTreeTuple;
+ return true;
+ }
+ }
+ } else {
+ return super.hasNext();
+ }
+
+ return false;
+ }
+
+ @Override
+ public void next() throws HyracksDataException {
+ if (includeMemComponent) {
+ foundNext = false;
+ } else {
+ super.next();
+ }
+
+ }
+
+ @Override
+ public ITupleReference getTuple() {
+ if (includeMemComponent) {
+ return frameTuple;
+ } else {
+ return super.getTuple();
+ }
+
+ }
+
+ @Override
+ public void close() throws HyracksDataException {
+ if (includeMemComponent) {
+ memRTreeCursor.close();
+ memBTreeCursor.close();
+ }
+ super.close();
+ }
+
+ public ITreeIndexCursor getMemRTreeCursor() {
+ return memRTreeCursor;
+ }
+
+ @Override
+ protected int compare(MultiComparator cmp, ITupleReference tupleA, ITupleReference tupleB) {
+ return cmp.selectiveFieldCompare(tupleA, tupleB, comparatorFields);
+ }
+
+ private boolean searchMemBTree(ITupleReference tuple) throws HyracksDataException {
+ try {
+ btreeRangePredicate.setHighKey(tuple, true);
+ btreeRangePredicate.setLowKey(tuple, true);
+ memBTreeAccessor.search(memBTreeCursor, btreeRangePredicate);
+ } catch (IndexException e) {
+ throw new HyracksDataException(e);
+ }
+ try {
+ if (memBTreeCursor.hasNext()) {
+ return false;
+ } else {
+ return true;
+ }
+ } finally {
+ memBTreeCursor.close();
+ }
+ }
+
+ @Override
+ protected void setPriorityQueueComparator() {
+ if (pqCmp == null || cmp != pqCmp.getMultiComparator()) {
+ pqCmp = new PriorityQueueHilbertComparator(cmp, comparatorFields);
+ }
+ }
+
+ public class PriorityQueueHilbertComparator implements Comparator<PriorityQueueElement> {
+
+ private final MultiComparator cmp;
+ private final int[] comparatorFields;
+
+ public PriorityQueueHilbertComparator(MultiComparator cmp, int[] comparatorFields) {
+ this.cmp = cmp;
+ this.comparatorFields = comparatorFields;
+ }
+
+ @Override
+ public int compare(PriorityQueueElement elementA, PriorityQueueElement elementB) {
+ int result = cmp.selectiveFieldCompare(elementA.getTuple(), elementB.getTuple(), comparatorFields);
+ if (result != 0) {
+ return result;
+ }
+ if (elementA.getCursorIndex() > elementB.getCursorIndex()) {
+ return 1;
+ } else {
+ return -1;
+ }
+ }
+
+ public MultiComparator getMultiComparator() {
+ return cmp;
+ }
+ }
+
+}
diff --git a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/RTreeTupleSorter.java b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/TreeTupleSorter.java
similarity index 73%
rename from hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/RTreeTupleSorter.java
rename to hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/TreeTupleSorter.java
index ab6eb59..d63cff9 100644
--- a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/RTreeTupleSorter.java
+++ b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/TreeTupleSorter.java
@@ -15,18 +15,20 @@
package edu.uci.ics.hyracks.storage.am.lsm.rtree.impls;
-import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparator;
import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparatorFactory;
import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
+import edu.uci.ics.hyracks.storage.am.common.api.ICursorInitialState;
+import edu.uci.ics.hyracks.storage.am.common.api.ISearchPredicate;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexCursor;
import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrame;
import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexTupleReference;
+import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
import edu.uci.ics.hyracks.storage.common.buffercache.IBufferCache;
import edu.uci.ics.hyracks.storage.common.buffercache.ICachedPage;
import edu.uci.ics.hyracks.storage.common.file.BufferedFileHandle;
-public class RTreeTupleSorter {
- private final IBinaryComparator[] comparators;
+public class TreeTupleSorter implements ITreeIndexCursor {
private int numTuples;
private int currentTupleIndex;
private int[] tPointers;
@@ -37,21 +39,21 @@
private ITreeIndexTupleReference frameTuple2;
private final int fileId;
private final static int ARRAY_GROWTH = 1000; // Must be at least of size 2
+ private final int[] comparatorFields;
+ private final MultiComparator cmp;
- public RTreeTupleSorter(int initialSize, int fileId, IBinaryComparatorFactory[] comparatorFactories,
- ITreeIndexFrame leafFrame1, ITreeIndexFrame leafFrame2, IBufferCache bufferCache) {
+ public TreeTupleSorter(int initialSize, int fileId, IBinaryComparatorFactory[] comparatorFactories,
+ ITreeIndexFrame leafFrame1, ITreeIndexFrame leafFrame2, IBufferCache bufferCache, int[] comparatorFields) {
this.fileId = fileId;
- comparators = new IBinaryComparator[comparatorFactories.length];
- for (int i = 0; i < comparatorFactories.length; ++i) {
- comparators[i] = comparatorFactories[i].createBinaryComparator();
- }
this.leafFrame1 = leafFrame1;
this.leafFrame2 = leafFrame2;
this.bufferCache = bufferCache;
+ this.comparatorFields = comparatorFields;
tPointers = new int[initialSize * 2];
frameTuple1 = leafFrame1.createTupleReference();
frameTuple2 = leafFrame2.createTupleReference();
currentTupleIndex = 0;
+ cmp = MultiComparator.create(comparatorFactories);
}
public void reset() {
@@ -63,11 +65,17 @@
if (numTuples <= currentTupleIndex) {
return false;
}
+ // We don't latch pages since this code is only used by flush () before
+ // bulk-loading the r-tree to disk and flush is not concurrent.
+ //
ICachedPage node1 = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, tPointers[currentTupleIndex * 2]),
false);
- leafFrame1.setPage(node1);
- frameTuple1.resetByTupleOffset(leafFrame1.getBuffer(), tPointers[currentTupleIndex * 2 + 1]);
-
+ try {
+ leafFrame1.setPage(node1);
+ frameTuple1.resetByTupleOffset(leafFrame1.getBuffer(), tPointers[currentTupleIndex * 2 + 1]);
+ } finally {
+ bufferCache.unpin(node1);
+ }
return true;
}
@@ -171,18 +179,46 @@
ICachedPage node2 = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, i2), false);
leafFrame2.setPage(node2);
- frameTuple1.resetByTupleOffset(leafFrame1.getBuffer(), j1);
- frameTuple2.resetByTupleOffset(leafFrame2.getBuffer(), j2);
+ try {
+ frameTuple1.resetByTupleOffset(leafFrame1.getBuffer(), j1);
+ frameTuple2.resetByTupleOffset(leafFrame2.getBuffer(), j2);
- for (int f = 0; f < comparators.length; ++f) {
- int c = comparators[f].compare(frameTuple1.getFieldData(f), frameTuple1.getFieldStart(f),
- frameTuple1.getFieldLength(f), frameTuple2.getFieldData(f), frameTuple2.getFieldStart(f),
- frameTuple2.getFieldLength(f));
- if (c != 0) {
- return c;
- }
+ return cmp.selectiveFieldCompare(frameTuple1, frameTuple2, comparatorFields);
+
+ } finally {
+ bufferCache.unpin(node1);
+ bufferCache.unpin(node2);
}
- return 0;
+ }
+
+ @Override
+ public void open(ICursorInitialState initialState, ISearchPredicate searchPred) throws HyracksDataException {
+ // do nothing
+ }
+
+ @Override
+ public void close() throws HyracksDataException {
+ // do nothing
+ }
+
+ @Override
+ public ICachedPage getPage() {
+ return null;
+ }
+
+ @Override
+ public void setBufferCache(IBufferCache bufferCache) {
+ // do nothing
+ }
+
+ @Override
+ public void setFileId(int fileId) {
+ // do nothing
+ }
+
+ @Override
+ public boolean exclusiveLatchNodes() {
+ return false;
}
}
\ No newline at end of file
diff --git a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/tuples/LSMRTreeCopyTupleWriter.java b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/tuples/LSMRTreeCopyTupleWriter.java
new file mode 100644
index 0000000..1852b51
--- /dev/null
+++ b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/tuples/LSMRTreeCopyTupleWriter.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package edu.uci.ics.hyracks.storage.am.lsm.rtree.tuples;
+
+import edu.uci.ics.hyracks.api.dataflow.value.ITypeTraits;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
+
+public class LSMRTreeCopyTupleWriter extends LSMRTreeTupleWriter {
+ public LSMRTreeCopyTupleWriter(ITypeTraits[] typeTraits) {
+ // Third parameter is never used locally, just give false.
+ super(typeTraits, false);
+ }
+
+ @Override
+ public int writeTuple(ITupleReference tuple, byte[] targetBuf, int targetOff) {
+ int tupleSize = bytesRequired(tuple);
+ byte[] buf = tuple.getFieldData(0);
+ int tupleStartOff = ((LSMRTreeTupleReference) tuple).getTupleStart();
+ System.arraycopy(buf, tupleStartOff, targetBuf, targetOff, tupleSize);
+ return tupleSize;
+ }
+}
diff --git a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/tuples/LSMRTreeCopyTupleWriterFactory.java b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/tuples/LSMRTreeCopyTupleWriterFactory.java
new file mode 100644
index 0000000..39a8e4d
--- /dev/null
+++ b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/tuples/LSMRTreeCopyTupleWriterFactory.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package edu.uci.ics.hyracks.storage.am.lsm.rtree.tuples;
+
+import edu.uci.ics.hyracks.api.dataflow.value.ITypeTraits;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexTupleWriter;
+import edu.uci.ics.hyracks.storage.am.common.tuples.TypeAwareTupleWriterFactory;
+
+public class LSMRTreeCopyTupleWriterFactory extends TypeAwareTupleWriterFactory {
+ private static final long serialVersionUID = 1L;
+ private final ITypeTraits[] typeTraits;
+
+ public LSMRTreeCopyTupleWriterFactory(ITypeTraits[] typeTraits) {
+ super(typeTraits);
+ this.typeTraits = typeTraits;
+ }
+
+ @Override
+ public ITreeIndexTupleWriter createTupleWriter() {
+ return new LSMRTreeCopyTupleWriter(typeTraits);
+ }
+}
diff --git a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/tuples/LSMRTreeTupleReference.java b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/tuples/LSMRTreeTupleReference.java
new file mode 100644
index 0000000..70072e1
--- /dev/null
+++ b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/tuples/LSMRTreeTupleReference.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package edu.uci.ics.hyracks.storage.am.lsm.rtree.tuples;
+
+import edu.uci.ics.hyracks.api.dataflow.value.ITypeTraits;
+import edu.uci.ics.hyracks.storage.am.common.tuples.TypeAwareTupleReference;
+import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMTreeTupleReference;
+
+public class LSMRTreeTupleReference extends TypeAwareTupleReference implements ILSMTreeTupleReference {
+
+ public LSMRTreeTupleReference(ITypeTraits[] typeTraits) {
+ super(typeTraits);
+ }
+
+ @Override
+ protected int getNullFlagsBytes() {
+ // +1.0 is for matter/antimatter bit.
+ return (int) Math.ceil((fieldCount + 1.0) / 8.0);
+ }
+
+ @Override
+ public boolean isAntimatter() {
+ // Check if the leftmost bit is 0 or 1.
+ final byte mask = (byte) (1 << 7);
+ if ((buf.array()[tupleStartOff] & mask) != 0) {
+ return true;
+ }
+ return false;
+ }
+
+ public int getTupleStart() {
+ return tupleStartOff;
+ }
+}
diff --git a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/tuples/LSMRTreeTupleWriter.java b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/tuples/LSMRTreeTupleWriter.java
new file mode 100644
index 0000000..932a307
--- /dev/null
+++ b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/tuples/LSMRTreeTupleWriter.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package edu.uci.ics.hyracks.storage.am.lsm.rtree.tuples;
+
+import edu.uci.ics.hyracks.api.dataflow.value.ITypeTraits;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexTupleReference;
+import edu.uci.ics.hyracks.storage.am.rtree.tuples.RTreeTypeAwareTupleWriter;
+
+public class LSMRTreeTupleWriter extends RTreeTypeAwareTupleWriter {
+ private final boolean isAntimatter;
+
+ public LSMRTreeTupleWriter(ITypeTraits[] typeTraits, boolean isAntimatter) {
+ super(typeTraits);
+ this.isAntimatter = isAntimatter;
+ }
+
+ @Override
+ public ITreeIndexTupleReference createTupleReference() {
+ return new LSMRTreeTupleReference(typeTraits);
+ }
+
+ @Override
+ public int bytesRequired(ITupleReference tuple) {
+ return super.bytesRequired(tuple);
+ }
+
+ @Override
+ public int writeTuple(ITupleReference tuple, byte[] targetBuf, int targetOff) {
+ int bytesWritten = super.writeTuple(tuple, targetBuf, targetOff);
+ if (isAntimatter) {
+ setAntimatterBit(targetBuf, targetOff);
+ }
+ return bytesWritten;
+ }
+
+ @Override
+ protected int getNullFlagsBytes(int numFields) {
+ // +1.0 is for matter/antimatter bit.
+ return (int) Math.ceil(((double) numFields + 1.0) / 8.0);
+ }
+
+ @Override
+ protected int getNullFlagsBytes(ITupleReference tuple) {
+ // +1.0 is for matter/antimatter bit.
+ return (int) Math.ceil(((double) tuple.getFieldCount() + 1.0) / 8.0);
+ }
+
+ protected void setAntimatterBit(byte[] targetBuf, int targetOff) {
+ // Set leftmost bit to 1.
+ targetBuf[targetOff] = (byte) (targetBuf[targetOff] | (1 << 7));
+ }
+
+}
diff --git a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/tuples/LSMRTreeTupleWriterFactory.java b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/tuples/LSMRTreeTupleWriterFactory.java
new file mode 100644
index 0000000..493d368
--- /dev/null
+++ b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/tuples/LSMRTreeTupleWriterFactory.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package edu.uci.ics.hyracks.storage.am.lsm.rtree.tuples;
+
+import edu.uci.ics.hyracks.api.dataflow.value.ITypeTraits;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexTupleWriter;
+import edu.uci.ics.hyracks.storage.am.common.tuples.TypeAwareTupleWriterFactory;
+
+public class LSMRTreeTupleWriterFactory extends TypeAwareTupleWriterFactory {
+
+ private static final long serialVersionUID = 1L;
+ private final ITypeTraits[] typeTraits;
+ private final boolean isDelete;
+
+ public LSMRTreeTupleWriterFactory(ITypeTraits[] typeTraits, boolean isDelete) {
+ super(typeTraits);
+ this.typeTraits = typeTraits;
+ this.isDelete = isDelete;
+ }
+
+ @Override
+ public ITreeIndexTupleWriter createTupleWriter() {
+ return new LSMRTreeTupleWriter(typeTraits, isDelete);
+ }
+}
diff --git a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/utils/LSMRTreeUtils.java b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/utils/LSMRTreeUtils.java
index 2a41962..bf20bbc 100644
--- a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/utils/LSMRTreeUtils.java
+++ b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/utils/LSMRTreeUtils.java
@@ -16,44 +16,55 @@
package edu.uci.ics.hyracks.storage.am.lsm.rtree.utils;
import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparatorFactory;
+import edu.uci.ics.hyracks.api.dataflow.value.ILinearizeComparatorFactory;
import edu.uci.ics.hyracks.api.dataflow.value.ITypeTraits;
import edu.uci.ics.hyracks.api.io.IIOManager;
+import edu.uci.ics.hyracks.data.std.primitive.DoublePointable;
+import edu.uci.ics.hyracks.data.std.primitive.IntegerPointable;
import edu.uci.ics.hyracks.storage.am.btree.frames.BTreeNSMInteriorFrameFactory;
import edu.uci.ics.hyracks.storage.am.btree.frames.BTreeNSMLeafFrameFactory;
import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrameFactory;
import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexMetaDataFrameFactory;
+import edu.uci.ics.hyracks.storage.am.common.api.TreeIndexException;
import edu.uci.ics.hyracks.storage.am.common.frames.LIFOMetaDataFrameFactory;
import edu.uci.ics.hyracks.storage.am.common.freepage.LinkedListFreePageManagerFactory;
import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMFileManager;
import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMFlushPolicy;
import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMMergePolicy;
-import edu.uci.ics.hyracks.storage.am.lsm.common.freepage.InMemoryBufferCache;
import edu.uci.ics.hyracks.storage.am.lsm.common.freepage.InMemoryFreePageManager;
import edu.uci.ics.hyracks.storage.am.lsm.common.impls.BTreeFactory;
+import edu.uci.ics.hyracks.storage.am.lsm.common.impls.LSMTreeFileManager;
import edu.uci.ics.hyracks.storage.am.lsm.rtree.impls.LSMRTree;
import edu.uci.ics.hyracks.storage.am.lsm.rtree.impls.LSMRTreeFileManager;
+import edu.uci.ics.hyracks.storage.am.lsm.rtree.impls.LSMRTreeWithAntiMatterTuples;
import edu.uci.ics.hyracks.storage.am.lsm.rtree.impls.RTreeFactory;
+import edu.uci.ics.hyracks.storage.am.lsm.rtree.tuples.LSMRTreeCopyTupleWriterFactory;
+import edu.uci.ics.hyracks.storage.am.lsm.rtree.tuples.LSMRTreeTupleWriterFactory;
import edu.uci.ics.hyracks.storage.am.lsm.rtree.tuples.LSMTypeAwareTupleWriterFactory;
import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreeNSMInteriorFrameFactory;
import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreeNSMLeafFrameFactory;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
+import edu.uci.ics.hyracks.storage.am.rtree.linearize.HilbertDoubleComparatorFactory;
+import edu.uci.ics.hyracks.storage.am.rtree.linearize.ZCurveDoubleComparatorFactory;
+import edu.uci.ics.hyracks.storage.am.rtree.linearize.ZCurveIntComparatorFactory;
import edu.uci.ics.hyracks.storage.common.buffercache.IBufferCache;
import edu.uci.ics.hyracks.storage.common.file.IFileMapProvider;
public class LSMRTreeUtils {
- public static LSMRTree createLSMTree(InMemoryBufferCache memBufferCache,
- InMemoryFreePageManager memFreePageManager, IIOManager ioManager, String onDiskDir,
- IBufferCache diskBufferCache, IFileMapProvider diskFileMapProvider, ITypeTraits[] typeTraits,
- IBinaryComparatorFactory[] rtreeCmpFactories, IBinaryComparatorFactory[] btreeCmpFactories,
- IPrimitiveValueProviderFactory[] valueProviderFactories, ILSMFlushPolicy flushPolicy,
- ILSMMergePolicy mergePolicy) {
+ public static LSMRTree createLSMTree(IBufferCache memBufferCache, InMemoryFreePageManager memFreePageManager,
+ IIOManager ioManager, String onDiskDir, IBufferCache diskBufferCache, IFileMapProvider diskFileMapProvider,
+ ITypeTraits[] typeTraits, IBinaryComparatorFactory[] rtreeCmpFactories,
+ IBinaryComparatorFactory[] btreeCmpFactories, IPrimitiveValueProviderFactory[] valueProviderFactories,
+ RTreePolicyType rtreePolicyType, ILSMFlushPolicy flushPolicy,
+ ILSMMergePolicy mergePolicy) throws TreeIndexException {
LSMTypeAwareTupleWriterFactory rtreeTupleWriterFactory = new LSMTypeAwareTupleWriterFactory(typeTraits, false);
LSMTypeAwareTupleWriterFactory btreeTupleWriterFactory = new LSMTypeAwareTupleWriterFactory(typeTraits, true);
ITreeIndexFrameFactory rtreeInteriorFrameFactory = new RTreeNSMInteriorFrameFactory(rtreeTupleWriterFactory,
- valueProviderFactories);
+ valueProviderFactories, rtreePolicyType);
ITreeIndexFrameFactory rtreeLeafFrameFactory = new RTreeNSMLeafFrameFactory(rtreeTupleWriterFactory,
- valueProviderFactories);
+ valueProviderFactories, rtreePolicyType);
ITreeIndexFrameFactory btreeInteriorFrameFactory = new BTreeNSMInteriorFrameFactory(btreeTupleWriterFactory);
ITreeIndexFrameFactory btreeLeafFrameFactory = new BTreeNSMLeafFrameFactory(btreeTupleWriterFactory);
@@ -68,11 +79,82 @@
BTreeFactory diskBTreeFactory = new BTreeFactory(diskBufferCache, freePageManagerFactory,
btreeCmpFactories, typeTraits.length, btreeInteriorFrameFactory, btreeLeafFrameFactory);
+ ILinearizeComparatorFactory linearizer = proposeBestLinearizer(typeTraits, rtreeCmpFactories.length);
+ int[] comparatorFields = { 0 };
+ IBinaryComparatorFactory[] linearizerArray = { linearizer };
+
ILSMFileManager fileNameManager = new LSMRTreeFileManager(ioManager, diskFileMapProvider, onDiskDir);
LSMRTree lsmTree = new LSMRTree(memBufferCache, memFreePageManager, rtreeInteriorFrameFactory,
rtreeLeafFrameFactory, btreeInteriorFrameFactory, btreeLeafFrameFactory, fileNameManager,
diskRTreeFactory, diskBTreeFactory, diskFileMapProvider, typeTraits.length, rtreeCmpFactories,
- btreeCmpFactories, flushPolicy, mergePolicy);
+ btreeCmpFactories, linearizer, comparatorFields, linearizerArray, flushPolicy, mergePolicy);
return lsmTree;
}
+
+ public static LSMRTreeWithAntiMatterTuples createLSMTreeWithAntiMatterTuples(IBufferCache memBufferCache,
+ InMemoryFreePageManager memFreePageManager, IIOManager ioManager, String onDiskDir,
+ IBufferCache diskBufferCache, IFileMapProvider diskFileMapProvider, ITypeTraits[] typeTraits,
+ IBinaryComparatorFactory[] rtreeCmpFactories, IBinaryComparatorFactory[] btreeCmpFactories,
+ IPrimitiveValueProviderFactory[] valueProviderFactories, RTreePolicyType rtreePolicyType,
+ ILSMFlushPolicy flushPolicy, ILSMMergePolicy mergePolicy)
+ throws TreeIndexException {
+
+ LSMRTreeTupleWriterFactory rtreeTupleWriterFactory = new LSMRTreeTupleWriterFactory(typeTraits, false);
+ LSMRTreeTupleWriterFactory btreeTupleWriterFactory = new LSMRTreeTupleWriterFactory(typeTraits, true);
+
+ LSMRTreeCopyTupleWriterFactory copyTupleWriterFactory = new LSMRTreeCopyTupleWriterFactory(typeTraits);
+
+ ITreeIndexFrameFactory rtreeInteriorFrameFactory = new RTreeNSMInteriorFrameFactory(rtreeTupleWriterFactory,
+ valueProviderFactories, rtreePolicyType);
+ ITreeIndexFrameFactory rtreeLeafFrameFactory = new RTreeNSMLeafFrameFactory(rtreeTupleWriterFactory,
+ valueProviderFactories, rtreePolicyType);
+
+ ITreeIndexFrameFactory btreeInteriorFrameFactory = new BTreeNSMInteriorFrameFactory(btreeTupleWriterFactory);
+ ITreeIndexFrameFactory btreeLeafFrameFactory = new BTreeNSMLeafFrameFactory(btreeTupleWriterFactory);
+
+ ITreeIndexFrameFactory copyTupleLeafFrameFactory = new RTreeNSMLeafFrameFactory(copyTupleWriterFactory,
+ valueProviderFactories, rtreePolicyType);
+
+ ITreeIndexMetaDataFrameFactory metaFrameFactory = new LIFOMetaDataFrameFactory();
+ LinkedListFreePageManagerFactory freePageManagerFactory = new LinkedListFreePageManagerFactory(diskBufferCache,
+ metaFrameFactory);
+
+ RTreeFactory diskRTreeFactory = new RTreeFactory(diskBufferCache, freePageManagerFactory, rtreeCmpFactories,
+ typeTraits.length, rtreeInteriorFrameFactory, copyTupleLeafFrameFactory);
+
+ RTreeFactory bulkLoadRTreeFactory = new RTreeFactory(diskBufferCache, freePageManagerFactory,
+ rtreeCmpFactories, typeTraits.length, rtreeInteriorFrameFactory, rtreeLeafFrameFactory);
+
+ ILinearizeComparatorFactory linearizer = proposeBestLinearizer(typeTraits, rtreeCmpFactories.length);
+ // The first field is for the sorted curve (e.g. Hilbert curve), and the
+ // second field is for the primary key.
+ int[] comparatorFields = { 0, btreeCmpFactories.length - 1 };
+ IBinaryComparatorFactory[] linearizerArray = { linearizer, btreeCmpFactories[btreeCmpFactories.length - 1] };
+
+ ILSMFileManager fileNameManager = new LSMTreeFileManager(ioManager, diskFileMapProvider, onDiskDir);
+ LSMRTreeWithAntiMatterTuples lsmTree = new LSMRTreeWithAntiMatterTuples(memBufferCache, memFreePageManager,
+ rtreeInteriorFrameFactory, rtreeLeafFrameFactory, btreeInteriorFrameFactory, btreeLeafFrameFactory,
+ fileNameManager, diskRTreeFactory, bulkLoadRTreeFactory, diskFileMapProvider, typeTraits.length,
+ rtreeCmpFactories, btreeCmpFactories, linearizer, comparatorFields, linearizerArray, flushPolicy, mergePolicy);
+ return lsmTree;
+ }
+
+ private static ILinearizeComparatorFactory proposeBestLinearizer(ITypeTraits[] typeTraits, int numKeyFields)
+ throws TreeIndexException {
+ for (int i = 0; i < numKeyFields; i++) {
+ if (!(typeTraits[i].getClass().equals(typeTraits[0].getClass()))) {
+ throw new TreeIndexException("Cannot propose linearizer if dimensions have different types");
+ }
+ }
+
+ if (numKeyFields / 2 == 2 && (typeTraits[0].getClass() == DoublePointable.TYPE_TRAITS.getClass())) {
+ return new HilbertDoubleComparatorFactory(2);
+ } else if (typeTraits[0].getClass() == DoublePointable.TYPE_TRAITS.getClass()) {
+ return new ZCurveDoubleComparatorFactory(numKeyFields / 2);
+ } else if (typeTraits[0].getClass() == IntegerPointable.TYPE_TRAITS.getClass()) {
+ return new ZCurveIntComparatorFactory(numKeyFields / 2);
+ }
+
+ throw new TreeIndexException("Cannot propose linearizer");
+ }
}
diff --git a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/api/IRTreePolicy.java b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/api/IRTreePolicy.java
new file mode 100644
index 0000000..b1d026a
--- /dev/null
+++ b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/api/IRTreePolicy.java
@@ -0,0 +1,33 @@
+/*
+ * 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.rtree.api;
+
+import java.nio.ByteBuffer;
+
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
+import edu.uci.ics.hyracks.storage.am.common.api.ISlotManager;
+import edu.uci.ics.hyracks.storage.am.common.api.ISplitKey;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrame;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexTupleReference;
+import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
+
+public interface IRTreePolicy {
+ public void split(ITreeIndexFrame leftFrame, ByteBuffer buf, ITreeIndexFrame rightFrame, ISlotManager slotManager,
+ ITreeIndexTupleReference frameTuple, ITupleReference tuple, ISplitKey splitKey);
+
+ public boolean findBestChild(ITreeIndexFrame frame, ITupleReference tuple, ITreeIndexTupleReference frameTuple,
+ MultiComparator cmp);
+}
diff --git a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/dataflow/RTreeDataflowHelper.java b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/dataflow/RTreeDataflowHelper.java
index 0470da9..843c472 100644
--- a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/dataflow/RTreeDataflowHelper.java
+++ b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/dataflow/RTreeDataflowHelper.java
@@ -21,22 +21,25 @@
import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexOperatorDescriptor;
import edu.uci.ics.hyracks.storage.am.common.dataflow.TreeIndexDataflowHelper;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
import edu.uci.ics.hyracks.storage.am.rtree.util.RTreeUtils;
public class RTreeDataflowHelper extends TreeIndexDataflowHelper {
private final IPrimitiveValueProviderFactory[] valueProviderFactories;
+ private final RTreePolicyType rtreePolicyType;
public RTreeDataflowHelper(IIndexOperatorDescriptor opDesc, IHyracksTaskContext ctx, int partition,
- IPrimitiveValueProviderFactory[] valueProviderFactories) {
+ IPrimitiveValueProviderFactory[] valueProviderFactories, RTreePolicyType rtreePolicyType) {
super(opDesc, ctx, partition);
this.valueProviderFactories = valueProviderFactories;
+ this.rtreePolicyType = rtreePolicyType;
}
@Override
public ITreeIndex createIndexInstance() throws HyracksDataException {
return RTreeUtils.createRTree(treeOpDesc.getStorageManager().getBufferCache(ctx),
treeOpDesc.getTreeIndexTypeTraits(), valueProviderFactories,
- treeOpDesc.getTreeIndexComparatorFactories());
+ treeOpDesc.getTreeIndexComparatorFactories(), rtreePolicyType);
}
}
diff --git a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/dataflow/RTreeDataflowHelperFactory.java b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/dataflow/RTreeDataflowHelperFactory.java
index 6b9fd4c..06af8ee 100644
--- a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/dataflow/RTreeDataflowHelperFactory.java
+++ b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/dataflow/RTreeDataflowHelperFactory.java
@@ -20,20 +20,24 @@
import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexDataflowHelperFactory;
import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexOperatorDescriptor;
import edu.uci.ics.hyracks.storage.am.common.dataflow.IndexDataflowHelper;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
public class RTreeDataflowHelperFactory implements IIndexDataflowHelperFactory {
private static final long serialVersionUID = 1L;
private final IPrimitiveValueProviderFactory[] valueProviderFactories;
+ private final RTreePolicyType rtreePolicyType;
- public RTreeDataflowHelperFactory(IPrimitiveValueProviderFactory[] valueProviderFactories) {
+ public RTreeDataflowHelperFactory(IPrimitiveValueProviderFactory[] valueProviderFactories,
+ RTreePolicyType rtreePolicyType) {
this.valueProviderFactories = valueProviderFactories;
+ this.rtreePolicyType = rtreePolicyType;
}
@Override
public IndexDataflowHelper createIndexDataflowHelper(IIndexOperatorDescriptor opDesc, IHyracksTaskContext ctx,
int partition) {
- return new RTreeDataflowHelper(opDesc, ctx, partition, valueProviderFactories);
+ return new RTreeDataflowHelper(opDesc, ctx, partition, valueProviderFactories, rtreePolicyType);
}
}
diff --git a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RStarTreePolicy.java b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RStarTreePolicy.java
new file mode 100644
index 0000000..adbb80d
--- /dev/null
+++ b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RStarTreePolicy.java
@@ -0,0 +1,342 @@
+/*
+ * 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.rtree.frames;
+
+import java.nio.ByteBuffer;
+
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
+import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProvider;
+import edu.uci.ics.hyracks.storage.am.common.api.ISlotManager;
+import edu.uci.ics.hyracks.storage.am.common.api.ISplitKey;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrame;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexTupleReference;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexTupleWriter;
+import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
+import edu.uci.ics.hyracks.storage.am.rtree.api.IRTreeFrame;
+import edu.uci.ics.hyracks.storage.am.rtree.api.IRTreePolicy;
+import edu.uci.ics.hyracks.storage.am.rtree.impls.EntriesOrder;
+import edu.uci.ics.hyracks.storage.am.rtree.impls.RTreeSplitKey;
+import edu.uci.ics.hyracks.storage.am.rtree.impls.Rectangle;
+import edu.uci.ics.hyracks.storage.am.rtree.impls.TupleEntryArrayList;
+import edu.uci.ics.hyracks.storage.am.rtree.impls.UnorderedSlotManager;
+import edu.uci.ics.hyracks.storage.am.rtree.tuples.RTreeTypeAwareTupleWriter;
+
+public class RStarTreePolicy implements IRTreePolicy {
+
+ private TupleEntryArrayList tupleEntries1;
+ private TupleEntryArrayList tupleEntries2;
+ private Rectangle[] rec;
+
+ private static final int nearMinimumOverlapFactor = 32;
+ private static final double splitFactor = 0.4;
+ private static final int numTuplesEntries = 100;
+
+ private final ITreeIndexTupleWriter tupleWriter;
+ private final IPrimitiveValueProvider[] keyValueProviders;
+ private ITreeIndexTupleReference cmpFrameTuple;
+ private final int totalFreeSpaceOff;
+
+ public RStarTreePolicy(ITreeIndexTupleWriter tupleWriter, IPrimitiveValueProvider[] keyValueProviders,
+ ITreeIndexTupleReference cmpFrameTuple, int totalFreeSpaceOff) {
+ this.tupleWriter = tupleWriter;
+ this.keyValueProviders = keyValueProviders;
+ this.totalFreeSpaceOff = totalFreeSpaceOff;
+ this.cmpFrameTuple = cmpFrameTuple;
+ tupleEntries1 = new TupleEntryArrayList(numTuplesEntries, numTuplesEntries);
+ tupleEntries2 = new TupleEntryArrayList(numTuplesEntries, numTuplesEntries);
+ rec = new Rectangle[4];
+ for (int i = 0; i < 4; i++) {
+ rec[i] = new Rectangle(keyValueProviders.length / 2);
+ }
+ }
+
+ public void split(ITreeIndexFrame leftFrame, ByteBuffer buf, ITreeIndexFrame rightFrame, ISlotManager slotManager,
+ ITreeIndexTupleReference frameTuple, ITupleReference tuple, ISplitKey splitKey) {
+ RTreeSplitKey rTreeSplitKey = ((RTreeSplitKey) splitKey);
+ RTreeTypeAwareTupleWriter rTreeTupleWriterleftRTreeFrame = ((RTreeTypeAwareTupleWriter) tupleWriter);
+ RTreeTypeAwareTupleWriter rTreeTupleWriterRightFrame = ((RTreeTypeAwareTupleWriter) rightFrame.getTupleWriter());
+
+ RTreeNSMFrame leftRTreeFrame = ((RTreeNSMFrame) leftFrame);
+
+ // calculations are based on the R*-tree paper
+ int m = (int) Math.floor((leftRTreeFrame.getTupleCount() + 1) * splitFactor);
+ int splitDistribution = leftRTreeFrame.getTupleCount() - (2 * m) + 2;
+
+ // to calculate the minimum margin in order to pick the split axis
+ double minMargin = Double.MAX_VALUE;
+ int splitAxis = 0, sortOrder = 0;
+
+ int maxFieldPos = keyValueProviders.length / 2;
+ for (int i = 0; i < maxFieldPos; i++) {
+ int j = maxFieldPos + i;
+ for (int k = 0; k < leftRTreeFrame.getTupleCount(); ++k) {
+
+ frameTuple.resetByTupleIndex(leftRTreeFrame, k);
+ double LowerKey = keyValueProviders[i]
+ .getValue(frameTuple.getFieldData(i), frameTuple.getFieldStart(i));
+ double UpperKey = keyValueProviders[j]
+ .getValue(frameTuple.getFieldData(j), frameTuple.getFieldStart(j));
+
+ tupleEntries1.add(k, LowerKey);
+ tupleEntries2.add(k, UpperKey);
+ }
+ double LowerKey = keyValueProviders[i].getValue(tuple.getFieldData(i), tuple.getFieldStart(i));
+ double UpperKey = keyValueProviders[j].getValue(tuple.getFieldData(j), tuple.getFieldStart(j));
+
+ tupleEntries1.add(-1, LowerKey);
+ tupleEntries2.add(-1, UpperKey);
+
+ tupleEntries1.sort(EntriesOrder.ASCENDING, leftRTreeFrame.getTupleCount() + 1);
+ tupleEntries2.sort(EntriesOrder.ASCENDING, leftRTreeFrame.getTupleCount() + 1);
+
+ double lowerMargin = 0.0, upperMargin = 0.0;
+ // generate distribution
+ for (int k = 1; k <= splitDistribution; ++k) {
+ int d = m - 1 + k;
+
+ generateDist(leftRTreeFrame, frameTuple, tuple, tupleEntries1, rec[0], 0, d);
+ generateDist(leftRTreeFrame, frameTuple, tuple, tupleEntries2, rec[1], 0, d);
+ generateDist(leftRTreeFrame, frameTuple, tuple, tupleEntries1, rec[2], d,
+ leftRTreeFrame.getTupleCount() + 1);
+ generateDist(leftRTreeFrame, frameTuple, tuple, tupleEntries2, rec[3], d,
+ leftRTreeFrame.getTupleCount() + 1);
+
+ // calculate the margin of the distributions
+ lowerMargin += rec[0].margin() + rec[2].margin();
+ upperMargin += rec[1].margin() + rec[3].margin();
+ }
+ double margin = Math.min(lowerMargin, upperMargin);
+
+ // store minimum margin as split axis
+ if (margin < minMargin) {
+ minMargin = margin;
+ splitAxis = i;
+ sortOrder = (lowerMargin < upperMargin) ? 0 : 2;
+ }
+
+ tupleEntries1.clear();
+ tupleEntries2.clear();
+ }
+
+ for (int i = 0; i < leftRTreeFrame.getTupleCount(); ++i) {
+ frameTuple.resetByTupleIndex(leftRTreeFrame, i);
+ double key = keyValueProviders[splitAxis + sortOrder].getValue(
+ frameTuple.getFieldData(splitAxis + sortOrder), frameTuple.getFieldStart(splitAxis + sortOrder));
+ tupleEntries1.add(i, key);
+ }
+ double key = keyValueProviders[splitAxis + sortOrder].getValue(tuple.getFieldData(splitAxis + sortOrder),
+ tuple.getFieldStart(splitAxis + sortOrder));
+ tupleEntries1.add(-1, key);
+ tupleEntries1.sort(EntriesOrder.ASCENDING, leftRTreeFrame.getTupleCount() + 1);
+
+ double minArea = Double.MAX_VALUE;
+ double minOverlap = Double.MAX_VALUE;
+ int splitPoint = 0;
+ for (int i = 1; i <= splitDistribution; ++i) {
+ int d = m - 1 + i;
+
+ generateDist(leftRTreeFrame, frameTuple, tuple, tupleEntries1, rec[0], 0, d);
+ generateDist(leftRTreeFrame, frameTuple, tuple, tupleEntries1, rec[2], d,
+ leftRTreeFrame.getTupleCount() + 1);
+
+ double overlap = rec[0].overlappedArea(rec[2]);
+ if (overlap < minOverlap) {
+ splitPoint = d;
+ minOverlap = overlap;
+ minArea = rec[0].area() + rec[2].area();
+ } else if (overlap == minOverlap) {
+ double area = rec[0].area() + rec[2].area();
+ if (area < minArea) {
+ splitPoint = d;
+ minArea = area;
+ }
+ }
+ }
+ int startIndex, endIndex;
+ if (splitPoint < (leftRTreeFrame.getTupleCount() + 1) / 2) {
+ startIndex = 0;
+ endIndex = splitPoint;
+ } else {
+ startIndex = splitPoint;
+ endIndex = (leftRTreeFrame.getTupleCount() + 1);
+ }
+ boolean tupleInserted = false;
+ int totalBytes = 0, numOfDeletedTuples = 0;
+ for (int i = startIndex; i < endIndex; i++) {
+ if (tupleEntries1.get(i).getTupleIndex() != -1) {
+ frameTuple.resetByTupleIndex(leftRTreeFrame, tupleEntries1.get(i).getTupleIndex());
+ rightFrame.insert(frameTuple, -1);
+ ((UnorderedSlotManager) slotManager).modifySlot(
+ slotManager.getSlotOff(tupleEntries1.get(i).getTupleIndex()), -1);
+ totalBytes += leftRTreeFrame.getTupleSize(frameTuple);
+ numOfDeletedTuples++;
+ } else {
+ rightFrame.insert(tuple, -1);
+ tupleInserted = true;
+ }
+ }
+
+ ((UnorderedSlotManager) slotManager).deleteEmptySlots();
+
+ // maintain space information
+ buf.putInt(totalFreeSpaceOff, buf.getInt(totalFreeSpaceOff) + totalBytes
+ + (slotManager.getSlotSize() * numOfDeletedTuples));
+
+ // compact both pages
+ rightFrame.compact();
+ leftRTreeFrame.compact();
+
+ if (!tupleInserted) {
+ leftRTreeFrame.insert(tuple, -1);
+ }
+
+ int tupleOff = slotManager.getTupleOff(slotManager.getSlotEndOff());
+ frameTuple.resetByTupleOffset(buf, tupleOff);
+ int splitKeySize = tupleWriter.bytesRequired(frameTuple, 0, keyValueProviders.length);
+
+ splitKey.initData(splitKeySize);
+ leftRTreeFrame.adjustMBR();
+ rTreeTupleWriterleftRTreeFrame.writeTupleFields(leftRTreeFrame.getTuples(), 0,
+ rTreeSplitKey.getLeftPageBuffer(), 0);
+ rTreeSplitKey.getLeftTuple().resetByTupleOffset(rTreeSplitKey.getLeftPageBuffer(), 0);
+
+ ((IRTreeFrame) rightFrame).adjustMBR();
+ rTreeTupleWriterRightFrame.writeTupleFields(((RTreeNSMFrame) rightFrame).getTuples(), 0,
+ rTreeSplitKey.getRightPageBuffer(), 0);
+ rTreeSplitKey.getRightTuple().resetByTupleOffset(rTreeSplitKey.getRightPageBuffer(), 0);
+
+ tupleEntries1.clear();
+ tupleEntries2.clear();
+ }
+
+ public void generateDist(ITreeIndexFrame leftRTreeFrame, ITreeIndexTupleReference frameTuple,
+ ITupleReference tuple, TupleEntryArrayList entries, Rectangle rec, int start, int end) {
+ int j = 0;
+ while (entries.get(j).getTupleIndex() == -1) {
+ j++;
+ }
+ frameTuple.resetByTupleIndex(leftRTreeFrame, entries.get(j).getTupleIndex());
+ rec.set(frameTuple, keyValueProviders);
+ for (int i = start; i < end; ++i) {
+ if (i != j) {
+ if (entries.get(i).getTupleIndex() != -1) {
+ frameTuple.resetByTupleIndex(leftRTreeFrame, entries.get(i).getTupleIndex());
+ rec.enlarge(frameTuple, keyValueProviders);
+ } else {
+ rec.enlarge(tuple, keyValueProviders);
+ }
+ }
+ }
+ }
+
+ public boolean findBestChild(ITreeIndexFrame frame, ITupleReference tuple, ITreeIndexTupleReference frameTuple, MultiComparator cmp) {
+ cmpFrameTuple.setFieldCount(cmp.getKeyFieldCount());
+ frameTuple.setFieldCount(cmp.getKeyFieldCount());
+
+ int bestChild = 0;
+ double minEnlargedArea = Double.MAX_VALUE;
+
+ // the children pointers in the node point to leaves
+ if (frame.getLevel() == 1) {
+ // find least overlap enlargement, use minimum enlarged area to
+ // break tie, if tie still exists use minimum area to break it
+ for (int i = 0; i < frame.getTupleCount(); ++i) {
+ frameTuple.resetByTupleIndex(frame, i);
+ double enlargedArea = RTreeComputationUtils.enlargedArea(frameTuple, tuple, cmp, keyValueProviders);
+ tupleEntries1.add(i, enlargedArea);
+ if (enlargedArea < minEnlargedArea) {
+ minEnlargedArea = enlargedArea;
+ bestChild = i;
+ }
+ }
+ if (minEnlargedArea < RTreeNSMFrame.doubleEpsilon() || minEnlargedArea > RTreeNSMFrame.doubleEpsilon()) {
+ minEnlargedArea = Double.MAX_VALUE;
+ int k;
+ if (frame.getTupleCount() > nearMinimumOverlapFactor) {
+ // sort the entries based on their area enlargement needed
+ // to include the object
+ tupleEntries1.sort(EntriesOrder.ASCENDING, frame.getTupleCount());
+ k = nearMinimumOverlapFactor;
+ } else {
+ k = frame.getTupleCount();
+ }
+
+ double minOverlap = Double.MAX_VALUE;
+ int id = 0;
+ for (int i = 0; i < k; ++i) {
+ double difference = 0.0;
+ for (int j = 0; j < frame.getTupleCount(); ++j) {
+ frameTuple.resetByTupleIndex(frame, j);
+ cmpFrameTuple.resetByTupleIndex(frame, tupleEntries1.get(i).getTupleIndex());
+
+ int c = ((RTreeNSMInteriorFrame)frame).pointerCmp(frameTuple, cmpFrameTuple, cmp);
+ if (c != 0) {
+ double intersection = RTreeComputationUtils.overlappedArea(frameTuple, tuple, cmpFrameTuple, cmp, keyValueProviders);
+ if (intersection != 0.0) {
+ difference += intersection - RTreeComputationUtils.overlappedArea(frameTuple, null, cmpFrameTuple, cmp, keyValueProviders);
+ }
+ } else {
+ id = j;
+ }
+ }
+
+ double enlargedArea = RTreeComputationUtils.enlargedArea(cmpFrameTuple, tuple, cmp, keyValueProviders);
+ if (difference < minOverlap) {
+ minOverlap = difference;
+ minEnlargedArea = enlargedArea;
+ bestChild = id;
+ } else if (difference == minOverlap) {
+ if (enlargedArea < minEnlargedArea) {
+ minEnlargedArea = enlargedArea;
+ bestChild = id;
+ } else if (enlargedArea == minEnlargedArea) {
+ double area = RTreeComputationUtils.area(cmpFrameTuple, cmp, keyValueProviders);
+ frameTuple.resetByTupleIndex(frame, bestChild);
+ double minArea = RTreeComputationUtils.area(frameTuple, cmp, keyValueProviders);
+ if (area < minArea) {
+ bestChild = id;
+ }
+ }
+ }
+ }
+ }
+ } else { // find minimum enlarged area, use minimum area to break tie
+ for (int i = 0; i < frame.getTupleCount(); i++) {
+ frameTuple.resetByTupleIndex(frame, i);
+ double enlargedArea = RTreeComputationUtils.enlargedArea(frameTuple, tuple, cmp, keyValueProviders);
+ if (enlargedArea < minEnlargedArea) {
+ minEnlargedArea = enlargedArea;
+ bestChild = i;
+ } else if (enlargedArea == minEnlargedArea) {
+ double area = RTreeComputationUtils.area(frameTuple, cmp, keyValueProviders);
+ frameTuple.resetByTupleIndex(frame, bestChild);
+ double minArea = RTreeComputationUtils.area(frameTuple, cmp, keyValueProviders);
+ if (area < minArea) {
+ bestChild = i;
+ }
+ }
+ }
+ }
+ tupleEntries1.clear();
+
+ frameTuple.resetByTupleIndex(frame, bestChild);
+ if (minEnlargedArea > 0.0) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeComputationUtils.java b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeComputationUtils.java
new file mode 100644
index 0000000..475dc6f
--- /dev/null
+++ b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeComputationUtils.java
@@ -0,0 +1,116 @@
+/*
+ * 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.rtree.frames;
+
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
+import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProvider;
+import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
+
+public class RTreeComputationUtils {
+
+ public static double enlargedArea(ITupleReference tuple, ITupleReference tupleToBeInserted, MultiComparator cmp,
+ IPrimitiveValueProvider[] keyValueProviders) {
+ double areaBeforeEnlarge = RTreeComputationUtils.area(tuple, cmp, keyValueProviders);
+ double areaAfterEnlarge = 1.0;
+
+ int maxFieldPos = cmp.getKeyFieldCount() / 2;
+ for (int i = 0; i < maxFieldPos; i++) {
+ int j = maxFieldPos + i;
+ double pHigh, pLow;
+ int c = cmp.getComparators()[i].compare(tuple.getFieldData(i), tuple.getFieldStart(i),
+ tuple.getFieldLength(i), tupleToBeInserted.getFieldData(i), tupleToBeInserted.getFieldStart(i),
+ tupleToBeInserted.getFieldLength(i));
+ if (c < 0) {
+ pLow = keyValueProviders[i].getValue(tuple.getFieldData(i), tuple.getFieldStart(i));
+ } else {
+ pLow = keyValueProviders[i].getValue(tupleToBeInserted.getFieldData(i),
+ tupleToBeInserted.getFieldStart(i));
+ }
+
+ c = cmp.getComparators()[j].compare(tuple.getFieldData(j), tuple.getFieldStart(j), tuple.getFieldLength(j),
+ tupleToBeInserted.getFieldData(j), tupleToBeInserted.getFieldStart(j),
+ tupleToBeInserted.getFieldLength(j));
+ if (c > 0) {
+ pHigh = keyValueProviders[j].getValue(tuple.getFieldData(j), tuple.getFieldStart(j));
+ } else {
+ pHigh = keyValueProviders[j].getValue(tupleToBeInserted.getFieldData(j),
+ tupleToBeInserted.getFieldStart(j));
+ }
+ areaAfterEnlarge *= pHigh - pLow;
+ }
+ return areaAfterEnlarge - areaBeforeEnlarge;
+ }
+
+ public static double overlappedArea(ITupleReference tuple1, ITupleReference tupleToBeInserted,
+ ITupleReference tuple2, MultiComparator cmp, IPrimitiveValueProvider[] keyValueProviders) {
+ double area = 1.0;
+ double f1, f2;
+
+ int maxFieldPos = cmp.getKeyFieldCount() / 2;
+ for (int i = 0; i < maxFieldPos; i++) {
+ int j = maxFieldPos + i;
+ double pHigh1, pLow1;
+ if (tupleToBeInserted != null) {
+ int c = cmp.getComparators()[i].compare(tuple1.getFieldData(i), tuple1.getFieldStart(i),
+ tuple1.getFieldLength(i), tupleToBeInserted.getFieldData(i),
+ tupleToBeInserted.getFieldStart(i), tupleToBeInserted.getFieldLength(i));
+ if (c < 0) {
+ pLow1 = keyValueProviders[i].getValue(tuple1.getFieldData(i), tuple1.getFieldStart(i));
+ } else {
+ pLow1 = keyValueProviders[i].getValue(tupleToBeInserted.getFieldData(i),
+ tupleToBeInserted.getFieldStart(i));
+ }
+
+ c = cmp.getComparators()[j].compare(tuple1.getFieldData(j), tuple1.getFieldStart(j),
+ tuple1.getFieldLength(j), tupleToBeInserted.getFieldData(j),
+ tupleToBeInserted.getFieldStart(j), tupleToBeInserted.getFieldLength(j));
+ if (c > 0) {
+ pHigh1 = keyValueProviders[j].getValue(tuple1.getFieldData(j), tuple1.getFieldStart(j));
+ } else {
+ pHigh1 = keyValueProviders[j].getValue(tupleToBeInserted.getFieldData(j),
+ tupleToBeInserted.getFieldStart(j));
+ }
+ } else {
+ pLow1 = keyValueProviders[i].getValue(tuple1.getFieldData(i), tuple1.getFieldStart(i));
+ pHigh1 = keyValueProviders[j].getValue(tuple1.getFieldData(j), tuple1.getFieldStart(j));
+ }
+
+ double pLow2 = keyValueProviders[i].getValue(tuple2.getFieldData(i), tuple2.getFieldStart(i));
+ double pHigh2 = keyValueProviders[j].getValue(tuple2.getFieldData(j), tuple2.getFieldStart(j));
+
+ if (pLow1 > pHigh2 || pHigh1 < pLow2) {
+ return 0.0;
+ }
+
+ f1 = Math.max(pLow1, pLow2);
+ f2 = Math.min(pHigh1, pHigh2);
+ area *= f2 - f1;
+ }
+ return area;
+ }
+
+ public static double area(ITupleReference tuple, MultiComparator cmp, IPrimitiveValueProvider[] keyValueProviders) {
+ double area = 1.0;
+ int maxFieldPos = cmp.getKeyFieldCount() / 2;
+ for (int i = 0; i < maxFieldPos; i++) {
+ int j = maxFieldPos + i;
+ area *= keyValueProviders[j].getValue(tuple.getFieldData(j), tuple.getFieldStart(j))
+ - keyValueProviders[i].getValue(tuple.getFieldData(i), tuple.getFieldStart(i));
+ }
+ return area;
+ }
+
+}
\ No newline at end of file
diff --git a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMFrame.java b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMFrame.java
index 6943199..23c717d 100644
--- a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMFrame.java
+++ b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMFrame.java
@@ -22,13 +22,12 @@
import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexTupleReference;
import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexTupleWriter;
import edu.uci.ics.hyracks.storage.am.common.frames.TreeIndexNSMFrame;
+import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
import edu.uci.ics.hyracks.storage.am.rtree.api.IRTreeFrame;
-import edu.uci.ics.hyracks.storage.am.rtree.impls.EntriesOrder;
-import edu.uci.ics.hyracks.storage.am.rtree.impls.RTreeSplitKey;
+import edu.uci.ics.hyracks.storage.am.rtree.api.IRTreePolicy;
import edu.uci.ics.hyracks.storage.am.rtree.impls.Rectangle;
import edu.uci.ics.hyracks.storage.am.rtree.impls.TupleEntryArrayList;
import edu.uci.ics.hyracks.storage.am.rtree.impls.UnorderedSlotManager;
-import edu.uci.ics.hyracks.storage.am.rtree.tuples.RTreeTypeAwareTupleWriter;
public abstract class RTreeNSMFrame extends TreeIndexNSMFrame implements IRTreeFrame {
protected static final int pageNsnOff = smFlagOff + 1;
@@ -42,13 +41,14 @@
protected Rectangle[] rec;
- protected static final double splitFactor = 0.4;
- protected static final int nearMinimumOverlapFactor = 32;
private static final double doubleEpsilon = computeDoubleEpsilon();
- private static final int numTuplesEntries = 100;
+ private static final int numTuplesEntries = 500;
protected final IPrimitiveValueProvider[] keyValueProviders;
- public RTreeNSMFrame(ITreeIndexTupleWriter tupleWriter, IPrimitiveValueProvider[] keyValueProviders) {
+ protected IRTreePolicy rtreePolicy;
+
+ public RTreeNSMFrame(ITreeIndexTupleWriter tupleWriter, IPrimitiveValueProvider[] keyValueProviders,
+ RTreePolicyType rtreePolicyType) {
super(tupleWriter, new UnorderedSlotManager());
this.tuples = new ITreeIndexTupleReference[keyValueProviders.length];
for (int i = 0; i < keyValueProviders.length; i++) {
@@ -63,6 +63,13 @@
rec[i] = new Rectangle(keyValueProviders.length / 2);
}
this.keyValueProviders = keyValueProviders;
+
+ if (rtreePolicyType == RTreePolicyType.RTREE) {
+ rtreePolicy = new RTreePolicy(tupleWriter, keyValueProviders, cmpFrameTuple, totalFreeSpaceOff);
+ } else {
+ rtreePolicy = new RStarTreePolicy(tupleWriter, keyValueProviders, cmpFrameTuple, totalFreeSpaceOff);
+ }
+
}
private static double computeDoubleEpsilon() {
@@ -115,161 +122,13 @@
buf.putInt(rightPageOff, rightPage);
}
- protected ITreeIndexTupleReference[] getTuples() {
+ public ITreeIndexTupleReference[] getTuples() {
return tuples;
}
@Override
public void split(ITreeIndexFrame rightFrame, ITupleReference tuple, ISplitKey splitKey) {
- RTreeSplitKey rTreeSplitKey = ((RTreeSplitKey) splitKey);
- RTreeTypeAwareTupleWriter rTreeTupleWriterLeftFrame = ((RTreeTypeAwareTupleWriter) tupleWriter);
- RTreeTypeAwareTupleWriter rTreeTupleWriterRightFrame = ((RTreeTypeAwareTupleWriter) rightFrame.getTupleWriter());
-
- // calculations are based on the R*-tree paper
- int m = (int) Math.floor((getTupleCount() + 1) * splitFactor);
- int splitDistribution = getTupleCount() - (2 * m) + 2;
-
- // to calculate the minimum margin in order to pick the split axis
- double minMargin = Double.MAX_VALUE;
- int splitAxis = 0, sortOrder = 0;
-
- int maxFieldPos = keyValueProviders.length / 2;
- for (int i = 0; i < maxFieldPos; i++) {
- int j = maxFieldPos + i;
- for (int k = 0; k < getTupleCount(); ++k) {
-
- frameTuple.resetByTupleIndex(this, k);
- double LowerKey = keyValueProviders[i]
- .getValue(frameTuple.getFieldData(i), frameTuple.getFieldStart(i));
- double UpperKey = keyValueProviders[j]
- .getValue(frameTuple.getFieldData(j), frameTuple.getFieldStart(j));
-
- tupleEntries1.add(k, LowerKey);
- tupleEntries2.add(k, UpperKey);
- }
- double LowerKey = keyValueProviders[i].getValue(tuple.getFieldData(i), tuple.getFieldStart(i));
- double UpperKey = keyValueProviders[j].getValue(tuple.getFieldData(j), tuple.getFieldStart(j));
-
- tupleEntries1.add(-1, LowerKey);
- tupleEntries2.add(-1, UpperKey);
-
- tupleEntries1.sort(EntriesOrder.ASCENDING, getTupleCount() + 1);
- tupleEntries2.sort(EntriesOrder.ASCENDING, getTupleCount() + 1);
-
- double lowerMargin = 0.0, upperMargin = 0.0;
- // generate distribution
- for (int k = 1; k <= splitDistribution; ++k) {
- int d = m - 1 + k;
-
- generateDist(tuple, tupleEntries1, rec[0], 0, d);
- generateDist(tuple, tupleEntries2, rec[1], 0, d);
- generateDist(tuple, tupleEntries1, rec[2], d, getTupleCount() + 1);
- generateDist(tuple, tupleEntries2, rec[3], d, getTupleCount() + 1);
-
- // calculate the margin of the distributions
- lowerMargin += rec[0].margin() + rec[2].margin();
- upperMargin += rec[1].margin() + rec[3].margin();
- }
- double margin = Math.min(lowerMargin, upperMargin);
-
- // store minimum margin as split axis
- if (margin < minMargin) {
- minMargin = margin;
- splitAxis = i;
- sortOrder = (lowerMargin < upperMargin) ? 0 : 2;
- }
-
- tupleEntries1.clear();
- tupleEntries2.clear();
- }
-
- for (int i = 0; i < getTupleCount(); ++i) {
- frameTuple.resetByTupleIndex(this, i);
- double key = keyValueProviders[splitAxis + sortOrder].getValue(
- frameTuple.getFieldData(splitAxis + sortOrder), frameTuple.getFieldStart(splitAxis + sortOrder));
- tupleEntries1.add(i, key);
- }
- double key = keyValueProviders[splitAxis + sortOrder].getValue(tuple.getFieldData(splitAxis + sortOrder),
- tuple.getFieldStart(splitAxis + sortOrder));
- tupleEntries1.add(-1, key);
- tupleEntries1.sort(EntriesOrder.ASCENDING, getTupleCount() + 1);
-
- double minArea = Double.MAX_VALUE;
- double minOverlap = Double.MAX_VALUE;
- int splitPoint = 0;
- for (int i = 1; i <= splitDistribution; ++i) {
- int d = m - 1 + i;
-
- generateDist(tuple, tupleEntries1, rec[0], 0, d);
- generateDist(tuple, tupleEntries1, rec[2], d, getTupleCount() + 1);
-
- double overlap = rec[0].overlappedArea(rec[2]);
- if (overlap < minOverlap) {
- splitPoint = d;
- minOverlap = overlap;
- minArea = rec[0].area() + rec[2].area();
- } else if (overlap == minOverlap) {
- double area = rec[0].area() + rec[2].area();
- if (area < minArea) {
- splitPoint = d;
- minArea = area;
- }
- }
- }
- int startIndex, endIndex;
- if (splitPoint < (getTupleCount() + 1) / 2) {
- startIndex = 0;
- endIndex = splitPoint;
- } else {
- startIndex = splitPoint;
- endIndex = (getTupleCount() + 1);
- }
- boolean tupleInserted = false;
- int totalBytes = 0, numOfDeletedTuples = 0;
- for (int i = startIndex; i < endIndex; i++) {
- if (tupleEntries1.get(i).getTupleIndex() != -1) {
- frameTuple.resetByTupleIndex(this, tupleEntries1.get(i).getTupleIndex());
- rightFrame.insert(frameTuple, -1);
- ((UnorderedSlotManager) slotManager).modifySlot(
- slotManager.getSlotOff(tupleEntries1.get(i).getTupleIndex()), -1);
- totalBytes += getTupleSize(frameTuple);
- numOfDeletedTuples++;
- } else {
- rightFrame.insert(tuple, -1);
- tupleInserted = true;
- }
- }
-
- ((UnorderedSlotManager) slotManager).deleteEmptySlots();
-
- // maintain space information
- buf.putInt(totalFreeSpaceOff, buf.getInt(totalFreeSpaceOff) + totalBytes
- + (slotManager.getSlotSize() * numOfDeletedTuples));
-
- // compact both pages
- rightFrame.compact();
- compact();
-
- if (!tupleInserted) {
- insert(tuple, -1);
- }
-
- int tupleOff = slotManager.getTupleOff(slotManager.getSlotEndOff());
- frameTuple.resetByTupleOffset(buf, tupleOff);
- int splitKeySize = tupleWriter.bytesRequired(frameTuple, 0, keyValueProviders.length);
-
- splitKey.initData(splitKeySize);
- this.adjustMBR();
- rTreeTupleWriterLeftFrame.writeTupleFields(getTuples(), 0, rTreeSplitKey.getLeftPageBuffer(), 0);
- rTreeSplitKey.getLeftTuple().resetByTupleOffset(rTreeSplitKey.getLeftPageBuffer(), 0);
-
- ((IRTreeFrame) rightFrame).adjustMBR();
- rTreeTupleWriterRightFrame.writeTupleFields(((RTreeNSMFrame) rightFrame).getTuples(), 0,
- rTreeSplitKey.getRightPageBuffer(), 0);
- rTreeSplitKey.getRightTuple().resetByTupleOffset(rTreeSplitKey.getRightPageBuffer(), 0);
-
- tupleEntries1.clear();
- tupleEntries2.clear();
+ rtreePolicy.split(this, buf, rightFrame, slotManager, frameTuple, tuple, splitKey);
}
abstract public int getTupleSize(ITupleReference tuple);
@@ -329,4 +188,9 @@
public int getPageHeaderSize() {
return rightPageOff;
}
+
+ @Override
+ public void setMultiComparator(MultiComparator cmp) {
+ // currently, R-Tree Frames are unsorted
+ }
}
\ No newline at end of file
diff --git a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMInteriorFrame.java b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMInteriorFrame.java
index 63387ef..c1d93c4 100644
--- a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMInteriorFrame.java
+++ b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMInteriorFrame.java
@@ -31,7 +31,6 @@
import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
import edu.uci.ics.hyracks.storage.am.common.ophelpers.SlotOffTupleOff;
import edu.uci.ics.hyracks.storage.am.rtree.api.IRTreeInteriorFrame;
-import edu.uci.ics.hyracks.storage.am.rtree.impls.EntriesOrder;
import edu.uci.ics.hyracks.storage.am.rtree.impls.PathList;
public class RTreeNSMInteriorFrame extends RTreeNSMFrame implements IRTreeInteriorFrame {
@@ -41,109 +40,16 @@
.createBinaryComparator();
private final int keyFieldCount;
- public RTreeNSMInteriorFrame(ITreeIndexTupleWriter tupleWriter, IPrimitiveValueProvider[] keyValueProviders) {
- super(tupleWriter, keyValueProviders);
+ public RTreeNSMInteriorFrame(ITreeIndexTupleWriter tupleWriter, IPrimitiveValueProvider[] keyValueProviders,
+ RTreePolicyType rtreePolicyType) {
+ super(tupleWriter, keyValueProviders, rtreePolicyType);
keyFieldCount = keyValueProviders.length;
frameTuple.setFieldCount(keyFieldCount);
}
@Override
public boolean findBestChild(ITupleReference tuple, MultiComparator cmp) {
- cmpFrameTuple.setFieldCount(cmp.getKeyFieldCount());
- frameTuple.setFieldCount(cmp.getKeyFieldCount());
-
- int bestChild = 0;
- double minEnlargedArea = Double.MAX_VALUE;
-
- // the children pointers in the node point to leaves
- if (getLevel() == 1) {
- // find least overlap enlargement, use minimum enlarged area to
- // break tie, if tie still exists use minimum area to break it
- for (int i = 0; i < getTupleCount(); ++i) {
- frameTuple.resetByTupleIndex(this, i);
- double enlargedArea = enlargedArea(frameTuple, tuple, cmp);
- tupleEntries1.add(i, enlargedArea);
- if (enlargedArea < minEnlargedArea) {
- minEnlargedArea = enlargedArea;
- bestChild = i;
- }
- }
- if (minEnlargedArea < RTreeNSMFrame.doubleEpsilon() || minEnlargedArea > RTreeNSMFrame.doubleEpsilon()) {
- minEnlargedArea = Double.MAX_VALUE;
- int k;
- if (getTupleCount() > nearMinimumOverlapFactor) {
- // sort the entries based on their area enlargement needed
- // to include the object
- tupleEntries1.sort(EntriesOrder.ASCENDING, getTupleCount());
- k = nearMinimumOverlapFactor;
- } else {
- k = getTupleCount();
- }
-
- double minOverlap = Double.MAX_VALUE;
- int id = 0;
- for (int i = 0; i < k; ++i) {
- double difference = 0.0;
- for (int j = 0; j < getTupleCount(); ++j) {
- frameTuple.resetByTupleIndex(this, j);
- cmpFrameTuple.resetByTupleIndex(this, tupleEntries1.get(i).getTupleIndex());
-
- int c = pointerCmp(frameTuple, cmpFrameTuple, cmp);
- if (c != 0) {
- double intersection = overlappedArea(frameTuple, tuple, cmpFrameTuple, cmp);
- if (intersection != 0.0) {
- difference += intersection - overlappedArea(frameTuple, null, cmpFrameTuple, cmp);
- }
- } else {
- id = j;
- }
- }
-
- double enlargedArea = enlargedArea(cmpFrameTuple, tuple, cmp);
- if (difference < minOverlap) {
- minOverlap = difference;
- minEnlargedArea = enlargedArea;
- bestChild = id;
- } else if (difference == minOverlap) {
- if (enlargedArea < minEnlargedArea) {
- minEnlargedArea = enlargedArea;
- bestChild = id;
- } else if (enlargedArea == minEnlargedArea) {
- double area = area(cmpFrameTuple, cmp);
- frameTuple.resetByTupleIndex(this, bestChild);
- double minArea = area(frameTuple, cmp);
- if (area < minArea) {
- bestChild = id;
- }
- }
- }
- }
- }
- } else { // find minimum enlarged area, use minimum area to break tie
- for (int i = 0; i < getTupleCount(); i++) {
- frameTuple.resetByTupleIndex(this, i);
- double enlargedArea = enlargedArea(frameTuple, tuple, cmp);
- if (enlargedArea < minEnlargedArea) {
- minEnlargedArea = enlargedArea;
- bestChild = i;
- } else if (enlargedArea == minEnlargedArea) {
- double area = area(frameTuple, cmp);
- frameTuple.resetByTupleIndex(this, bestChild);
- double minArea = area(frameTuple, cmp);
- if (area < minArea) {
- bestChild = i;
- }
- }
- }
- }
- tupleEntries1.clear();
-
- frameTuple.resetByTupleIndex(this, bestChild);
- if (minEnlargedArea > 0.0) {
- return true;
- } else {
- return false;
- }
+ return rtreePolicy.findBestChild(this, tuple, frameTuple, cmp);
}
@Override
@@ -279,7 +185,7 @@
}
- private int pointerCmp(ITupleReference tupleA, ITupleReference tupleB, MultiComparator cmp) {
+ protected int pointerCmp(ITupleReference tupleA, ITupleReference tupleB, MultiComparator cmp) {
return childPtrCmp
.compare(tupleA.getFieldData(cmp.getKeyFieldCount() - 1), getChildPointerOff(tupleA), childPtrSize,
tupleB.getFieldData(cmp.getKeyFieldCount() - 1), getChildPointerOff(tupleB), childPtrSize);
@@ -354,97 +260,6 @@
return false;
}
- private double overlappedArea(ITupleReference tuple1, ITupleReference tupleToBeInserted, ITupleReference tuple2,
- MultiComparator cmp) {
- double area = 1.0;
- double f1, f2;
-
- int maxFieldPos = cmp.getKeyFieldCount() / 2;
- for (int i = 0; i < maxFieldPos; i++) {
- int j = maxFieldPos + i;
- double pHigh1, pLow1;
- if (tupleToBeInserted != null) {
- int c = cmp.getComparators()[i].compare(tuple1.getFieldData(i), tuple1.getFieldStart(i),
- tuple1.getFieldLength(i), tupleToBeInserted.getFieldData(i),
- tupleToBeInserted.getFieldStart(i), tupleToBeInserted.getFieldLength(i));
- if (c < 0) {
- pLow1 = keyValueProviders[i].getValue(tuple1.getFieldData(i), tuple1.getFieldStart(i));
- } else {
- pLow1 = keyValueProviders[i].getValue(tupleToBeInserted.getFieldData(i),
- tupleToBeInserted.getFieldStart(i));
- }
-
- c = cmp.getComparators()[j].compare(tuple1.getFieldData(j), tuple1.getFieldStart(j),
- tuple1.getFieldLength(j), tupleToBeInserted.getFieldData(j),
- tupleToBeInserted.getFieldStart(j), tupleToBeInserted.getFieldLength(j));
- if (c > 0) {
- pHigh1 = keyValueProviders[j].getValue(tuple1.getFieldData(j), tuple1.getFieldStart(j));
- } else {
- pHigh1 = keyValueProviders[j].getValue(tupleToBeInserted.getFieldData(j),
- tupleToBeInserted.getFieldStart(j));
- }
- } else {
- pLow1 = keyValueProviders[i].getValue(tuple1.getFieldData(i), tuple1.getFieldStart(i));
- pHigh1 = keyValueProviders[j].getValue(tuple1.getFieldData(j), tuple1.getFieldStart(j));
- }
-
- double pLow2 = keyValueProviders[i].getValue(tuple2.getFieldData(i), tuple2.getFieldStart(i));
- double pHigh2 = keyValueProviders[j].getValue(tuple2.getFieldData(j), tuple2.getFieldStart(j));
-
- if (pLow1 > pHigh2 || pHigh1 < pLow2) {
- return 0.0;
- }
-
- f1 = Math.max(pLow1, pLow2);
- f2 = Math.min(pHigh1, pHigh2);
- area *= f2 - f1;
- }
- return area;
- }
-
- private double enlargedArea(ITupleReference tuple, ITupleReference tupleToBeInserted, MultiComparator cmp) {
- double areaBeforeEnlarge = area(tuple, cmp);
- double areaAfterEnlarge = 1.0;
-
- int maxFieldPos = cmp.getKeyFieldCount() / 2;
- for (int i = 0; i < maxFieldPos; i++) {
- int j = maxFieldPos + i;
- double pHigh, pLow;
- int c = cmp.getComparators()[i].compare(tuple.getFieldData(i), tuple.getFieldStart(i),
- tuple.getFieldLength(i), tupleToBeInserted.getFieldData(i), tupleToBeInserted.getFieldStart(i),
- tupleToBeInserted.getFieldLength(i));
- if (c < 0) {
- pLow = keyValueProviders[i].getValue(tuple.getFieldData(i), tuple.getFieldStart(i));
- } else {
- pLow = keyValueProviders[i].getValue(tupleToBeInserted.getFieldData(i),
- tupleToBeInserted.getFieldStart(i));
- }
-
- c = cmp.getComparators()[j].compare(tuple.getFieldData(j), tuple.getFieldStart(j), tuple.getFieldLength(j),
- tupleToBeInserted.getFieldData(j), tupleToBeInserted.getFieldStart(j),
- tupleToBeInserted.getFieldLength(j));
- if (c > 0) {
- pHigh = keyValueProviders[j].getValue(tuple.getFieldData(j), tuple.getFieldStart(j));
- } else {
- pHigh = keyValueProviders[j].getValue(tupleToBeInserted.getFieldData(j),
- tupleToBeInserted.getFieldStart(j));
- }
- areaAfterEnlarge *= pHigh - pLow;
- }
- return areaAfterEnlarge - areaBeforeEnlarge;
- }
-
- private double area(ITupleReference tuple, MultiComparator cmp) {
- double area = 1.0;
- int maxFieldPos = cmp.getKeyFieldCount() / 2;
- for (int i = 0; i < maxFieldPos; i++) {
- int j = maxFieldPos + i;
- area *= keyValueProviders[j].getValue(tuple.getFieldData(j), tuple.getFieldStart(j))
- - keyValueProviders[i].getValue(tuple.getFieldData(i), tuple.getFieldStart(i));
- }
- return area;
- }
-
@Override
public boolean checkEnlargement(ITupleReference tuple, MultiComparator cmp) {
int maxFieldPos = cmp.getKeyFieldCount() / 2;
@@ -509,4 +324,8 @@
public int getFieldCount() {
return keyValueProviders.length;
}
+
+ public int getChildPointerSize() {
+ return childPtrSize;
+ }
}
diff --git a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMInteriorFrameFactory.java b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMInteriorFrameFactory.java
index 943a179..fdb0e0a 100644
--- a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMInteriorFrameFactory.java
+++ b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMInteriorFrameFactory.java
@@ -26,13 +26,16 @@
private static final long serialVersionUID = 1L;
private final ITreeIndexTupleWriterFactory tupleWriterFactory;
private final IPrimitiveValueProviderFactory[] keyValueProviderFactories;
+ private final RTreePolicyType rtreePolicyType;
- public RTreeNSMInteriorFrameFactory(ITreeIndexTupleWriterFactory tupleWriterFactory, IPrimitiveValueProviderFactory[] keyValueProviderFactories) {
+ public RTreeNSMInteriorFrameFactory(ITreeIndexTupleWriterFactory tupleWriterFactory,
+ IPrimitiveValueProviderFactory[] keyValueProviderFactories, RTreePolicyType rtreePolicyType) {
this.tupleWriterFactory = tupleWriterFactory;
if (keyValueProviderFactories.length % 2 != 0) {
throw new IllegalArgumentException("The key has different number of dimensions.");
}
this.keyValueProviderFactories = keyValueProviderFactories;
+ this.rtreePolicyType = rtreePolicyType;
}
@Override
@@ -41,11 +44,11 @@
for (int i = 0; i < keyValueProviders.length; i++) {
keyValueProviders[i] = keyValueProviderFactories[i].createPrimitiveValueProvider();
}
- return new RTreeNSMInteriorFrame(tupleWriterFactory.createTupleWriter(), keyValueProviders);
+ return new RTreeNSMInteriorFrame(tupleWriterFactory.createTupleWriter(), keyValueProviders, rtreePolicyType);
}
- @Override
- public ITreeIndexTupleWriterFactory getTupleWriterFactory() {
- return tupleWriterFactory;
- }
+ @Override
+ public ITreeIndexTupleWriterFactory getTupleWriterFactory() {
+ return tupleWriterFactory;
+ }
}
diff --git a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMLeafFrame.java b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMLeafFrame.java
index 3c6701e..d52ef16 100644
--- a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMLeafFrame.java
+++ b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMLeafFrame.java
@@ -24,8 +24,9 @@
public class RTreeNSMLeafFrame extends RTreeNSMFrame implements IRTreeLeafFrame {
- public RTreeNSMLeafFrame(ITreeIndexTupleWriter tupleWriter, IPrimitiveValueProvider[] keyValueProviders) {
- super(tupleWriter, keyValueProviders);
+ public RTreeNSMLeafFrame(ITreeIndexTupleWriter tupleWriter, IPrimitiveValueProvider[] keyValueProviders,
+ RTreePolicyType rtreePolicyType) {
+ super(tupleWriter, keyValueProviders, rtreePolicyType);
}
@Override
diff --git a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMLeafFrameFactory.java b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMLeafFrameFactory.java
index e31148f..b4d382b 100644
--- a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMLeafFrameFactory.java
+++ b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMLeafFrameFactory.java
@@ -26,13 +26,16 @@
private static final long serialVersionUID = 1L;
private final ITreeIndexTupleWriterFactory tupleWriterFactory;
private final IPrimitiveValueProviderFactory[] keyValueProviderFactories;
+ private final RTreePolicyType rtreePolicyType;
- public RTreeNSMLeafFrameFactory(ITreeIndexTupleWriterFactory tupleWriterFactory, IPrimitiveValueProviderFactory[] keyValueProviderFactories) {
+ public RTreeNSMLeafFrameFactory(ITreeIndexTupleWriterFactory tupleWriterFactory,
+ IPrimitiveValueProviderFactory[] keyValueProviderFactories, RTreePolicyType rtreePolicyType) {
this.tupleWriterFactory = tupleWriterFactory;
if (keyValueProviderFactories.length % 2 != 0) {
throw new IllegalArgumentException("The key has different number of dimensions.");
}
this.keyValueProviderFactories = keyValueProviderFactories;
+ this.rtreePolicyType = rtreePolicyType;
}
@Override
@@ -41,11 +44,11 @@
for (int i = 0; i < keyValueProviders.length; i++) {
keyValueProviders[i] = keyValueProviderFactories[i].createPrimitiveValueProvider();
}
- return new RTreeNSMLeafFrame(tupleWriterFactory.createTupleWriter(), keyValueProviders);
+ return new RTreeNSMLeafFrame(tupleWriterFactory.createTupleWriter(), keyValueProviders, rtreePolicyType);
}
- @Override
- public ITreeIndexTupleWriterFactory getTupleWriterFactory() {
- return tupleWriterFactory;
- }
+ @Override
+ public ITreeIndexTupleWriterFactory getTupleWriterFactory() {
+ return tupleWriterFactory;
+ }
}
diff --git a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreePolicy.java b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreePolicy.java
new file mode 100644
index 0000000..7f69661
--- /dev/null
+++ b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreePolicy.java
@@ -0,0 +1,236 @@
+/*
+ * 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.rtree.frames;
+
+import java.nio.ByteBuffer;
+
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
+import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProvider;
+import edu.uci.ics.hyracks.storage.am.common.api.ISlotManager;
+import edu.uci.ics.hyracks.storage.am.common.api.ISplitKey;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrame;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexTupleReference;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexTupleWriter;
+import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
+import edu.uci.ics.hyracks.storage.am.rtree.api.IRTreeFrame;
+import edu.uci.ics.hyracks.storage.am.rtree.api.IRTreePolicy;
+import edu.uci.ics.hyracks.storage.am.rtree.impls.RTreeSplitKey;
+import edu.uci.ics.hyracks.storage.am.rtree.impls.Rectangle;
+import edu.uci.ics.hyracks.storage.am.rtree.impls.UnorderedSlotManager;
+import edu.uci.ics.hyracks.storage.am.rtree.tuples.RTreeTypeAwareTupleWriter;
+
+public class RTreePolicy implements IRTreePolicy {
+
+ private Rectangle[] rec;
+
+ private final ITreeIndexTupleWriter tupleWriter;
+ private final IPrimitiveValueProvider[] keyValueProviders;
+ private ITreeIndexTupleReference cmpFrameTuple;
+ private final int totalFreeSpaceOff;
+
+ public RTreePolicy(ITreeIndexTupleWriter tupleWriter, IPrimitiveValueProvider[] keyValueProviders,
+ ITreeIndexTupleReference cmpFrameTuple, int totalFreeSpaceOff) {
+ this.tupleWriter = tupleWriter;
+ this.keyValueProviders = keyValueProviders;
+ this.cmpFrameTuple = cmpFrameTuple;
+ this.totalFreeSpaceOff = totalFreeSpaceOff;
+
+ rec = new Rectangle[2];
+ for (int i = 0; i < 2; i++) {
+ rec[i] = new Rectangle(keyValueProviders.length / 2);
+ }
+ }
+
+ public void split(ITreeIndexFrame leftFrame, ByteBuffer buf, ITreeIndexFrame rightFrame, ISlotManager slotManager,
+ ITreeIndexTupleReference frameTuple, ITupleReference tuple, ISplitKey splitKey) {
+ RTreeSplitKey rTreeSplitKey = ((RTreeSplitKey) splitKey);
+ RTreeTypeAwareTupleWriter rTreeTupleWriterLeftFrame = ((RTreeTypeAwareTupleWriter) tupleWriter);
+ RTreeTypeAwareTupleWriter rTreeTupleWriterRightFrame = ((RTreeTypeAwareTupleWriter) rightFrame.getTupleWriter());
+
+ RTreeNSMFrame leftRTreeFrame = ((RTreeNSMFrame) leftFrame);
+
+ double separation = Double.NEGATIVE_INFINITY;
+ int seed1 = 0, seed2 = 0;
+ int maxFieldPos = keyValueProviders.length / 2;
+ for (int i = 0; i < maxFieldPos; i++) {
+ int j = maxFieldPos + i;
+ frameTuple.resetByTupleIndex(leftRTreeFrame, 0);
+ double leastLowerValue = keyValueProviders[i].getValue(tuple.getFieldData(i), tuple.getFieldStart(i));
+ double greatestUpperValue = keyValueProviders[j].getValue(tuple.getFieldData(j), tuple.getFieldStart(j));
+ double leastUpperValue = leastLowerValue;
+ double greatestLowerValue = greatestUpperValue;
+ int leastUpperIndex = -1;
+ int greatestLowerIndex = -1;
+ double width;
+
+ for (int k = 0; k < leftRTreeFrame.getTupleCount(); ++k) {
+ frameTuple.resetByTupleIndex(leftRTreeFrame, k);
+ double lowerValue = keyValueProviders[i].getValue(frameTuple.getFieldData(i),
+ frameTuple.getFieldStart(i));
+ if (lowerValue > greatestLowerValue) {
+ greatestLowerIndex = k;
+ cmpFrameTuple.resetByTupleIndex(leftRTreeFrame, k);
+ greatestLowerValue = keyValueProviders[i].getValue(cmpFrameTuple.getFieldData(i),
+ cmpFrameTuple.getFieldStart(i));
+ }
+ double higherValue = keyValueProviders[j].getValue(frameTuple.getFieldData(j),
+ frameTuple.getFieldStart(j));
+ if (higherValue < leastUpperValue) {
+ leastUpperIndex = k;
+ cmpFrameTuple.resetByTupleIndex(leftRTreeFrame, k);
+ leastUpperValue = keyValueProviders[j].getValue(cmpFrameTuple.getFieldData(j),
+ cmpFrameTuple.getFieldStart(j));
+ }
+
+ leastLowerValue = Math.min(lowerValue, leastLowerValue);
+ greatestUpperValue = Math.max(higherValue, greatestUpperValue);
+ }
+
+ width = greatestUpperValue - leastLowerValue;
+ if (width <= 0) {
+ width = 1;
+ }
+
+ double f = (greatestLowerValue - leastUpperValue) / width;
+
+ if (f > separation) {
+ seed1 = leastUpperIndex;
+ seed2 = greatestLowerIndex;
+ separation = f;
+ }
+ }
+
+ if (seed1 == -1 && seed1 == seed2) {
+ seed2 = 0;
+ } else if (seed1 == seed2) {
+ if (seed2 == 0) {
+ ++seed2;
+ } else {
+ --seed2;
+ }
+ }
+
+ int totalBytes = 0, numOfDeletedTuples = 0;
+ if (seed1 == -1) {
+ rightFrame.insert(tuple, -1);
+ rec[0].set(tuple, keyValueProviders);
+ } else {
+ frameTuple.resetByTupleIndex(leftRTreeFrame, seed1);
+ rec[0].set(frameTuple, keyValueProviders);
+ rightFrame.insert(frameTuple, -1);
+ ((UnorderedSlotManager) slotManager).modifySlot(slotManager.getSlotOff(seed1), -1);
+ totalBytes += leftRTreeFrame.getTupleSize(frameTuple);
+ numOfDeletedTuples++;
+ }
+
+ if (seed2 == -1) {
+ rec[1].set(tuple, keyValueProviders);
+ } else {
+ frameTuple.resetByTupleIndex(leftRTreeFrame, seed2);
+ rec[1].set(frameTuple, keyValueProviders);
+ }
+ int remainingTuplestoBeInsertedInRightFrame;
+ for (int k = 0; k < leftRTreeFrame.getTupleCount(); ++k) {
+ remainingTuplestoBeInsertedInRightFrame = leftRTreeFrame.getTupleCount() / 2 - rightFrame.getTupleCount();
+ if (remainingTuplestoBeInsertedInRightFrame == 0) {
+ break;
+ }
+ if (k != seed1 && k != seed2) {
+ frameTuple.resetByTupleIndex(leftRTreeFrame, k);
+ if (rec[0].enlargedArea(frameTuple, keyValueProviders) < rec[1].enlargedArea(frameTuple,
+ keyValueProviders)
+ || leftRTreeFrame.getTupleCount() - k <= remainingTuplestoBeInsertedInRightFrame) {
+ rightFrame.insert(frameTuple, -1);
+ rec[0].enlarge(frameTuple, keyValueProviders);
+ ((UnorderedSlotManager) slotManager).modifySlot(slotManager.getSlotOff(k), -1);
+ totalBytes += leftRTreeFrame.getTupleSize(frameTuple);
+ numOfDeletedTuples++;
+ } else {
+ rec[1].enlarge(frameTuple, keyValueProviders);
+ }
+ }
+
+ }
+
+ ((UnorderedSlotManager) slotManager).deleteEmptySlots();
+
+ // maintain space information
+ buf.putInt(totalFreeSpaceOff, buf.getInt(totalFreeSpaceOff) + totalBytes
+ + (slotManager.getSlotSize() * numOfDeletedTuples));
+
+ // compact both pages
+ rightFrame.compact();
+ leftRTreeFrame.compact();
+
+ if (seed2 == -1) {
+ leftRTreeFrame.insert(tuple, -1);
+ } else if (seed1 != -1
+ && rec[0].enlargedArea(tuple, keyValueProviders) < rec[1].enlargedArea(tuple, keyValueProviders)) {
+ rightFrame.insert(tuple, -1);
+ } else if (seed1 != -1) {
+ leftRTreeFrame.insert(tuple, -1);
+ }
+
+ int tupleOff = slotManager.getTupleOff(slotManager.getSlotEndOff());
+ frameTuple.resetByTupleOffset(buf, tupleOff);
+ int splitKeySize = tupleWriter.bytesRequired(frameTuple, 0, keyValueProviders.length);
+
+ splitKey.initData(splitKeySize);
+ leftRTreeFrame.adjustMBR();
+ rTreeTupleWriterLeftFrame.writeTupleFields(leftRTreeFrame.getTuples(), 0, rTreeSplitKey.getLeftPageBuffer(), 0);
+ rTreeSplitKey.getLeftTuple().resetByTupleOffset(rTreeSplitKey.getLeftPageBuffer(), 0);
+
+ ((IRTreeFrame) rightFrame).adjustMBR();
+ rTreeTupleWriterRightFrame.writeTupleFields(((RTreeNSMFrame) rightFrame).getTuples(), 0,
+ rTreeSplitKey.getRightPageBuffer(), 0);
+ rTreeSplitKey.getRightTuple().resetByTupleOffset(rTreeSplitKey.getRightPageBuffer(), 0);
+
+ }
+
+ public boolean findBestChild(ITreeIndexFrame frame, ITupleReference tuple, ITreeIndexTupleReference frameTuple,
+ MultiComparator cmp) {
+ cmpFrameTuple.setFieldCount(cmp.getKeyFieldCount());
+ frameTuple.setFieldCount(cmp.getKeyFieldCount());
+
+ int bestChild = 0;
+ double minEnlargedArea = Double.MAX_VALUE;
+
+ // find minimum enlarged area, use minimum area to break tie
+ for (int i = 0; i < frame.getTupleCount(); i++) {
+ frameTuple.resetByTupleIndex(frame, i);
+ double enlargedArea = RTreeComputationUtils.enlargedArea(frameTuple, tuple, cmp, keyValueProviders);
+ if (enlargedArea < minEnlargedArea) {
+ minEnlargedArea = enlargedArea;
+ bestChild = i;
+ } else if (enlargedArea == minEnlargedArea) {
+ double area = RTreeComputationUtils.area(frameTuple, cmp, keyValueProviders);
+ frameTuple.resetByTupleIndex(frame, bestChild);
+ double minArea = RTreeComputationUtils.area(frameTuple, cmp, keyValueProviders);
+ if (area < minArea) {
+ bestChild = i;
+ }
+ }
+ }
+
+ frameTuple.resetByTupleIndex(frame, bestChild);
+ if (minEnlargedArea > 0.0) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/btree/tuples/ILSMBTreeTupleReference.java b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreePolicyType.java
similarity index 72%
copy from hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/btree/tuples/ILSMBTreeTupleReference.java
copy to hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreePolicyType.java
index cfc71fc..712c424 100644
--- a/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/btree/tuples/ILSMBTreeTupleReference.java
+++ b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreePolicyType.java
@@ -13,10 +13,8 @@
* limitations under the License.
*/
-package edu.uci.ics.hyracks.storage.am.lsm.btree.tuples;
+package edu.uci.ics.hyracks.storage.am.rtree.frames;
-import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexTupleReference;
-
-public interface ILSMBTreeTupleReference extends ITreeIndexTupleReference {
- public boolean isAntimatter();
+public enum RTreePolicyType {
+ RTREE, RSTARTREE
}
diff --git a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/RTree.java b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/RTree.java
index d69de4b..356c097 100644
--- a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/RTree.java
+++ b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/RTree.java
@@ -15,33 +15,32 @@
package edu.uci.ics.hyracks.storage.am.rtree.impls;
+import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicLong;
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparatorFactory;
import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
import edu.uci.ics.hyracks.storage.am.common.api.IFreePageManager;
-import edu.uci.ics.hyracks.storage.am.common.api.IIndexBulkLoadContext;
import edu.uci.ics.hyracks.storage.am.common.api.IIndexCursor;
import edu.uci.ics.hyracks.storage.am.common.api.IIndexOpContext;
import edu.uci.ics.hyracks.storage.am.common.api.IModificationOperationCallback;
import edu.uci.ics.hyracks.storage.am.common.api.ISearchOperationCallback;
import edu.uci.ics.hyracks.storage.am.common.api.ISearchPredicate;
-import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexAccessor;
import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexCursor;
import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrame;
import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrameFactory;
import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexMetaDataFrame;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexTupleReference;
import edu.uci.ics.hyracks.storage.am.common.api.IndexException;
import edu.uci.ics.hyracks.storage.am.common.api.IndexType;
import edu.uci.ics.hyracks.storage.am.common.api.TreeIndexException;
import edu.uci.ics.hyracks.storage.am.common.frames.FrameOpSpaceStatus;
-import edu.uci.ics.hyracks.storage.am.common.impls.NoOpOperationCallback;
+import edu.uci.ics.hyracks.storage.am.common.impls.AbstractTreeIndex;
+import edu.uci.ics.hyracks.storage.am.common.impls.NodeFrontier;
import edu.uci.ics.hyracks.storage.am.common.impls.TreeDiskOrderScanCursor;
import edu.uci.ics.hyracks.storage.am.common.ophelpers.IndexOp;
import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
@@ -49,57 +48,29 @@
import edu.uci.ics.hyracks.storage.am.rtree.api.IRTreeFrame;
import edu.uci.ics.hyracks.storage.am.rtree.api.IRTreeInteriorFrame;
import edu.uci.ics.hyracks.storage.am.rtree.api.IRTreeLeafFrame;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreeNSMFrame;
import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreeNSMInteriorFrame;
+import edu.uci.ics.hyracks.storage.am.rtree.tuples.RTreeTypeAwareTupleWriter;
import edu.uci.ics.hyracks.storage.common.buffercache.IBufferCache;
import edu.uci.ics.hyracks.storage.common.buffercache.ICachedPage;
import edu.uci.ics.hyracks.storage.common.file.BufferedFileHandle;
-public class RTree implements ITreeIndex {
-
- private final int rootPage = 1;
+public class RTree extends AbstractTreeIndex {
// Global node sequence number used for the concurrency control protocol
private final AtomicLong globalNsn;
- private final ReadWriteLock treeLatch;
-
- private final IFreePageManager freePageManager;
- private final IBufferCache bufferCache;
- private int fileId;
-
- private final ITreeIndexFrameFactory interiorFrameFactory;
- private final ITreeIndexFrameFactory leafFrameFactory;
- private final int fieldCount;
- private final IBinaryComparatorFactory[] cmpFactories;
public RTree(IBufferCache bufferCache, int fieldCount, IBinaryComparatorFactory[] cmpFactories,
IFreePageManager freePageManager, ITreeIndexFrameFactory interiorFrameFactory,
ITreeIndexFrameFactory leafFrameFactory) {
- this.bufferCache = bufferCache;
- this.fieldCount = fieldCount;
- this.cmpFactories = cmpFactories;
- this.freePageManager = freePageManager;
- this.interiorFrameFactory = interiorFrameFactory;
- this.leafFrameFactory = leafFrameFactory;
+ super(bufferCache, fieldCount, cmpFactories, freePageManager, interiorFrameFactory, leafFrameFactory);
globalNsn = new AtomicLong();
- this.treeLatch = new ReentrantReadWriteLock(true);
}
private long incrementGlobalNsn() {
return globalNsn.incrementAndGet();
}
- public byte getTreeHeight(IRTreeLeafFrame leafFrame) throws HyracksDataException {
- ICachedPage rootNode = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, rootPage), false);
- rootNode.acquireReadLatch();
- try {
- leafFrame.setPage(rootNode);
- return leafFrame.getLevel();
- } finally {
- rootNode.releaseReadLatch();
- bufferCache.unpin(rootNode);
- }
- }
-
@SuppressWarnings("rawtypes")
public String printTree(IRTreeLeafFrame leafFrame, IRTreeInteriorFrame interiorFrame,
ISerializerDeserializer[] keySerdes) throws Exception {
@@ -190,28 +161,6 @@
}
}
- @Override
- public void open(int fileId) {
- this.fileId = fileId;
- freePageManager.open(fileId);
- }
-
- @Override
- public void close() {
- fileId = -1;
- freePageManager.close();
- }
-
- @Override
- public int getFileId() {
- return fileId;
- }
-
- @Override
- public IBufferCache getBufferCache() {
- return bufferCache;
- }
-
private RTreeOpContext createOpContext(IModificationOperationCallback modificationCallback,
ISearchOperationCallback searchCallback) {
return new RTreeOpContext((IRTreeLeafFrame) leafFrameFactory.createFrame(),
@@ -820,82 +769,10 @@
ctx.cursor.open(ctx.cursorInitialState, (SearchPredicate) searchPred);
}
- @Override
- public ITreeIndexFrameFactory getInteriorFrameFactory() {
- return interiorFrameFactory;
- }
-
- @Override
- public ITreeIndexFrameFactory getLeafFrameFactory() {
- return leafFrameFactory;
- }
-
- @Override
- public IBinaryComparatorFactory[] getComparatorFactories() {
- return cmpFactories;
- }
-
- @Override
- public IFreePageManager getFreePageManager() {
- return freePageManager;
- }
-
private void update(ITupleReference tuple, RTreeOpContext ctx) {
throw new UnsupportedOperationException("RTree Update not implemented.");
}
- public boolean isEmptyTree(IRTreeLeafFrame leafFrame) throws HyracksDataException {
- ICachedPage rootNode = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, rootPage), false);
- rootNode.acquireReadLatch();
- try {
- leafFrame.setPage(rootNode);
- if (leafFrame.getLevel() == 0 && leafFrame.getTupleCount() == 0) {
- return true;
- } else {
- return false;
- }
- } finally {
- rootNode.releaseReadLatch();
- bufferCache.unpin(rootNode);
- }
- }
-
- public final class BulkLoadContext implements IIndexBulkLoadContext {
-
- public ITreeIndexAccessor indexAccessor;
-
- public BulkLoadContext(float fillFactor, IRTreeFrame leafFrame, IRTreeFrame interiorFrame,
- ITreeIndexMetaDataFrame metaFrame) throws HyracksDataException {
- indexAccessor = createAccessor(NoOpOperationCallback.INSTANCE, NoOpOperationCallback.INSTANCE);
- }
- }
-
- @Override
- public IIndexBulkLoadContext beginBulkLoad(float fillFactor) throws HyracksDataException {
- IRTreeLeafFrame leafFrame = (IRTreeLeafFrame) leafFrameFactory.createFrame();
- if (!isEmptyTree(leafFrame)) {
- throw new HyracksDataException("Trying to Bulk-load a non-empty RTree.");
- }
-
- BulkLoadContext ctx = new BulkLoadContext(fillFactor, (IRTreeFrame) leafFrameFactory.createFrame(),
- (IRTreeFrame) interiorFrameFactory.createFrame(), freePageManager.getMetaDataFrameFactory()
- .createFrame());
- return ctx;
- }
-
- @Override
- public void bulkLoadAddTuple(ITupleReference tuple, IIndexBulkLoadContext ictx) throws HyracksDataException {
- try {
- ((BulkLoadContext) ictx).indexAccessor.insert(tuple);
- } catch (Exception e) {
- throw new HyracksDataException("BulkLoad Error", e);
- }
- }
-
- @Override
- public void endBulkLoad(IIndexBulkLoadContext ictx) throws HyracksDataException {
- }
-
private void diskOrderScan(ITreeIndexCursor icursor, RTreeOpContext ctx) throws HyracksDataException {
TreeDiskOrderScanCursor cursor = (TreeDiskOrderScanCursor) icursor;
ctx.reset();
@@ -903,7 +780,7 @@
MultiComparator cmp = MultiComparator.create(cmpFactories);
SearchPredicate searchPred = new SearchPredicate(null, cmp);
- int currentPageId = rootPage + 1;
+ int currentPageId = rootPage;
int maxPageId = freePageManager.getMaxPage(ctx.metaFrame);
ICachedPage page = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, currentPageId), false);
@@ -924,16 +801,6 @@
}
@Override
- public int getRootPageId() {
- return rootPage;
- }
-
- @Override
- public int getFieldCount() {
- return fieldCount;
- }
-
- @Override
public IndexType getIndexType() {
return IndexType.RTREE;
}
@@ -1006,4 +873,121 @@
"The RTree does not support the notion of keys, therefore upsert does not make sense.");
}
}
+
+ @Override
+ public AbstractTreeIndexBulkLoader createBulkLoader(float fillFactor) throws TreeIndexException {
+ try {
+ return new RTreeBulkLoader(fillFactor);
+ } catch (HyracksDataException e) {
+ throw new TreeIndexException(e);
+ }
+ }
+
+ public class RTreeBulkLoader extends AbstractTreeIndex.AbstractTreeIndexBulkLoader {
+ ITreeIndexFrame lowerFrame, prevInteriorFrame;
+ RTreeTypeAwareTupleWriter tupleWriter = ((RTreeTypeAwareTupleWriter) interiorFrame.getTupleWriter());
+ ITreeIndexTupleReference mbrTuple = interiorFrame.createTupleReference();
+ ByteBuffer mbr;
+
+ public RTreeBulkLoader(float fillFactor) throws TreeIndexException, HyracksDataException {
+ super(fillFactor);
+ prevInteriorFrame = interiorFrameFactory.createFrame();
+ }
+
+ @Override
+ public void add(ITupleReference tuple) throws HyracksDataException {
+ NodeFrontier leafFrontier = nodeFrontiers.get(0);
+
+ int spaceNeeded = tupleWriter.bytesRequired(tuple) + slotSize;
+ int spaceUsed = leafFrame.getBuffer().capacity() - leafFrame.getTotalFreeSpace();
+
+ // try to free space by compression
+ if (spaceUsed + spaceNeeded > leafMaxBytes) {
+ leafFrame.compress();
+ spaceUsed = leafFrame.getBuffer().capacity() - leafFrame.getTotalFreeSpace();
+ }
+
+ if (spaceUsed + spaceNeeded > leafMaxBytes) {
+ propagateBulk(1, false);
+
+ leafFrontier.pageId = freePageManager.getFreePage(metaFrame);
+
+ leafFrontier.page.releaseWriteLatch();
+ bufferCache.unpin(leafFrontier.page);
+
+ leafFrontier.page = bufferCache
+ .pin(BufferedFileHandle.getDiskPageId(fileId, leafFrontier.pageId), true);
+ leafFrontier.page.acquireWriteLatch();
+ leafFrame.setPage(leafFrontier.page);
+ leafFrame.initBuffer((byte) 0);
+ }
+
+ leafFrame.setPage(leafFrontier.page);
+ leafFrame.insert(tuple, -1);
+ }
+
+ public void end() throws HyracksDataException {
+ propagateBulk(1, true);
+
+ super.end();
+ }
+
+ protected void propagateBulk(int level, boolean toRoot) throws HyracksDataException {
+ boolean propagated = false;
+
+ if (level == 1)
+ lowerFrame = leafFrame;
+
+ if (lowerFrame.getTupleCount() == 0)
+ return;
+
+ if (level >= nodeFrontiers.size())
+ addLevel();
+
+ ((RTreeNSMFrame) lowerFrame).adjustMBR();
+
+ if (mbr == null) {
+ int bytesRequired = tupleWriter.bytesRequired(((RTreeNSMFrame) lowerFrame).getTuples()[0], 0,
+ cmp.getKeyFieldCount())
+ + ((RTreeNSMInteriorFrame) interiorFrame).getChildPointerSize();
+ mbr = ByteBuffer.allocate(bytesRequired);
+ }
+ tupleWriter.writeTupleFields(((RTreeNSMFrame) lowerFrame).getTuples(), 0, mbr, 0);
+ mbrTuple.resetByTupleOffset(mbr, 0);
+
+ NodeFrontier frontier = nodeFrontiers.get(level);
+ interiorFrame.setPage(frontier.page);
+
+ interiorFrame.insert(mbrTuple, -1);
+
+ interiorFrame.getBuffer().putInt(
+ interiorFrame.getTupleOffset(interiorFrame.getTupleCount() - 1) + mbrTuple.getTupleSize(),
+ nodeFrontiers.get(level - 1).pageId);
+
+ if (interiorFrame.hasSpaceInsert(mbrTuple) != FrameOpSpaceStatus.SUFFICIENT_CONTIGUOUS_SPACE && !toRoot) {
+ lowerFrame = prevInteriorFrame;
+ lowerFrame.setPage(frontier.page);
+
+ propagateBulk(level + 1, toRoot);
+ propagated = true;
+
+ frontier.page.releaseWriteLatch();
+ bufferCache.unpin(frontier.page);
+ frontier.pageId = freePageManager.getFreePage(metaFrame);
+
+ frontier.page = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, frontier.pageId), true);
+ frontier.page.acquireWriteLatch();
+ interiorFrame.setPage(frontier.page);
+ interiorFrame.initBuffer((byte) level);
+ }
+
+ if (toRoot && !propagated && level < nodeFrontiers.size() - 1) {
+ lowerFrame = prevInteriorFrame;
+ lowerFrame.setPage(frontier.page);
+ propagateBulk(level + 1, true);
+ }
+
+ leafFrame.setPage(nodeFrontiers.get(0).page);
+ }
+ }
}
\ No newline at end of file
diff --git a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/RTreeSearchCursor.java b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/RTreeSearchCursor.java
index 0ae8969..799dbe5 100644
--- a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/RTreeSearchCursor.java
+++ b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/RTreeSearchCursor.java
@@ -40,14 +40,14 @@
private SearchPredicate pred;
private PathList pathList;
private int rootPage;
- private ITupleReference searchKey;
+ protected ITupleReference searchKey;
private int tupleIndex = 0;
private int tupleIndexInc = 0;
private int currentTupleIndex = 0;
private int pageId = -1;
- private MultiComparator cmp;
+ protected MultiComparator cmp;
private ITreeIndexTupleReference frameTuple;
private boolean readLatched = false;
@@ -73,6 +73,7 @@
pathList = null;
}
+ @Override
public ITupleReference getTuple() {
return frameTuple;
}
@@ -120,15 +121,18 @@
}
if (!isLeaf) {
+ // We do DFS so that we get the tuples ordered (for disk
+ // RTrees only) in the case we we are using total order
+ // (such as Hilbert order)
if (searchKey != null) {
- for (int i = 0; i < interiorFrame.getTupleCount(); i++) {
+ for (int i = interiorFrame.getTupleCount() - 1; i >= 0; i--) {
int childPageId = interiorFrame.getChildPageIdIfIntersect(searchKey, i, cmp);
if (childPageId != -1) {
pathList.add(childPageId, pageLsn, -1);
}
}
} else {
- for (int i = 0; i < interiorFrame.getTupleCount(); i++) {
+ for (int i = interiorFrame.getTupleCount() - 1; i >= 0; i--) {
int childPageId = interiorFrame.getChildPageId(i);
pathList.add(childPageId, pageLsn, -1);
}
diff --git a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/Rectangle.java b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/Rectangle.java
index cb9b160..d0f4c71 100644
--- a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/Rectangle.java
+++ b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/Rectangle.java
@@ -19,94 +19,120 @@
import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProvider;
public class Rectangle {
- private int dim;
- private double[] low;
- private double[] high;
+ private int dim;
+ private double[] low;
+ private double[] high;
- public Rectangle(int dim) {
- this.dim = dim;
- low = new double[this.dim];
- high = new double[this.dim];
- }
+ public Rectangle(int dim) {
+ this.dim = dim;
+ low = new double[this.dim];
+ high = new double[this.dim];
+ }
- public int getDim() {
- return dim;
- }
+ public int getDim() {
+ return dim;
+ }
- public double getLow(int i) {
- return low[i];
- }
+ public double getLow(int i) {
+ return low[i];
+ }
- public double getHigh(int i) {
- return high[i];
- }
+ public double getHigh(int i) {
+ return high[i];
+ }
- public void setLow(int i, double value) {
- low[i] = value;
- }
+ public void setLow(int i, double value) {
+ low[i] = value;
+ }
- public void setHigh(int i, double value) {
- high[i] = value;
- }
+ public void setHigh(int i, double value) {
+ high[i] = value;
+ }
- public void set(ITupleReference tuple, IPrimitiveValueProvider[] valueProviders) {
- for (int i = 0; i < getDim(); i++) {
- int j = i + getDim();
- setLow(i, valueProviders[i].getValue(
- tuple.getFieldData(i), tuple.getFieldStart(i)));
- setHigh(i, valueProviders[j].getValue(
- tuple.getFieldData(j), tuple.getFieldStart(j)));
- }
- }
+ public void set(ITupleReference tuple, IPrimitiveValueProvider[] valueProviders) {
+ for (int i = 0; i < getDim(); i++) {
+ int j = i + getDim();
+ setLow(i, valueProviders[i].getValue(tuple.getFieldData(i), tuple.getFieldStart(i)));
+ setHigh(i, valueProviders[j].getValue(tuple.getFieldData(j), tuple.getFieldStart(j)));
+ }
+ }
- public void enlarge(ITupleReference tupleToBeInserted, IPrimitiveValueProvider[] valueProviders) {
- for (int i = 0; i < getDim(); i++) {
- int j = getDim() + i;
- double low = valueProviders[i].getValue(
- tupleToBeInserted.getFieldData(i),
- tupleToBeInserted.getFieldStart(i));
- if (getLow(i) > low) {
- setLow(i, low);
- }
- double high = valueProviders[j].getValue(
- tupleToBeInserted.getFieldData(j),
- tupleToBeInserted.getFieldStart(j));
- if (getHigh(i) < high) {
- setHigh(i, high);
- }
- }
- }
+ public void enlarge(ITupleReference tupleToBeInserted, IPrimitiveValueProvider[] valueProviders) {
+ for (int i = 0; i < getDim(); i++) {
+ int j = getDim() + i;
+ double low = valueProviders[i].getValue(tupleToBeInserted.getFieldData(i),
+ tupleToBeInserted.getFieldStart(i));
+ if (getLow(i) > low) {
+ setLow(i, low);
+ }
+ double high = valueProviders[j].getValue(tupleToBeInserted.getFieldData(j),
+ tupleToBeInserted.getFieldStart(j));
+ if (getHigh(i) < high) {
+ setHigh(i, high);
+ }
+ }
+ }
- public double margin() {
- double margin = 0.0;
- double mul = Math.pow(2, (double) getDim() - 1.0);
- for (int i = 0; i < getDim(); i++) {
- margin += (getHigh(i) - getLow(i)) * mul;
- }
- return margin;
- }
+ public double enlargedArea(ITupleReference tupleToBeInserted, IPrimitiveValueProvider[] valueProviders) {
+ double areaBeforeEnlarge = area();
+ double areaAfterEnlarge = 1.0;
- public double overlappedArea(Rectangle rec) {
- double area = 1.0;
- double f1, f2;
+ for (int i = 0; i < getDim(); i++) {
+ int j = getDim() + i;
- for (int i = 0; i < getDim(); i++) {
- if (getLow(i) > rec.getHigh(i) || getHigh(i) < rec.getLow(i)) {
- return 0.0;
- }
+ double low = valueProviders[i].getValue(tupleToBeInserted.getFieldData(i),
+ tupleToBeInserted.getFieldStart(i));
+ double lowAfterEnlargement;
+ if (getLow(i) > low) {
+ lowAfterEnlargement = low;
+ } else {
+ lowAfterEnlargement = getLow(i);
+ }
- f1 = Math.max(getLow(i), rec.getLow(i));
- f2 = Math.min(getHigh(i), rec.getHigh(i));
- area *= f2 - f1;
- }
- return area;
- }
+ double high = valueProviders[j].getValue(tupleToBeInserted.getFieldData(j),
+ tupleToBeInserted.getFieldStart(j));
+ double highAfterEnlargement;
+ if (getHigh(i) < high) {
+ highAfterEnlargement = high;
+ } else {
+ highAfterEnlargement = getHigh(i);
+ }
- public double area() {
- double area = 1.0;
- for (int i = 0; i < getDim(); i++) {
- area *= getHigh(i) - getLow(i);
- }
- return area;
- }
+ areaAfterEnlarge *= highAfterEnlargement - lowAfterEnlargement;
+ }
+ return areaAfterEnlarge - areaBeforeEnlarge;
+ }
+
+ public double margin() {
+ double margin = 0.0;
+ double mul = Math.pow(2, (double) getDim() - 1.0);
+ for (int i = 0; i < getDim(); i++) {
+ margin += (getHigh(i) - getLow(i)) * mul;
+ }
+ return margin;
+ }
+
+ public double overlappedArea(Rectangle rec) {
+ double area = 1.0;
+ double f1, f2;
+
+ for (int i = 0; i < getDim(); i++) {
+ if (getLow(i) > rec.getHigh(i) || getHigh(i) < rec.getLow(i)) {
+ return 0.0;
+ }
+
+ f1 = Math.max(getLow(i), rec.getLow(i));
+ f2 = Math.min(getHigh(i), rec.getHigh(i));
+ area *= f2 - f1;
+ }
+ return area;
+ }
+
+ public double area() {
+ double area = 1.0;
+ for (int i = 0; i < getDim(); i++) {
+ area *= getHigh(i) - getLow(i);
+ }
+ return area;
+ }
}
\ No newline at end of file
diff --git a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/linearize/HilbertDoubleComparator.java b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/linearize/HilbertDoubleComparator.java
new file mode 100644
index 0000000..7fce7e0
--- /dev/null
+++ b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/linearize/HilbertDoubleComparator.java
@@ -0,0 +1,180 @@
+package edu.uci.ics.hyracks.storage.am.rtree.linearize;
+
+import edu.uci.ics.hyracks.api.dataflow.value.ILinearizeComparator;
+import edu.uci.ics.hyracks.data.std.primitive.DoublePointable;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.DoubleSerializerDeserializer;
+import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProvider;
+import edu.uci.ics.hyracks.storage.am.common.ophelpers.DoubleArrayList;
+import edu.uci.ics.hyracks.storage.am.common.ophelpers.IntArrayList;
+import edu.uci.ics.hyracks.storage.am.rtree.impls.DoublePrimitiveValueProviderFactory;
+
+/*
+ * This compares two points based on the hilbert curve. Currently, it only supports
+ * doubles (this can be changed by changing all doubles to ints as there are no
+ * number generics in Java) in the two-dimensional space. For more dimensions, the
+ * state machine has to be automatically generated. The idea of the fractal generation
+ * of the curve is described e.g. in http://dl.acm.org/ft_gateway.cfm?id=383528&type=pdf
+ *
+ * Unlike the described approach, this comparator does not compute the hilbert value at
+ * any point. Instead, it only evaluates how the two inputs compare to each other. This
+ * is done by starting at the lowest hilbert resolution and zooming in on the fractal until
+ * the two points are in different quadrants.
+ *
+ * As a performance optimization, the state of the state machine is saved in a stack and
+ * maintained over comparisons. The idea behind this is that comparisons are usually in a
+ * similar area (e.g. geo coordinates). Zooming in from [-MAX_VALUE, MAX_VALUE] would take
+ * ~300 steps every time. Instead, the comparator start from the previous state and zooms out
+ * if necessary
+ */
+
+public class HilbertDoubleComparator implements ILinearizeComparator {
+ private final int dim; // dimension
+ private final HilbertState[] states;
+
+ private double[] bounds;
+ private double stepsize;
+ private int state;
+ private IntArrayList stateStack = new IntArrayList(1000, 200);
+ private DoubleArrayList boundsStack = new DoubleArrayList(2000, 400);
+
+ private IPrimitiveValueProvider valueProvider = DoublePrimitiveValueProviderFactory.INSTANCE
+ .createPrimitiveValueProvider();
+
+ private double[] a;
+ private double[] b;
+
+ private class HilbertState {
+ public final int[] nextState;
+ public final int[] position;
+
+ public HilbertState(int[] nextState, int[] order) {
+ this.nextState = nextState;
+ this.position = order;
+ }
+ }
+
+ public HilbertDoubleComparator(int dimension) {
+ if (dimension != 2)
+ throw new IllegalArgumentException();
+ dim = dimension;
+ a = new double[dim];
+ b = new double[dim];
+
+ states = new HilbertState[] { new HilbertState(new int[] { 3, 0, 1, 0 }, new int[] { 0, 1, 3, 2 }),
+ new HilbertState(new int[] { 1, 1, 0, 2 }, new int[] { 2, 1, 3, 0 }),
+ new HilbertState(new int[] { 2, 3, 2, 1 }, new int[] { 2, 3, 1, 0 }),
+ new HilbertState(new int[] { 0, 2, 3, 3 }, new int[] { 0, 3, 1, 2 }) };
+
+ resetStateMachine();
+ }
+
+ private void resetStateMachine() {
+ state = 0;
+ stateStack.clear();
+ stepsize = Double.MAX_VALUE / 2;
+ bounds = new double[dim];
+ boundsStack.clear();
+ }
+
+ public int compare() {
+ boolean equal = true;
+ for (int i = 0; i < dim; i++) {
+ if (a[i] != b[i])
+ equal = false;
+ }
+ if (equal)
+ return 0;
+
+ // We keep the state of the state machine after a comparison. In most
+ // cases,
+ // the needed zoom factor is close to the old one. In this step, we
+ // check if we have
+ // to zoom out
+ while (true) {
+ if (stateStack.size() <= dim) {
+ resetStateMachine();
+ break;
+ }
+ boolean zoomOut = false;
+ for (int i = 0; i < dim; i++) {
+ if (Math.min(a[i], b[i]) <= bounds[i] - 2 * stepsize
+ || Math.max(a[i], b[i]) >= bounds[i] + 2 * stepsize) {
+ zoomOut = true;
+ break;
+ }
+ }
+ state = stateStack.getLast();
+ stateStack.removeLast();
+ for (int j = dim - 1; j >= 0; j--) {
+ bounds[j] = boundsStack.getLast();
+ boundsStack.removeLast();
+ }
+ stepsize *= 2;
+ if (!zoomOut) {
+ state = stateStack.getLast();
+ stateStack.removeLast();
+ for (int j = dim - 1; j >= 0; j--) {
+ bounds[j] = boundsStack.getLast();
+ boundsStack.removeLast();
+ }
+ stepsize *= 2;
+ break;
+ }
+ }
+
+ while (true) {
+ stateStack.add(state);
+ for (int j = 0; j < dim; j++) {
+ boundsStack.add(bounds[j]);
+ }
+
+ // Find the quadrant in which A and B are
+ int quadrantA = 0, quadrantB = 0;
+ for (int i = dim - 1; i >= 0; i--) {
+ if (a[i] >= bounds[i])
+ quadrantA ^= (1 << (dim - i - 1));
+ if (b[i] >= bounds[i])
+ quadrantB ^= (1 << (dim - i - 1));
+
+ if (a[i] >= bounds[i]) {
+ bounds[i] += stepsize;
+ } else {
+ bounds[i] -= stepsize;
+ }
+ }
+
+ stepsize /= 2;
+ if (stepsize <= 2 * DoublePointable.getEpsilon())
+ return 0;
+ // avoid infinite loop due to machine epsilon problems
+
+ if (quadrantA != quadrantB) {
+ // find the position of A and B's quadrants
+ int posA = states[state].position[quadrantA];
+ int posB = states[state].position[quadrantB];
+
+ if (posA < posB)
+ return -1;
+ else
+ return 1;
+ }
+
+ state = states[state].nextState[quadrantA];
+ }
+ }
+
+ @Override
+ public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
+ for (int i = 0; i < dim; i++) {
+ a[i] = DoubleSerializerDeserializer.getDouble(b1, s1 + (i * 8));
+ b[i] = DoubleSerializerDeserializer.getDouble(b2, s2 + (i * 8));
+ }
+
+ return compare();
+ }
+
+ @Override
+ public int getDimensions() {
+ return dim;
+ }
+}
diff --git a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/linearize/HilbertDoubleComparatorFactory.java b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/linearize/HilbertDoubleComparatorFactory.java
new file mode 100644
index 0000000..e06dba8
--- /dev/null
+++ b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/linearize/HilbertDoubleComparatorFactory.java
@@ -0,0 +1,37 @@
+/*
+ * 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.rtree.linearize;
+
+import edu.uci.ics.hyracks.api.dataflow.value.ILinearizeComparator;
+import edu.uci.ics.hyracks.api.dataflow.value.ILinearizeComparatorFactory;
+
+public class HilbertDoubleComparatorFactory implements ILinearizeComparatorFactory {
+ private static final long serialVersionUID = 1L;
+
+ private int dim;
+
+ public static HilbertDoubleComparatorFactory get(int dim) {
+ return new HilbertDoubleComparatorFactory(dim);
+ }
+
+ public HilbertDoubleComparatorFactory(int dim) {
+ this.dim = dim;
+ }
+
+ @Override
+ public ILinearizeComparator createBinaryComparator() {
+ return new HilbertDoubleComparator(dim);
+ }
+}
\ No newline at end of file
diff --git a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/linearize/ZCurveDoubleComparator.java b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/linearize/ZCurveDoubleComparator.java
new file mode 100644
index 0000000..ee47761
--- /dev/null
+++ b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/linearize/ZCurveDoubleComparator.java
@@ -0,0 +1,136 @@
+package edu.uci.ics.hyracks.storage.am.rtree.linearize;
+
+import edu.uci.ics.hyracks.api.dataflow.value.ILinearizeComparator;
+import edu.uci.ics.hyracks.data.std.primitive.DoublePointable;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.DoubleSerializerDeserializer;
+import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProvider;
+import edu.uci.ics.hyracks.storage.am.common.ophelpers.DoubleArrayList;
+import edu.uci.ics.hyracks.storage.am.rtree.impls.DoublePrimitiveValueProviderFactory;
+
+/*
+ * This compares two points based on the z curve. For doubles, we cannot use
+ * the simple bit magic approach. There may, however, be a better approach than this.
+ */
+
+public class ZCurveDoubleComparator implements ILinearizeComparator {
+ private final int dim; // dimension
+
+ private double[] bounds;
+ private double stepsize;
+ private DoubleArrayList boundsStack = new DoubleArrayList(2000, 400);
+
+ private IPrimitiveValueProvider valueProvider = DoublePrimitiveValueProviderFactory.INSTANCE
+ .createPrimitiveValueProvider();
+
+ private double[] a;
+ private double[] b;
+
+ public ZCurveDoubleComparator(int dimension) {
+ dim = dimension;
+ a = new double[dim];
+ b = new double[dim];
+
+ resetStateMachine();
+ }
+
+ private void resetStateMachine() {
+ stepsize = Double.MAX_VALUE / 2;
+ bounds = new double[dim];
+ boundsStack.clear();
+ }
+
+ public int compare() {
+ boolean equal = true;
+ for (int i = 0; i < dim; i++) {
+ if (a[i] != b[i])
+ equal = false;
+ }
+ if (equal)
+ return 0;
+
+ // We keep the state of the state machine after a comparison. In most
+ // cases,
+ // the needed zoom factor is close to the old one. In this step, we
+ // check if we have
+ // to zoom out
+ while (true) {
+ if (boundsStack.size() <= dim) {
+ resetStateMachine();
+ break;
+ }
+ boolean zoomOut = false;
+ for (int i = 0; i < dim; i++) {
+ if (Math.min(a[i], b[i]) <= bounds[i] - 2 * stepsize
+ || Math.max(a[i], b[i]) >= bounds[i] + 2 * stepsize) {
+ zoomOut = true;
+ break;
+ }
+ }
+
+ for (int j = dim - 1; j >= 0; j--) {
+ bounds[j] = boundsStack.getLast();
+ boundsStack.removeLast();
+ }
+ stepsize *= 2;
+ if (!zoomOut) {
+ for (int j = dim - 1; j >= 0; j--) {
+ bounds[j] = boundsStack.getLast();
+ boundsStack.removeLast();
+ }
+ stepsize *= 2;
+ break;
+ }
+ }
+
+ while (true) {
+ for (int j = 0; j < dim; j++) {
+ boundsStack.add(bounds[j]);
+ }
+
+ // Find the quadrant in which A and B are
+ int quadrantA = 0, quadrantB = 0;
+ for (int i = dim - 1; i >= 0; i--) {
+ if (a[i] >= bounds[i])
+ quadrantA ^= (1 << (dim - i - 1));
+ if (b[i] >= bounds[i])
+ quadrantB ^= (1 << (dim - i - 1));
+
+ if (a[i] >= bounds[i]) {
+ bounds[i] += stepsize;
+ } else {
+ bounds[i] -= stepsize;
+ }
+ }
+
+ stepsize /= 2;
+ if (stepsize <= 2 * DoublePointable.getEpsilon())
+ return 0;
+ // avoid infinite loop due to machine epsilon problems
+
+ if (quadrantA != quadrantB) {
+ // find the position of A and B's quadrants
+ if (quadrantA < quadrantB)
+ return -1;
+ else if (quadrantA > quadrantB)
+ return 1;
+ else
+ return 0;
+ }
+ }
+ }
+
+ @Override
+ public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
+ for (int i = 0; i < dim; i++) {
+ a[i] = DoubleSerializerDeserializer.getDouble(b1, s1 + (i * 8));
+ b[i] = DoubleSerializerDeserializer.getDouble(b2, s2 + (i * 8));
+ }
+
+ return compare();
+ }
+
+ @Override
+ public int getDimensions() {
+ return dim;
+ }
+}
diff --git a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/linearize/ZCurveDoubleComparatorFactory.java b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/linearize/ZCurveDoubleComparatorFactory.java
new file mode 100644
index 0000000..f1b5806
--- /dev/null
+++ b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/linearize/ZCurveDoubleComparatorFactory.java
@@ -0,0 +1,37 @@
+/*
+ * 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.rtree.linearize;
+
+import edu.uci.ics.hyracks.api.dataflow.value.ILinearizeComparator;
+import edu.uci.ics.hyracks.api.dataflow.value.ILinearizeComparatorFactory;
+
+public class ZCurveDoubleComparatorFactory implements ILinearizeComparatorFactory {
+ private static final long serialVersionUID = 1L;
+
+ private int dim;
+
+ public static ZCurveDoubleComparatorFactory get(int dim) {
+ return new ZCurveDoubleComparatorFactory(dim);
+ }
+
+ public ZCurveDoubleComparatorFactory(int dim) {
+ this.dim = dim;
+ }
+
+ @Override
+ public ILinearizeComparator createBinaryComparator() {
+ return new ZCurveDoubleComparator(dim);
+ }
+}
\ No newline at end of file
diff --git a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/linearize/ZCurveIntComparator.java b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/linearize/ZCurveIntComparator.java
new file mode 100644
index 0000000..1f26f41
--- /dev/null
+++ b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/linearize/ZCurveIntComparator.java
@@ -0,0 +1,129 @@
+package edu.uci.ics.hyracks.storage.am.rtree.linearize;
+
+import edu.uci.ics.hyracks.api.dataflow.value.ILinearizeComparator;
+import edu.uci.ics.hyracks.data.std.primitive.DoublePointable;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;
+import edu.uci.ics.hyracks.storage.am.common.ophelpers.DoubleArrayList;
+
+/*
+ * This compares two points based on the z curve. For doubles, we cannot use
+ * the simple bit magic approach. There may, however, be a better approach than this.
+ */
+
+public class ZCurveIntComparator implements ILinearizeComparator {
+ private final int dim; // dimension
+
+ private double[] bounds;
+ private double stepsize;
+ private DoubleArrayList boundsStack = new DoubleArrayList(2000, 400);
+
+ private int[] a;
+ private int[] b;
+
+ public ZCurveIntComparator(int dimension) {
+ dim = dimension;
+ a = new int[dim];
+ b = new int[dim];
+
+ resetStateMachine();
+ }
+
+ private void resetStateMachine() {
+ stepsize = Integer.MAX_VALUE / 2;
+ bounds = new double[dim];
+ boundsStack.clear();
+ }
+
+ public int compare() {
+ boolean equal = true;
+ for (int i = 0; i < dim; i++) {
+ if (a[i] != b[i])
+ equal = false;
+ }
+ if (equal)
+ return 0;
+
+ // We keep the state of the state machine after a comparison. In most cases,
+ // the needed zoom factor is close to the old one. In this step, we check if we have
+ // to zoom out
+ while (true) {
+ if (boundsStack.size() <= dim) {
+ resetStateMachine();
+ break;
+ }
+ boolean zoomOut = false;
+ for (int i = 0; i < dim; i++) {
+ if (Math.min(a[i], b[i]) <= bounds[i] - 2 * stepsize
+ || Math.max(a[i], b[i]) >= bounds[i] + 2 * stepsize) {
+ zoomOut = true;
+ break;
+ }
+ }
+
+ for (int j = dim - 1; j >= 0; j--) {
+ bounds[j] = boundsStack.getLast();
+ boundsStack.removeLast();
+ }
+ stepsize *= 2;
+ if (!zoomOut) {
+ for (int j = dim - 1; j >= 0; j--) {
+ bounds[j] = boundsStack.getLast();
+ boundsStack.removeLast();
+ }
+ stepsize *= 2;
+ break;
+ }
+ }
+
+ while (true) {
+ for (int j = 0; j < dim; j++) {
+ boundsStack.add(bounds[j]);
+ }
+
+ // Find the quadrant in which A and B are
+ int quadrantA = 0, quadrantB = 0;
+ for (int i = dim - 1; i >= 0; i--) {
+ if (a[i] >= bounds[i])
+ quadrantA ^= (1 << (dim - i - 1));
+ if (b[i] >= bounds[i])
+ quadrantB ^= (1 << (dim - i - 1));
+
+ if (a[i] >= bounds[i]) {
+ bounds[i] += stepsize;
+ } else {
+ bounds[i] -= stepsize;
+ }
+ }
+
+ stepsize /= 2;
+ if (stepsize <= 2 * DoublePointable.getEpsilon())
+ return 0;
+ // avoid infinite loop due to machine epsilon problems
+
+ if (quadrantA != quadrantB) {
+ // find the position of A and B's quadrants
+ if (quadrantA < quadrantB)
+ return -1;
+ else if (quadrantA > quadrantB)
+ return 1;
+ else
+ return 0;
+ }
+ }
+ }
+
+ @Override
+ public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
+ for (int i = 0; i < dim; i++) {
+ a[i] = IntegerSerializerDeserializer.getInt(b1, s1 + (i * 8));
+ b[i] = IntegerSerializerDeserializer.getInt(b2, s2 + (i * 8));
+ }
+
+ return compare();
+ }
+
+ @Override
+ public int getDimensions() {
+ return dim;
+ }
+}
diff --git a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/linearize/ZCurveIntComparatorFactory.java b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/linearize/ZCurveIntComparatorFactory.java
new file mode 100644
index 0000000..4a35a79
--- /dev/null
+++ b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/linearize/ZCurveIntComparatorFactory.java
@@ -0,0 +1,37 @@
+/*
+ * 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.rtree.linearize;
+
+import edu.uci.ics.hyracks.api.dataflow.value.ILinearizeComparator;
+import edu.uci.ics.hyracks.api.dataflow.value.ILinearizeComparatorFactory;
+
+public class ZCurveIntComparatorFactory implements ILinearizeComparatorFactory {
+ private static final long serialVersionUID = 1L;
+
+ private int dim;
+
+ public static ZCurveIntComparatorFactory get(int dim) {
+ return new ZCurveIntComparatorFactory(dim);
+ }
+
+ public ZCurveIntComparatorFactory(int dim) {
+ this.dim = dim;
+ }
+
+ @Override
+ public ILinearizeComparator createBinaryComparator() {
+ return new ZCurveIntComparator(dim);
+ }
+}
\ No newline at end of file
diff --git a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/util/RTreeUtils.java b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/util/RTreeUtils.java
index 6f5d36f..6527d40 100644
--- a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/util/RTreeUtils.java
+++ b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/util/RTreeUtils.java
@@ -30,19 +30,21 @@
import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreeNSMInteriorFrameFactory;
import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreeNSMLeafFrameFactory;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
import edu.uci.ics.hyracks.storage.am.rtree.impls.RTree;
import edu.uci.ics.hyracks.storage.am.rtree.tuples.RTreeTypeAwareTupleWriterFactory;
import edu.uci.ics.hyracks.storage.common.buffercache.IBufferCache;
public class RTreeUtils {
public static RTree createRTree(IBufferCache bufferCache, ITypeTraits[] typeTraits,
- IPrimitiveValueProviderFactory[] valueProviderFactories, IBinaryComparatorFactory[] cmpFactories) {
+ IPrimitiveValueProviderFactory[] valueProviderFactories, IBinaryComparatorFactory[] cmpFactories,
+ RTreePolicyType rtreePolicyType) {
RTreeTypeAwareTupleWriterFactory tupleWriterFactory = new RTreeTypeAwareTupleWriterFactory(typeTraits);
ITreeIndexFrameFactory interiorFrameFactory = new RTreeNSMInteriorFrameFactory(tupleWriterFactory,
- valueProviderFactories);
+ valueProviderFactories, rtreePolicyType);
ITreeIndexFrameFactory leafFrameFactory = new RTreeNSMLeafFrameFactory(tupleWriterFactory,
- valueProviderFactories);
+ valueProviderFactories, rtreePolicyType);
ITreeIndexMetaDataFrameFactory metaFrameFactory = new LIFOMetaDataFrameFactory();
IFreePageManager freePageManager = new LinkedListFreePageManager(bufferCache, 0, metaFrameFactory);
diff --git a/hyracks-storage-common/src/main/java/edu/uci/ics/hyracks/storage/common/buffercache/BufferCache.java b/hyracks-storage-common/src/main/java/edu/uci/ics/hyracks/storage/common/buffercache/BufferCache.java
index bfcd765..7abb20c 100644
--- a/hyracks-storage-common/src/main/java/edu/uci/ics/hyracks/storage/common/buffercache/BufferCache.java
+++ b/hyracks-storage-common/src/main/java/edu/uci/ics/hyracks/storage/common/buffercache/BufferCache.java
@@ -148,8 +148,10 @@
if (!newPage) {
if (!cPage.valid) {
/*
- * We got a buffer and we have pinned it. But its invalid. If its a new page, we just mark it as valid
- * and return. Or else, while we hold the page lock, we get a write latch on the data and start a read.
+ * We got a buffer and we have pinned it. But its invalid. If
+ * its a new page, we just mark it as valid and return. Or else,
+ * while we hold the page lock, we get a write latch on the data
+ * and start a read.
*/
cPage.acquireWriteLatch(false);
try {
@@ -175,7 +177,8 @@
CachedPage cPage = null;
/*
- * Hash dpid to get a bucket and then check if the page exists in the bucket.
+ * Hash dpid to get a bucket and then check if the page exists in
+ * the bucket.
*/
int hash = hash(dpid);
CacheBucket bucket = pageMap[hash];
@@ -193,29 +196,38 @@
bucket.bucketLock.unlock();
}
/*
- * If we got here, the page was not in the hash table. Now we ask the page replacement strategy to find us a victim.
+ * If we got here, the page was not in the hash table. Now we ask
+ * the page replacement strategy to find us a victim.
*/
CachedPage victim = (CachedPage) pageReplacementStrategy.findVictim();
if (victim != null) {
/*
- * We have a victim with the following invariants.
- * 1. The dpid on the CachedPage may or may not be valid.
- * 2. We have a pin on the CachedPage. We have to deal with three cases here.
- * Case 1: The dpid on the CachedPage is invalid (-1). This indicates that this buffer has never been used.
- * So we are the only ones holding it. Get a lock on the required dpid's hash bucket, check if someone inserted
- * the page we want into the table. If so, decrement the pincount on the victim and return the winner page in the
- * table. If such a winner does not exist, insert the victim and return it.
- * Case 2: The dpid on the CachedPage is valid.
- * Case 2a: The current dpid and required dpid hash to the same bucket.
- * Get the bucket lock, check that the victim is still at pinCount == 1 If so check if there is a winning
- * CachedPage with the required dpid. If so, decrement the pinCount on the victim and return the winner.
- * If not, update the contents of the CachedPage to hold the required dpid and return it. If the picCount
- * on the victim was != 1 or CachedPage was dirty someone used the victim for its old contents -- Decrement
- * the pinCount and retry.
- * Case 2b: The current dpid and required dpid hash to different buckets. Get the two bucket locks in the order
- * of the bucket indexes (Ordering prevents deadlocks). Check for the existence of a winner in the new bucket
- * and for potential use of the victim (pinCount != 1). If everything looks good, remove the CachedPage from
- * the old bucket, and add it to the new bucket and update its header with the new dpid.
+ * We have a victim with the following invariants. 1. The dpid
+ * on the CachedPage may or may not be valid. 2. We have a pin
+ * on the CachedPage. We have to deal with three cases here.
+ * Case 1: The dpid on the CachedPage is invalid (-1). This
+ * indicates that this buffer has never been used. So we are the
+ * only ones holding it. Get a lock on the required dpid's hash
+ * bucket, check if someone inserted the page we want into the
+ * table. If so, decrement the pincount on the victim and return
+ * the winner page in the table. If such a winner does not
+ * exist, insert the victim and return it. Case 2: The dpid on
+ * the CachedPage is valid. Case 2a: The current dpid and
+ * required dpid hash to the same bucket. Get the bucket lock,
+ * check that the victim is still at pinCount == 1 If so check
+ * if there is a winning CachedPage with the required dpid. If
+ * so, decrement the pinCount on the victim and return the
+ * winner. If not, update the contents of the CachedPage to hold
+ * the required dpid and return it. If the picCount on the
+ * victim was != 1 or CachedPage was dirty someone used the
+ * victim for its old contents -- Decrement the pinCount and
+ * retry. Case 2b: The current dpid and required dpid hash to
+ * different buckets. Get the two bucket locks in the order of
+ * the bucket indexes (Ordering prevents deadlocks). Check for
+ * the existence of a winner in the new bucket and for potential
+ * use of the victim (pinCount != 1). If everything looks good,
+ * remove the CachedPage from the old bucket, and add it to the
+ * new bucket and update its header with the new dpid.
*/
if (victim.dpid < 0) {
/*
@@ -312,7 +324,9 @@
}
}
/*
- * Victimization failed -- all pages pinned? wait a bit, increment victimizationTryCount and loop around. Give up after MAX_VICTIMIZATION_TRY_COUNT trys.
+ * Victimization failed -- all pages pinned? wait a bit, increment
+ * victimizationTryCount and loop around. Give up after
+ * MAX_VICTIMIZATION_TRY_COUNT trys.
*/
if (++victimizationTryCount >= MAX_VICTIMIZATION_TRY_COUNT) {
return null;
@@ -654,7 +668,8 @@
}
fileInfoMap.remove(entryFileId);
unreferencedFileFound = true;
- // for-each iterator is invalid because we changed fileInfoMap
+ // for-each iterator is invalid because we changed
+ // fileInfoMap
break;
}
}
@@ -788,7 +803,7 @@
} finally {
fileMapManager.unregisterFile(fileId);
if (fInfo != null) {
- // Mark the fInfo as deleted,
+ // Mark the fInfo as deleted,
// such that when its pages are reclaimed in openFile(),
// the pages are not flushed to disk but only invalidates.
ioManager.close(fInfo.getFileHandle());
diff --git a/hyracks-storage-common/src/main/java/edu/uci/ics/hyracks/storage/common/buffercache/DebugBufferCache.java b/hyracks-storage-common/src/main/java/edu/uci/ics/hyracks/storage/common/buffercache/DebugBufferCache.java
index d610c7e..13f7d52 100644
--- a/hyracks-storage-common/src/main/java/edu/uci/ics/hyracks/storage/common/buffercache/DebugBufferCache.java
+++ b/hyracks-storage-common/src/main/java/edu/uci/ics/hyracks/storage/common/buffercache/DebugBufferCache.java
@@ -30,16 +30,16 @@
// Actual BufferCache functionality is delegated to this bufferCache.
private final IBufferCache bufferCache;
- private AtomicLong pinCount;
- private AtomicLong unpinCount;
- private AtomicLong readLatchCount;
- private AtomicLong readUnlatchCount;
- private AtomicLong writeLatchCount;
- private AtomicLong writeUnlatchCount;
- private AtomicLong createFileCount;
- private AtomicLong deleteFileCount;
- private AtomicLong openFileCount;
- private AtomicLong closeFileCount;
+ private AtomicLong pinCount = new AtomicLong();
+ private AtomicLong unpinCount = new AtomicLong();
+ private AtomicLong readLatchCount = new AtomicLong();
+ private AtomicLong readUnlatchCount = new AtomicLong();
+ private AtomicLong writeLatchCount = new AtomicLong();
+ private AtomicLong writeUnlatchCount = new AtomicLong();
+ private AtomicLong createFileCount = new AtomicLong();
+ private AtomicLong deleteFileCount = new AtomicLong();
+ private AtomicLong openFileCount = new AtomicLong();
+ private AtomicLong closeFileCount = new AtomicLong();
public DebugBufferCache(IBufferCache bufferCache) {
this.bufferCache = bufferCache;
diff --git a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/btree/OrderedIndexDeleteTest.java b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/btree/OrderedIndexDeleteTest.java
index 93075a1..0935315 100644
--- a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/btree/OrderedIndexDeleteTest.java
+++ b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/btree/OrderedIndexDeleteTest.java
@@ -20,6 +20,7 @@
import edu.uci.ics.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;
import edu.uci.ics.hyracks.dataflow.common.data.marshalling.UTF8StringSerializerDeserializer;
import edu.uci.ics.hyracks.storage.am.btree.frames.BTreeLeafFrameType;
+import edu.uci.ics.hyracks.storage.am.config.AccessMethodTestsConfig;
@SuppressWarnings("rawtypes")
public abstract class OrderedIndexDeleteTest extends OrderedIndexTestDriver {
@@ -31,8 +32,8 @@
this.orderedIndexTestUtils = new OrderedIndexTestUtils();
}
- private static final int numInsertRounds = 3;
- private static final int numDeleteRounds = 3;
+ private static final int numInsertRounds = AccessMethodTestsConfig.BTREE_NUM_INSERT_ROUNDS;
+ private static final int numDeleteRounds = AccessMethodTestsConfig.BTREE_NUM_DELETE_ROUNDS;
@Override
protected void runTest(ISerializerDeserializer[] fieldSerdes, int numKeys, BTreeLeafFrameType leafType,
diff --git a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/btree/OrderedIndexMultiThreadTest.java b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/btree/OrderedIndexMultiThreadTest.java
index 3a894a2..0401038 100644
--- a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/btree/OrderedIndexMultiThreadTest.java
+++ b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/btree/OrderedIndexMultiThreadTest.java
@@ -35,6 +35,7 @@
import edu.uci.ics.hyracks.storage.am.common.TestOperationSelector.TestOperation;
import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
import edu.uci.ics.hyracks.storage.am.common.api.TreeIndexException;
+import edu.uci.ics.hyracks.storage.am.config.AccessMethodTestsConfig;
@SuppressWarnings("rawtypes")
public abstract class OrderedIndexMultiThreadTest {
@@ -45,7 +46,7 @@
protected final int REGULAR_NUM_THREADS = Runtime.getRuntime().availableProcessors();
// Excessive number of threads for testing.
protected final int EXCESSIVE_NUM_THREADS = Runtime.getRuntime().availableProcessors() * 4;
- protected final int NUM_OPERATIONS = 10000;
+ protected final int NUM_OPERATIONS = AccessMethodTestsConfig.BTREE_MULTITHREAD_NUM_OPERATIONS;
protected ArrayList<TestWorkloadConf> workloadConfs = getTestWorkloadConf();
diff --git a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/btree/OrderedIndexTestDriver.java b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/btree/OrderedIndexTestDriver.java
index 8daa5e0..ef2ee0b 100644
--- a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/btree/OrderedIndexTestDriver.java
+++ b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/btree/OrderedIndexTestDriver.java
@@ -27,12 +27,13 @@
import edu.uci.ics.hyracks.dataflow.common.data.marshalling.UTF8StringSerializerDeserializer;
import edu.uci.ics.hyracks.dataflow.common.util.TupleUtils;
import edu.uci.ics.hyracks.storage.am.btree.frames.BTreeLeafFrameType;
+import edu.uci.ics.hyracks.storage.am.config.AccessMethodTestsConfig;
@SuppressWarnings("rawtypes")
public abstract class OrderedIndexTestDriver {
protected final Logger LOGGER = Logger.getLogger(OrderedIndexTestDriver.class.getName());
- protected static final int numTuplesToInsert = 10000;
+ protected static final int numTuplesToInsert = AccessMethodTestsConfig.BTREE_NUM_TUPLES_TO_INSERT;
protected abstract OrderedIndexTestContext createTestContext(ISerializerDeserializer[] fieldSerdes, int numKeys,
BTreeLeafFrameType leafType) throws Exception;
diff --git a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/btree/OrderedIndexUpdateTest.java b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/btree/OrderedIndexUpdateTest.java
index 65b2ade..fbf1011 100644
--- a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/btree/OrderedIndexUpdateTest.java
+++ b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/btree/OrderedIndexUpdateTest.java
@@ -20,6 +20,7 @@
import edu.uci.ics.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;
import edu.uci.ics.hyracks.dataflow.common.data.marshalling.UTF8StringSerializerDeserializer;
import edu.uci.ics.hyracks.storage.am.btree.frames.BTreeLeafFrameType;
+import edu.uci.ics.hyracks.storage.am.config.AccessMethodTestsConfig;
@SuppressWarnings("rawtypes")
public abstract class OrderedIndexUpdateTest extends OrderedIndexTestDriver {
@@ -31,7 +32,7 @@
this.orderedIndexTestUtils = new OrderedIndexTestUtils();
}
- private static final int numUpdateRounds = 3;
+ private static final int numUpdateRounds = AccessMethodTestsConfig.BTREE_NUM_UPDATE_ROUNDS;
@Override
protected void runTest(ISerializerDeserializer[] fieldSerdes, int numKeys, BTreeLeafFrameType leafType,
diff --git a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/common/TreeIndexTestUtils.java b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/common/TreeIndexTestUtils.java
index d16553a..c99299f 100644
--- a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/common/TreeIndexTestUtils.java
+++ b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/common/TreeIndexTestUtils.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.common;
import static org.junit.Assert.fail;
diff --git a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/config/AccessMethodTestsConfig.java b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/config/AccessMethodTestsConfig.java
new file mode 100644
index 0000000..73ada0e
--- /dev/null
+++ b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/config/AccessMethodTestsConfig.java
@@ -0,0 +1,118 @@
+/*
+ * 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.config;
+
+/**
+ * Global parameters used for executing access method JUnit tests.
+ */
+public class AccessMethodTestsConfig {
+ // Test params for RTree, LSMRTree and LSMRTreeWithAntiMatterTuples.
+ public static final int RTREE_NUM_TUPLES_TO_INSERT = 10000;
+ public static final int RTREE_NUM_INSERT_ROUNDS = 2;
+ public static final int RTREE_NUM_DELETE_ROUNDS = 2;
+ public static final int RTREE_MULTITHREAD_NUM_OPERATIONS = 10000;
+ // Test params for LSMRTree and LSMRTreeWithAntiMatterTuples.
+ public static final int LSM_RTREE_BULKLOAD_ROUNDS = 5;
+ public static final int LSM_RTREE_MAX_TREES_TO_MERGE = 3;
+
+ // Test params for BTree, LSMBTree.
+ public static final int BTREE_NUM_TUPLES_TO_INSERT = 10000;
+ public static final int BTREE_NUM_INSERT_ROUNDS = 3;
+ public static final int BTREE_NUM_DELETE_ROUNDS = 3;
+ public static final int BTREE_NUM_UPDATE_ROUNDS = 3;
+ public static final int BTREE_MULTITHREAD_NUM_OPERATIONS = 10000;
+ // Test params for LSMBTree only.
+ public static final int LSM_BTREE_BULKLOAD_ROUNDS = 5;
+ public static final int LSM_BTREE_MAX_TREES_TO_MERGE = 10;
+
+ // Mem configuration for RTree.
+ public static final int RTREE_PAGE_SIZE = 512;
+ public static final int RTREE_NUM_PAGES = 1000;
+ public static final int RTREE_MAX_OPEN_FILES = 10;
+ public static final int RTREE_HYRACKS_FRAME_SIZE = 128;
+
+ // Mem configuration for LSMRTree and LSMRTreeWithAntiMatterTuples.
+ public static final int LSM_RTREE_DISK_PAGE_SIZE = 256;
+ public static final int LSM_RTREE_DISK_NUM_PAGES = 1000;
+ public static final int LSM_RTREE_DISK_MAX_OPEN_FILES = 2000;
+ public static final int LSM_RTREE_MEM_PAGE_SIZE = 256;
+ public static final int LSM_RTREE_MEM_NUM_PAGES = 1000;
+ public static final int LSM_RTREE_HYRACKS_FRAME_SIZE = 128;
+
+ // Mem configuration for BTree.
+ public static final int BTREE_PAGE_SIZE = 256;
+ public static final int BTREE_NUM_PAGES = 100;
+ public static final int BTREE_MAX_OPEN_FILES = 10;
+ public static final int BTREE_HYRACKS_FRAME_SIZE = 128;
+
+ // Mem configuration for LSMBTree.
+ public static final int LSM_BTREE_DISK_PAGE_SIZE = 256;
+ public static final int LSM_BTREE_DISK_NUM_PAGES = 1000;
+ public static final int LSM_BTREE_DISK_MAX_OPEN_FILES = 200;
+ public static final int LSM_BTREE_MEM_PAGE_SIZE = 256;
+ public static final int LSM_BTREE_MEM_NUM_PAGES = 100;
+ public static final int LSM_BTREE_HYRACKS_FRAME_SIZE = 128;
+}
+
+/* ORIGINAL TEST PARAMETERS: DO NOT EDIT!
+// Test params for RTree, LSMRTree and LSMRTreeWithAntiMatterTuples.
+public static final int RTREE_NUM_TUPLES_TO_INSERT = 10000;
+public static final int RTREE_NUM_INSERT_ROUNDS = 2;
+public static final int RTREE_NUM_DELETE_ROUNDS = 2;
+public static final int RTREE_MULTITHREAD_NUM_OPERATIONS = 10000;
+// Test params for LSMRTree and LSMRTreeWithAntiMatterTuples.
+public static final int LSM_RTREE_BULKLOAD_ROUNDS = 5;
+public static final int LSM_RTREE_MAX_TREES_TO_MERGE = 3;
+
+// Test params for BTree, LSMBTree.
+public static final int BTREE_NUM_TUPLES_TO_INSERT = 10000;
+public static final int BTREE_NUM_INSERT_ROUNDS = 3;
+public static final int BTREE_NUM_DELETE_ROUNDS = 3;
+public static final int BTREE_NUM_UPDATE_ROUNDS = 3;
+public static final int BTREE_MULTITHREAD_NUM_OPERATIONS = 10000;
+// Test params for LSMBTree only.
+public static final int LSM_BTREE_BULKLOAD_ROUNDS = 5;
+public static final int LSM_BTREE_MAX_TREES_TO_MERGE = 10;
+
+
+// Mem configuration for RTree.
+public static final int RTREE_PAGE_SIZE = 512;
+public static final int RTREE_NUM_PAGES = 1000;
+public static final int RTREE_MAX_OPEN_FILES = 10;
+public static final int RTREE_HYRACKS_FRAME_SIZE = 128;
+
+// Mem configuration for LSMRTree and LSMRTreeWithAntiMatterTuples.
+public static final int LSM_RTREE_DISK_PAGE_SIZE = 256;
+public static final int LSM_RTREE_DISK_NUM_PAGES = 1000;
+public static final int LSM_RTREE_DISK_MAX_OPEN_FILES = 2000;
+public static final int LSM_RTREE_MEM_PAGE_SIZE = 256;
+public static final int LSM_RTREE_MEM_NUM_PAGES = 1000;
+public static final int LSM_RTREE_HYRACKS_FRAME_SIZE = 128;
+
+// Mem configuration for BTree.
+public static final int BTREE_PAGE_SIZE = 256;
+public static final int BTREE_NUM_PAGES = 100;
+public static final int BTREE_MAX_OPEN_FILES = 10;
+public static final int BTREE_HYRACKS_FRAME_SIZE = 128;
+
+// Mem configuration for LSMBTree.
+public static final int LSM_BTREE_DISK_PAGE_SIZE = 256;
+public static final int LSM_BTREE_DISK_NUM_PAGES = 1000;
+public static final int LSM_BTREE_DISK_MAX_OPEN_FILES = 200;
+public static final int LSM_BTREE_MEM_PAGE_SIZE = 256;
+public static final int LSM_BTREE_MEM_NUM_PAGES = 100;
+public static final int LSM_BTREE_HYRACKS_FRAME_SIZE = 128;
+*/
diff --git a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/AbstractRTreeBulkLoadTest.java b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/AbstractRTreeBulkLoadTest.java
index 198ac58..0d0c3b5 100644
--- a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/AbstractRTreeBulkLoadTest.java
+++ b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/AbstractRTreeBulkLoadTest.java
@@ -20,6 +20,7 @@
import edu.uci.ics.hyracks.dataflow.common.data.marshalling.DoubleSerializerDeserializer;
import edu.uci.ics.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;
import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
@SuppressWarnings("rawtypes")
public abstract class AbstractRTreeBulkLoadTest extends AbstractRTreeTestDriver {
@@ -34,8 +35,9 @@
@Override
protected void runTest(ISerializerDeserializer[] fieldSerdes,
- IPrimitiveValueProviderFactory[] valueProviderFactories, int numKeys, ITupleReference key) throws Exception {
- AbstractRTreeTestContext ctx = createTestContext(fieldSerdes, valueProviderFactories, numKeys);
+ IPrimitiveValueProviderFactory[] valueProviderFactories, int numKeys, ITupleReference key,
+ RTreePolicyType rtreePolicyType) throws Exception {
+ AbstractRTreeTestContext ctx = createTestContext(fieldSerdes, valueProviderFactories, numKeys, rtreePolicyType);
for (int i = 0; i < bulkLoadRounds; i++) {
// We assume all fieldSerdes are of the same type. Check the first
// one to determine which field types to generate.
diff --git a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/AbstractRTreeDeleteTest.java b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/AbstractRTreeDeleteTest.java
index e70f433..2e0f32f 100644
--- a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/AbstractRTreeDeleteTest.java
+++ b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/AbstractRTreeDeleteTest.java
@@ -20,14 +20,16 @@
import edu.uci.ics.hyracks.dataflow.common.data.marshalling.DoubleSerializerDeserializer;
import edu.uci.ics.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;
import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
+import edu.uci.ics.hyracks.storage.am.config.AccessMethodTestsConfig;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
@SuppressWarnings("rawtypes")
public abstract class AbstractRTreeDeleteTest extends AbstractRTreeTestDriver {
private final RTreeTestUtils rTreeTestUtils;
- private static final int numInsertRounds = 2;
- private static final int numDeleteRounds = 2;
+ private static final int numInsertRounds = AccessMethodTestsConfig.RTREE_NUM_INSERT_ROUNDS;
+ private static final int numDeleteRounds = AccessMethodTestsConfig.RTREE_NUM_DELETE_ROUNDS;
public AbstractRTreeDeleteTest() {
this.rTreeTestUtils = new RTreeTestUtils();
@@ -35,8 +37,9 @@
@Override
protected void runTest(ISerializerDeserializer[] fieldSerdes,
- IPrimitiveValueProviderFactory[] valueProviderFactories, int numKeys, ITupleReference key) throws Exception {
- AbstractRTreeTestContext ctx = createTestContext(fieldSerdes, valueProviderFactories, numKeys);
+ IPrimitiveValueProviderFactory[] valueProviderFactories, int numKeys, ITupleReference key,
+ RTreePolicyType rtreePolicyType) throws Exception {
+ AbstractRTreeTestContext ctx = createTestContext(fieldSerdes, valueProviderFactories, numKeys, rtreePolicyType);
for (int i = 0; i < numInsertRounds; i++) {
// We assume all fieldSerdes are of the same type. Check the first
// one to determine which field types to generate.
diff --git a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/AbstractRTreeExamplesTest.java b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/AbstractRTreeExamplesTest.java
index baa04f5..8b1f3c7 100644
--- a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/AbstractRTreeExamplesTest.java
+++ b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/AbstractRTreeExamplesTest.java
@@ -43,6 +43,7 @@
import edu.uci.ics.hyracks.storage.am.common.impls.NoOpOperationCallback;
import edu.uci.ics.hyracks.storage.am.common.impls.TreeDiskOrderScanCursor;
import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
import edu.uci.ics.hyracks.storage.am.rtree.impls.SearchPredicate;
import edu.uci.ics.hyracks.storage.am.rtree.util.RTreeUtils;
@@ -53,7 +54,8 @@
protected abstract ITreeIndex createTreeIndex(ITypeTraits[] typeTraits,
IBinaryComparatorFactory[] rtreeCmpFactories, IBinaryComparatorFactory[] btreeCmpFactories,
- IPrimitiveValueProviderFactory[] valueProviderFactories) throws TreeIndexException;
+ IPrimitiveValueProviderFactory[] valueProviderFactories, RTreePolicyType rtreePolicyType)
+ throws TreeIndexException;
protected abstract int getIndexFileId();
@@ -108,7 +110,8 @@
rtreeCmpFactories.length, IntegerPointable.FACTORY);
int indexFileId = getIndexFileId();
- ITreeIndex treeIndex = createTreeIndex(typeTraits, rtreeCmpFactories, btreeCmpFactories, valueProviderFactories);
+ ITreeIndex treeIndex = createTreeIndex(typeTraits, rtreeCmpFactories, btreeCmpFactories,
+ valueProviderFactories, RTreePolicyType.RTREE);
treeIndex.create(indexFileId);
treeIndex.open(indexFileId);
@@ -215,7 +218,8 @@
rtreeCmpFactories.length, DoublePointable.FACTORY);
int indexFileId = getIndexFileId();
- ITreeIndex treeIndex = createTreeIndex(typeTraits, rtreeCmpFactories, btreeCmpFactories, valueProviderFactories);
+ ITreeIndex treeIndex = createTreeIndex(typeTraits, rtreeCmpFactories, btreeCmpFactories,
+ valueProviderFactories, RTreePolicyType.RTREE);
treeIndex.create(indexFileId);
treeIndex.open(indexFileId);
@@ -314,7 +318,8 @@
rtreeCmpFactories.length, IntegerPointable.FACTORY);
int indexFileId = getIndexFileId();
- ITreeIndex treeIndex = createTreeIndex(typeTraits, rtreeCmpFactories, btreeCmpFactories, valueProviderFactories);
+ ITreeIndex treeIndex = createTreeIndex(typeTraits, rtreeCmpFactories, btreeCmpFactories,
+ valueProviderFactories, RTreePolicyType.RTREE);
treeIndex.create(indexFileId);
treeIndex.open(indexFileId);
@@ -446,7 +451,8 @@
rtreeCmpFactories.length, IntegerPointable.FACTORY);
int indexFileId = getIndexFileId();
- ITreeIndex treeIndex = createTreeIndex(typeTraits, rtreeCmpFactories, btreeCmpFactories, valueProviderFactories);
+ ITreeIndex treeIndex = createTreeIndex(typeTraits, rtreeCmpFactories, btreeCmpFactories,
+ valueProviderFactories, RTreePolicyType.RTREE);
treeIndex.create(indexFileId);
treeIndex.open(indexFileId);
@@ -512,8 +518,7 @@
}
}
- private void diskOrderScan(IIndexAccessor indexAccessor, ISerializerDeserializer[] fieldSerdes)
- throws Exception {
+ private void diskOrderScan(IIndexAccessor indexAccessor, ISerializerDeserializer[] fieldSerdes) throws Exception {
try {
if (LOGGER.isLoggable(Level.INFO)) {
LOGGER.info("Disk-Order Scan:");
@@ -541,12 +546,12 @@
LOGGER.info("Ignoring disk-order scan since it's not supported.");
}
} catch (ClassCastException e) {
- // Ignore exception because IIndexAccessor sometimes isn't
- // an ITreeIndexAccessor, e.g., for the LSMRTree.
- if (LOGGER.isLoggable(Level.INFO)) {
- LOGGER.info("Ignoring disk-order scan since it's not supported.");
- }
- }
+ // Ignore exception because IIndexAccessor sometimes isn't
+ // an ITreeIndexAccessor, e.g., for the LSMRTree.
+ if (LOGGER.isLoggable(Level.INFO)) {
+ LOGGER.info("Ignoring disk-order scan since it's not supported.");
+ }
+ }
}
private void rangeSearch(IBinaryComparatorFactory[] cmpFactories, IIndexAccessor indexAccessor,
diff --git a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/AbstractRTreeInsertTest.java b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/AbstractRTreeInsertTest.java
index cdd6ee0..53712b8 100644
--- a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/AbstractRTreeInsertTest.java
+++ b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/AbstractRTreeInsertTest.java
@@ -20,6 +20,7 @@
import edu.uci.ics.hyracks.dataflow.common.data.marshalling.DoubleSerializerDeserializer;
import edu.uci.ics.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;
import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
/**
* Tests the RTree insert operation with integer and double fields using various
@@ -41,8 +42,9 @@
@Override
protected void runTest(ISerializerDeserializer[] fieldSerdes,
- IPrimitiveValueProviderFactory[] valueProviderFactories, int numKeys, ITupleReference key) throws Exception {
- AbstractRTreeTestContext ctx = createTestContext(fieldSerdes, valueProviderFactories, numKeys);
+ IPrimitiveValueProviderFactory[] valueProviderFactories, int numKeys, ITupleReference key,
+ RTreePolicyType rtreePolicyType) throws Exception {
+ AbstractRTreeTestContext ctx = createTestContext(fieldSerdes, valueProviderFactories, numKeys, rtreePolicyType);
// We assume all fieldSerdes are of the same type. Check the first one
// to determine which field types to generate.
if (fieldSerdes[0] instanceof IntegerSerializerDeserializer) {
diff --git a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/AbstractRTreeMultiThreadTest.java b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/AbstractRTreeMultiThreadTest.java
index 2c185a5f..9aafc48 100644
--- a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/AbstractRTreeMultiThreadTest.java
+++ b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/AbstractRTreeMultiThreadTest.java
@@ -38,6 +38,8 @@
import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
import edu.uci.ics.hyracks.storage.am.common.api.TreeIndexException;
+import edu.uci.ics.hyracks.storage.am.config.AccessMethodTestsConfig;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
import edu.uci.ics.hyracks.storage.am.rtree.util.RTreeUtils;
@SuppressWarnings("rawtypes")
@@ -49,7 +51,7 @@
protected final int REGULAR_NUM_THREADS = Runtime.getRuntime().availableProcessors();
// Excessive number of threads for testing.
protected final int EXCESSIVE_NUM_THREADS = Runtime.getRuntime().availableProcessors() * 4;
- protected final int NUM_OPERATIONS = 5000;
+ protected final int NUM_OPERATIONS = AccessMethodTestsConfig.RTREE_MULTITHREAD_NUM_OPERATIONS;
protected ArrayList<TestWorkloadConf> workloadConfs = getTestWorkloadConf();
@@ -59,7 +61,8 @@
protected abstract ITreeIndex createTreeIndex(ITypeTraits[] typeTraits,
IBinaryComparatorFactory[] rtreeCmpFactories, IBinaryComparatorFactory[] btreeCmpFactories,
- IPrimitiveValueProviderFactory[] valueProviderFactories) throws TreeIndexException;
+ IPrimitiveValueProviderFactory[] valueProviderFactories, RTreePolicyType rtreePolicyType)
+ throws TreeIndexException;
protected abstract int getFileId();
@@ -78,8 +81,9 @@
}
protected void runTest(ISerializerDeserializer[] fieldSerdes,
- IPrimitiveValueProviderFactory[] valueProviderFactories, int numKeys, int numThreads,
- TestWorkloadConf conf, String dataMsg) throws HyracksException, InterruptedException, TreeIndexException {
+ IPrimitiveValueProviderFactory[] valueProviderFactories, int numKeys, RTreePolicyType rtreePolicyType,
+ int numThreads, TestWorkloadConf conf, String dataMsg) throws HyracksException, InterruptedException,
+ TreeIndexException {
setUp();
if (LOGGER.isLoggable(Level.INFO)) {
@@ -93,7 +97,8 @@
IBinaryComparatorFactory[] btreeCmpFactories = SerdeUtils.serdesToComparatorFactories(fieldSerdes,
fieldSerdes.length);
- ITreeIndex index = createTreeIndex(typeTraits, rtreeCmpFactories, btreeCmpFactories, valueProviderFactories);
+ ITreeIndex index = createTreeIndex(typeTraits, rtreeCmpFactories, btreeCmpFactories, valueProviderFactories,
+ rtreePolicyType);
ITreeIndexTestWorkerFactory workerFactory = getWorkerFactory();
// 4 batches per thread.
@@ -113,7 +118,7 @@
}
@Test
- public void twoDimensionsInt() throws InterruptedException, HyracksException, TreeIndexException {
+ public void rtreeTwoDimensionsInt() throws InterruptedException, HyracksException, TreeIndexException {
ISerializerDeserializer[] fieldSerdes = { IntegerSerializerDeserializer.INSTANCE,
IntegerSerializerDeserializer.INSTANCE, IntegerSerializerDeserializer.INSTANCE,
IntegerSerializerDeserializer.INSTANCE, IntegerSerializerDeserializer.INSTANCE };
@@ -125,13 +130,36 @@
String dataMsg = "Two Dimensions Of Integer Values";
for (TestWorkloadConf conf : workloadConfs) {
- runTest(fieldSerdes, valueProviderFactories, numKeys, REGULAR_NUM_THREADS, conf, dataMsg);
- runTest(fieldSerdes, valueProviderFactories, numKeys, EXCESSIVE_NUM_THREADS, conf, dataMsg);
+ runTest(fieldSerdes, valueProviderFactories, numKeys, RTreePolicyType.RTREE, REGULAR_NUM_THREADS, conf,
+ dataMsg);
+ runTest(fieldSerdes, valueProviderFactories, numKeys, RTreePolicyType.RTREE, EXCESSIVE_NUM_THREADS, conf,
+ dataMsg);
}
}
@Test
- public void fourDimensionsDouble() throws InterruptedException, HyracksException, TreeIndexException {
+ public void rtreeTwoDimensionsDouble() throws Exception {
+ ISerializerDeserializer[] fieldSerdes = { DoubleSerializerDeserializer.INSTANCE,
+ DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE,
+ DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE };
+
+ int numKeys = 4;
+ IPrimitiveValueProviderFactory[] valueProviderFactories = RTreeUtils.createPrimitiveValueProviderFactories(
+ numKeys, DoublePointable.FACTORY);
+
+ String dataMsg = "Two Dimensions Of Double Values";
+
+ for (TestWorkloadConf conf : workloadConfs) {
+ runTest(fieldSerdes, valueProviderFactories, numKeys, RTreePolicyType.RTREE, REGULAR_NUM_THREADS, conf,
+ dataMsg);
+ runTest(fieldSerdes, valueProviderFactories, numKeys, RTreePolicyType.RTREE, EXCESSIVE_NUM_THREADS, conf,
+ dataMsg);
+ }
+
+ }
+
+ @Test
+ public void rtreeFourDimensionsDouble() throws InterruptedException, HyracksException, TreeIndexException {
ISerializerDeserializer[] fieldSerdes = { DoubleSerializerDeserializer.INSTANCE,
DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE,
DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE,
@@ -145,8 +173,74 @@
String dataMsg = "Four Dimensions Of Double Values";
for (TestWorkloadConf conf : workloadConfs) {
- runTest(fieldSerdes, valueProviderFactories, numKeys, REGULAR_NUM_THREADS, conf, dataMsg);
- runTest(fieldSerdes, valueProviderFactories, numKeys, EXCESSIVE_NUM_THREADS, conf, dataMsg);
+ runTest(fieldSerdes, valueProviderFactories, numKeys, RTreePolicyType.RTREE, REGULAR_NUM_THREADS, conf,
+ dataMsg);
+ runTest(fieldSerdes, valueProviderFactories, numKeys, RTreePolicyType.RTREE, EXCESSIVE_NUM_THREADS, conf,
+ dataMsg);
}
}
+
+ @Test
+ public void rstartreeTwoDimensionsInt() throws InterruptedException, HyracksException, TreeIndexException {
+ ISerializerDeserializer[] fieldSerdes = { IntegerSerializerDeserializer.INSTANCE,
+ IntegerSerializerDeserializer.INSTANCE, IntegerSerializerDeserializer.INSTANCE,
+ IntegerSerializerDeserializer.INSTANCE, IntegerSerializerDeserializer.INSTANCE };
+
+ int numKeys = 4;
+ IPrimitiveValueProviderFactory[] valueProviderFactories = RTreeUtils.createPrimitiveValueProviderFactories(
+ numKeys, IntegerPointable.FACTORY);
+
+ String dataMsg = "Two Dimensions Of Integer Values";
+
+ for (TestWorkloadConf conf : workloadConfs) {
+ runTest(fieldSerdes, valueProviderFactories, numKeys, RTreePolicyType.RSTARTREE, REGULAR_NUM_THREADS, conf,
+ dataMsg);
+ runTest(fieldSerdes, valueProviderFactories, numKeys, RTreePolicyType.RSTARTREE, EXCESSIVE_NUM_THREADS,
+ conf, dataMsg);
+ }
+ }
+
+ @Test
+ public void rstartreeTwoDimensionsDouble() throws Exception {
+ ISerializerDeserializer[] fieldSerdes = { DoubleSerializerDeserializer.INSTANCE,
+ DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE,
+ DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE };
+
+ int numKeys = 4;
+ IPrimitiveValueProviderFactory[] valueProviderFactories = RTreeUtils.createPrimitiveValueProviderFactories(
+ numKeys, DoublePointable.FACTORY);
+
+ String dataMsg = "Two Dimensions Of Double Values";
+
+ for (TestWorkloadConf conf : workloadConfs) {
+ runTest(fieldSerdes, valueProviderFactories, numKeys, RTreePolicyType.RSTARTREE, REGULAR_NUM_THREADS, conf,
+ dataMsg);
+ runTest(fieldSerdes, valueProviderFactories, numKeys, RTreePolicyType.RSTARTREE, EXCESSIVE_NUM_THREADS,
+ conf, dataMsg);
+ }
+
+ }
+
+ @Test
+ public void rstartreeFourDimensionsDouble() throws InterruptedException, HyracksException, TreeIndexException {
+ ISerializerDeserializer[] fieldSerdes = { DoubleSerializerDeserializer.INSTANCE,
+ DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE,
+ DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE,
+ DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE,
+ DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE };
+
+ int numKeys = 8;
+ IPrimitiveValueProviderFactory[] valueProviderFactories = RTreeUtils.createPrimitiveValueProviderFactories(
+ numKeys, DoublePointable.FACTORY);
+
+ String dataMsg = "Four Dimensions Of Double Values";
+
+ for (TestWorkloadConf conf : workloadConfs) {
+ runTest(fieldSerdes, valueProviderFactories, numKeys, RTreePolicyType.RSTARTREE, REGULAR_NUM_THREADS, conf,
+ dataMsg);
+ runTest(fieldSerdes, valueProviderFactories, numKeys, RTreePolicyType.RSTARTREE, EXCESSIVE_NUM_THREADS,
+ conf, dataMsg);
+ }
+ }
+
}
diff --git a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/AbstractRTreeTestDriver.java b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/AbstractRTreeTestDriver.java
index 10f4364..4c0bbc7 100644
--- a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/AbstractRTreeTestDriver.java
+++ b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/AbstractRTreeTestDriver.java
@@ -29,26 +29,30 @@
import edu.uci.ics.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;
import edu.uci.ics.hyracks.dataflow.common.util.TupleUtils;
import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
+import edu.uci.ics.hyracks.storage.am.config.AccessMethodTestsConfig;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
import edu.uci.ics.hyracks.storage.am.rtree.util.RTreeUtils;
@SuppressWarnings("rawtypes")
public abstract class AbstractRTreeTestDriver {
protected final Logger LOGGER = Logger.getLogger(AbstractRTreeTestDriver.class.getName());
- protected static final int numTuplesToInsert = 5000;
+ protected static final int numTuplesToInsert = AccessMethodTestsConfig.RTREE_NUM_TUPLES_TO_INSERT;
protected abstract AbstractRTreeTestContext createTestContext(ISerializerDeserializer[] fieldSerdes,
- IPrimitiveValueProviderFactory[] valueProviderFactories, int numKeys) throws Exception;
+ IPrimitiveValueProviderFactory[] valueProviderFactories, int numKeys, RTreePolicyType rtreePolicyType)
+ throws Exception;
protected abstract Random getRandom();
protected abstract void runTest(ISerializerDeserializer[] fieldSerdes,
- IPrimitiveValueProviderFactory[] valueProviderFactories, int numKeys, ITupleReference key) throws Exception;
+ IPrimitiveValueProviderFactory[] valueProviderFactories, int numKeys, ITupleReference key,
+ RTreePolicyType rtreePolicyType) throws Exception;
protected abstract String getTestOpName();
@Test
- public void twoDimensionsInt() throws Exception {
+ public void rtreeTwoDimensionsInt() throws Exception {
if (LOGGER.isLoggable(Level.INFO)) {
LOGGER.info("RTree " + getTestOpName() + " Test With Two Dimensions With Integer Keys.");
}
@@ -64,12 +68,12 @@
// and the top right coordinates are 1000, 1000
ITupleReference key = TupleUtils.createIntegerTuple(-1000, -1000, 1000, 1000);
- runTest(fieldSerdes, valueProviderFactories, numKeys, key);
+ runTest(fieldSerdes, valueProviderFactories, numKeys, key, RTreePolicyType.RTREE);
}
@Test
- public void twoDimensionsDouble() throws Exception {
+ public void rtreeTwoDimensionsDouble() throws Exception {
if (LOGGER.isLoggable(Level.INFO)) {
LOGGER.info("RTree " + getTestOpName() + " Test With Two Dimensions With Double Keys.");
}
@@ -85,12 +89,12 @@
// -1000.0 and the top right coordinates are 1000.0, 1000.0
ITupleReference key = TupleUtils.createDoubleTuple(-1000.0, -1000.0, 1000.0, 1000.0);
- runTest(fieldSerdes, valueProviderFactories, numKeys, key);
+ runTest(fieldSerdes, valueProviderFactories, numKeys, key, RTreePolicyType.RTREE);
}
@Test
- public void fourDimensionsDouble() throws Exception {
+ public void rtreeFourDimensionsDouble() throws Exception {
if (LOGGER.isLoggable(Level.INFO)) {
LOGGER.info("RTree " + getTestOpName() + " Test With Four Dimensions With Double Keys.");
}
@@ -110,7 +114,72 @@
ITupleReference key = TupleUtils.createDoubleTuple(-1000.0, -1000.0, -1000.0, -1000.0, 1000.0, 1000.0, 1000.0,
1000.0);
- runTest(fieldSerdes, valueProviderFactories, numKeys, key);
+ runTest(fieldSerdes, valueProviderFactories, numKeys, key, RTreePolicyType.RTREE);
+ }
+ @Test
+ public void rstartreeTwoDimensionsInt() throws Exception {
+ if (LOGGER.isLoggable(Level.INFO)) {
+ LOGGER.info("RTree " + getTestOpName() + " Test With Two Dimensions With Integer Keys.");
+ }
+
+ ISerializerDeserializer[] fieldSerdes = { IntegerSerializerDeserializer.INSTANCE,
+ IntegerSerializerDeserializer.INSTANCE, IntegerSerializerDeserializer.INSTANCE,
+ IntegerSerializerDeserializer.INSTANCE, IntegerSerializerDeserializer.INSTANCE };
+
+ int numKeys = 4;
+ IPrimitiveValueProviderFactory[] valueProviderFactories = RTreeUtils.createPrimitiveValueProviderFactories(
+ numKeys, IntegerPointable.FACTORY);
+ // Range search, the rectangle bottom left coordinates are -1000, -1000
+ // and the top right coordinates are 1000, 1000
+ ITupleReference key = TupleUtils.createIntegerTuple(-1000, -1000, 1000, 1000);
+
+ runTest(fieldSerdes, valueProviderFactories, numKeys, key, RTreePolicyType.RSTARTREE);
+
+ }
+
+ @Test
+ public void rstartreeTwoDimensionsDouble() throws Exception {
+ if (LOGGER.isLoggable(Level.INFO)) {
+ LOGGER.info("RTree " + getTestOpName() + " Test With Two Dimensions With Double Keys.");
+ }
+
+ ISerializerDeserializer[] fieldSerdes = { DoubleSerializerDeserializer.INSTANCE,
+ DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE,
+ DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE };
+
+ int numKeys = 4;
+ IPrimitiveValueProviderFactory[] valueProviderFactories = RTreeUtils.createPrimitiveValueProviderFactories(
+ numKeys, DoublePointable.FACTORY);
+ // Range search, the rectangle bottom left coordinates are -1000.0,
+ // -1000.0 and the top right coordinates are 1000.0, 1000.0
+ ITupleReference key = TupleUtils.createDoubleTuple(-1000.0, -1000.0, 1000.0, 1000.0);
+
+ runTest(fieldSerdes, valueProviderFactories, numKeys, key, RTreePolicyType.RSTARTREE);
+
+ }
+
+ @Test
+ public void rstartreeFourDimensionsDouble() throws Exception {
+ if (LOGGER.isLoggable(Level.INFO)) {
+ LOGGER.info("RTree " + getTestOpName() + " Test With Four Dimensions With Double Keys.");
+ }
+
+ ISerializerDeserializer[] fieldSerdes = { DoubleSerializerDeserializer.INSTANCE,
+ DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE,
+ DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE,
+ DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE,
+ DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE };
+
+ int numKeys = 8;
+ IPrimitiveValueProviderFactory[] valueProviderFactories = RTreeUtils.createPrimitiveValueProviderFactories(
+ numKeys, DoublePointable.FACTORY);
+ // Range search, the rectangle bottom left coordinates are -1000.0,
+ // -1000.0, -1000.0, -1000.0 and the top right coordinates are 1000.0,
+ // 1000.0, 1000.0, 1000.0
+ ITupleReference key = TupleUtils.createDoubleTuple(-1000.0, -1000.0, -1000.0, -1000.0, 1000.0, 1000.0, 1000.0,
+ 1000.0);
+
+ runTest(fieldSerdes, valueProviderFactories, numKeys, key, RTreePolicyType.RSTARTREE);
}
}
diff --git a/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/util/BTreeTestHarness.java b/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/util/BTreeTestHarness.java
index f5f8af5..80d2be1 100644
--- a/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/util/BTreeTestHarness.java
+++ b/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/util/BTreeTestHarness.java
@@ -24,6 +24,7 @@
import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
import edu.uci.ics.hyracks.api.io.FileReference;
import edu.uci.ics.hyracks.storage.am.btree.frames.BTreeLeafFrameType;
+import edu.uci.ics.hyracks.storage.am.config.AccessMethodTestsConfig;
import edu.uci.ics.hyracks.storage.common.buffercache.IBufferCache;
import edu.uci.ics.hyracks.storage.common.file.IFileMapProvider;
import edu.uci.ics.hyracks.test.support.TestStorageManagerComponentHolder;
@@ -34,10 +35,6 @@
BTreeLeafFrameType.REGULAR_NSM, BTreeLeafFrameType.FIELD_PREFIX_COMPRESSED_NSM };
private static final long RANDOM_SEED = 50;
- private static final int DEFAULT_PAGE_SIZE = 256;
- private static final int DEFAULT_NUM_PAGES = 100;
- private static final int DEFAULT_MAX_OPEN_FILES = 10;
- private static final int DEFAULT_HYRACKS_FRAME_SIZE = 128;
protected final int pageSize;
protected final int numPages;
@@ -55,10 +52,10 @@
protected String fileName;
public BTreeTestHarness() {
- this.pageSize = DEFAULT_PAGE_SIZE;
- this.numPages = DEFAULT_NUM_PAGES;
- this.maxOpenFiles = DEFAULT_MAX_OPEN_FILES;
- this.hyracksFrameSize = DEFAULT_HYRACKS_FRAME_SIZE;
+ this.pageSize = AccessMethodTestsConfig.BTREE_PAGE_SIZE;
+ this.numPages = AccessMethodTestsConfig.BTREE_NUM_PAGES;
+ this.maxOpenFiles = AccessMethodTestsConfig.BTREE_MAX_OPEN_FILES;
+ this.hyracksFrameSize = AccessMethodTestsConfig.BTREE_HYRACKS_FRAME_SIZE;
}
public BTreeTestHarness(int pageSize, int numPages, int maxOpenFiles, int hyracksFrameSize) {
diff --git a/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/btree/LSMBTreeMergeTestDriver.java b/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/btree/LSMBTreeMergeTestDriver.java
index 5268de6..6726418 100644
--- a/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/btree/LSMBTreeMergeTestDriver.java
+++ b/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/btree/LSMBTreeMergeTestDriver.java
@@ -23,6 +23,7 @@
import edu.uci.ics.hyracks.storage.am.btree.OrderedIndexTestDriver;
import edu.uci.ics.hyracks.storage.am.btree.OrderedIndexTestUtils;
import edu.uci.ics.hyracks.storage.am.btree.frames.BTreeLeafFrameType;
+import edu.uci.ics.hyracks.storage.am.config.AccessMethodTestsConfig;
import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMIndexAccessor;
@SuppressWarnings("rawtypes")
@@ -50,7 +51,7 @@
orderedIndexTestUtils.bulkLoadStringTuples(ctx, numTuplesToInsert, getRandom());
}
- int maxTreesToMerge = 10;
+ int maxTreesToMerge = AccessMethodTestsConfig.LSM_BTREE_MAX_TREES_TO_MERGE;
for (int i = 0; i < maxTreesToMerge; i++) {
for (int j = 0; j < i; j++) {
if (fieldSerdes[0] instanceof IntegerSerializerDeserializer) {
diff --git a/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/btree/LSMBTreeMultiBulkLoadTest.java b/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/btree/LSMBTreeMultiBulkLoadTest.java
index f1b357e..1237653 100644
--- a/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/btree/LSMBTreeMultiBulkLoadTest.java
+++ b/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/btree/LSMBTreeMultiBulkLoadTest.java
@@ -26,6 +26,7 @@
import edu.uci.ics.hyracks.storage.am.btree.OrderedIndexBulkLoadTest;
import edu.uci.ics.hyracks.storage.am.btree.OrderedIndexTestContext;
import edu.uci.ics.hyracks.storage.am.btree.frames.BTreeLeafFrameType;
+import edu.uci.ics.hyracks.storage.am.config.AccessMethodTestsConfig;
import edu.uci.ics.hyracks.storage.am.lsm.btree.util.LSMBTreeTestContext;
import edu.uci.ics.hyracks.storage.am.lsm.btree.util.LSMBTreeTestHarness;
import edu.uci.ics.hyracks.storage.am.lsm.common.impls.NoMergePolicy;
@@ -34,7 +35,7 @@
public class LSMBTreeMultiBulkLoadTest extends OrderedIndexBulkLoadTest {
public LSMBTreeMultiBulkLoadTest() {
// Using 5 bulk load rounds.
- super(LSMBTreeTestHarness.LEAF_FRAMES_TO_TEST, 5);
+ super(LSMBTreeTestHarness.LEAF_FRAMES_TO_TEST, AccessMethodTestsConfig.LSM_RTREE_BULKLOAD_ROUNDS);
}
private final LSMBTreeTestHarness harness = new LSMBTreeTestHarness();
diff --git a/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/btree/util/LSMBTreeTestHarness.java b/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/btree/util/LSMBTreeTestHarness.java
index d514722..d2f25bc 100644
--- a/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/btree/util/LSMBTreeTestHarness.java
+++ b/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/btree/util/LSMBTreeTestHarness.java
@@ -29,6 +29,7 @@
import edu.uci.ics.hyracks.control.nc.io.IOManager;
import edu.uci.ics.hyracks.storage.am.btree.frames.BTreeLeafFrameType;
import edu.uci.ics.hyracks.storage.am.common.frames.LIFOMetaDataFrameFactory;
+import edu.uci.ics.hyracks.storage.am.config.AccessMethodTestsConfig;
import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMIOScheduler;
import edu.uci.ics.hyracks.storage.am.lsm.common.freepage.InMemoryBufferCache;
import edu.uci.ics.hyracks.storage.am.lsm.common.freepage.InMemoryFreePageManager;
@@ -45,12 +46,6 @@
public static final BTreeLeafFrameType[] LEAF_FRAMES_TO_TEST = new BTreeLeafFrameType[] { BTreeLeafFrameType.REGULAR_NSM };
private static final long RANDOM_SEED = 50;
- private static final int DEFAULT_DISK_PAGE_SIZE = 256;
- private static final int DEFAULT_DISK_NUM_PAGES = 1000;
- private static final int DEFAULT_DISK_MAX_OPEN_FILES = 200;
- private static final int DEFAULT_MEM_PAGE_SIZE = 256;
- private static final int DEFAULT_MEM_NUM_PAGES = 100;
- private static final int DEFAULT_HYRACKS_FRAME_SIZE = 128;
private static final int DUMMY_FILE_ID = -1;
protected final int diskPageSize;
@@ -74,8 +69,13 @@
protected String onDiskDir;
public LSMBTreeTestHarness() {
- this(DEFAULT_DISK_PAGE_SIZE, DEFAULT_DISK_NUM_PAGES, DEFAULT_DISK_MAX_OPEN_FILES, DEFAULT_MEM_PAGE_SIZE,
- DEFAULT_MEM_NUM_PAGES, DEFAULT_HYRACKS_FRAME_SIZE);
+ this.diskPageSize = AccessMethodTestsConfig.LSM_BTREE_DISK_PAGE_SIZE;
+ this.diskNumPages = AccessMethodTestsConfig.LSM_BTREE_DISK_NUM_PAGES;
+ this.diskMaxOpenFiles = AccessMethodTestsConfig.LSM_BTREE_DISK_MAX_OPEN_FILES;
+ this.memPageSize = AccessMethodTestsConfig.LSM_BTREE_MEM_PAGE_SIZE;
+ this.memNumPages = AccessMethodTestsConfig.LSM_BTREE_MEM_NUM_PAGES;
+ this.hyracksFrameSize = AccessMethodTestsConfig.LSM_BTREE_HYRACKS_FRAME_SIZE;
+ this.ioScheduler = SequentialScheduler.INSTANCE;
}
public LSMBTreeTestHarness(int diskPageSize, int diskNumPages, int diskMaxOpenFiles, int memPageSize,
diff --git a/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeBulkLoadTest.java b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeBulkLoadTest.java
index 337fda2..288bccd 100644
--- a/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeBulkLoadTest.java
+++ b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeBulkLoadTest.java
@@ -29,6 +29,7 @@
import edu.uci.ics.hyracks.storage.am.lsm.rtree.util.LSMRTreeTestHarness;
import edu.uci.ics.hyracks.storage.am.rtree.AbstractRTreeBulkLoadTest;
import edu.uci.ics.hyracks.storage.am.rtree.AbstractRTreeTestContext;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
@SuppressWarnings("rawtypes")
public class LSMRTreeBulkLoadTest extends AbstractRTreeBulkLoadTest {
@@ -51,12 +52,12 @@
@Override
protected AbstractRTreeTestContext createTestContext(ISerializerDeserializer[] fieldSerdes,
- IPrimitiveValueProviderFactory[] valueProviderFactories, int numKeys) throws Exception {
+ IPrimitiveValueProviderFactory[] valueProviderFactories, int numKeys, RTreePolicyType rtreePolicyType)
+ throws Exception {
return LSMRTreeTestContext.create(harness.getMemBufferCache(), harness.getMemFreePageManager(),
harness.getIOManager(), harness.getOnDiskDir(), harness.getDiskBufferCache(),
- harness.getDiskFileMapProvider(), fieldSerdes, valueProviderFactories, numKeys, harness.getFileId(),
- NoMergePolicy.INSTANCE);
-
+ harness.getDiskFileMapProvider(), fieldSerdes, valueProviderFactories, numKeys, rtreePolicyType,
+ harness.getFileId(), NoMergePolicy.INSTANCE);
}
@Override
diff --git a/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeDeleteTest.java b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeDeleteTest.java
index c13c401..9c31b48 100644
--- a/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeDeleteTest.java
+++ b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeDeleteTest.java
@@ -29,6 +29,7 @@
import edu.uci.ics.hyracks.storage.am.lsm.rtree.util.LSMRTreeTestHarness;
import edu.uci.ics.hyracks.storage.am.rtree.AbstractRTreeDeleteTest;
import edu.uci.ics.hyracks.storage.am.rtree.AbstractRTreeTestContext;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
@SuppressWarnings("rawtypes")
public class LSMRTreeDeleteTest extends AbstractRTreeDeleteTest {
@@ -47,12 +48,12 @@
@Override
protected AbstractRTreeTestContext createTestContext(ISerializerDeserializer[] fieldSerdes,
- IPrimitiveValueProviderFactory[] valueProviderFactories, int numKeys) throws Exception {
+ IPrimitiveValueProviderFactory[] valueProviderFactories, int numKeys, RTreePolicyType rtreePolicyType)
+ throws Exception {
return LSMRTreeTestContext.create(harness.getMemBufferCache(), harness.getMemFreePageManager(),
harness.getIOManager(), harness.getOnDiskDir(), harness.getDiskBufferCache(),
- harness.getDiskFileMapProvider(), fieldSerdes, valueProviderFactories, numKeys, harness.getFileId(),
- NoMergePolicy.INSTANCE);
-
+ harness.getDiskFileMapProvider(), fieldSerdes, valueProviderFactories, numKeys, rtreePolicyType,
+ harness.getFileId(), NoMergePolicy.INSTANCE);
}
@Override
diff --git a/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeExamplesTest.java b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeExamplesTest.java
index fc80861..888e794 100644
--- a/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeExamplesTest.java
+++ b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeExamplesTest.java
@@ -30,18 +30,20 @@
import edu.uci.ics.hyracks.storage.am.lsm.rtree.util.LSMRTreeTestHarness;
import edu.uci.ics.hyracks.storage.am.lsm.rtree.utils.LSMRTreeUtils;
import edu.uci.ics.hyracks.storage.am.rtree.AbstractRTreeExamplesTest;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
public class LSMRTreeExamplesTest extends AbstractRTreeExamplesTest {
private final LSMRTreeTestHarness harness = new LSMRTreeTestHarness();
@Override
protected ITreeIndex createTreeIndex(ITypeTraits[] typeTraits, IBinaryComparatorFactory[] rtreeCmpFactories,
- IBinaryComparatorFactory[] btreeCmpFactories, IPrimitiveValueProviderFactory[] valueProviderFactories)
- throws TreeIndexException {
+ IBinaryComparatorFactory[] btreeCmpFactories, IPrimitiveValueProviderFactory[] valueProviderFactories,
+ RTreePolicyType rtreePolicyType) throws TreeIndexException {
return LSMRTreeUtils.createLSMTree(harness.getMemBufferCache(), harness.getMemFreePageManager(),
harness.getIOManager(), harness.getOnDiskDir(), harness.getDiskBufferCache(),
harness.getDiskFileMapProvider(), typeTraits, rtreeCmpFactories, btreeCmpFactories,
- valueProviderFactories, new ImmediateFlushPolicy(harness.getIOScheduler()), NoMergePolicy.INSTANCE);
+ valueProviderFactories, rtreePolicyType, new ImmediateFlushPolicy(harness.getIOScheduler()),
+ NoMergePolicy.INSTANCE);
}
@Override
diff --git a/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeInsertTest.java b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeInsertTest.java
index a6dc5a2..639a926 100644
--- a/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeInsertTest.java
+++ b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeInsertTest.java
@@ -29,6 +29,7 @@
import edu.uci.ics.hyracks.storage.am.lsm.rtree.util.LSMRTreeTestHarness;
import edu.uci.ics.hyracks.storage.am.rtree.AbstractRTreeInsertTest;
import edu.uci.ics.hyracks.storage.am.rtree.AbstractRTreeTestContext;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
@SuppressWarnings("rawtypes")
public class LSMRTreeInsertTest extends AbstractRTreeInsertTest {
@@ -47,12 +48,12 @@
@Override
protected AbstractRTreeTestContext createTestContext(ISerializerDeserializer[] fieldSerdes,
- IPrimitiveValueProviderFactory[] valueProviderFactories, int numKeys) throws Exception {
+ IPrimitiveValueProviderFactory[] valueProviderFactories, int numKeys, RTreePolicyType rtreePolicyType)
+ throws Exception {
return LSMRTreeTestContext.create(harness.getMemBufferCache(), harness.getMemFreePageManager(),
harness.getIOManager(), harness.getOnDiskDir(), harness.getDiskBufferCache(),
- harness.getDiskFileMapProvider(), fieldSerdes, valueProviderFactories, numKeys, harness.getFileId(),
- NoMergePolicy.INSTANCE);
-
+ harness.getDiskFileMapProvider(), fieldSerdes, valueProviderFactories, numKeys, rtreePolicyType,
+ harness.getFileId(), NoMergePolicy.INSTANCE);
}
@Override
diff --git a/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeMergeTest.java b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeMergeTest.java
index ed0efe3..8ddf58c 100644
--- a/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeMergeTest.java
+++ b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeMergeTest.java
@@ -28,6 +28,7 @@
import edu.uci.ics.hyracks.storage.am.lsm.rtree.util.LSMRTreeTestContext;
import edu.uci.ics.hyracks.storage.am.lsm.rtree.util.LSMRTreeTestHarness;
import edu.uci.ics.hyracks.storage.am.rtree.AbstractRTreeTestContext;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
@SuppressWarnings("rawtypes")
public class LSMRTreeMergeTest extends LSMRTreeMergeTestDriver {
@@ -46,11 +47,12 @@
@Override
protected AbstractRTreeTestContext createTestContext(ISerializerDeserializer[] fieldSerdes,
- IPrimitiveValueProviderFactory[] valueProviderFactories, int numKeys) throws Exception {
+ IPrimitiveValueProviderFactory[] valueProviderFactories, int numKeys, RTreePolicyType rtreePolicyType)
+ throws Exception {
return LSMRTreeTestContext.create(harness.getMemBufferCache(), harness.getMemFreePageManager(),
harness.getIOManager(), harness.getOnDiskDir(), harness.getDiskBufferCache(),
- harness.getDiskFileMapProvider(), fieldSerdes, valueProviderFactories, numKeys, harness.getFileId(),
- NoMergePolicy.INSTANCE);
+ harness.getDiskFileMapProvider(), fieldSerdes, valueProviderFactories, numKeys, rtreePolicyType,
+ harness.getFileId(), NoMergePolicy.INSTANCE);
}
@Override
diff --git a/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeMergeTestDriver.java b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeMergeTestDriver.java
index 86204fb..15eb08f 100644
--- a/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeMergeTestDriver.java
+++ b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeMergeTestDriver.java
@@ -20,10 +20,12 @@
import edu.uci.ics.hyracks.dataflow.common.data.marshalling.DoubleSerializerDeserializer;
import edu.uci.ics.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;
import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
+import edu.uci.ics.hyracks.storage.am.config.AccessMethodTestsConfig;
import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMIndexAccessor;
import edu.uci.ics.hyracks.storage.am.rtree.AbstractRTreeTestContext;
import edu.uci.ics.hyracks.storage.am.rtree.AbstractRTreeTestDriver;
import edu.uci.ics.hyracks.storage.am.rtree.RTreeTestUtils;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
@SuppressWarnings("rawtypes")
public abstract class LSMRTreeMergeTestDriver extends AbstractRTreeTestDriver {
@@ -36,9 +38,10 @@
@Override
protected void runTest(ISerializerDeserializer[] fieldSerdes,
- IPrimitiveValueProviderFactory[] valueProviderFactories, int numKeys, ITupleReference key) throws Exception {
+ IPrimitiveValueProviderFactory[] valueProviderFactories, int numKeys, ITupleReference key,
+ RTreePolicyType rtreePolicyType) throws Exception {
- AbstractRTreeTestContext ctx = createTestContext(fieldSerdes, valueProviderFactories, numKeys);
+ AbstractRTreeTestContext ctx = createTestContext(fieldSerdes, valueProviderFactories, numKeys, rtreePolicyType);
// Start off with one tree bulk loaded.
// We assume all fieldSerdes are of the same type. Check the first one
@@ -49,13 +52,13 @@
rTreeTestUtils.bulkLoadDoubleTuples(ctx, numTuplesToInsert, getRandom());
}
- int maxTreesToMerge = 3;
+ int maxTreesToMerge = AccessMethodTestsConfig.LSM_RTREE_BULKLOAD_ROUNDS;
for (int i = 0; i < maxTreesToMerge; i++) {
- for (int j = 0; j < i; j++) {
- if (fieldSerdes[0] instanceof IntegerSerializerDeserializer) {
- rTreeTestUtils.bulkLoadIntTuples(ctx, numTuplesToInsert, getRandom());
+ for (int j = 0; j < i; j++) {
+ if (fieldSerdes[0] instanceof IntegerSerializerDeserializer) {
+ rTreeTestUtils.bulkLoadIntTuples(ctx, numTuplesToInsert, getRandom());
} else if (fieldSerdes[0] instanceof DoubleSerializerDeserializer) {
- rTreeTestUtils.bulkLoadDoubleTuples(ctx, numTuplesToInsert, getRandom());
+ rTreeTestUtils.bulkLoadDoubleTuples(ctx, numTuplesToInsert, getRandom());
}
}
diff --git a/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeMultiBulkLoadTest.java b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeMultiBulkLoadTest.java
index 0471136..e3dce3d 100644
--- a/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeMultiBulkLoadTest.java
+++ b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeMultiBulkLoadTest.java
@@ -24,17 +24,18 @@
import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
import edu.uci.ics.hyracks.api.exceptions.HyracksException;
import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
+import edu.uci.ics.hyracks.storage.am.config.AccessMethodTestsConfig;
import edu.uci.ics.hyracks.storage.am.lsm.common.impls.NoMergePolicy;
import edu.uci.ics.hyracks.storage.am.lsm.rtree.util.LSMRTreeTestContext;
import edu.uci.ics.hyracks.storage.am.lsm.rtree.util.LSMRTreeTestHarness;
import edu.uci.ics.hyracks.storage.am.rtree.AbstractRTreeBulkLoadTest;
import edu.uci.ics.hyracks.storage.am.rtree.AbstractRTreeTestContext;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
@SuppressWarnings("rawtypes")
public class LSMRTreeMultiBulkLoadTest extends AbstractRTreeBulkLoadTest {
public LSMRTreeMultiBulkLoadTest() {
- // Using 5 bulk load rounds.
- super(5);
+ super(AccessMethodTestsConfig.LSM_RTREE_BULKLOAD_ROUNDS);
}
private final LSMRTreeTestHarness harness = new LSMRTreeTestHarness();
@@ -51,12 +52,12 @@
@Override
protected AbstractRTreeTestContext createTestContext(ISerializerDeserializer[] fieldSerdes,
- IPrimitiveValueProviderFactory[] valueProviderFactories, int numKeys) throws Exception {
+ IPrimitiveValueProviderFactory[] valueProviderFactories, int numKeys, RTreePolicyType rtreePolicyType)
+ throws Exception {
return LSMRTreeTestContext.create(harness.getMemBufferCache(), harness.getMemFreePageManager(),
harness.getIOManager(), harness.getOnDiskDir(), harness.getDiskBufferCache(),
- harness.getDiskFileMapProvider(), fieldSerdes, valueProviderFactories, numKeys, harness.getFileId(),
- NoMergePolicy.INSTANCE);
-
+ harness.getDiskFileMapProvider(), fieldSerdes, valueProviderFactories, numKeys, rtreePolicyType,
+ harness.getFileId(), NoMergePolicy.INSTANCE);
}
@Override
diff --git a/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeWithAntiMatterTuplesBulkLoadTest.java b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeWithAntiMatterTuplesBulkLoadTest.java
new file mode 100644
index 0000000..2f23ccf
--- /dev/null
+++ b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeWithAntiMatterTuplesBulkLoadTest.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package edu.uci.ics.hyracks.storage.am.lsm.rtree;
+
+import java.util.Random;
+
+import org.junit.After;
+import org.junit.Before;
+
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.api.exceptions.HyracksException;
+import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
+import edu.uci.ics.hyracks.storage.am.lsm.common.impls.NoMergePolicy;
+import edu.uci.ics.hyracks.storage.am.lsm.rtree.util.LSMRTreeTestHarness;
+import edu.uci.ics.hyracks.storage.am.lsm.rtree.util.LSMRTreeWithAntiMatterTuplesTestContext;
+import edu.uci.ics.hyracks.storage.am.rtree.AbstractRTreeBulkLoadTest;
+import edu.uci.ics.hyracks.storage.am.rtree.AbstractRTreeTestContext;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
+
+@SuppressWarnings("rawtypes")
+public class LSMRTreeWithAntiMatterTuplesBulkLoadTest extends AbstractRTreeBulkLoadTest {
+
+ public LSMRTreeWithAntiMatterTuplesBulkLoadTest() {
+ super(1);
+ }
+
+ private final LSMRTreeTestHarness harness = new LSMRTreeTestHarness();
+
+ @Before
+ public void setUp() throws HyracksException {
+ harness.setUp();
+ }
+
+ @After
+ public void tearDown() throws HyracksDataException {
+ harness.tearDown();
+ }
+
+ @Override
+ protected AbstractRTreeTestContext createTestContext(ISerializerDeserializer[] fieldSerdes,
+ IPrimitiveValueProviderFactory[] valueProviderFactories, int numKeys, RTreePolicyType rtreePolicyType)
+ throws Exception {
+ return LSMRTreeWithAntiMatterTuplesTestContext.create(harness.getMemBufferCache(),
+ harness.getMemFreePageManager(), harness.getIOManager(), harness.getOnDiskDir(),
+ harness.getDiskBufferCache(), harness.getDiskFileMapProvider(), fieldSerdes, valueProviderFactories,
+ numKeys, rtreePolicyType, harness.getFileId(), NoMergePolicy.INSTANCE);
+
+ }
+
+ @Override
+ protected Random getRandom() {
+ return harness.getRandom();
+ }
+}
diff --git a/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeWithAntiMatterTuplesDeleteTest.java b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeWithAntiMatterTuplesDeleteTest.java
new file mode 100644
index 0000000..b830317
--- /dev/null
+++ b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeWithAntiMatterTuplesDeleteTest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package edu.uci.ics.hyracks.storage.am.lsm.rtree;
+
+import java.util.Random;
+
+import org.junit.After;
+import org.junit.Before;
+
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.api.exceptions.HyracksException;
+import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
+import edu.uci.ics.hyracks.storage.am.lsm.common.impls.NoMergePolicy;
+import edu.uci.ics.hyracks.storage.am.lsm.rtree.util.LSMRTreeTestHarness;
+import edu.uci.ics.hyracks.storage.am.lsm.rtree.util.LSMRTreeWithAntiMatterTuplesTestContext;
+import edu.uci.ics.hyracks.storage.am.rtree.AbstractRTreeDeleteTest;
+import edu.uci.ics.hyracks.storage.am.rtree.AbstractRTreeTestContext;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
+
+@SuppressWarnings("rawtypes")
+public class LSMRTreeWithAntiMatterTuplesDeleteTest extends AbstractRTreeDeleteTest {
+
+ private final LSMRTreeTestHarness harness = new LSMRTreeTestHarness();
+
+ @Before
+ public void setUp() throws HyracksException {
+ harness.setUp();
+ }
+
+ @After
+ public void tearDown() throws HyracksDataException {
+ harness.tearDown();
+ }
+
+ @Override
+ protected AbstractRTreeTestContext createTestContext(ISerializerDeserializer[] fieldSerdes,
+ IPrimitiveValueProviderFactory[] valueProviderFactories, int numKeys, RTreePolicyType rtreePolicyType)
+ throws Exception {
+ return LSMRTreeWithAntiMatterTuplesTestContext.create(harness.getMemBufferCache(),
+ harness.getMemFreePageManager(), harness.getIOManager(), harness.getOnDiskDir(),
+ harness.getDiskBufferCache(), harness.getDiskFileMapProvider(), fieldSerdes, valueProviderFactories,
+ numKeys, rtreePolicyType, harness.getFileId(), NoMergePolicy.INSTANCE);
+
+ }
+
+ @Override
+ protected Random getRandom() {
+ return harness.getRandom();
+ }
+}
diff --git a/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeWithAntiMatterTuplesExamplesTest.java b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeWithAntiMatterTuplesExamplesTest.java
new file mode 100644
index 0000000..a972228
--- /dev/null
+++ b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeWithAntiMatterTuplesExamplesTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package edu.uci.ics.hyracks.storage.am.lsm.rtree;
+
+import org.junit.After;
+import org.junit.Before;
+
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparatorFactory;
+import edu.uci.ics.hyracks.api.dataflow.value.ITypeTraits;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.api.exceptions.HyracksException;
+import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
+import edu.uci.ics.hyracks.storage.am.common.api.TreeIndexException;
+import edu.uci.ics.hyracks.storage.am.lsm.common.impls.ImmediateFlushPolicy;
+import edu.uci.ics.hyracks.storage.am.lsm.common.impls.NoMergePolicy;
+import edu.uci.ics.hyracks.storage.am.lsm.rtree.util.LSMRTreeTestHarness;
+import edu.uci.ics.hyracks.storage.am.lsm.rtree.utils.LSMRTreeUtils;
+import edu.uci.ics.hyracks.storage.am.rtree.AbstractRTreeExamplesTest;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
+
+public class LSMRTreeWithAntiMatterTuplesExamplesTest extends AbstractRTreeExamplesTest {
+ private final LSMRTreeTestHarness harness = new LSMRTreeTestHarness();
+
+ @Override
+ protected ITreeIndex createTreeIndex(ITypeTraits[] typeTraits, IBinaryComparatorFactory[] rtreeCmpFactories,
+ IBinaryComparatorFactory[] btreeCmpFactories, IPrimitiveValueProviderFactory[] valueProviderFactories,
+ RTreePolicyType rtreePolicyType) throws TreeIndexException {
+ return LSMRTreeUtils.createLSMTreeWithAntiMatterTuples(harness.getMemBufferCache(),
+ harness.getMemFreePageManager(), harness.getIOManager(), harness.getOnDiskDir(),
+ harness.getDiskBufferCache(), harness.getDiskFileMapProvider(), typeTraits, rtreeCmpFactories,
+ btreeCmpFactories, valueProviderFactories, rtreePolicyType,
+ new ImmediateFlushPolicy(harness.getIOScheduler()), NoMergePolicy.INSTANCE);
+ }
+
+ @Override
+ protected int getIndexFileId() {
+ return harness.getFileId();
+ }
+
+ @Before
+ public void setUp() throws HyracksException {
+ harness.setUp();
+ }
+
+ @After
+ public void tearDown() throws HyracksDataException {
+ harness.tearDown();
+ }
+}
diff --git a/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeWithAntiMatterTuplesInsertTest.java b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeWithAntiMatterTuplesInsertTest.java
new file mode 100644
index 0000000..8468ed3
--- /dev/null
+++ b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeWithAntiMatterTuplesInsertTest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package edu.uci.ics.hyracks.storage.am.lsm.rtree;
+
+import java.util.Random;
+
+import org.junit.After;
+import org.junit.Before;
+
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.api.exceptions.HyracksException;
+import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
+import edu.uci.ics.hyracks.storage.am.lsm.common.impls.NoMergePolicy;
+import edu.uci.ics.hyracks.storage.am.lsm.rtree.util.LSMRTreeTestHarness;
+import edu.uci.ics.hyracks.storage.am.lsm.rtree.util.LSMRTreeWithAntiMatterTuplesTestContext;
+import edu.uci.ics.hyracks.storage.am.rtree.AbstractRTreeInsertTest;
+import edu.uci.ics.hyracks.storage.am.rtree.AbstractRTreeTestContext;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
+
+@SuppressWarnings("rawtypes")
+public class LSMRTreeWithAntiMatterTuplesInsertTest extends AbstractRTreeInsertTest {
+
+ private final LSMRTreeTestHarness harness = new LSMRTreeTestHarness();
+
+ @Before
+ public void setUp() throws HyracksException {
+ harness.setUp();
+ }
+
+ @After
+ public void tearDown() throws HyracksDataException {
+ harness.tearDown();
+ }
+
+ @Override
+ protected AbstractRTreeTestContext createTestContext(ISerializerDeserializer[] fieldSerdes,
+ IPrimitiveValueProviderFactory[] valueProviderFactories, int numKeys, RTreePolicyType rtreePolicyType)
+ throws Exception {
+ return LSMRTreeWithAntiMatterTuplesTestContext.create(harness.getMemBufferCache(),
+ harness.getMemFreePageManager(), harness.getIOManager(), harness.getOnDiskDir(),
+ harness.getDiskBufferCache(), harness.getDiskFileMapProvider(), fieldSerdes, valueProviderFactories,
+ numKeys, rtreePolicyType, harness.getFileId(), NoMergePolicy.INSTANCE);
+
+ }
+
+ @Override
+ protected Random getRandom() {
+ return harness.getRandom();
+ }
+}
diff --git a/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeWithAntiMatterTuplesMergeTest.java b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeWithAntiMatterTuplesMergeTest.java
new file mode 100644
index 0000000..4d1ffd4
--- /dev/null
+++ b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeWithAntiMatterTuplesMergeTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package edu.uci.ics.hyracks.storage.am.lsm.rtree;
+
+import java.util.Random;
+
+import org.junit.After;
+import org.junit.Before;
+
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.api.exceptions.HyracksException;
+import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
+import edu.uci.ics.hyracks.storage.am.lsm.common.impls.NoMergePolicy;
+import edu.uci.ics.hyracks.storage.am.lsm.rtree.util.LSMRTreeTestHarness;
+import edu.uci.ics.hyracks.storage.am.lsm.rtree.util.LSMRTreeWithAntiMatterTuplesTestContext;
+import edu.uci.ics.hyracks.storage.am.rtree.AbstractRTreeTestContext;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
+
+@SuppressWarnings("rawtypes")
+public class LSMRTreeWithAntiMatterTuplesMergeTest extends LSMRTreeMergeTestDriver {
+
+ private final LSMRTreeTestHarness harness = new LSMRTreeTestHarness();
+
+ @Before
+ public void setUp() throws HyracksException {
+ harness.setUp();
+ }
+
+ @After
+ public void tearDown() throws HyracksDataException {
+ harness.tearDown();
+ }
+
+ @Override
+ protected AbstractRTreeTestContext createTestContext(ISerializerDeserializer[] fieldSerdes,
+ IPrimitiveValueProviderFactory[] valueProviderFactories, int numKeys, RTreePolicyType rtreePolicyType)
+ throws Exception {
+ return LSMRTreeWithAntiMatterTuplesTestContext.create(harness.getMemBufferCache(),
+ harness.getMemFreePageManager(), harness.getIOManager(), harness.getOnDiskDir(),
+ harness.getDiskBufferCache(), harness.getDiskFileMapProvider(), fieldSerdes, valueProviderFactories,
+ numKeys, rtreePolicyType, harness.getFileId(), NoMergePolicy.INSTANCE);
+ }
+
+ @Override
+ protected Random getRandom() {
+ return harness.getRandom();
+ }
+}
diff --git a/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeWithAntiMatterTuplesMultiBulkLoadTest.java b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeWithAntiMatterTuplesMultiBulkLoadTest.java
new file mode 100644
index 0000000..cfb4bc7
--- /dev/null
+++ b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeWithAntiMatterTuplesMultiBulkLoadTest.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package edu.uci.ics.hyracks.storage.am.lsm.rtree;
+
+import java.util.Random;
+
+import org.junit.After;
+import org.junit.Before;
+
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.api.exceptions.HyracksException;
+import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
+import edu.uci.ics.hyracks.storage.am.config.AccessMethodTestsConfig;
+import edu.uci.ics.hyracks.storage.am.lsm.common.impls.NoMergePolicy;
+import edu.uci.ics.hyracks.storage.am.lsm.rtree.util.LSMRTreeTestHarness;
+import edu.uci.ics.hyracks.storage.am.lsm.rtree.util.LSMRTreeWithAntiMatterTuplesTestContext;
+import edu.uci.ics.hyracks.storage.am.rtree.AbstractRTreeBulkLoadTest;
+import edu.uci.ics.hyracks.storage.am.rtree.AbstractRTreeTestContext;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
+
+@SuppressWarnings("rawtypes")
+public class LSMRTreeWithAntiMatterTuplesMultiBulkLoadTest extends AbstractRTreeBulkLoadTest {
+ public LSMRTreeWithAntiMatterTuplesMultiBulkLoadTest() {
+ super(AccessMethodTestsConfig.LSM_RTREE_BULKLOAD_ROUNDS);
+ }
+
+ private final LSMRTreeTestHarness harness = new LSMRTreeTestHarness();
+
+ @Before
+ public void setUp() throws HyracksException {
+ harness.setUp();
+ }
+
+ @After
+ public void tearDown() throws HyracksDataException {
+ harness.tearDown();
+ }
+
+ @Override
+ protected AbstractRTreeTestContext createTestContext(ISerializerDeserializer[] fieldSerdes,
+ IPrimitiveValueProviderFactory[] valueProviderFactories, int numKeys, RTreePolicyType rtreePolicyType)
+ throws Exception {
+ return LSMRTreeWithAntiMatterTuplesTestContext.create(harness.getMemBufferCache(),
+ harness.getMemFreePageManager(), harness.getIOManager(), harness.getOnDiskDir(),
+ harness.getDiskBufferCache(), harness.getDiskFileMapProvider(), fieldSerdes, valueProviderFactories,
+ numKeys, rtreePolicyType, harness.getFileId(), NoMergePolicy.INSTANCE);
+
+ }
+
+ @Override
+ protected Random getRandom() {
+ return harness.getRandom();
+ }
+}
diff --git a/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/multithread/AbstractLSMRTreeTestWorker.java b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/multithread/AbstractLSMRTreeTestWorker.java
new file mode 100644
index 0000000..a89dca1
--- /dev/null
+++ b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/multithread/AbstractLSMRTreeTestWorker.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package edu.uci.ics.hyracks.storage.am.lsm.rtree.multithread;
+
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.comm.io.ArrayTupleBuilder;
+import edu.uci.ics.hyracks.dataflow.common.comm.io.ArrayTupleReference;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
+import edu.uci.ics.hyracks.storage.am.common.AbstractTreeIndexTestWorker;
+import edu.uci.ics.hyracks.storage.am.common.TestOperationSelector;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexCursor;
+import edu.uci.ics.hyracks.storage.am.common.datagen.DataGenThread;
+import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
+
+public abstract class AbstractLSMRTreeTestWorker extends AbstractTreeIndexTestWorker {
+
+ protected final ITreeIndex lsmRTree;
+ protected final int numFields;
+ protected final ArrayTupleBuilder rearrangedTb;
+ protected final ArrayTupleReference rearrangedTuple = new ArrayTupleReference();
+
+ public AbstractLSMRTreeTestWorker(DataGenThread dataGen, TestOperationSelector opSelector, ITreeIndex index,
+ int numBatches) {
+ super(dataGen, opSelector, index, numBatches);
+ lsmRTree = index;
+ numFields = lsmRTree.getFieldCount();
+ rearrangedTb = new ArrayTupleBuilder(numFields);
+ }
+
+ protected void rearrangeTuple(ITupleReference tuple, MultiComparator cmp) throws HyracksDataException {
+ // Create a tuple with rearranged key values to make sure lower points
+ // have larger coordinates than high points.
+ rearrangedTb.reset();
+ int maxFieldPos = cmp.getKeyFieldCount() / 2;
+ for (int i = 0; i < maxFieldPos; i++) {
+ int j = maxFieldPos + i;
+ int c = cmp.getComparators()[i].compare(tuple.getFieldData(i), tuple.getFieldStart(i),
+ tuple.getFieldLength(i), tuple.getFieldData(j), tuple.getFieldStart(j), tuple.getFieldLength(j));
+ if (c > 0) {
+ rearrangedTb.addField(tuple.getFieldData(j), tuple.getFieldStart(j), tuple.getFieldLength(j));
+ } else {
+ rearrangedTb.addField(tuple.getFieldData(i), tuple.getFieldStart(i), tuple.getFieldLength(i));
+ }
+ }
+ for (int i = 0; i < maxFieldPos; i++) {
+ int j = maxFieldPos + i;
+ int c = cmp.getComparators()[i].compare(tuple.getFieldData(i), tuple.getFieldStart(i),
+ tuple.getFieldLength(i), tuple.getFieldData(j), tuple.getFieldStart(j), tuple.getFieldLength(j));
+ if (c > 0) {
+ rearrangedTb.addField(tuple.getFieldData(i), tuple.getFieldStart(i), tuple.getFieldLength(i));
+ } else {
+ rearrangedTb.addField(tuple.getFieldData(j), tuple.getFieldStart(j), tuple.getFieldLength(j));
+ }
+ }
+ for (int i = cmp.getKeyFieldCount(); i < numFields; i++) {
+ rearrangedTb.addField(tuple.getFieldData(i), tuple.getFieldStart(i), tuple.getFieldLength(i));
+ }
+ rearrangedTuple.reset(rearrangedTb.getFieldEndOffsets(), rearrangedTb.getByteArray());
+ }
+
+ protected void consumeCursorTuples(ITreeIndexCursor cursor) throws HyracksDataException {
+ try {
+ while (cursor.hasNext()) {
+ cursor.next();
+ }
+ } finally {
+ cursor.close();
+ }
+ }
+}
diff --git a/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/multithread/LSMRTreeMultiThreadTest.java b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/multithread/LSMRTreeMultiThreadTest.java
index b689cf5..710076a 100644
--- a/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/multithread/LSMRTreeMultiThreadTest.java
+++ b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/multithread/LSMRTreeMultiThreadTest.java
@@ -32,6 +32,7 @@
import edu.uci.ics.hyracks.storage.am.lsm.rtree.util.LSMRTreeTestHarness;
import edu.uci.ics.hyracks.storage.am.lsm.rtree.utils.LSMRTreeUtils;
import edu.uci.ics.hyracks.storage.am.rtree.AbstractRTreeMultiThreadTest;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
public class LSMRTreeMultiThreadTest extends AbstractRTreeMultiThreadTest {
@@ -51,13 +52,13 @@
@Override
protected ITreeIndex createTreeIndex(ITypeTraits[] typeTraits, IBinaryComparatorFactory[] rtreeCmpFactories,
- IBinaryComparatorFactory[] btreeCmpFactories, IPrimitiveValueProviderFactory[] valueProviderFactories)
- throws TreeIndexException {
+ IBinaryComparatorFactory[] btreeCmpFactories, IPrimitiveValueProviderFactory[] valueProviderFactories,
+ RTreePolicyType rtreePolicyType) throws TreeIndexException {
return LSMRTreeUtils.createLSMTree(harness.getMemBufferCache(), harness.getMemFreePageManager(),
harness.getIOManager(), harness.getOnDiskDir(), harness.getDiskBufferCache(),
harness.getDiskFileMapProvider(), typeTraits, rtreeCmpFactories, btreeCmpFactories,
- valueProviderFactories, new ImmediateFlushPolicy(harness.getIOScheduler()), NoMergePolicy.INSTANCE);
-
+ valueProviderFactories, rtreePolicyType, new ImmediateFlushPolicy(harness.getIOScheduler()),
+ NoMergePolicy.INSTANCE);
}
@Override
diff --git a/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/multithread/LSMRTreeWithAntiMatterTuplesMultiThreadTest.java b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/multithread/LSMRTreeWithAntiMatterTuplesMultiThreadTest.java
new file mode 100644
index 0000000..f0211d8
--- /dev/null
+++ b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/multithread/LSMRTreeWithAntiMatterTuplesMultiThreadTest.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package edu.uci.ics.hyracks.storage.am.lsm.rtree.multithread;
+
+import java.util.ArrayList;
+
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparatorFactory;
+import edu.uci.ics.hyracks.api.dataflow.value.ITypeTraits;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.api.exceptions.HyracksException;
+import edu.uci.ics.hyracks.storage.am.common.ITreeIndexTestWorkerFactory;
+import edu.uci.ics.hyracks.storage.am.common.TestOperationSelector.TestOperation;
+import edu.uci.ics.hyracks.storage.am.common.TestWorkloadConf;
+import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
+import edu.uci.ics.hyracks.storage.am.common.api.TreeIndexException;
+import edu.uci.ics.hyracks.storage.am.lsm.common.impls.ImmediateFlushPolicy;
+import edu.uci.ics.hyracks.storage.am.lsm.common.impls.NoMergePolicy;
+import edu.uci.ics.hyracks.storage.am.lsm.rtree.util.LSMRTreeTestHarness;
+import edu.uci.ics.hyracks.storage.am.lsm.rtree.utils.LSMRTreeUtils;
+import edu.uci.ics.hyracks.storage.am.rtree.AbstractRTreeMultiThreadTest;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
+
+public class LSMRTreeWithAntiMatterTuplesMultiThreadTest extends AbstractRTreeMultiThreadTest {
+
+ private LSMRTreeTestHarness harness = new LSMRTreeTestHarness();
+
+ private LSMRTreeWithAntiMatterTuplesTestWorkerFactory workerFactory = new LSMRTreeWithAntiMatterTuplesTestWorkerFactory();
+
+ @Override
+ protected void setUp() throws HyracksException {
+ harness.setUp();
+ }
+
+ @Override
+ protected void tearDown() throws HyracksDataException {
+ harness.tearDown();
+ }
+
+ @Override
+ protected ITreeIndex createTreeIndex(ITypeTraits[] typeTraits, IBinaryComparatorFactory[] rtreeCmpFactories,
+ IBinaryComparatorFactory[] btreeCmpFactories, IPrimitiveValueProviderFactory[] valueProviderFactories,
+ RTreePolicyType rtreePolicyType) throws TreeIndexException {
+ return LSMRTreeUtils.createLSMTreeWithAntiMatterTuples(harness.getMemBufferCache(),
+ harness.getMemFreePageManager(), harness.getIOManager(), harness.getOnDiskDir(),
+ harness.getDiskBufferCache(), harness.getDiskFileMapProvider(), typeTraits, rtreeCmpFactories,
+ btreeCmpFactories, valueProviderFactories, rtreePolicyType, new ImmediateFlushPolicy(harness.getIOScheduler()),
+ NoMergePolicy.INSTANCE);
+
+ }
+
+ @Override
+ protected ITreeIndexTestWorkerFactory getWorkerFactory() {
+ return workerFactory;
+ }
+
+ @Override
+ protected ArrayList<TestWorkloadConf> getTestWorkloadConf() {
+ ArrayList<TestWorkloadConf> workloadConfs = new ArrayList<TestWorkloadConf>();
+
+ // Insert only workload.
+ TestOperation[] insertOnlyOps = new TestOperation[] { TestOperation.INSERT };
+ workloadConfs.add(new TestWorkloadConf(insertOnlyOps, getUniformOpProbs(insertOnlyOps)));
+
+ // Insert and merge workload.
+ TestOperation[] insertMergeOps = new TestOperation[] { TestOperation.INSERT, TestOperation.MERGE };
+ workloadConfs.add(new TestWorkloadConf(insertMergeOps, getUniformOpProbs(insertMergeOps)));
+
+ // Inserts mixed with scans.
+ TestOperation[] insertSearchOnlyOps = new TestOperation[] { TestOperation.INSERT, TestOperation.SCAN };
+ workloadConfs.add(new TestWorkloadConf(insertSearchOnlyOps, getUniformOpProbs(insertSearchOnlyOps)));
+
+ // Inserts and deletes.
+ TestOperation[] insertDeleteOps = new TestOperation[] { TestOperation.INSERT, TestOperation.DELETE };
+ workloadConfs.add(new TestWorkloadConf(insertDeleteOps, getUniformOpProbs(insertDeleteOps)));
+
+ // Inserts, deletes and merges.
+ TestOperation[] insertDeleteMergeOps = new TestOperation[] { TestOperation.INSERT, TestOperation.DELETE,
+ TestOperation.MERGE };
+ workloadConfs.add(new TestWorkloadConf(insertDeleteMergeOps, getUniformOpProbs(insertDeleteMergeOps)));
+
+ // All operations except merge.
+ TestOperation[] allNoMergeOps = new TestOperation[] { TestOperation.INSERT, TestOperation.DELETE,
+ TestOperation.SCAN };
+ workloadConfs.add(new TestWorkloadConf(allNoMergeOps, getUniformOpProbs(allNoMergeOps)));
+
+ // All operations.
+ TestOperation[] allOps = new TestOperation[] { TestOperation.INSERT, TestOperation.DELETE, TestOperation.SCAN,
+ TestOperation.MERGE };
+ workloadConfs.add(new TestWorkloadConf(allOps, getUniformOpProbs(allOps)));
+
+ return workloadConfs;
+ }
+
+ @Override
+ protected int getFileId() {
+ return harness.getFileId();
+ }
+
+ @Override
+ protected String getIndexTypeName() {
+ return "LSMRTree";
+ }
+
+}
diff --git a/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/multithread/LSMRTreeWithAntiMatterTuplesTestWorker.java b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/multithread/LSMRTreeWithAntiMatterTuplesTestWorker.java
new file mode 100644
index 0000000..8c5613a
--- /dev/null
+++ b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/multithread/LSMRTreeWithAntiMatterTuplesTestWorker.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package edu.uci.ics.hyracks.storage.am.lsm.rtree.multithread;
+
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
+import edu.uci.ics.hyracks.storage.am.common.TestOperationSelector;
+import edu.uci.ics.hyracks.storage.am.common.TestOperationSelector.TestOperation;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexCursor;
+import edu.uci.ics.hyracks.storage.am.common.api.IndexException;
+import edu.uci.ics.hyracks.storage.am.common.datagen.DataGenThread;
+import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
+import edu.uci.ics.hyracks.storage.am.lsm.common.impls.LSMMergeInProgressException;
+import edu.uci.ics.hyracks.storage.am.lsm.rtree.impls.LSMRTreeWithAntiMatterTuples.LSMRTreeWithAntiMatterTuplesAccessor;
+import edu.uci.ics.hyracks.storage.am.rtree.impls.SearchPredicate;
+
+public class LSMRTreeWithAntiMatterTuplesTestWorker extends AbstractLSMRTreeTestWorker {
+
+ public LSMRTreeWithAntiMatterTuplesTestWorker(DataGenThread dataGen, TestOperationSelector opSelector,
+ ITreeIndex index, int numBatches) {
+ super(dataGen, opSelector, index, numBatches);
+ }
+
+ @Override
+ public void performOp(ITupleReference tuple, TestOperation op) throws HyracksDataException, IndexException {
+ LSMRTreeWithAntiMatterTuplesAccessor accessor = (LSMRTreeWithAntiMatterTuplesAccessor) indexAccessor;
+ ITreeIndexCursor searchCursor = accessor.createSearchCursor();
+ MultiComparator cmp = accessor.getMultiComparator();
+ SearchPredicate rangePred = new SearchPredicate(tuple, cmp);
+
+ switch (op) {
+ case INSERT:
+ rearrangeTuple(tuple, cmp);
+ accessor.insert(rearrangedTuple);
+ break;
+
+ case DELETE:
+ rearrangeTuple(tuple, cmp);
+ accessor.delete(rearrangedTuple);
+ break;
+
+ case SCAN:
+ searchCursor.reset();
+ rangePred.setSearchKey(null);
+ accessor.search(searchCursor, rangePred);
+ consumeCursorTuples(searchCursor);
+ break;
+
+ case MERGE:
+ try {
+ accessor.merge();
+ } catch (LSMMergeInProgressException e) {
+ // Ignore ongoing merges. Do an insert instead.
+ rearrangeTuple(tuple, cmp);
+ accessor.insert(rearrangedTuple);
+ }
+ break;
+
+ default:
+ throw new HyracksDataException("Op " + op.toString() + " not supported.");
+ }
+ }
+}
diff --git a/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/multithread/LSMRTreeWithAntiMatterTuplesTestWorkerFactory.java b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/multithread/LSMRTreeWithAntiMatterTuplesTestWorkerFactory.java
new file mode 100644
index 0000000..4613234
--- /dev/null
+++ b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/multithread/LSMRTreeWithAntiMatterTuplesTestWorkerFactory.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package edu.uci.ics.hyracks.storage.am.lsm.rtree.multithread;
+
+import edu.uci.ics.hyracks.storage.am.common.AbstractTreeIndexTestWorker;
+import edu.uci.ics.hyracks.storage.am.common.ITreeIndexTestWorkerFactory;
+import edu.uci.ics.hyracks.storage.am.common.TestOperationSelector;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
+import edu.uci.ics.hyracks.storage.am.common.datagen.DataGenThread;
+
+public class LSMRTreeWithAntiMatterTuplesTestWorkerFactory implements ITreeIndexTestWorkerFactory {
+ @Override
+ public AbstractTreeIndexTestWorker create(DataGenThread dataGen, TestOperationSelector opSelector,
+ ITreeIndex index, int numBatches) {
+ return new LSMRTreeWithAntiMatterTuplesTestWorker(dataGen, opSelector, index, numBatches);
+ }
+}
diff --git a/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/util/LSMRTreeTestContext.java b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/util/LSMRTreeTestContext.java
index bf40384..fbedc6a 100644
--- a/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/util/LSMRTreeTestContext.java
+++ b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/util/LSMRTreeTestContext.java
@@ -33,6 +33,7 @@
import edu.uci.ics.hyracks.storage.am.lsm.rtree.utils.LSMRTreeUtils;
import edu.uci.ics.hyracks.storage.am.rtree.AbstractRTreeTestContext;
import edu.uci.ics.hyracks.storage.am.rtree.RTreeCheckTuple;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
import edu.uci.ics.hyracks.storage.common.buffercache.IBufferCache;
import edu.uci.ics.hyracks.storage.common.file.IFileMapProvider;
@@ -67,8 +68,8 @@
public static LSMRTreeTestContext create(InMemoryBufferCache memBufferCache,
InMemoryFreePageManager memFreePageManager, IOManager ioManager, String onDiskDir,
IBufferCache diskBufferCache, IFileMapProvider diskFileMapProvider, ISerializerDeserializer[] fieldSerdes,
- IPrimitiveValueProviderFactory[] valueProviderFactories, int numKeyFields, int fileId,
- ILSMMergePolicy mergePolicy) throws Exception {
+ IPrimitiveValueProviderFactory[] valueProviderFactories, int numKeyFields, RTreePolicyType rtreePolicyType,
+ int fileId, ILSMMergePolicy mergePolicy) throws Exception {
ITypeTraits[] typeTraits = SerdeUtils.serdesToTypeTraits(fieldSerdes);
IBinaryComparatorFactory[] rtreeCmpFactories = SerdeUtils
.serdesToComparatorFactories(fieldSerdes, numKeyFields);
@@ -76,7 +77,8 @@
fieldSerdes.length);
LSMRTree lsmTree = LSMRTreeUtils.createLSMTree(memBufferCache, memFreePageManager, ioManager, onDiskDir,
diskBufferCache, diskFileMapProvider, typeTraits, rtreeCmpFactories, btreeCmpFactories,
- valueProviderFactories, new ImmediateFlushPolicy(SequentialScheduler.INSTANCE), mergePolicy);
+ valueProviderFactories, rtreePolicyType, new ImmediateFlushPolicy(SequentialScheduler.INSTANCE),
+ mergePolicy);
lsmTree.create(fileId);
lsmTree.open(fileId);
LSMRTreeTestContext testCtx = new LSMRTreeTestContext(fieldSerdes, lsmTree);
diff --git a/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/util/LSMRTreeTestHarness.java b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/util/LSMRTreeTestHarness.java
index 756c746..2c4432d 100644
--- a/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/util/LSMRTreeTestHarness.java
+++ b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/util/LSMRTreeTestHarness.java
@@ -28,6 +28,7 @@
import edu.uci.ics.hyracks.api.io.IODeviceHandle;
import edu.uci.ics.hyracks.control.nc.io.IOManager;
import edu.uci.ics.hyracks.storage.am.common.frames.LIFOMetaDataFrameFactory;
+import edu.uci.ics.hyracks.storage.am.config.AccessMethodTestsConfig;
import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMIOScheduler;
import edu.uci.ics.hyracks.storage.am.lsm.common.freepage.InMemoryBufferCache;
import edu.uci.ics.hyracks.storage.am.lsm.common.freepage.InMemoryFreePageManager;
@@ -44,12 +45,6 @@
protected static final Logger LOGGER = Logger.getLogger(LSMRTreeTestHarness.class.getName());
private static final long RANDOM_SEED = 50;
- private static final int DEFAULT_DISK_PAGE_SIZE = 256;
- private static final int DEFAULT_DISK_NUM_PAGES = 1000;
- private static final int DEFAULT_DISK_MAX_OPEN_FILES = 2000;
- private static final int DEFAULT_MEM_PAGE_SIZE = 256;
- private static final int DEFAULT_MEM_NUM_PAGES = 1000;
- private static final int DEFAULT_HYRACKS_FRAME_SIZE = 128;
private static final int DUMMY_FILE_ID = -1;
protected final int diskPageSize;
@@ -73,8 +68,13 @@
protected String onDiskDir;
public LSMRTreeTestHarness() {
- this(DEFAULT_DISK_PAGE_SIZE, DEFAULT_DISK_NUM_PAGES, DEFAULT_DISK_MAX_OPEN_FILES, DEFAULT_MEM_PAGE_SIZE,
- DEFAULT_MEM_NUM_PAGES, DEFAULT_HYRACKS_FRAME_SIZE);
+ this.diskPageSize = AccessMethodTestsConfig.LSM_RTREE_DISK_PAGE_SIZE;
+ this.diskNumPages = AccessMethodTestsConfig.LSM_RTREE_DISK_NUM_PAGES;
+ this.diskMaxOpenFiles = AccessMethodTestsConfig.LSM_RTREE_DISK_MAX_OPEN_FILES;
+ this.memPageSize = AccessMethodTestsConfig.LSM_RTREE_MEM_PAGE_SIZE;
+ this.memNumPages = AccessMethodTestsConfig.LSM_RTREE_MEM_NUM_PAGES;
+ this.hyracksFrameSize = AccessMethodTestsConfig.LSM_RTREE_HYRACKS_FRAME_SIZE;
+ this.ioScheduler = SequentialScheduler.INSTANCE;
}
public LSMRTreeTestHarness(int diskPageSize, int diskNumPages, int diskMaxOpenFiles, int memPageSize,
diff --git a/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/util/LSMRTreeWithAntiMatterTuplesTestContext.java b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/util/LSMRTreeWithAntiMatterTuplesTestContext.java
new file mode 100644
index 0000000..410adca
--- /dev/null
+++ b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/util/LSMRTreeWithAntiMatterTuplesTestContext.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package edu.uci.ics.hyracks.storage.am.lsm.rtree.util;
+
+import java.util.Collection;
+
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparatorFactory;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.dataflow.value.ITypeTraits;
+import edu.uci.ics.hyracks.control.nc.io.IOManager;
+import edu.uci.ics.hyracks.dataflow.common.util.SerdeUtils;
+import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
+import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMMergePolicy;
+import edu.uci.ics.hyracks.storage.am.lsm.common.freepage.InMemoryBufferCache;
+import edu.uci.ics.hyracks.storage.am.lsm.common.freepage.InMemoryFreePageManager;
+import edu.uci.ics.hyracks.storage.am.lsm.common.impls.ImmediateFlushPolicy;
+import edu.uci.ics.hyracks.storage.am.lsm.common.impls.SequentialScheduler;
+import edu.uci.ics.hyracks.storage.am.lsm.rtree.impls.LSMRTreeWithAntiMatterTuples;
+import edu.uci.ics.hyracks.storage.am.lsm.rtree.utils.LSMRTreeUtils;
+import edu.uci.ics.hyracks.storage.am.rtree.AbstractRTreeTestContext;
+import edu.uci.ics.hyracks.storage.am.rtree.RTreeCheckTuple;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
+import edu.uci.ics.hyracks.storage.common.buffercache.IBufferCache;
+import edu.uci.ics.hyracks.storage.common.file.IFileMapProvider;
+
+@SuppressWarnings("rawtypes")
+public final class LSMRTreeWithAntiMatterTuplesTestContext extends AbstractRTreeTestContext {
+
+ public LSMRTreeWithAntiMatterTuplesTestContext(ISerializerDeserializer[] fieldSerdes, ITreeIndex treeIndex) {
+ super(fieldSerdes, treeIndex);
+ }
+
+ @Override
+ public int getKeyFieldCount() {
+ LSMRTreeWithAntiMatterTuples lsmTree = (LSMRTreeWithAntiMatterTuples) treeIndex;
+ return lsmTree.getComparatorFactories().length;
+ }
+
+ /**
+ * Override to provide delete semantics for the check tuples.
+ */
+ @Override
+ public void deleteCheckTuple(RTreeCheckTuple checkTuple, Collection<RTreeCheckTuple> checkTuples) {
+ while (checkTuples.remove(checkTuple)) {
+ }
+ }
+
+ @Override
+ public IBinaryComparatorFactory[] getComparatorFactories() {
+ LSMRTreeWithAntiMatterTuples lsmTree = (LSMRTreeWithAntiMatterTuples) treeIndex;
+ return lsmTree.getComparatorFactories();
+ }
+
+ public static LSMRTreeWithAntiMatterTuplesTestContext create(InMemoryBufferCache memBufferCache,
+ InMemoryFreePageManager memFreePageManager, IOManager ioManager, String onDiskDir,
+ IBufferCache diskBufferCache, IFileMapProvider diskFileMapProvider, ISerializerDeserializer[] fieldSerdes,
+ IPrimitiveValueProviderFactory[] valueProviderFactories, int numKeyFields, RTreePolicyType rtreePolicyType,
+ int fileId, ILSMMergePolicy mergePolicy) throws Exception {
+ ITypeTraits[] typeTraits = SerdeUtils.serdesToTypeTraits(fieldSerdes);
+ IBinaryComparatorFactory[] rtreeCmpFactories = SerdeUtils
+ .serdesToComparatorFactories(fieldSerdes, numKeyFields);
+ IBinaryComparatorFactory[] btreeCmpFactories = SerdeUtils.serdesToComparatorFactories(fieldSerdes,
+ fieldSerdes.length);
+ LSMRTreeWithAntiMatterTuples lsmTree = LSMRTreeUtils.createLSMTreeWithAntiMatterTuples(memBufferCache,
+ memFreePageManager, ioManager, onDiskDir, diskBufferCache, diskFileMapProvider, typeTraits,
+ rtreeCmpFactories, btreeCmpFactories, valueProviderFactories, rtreePolicyType, new ImmediateFlushPolicy(SequentialScheduler.INSTANCE),
+ mergePolicy);
+ lsmTree.create(fileId);
+ lsmTree.open(fileId);
+ LSMRTreeWithAntiMatterTuplesTestContext testCtx = new LSMRTreeWithAntiMatterTuplesTestContext(fieldSerdes,
+ lsmTree);
+ return testCtx;
+ }
+}
diff --git a/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/RTreeBulkLoadTest.java b/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/RTreeBulkLoadTest.java
index 58bca10..da38708 100644
--- a/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/RTreeBulkLoadTest.java
+++ b/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/RTreeBulkLoadTest.java
@@ -23,8 +23,7 @@
import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
-import edu.uci.ics.hyracks.storage.am.rtree.AbstractRTreeBulkLoadTest;
-import edu.uci.ics.hyracks.storage.am.rtree.AbstractRTreeTestContext;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
import edu.uci.ics.hyracks.storage.am.rtree.utils.RTreeTestContext;
import edu.uci.ics.hyracks.storage.am.rtree.utils.RTreeTestHarness;
@@ -49,9 +48,10 @@
@Override
protected AbstractRTreeTestContext createTestContext(ISerializerDeserializer[] fieldSerdes,
- IPrimitiveValueProviderFactory[] valueProviderFactories, int numKeys) throws Exception {
+ IPrimitiveValueProviderFactory[] valueProviderFactories, int numKeys, RTreePolicyType rtreePolicyType)
+ throws Exception {
return RTreeTestContext.create(harness.getBufferCache(), harness.getTreeFileId(), fieldSerdes,
- valueProviderFactories, numKeys);
+ valueProviderFactories, numKeys, rtreePolicyType);
}
@Override
diff --git a/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/RTreeDeleteTest.java b/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/RTreeDeleteTest.java
index 42e933e..4d0bad4 100644
--- a/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/RTreeDeleteTest.java
+++ b/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/RTreeDeleteTest.java
@@ -23,8 +23,7 @@
import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
-import edu.uci.ics.hyracks.storage.am.rtree.AbstractRTreeDeleteTest;
-import edu.uci.ics.hyracks.storage.am.rtree.AbstractRTreeTestContext;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
import edu.uci.ics.hyracks.storage.am.rtree.utils.RTreeTestContext;
import edu.uci.ics.hyracks.storage.am.rtree.utils.RTreeTestHarness;
@@ -45,9 +44,10 @@
@Override
protected AbstractRTreeTestContext createTestContext(ISerializerDeserializer[] fieldSerdes,
- IPrimitiveValueProviderFactory[] valueProviderFactories, int numKeys) throws Exception {
+ IPrimitiveValueProviderFactory[] valueProviderFactories, int numKeys, RTreePolicyType rtreePolicyType)
+ throws Exception {
return RTreeTestContext.create(harness.getBufferCache(), harness.getTreeFileId(), fieldSerdes,
- valueProviderFactories, numKeys);
+ valueProviderFactories, numKeys, rtreePolicyType);
}
@Override
diff --git a/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/RTreeExamplesTest.java b/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/RTreeExamplesTest.java
index c72338e..99b496f 100644
--- a/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/RTreeExamplesTest.java
+++ b/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/RTreeExamplesTest.java
@@ -24,7 +24,7 @@
import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
import edu.uci.ics.hyracks.storage.am.common.api.TreeIndexException;
-import edu.uci.ics.hyracks.storage.am.rtree.AbstractRTreeExamplesTest;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
import edu.uci.ics.hyracks.storage.am.rtree.util.RTreeUtils;
import edu.uci.ics.hyracks.storage.am.rtree.utils.RTreeTestHarness;
@@ -43,10 +43,10 @@
@Override
protected ITreeIndex createTreeIndex(ITypeTraits[] typeTraits, IBinaryComparatorFactory[] rtreeCmpFactories,
- IBinaryComparatorFactory[] btreeCmpFactories, IPrimitiveValueProviderFactory[] valueProviderFactories)
- throws TreeIndexException {
- return RTreeUtils.createRTree(harness.getBufferCache(), typeTraits,
- valueProviderFactories, rtreeCmpFactories);
+ IBinaryComparatorFactory[] btreeCmpFactories, IPrimitiveValueProviderFactory[] valueProviderFactories,
+ RTreePolicyType rtreePolicyType) throws TreeIndexException {
+ return RTreeUtils.createRTree(harness.getBufferCache(), typeTraits, valueProviderFactories, rtreeCmpFactories,
+ rtreePolicyType);
}
@Override
diff --git a/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/RTreeInsertTest.java b/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/RTreeInsertTest.java
index 6efa620..193e067 100644
--- a/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/RTreeInsertTest.java
+++ b/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/RTreeInsertTest.java
@@ -23,21 +23,10 @@
import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
-import edu.uci.ics.hyracks.storage.am.rtree.AbstractRTreeInsertTest;
-import edu.uci.ics.hyracks.storage.am.rtree.AbstractRTreeTestContext;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
import edu.uci.ics.hyracks.storage.am.rtree.utils.RTreeTestContext;
import edu.uci.ics.hyracks.storage.am.rtree.utils.RTreeTestHarness;
-/**
- * Tests the BTree insert operation with strings and integer fields using
- * various numbers of key and payload fields.
- *
- * Each tests first fills a BTree with randomly generated tuples. We compare the
- * following operations against expected results: 1. Point searches for all
- * tuples. 2. Ordered scan. 3. Disk-order scan. 4. Range search (and prefix
- * search for composite keys).
- *
- */
@SuppressWarnings("rawtypes")
public class RTreeInsertTest extends AbstractRTreeInsertTest {
@@ -55,9 +44,10 @@
@Override
protected AbstractRTreeTestContext createTestContext(ISerializerDeserializer[] fieldSerdes,
- IPrimitiveValueProviderFactory[] valueProviderFactories, int numKeys) throws Exception {
+ IPrimitiveValueProviderFactory[] valueProviderFactories, int numKeys, RTreePolicyType rtreePolicyType)
+ throws Exception {
return RTreeTestContext.create(harness.getBufferCache(), harness.getTreeFileId(), fieldSerdes,
- valueProviderFactories, numKeys);
+ valueProviderFactories, numKeys, rtreePolicyType);
}
@Override
diff --git a/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/RTreeSearchCursorTest.java b/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/RTreeSearchCursorTest.java
index 9248deb..7d18999 100644
--- a/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/RTreeSearchCursorTest.java
+++ b/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/RTreeSearchCursorTest.java
@@ -47,6 +47,7 @@
import edu.uci.ics.hyracks.storage.am.rtree.api.IRTreeLeafFrame;
import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreeNSMInteriorFrameFactory;
import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreeNSMLeafFrameFactory;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
import edu.uci.ics.hyracks.storage.am.rtree.impls.RTree;
import edu.uci.ics.hyracks.storage.am.rtree.impls.RTreeSearchCursor;
import edu.uci.ics.hyracks.storage.am.rtree.impls.SearchPredicate;
@@ -108,9 +109,9 @@
ITreeIndexMetaDataFrameFactory metaFrameFactory = new LIFOMetaDataFrameFactory();
ITreeIndexFrameFactory interiorFrameFactory = new RTreeNSMInteriorFrameFactory(tupleWriterFactory,
- valueProviderFactories);
+ valueProviderFactories, RTreePolicyType.RTREE);
ITreeIndexFrameFactory leafFrameFactory = new RTreeNSMLeafFrameFactory(tupleWriterFactory,
- valueProviderFactories);
+ valueProviderFactories, RTreePolicyType.RTREE);
IRTreeInteriorFrame interiorFrame = (IRTreeInteriorFrame) interiorFrameFactory.createFrame();
IRTreeLeafFrame leafFrame = (IRTreeLeafFrame) leafFrameFactory.createFrame();
@@ -132,7 +133,8 @@
int p2x = rnd.nextInt();
int p2y = rnd.nextInt();
- int pk = rnd.nextInt();;
+ int pk = rnd.nextInt();
+ ;
TupleUtils.createIntegerTuple(tb, tuple, Math.min(p1x, p2x), Math.min(p1y, p2y), Math.max(p1x, p2x),
Math.max(p1y, p2y), pk);
diff --git a/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/multithread/RTreeMultiThreadTest.java b/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/multithread/RTreeMultiThreadTest.java
index 7520793..2e8c28f 100644
--- a/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/multithread/RTreeMultiThreadTest.java
+++ b/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/multithread/RTreeMultiThreadTest.java
@@ -21,12 +21,13 @@
import edu.uci.ics.hyracks.api.dataflow.value.ITypeTraits;
import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
import edu.uci.ics.hyracks.storage.am.common.ITreeIndexTestWorkerFactory;
-import edu.uci.ics.hyracks.storage.am.common.TestWorkloadConf;
import edu.uci.ics.hyracks.storage.am.common.TestOperationSelector.TestOperation;
+import edu.uci.ics.hyracks.storage.am.common.TestWorkloadConf;
import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
import edu.uci.ics.hyracks.storage.am.common.api.TreeIndexException;
import edu.uci.ics.hyracks.storage.am.rtree.AbstractRTreeMultiThreadTest;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
import edu.uci.ics.hyracks.storage.am.rtree.util.RTreeUtils;
import edu.uci.ics.hyracks.storage.am.rtree.utils.RTreeTestHarness;
@@ -48,10 +49,10 @@
@Override
protected ITreeIndex createTreeIndex(ITypeTraits[] typeTraits, IBinaryComparatorFactory[] rtreeCmpFactories,
- IBinaryComparatorFactory[] btreeCmpFactories, IPrimitiveValueProviderFactory[] valueProviderFactories)
- throws TreeIndexException {
- return RTreeUtils.createRTree(harness.getBufferCache(), typeTraits,
- valueProviderFactories, rtreeCmpFactories);
+ IBinaryComparatorFactory[] btreeCmpFactories, IPrimitiveValueProviderFactory[] valueProviderFactories,
+ RTreePolicyType rtreePolicyType) throws TreeIndexException {
+ return RTreeUtils.createRTree(harness.getBufferCache(), typeTraits, valueProviderFactories, rtreeCmpFactories,
+ rtreePolicyType);
}
diff --git a/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/utils/RTreeTestContext.java b/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/utils/RTreeTestContext.java
index 039fb0b..4591398 100644
--- a/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/utils/RTreeTestContext.java
+++ b/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/utils/RTreeTestContext.java
@@ -22,6 +22,7 @@
import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
import edu.uci.ics.hyracks.storage.am.rtree.AbstractRTreeTestContext;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreePolicyType;
import edu.uci.ics.hyracks.storage.am.rtree.impls.RTree;
import edu.uci.ics.hyracks.storage.am.rtree.util.RTreeUtils;
import edu.uci.ics.hyracks.storage.common.buffercache.IBufferCache;
@@ -47,11 +48,11 @@
public static RTreeTestContext create(IBufferCache bufferCache, int rtreeFileId,
ISerializerDeserializer[] fieldSerdes, IPrimitiveValueProviderFactory[] valueProviderFactories,
- int numKeyFields) throws Exception {
+ int numKeyFields, RTreePolicyType rtreePolicyType) throws Exception {
ITypeTraits[] typeTraits = SerdeUtils.serdesToTypeTraits(fieldSerdes);
IBinaryComparatorFactory[] cmpFactories = SerdeUtils.serdesToComparatorFactories(fieldSerdes, numKeyFields);
- RTree rtree = RTreeUtils
- .createRTree(bufferCache, typeTraits, valueProviderFactories, cmpFactories);
+ RTree rtree = RTreeUtils.createRTree(bufferCache, typeTraits, valueProviderFactories, cmpFactories,
+ rtreePolicyType);
rtree.create(rtreeFileId);
rtree.open(rtreeFileId);
RTreeTestContext testCtx = new RTreeTestContext(fieldSerdes, rtree);
diff --git a/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/utils/RTreeTestHarness.java b/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/utils/RTreeTestHarness.java
index c0cec35..e463f57 100644
--- a/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/utils/RTreeTestHarness.java
+++ b/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/utils/RTreeTestHarness.java
@@ -23,6 +23,7 @@
import edu.uci.ics.hyracks.api.context.IHyracksTaskContext;
import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
import edu.uci.ics.hyracks.api.io.FileReference;
+import edu.uci.ics.hyracks.storage.am.config.AccessMethodTestsConfig;
import edu.uci.ics.hyracks.storage.common.buffercache.IBufferCache;
import edu.uci.ics.hyracks.storage.common.file.IFileMapProvider;
import edu.uci.ics.hyracks.test.support.TestStorageManagerComponentHolder;
@@ -31,10 +32,6 @@
public class RTreeTestHarness {
private static final long RANDOM_SEED = 50;
- private static final int DEFAULT_PAGE_SIZE = 256;
- private static final int DEFAULT_NUM_PAGES = 1000;
- private static final int DEFAULT_MAX_OPEN_FILES = 10;
- private static final int DEFAULT_HYRACKS_FRAME_SIZE = 128;
protected final int pageSize;
protected final int numPages;
@@ -52,10 +49,10 @@
protected String fileName;
public RTreeTestHarness() {
- this.pageSize = DEFAULT_PAGE_SIZE;
- this.numPages = DEFAULT_NUM_PAGES;
- this.maxOpenFiles = DEFAULT_MAX_OPEN_FILES;
- this.hyracksFrameSize = DEFAULT_HYRACKS_FRAME_SIZE;
+ this.pageSize = AccessMethodTestsConfig.RTREE_PAGE_SIZE;
+ this.numPages = AccessMethodTestsConfig.RTREE_NUM_PAGES;
+ this.maxOpenFiles = AccessMethodTestsConfig.RTREE_MAX_OPEN_FILES;
+ this.hyracksFrameSize = AccessMethodTestsConfig.RTREE_HYRACKS_FRAME_SIZE;
}
public RTreeTestHarness(int pageSize, int numPages, int maxOpenFiles, int hyracksFrameSize) {