This is an automated email from the ASF dual-hosted git repository.

jackietien pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/tsfile.git


The following commit(s) were added to refs/heads/develop by this push:
     new ae3e8c8c Implement extract value filters
ae3e8c8c is described below

commit ae3e8c8c680d2bed16c3e206a392871c13ace902
Author: Weihao Li <[email protected]>
AuthorDate: Tue Jul 22 17:06:54 2025 +0800

    Implement extract value filters
---
 .../apache/tsfile/read/filter/basic/Filter.java    |  13 +
 .../tsfile/read/filter/basic/OperatorType.java     |   8 +-
 .../tsfile/read/filter/basic/TimeFilter.java       |   2 +-
 .../tsfile/read/filter/factory/ValueFilterApi.java |  64 ++++
 .../operator/ExtractTimeFilterOperators.java       |  16 +
 .../operator/ExtractValueFilterOperators.java      | 341 +++++++++++++++++++++
 .../tsfile/read/filter/ExtractValueFilterTest.java | 116 +++++++
 7 files changed, 558 insertions(+), 2 deletions(-)

diff --git 
a/java/tsfile/src/main/java/org/apache/tsfile/read/filter/basic/Filter.java 
b/java/tsfile/src/main/java/org/apache/tsfile/read/filter/basic/Filter.java
index db5276e8..00801fd0 100755
--- a/java/tsfile/src/main/java/org/apache/tsfile/read/filter/basic/Filter.java
+++ b/java/tsfile/src/main/java/org/apache/tsfile/read/filter/basic/Filter.java
@@ -27,6 +27,7 @@ import org.apache.tsfile.read.filter.factory.TimeFilterApi;
 import org.apache.tsfile.read.filter.factory.ValueFilterApi;
 import org.apache.tsfile.read.filter.operator.And;
 import org.apache.tsfile.read.filter.operator.ExtractTimeFilterOperators;
+import org.apache.tsfile.read.filter.operator.ExtractValueFilterOperators;
 import org.apache.tsfile.read.filter.operator.GroupByFilter;
 import org.apache.tsfile.read.filter.operator.GroupByMonthFilter;
 import org.apache.tsfile.read.filter.operator.Not;
@@ -258,6 +259,18 @@ public abstract class Filter {
         return new ExtractTimeFilterOperators.ExtractTimeLt(buffer);
       case EXTRACT_TIME_LTEQ:
         return new ExtractTimeFilterOperators.ExtractTimeLtEq(buffer);
+      case EXTRACT_VALUE_EQ:
+        return new ExtractValueFilterOperators.ExtractValueEq(buffer);
+      case EXTRACT_VALUE_NEQ:
+        return new ExtractValueFilterOperators.ExtractValueNotEq(buffer);
+      case EXTRACT_VALUE_GT:
+        return new ExtractValueFilterOperators.ExtractValueGt(buffer);
+      case EXTRACT_VALUE_GTEQ:
+        return new ExtractValueFilterOperators.ExtractValueGtEq(buffer);
+      case EXTRACT_VALUE_LT:
+        return new ExtractValueFilterOperators.ExtractValueLt(buffer);
+      case EXTRACT_VALUE_LTEQ:
+        return new ExtractValueFilterOperators.ExtractValueLtEq(buffer);
       default:
         throw new UnsupportedOperationException("Unsupported operator type:" + 
type);
     }
diff --git 
a/java/tsfile/src/main/java/org/apache/tsfile/read/filter/basic/OperatorType.java
 
