Fix for ASTERIXDB-1879

The issue was the filter was not persisted correctly for a number
of reasons.

Change-Id: I63734838235e86ee9f0127663f73f65444c423bb
Reviewed-on: https://asterix-gerrit.ics.uci.edu/1672
Sonar-Qube: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
BAD: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Jianfeng Jia <jianfeng.jia@gmail.com>
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/frames/LSMComponentFilterReference.java b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/frames/LSMComponentFilterReference.java
index f04cbb0..dd77bf5 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/frames/LSMComponentFilterReference.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/frames/LSMComponentFilterReference.java
@@ -103,13 +103,14 @@
             }
             binaryFilter.setSize(binarySize);
             byte[] buf = binaryFilter.getByteArray();
-            BooleanPointable.setBoolean(buf, MIN_SET_INDICATOR_OFFSET, min.getLength() == 0);
-            BooleanPointable.setBoolean(buf, MAX_SET_INDICATOR_OFFSET, max.getLength() == 0);
+            BooleanPointable.setBoolean(buf, MIN_SET_INDICATOR_OFFSET, min.getLength() > 0);
+            BooleanPointable.setBoolean(buf, MAX_SET_INDICATOR_OFFSET, max.getLength() > 0);
             int offset = 2;
             if (min.getLength() > 0) {
                 IntegerPointable.setInteger(buf, offset, min.getLength());
                 offset += Integer.BYTES;
                 System.arraycopy(min.getByteArray(), 0, buf, offset, min.getLength());
+                offset += min.getLength();
             }
             if (max.getLength() > 0) {
                 IntegerPointable.setInteger(buf, offset, max.getLength());
@@ -127,6 +128,9 @@
 
     @Override
     public int getLength() {
+        if (binaryFilter.getLength() <= 0 && (isMinTupleSet() || isMaxTupleSet())) {
+            getByteArray();
+        }
         return binaryFilter.getLength();
     }
 
diff --git a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-common-test/pom.xml b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-common-test/pom.xml
index 0530394..97f93f7 100644
--- a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-common-test/pom.xml
+++ b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-common-test/pom.xml
@@ -75,6 +75,16 @@
       <version>${project.version}</version>
     </dependency>
     <dependency>
+      <groupId>org.apache.hyracks</groupId>
+      <artifactId>hyracks-dataflow-common</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hyracks</groupId>
+      <artifactId>hyracks-data-std</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
     </dependency>
diff --git a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-common-test/src/test/java/org/apache/hyracks/storage/am/lsm/common/LSMComponentFilterReferenceTest.java b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-common-test/src/test/java/org/apache/hyracks/storage/am/lsm/common/LSMComponentFilterReferenceTest.java
new file mode 100644
index 0000000..fcc0a48
--- /dev/null
+++ b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-common-test/src/test/java/org/apache/hyracks/storage/am/lsm/common/LSMComponentFilterReferenceTest.java
@@ -0,0 +1,63 @@
+/*
+ * 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.common;
+
+import java.nio.ByteBuffer;
+
+import org.apache.hyracks.api.dataflow.value.ISerializerDeserializer;
+import org.apache.hyracks.api.dataflow.value.ITypeTraits;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.data.std.primitive.IntegerPointable;
+import org.apache.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;
+import org.apache.hyracks.dataflow.common.utils.TupleUtils;
+import org.apache.hyracks.storage.am.common.tuples.TypeAwareTupleWriter;
+import org.apache.hyracks.storage.am.lsm.common.frames.LSMComponentFilterReference;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class LSMComponentFilterReferenceTest {
+
+    @Test
+    public void test() throws HyracksDataException {
+        LSMComponentFilterReference filter = new LSMComponentFilterReference(
+                new TypeAwareTupleWriter(new ITypeTraits[] { IntegerPointable.TYPE_TRAITS }));
+        Assert.assertEquals(filter.getLength(), 0);
+        Assert.assertFalse(filter.isMaxTupleSet() || filter.isMinTupleSet());
+        filter.writeMaxTuple(TupleUtils.createIntegerTuple(Integer.MAX_VALUE));
+        Assert.assertFalse(filter.isMinTupleSet());
+        Assert.assertTrue(filter.isMaxTupleSet());
+        Assert.assertTrue(filter.getLength() == 11);
+        filter.writeMinTuple(TupleUtils.createIntegerTuple(Integer.MIN_VALUE));
+        Assert.assertTrue(filter.isMinTupleSet() && filter.isMaxTupleSet());
+        Assert.assertTrue(filter.getLength() == 20);
+        byte[] serFilter = filter.getByteArray();
+        LSMComponentFilterReference deserFilter = new LSMComponentFilterReference(
+                new TypeAwareTupleWriter((new ITypeTraits[] { IntegerPointable.TYPE_TRAITS })));
+        deserFilter.set(serFilter,0,20);
+        Assert.assertTrue(deserFilter.isMaxTupleSet() && deserFilter.isMinTupleSet());
+        Assert.assertEquals(
+                TupleUtils.deserializeTuple(deserFilter.getMinTuple(),
+                        new ISerializerDeserializer[] { IntegerSerializerDeserializer.INSTANCE })[0],
+                Integer.MIN_VALUE);
+        Assert.assertEquals(
+                TupleUtils.deserializeTuple(deserFilter.getMaxTuple(),
+                        new ISerializerDeserializer[] { IntegerSerializerDeserializer.INSTANCE })[0],
+                Integer.MAX_VALUE);
+    }
+}