You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tsfile.apache.org by ji...@apache.org on 2026/07/30 08:57:16 UTC
(tsfile) 01/01: add range test interface
This is an automated email from the ASF dual-hosted git repository.
jt2594838 pushed a commit to branch add_bitmap_interface
in repository https://gitbox.apache.org/repos/asf/tsfile.git
commit 3dacbaa4552f8bf028e6bbe3227bb090f891788f
Author: Tian Jiang <jt...@163.com>
AuthorDate: Thu Jul 30 16:48:18 2026 +0800
add range test interface
---
.../main/java/org/apache/tsfile/utils/BitMap.java | 29 ++++++++++++++++
.../java/org/apache/tsfile/utils/BitMapImpl.java | 35 +++++++++++++++++++
.../java/org/apache/tsfile/utils/BitMapTest.java | 40 ++++++++++++++++++++++
3 files changed, 104 insertions(+)
diff --git a/java/common/src/main/java/org/apache/tsfile/utils/BitMap.java b/java/common/src/main/java/org/apache/tsfile/utils/BitMap.java
index 629cda9c0..337bec90f 100644
--- a/java/common/src/main/java/org/apache/tsfile/utils/BitMap.java
+++ b/java/common/src/main/java/org/apache/tsfile/utils/BitMap.java
@@ -54,6 +54,35 @@ public class BitMap implements Accountable {
return implementation.isMarked(position);
}
+ /**
+ * Returns whether at least one bit in the specified range is marked. An empty range returns
+ * {@code false}.
+ *
+ * @throws IndexOutOfBoundsException if the range is outside this bitmap
+ */
+ public boolean isRangeAnyMarked(int start, int length) {
+ return implementation.isRangeAnyMarked(start, length);
+ }
+
+ /**
+ * Returns whether every bit in the specified range is marked. An empty range returns {@code
+ * true}.
+ *
+ * @throws IndexOutOfBoundsException if the range is outside this bitmap
+ */
+ public boolean isRangeAllMarked(int start, int length) {
+ return implementation.isRangeAllMarked(start, length);
+ }
+
+ /**
+ * Returns whether no bit in the specified range is marked. An empty range returns {@code true}.
+ *
+ * @throws IndexOutOfBoundsException if the range is outside this bitmap
+ */
+ public boolean isRangeNoneMarked(int start, int length) {
+ return implementation.isRangeNoneMarked(start, length);
+ }
+
/** mark as 1 at all positions. */
public void markAll() {
implementation.markAll();
diff --git a/java/common/src/main/java/org/apache/tsfile/utils/BitMapImpl.java b/java/common/src/main/java/org/apache/tsfile/utils/BitMapImpl.java
index d9f296fe2..801e67cc8 100644
--- a/java/common/src/main/java/org/apache/tsfile/utils/BitMapImpl.java
+++ b/java/common/src/main/java/org/apache/tsfile/utils/BitMapImpl.java
@@ -19,6 +19,8 @@
package org.apache.tsfile.utils;
+import org.apache.tsfile.i18n.Messages;
+
abstract class BitMapImpl {
protected int size;
@@ -39,6 +41,32 @@ abstract class BitMapImpl {
abstract boolean isMarked(int position);
+ boolean isRangeAnyMarked(int start, int length) {
+ checkRange(start, length);
+ for (int offset = 0; offset < length; offset += Long.SIZE) {
+ int batchSize = Math.min(length - offset, Long.SIZE);
+ if (extractBits(start + offset, batchSize) != 0L) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ boolean isRangeAllMarked(int start, int length) {
+ checkRange(start, length);
+ for (int offset = 0; offset < length; offset += Long.SIZE) {
+ int batchSize = Math.min(length - offset, Long.SIZE);
+ if (extractBits(start + offset, batchSize) != BitMapLongImpl.lowerBitsMask(batchSize)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ boolean isRangeNoneMarked(int start, int length) {
+ return !isRangeAnyMarked(start, length);
+ }
+
abstract void markAll();
abstract void mark(int position);
@@ -102,4 +130,11 @@ abstract class BitMapImpl {
abstract BitMapImpl extend(int newSize);
abstract long getRetainedSizeInBytes();
+
+ private void checkRange(int start, int length) {
+ if (start < 0 || length < 0 || start > size - length) {
+ throw new IndexOutOfBoundsException(
+ Messages.format("error.common.bitmap_start_length_out_of_range", start, length, size));
+ }
+ }
}
diff --git a/java/tsfile/src/test/java/org/apache/tsfile/utils/BitMapTest.java b/java/tsfile/src/test/java/org/apache/tsfile/utils/BitMapTest.java
index e4b59e452..ef73614ad 100644
--- a/java/tsfile/src/test/java/org/apache/tsfile/utils/BitMapTest.java
+++ b/java/tsfile/src/test/java/org/apache/tsfile/utils/BitMapTest.java
@@ -27,6 +27,7 @@ import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
public class BitMapTest {
@@ -217,6 +218,45 @@ public class BitMapTest {
assertFalse(bitMap.isAllUnmarked(10));
}
+ @Test
+ public void testRangeMarkedQueries() {
+ assertRangeMarkedQueries(new BitMap(0));
+ assertRangeMarkedQueries(new BitMap(64));
+ assertRangeMarkedQueries(BitMap.createBitMapDynamically(64));
+ assertRangeMarkedQueries(new BitMap(100));
+ }
+
+ private void assertRangeMarkedQueries(BitMap bitMap) {
+ for (int i = 0; i < bitMap.getSize(); i++) {
+ if (i % 4 != 2) {
+ bitMap.mark(i);
+ }
+ }
+
+ for (int start = 0; start <= bitMap.getSize(); start++) {
+ for (int length = 0; length <= bitMap.getSize() - start; length++) {
+ boolean anyMarked = false;
+ boolean allMarked = true;
+ for (int i = start; i < start + length; i++) {
+ anyMarked |= bitMap.isMarked(i);
+ allMarked &= bitMap.isMarked(i);
+ }
+ assertEquals(anyMarked, bitMap.isRangeAnyMarked(start, length));
+ assertEquals(allMarked, bitMap.isRangeAllMarked(start, length));
+ assertEquals(!anyMarked, bitMap.isRangeNoneMarked(start, length));
+ }
+ }
+
+ assertThrows(IndexOutOfBoundsException.class, () -> bitMap.isRangeAnyMarked(-1, 0));
+ assertThrows(IndexOutOfBoundsException.class, () -> bitMap.isRangeAllMarked(0, -1));
+ assertThrows(
+ IndexOutOfBoundsException.class, () -> bitMap.isRangeNoneMarked(bitMap.getSize() + 1, 0));
+ assertThrows(
+ IndexOutOfBoundsException.class, () -> bitMap.isRangeAnyMarked(bitMap.getSize(), 1));
+ assertThrows(
+ IndexOutOfBoundsException.class, () -> bitMap.isRangeAllMarked(1, Integer.MAX_VALUE));
+ }
+
@Test
public void testGetTruncatedByteArray() {
BitMap bitMap = new BitMap(16);