b/java/tsfile/src/main/java/org/apache/tsfile/read/filter/basic/OperatorType.java
index bad1ce76..d898e009 100644
--- 
a/java/tsfile/src/main/java/org/apache/tsfile/read/filter/basic/OperatorType.java
+++ 
b/java/tsfile/src/main/java/org/apache/tsfile/read/filter/basic/OperatorType.java
@@ -73,7 +73,13 @@ public enum OperatorType {
   EXTRACT_TIME_GT(">"),
   EXTRACT_TIME_GTEQ(">="),
   EXTRACT_TIME_LT("<"),
-  EXTRACT_TIME_LTEQ("<=");
+  EXTRACT_TIME_LTEQ("<="),
+  EXTRACT_VALUE_EQ("="),
+  EXTRACT_VALUE_NEQ("!="),
+  EXTRACT_VALUE_GT(">"),
+  EXTRACT_VALUE_GTEQ(">="),
+  EXTRACT_VALUE_LT("<"),
+  EXTRACT_VALUE_LTEQ("<=");
 
   private final String symbol;
 
diff --git 
a/java/tsfile/src/main/java/org/apache/tsfile/read/filter/basic/TimeFilter.java 
b/java/tsfile/src/main/java/org/apache/tsfile/read/filter/basic/TimeFilter.java
index 18d444d7..f1789b4b 100644
--- 
a/java/tsfile/src/main/java/org/apache/tsfile/read/filter/basic/TimeFilter.java
+++ 
b/java/tsfile/src/main/java/org/apache/tsfile/read/filter/basic/TimeFilter.java
@@ -137,7 +137,7 @@ public abstract class TimeFilter extends Filter {
     return satisfyInfo;
   }
 
-  protected abstract boolean timeSatisfy(long time);
+  public abstract boolean timeSatisfy(long time);
 
   @Override
   public boolean canSkip(IMetadata metadata) {
diff --git 
a/java/tsfile/src/main/java/org/apache/tsfile/read/filter/factory/ValueFilterApi.java
 
b/java/tsfile/src/main/java/org/apache/tsfile/read/filter/factory/ValueFilterApi.java
index 53c4b74c..6ccec7ec 100644
--- 
a/java/tsfile/src/main/java/org/apache/tsfile/read/filter/factory/ValueFilterApi.java
+++ 
b/java/tsfile/src/main/java/org/apache/tsfile/read/filter/factory/ValueFilterApi.java
@@ -25,6 +25,8 @@ import org.apache.tsfile.read.filter.basic.Filter;
 import org.apache.tsfile.read.filter.operator.BinaryFilterOperators;
 import org.apache.tsfile.read.filter.operator.BooleanFilterOperators;
 import org.apache.tsfile.read.filter.operator.DoubleFilterOperators;
+import org.apache.tsfile.read.filter.operator.ExtractTimeFilterOperators;
+import org.apache.tsfile.read.filter.operator.ExtractValueFilterOperators;
 import org.apache.tsfile.read.filter.operator.FloatFilterOperators;
 import org.apache.tsfile.read.filter.operator.IntegerFilterOperators;
 import org.apache.tsfile.read.filter.operator.LongFilterOperators;
@@ -33,8 +35,10 @@ import 
org.apache.tsfile.read.filter.operator.ValueIsNotNullOperator;
 import org.apache.tsfile.read.filter.operator.ValueIsNullOperator;
 import org.apache.tsfile.utils.Binary;
 
+import java.time.ZoneId;
 import java.util.Objects;
 import java.util.Set;
+import java.util.concurrent.TimeUnit;
 import java.util.regex.Pattern;
 
 public class ValueFilterApi {
@@ -435,4 +439,64 @@ public class ValueFilterApi {
         throw new UnsupportedOperationException("Unsupported data type: " + 
type);
     }
   }
+
+  public static Filter extractValueGt(
+      int measurementIndex,
+      long value,
+      ExtractTimeFilterOperators.Field field,
+      ZoneId zoneId,
+      TimeUnit currPrecision) {
+    return new ExtractValueFilterOperators.ExtractValueGt(
+        measurementIndex, value, field, zoneId, currPrecision);
+  }
+
+  public static Filter extractValueGtEq(
+      int measurementIndex,
+      long value,
+      ExtractTimeFilterOperators.Field field,
+      ZoneId zoneId,
+      TimeUnit currPrecision) {
+    return new ExtractValueFilterOperators.ExtractValueGtEq(
+        measurementIndex, value, field, zoneId, currPrecision);
+  }
+
+  public static Filter extractValueLt(
+      int measurementIndex,
+      long value,
+      ExtractTimeFilterOperators.Field field,
+      ZoneId zoneId,
+      TimeUnit currPrecision) {
+    return new ExtractValueFilterOperators.ExtractValueLt(
+        measurementIndex, value, field, zoneId, currPrecision);
+  }
+
+  public static Filter extractValueLtEq(
+      int measurementIndex,
+      long value,
+      ExtractTimeFilterOperators.Field field,
+      ZoneId zoneId,
+      TimeUnit currPrecision) {
+    return new ExtractValueFilterOperators.ExtractValueLtEq(
+        measurementIndex, value, field, zoneId, currPrecision);
+  }
+
+  public static Filter extractValueEq(
+      int measurementIndex,
+      long value,
+      ExtractTimeFilterOperators.Field field,
+      ZoneId zoneId,
+      TimeUnit currPrecision) {
+    return new ExtractValueFilterOperators.ExtractValueEq(
+        measurementIndex, value, field, zoneId, currPrecision);
+  }
+
+  public static Filter extractValueNotEq(
+      int measurementIndex,
+      long value,
+      ExtractTimeFilterOperators.Field field,
+      ZoneId zoneId,
+      TimeUnit currPrecision) {
+    return new ExtractValueFilterOperators.ExtractValueNotEq(
+        measurementIndex, value, field, zoneId, currPrecision);
+  }
 }
diff --git 
a/java/tsfile/src/main/java/org/apache/tsfile/read/filter/operator/ExtractTimeFilterOperators.java
 
b/java/tsfile/src/main/java/org/apache/tsfile/read/filter/operator/ExtractTimeFilterOperators.java
index 8c43d1bf..3c93af5a 100644
--- 
a/java/tsfile/src/main/java/org/apache/tsfile/read/filter/operator/ExtractTimeFilterOperators.java
+++ 
b/java/tsfile/src/main/java/org/apache/tsfile/read/filter/operator/ExtractTimeFilterOperators.java
@@ -280,6 +280,22 @@ public final class ExtractTimeFilterOperators {
           TimeUnit.values()[ReadWriteIOUtils.readInt(buffer)]);
     }
 
