asterixdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From amo...@apache.org
Subject [1/7] asterixdb git commit: [ASTERIXDB-2204][STO] Fix implementations and usages of IIndexCursor
Date Tue, 13 Feb 2018 00:09:50 GMT
Repository: asterixdb
Updated Branches:
  refs/heads/master 2f392e855 -> 4ff6a36d1


http://git-wip-us.apache.org/repos/asf/asterixdb/blob/4ff6a36d/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/org/apache/hyracks/storage/am/lsm/btree/cursor/LSMBTreeSearchCursorTest.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/org/apache/hyracks/storage/am/lsm/btree/cursor/LSMBTreeSearchCursorTest.java
b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/org/apache/hyracks/storage/am/lsm/btree/cursor/LSMBTreeSearchCursorTest.java
new file mode 100644
index 0000000..19b3880
--- /dev/null
+++ b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/org/apache/hyracks/storage/am/lsm/btree/cursor/LSMBTreeSearchCursorTest.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 at
+ *
+ *   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 org.apache.hyracks.storage.am.lsm.btree.cursor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.dataflow.common.comm.io.ArrayTupleBuilder;
+import org.apache.hyracks.dataflow.common.comm.io.ArrayTupleReference;
+import org.apache.hyracks.dataflow.common.utils.TupleUtils;
+import org.apache.hyracks.storage.am.btree.impls.RangePredicate;
+import org.apache.hyracks.storage.am.btree.util.BTreeUtils;
+import org.apache.hyracks.storage.am.common.impls.NoOpIndexAccessParameters;
+import org.apache.hyracks.storage.am.common.test.IIndexCursorTest;
+import org.apache.hyracks.storage.am.lsm.btree.LSMBTreeExamplesTest;
+import org.apache.hyracks.storage.am.lsm.btree.impls.LSMBTree;
+import org.apache.hyracks.storage.am.lsm.btree.util.LSMBTreeTestHarness;
+import org.apache.hyracks.storage.common.IIndexAccessor;
+import org.apache.hyracks.storage.common.ISearchPredicate;
+import org.apache.hyracks.storage.common.MultiComparator;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+
+public class LSMBTreeSearchCursorTest extends IIndexCursorTest {
+
+    private static final LSMBTreeTestHarness harness = new LSMBTreeTestHarness();
+    private static LSMBTree lsmBtree;
+
+    @BeforeClass
+    public static void setup() throws HyracksDataException {
+        harness.setUp();
+        lsmBtree = LSMBTreeExamplesTest.createTreeIndex(harness, LSMBTreePointSearchCursorTest.TYPE_TRAITS,
+                LSMBTreePointSearchCursorTest.CMP_FACTORIES, LSMBTreePointSearchCursorTest.BLOOM_FILTER_KEY_FIELDS,
+                null, null, null, null);
+        lsmBtree.create();
+        lsmBtree.activate();
+        LSMBTreePointSearchCursorTest.insertData(lsmBtree);
+    }
+
+    @AfterClass
+    public static void teardown() throws HyracksDataException {
+        try {
+            lsmBtree.deactivate();
+            lsmBtree.destroy();
+        } finally {
+            harness.tearDown();
+        }
+    }
+
+    @Override
+    protected List<ISearchPredicate> createSearchPredicates() throws Exception {
+        // exact and windows of length = 50
+        List<ISearchPredicate> predicates = new ArrayList<>();
+        for (int i = 0; i < 10; i++) {
+            // Build low key.
+            ArrayTupleBuilder lowKeyTb = new ArrayTupleBuilder(LSMBTreePointSearchCursorTest.KEY_FIELD_COUNT);
+            ArrayTupleReference lowKey = new ArrayTupleReference();
+            TupleUtils.createIntegerTuple(lowKeyTb, lowKey, -100 + (i * 50));
+            // Build high key.
+            ArrayTupleBuilder highKeyTb = new ArrayTupleBuilder(LSMBTreePointSearchCursorTest.KEY_FIELD_COUNT);
+            ArrayTupleReference highKey = new ArrayTupleReference();
+            TupleUtils.createIntegerTuple(highKeyTb, highKey, -100 + (i * 50) + 50);
+            MultiComparator lowKeySearchCmp =
+                    BTreeUtils.getSearchMultiComparator(LSMBTreePointSearchCursorTest.CMP_FACTORIES,
lowKey);
+            MultiComparator highKeySearchCmp =
+                    BTreeUtils.getSearchMultiComparator(LSMBTreePointSearchCursorTest.CMP_FACTORIES,
highKey);
+            predicates.add(new RangePredicate(lowKey, highKey, true, true, lowKeySearchCmp,
highKeySearchCmp));
+            lowKeyTb = new ArrayTupleBuilder(LSMBTreePointSearchCursorTest.KEY_FIELD_COUNT);
+            lowKey = new ArrayTupleReference();
+            TupleUtils.createIntegerTuple(lowKeyTb, lowKey, -100 + (i * 50) + 25);
+            // Build high key.
+            highKeyTb = new ArrayTupleBuilder(LSMBTreePointSearchCursorTest.KEY_FIELD_COUNT);
+            highKey = new ArrayTupleReference();
+            TupleUtils.createIntegerTuple(highKeyTb, highKey, -100 + (i * 50) + 25);
+            lowKeySearchCmp = BTreeUtils.getSearchMultiComparator(LSMBTreePointSearchCursorTest.CMP_FACTORIES,
lowKey);
+            highKeySearchCmp =
+                    BTreeUtils.getSearchMultiComparator(LSMBTreePointSearchCursorTest.CMP_FACTORIES,
highKey);
+            predicates.add(new RangePredicate(lowKey, highKey, true, true, lowKeySearchCmp,
highKeySearchCmp));
+        }
+        return predicates;
+    }
+
+    @Override
+    protected IIndexAccessor createAccessor() throws Exception {
+        return lsmBtree.createAccessor(NoOpIndexAccessParameters.INSTANCE);
+    }
+}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/4ff6a36d/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/org/apache/hyracks/storage/am/lsm/btree/impl/TestLsmBtreeSearchCursor.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/org/apache/hyracks/storage/am/lsm/btree/impl/TestLsmBtreeSearchCursor.java
b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/org/apache/hyracks/storage/am/lsm/btree/impl/TestLsmBtreeSearchCursor.java
index 45e39aa..4e4ecb7 100644
--- a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/org/apache/hyracks/storage/am/lsm/btree/impl/TestLsmBtreeSearchCursor.java
+++ b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/org/apache/hyracks/storage/am/lsm/btree/impl/TestLsmBtreeSearchCursor.java
@@ -35,7 +35,7 @@ public class TestLsmBtreeSearchCursor extends LSMBTreeSearchCursor {
     }
 
     @Override