+    public long getConstant() {
+      return constant;
+    }
+
+    public Field getField() {
+      return field;
+    }
+
+    public TimeUnit getCurrPrecision() {
+      return currPrecision;
+    }
+
+    public ZoneId getZoneId() {
+      return zoneId;
+    }
+
     @Override
     public void serialize(DataOutputStream outputStream) throws IOException {
       super.serialize(outputStream);
diff --git 
a/java/tsfile/src/main/java/org/apache/tsfile/read/filter/operator/ExtractValueFilterOperators.java
 
b/java/tsfile/src/main/java/org/apache/tsfile/read/filter/operator/ExtractValueFilterOperators.java
new file mode 100644
index 00000000..05a39f0a
--- /dev/null
+++ 
b/java/tsfile/src/main/java/org/apache/tsfile/read/filter/operator/ExtractValueFilterOperators.java
@@ -0,0 +1,341 @@
+/*
+ * 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.tsfile.read.filter.operator;
+
+import org.apache.tsfile.file.metadata.statistics.Statistics;
+import org.apache.tsfile.read.filter.basic.Filter;
+import org.apache.tsfile.read.filter.basic.LongFilter;
+import org.apache.tsfile.read.filter.basic.OperatorType;
+import org.apache.tsfile.utils.ReadWriteIOUtils;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.Serializable;
+import java.nio.ByteBuffer;
+import java.time.ZoneId;
+import java.util.Objects;
+import java.util.concurrent.TimeUnit;
+
+public final class ExtractValueFilterOperators {
+
+  private ExtractValueFilterOperators() {
+    // forbidden construction
+  }
+
+  private static final String EXTRACT_OPERATOR_TO_STRING_FORMAT =
+      "extract %s from measurements[%s] %s %s";
+
+  // The input type of Extract must be INT64
+  abstract static class ExtractValueCompareFilter extends LongFilter {
+
+    protected final ExtractTimeFilterOperators.ExtractTimeCompareFilter 
delegate;
+
+    protected ExtractValueCompareFilter(
+        int measurementIndex, 
ExtractTimeFilterOperators.ExtractTimeCompareFilter delegate) {
+      super(measurementIndex);
+      this.delegate = delegate;
+    }
+
+    @Override
+    public void serialize(DataOutputStream outputStream) throws IOException {
+      super.serialize(outputStream);
+      delegate.serialize(outputStream);
+    }
+
+    @Override
+    public boolean valueSatisfy(Object value) {
+      return valueSatisfy((long) value);
+    }
+
+    @Override
+    public boolean valueSatisfy(long value) {
+      return delegate.timeSatisfy(value);
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public boolean canSkip(Statistics<? extends Serializable> statistics) {
+      if (statistics.isEmpty()) {
+        return false;
+      }
+      // has no intersection
+      return !delegate.satisfyStartEndTime(
+          (Long) statistics.getMinValue(), (Long) statistics.getMaxValue());
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public boolean allSatisfy(Statistics<? extends Serializable> statistics) {
+      if (statistics.isEmpty()) {
+        return false;
+      }
+      // contains all start and end time
+      return delegate.containStartEndTime(
+          (Long) statistics.getMinValue(), (Long) statistics.getMaxValue());
+    }
+
+    @Override
+    public boolean equals(Object o) {
+      if (this == o) {
+        return true;
+      }
+      if (o == null || getClass() != o.getClass()) {
+        return false;
+      }
+      if (!super.equals(o)) {
+        return false;
+      }
+      ExtractTimeFilterOperators.ExtractTimeCompareFilter thatDelegate =
+          ((ExtractValueCompareFilter) o).delegate;
+      return delegate.equals(thatDelegate);
+    }
+
+    @Override
+    public int hashCode() {
+      return Objects.hash(super.hashCode(), delegate);
+    }
+
+    @Override
+    public String toString() {
+      return String.format(
+          EXTRACT_OPERATOR_TO_STRING_FORMAT,
+          delegate.getField(),
+          measurementIndex,
+          getOperatorType().getSymbol(),
+          delegate.getConstant());
+    }
+  }
+
+  public static final class ExtractValueEq extends ExtractValueCompareFilter {
+
+    public ExtractValueEq(
+        int measurementIndex,
+        long constant,
+        ExtractTimeFilterOperators.Field field,
+        ZoneId zoneId,
+        TimeUnit currPrecision) {
+      super(
+          measurementIndex,
+          new ExtractTimeFilterOperators.ExtractTimeEq(constant, field, 
zoneId, currPrecision));
+    }
+
+    public ExtractValueEq(ByteBuffer buffer) {
+      super(
+          ReadWriteIOUtils.readInt(buffer),
+          (ExtractTimeFilterOperators.ExtractTimeCompareFilter)
+              ExtractTimeFilterOperators.ExtractTimeEq.deserialize(buffer));
+    }
+
+    @Override
+    public Filter reverse() {
+      return new ExtractValueNotEq(
+          measurementIndex,
+          delegate.getConstant(),
+          delegate.getField(),
+          delegate.getZoneId(),
+          delegate.getCurrPrecision());
+    }
+
+    @Override
+    public OperatorType getOperatorType() {
+      return OperatorType.EXTRACT_VALUE_EQ;
+    }
+  }
+
+  public static final class ExtractValueNotEq extends 
ExtractValueCompareFilter {
+
+    public ExtractValueNotEq(
+        int measurementIndex,
+        long constant,
+        ExtractTimeFilterOperators.Field field,
+        ZoneId zoneId,
+        TimeUnit currPrecision) {
+      super(
+          measurementIndex,
+          new ExtractTimeFilterOperators.ExtractTimeNotEq(constant, field, 
zoneId, currPrecision));
+    }
+
+    public ExtractValueNotEq(ByteBuffer buffer) {
+      super(
+          ReadWriteIOUtils.readInt(buffer),
+          (ExtractTimeFilterOperators.ExtractTimeCompareFilter)
+              ExtractTimeFilterOperators.ExtractTimeNotEq.deserialize(buffer));
+    }
+
+    @Override
+    public Filter reverse() {
+      return new ExtractValueEq(
+          measurementIndex,
+          delegate.getConstant(),
+          delegate.getField(),
+          delegate.getZoneId(),
+          delegate.getCurrPrecision());
+    }
+
+    @Override
+    public OperatorType getOperatorType() {
+      return OperatorType.EXTRACT_VALUE_NEQ;
+    }
+  }
+
+  public static final class ExtractValueLt extends ExtractValueCompareFilter {
+
+    public ExtractValueLt(
+        int measurementIndex,
+        long constant,
+        ExtractTimeFilterOperators.Field field,
+        ZoneId zoneId,
+        TimeUnit currPrecision) {
+      super(
+          measurementIndex,
+          new ExtractTimeFilterOperators.ExtractTimeLt(constant, field, 
zoneId, currPrecision));
+    }
+
+    public ExtractValueLt(ByteBuffer buffer) {
+      super(
+          ReadWriteIOUtils.readInt(buffer),
+          (ExtractTimeFilterOperators.ExtractTimeCompareFilter)
+              ExtractTimeFilterOperators.ExtractTimeLt.deserialize(buffer));
+    }
+
+    @Override
+    public Filter reverse() {
+      return new ExtractValueGtEq(
+          measurementIndex,
+          delegate.getConstant(),
+          delegate.getField(),
+          delegate.getZoneId(),
+          delegate.getCurrPrecision());
+    }
+
+    @Override
+    public OperatorType getOperatorType() {
+      return OperatorType.EXTRACT_VALUE_LT;
+    }
+  }
+
+  public static final class ExtractValueLtEq extends ExtractValueCompareFilter 
{
+
+    public ExtractValueLtEq(
+        int measurementIndex,
+        long constant,
+        ExtractTimeFilterOperators.Field field,
+        ZoneId zoneId,
+        TimeUnit currPrecision) {
+      super(
+          measurementIndex,
+          new ExtractTimeFilterOperators.ExtractTimeLtEq(constant, field, 
zoneId, currPrecision));
+    }
+
+    public ExtractValueLtEq(ByteBuffer buffer) {
+      super(
+          ReadWriteIOUtils.readInt(buffer),
+          (ExtractTimeFilterOperators.ExtractTimeCompareFilter)
+              ExtractTimeFilterOperators.ExtractTimeLtEq.deserialize(buffer));
+    }
+
+    @Override
+    public Filter reverse() {
+      return new ExtractValueGt(
+          measurementIndex,
+          delegate.getConstant(),
+          delegate.getField(),
+          delegate.getZoneId(),
+          delegate.getCurrPrecision());
+    }
+
+    @Override
+    public OperatorType getOperatorType() {
+      return OperatorType.EXTRACT_VALUE_LTEQ;
+    }
+  }
+
+  public static final class ExtractValueGt extends ExtractValueCompareFilter {
+
+    public ExtractValueGt(
+        int measurementIndex,
+        long constant,
+        ExtractTimeFilterOperators.Field field,
+        ZoneId zoneId,
+        TimeUnit currPrecision) {
+      super(
+          measurementIndex,
+          new ExtractTimeFilterOperators.ExtractTimeGt(constant, field, 
zoneId, currPrecision));
+    }
+
+    public ExtractValueGt(ByteBuffer buffer) {
+      super(
+          ReadWriteIOUtils.readInt(buffer),
+          (ExtractTimeFilterOperators.ExtractTimeCompareFilter)
+              ExtractTimeFilterOperators.ExtractTimeGt.deserialize(buffer));
+    }
+
+    @Override
+    public Filter reverse() {
+      return new ExtractValueLtEq(
+          measurementIndex,
+          delegate.getConstant(),
+          delegate.getField(),
+          delegate.getZoneId(),
+          delegate.getCurrPrecision());
+    }
+
+    @Override
+    public OperatorType getOperatorType() {
+      return OperatorType.EXTRACT_VALUE_GT;
+    }
+  }
+
+  public static final class ExtractValueGtEq extends ExtractValueCompareFilter 
{
+
+    public ExtractValueGtEq(
+        int measurementIndex,
+        long constant,
+        ExtractTimeFilterOperators.Field field,
+        ZoneId zoneId,
+        TimeUnit currPrecision) {
+      super(
+          measurementIndex,
+          new ExtractTimeFilterOperators.ExtractTimeGtEq(constant, field, 
zoneId, currPrecision));
+    }
+
+    public ExtractValueGtEq(ByteBuffer buffer) {
+      super(
+          ReadWriteIOUtils.readInt(buffer),
+          (ExtractTimeFilterOperators.ExtractTimeCompareFilter)
+              ExtractTimeFilterOperators.ExtractTimeGtEq.deserialize(buffer));
+    }
+
+    @Override
+    public Filter reverse() {
+      return new ExtractValueLt(
+          measurementIndex,
+          delegate.getConstant(),
+          delegate.getField(),
+          delegate.getZoneId(),
+          delegate.getCurrPrecision());
+    }
+
+    @Override
+    public OperatorType getOperatorType() {
+      return OperatorType.EXTRACT_VALUE_GTEQ;
+    }
+  }
+}
diff --git 
a/java/tsfile/src/test/java/org/apache/tsfile/read/filter/ExtractValueFilterTest.java
 
b/java/tsfile/src/test/java/org/apache/tsfile/read/filter/ExtractValueFilterTest.java
new file mode 100644
index 00000000..63cb0b04
--- /dev/null
+++ 
b/java/tsfile/src/test/java/org/apache/tsfile/read/filter/ExtractValueFilterTest.java
@@ -0,0 +1,116 @@
+/*
+ * 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.tsfile.read.filter;
+
+import org.apache.tsfile.file.metadata.IMetadata;
+import org.apache.tsfile.file.metadata.statistics.LongStatistics;
+import org.apache.tsfile.read.filter.basic.ValueFilter;
+import org.apache.tsfile.read.filter.factory.ValueFilterApi;
+import org.apache.tsfile.read.filter.operator.ExtractTimeFilterOperators;
+import org.apache.tsfile.read.filter.operator.ExtractValueFilterOperators;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.time.ZoneId;
+import java.util.concurrent.TimeUnit;
+
+import static org.apache.tsfile.read.filter.FilterTestUtil.newMetadata;
+
+public class ExtractValueFilterTest {
+  private final ZoneId zoneId1 = ZoneId.of("+0000");
+  private final ZoneId zoneId2 = ZoneId.of("+0800");
+
+  private final LongStatistics statistics = new LongStatistics();
+  private final IMetadata metadata = newMetadata(statistics);
+
+  // Test delegate logic is right
+  @Test
+  public void test() {
+    statistics.setEmpty(false);
+    // 2025/07/08 09:18:51 00:00:00+8:00
+    long testTime1 = 1751937531000L;
+    // 2025/07/08 10:18:51 00:00:00+8:00
+    long testTime2 = 1751941131000L;
+
+    // 1751936400000L -> 2025/07/08 09:00:00+8:00
+    // 1751940000000L -> 2025/07/08 10:00:00+8:00
+    ValueFilter extractValueEq1 =
+        new ExtractValueFilterOperators.ExtractValueEq(
+            ValueFilterApi.DEFAULT_MEASUREMENT_INDEX,
+            1,
+            ExtractTimeFilterOperators.Field.HOUR,
+            zoneId1,
+            TimeUnit.MILLISECONDS);
+    Assert.assertTrue(extractValueEq1.satisfy(testTime1, testTime1));
+    Assert.assertFalse(extractValueEq1.satisfy(testTime2, testTime2));
+    statistics.initializeStats(testTime1 - 1, testTime1 + 1, 0, 0, 0);
+    Assert.assertFalse(extractValueEq1.canSkip(metadata));
+    statistics.initializeStats(1751936400000L, 2751936400000L, 0, 0, 0);
+    Assert.assertFalse(extractValueEq1.canSkip(metadata));
+    statistics.initializeStats(1751936400000L - 1, testTime1 + 1, 0, 0, 0);
+    Assert.assertFalse(extractValueEq1.canSkip(metadata));
+    statistics.initializeStats(1751936400000L - 2, 1751936400000L - 1, 0, 0, 
0);
+    Assert.assertTrue(extractValueEq1.canSkip(metadata));
+
+    statistics.initializeStats(1751936400000L, 1751940000000L - 1, 0, 0, 0);
+    Assert.assertTrue(extractValueEq1.allSatisfy(metadata));
+    statistics.initializeStats(testTime1 - 1, testTime1 + 1, 0, 0, 0);
+    Assert.assertTrue(extractValueEq1.allSatisfy(metadata));
+    statistics.initializeStats(1751936400000L - 1, 1751940000000L, 0, 0, 0);
+    Assert.assertFalse(extractValueEq1.allSatisfy(metadata));
+    statistics.initializeStats(1751936400000L - 1, testTime1 + 1, 0, 0, 0);
+    Assert.assertFalse(extractValueEq1.allSatisfy(metadata));
+    statistics.initializeStats(1751936400000L - 2, 1751936400000L - 1, 0, 0, 
0);
+    Assert.assertFalse(extractValueEq1.allSatisfy(metadata));
+    statistics.initializeStats(1751936400000L, 2751936400000L, 0, 0, 0);
+    Assert.assertFalse(extractValueEq1.allSatisfy(metadata));
+
+    ValueFilter extractValueEq2 =
+        new ExtractValueFilterOperators.ExtractValueEq(
+            ValueFilterApi.DEFAULT_MEASUREMENT_INDEX,
+            9,
+            ExtractTimeFilterOperators.Field.HOUR,
+            zoneId2,
+            TimeUnit.MILLISECONDS);
+    Assert.assertTrue(extractValueEq2.satisfy(testTime1, testTime1));
+    Assert.assertFalse(extractValueEq2.satisfy(testTime2, testTime2));
+    statistics.initializeStats(testTime1 - 1, testTime1 + 1, 0, 0, 0);
+    Assert.assertFalse(extractValueEq2.canSkip(metadata));
+    statistics.initializeStats(1751936400000L, 2751936400000L, 0, 0, 0);
+    Assert.assertFalse(extractValueEq2.canSkip(metadata));
+    statistics.initializeStats(1751936400000L - 1, testTime1 + 1, 0, 0, 0);
+    Assert.assertFalse(extractValueEq2.canSkip(metadata));
+    statistics.initializeStats(1751936400000L - 2, 1751936400000L - 1, 0, 0, 
0);
+    Assert.assertTrue(extractValueEq2.canSkip(metadata));
+
+    statistics.initializeStats(1751936400000L, 1751940000000L - 1, 0, 0, 0);
+    Assert.assertTrue(extractValueEq2.allSatisfy(metadata));
+    statistics.initializeStats(testTime1 - 1, testTime1 + 1, 0, 0, 0);
+    Assert.assertTrue(extractValueEq2.allSatisfy(metadata));
+    statistics.initializeStats(1751936400000L - 1, 1751940000000L, 0, 0, 0);
+    Assert.assertFalse(extractValueEq2.allSatisfy(metadata));
+    statistics.initializeStats(1751936400000L - 1, testTime1 + 1, 0, 0, 0);
+    Assert.assertFalse(extractValueEq2.allSatisfy(metadata));
+    statistics.initializeStats(1751936400000L - 2, 1751936400000L - 1, 0, 0, 
0);
+    Assert.assertFalse(extractValueEq2.allSatisfy(metadata));
+    statistics.initializeStats(1751936400000L, 2751936400000L, 0, 0, 0);
+    Assert.assertFalse(extractValueEq2.allSatisfy(metadata));
+  }
+}

Reply via email to