-    public void next() throws HyracksDataException {
+    public void doNext() throws HyracksDataException {
         try {
             List<ITestOpCallback<Semaphore>> callbacks = lsmBtree.getSearchCallbacks();
             synchronized (callbacks) {
@@ -47,6 +47,6 @@ public class TestLsmBtreeSearchCursor extends LSMBTreeSearchCursor {
         } catch (Exception e) {
             throw HyracksDataException.create(e);
         }
-        super.next();
+        super.doNext();
     }
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/4ff6a36d/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-invertedindex-test/src/test/java/org/apache/hyracks/storage/am/lsm/invertedindex/util/LSMInvertedIndexTestUtils.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-invertedindex-test/src/test/java/org/apache/hyracks/storage/am/lsm/invertedindex/util/LSMInvertedIndexTestUtils.java
b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-invertedindex-test/src/test/java/org/apache/hyracks/storage/am/lsm/invertedindex/util/LSMInvertedIndexTestUtils.java
index 5902e62..3423f70 100644
--- a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-invertedindex-test/src/test/java/org/apache/hyracks/storage/am/lsm/invertedindex/util/LSMInvertedIndexTestUtils.java
+++ b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-invertedindex-test/src/test/java/org/apache/hyracks/storage/am/lsm/invertedindex/util/LSMInvertedIndexTestUtils.java
@@ -260,42 +260,44 @@ public class LSMInvertedIndexTestUtils {
         IInvertedIndexAccessor invIndexAccessor =
                 (IInvertedIndexAccessor) invIndex.createAccessor(NoOpIndexAccessParameters.INSTANCE);
         IIndexCursor invIndexCursor = invIndexAccessor.createRangeSearchCursor();
-        MultiComparator tokenCmp = MultiComparator.create(invIndex.getTokenCmpFactories());
-        IBinaryComparatorFactory[] tupleCmpFactories =
-                new IBinaryComparatorFactory[tokenFieldCount + invListFieldCount];
-        for (int i = 0; i < tokenFieldCount; i++) {
-            tupleCmpFactories[i] = invIndex.getTokenCmpFactories()[i];
-        }
-        for (int i = 0; i < invListFieldCount; i++) {
-            tupleCmpFactories[tokenFieldCount + i] = invIndex.getInvListCmpFactories()[i];
-        }
-        MultiComparator tupleCmp = MultiComparator.create(tupleCmpFactories);
-        RangePredicate nullPred = new RangePredicate(null, null, true, true, tokenCmp, tokenCmp);
-        invIndexAccessor.rangeSearch(invIndexCursor, nullPred);
-
-        // Helpers for generating a serialized inverted-list element from a CheckTuple from
the expected index.
-        ISerializerDeserializer[] fieldSerdes = testCtx.getFieldSerdes();
-        ArrayTupleBuilder expectedBuilder = new ArrayTupleBuilder(fieldSerdes.length);
-        ArrayTupleReference expectedTuple = new ArrayTupleReference();
-
-        Iterator<CheckTuple> expectedIter = testCtx.getCheckTuples().iterator();
-
-        // Compare index elements.
         try {
-            while (invIndexCursor.hasNext() && expectedIter.hasNext()) {
-                invIndexCursor.next();
-                ITupleReference actualTuple = invIndexCursor.getTuple();
-                CheckTuple expected = expectedIter.next();
-                OrderedIndexTestUtils.createTupleFromCheckTuple(expected, expectedBuilder,
expectedTuple, fieldSerdes);
-                if (tupleCmp.compare(actualTuple, expectedTuple) != 0) {
-                    fail("Index entries differ for token '" + expected.getField(0) + "'.");
-                }
+            MultiComparator tokenCmp = MultiComparator.create(invIndex.getTokenCmpFactories());
+            IBinaryComparatorFactory[] tupleCmpFactories =
+                    new IBinaryComparatorFactory[tokenFieldCount + invListFieldCount];
+            for (int i = 0; i < tokenFieldCount; i++) {
+                tupleCmpFactories[i] = invIndex.getTokenCmpFactories()[i];
             }
-            if (expectedIter.hasNext()) {
-                fail("Indexes do not match. Actual index is missing entries.");
+            for (int i = 0; i < invListFieldCount; i++) {
+                tupleCmpFactories[tokenFieldCount + i] = invIndex.getInvListCmpFactories()[i];
             }
-            if (invIndexCursor.hasNext()) {
-                fail("Indexes do not match. Actual index contains too many entries.");
+            MultiComparator tupleCmp = MultiComparator.create(tupleCmpFactories);
+            RangePredicate nullPred = new RangePredicate(null, null, true, true, tokenCmp,
tokenCmp);
+            // Helpers for generating a serialized inverted-list element from a CheckTuple
from the expected index.
+            ISerializerDeserializer[] fieldSerdes = testCtx.getFieldSerdes();
+            ArrayTupleBuilder expectedBuilder = new ArrayTupleBuilder(fieldSerdes.length);
+            ArrayTupleReference expectedTuple = new ArrayTupleReference();
+            Iterator<CheckTuple> expectedIter = testCtx.getCheckTuples().iterator();
+            // Compare index elements.
+            invIndexAccessor.rangeSearch(invIndexCursor, nullPred);
+            try {
+                while (invIndexCursor.hasNext() && expectedIter.hasNext()) {
+                    invIndexCursor.next();
+                    ITupleReference actualTuple = invIndexCursor.getTuple();
+                    CheckTuple expected = expectedIter.next();
+                    OrderedIndexTestUtils.createTupleFromCheckTuple(expected, expectedBuilder,
expectedTuple,
+                            fieldSerdes);
+                    if (tupleCmp.compare(actualTuple, expectedTuple) != 0) {
+                        fail("Index entries differ for token '" + expected.getField(0) +
"'.");
+                    }
+                }
+                if (expectedIter.hasNext()) {
+                    fail("Indexes do not match. Actual index is missing entries.");
+                }
+                if (invIndexCursor.hasNext()) {
+                    fail("Indexes do not match. Actual index contains too many entries.");
+                }
+            } finally {
+                invIndexCursor.close();
             }
         } finally {
             invIndexCursor.destroy();
@@ -517,61 +519,65 @@ public class LSMInvertedIndexTestUtils {
             searchPred.setQueryFieldIndex(0);
 
             IIndexCursor resultCursor = accessor.createSearchCursor(false);
-            boolean panic = false;
             try {
-                accessor.search(resultCursor, searchPred);
-            } catch (HyracksDataException e) {
-                // ignore panic queries.
-                if (e.getErrorCode() == ErrorCode.OCCURRENCE_THRESHOLD_PANIC_EXCEPTION) {
-                    panic = true;
-                } else {
-                    throw e;
+                boolean panic = false;
+                try {
+                    accessor.search(resultCursor, searchPred);
+                } catch (HyracksDataException e) {
+                    // ignore panic queries.
+                    if (e.getErrorCode() == ErrorCode.OCCURRENCE_THRESHOLD_PANIC_EXCEPTION)
{
+                        panic = true;
+                    } else {
+                        throw e;
+                    }
                 }
-            }
-
-            try {
-                if (!panic) {
-                    // Consume cursor and deserialize results so we can sort them. Some search
cursors may not deliver the result sorted (e.g., LSM search cursor).
-                    ArrayList<Integer> actualResults = new ArrayList<>();
-                    try {
-                        while (resultCursor.hasNext()) {
-                            resultCursor.next();
-                            ITupleReference resultTuple = resultCursor.getTuple();
-                            int actual = IntegerPointable.getInteger(resultTuple.getFieldData(0),
-                                    resultTuple.getFieldStart(0));
-                            actualResults.add(Integer.valueOf(actual));
+                try {
+                    if (!panic) {
+                        // Consume cursor and deserialize results so we can sort them. Some
search cursors may not deliver the result sorted (e.g., LSM search cursor).
+                        ArrayList<Integer> actualResults = new ArrayList<>();
+                        try {
+                            while (resultCursor.hasNext()) {
+                                resultCursor.next();
+                                ITupleReference resultTuple = resultCursor.getTuple();
+                                int actual = IntegerPointable.getInteger(resultTuple.getFieldData(0),
+                                        resultTuple.getFieldStart(0));
+                                actualResults.add(Integer.valueOf(actual));
+                            }
+                        } catch (HyracksDataException e) {
+                            if (e.getErrorCode() == ErrorCode.OCCURRENCE_THRESHOLD_PANIC_EXCEPTION)
{
+                                // Ignore panic queries.
+                                continue;
+                            } else {
+                                throw e;
+                            }
                         }
-                    } catch (HyracksDataException e) {
-                        if (e.getErrorCode() == ErrorCode.OCCURRENCE_THRESHOLD_PANIC_EXCEPTION)
{
-                            // Ignore panic queries.
-                            continue;
-                        } else {
-                            throw e;
+                        Collections.sort(actualResults);
+
+                        // Get expected results.
+                        List<Integer> expectedResults = new ArrayList<>();
+                        LSMInvertedIndexTestUtils.getExpectedResults(scanCountArray, testCtx.getCheckTuples(),
+                                searchDocument, tokenizer, testCtx.getFieldSerdes()[0], searchModifier,
expectedResults,
+                                testCtx.getInvertedIndexType());
+
+                        Iterator<Integer> expectedIter = expectedResults.iterator();
+                        Iterator<Integer> actualIter = actualResults.iterator();
+                        while (expectedIter.hasNext() && actualIter.hasNext()) {
+                            int expected = expectedIter.next();
+                            int actual = actualIter.next();
+                            if (actual != expected) {
+                                fail("Query results do not match. Encountered: " + actual
+ ". Expected: " + expected
+                                        + "");
+                            }
                         }
-                    }
-                    Collections.sort(actualResults);
-
-                    // Get expected results.
-                    List<Integer> expectedResults = new ArrayList<>();
-                    LSMInvertedIndexTestUtils.getExpectedResults(scanCountArray, testCtx.getCheckTuples(),
-                            searchDocument, tokenizer, testCtx.getFieldSerdes()[0], searchModifier,
expectedResults,
-                            testCtx.getInvertedIndexType());
-
-                    Iterator<Integer> expectedIter = expectedResults.iterator();
-                    Iterator<Integer> actualIter = actualResults.iterator();
-                    while (expectedIter.hasNext() && actualIter.hasNext()) {
-                        int expected = expectedIter.next();
-                        int actual = actualIter.next();
-                        if (actual != expected) {
-                            fail("Query results do not match. Encountered: " + actual + ".
Expected: " + expected + "");
+                        if (expectedIter.hasNext()) {
+                            fail("Query results do not match. Actual results missing.");
+                        }
+                        if (actualIter.hasNext()) {
+                            fail("Query results do not match. Actual contains too many results.");
                         }
                     }
-                    if (expectedIter.hasNext()) {
-                        fail("Query results do not match. Actual results missing.");
-                    }
-                    if (actualIter.hasNext()) {
-                        fail("Query results do not match. Actual contains too many results.");
-                    }
+                } finally {
+                    resultCursor.close();
                 }
             } finally {
                 resultCursor.destroy();

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/4ff6a36d/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-rtree-test/pom.xml
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-rtree-test/pom.xml
b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-rtree-test/pom.xml
index 947debc..db41659 100644
--- a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-rtree-test/pom.xml
+++ b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-rtree-test/pom.xml
@@ -68,6 +68,13 @@
     </dependency>
     <dependency>
       <groupId>org.apache.hyracks</groupId>
+      <artifactId>hyracks-storage-am-common</artifactId>
+      <version>${project.version}</version>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hyracks</groupId>
       <artifactId>hyracks-api</artifactId>
       <version>${project.version}</version>
     </dependency>

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/4ff6a36d/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/org/apache/hyracks/storage/am/rtree/RTreeSearchCursorLifecycleTest.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/org/apache/hyracks/storage/am/rtree/RTreeSearchCursorLifecycleTest.java
b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/org/apache/hyracks/storage/am/rtree/RTreeSearchCursorLifecycleTest.java
new file mode 100644
index 0000000..8ae7dac
--- /dev/null
+++ b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/org/apache/hyracks/storage/am/rtree/RTreeSearchCursorLifecycleTest.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 at
+ *
+ *   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 org.apache.hyracks.storage.am.rtree;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.dataflow.common.comm.io.ArrayTupleReference;
+import org.apache.hyracks.storage.am.common.freepage.LinkedMetaDataPageManager;
+import org.apache.hyracks.storage.am.common.impls.NoOpIndexAccessParameters;
+import org.apache.hyracks.storage.am.common.test.IIndexCursorTest;
+import org.apache.hyracks.storage.am.rtree.impls.RTree;
+import org.apache.hyracks.storage.am.rtree.utils.RTreeTestHarness;
+import org.apache.hyracks.storage.common.IIndexAccessor;
+import org.apache.hyracks.storage.common.ISearchPredicate;
+import org.apache.hyracks.storage.common.buffercache.IBufferCache;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+
+public class RTreeSearchCursorLifecycleTest extends IIndexCursorTest {
+
+    private static final RTreeTestHarness harness = new RTreeTestHarness();
+    private static RTree rtree;
+
+    @BeforeClass
+    public static void setup() throws HyracksDataException {
+        harness.setUp();
+        IBufferCache bufferCache = harness.getBufferCache();
+        rtree = new RTree(bufferCache,
+                new LinkedMetaDataPageManager(bufferCache, RTreeSearchCursorTest.META_FRAME_FACTORY),
+                RTreeSearchCursorTest.INTERIOR_FRAME_FACTORY, RTreeSearchCursorTest.LEAF_FRAME_FACTORY,
+                RTreeSearchCursorTest.CMP_FACTORIES, RTreeSearchCursorTest.FIELD_COUNT, harness.getFileReference(),
+                false);
+        rtree.create();
+        rtree.activate();
+        RTreeSearchCursorTest.insert(rtree);
+    }
+
+    @AfterClass
+    public static void teardown() throws HyracksDataException {
+        try {
+            rtree.deactivate();
+            rtree.destroy();
+        } finally {
+            harness.tearDown();
+        }
+    }
+
+    @Override
+    protected List<ISearchPredicate> createSearchPredicates() throws Exception {
+        List<ISearchPredicate> predicates = new ArrayList<>();
+        predicates.add(RTreeSearchCursorTest.createSearchPredicate(new ArrayTupleReference(),
-100, -100, 100, 100));
+        predicates.add(RTreeSearchCursorTest.createSearchPredicate(new ArrayTupleReference(),
-200, -200, 200, 200));
+        predicates.add(RTreeSearchCursorTest.createSearchPredicate(new ArrayTupleReference(),
-300, -300, 300, 300));
+        predicates.add(RTreeSearchCursorTest.createSearchPredicate(new ArrayTupleReference(),
-400, -400, 400, 400));
+        predicates.add(RTreeSearchCursorTest.createSearchPredicate(new ArrayTupleReference(),
-500, -500, 500, 500));
+        predicates.add(RTreeSearchCursorTest.createSearchPredicate(new ArrayTupleReference(),
-600, -600, 600, 600));
+        predicates.add(RTreeSearchCursorTest.createSearchPredicate(new ArrayTupleReference(),
-700, -700, 700, 700));
+        predicates.add(RTreeSearchCursorTest.createSearchPredicate(new ArrayTupleReference(),
-800, -800, 800, 800));
+        predicates.add(RTreeSearchCursorTest.createSearchPredicate(new ArrayTupleReference(),
-900, -900, 900, 900));
+        predicates
+                .add(RTreeSearchCursorTest.createSearchPredicate(new ArrayTupleReference(),
-1000, -1000, 1000, 1000));
+        return predicates;
+    }
+
+    @Override
+    protected IIndexAccessor createAccessor() throws Exception {
+        return rtree.createAccessor(NoOpIndexAccessParameters.INSTANCE);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/4ff6a36d/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/org/apache/hyracks/storage/am/rtree/RTreeSearchCursorTest.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/org/apache/hyracks/storage/am/rtree/RTreeSearchCursorTest.java
b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/org/apache/hyracks/storage/am/rtree/RTreeSearchCursorTest.java
index 15f69bc..56c4b53 100644
--- a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/org/apache/hyracks/storage/am/rtree/RTreeSearchCursorTest.java
+++ b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/org/apache/hyracks/storage/am/rtree/RTreeSearchCursorTest.java
@@ -61,8 +61,31 @@ import org.junit.Test;
 
 public class RTreeSearchCursorTest extends AbstractRTreeTest {
 
+    public static final int FIELD_COUNT = 5;
+    public static final ITypeTraits[] TYPE_TRAITS = { IntegerPointable.TYPE_TRAITS, IntegerPointable.TYPE_TRAITS,
+            IntegerPointable.TYPE_TRAITS, IntegerPointable.TYPE_TRAITS, IntegerPointable.TYPE_TRAITS
};
+    // Declare field serdes.
+    @SuppressWarnings("rawtypes")
+    public static final ISerializerDeserializer[] FIELD_SERDES = { IntegerSerializerDeserializer.INSTANCE,
+            IntegerSerializerDeserializer.INSTANCE, IntegerSerializerDeserializer.INSTANCE,
+            IntegerSerializerDeserializer.INSTANCE, IntegerSerializerDeserializer.INSTANCE
};
+    public static final int KEY_FIELD_COUNT = 4;
+    public static final IBinaryComparatorFactory[] CMP_FACTORIES =
+            { PointableBinaryComparatorFactory.of(IntegerPointable.FACTORY),
+                    PointableBinaryComparatorFactory.of(IntegerPointable.FACTORY),
+                    PointableBinaryComparatorFactory.of(IntegerPointable.FACTORY),
+                    PointableBinaryComparatorFactory.of(IntegerPointable.FACTORY) };
+    public static final IPrimitiveValueProviderFactory[] VALUE_PROVIDER_FACTORY =
+            RTreeUtils.createPrimitiveValueProviderFactories(CMP_FACTORIES.length, IntegerPointable.FACTORY);
+    public static final RTreeTypeAwareTupleWriterFactory TUPLE_WRITER_FACTORY =
+            new RTreeTypeAwareTupleWriterFactory(TYPE_TRAITS);
+    public static final ITreeIndexMetadataFrameFactory META_FRAME_FACTORY = new LIFOMetaDataFrameFactory();
+    public static final ITreeIndexFrameFactory INTERIOR_FRAME_FACTORY = new RTreeNSMInteriorFrameFactory(
+            TUPLE_WRITER_FACTORY, VALUE_PROVIDER_FACTORY, RTreePolicyType.RTREE, false);
+    public static final ITreeIndexFrameFactory LEAF_FRAME_FACTORY =
+            new RTreeNSMLeafFrameFactory(TUPLE_WRITER_FACTORY, VALUE_PROVIDER_FACTORY, RTreePolicyType.RTREE,
false);
+    private static final Random RND = new Random(50);
     private final RTreeTestUtils rTreeTestUtils;
-    private Random rnd = new Random(50);
 
     public RTreeSearchCursorTest() {
         this.rTreeTestUtils = new RTreeTestUtils();
@@ -74,69 +97,73 @@ public class RTreeSearchCursorTest extends AbstractRTreeTest {
         super.setUp();
     }
 
-    @SuppressWarnings({ "unchecked", "rawtypes" })
+    @SuppressWarnings({ "rawtypes" })
     @Test
     public void rangeSearchTest() throws Exception {
         if (LOGGER.isInfoEnabled()) {
             LOGGER.info("TESTING RANGE SEARCH CURSOR FOR RTREE");
         }
-
         IBufferCache bufferCache = harness.getBufferCache();
-
-        // Declare fields.
-        int fieldCount = 5;
-        ITypeTraits[] typeTraits = new ITypeTraits[fieldCount];
-        typeTraits[0] = IntegerPointable.TYPE_TRAITS;
-        typeTraits[1] = IntegerPointable.TYPE_TRAITS;
-        typeTraits[2] = IntegerPointable.TYPE_TRAITS;
-        typeTraits[3] = IntegerPointable.TYPE_TRAITS;
-        typeTraits[4] = IntegerPointable.TYPE_TRAITS;
-        // Declare field serdes.
-        ISerializerDeserializer[] fieldSerdes = { IntegerSerializerDeserializer.INSTANCE,
-                IntegerSerializerDeserializer.INSTANCE, IntegerSerializerDeserializer.INSTANCE,
-                IntegerSerializerDeserializer.INSTANCE, IntegerSerializerDeserializer.INSTANCE
};
-
-        // Declare keys.
-        int keyFieldCount = 4;
-        IBinaryComparatorFactory[] cmpFactories = new IBinaryComparatorFactory[keyFieldCount];
-        cmpFactories[0] = PointableBinaryComparatorFactory.of(IntegerPointable.FACTORY);
-        cmpFactories[1] = PointableBinaryComparatorFactory.of(IntegerPointable.FACTORY);
-        cmpFactories[2] = PointableBinaryComparatorFactory.of(IntegerPointable.FACTORY);
-        cmpFactories[3] = PointableBinaryComparatorFactory.of(IntegerPointable.FACTORY);
-
         // create value providers
-        IPrimitiveValueProviderFactory[] valueProviderFactories =
-                RTreeUtils.createPrimitiveValueProviderFactories(cmpFactories.length, IntegerPointable.FACTORY);
-
-        RTreeTypeAwareTupleWriterFactory tupleWriterFactory = new RTreeTypeAwareTupleWriterFactory(typeTraits);
-        ITreeIndexMetadataFrameFactory metaFrameFactory = new LIFOMetaDataFrameFactory();
-
-        ITreeIndexFrameFactory interiorFrameFactory = new RTreeNSMInteriorFrameFactory(tupleWriterFactory,
-                valueProviderFactories, RTreePolicyType.RTREE, false);
-        ITreeIndexFrameFactory leafFrameFactory =
-                new RTreeNSMLeafFrameFactory(tupleWriterFactory, valueProviderFactories,
RTreePolicyType.RTREE, false);
-
-        IRTreeInteriorFrame interiorFrame = (IRTreeInteriorFrame) interiorFrameFactory.createFrame();
-        IRTreeLeafFrame leafFrame = (IRTreeLeafFrame) leafFrameFactory.createFrame();
-        IMetadataPageManager freePageManager = new LinkedMetaDataPageManager(bufferCache,
metaFrameFactory);
-
-        RTree rtree = new RTree(bufferCache, freePageManager, interiorFrameFactory, leafFrameFactory,
cmpFactories,
-                fieldCount, harness.getFileReference(), false);
+        IRTreeInteriorFrame interiorFrame = (IRTreeInteriorFrame) INTERIOR_FRAME_FACTORY.createFrame();
+        IRTreeLeafFrame leafFrame = (IRTreeLeafFrame) LEAF_FRAME_FACTORY.createFrame();
+        IMetadataPageManager freePageManager = new LinkedMetaDataPageManager(bufferCache,
META_FRAME_FACTORY);
+        RTree rtree = new RTree(bufferCache, freePageManager, INTERIOR_FRAME_FACTORY, LEAF_FRAME_FACTORY,
CMP_FACTORIES,
+                FIELD_COUNT, harness.getFileReference(), false);
         rtree.create();
         rtree.activate();
+        ArrayList<RTreeCheckTuple> checkTuples = insert(rtree);
+        ITreeIndexAccessor indexAccessor = rtree.createAccessor(NoOpIndexAccessParameters.INSTANCE);
+        try {
+            // Build key.
+            ArrayTupleReference key = new ArrayTupleReference();
+            SearchPredicate searchPredicate = createSearchPredicate(key, -1000, -1000, 1000,
1000);
+            ITreeIndexCursor searchCursor = new RTreeSearchCursor(interiorFrame, leafFrame);
+            try {
+                RTreeCheckTuple keyCheck =
+                        (RTreeCheckTuple) rTreeTestUtils.createCheckTupleFromTuple(key, FIELD_SERDES,
KEY_FIELD_COUNT);
+                HashMultiSet<RTreeCheckTuple> expectedResult =
+                        rTreeTestUtils.getRangeSearchExpectedResults(checkTuples, keyCheck);
+                rTreeTestUtils.getRangeSearchExpectedResults(checkTuples, keyCheck);
+                indexAccessor.search(searchCursor, searchPredicate);
+                try {
+                    rTreeTestUtils.checkExpectedResults(searchCursor, expectedResult, FIELD_SERDES,
KEY_FIELD_COUNT,
+                            null);
+                } finally {
+                    searchCursor.close();
+                }
+            } finally {
+                searchCursor.destroy();
+            }
+        } finally {
+            indexAccessor.destroy();
+        }
+        rtree.deactivate();
+        rtree.destroy();
+    }
+
+    public static SearchPredicate createSearchPredicate(ArrayTupleReference key, int first,
int second, int third,
+            int fourth) throws HyracksDataException {
+        ArrayTupleBuilder keyTb = new ArrayTupleBuilder(KEY_FIELD_COUNT);
+        TupleUtils.createIntegerTuple(keyTb, key, first, second, third, fourth);
+        MultiComparator cmp = MultiComparator.create(CMP_FACTORIES);
+        return new SearchPredicate(key, cmp);
+    }
 
-        ArrayTupleBuilder tb = new ArrayTupleBuilder(fieldCount);
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    public static ArrayList<RTreeCheckTuple> insert(RTree rtree) throws HyracksDataException
{
+        ArrayTupleBuilder tb = new ArrayTupleBuilder(FIELD_COUNT);
         ArrayTupleReference tuple = new ArrayTupleReference();
         ITreeIndexAccessor indexAccessor = rtree.createAccessor(NoOpIndexAccessParameters.INSTANCE);
         int numInserts = 10000;
         ArrayList<RTreeCheckTuple> checkTuples = new ArrayList<>();
         for (int i = 0; i < numInserts; i++) {
-            int p1x = rnd.nextInt();
-            int p1y = rnd.nextInt();
-            int p2x = rnd.nextInt();
-            int p2y = rnd.nextInt();
+            int p1x = RND.nextInt();
+            int p1y = RND.nextInt();
+            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);
@@ -147,7 +174,7 @@ public class RTreeSearchCursorTest extends AbstractRTreeTest {
                     throw e;
                 }
             }
-            RTreeCheckTuple checkTuple = new RTreeCheckTuple(fieldCount, keyFieldCount);
+            RTreeCheckTuple checkTuple = new RTreeCheckTuple(FIELD_COUNT, KEY_FIELD_COUNT);
             checkTuple.appendField(Math.min(p1x, p2x));
             checkTuple.appendField(Math.min(p1y, p2y));
             checkTuple.appendField(Math.max(p1x, p2x));
@@ -156,28 +183,6 @@ public class RTreeSearchCursorTest extends AbstractRTreeTest {
 
             checkTuples.add(checkTuple);
         }
-
-        // Build key.
-        ArrayTupleBuilder keyTb = new ArrayTupleBuilder(keyFieldCount);
-        ArrayTupleReference key = new ArrayTupleReference();
-        TupleUtils.createIntegerTuple(keyTb, key, -1000, -1000, 1000, 1000);
-
-        MultiComparator cmp = MultiComparator.create(cmpFactories);
-        ITreeIndexCursor searchCursor = new RTreeSearchCursor(interiorFrame, leafFrame);
-        SearchPredicate searchPredicate = new SearchPredicate(key, cmp);
-
-        RTreeCheckTuple keyCheck =
-                (RTreeCheckTuple) rTreeTestUtils.createCheckTupleFromTuple(key, fieldSerdes,
keyFieldCount);
-        HashMultiSet<RTreeCheckTuple> expectedResult =
-                rTreeTestUtils.getRangeSearchExpectedResults(checkTuples, keyCheck);
-
-        rTreeTestUtils.getRangeSearchExpectedResults(checkTuples, keyCheck);
-        indexAccessor.search(searchCursor, searchPredicate);
-
-        rTreeTestUtils.checkExpectedResults(searchCursor, expectedResult, fieldSerdes, keyFieldCount,
null);
-
-        rtree.deactivate();
-        rtree.destroy();
+        return checkTuples;
     }
-
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/4ff6a36d/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/org/apache/hyracks/storage/am/rtree/multithread/RTreeTestWorker.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/org/apache/hyracks/storage/am/rtree/multithread/RTreeTestWorker.java
b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/org/apache/hyracks/storage/am/rtree/multithread/RTreeTestWorker.java
index 9d2d59e..36e0209 100644
--- a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/org/apache/hyracks/storage/am/rtree/multithread/RTreeTestWorker.java
+++ b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/org/apache/hyracks/storage/am/rtree/multithread/RTreeTestWorker.java
@@ -52,37 +52,49 @@ public class RTreeTestWorker extends AbstractIndexTestWorker {
     @Override
     public void performOp(ITupleReference tuple, TestOperation op) throws HyracksDataException
{
         RTree.RTreeAccessor accessor = (RTree.RTreeAccessor) indexAccessor;
-        IIndexCursor searchCursor = accessor.createSearchCursor(false);
-        ITreeIndexCursor diskOrderScanCursor = accessor.createDiskOrderScanCursor();
         MultiComparator cmp = accessor.getOpContext().getCmp();
         SearchPredicate rangePred = new SearchPredicate(tuple, cmp);
+        IIndexCursor searchCursor = accessor.createSearchCursor(false);
+        try {
+            ITreeIndexCursor diskOrderScanCursor = accessor.createDiskOrderScanCursor();
+            try {
+                switch (op) {
+                    case INSERT:
+                        rearrangeTuple(tuple, cmp);
+                        accessor.insert(rearrangedTuple);
+                        break;
 
-        switch (op) {
-            case INSERT:
-                rearrangeTuple(tuple, cmp);
-                accessor.insert(rearrangedTuple);
-                break;
-
-            case DELETE:
-                rearrangeTuple(tuple, cmp);
-                accessor.delete(rearrangedTuple);
-                break;
-
-            case SCAN:
-                searchCursor.close();
-                rangePred.setSearchKey(null);
-                accessor.search(searchCursor, rangePred);
-                consumeCursorTuples(searchCursor);
-                break;
+                    case DELETE:
+                        rearrangeTuple(tuple, cmp);
+                        accessor.delete(rearrangedTuple);
+                        break;
 
-            case DISKORDER_SCAN:
-                diskOrderScanCursor.close();
-                accessor.diskOrderScan(diskOrderScanCursor);
-                consumeCursorTuples(diskOrderScanCursor);
-                break;
+                    case SCAN:
+                        rangePred.setSearchKey(null);
+                        accessor.search(searchCursor, rangePred);
+                        try {
+                            consumeCursorTuples(searchCursor);
+                        } finally {
+                            searchCursor.close();
+                        }
+                        break;
 
-            default:
-                throw new HyracksDataException("Op " + op.toString() + " not supported.");
+                    case DISKORDER_SCAN:
+                        accessor.diskOrderScan(diskOrderScanCursor);
+                        try {
+                            consumeCursorTuples(diskOrderScanCursor);
+                        } finally {
+                            diskOrderScanCursor.close();
+                        }
+                        break;
+                    default:
+                        throw new HyracksDataException("Op " + op.toString() + " not supported.");
+                }
+            } finally {
+                diskOrderScanCursor.destroy();
+            }
+        } finally {
+            searchCursor.destroy();
         }
     }
 

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/4ff6a36d/hyracks-fullstack/pom.xml
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/pom.xml b/hyracks-fullstack/pom.xml
index 339372e..7b5fd6b 100644
--- a/hyracks-fullstack/pom.xml
+++ b/hyracks-fullstack/pom.xml
@@ -16,8 +16,8 @@
  ! specific language governing permissions and limitations
  ! under the License.
  !-->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <groupId>org.apache.hyracks</groupId>
   <artifactId>apache-hyracks</artifactId>
@@ -25,14 +25,12 @@
   <packaging>pom</packaging>
   <name>hyracks-ecosystem-full-stack</name>
   <url>https://asterixdb.apache.org/</url>
-
   <parent>
     <groupId>org.apache</groupId>
     <artifactId>apache</artifactId>
     <version>18</version>
     <relativePath />
   </parent>
-
   <licenses>
     <license>
       <name>Apache License, Version 2.0</name>
@@ -41,14 +39,12 @@
       <comments>A business-friendly OSS license</comments>
     </license>
   </licenses>
-
   <scm>
     <connection>scm:git:https://github.com/apache/asterixdb</connection>
     <developerConnection>scm:git:ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb</developerConnection>
     <url>https://github.com/apache/asterixdb</url>
     <tag>HEAD</tag>
   </scm>
-
   <properties>
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     <file.encoding>UTF-8</file.encoding>
@@ -196,9 +192,13 @@
         <artifactId>log4j-core</artifactId>
         <version>2.10.0</version>
       </dependency>
+      <dependency>
+        <groupId>org.mockito</groupId>
+        <artifactId>mockito-all</artifactId>
+        <version>2.0.2-beta</version>
+      </dependency>
     </dependencies>
   </dependencyManagement>
-
   <build>
     <plugins>
       <plugin>
@@ -241,10 +241,10 @@
           <addDefaultLicenseMatchers>false</addDefaultLicenseMatchers>
           <consoleOutput>true</consoleOutput>
           <licenses>
-            <license implementation="org.apache.rat.analysis.license.ApacheSoftwareLicense20"/>
+            <license implementation="org.apache.rat.analysis.license.ApacheSoftwareLicense20"
/>
           </licenses>
           <licenseFamilies>
-            <licenseFamily implementation="org.apache.rat.license.Apache20LicenseFamily"/>
+            <licenseFamily implementation="org.apache.rat.license.Apache20LicenseFamily"
/>
           </licenseFamilies>
           <excludeSubProjects>true</excludeSubProjects>
           <excludes combine.children="append">
@@ -259,11 +259,8 @@
           <failIfNoTests>false</failIfNoTests>
           <forkCount>1</forkCount>
           <reuseForks>false</reuseForks>
-          <argLine>-enableassertions -Xmx2048m
-            -Dfile.encoding=UTF-8
-            -Xdebug
-            -Xrunjdwp:transport=dt_socket,server=y,address=8000,suspend=n
-            ${coverageArgLine}
+          <argLine>-enableassertions -Xmx2048m -Dfile.encoding=UTF-8 -Xdebug
+            -Xrunjdwp:transport=dt_socket,server=y,address=8000,suspend=n ${coverageArgLine}

           </argLine>
           <systemPropertyVariables>
             <log4j.configurationFile>${testLog4jConfigFile}</log4j.configurationFile>
@@ -458,16 +455,16 @@
                 </pluginExecution>
                 <pluginExecution>
                   <pluginExecutionFilter>
-                   <groupId>net.revelc.code.formatter</groupId>
-                   <artifactId>formatter-maven-plugin</artifactId>
-                   <versionRange>[2.0.1,)</versionRange>
-                   <goals>
-                       <goal>format</goal>
-                   </goals>
-                   </pluginExecutionFilter>
-                   <action>
-                       <ignore></ignore>
-                   </action>
+                    <groupId>net.revelc.code.formatter</groupId>
+                    <artifactId>formatter-maven-plugin</artifactId>
+                    <versionRange>[2.0.1,)</versionRange>
+                    <goals>
+                      <goal>format</goal>
+                    </goals>
+                  </pluginExecutionFilter>
+                  <action>
+                    <ignore></ignore>
+                  </action>
                 </pluginExecution>
               </pluginExecutions>
             </lifecycleMappingMetadata>
@@ -541,7 +538,6 @@
       </plugins>
     </pluginManagement>
   </build>
-
   <profiles>
     <profile>
       <id>skip-assembly</id>
@@ -668,11 +664,9 @@
       </properties>
     </profile>
   </profiles>
-
   <modules>
     <module>hyracks</module>
     <module>algebricks</module>
     <module>hyracks-fullstack-license</module>
   </modules>
-
-</project>
+</project>
\ No newline at end of file


Mime
View raw message