This is an automated email from the ASF dual-hosted git repository.
haonan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/master by this push:
new 5a1b4c0 [IOTDB-1514] Support null in insertTablet (#3995)
5a1b4c0 is described below
commit 5a1b4c0ad2964c92d630af6492f26aede00b0950
Author: Alan Choo <[email protected]>
AuthorDate: Wed Sep 29 11:09:11 2021 +0800
[IOTDB-1514] Support null in insertTablet (#3995)
---
.../main/java/org/apache/iotdb/SessionExample.java | 83 ++++++++++++++++++++
.../iotdb/db/engine/memtable/AbstractMemTable.java | 4 +-
.../apache/iotdb/db/engine/memtable/IMemTable.java | 8 +-
.../db/engine/memtable/IWritableMemChunk.java | 21 ++---
.../iotdb/db/engine/memtable/WritableMemChunk.java | 44 +++++------
.../engine/storagegroup/StorageGroupProcessor.java | 3 +-
.../db/engine/storagegroup/TsFileProcessor.java | 5 +-
.../db/qp/physical/crud/InsertTabletPlan.java | 30 ++++++--
.../iotdb/db/utils/datastructure/BinaryTVList.java | 59 ++++++++++++--
.../db/utils/datastructure/BooleanTVList.java | 59 ++++++++++++--
.../iotdb/db/utils/datastructure/DoubleTVList.java | 59 ++++++++++++--
.../iotdb/db/utils/datastructure/FloatTVList.java | 59 ++++++++++++--
.../iotdb/db/utils/datastructure/IntTVList.java | 59 ++++++++++++--
.../iotdb/db/utils/datastructure/LongTVList.java | 69 ++++++++++++++---
.../iotdb/db/utils/datastructure/TVList.java | 16 ++--
.../iotdb/db/utils/datastructure/VectorTVList.java | 82 ++++++++++++--------
.../iotdb/db/integration/IoTDBSelectIntoIT.java | 2 +-
.../iotdb/db/qp/physical/InsertTabletPlanTest.java | 89 +++++++++++++++++++---
.../db/utils/datastructure/BinaryTVListTest.java | 59 +++++++++++++-
.../db/utils/datastructure/BooleanTVListTest.java | 63 ++++++++++++++-
.../db/utils/datastructure/DoubleTVListTest.java | 63 ++++++++++++++-
.../db/utils/datastructure/FloatTVListTest.java | 63 ++++++++++++++-
.../db/utils/datastructure/IntTVListTest.java | 63 ++++++++++++++-
.../db/utils/datastructure/LongTVListTest.java | 62 ++++++++++++++-
.../db/utils/datastructure/VectorTVListTest.java | 40 +++++++++-
.../apache/iotdb/session/IoTDBSessionSimpleIT.java | 53 +++++++++++++
.../java/org/apache/iotdb/tsfile/utils/BitMap.java | 7 ++
.../apache/iotdb/tsfile/write/record/Tablet.java | 9 ++-
28 files changed, 1093 insertions(+), 140 deletions(-)
diff --git a/example/session/src/main/java/org/apache/iotdb/SessionExample.java
b/example/session/src/main/java/org/apache/iotdb/SessionExample.java
index a043962..32f3f74 100644
--- a/example/session/src/main/java/org/apache/iotdb/SessionExample.java
+++ b/example/session/src/main/java/org/apache/iotdb/SessionExample.java
@@ -28,6 +28,7 @@ import org.apache.iotdb.session.SessionDataSet.DataIterator;
import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
+import org.apache.iotdb.tsfile.utils.BitMap;
import org.apache.iotdb.tsfile.write.record.Tablet;
import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
import org.apache.iotdb.tsfile.write.schema.MeasurementSchema;
@@ -74,6 +75,7 @@ public class SessionExample {
createMultiTimeseries();
insertRecord();
insertTablet();
+ insertTabletWithNullValues();
insertTablets();
insertRecords();
selectInto();
@@ -433,6 +435,87 @@ public class SessionExample {
}
}
+ private static void insertTabletWithNullValues()
+ throws IoTDBConnectionException, StatementExecutionException {
+ /*
+ * A Tablet example:
+ * device1
+ * time s1, s2, s3
+ * 1, null, 1, 1
+ * 2, 2, null, 2
+ * 3, 3, 3, null
+ */
+ // The schema of measurements of one device
+ // only measurementId and data type in MeasurementSchema take effects in
Tablet
+ List<IMeasurementSchema> schemaList = new ArrayList<>();
+ schemaList.add(new MeasurementSchema("s1", TSDataType.INT64));
+ schemaList.add(new MeasurementSchema("s2", TSDataType.INT64));
+ schemaList.add(new MeasurementSchema("s3", TSDataType.INT64));
+
+ Tablet tablet = new Tablet(ROOT_SG1_D1, schemaList, 100);
+
+ // Method 1 to add tablet data
+ tablet.bitMaps = new BitMap[schemaList.size()];
+ for (int s = 0; s < 3; s++) {
+ tablet.bitMaps[s] = new BitMap(tablet.getMaxRowNumber());
+ }
+
+ long timestamp = System.currentTimeMillis();
+ for (long row = 0; row < 100; row++) {
+ int rowIndex = tablet.rowSize++;
+ tablet.addTimestamp(rowIndex, timestamp);
+ for (int s = 0; s < 3; s++) {
+ long value = new Random().nextLong();
+ // mark null value
+ if (row % 3 == s) {
+ tablet.bitMaps[s].mark((int) row);
+ }
+ tablet.addValue(schemaList.get(s).getMeasurementId(), rowIndex, value);
+ }
+ if (tablet.rowSize == tablet.getMaxRowNumber()) {
+ session.insertTablet(tablet, true);
+ tablet.reset();
+ }
+ timestamp++;
+ }
+
+ if (tablet.rowSize != 0) {
+ session.insertTablet(tablet);
+ tablet.reset();
+ }
+
+ // Method 2 to add tablet data
+ long[] timestamps = tablet.timestamps;
+ Object[] values = tablet.values;
+ BitMap[] bitMaps = new BitMap[schemaList.size()];
+ for (int s = 0; s < 3; s++) {
+ bitMaps[s] = new BitMap(tablet.getMaxRowNumber());
+ }
+ tablet.bitMaps = bitMaps;
+
+ for (long time = 0; time < 100; time++) {
+ int row = tablet.rowSize++;
+ timestamps[row] = time;
+ for (int i = 0; i < 3; i++) {
+ long[] sensor = (long[]) values[i];
+ // mark null value
+ if (row % 3 == i) {
+ bitMaps[i].mark(row);
+ }
+ sensor[row] = i;
+ }
+ if (tablet.rowSize == tablet.getMaxRowNumber()) {
+ session.insertTablet(tablet, true);
+ tablet.reset();
+ }
+ }
+
+ if (tablet.rowSize != 0) {
+ session.insertTablet(tablet);
+ tablet.reset();
+ }
+ }
+
private static void insertTablets() throws IoTDBConnectionException,
StatementExecutionException {
// The schema of measurements of one device
// only measurementId and data type in MeasurementSchema take effects in
Tablet
diff --git
a/server/src/main/java/org/apache/iotdb/db/engine/memtable/AbstractMemTable.java
b/server/src/main/java/org/apache/iotdb/db/engine/memtable/AbstractMemTable.java
index 3f05dc9..58501a9 100644
---
a/server/src/main/java/org/apache/iotdb/db/engine/memtable/AbstractMemTable.java
+++
b/server/src/main/java/org/apache/iotdb/db/engine/memtable/AbstractMemTable.java
@@ -220,15 +220,15 @@ public abstract class AbstractMemTable implements
IMemTable {
columnIndex++;
}
memSeries.write(
- insertTabletPlan.getTimes(), bitMaps, columns, TSDataType.VECTOR,
start, end);
+ insertTabletPlan.getTimes(), columns, bitMaps, TSDataType.VECTOR,
start, end);
break;
} else {
memSeries.write(
insertTabletPlan.getTimes(),
+ insertTabletPlan.getColumns()[columnIndex],
insertTabletPlan.getBitMaps() != null
? insertTabletPlan.getBitMaps()[columnIndex]
: null,
- insertTabletPlan.getColumns()[columnIndex],
insertTabletPlan.getDataTypes()[columnIndex],
start,
end);
diff --git
a/server/src/main/java/org/apache/iotdb/db/engine/memtable/IMemTable.java
b/server/src/main/java/org/apache/iotdb/db/engine/memtable/IMemTable.java
index 8cf61dc..e86fc96 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/memtable/IMemTable.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/memtable/IMemTable.java
@@ -46,6 +46,10 @@ public interface IMemTable {
void write(String deviceId, IMeasurementSchema schema, long insertTime,
Object objectValue);
+ /**
+ * write data in the range [start, end). Null value in each column values
will be replaced by the
+ * subsequent non-null value, e.g., {1, null, 3, null, 5} will be {1, 3, 5,
null, 5}
+ */
void write(InsertTabletPlan insertTabletPlan, int start, int end);
/** @return the number of points */
@@ -82,7 +86,9 @@ public interface IMemTable {
void insert(InsertRowPlan insertRowPlan);
/**
- * insert tablet into this memtable
+ * insert tablet into this memtable. The rows to be inserted are in the
range [start, end). Null
+ * value in each column values will be replaced by the subsequent non-null
value, e.g., {1, null,
+ * 3, null, 5} will be {1, 3, 5, null, 5}
*
* @param insertTabletPlan insertTabletPlan
* @param start included
diff --git
a/server/src/main/java/org/apache/iotdb/db/engine/memtable/IWritableMemChunk.java
b/server/src/main/java/org/apache/iotdb/db/engine/memtable/IWritableMemChunk.java
index 6cb896f..b58f3b7 100644
---
a/server/src/main/java/org/apache/iotdb/db/engine/memtable/IWritableMemChunk.java
+++
b/server/src/main/java/org/apache/iotdb/db/engine/memtable/IWritableMemChunk.java
@@ -42,25 +42,28 @@ public interface IWritableMemChunk {
void putVector(long t, Object[] v);
- void putLongs(long[] t, BitMap bitMap, long[] v, int start, int end);
+ void putLongs(long[] t, long[] v, BitMap bitMap, int start, int end);
- void putInts(long[] t, BitMap bitMap, int[] v, int start, int end);
+ void putInts(long[] t, int[] v, BitMap bitMap, int start, int end);
- void putFloats(long[] t, BitMap bitMap, float[] v, int start, int end);
+ void putFloats(long[] t, float[] v, BitMap bitMap, int start, int end);
- void putDoubles(long[] t, BitMap bitMap, double[] v, int start, int end);
+ void putDoubles(long[] t, double[] v, BitMap bitMap, int start, int end);
- void putBinaries(long[] t, BitMap bitMap, Binary[] v, int start, int end);
+ void putBinaries(long[] t, Binary[] v, BitMap bitMap, int start, int end);
- void putBooleans(long[] t, BitMap bitMap, boolean[] v, int start, int end);
+ void putBooleans(long[] t, boolean[] v, BitMap bitMap, int start, int end);
- void putVectors(long[] t, BitMap[] bitMaps, Object[] v, int start, int end);
+ void putVectors(long[] t, Object[] v, BitMap[] bitMaps, int start, int end);
void write(long insertTime, Object objectValue);
- /** [start, end) */
+ /**
+ * write data in the range [start, end). Null value in the valueList will be
replaced by the
+ * subsequent non-null value, e.g., {1, null, 3, null, 5} will be {1, 3, 5,
null, 5}
+ */
void write(
- long[] times, Object bitMaps, Object valueList, TSDataType dataType, int
start, int end);
+ long[] times, Object valueList, Object bitMaps, TSDataType dataType, int
start, int end);
long count();
diff --git
a/server/src/main/java/org/apache/iotdb/db/engine/memtable/WritableMemChunk.java
b/server/src/main/java/org/apache/iotdb/db/engine/memtable/WritableMemChunk.java
index a841486..09b30e8 100644
---
a/server/src/main/java/org/apache/iotdb/db/engine/memtable/WritableMemChunk.java
+++
b/server/src/main/java/org/apache/iotdb/db/engine/memtable/WritableMemChunk.java
@@ -69,35 +69,35 @@ public class WritableMemChunk implements IWritableMemChunk {
@Override
public void write(
- long[] times, Object bitMap, Object valueList, TSDataType dataType, int
start, int end) {
+ long[] times, Object valueList, Object bitMap, TSDataType dataType, int
start, int end) {
switch (dataType) {
case BOOLEAN:
boolean[] boolValues = (boolean[]) valueList;
- putBooleans(times, (BitMap) bitMap, boolValues, start, end);
+ putBooleans(times, boolValues, (BitMap) bitMap, start, end);
break;
case INT32:
int[] intValues = (int[]) valueList;
- putInts(times, (BitMap) bitMap, intValues, start, end);
+ putInts(times, intValues, (BitMap) bitMap, start, end);
break;
case INT64:
long[] longValues = (long[]) valueList;
- putLongs(times, (BitMap) bitMap, longValues, start, end);
+ putLongs(times, longValues, (BitMap) bitMap, start, end);
break;
case FLOAT:
float[] floatValues = (float[]) valueList;
- putFloats(times, (BitMap) bitMap, floatValues, start, end);
+ putFloats(times, floatValues, (BitMap) bitMap, start, end);
break;
case DOUBLE:
double[] doubleValues = (double[]) valueList;
- putDoubles(times, (BitMap) bitMap, doubleValues, start, end);
+ putDoubles(times, doubleValues, (BitMap) bitMap, start, end);
break;
case TEXT:
Binary[] binaryValues = (Binary[]) valueList;
- putBinaries(times, (BitMap) bitMap, binaryValues, start, end);
+ putBinaries(times, binaryValues, (BitMap) bitMap, start, end);
break;
case VECTOR:
Object[] vectorValues = (Object[]) valueList;
- putVectors(times, (BitMap[]) bitMap, vectorValues, start, end);
+ putVectors(times, vectorValues, (BitMap[]) bitMap, start, end);
break;
default:
throw new UnSupportedDataTypeException(UNSUPPORTED_TYPE + dataType);
@@ -140,38 +140,38 @@ public class WritableMemChunk implements
IWritableMemChunk {
}
@Override
- public void putLongs(long[] t, BitMap bitMap, long[] v, int start, int end) {
- list.putLongs(t, v, start, end);
+ public void putLongs(long[] t, long[] v, BitMap bitMap, int start, int end) {
+ list.putLongs(t, v, bitMap, start, end);
}
@Override
- public void putInts(long[] t, BitMap bitMap, int[] v, int start, int end) {
- list.putInts(t, v, start, end);
+ public void putInts(long[] t, int[] v, BitMap bitMap, int start, int end) {
+ list.putInts(t, v, bitMap, start, end);
}
@Override
- public void putFloats(long[] t, BitMap bitMap, float[] v, int start, int
end) {
- list.putFloats(t, v, start, end);
+ public void putFloats(long[] t, float[] v, BitMap bitMap, int start, int
end) {
+ list.putFloats(t, v, bitMap, start, end);
}
@Override
- public void putDoubles(long[] t, BitMap bitMap, double[] v, int start, int
end) {
- list.putDoubles(t, v, start, end);
+ public void putDoubles(long[] t, double[] v, BitMap bitMap, int start, int
end) {
+ list.putDoubles(t, v, bitMap, start, end);
}
@Override
- public void putBinaries(long[] t, BitMap bitMap, Binary[] v, int start, int
end) {
- list.putBinaries(t, v, start, end);
+ public void putBinaries(long[] t, Binary[] v, BitMap bitMap, int start, int
end) {
+ list.putBinaries(t, v, bitMap, start, end);
}
@Override
- public void putBooleans(long[] t, BitMap bitMap, boolean[] v, int start, int
end) {
- list.putBooleans(t, v, start, end);
+ public void putBooleans(long[] t, boolean[] v, BitMap bitMap, int start, int
end) {
+ list.putBooleans(t, v, bitMap, start, end);
}
@Override
- public void putVectors(long[] t, BitMap[] bitMaps, Object[] v, int start,
int end) {
- list.putVectors(t, bitMaps, v, start, end);
+ public void putVectors(long[] t, Object[] v, BitMap[] bitMaps, int start,
int end) {
+ list.putVectors(t, v, bitMaps, start, end);
}
@Override
diff --git
a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/StorageGroupProcessor.java
b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/StorageGroupProcessor.java
index 717a971..8e92a26 100755
---
a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/StorageGroupProcessor.java
+++
b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/StorageGroupProcessor.java
@@ -1020,7 +1020,8 @@ public class StorageGroupProcessor {
/**
* insert batch to tsfile processor thread-safety that the caller need to
guarantee The rows to be
- * inserted are in the range [start, end)
+ * inserted are in the range [start, end) Null value in each column values
will be replaced by the
+ * subsequent non-null value, e.g., {1, null, 3, null, 5} will be {1, 3, 5,
null, 5}
*
* @param insertTabletPlan insert a tablet of a device
* @param sequence whether is sequence
diff --git
a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/TsFileProcessor.java
b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/TsFileProcessor.java
index c00a245..ec71755 100644
---
a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/TsFileProcessor.java
+++
b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/TsFileProcessor.java
@@ -247,8 +247,9 @@ public class TsFileProcessor {
}
/**
- * insert batch data of insertTabletPlan into the workingMemtable The rows
to be inserted are in
- * the range [start, end)
+ * insert batch data of insertTabletPlan into the workingMemtable. The rows
to be inserted are in
+ * the range [start, end). Null value in each column values will be replaced
by the subsequent
+ * non-null value, e.g., {1, null, 3, null, 5} will be {1, 3, 5, null, 5}
*
* @param insertTabletPlan insert a tablet of a device
* @param start start index of rows to be inserted in insertTabletPlan
diff --git
a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertTabletPlan.java
b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertTabletPlan.java
index 75e3aef..6a5b3dc 100644
---
a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertTabletPlan.java
+++
b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertTabletPlan.java
@@ -534,37 +534,53 @@ public class InsertTabletPlan extends InsertPlan {
if (measurementIndex >= columns.length) {
return null;
}
+
+ // get non-null value
+ int lastIdx = rowCount - 1;
+ if (bitMaps != null && bitMaps[measurementIndex] != null) {
+ BitMap bitMap = bitMaps[measurementIndex];
+ while (lastIdx >= 0) {
+ if (!bitMap.isMarked(lastIdx)) {
+ break;
+ }
+ lastIdx--;
+ }
+ }
+ if (lastIdx < 0) {
+ return null;
+ }
+
TsPrimitiveType value;
switch (dataTypes[measurementIndex]) {
case INT32:
int[] intValues = (int[]) columns[measurementIndex];
- value = new TsInt(intValues[rowCount - 1]);
+ value = new TsInt(intValues[lastIdx]);
break;
case INT64:
long[] longValues = (long[]) columns[measurementIndex];
- value = new TsLong(longValues[rowCount - 1]);
+ value = new TsLong(longValues[lastIdx]);
break;
case FLOAT:
float[] floatValues = (float[]) columns[measurementIndex];
- value = new TsFloat(floatValues[rowCount - 1]);
+ value = new TsFloat(floatValues[lastIdx]);
break;
case DOUBLE:
double[] doubleValues = (double[]) columns[measurementIndex];
- value = new TsDouble(doubleValues[rowCount - 1]);
+ value = new TsDouble(doubleValues[lastIdx]);
break;
case BOOLEAN:
boolean[] boolValues = (boolean[]) columns[measurementIndex];
- value = new TsBoolean(boolValues[rowCount - 1]);
+ value = new TsBoolean(boolValues[lastIdx]);
break;
case TEXT:
Binary[] binaryValues = (Binary[]) columns[measurementIndex];
- value = new TsBinary(binaryValues[rowCount - 1]);
+ value = new TsBinary(binaryValues[lastIdx]);
break;
default:
throw new UnSupportedDataTypeException(
String.format(DATATYPE_UNSUPPORTED, dataTypes[measurementIndex]));
}
- return new TimeValuePair(times[rowCount - 1], value);
+ return new TimeValuePair(times[lastIdx], value);
}
public long[] getTimes() {
diff --git
a/server/src/main/java/org/apache/iotdb/db/utils/datastructure/BinaryTVList.java
b/server/src/main/java/org/apache/iotdb/db/utils/datastructure/BinaryTVList.java
index bf62d63..136c283 100644
---
a/server/src/main/java/org/apache/iotdb/db/utils/datastructure/BinaryTVList.java
+++
b/server/src/main/java/org/apache/iotdb/db/utils/datastructure/BinaryTVList.java
@@ -23,6 +23,7 @@ import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
import org.apache.iotdb.tsfile.read.TimeValuePair;
import org.apache.iotdb.tsfile.utils.Binary;
+import org.apache.iotdb.tsfile.utils.BitMap;
import org.apache.iotdb.tsfile.utils.TsPrimitiveType;
import java.util.ArrayList;
@@ -32,6 +33,8 @@ import static
org.apache.iotdb.db.rescon.PrimitiveArrayManager.ARRAY_SIZE;
public class BinaryTVList extends TVList {
+ // list of primitive array, add 1 when expanded -> Binary primitive array
+ // index relation: arrayIndex -> elementIndex
private List<Binary[]> values;
private Binary[][] sortedValues;
@@ -194,11 +197,25 @@ public class BinaryTVList extends TVList {
}
@Override
- public void putBinaries(long[] time, Binary[] value, int start, int end) {
+ public void putBinaries(long[] time, Binary[] value, BitMap bitMap, int
start, int end) {
checkExpansion();
- int idx = start;
- updateMinTimeAndSorted(time, start, end);
+ int idx = start;
+ // constraint: time.length + timeIdxOffset == value.length
+ int timeIdxOffset = 0;
+ if (bitMap != null && !bitMap.isAllUnmarked()) {
+ // time array is a reference, should clone necessary time values
+ long[] clonedTime = new long[end - start];
+ System.arraycopy(time, start, clonedTime, 0, end - start);
+ time = clonedTime;
+ timeIdxOffset = start;
+ // drop null at the end of value array
+ int nullCnt =
+ dropNullValThenUpdateMinTimeAndSorted(time, value, bitMap, start,
end, timeIdxOffset);
+ end -= nullCnt;
+ } else {
+ updateMinTimeAndSorted(time, start, end);
+ }
while (idx < end) {
int inputRemaining = end - idx;
@@ -207,14 +224,16 @@ public class BinaryTVList extends TVList {
int internalRemaining = ARRAY_SIZE - elementIdx;
if (internalRemaining >= inputRemaining) {
// the remaining inputs can fit the last array, copy all remaining
inputs into last array
- System.arraycopy(time, idx, timestamps.get(arrayIdx), elementIdx,
inputRemaining);
+ System.arraycopy(
+ time, idx - timeIdxOffset, timestamps.get(arrayIdx), elementIdx,
inputRemaining);
System.arraycopy(value, idx, values.get(arrayIdx), elementIdx,
inputRemaining);
size += inputRemaining;
break;
} else {
// the remaining inputs cannot fit the last array, fill the last array
and create a new
// one and enter the next loop
- System.arraycopy(time, idx, timestamps.get(arrayIdx), elementIdx,
internalRemaining);
+ System.arraycopy(
+ time, idx - timeIdxOffset, timestamps.get(arrayIdx), elementIdx,
internalRemaining);
System.arraycopy(value, idx, values.get(arrayIdx), elementIdx,
internalRemaining);
idx += internalRemaining;
size += internalRemaining;
@@ -223,6 +242,36 @@ public class BinaryTVList extends TVList {
}
}
+ // move null values to the end of time array and value array, then return
number of null values
+ int dropNullValThenUpdateMinTimeAndSorted(
+ long[] time, Binary[] values, BitMap bitMap, int start, int end, int
tIdxOffset) {
+ long inPutMinTime = Long.MAX_VALUE;
+ boolean inputSorted = true;
+
+ int nullCnt = 0;
+ for (int vIdx = start; vIdx < end; vIdx++) {
+ if (bitMap.isMarked(vIdx)) {
+ nullCnt++;
+ continue;
+ }
+ // move value ahead to replace null
+ int tIdx = vIdx - tIdxOffset;
+ if (nullCnt != 0) {
+ time[tIdx - nullCnt] = time[tIdx];
+ values[vIdx - nullCnt] = values[vIdx];
+ }
+ // update minTime and sorted
+ tIdx = tIdx - nullCnt;
+ inPutMinTime = Math.min(inPutMinTime, time[tIdx]);
+ if (inputSorted && tIdx > 0 && time[tIdx - 1] > time[tIdx]) {
+ inputSorted = false;
+ }
+ }
+ minTime = Math.min(inPutMinTime, minTime);
+ sorted = sorted && inputSorted && (size == 0 || inPutMinTime >=
getTime(size - 1));
+ return nullCnt;
+ }
+
@Override
public TSDataType getDataType() {
return TSDataType.TEXT;
diff --git
a/server/src/main/java/org/apache/iotdb/db/utils/datastructure/BooleanTVList.java
b/server/src/main/java/org/apache/iotdb/db/utils/datastructure/BooleanTVList.java
index e293544..f4c9b31 100644
---
a/server/src/main/java/org/apache/iotdb/db/utils/datastructure/BooleanTVList.java
+++
b/server/src/main/java/org/apache/iotdb/db/utils/datastructure/BooleanTVList.java
@@ -22,6 +22,7 @@ import org.apache.iotdb.db.rescon.PrimitiveArrayManager;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
import org.apache.iotdb.tsfile.read.TimeValuePair;
+import org.apache.iotdb.tsfile.utils.BitMap;
import org.apache.iotdb.tsfile.utils.TsPrimitiveType;
import java.util.ArrayList;
@@ -31,6 +32,8 @@ import static
org.apache.iotdb.db.rescon.PrimitiveArrayManager.ARRAY_SIZE;
public class BooleanTVList extends TVList {
+ // list of primitive array, add 1 when expanded -> boolean primitive array
+ // index relation: arrayIndex -> elementIndex
private List<boolean[]> values;
private boolean[][] sortedValues;
@@ -194,11 +197,25 @@ public class BooleanTVList extends TVList {
}
@Override
- public void putBooleans(long[] time, boolean[] value, int start, int end) {
+ public void putBooleans(long[] time, boolean[] value, BitMap bitMap, int
start, int end) {
checkExpansion();
- int idx = start;
- updateMinTimeAndSorted(time, start, end);
+ int idx = start;
+ // constraint: time.length + timeIdxOffset == value.length
+ int timeIdxOffset = 0;
+ if (bitMap != null && !bitMap.isAllUnmarked()) {
+ // time array is a reference, should clone necessary time values
+ long[] clonedTime = new long[end - start];
+ System.arraycopy(time, start, clonedTime, 0, end - start);
+ time = clonedTime;
+ timeIdxOffset = start;
+ // drop null at the end of value array
+ int nullCnt =
+ dropNullValThenUpdateMinTimeAndSorted(time, value, bitMap, start,
end, timeIdxOffset);
+ end -= nullCnt;
+ } else {
+ updateMinTimeAndSorted(time, start, end);
+ }
while (idx < end) {
int inputRemaining = end - idx;
@@ -207,14 +224,16 @@ public class BooleanTVList extends TVList {
int internalRemaining = ARRAY_SIZE - elementIdx;
if (internalRemaining >= inputRemaining) {
// the remaining inputs can fit the last array, copy all remaining
inputs into last array
- System.arraycopy(time, idx, timestamps.get(arrayIdx), elementIdx,
inputRemaining);
+ System.arraycopy(
+ time, idx - timeIdxOffset, timestamps.get(arrayIdx), elementIdx,
inputRemaining);
System.arraycopy(value, idx, values.get(arrayIdx), elementIdx,
inputRemaining);
size += inputRemaining;
break;
} else {
// the remaining inputs cannot fit the last array, fill the last array
and create a new
// one and enter the next loop
- System.arraycopy(time, idx, timestamps.get(arrayIdx), elementIdx,
internalRemaining);
+ System.arraycopy(
+ time, idx - timeIdxOffset, timestamps.get(arrayIdx), elementIdx,
internalRemaining);
System.arraycopy(value, idx, values.get(arrayIdx), elementIdx,
internalRemaining);
idx += internalRemaining;
size += internalRemaining;
@@ -223,6 +242,36 @@ public class BooleanTVList extends TVList {
}
}
+ // move null values to the end of time array and value array, then return
number of null values
+ int dropNullValThenUpdateMinTimeAndSorted(
+ long[] time, boolean[] values, BitMap bitMap, int start, int end, int
tIdxOffset) {
+ long inPutMinTime = Long.MAX_VALUE;
+ boolean inputSorted = true;
+
+ int nullCnt = 0;
+ for (int vIdx = start; vIdx < end; vIdx++) {
+ if (bitMap.isMarked(vIdx)) {
+ nullCnt++;
+ continue;
+ }
+ // move value ahead to replace null
+ int tIdx = vIdx - tIdxOffset;
+ if (nullCnt != 0) {
+ time[tIdx - nullCnt] = time[tIdx];
+ values[vIdx - nullCnt] = values[vIdx];
+ }
+ // update minTime and sorted
+ tIdx = tIdx - nullCnt;
+ inPutMinTime = Math.min(inPutMinTime, time[tIdx]);
+ if (inputSorted && tIdx > 0 && time[tIdx - 1] > time[tIdx]) {
+ inputSorted = false;
+ }
+ }
+ minTime = Math.min(inPutMinTime, minTime);
+ sorted = sorted && inputSorted && (size == 0 || inPutMinTime >=
getTime(size - 1));
+ return nullCnt;
+ }
+
@Override
public TSDataType getDataType() {
return TSDataType.BOOLEAN;
diff --git
a/server/src/main/java/org/apache/iotdb/db/utils/datastructure/DoubleTVList.java
b/server/src/main/java/org/apache/iotdb/db/utils/datastructure/DoubleTVList.java
index d7e8178..6b3fcb8 100644
---
a/server/src/main/java/org/apache/iotdb/db/utils/datastructure/DoubleTVList.java
+++
b/server/src/main/java/org/apache/iotdb/db/utils/datastructure/DoubleTVList.java
@@ -23,6 +23,7 @@ import org.apache.iotdb.db.utils.MathUtils;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
import org.apache.iotdb.tsfile.read.TimeValuePair;
+import org.apache.iotdb.tsfile.utils.BitMap;
import org.apache.iotdb.tsfile.utils.TsPrimitiveType;
import java.util.ArrayList;
@@ -32,6 +33,8 @@ import static
org.apache.iotdb.db.rescon.PrimitiveArrayManager.ARRAY_SIZE;
public class DoubleTVList extends TVList {
+ // list of primitive array, add 1 when expanded -> double primitive array
+ // index relation: arrayIndex -> elementIndex
private List<double[]> values;
private double[][] sortedValues;
@@ -198,11 +201,25 @@ public class DoubleTVList extends TVList {
}
@Override
- public void putDoubles(long[] time, double[] value, int start, int end) {
+ public void putDoubles(long[] time, double[] value, BitMap bitMap, int
start, int end) {
checkExpansion();
- int idx = start;
- updateMinTimeAndSorted(time, start, end);
+ int idx = start;
+ // constraint: time.length + timeIdxOffset == value.length
+ int timeIdxOffset = 0;
+ if (bitMap != null && !bitMap.isAllUnmarked()) {
+ // time array is a reference, should clone necessary time values
+ long[] clonedTime = new long[end - start];
+ System.arraycopy(time, start, clonedTime, 0, end - start);
+ time = clonedTime;
+ timeIdxOffset = start;
+ // drop null at the end of value array
+ int nullCnt =
+ dropNullValThenUpdateMinTimeAndSorted(time, value, bitMap, start,
end, timeIdxOffset);
+ end -= nullCnt;
+ } else {
+ updateMinTimeAndSorted(time, start, end);
+ }
while (idx < end) {
int inputRemaining = end - idx;
@@ -211,14 +228,16 @@ public class DoubleTVList extends TVList {
int internalRemaining = ARRAY_SIZE - elementIdx;
if (internalRemaining >= inputRemaining) {
// the remaining inputs can fit the last array, copy all remaining
inputs into last array
- System.arraycopy(time, idx, timestamps.get(arrayIdx), elementIdx,
inputRemaining);
+ System.arraycopy(
+ time, idx - timeIdxOffset, timestamps.get(arrayIdx), elementIdx,
inputRemaining);
System.arraycopy(value, idx, values.get(arrayIdx), elementIdx,
inputRemaining);
size += inputRemaining;
break;
} else {
// the remaining inputs cannot fit the last array, fill the last array
and create a new
// one and enter the next loop
- System.arraycopy(time, idx, timestamps.get(arrayIdx), elementIdx,
internalRemaining);
+ System.arraycopy(
+ time, idx - timeIdxOffset, timestamps.get(arrayIdx), elementIdx,
internalRemaining);
System.arraycopy(value, idx, values.get(arrayIdx), elementIdx,
internalRemaining);
idx += internalRemaining;
size += internalRemaining;
@@ -227,6 +246,36 @@ public class DoubleTVList extends TVList {
}
}
+ // move null values to the end of time array and value array, then return
number of null values
+ int dropNullValThenUpdateMinTimeAndSorted(
+ long[] time, double[] values, BitMap bitMap, int start, int end, int
tIdxOffset) {
+ long inPutMinTime = Long.MAX_VALUE;
+ boolean inputSorted = true;
+
+ int nullCnt = 0;
+ for (int vIdx = start; vIdx < end; vIdx++) {
+ if (bitMap.isMarked(vIdx)) {
+ nullCnt++;
+ continue;
+ }
+ // move value ahead to replace null
+ int tIdx = vIdx - tIdxOffset;
+ if (nullCnt != 0) {
+ time[tIdx - nullCnt] = time[tIdx];
+ values[vIdx - nullCnt] = values[vIdx];
+ }
+ // update minTime and sorted
+ tIdx = tIdx - nullCnt;
+ inPutMinTime = Math.min(inPutMinTime, time[tIdx]);
+ if (inputSorted && tIdx > 0 && time[tIdx - 1] > time[tIdx]) {
+ inputSorted = false;
+ }
+ }
+ minTime = Math.min(inPutMinTime, minTime);
+ sorted = sorted && inputSorted && (size == 0 || inPutMinTime >=
getTime(size - 1));
+ return nullCnt;
+ }
+
@Override
public TSDataType getDataType() {
return TSDataType.DOUBLE;
diff --git
a/server/src/main/java/org/apache/iotdb/db/utils/datastructure/FloatTVList.java
b/server/src/main/java/org/apache/iotdb/db/utils/datastructure/FloatTVList.java
index d2ead4b..3e4078a 100644
---
a/server/src/main/java/org/apache/iotdb/db/utils/datastructure/FloatTVList.java
+++
b/server/src/main/java/org/apache/iotdb/db/utils/datastructure/FloatTVList.java
@@ -23,6 +23,7 @@ import org.apache.iotdb.db.utils.MathUtils;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
import org.apache.iotdb.tsfile.read.TimeValuePair;
+import org.apache.iotdb.tsfile.utils.BitMap;
import org.apache.iotdb.tsfile.utils.TsPrimitiveType;
import java.util.ArrayList;
@@ -32,6 +33,8 @@ import static
org.apache.iotdb.db.rescon.PrimitiveArrayManager.ARRAY_SIZE;
public class FloatTVList extends TVList {
+ // list of primitive array, add 1 when expanded -> float primitive array
+ // index relation: arrayIndex -> elementIndex
private List<float[]> values;
private float[][] sortedValues;
@@ -198,11 +201,25 @@ public class FloatTVList extends TVList {
}
@Override
- public void putFloats(long[] time, float[] value, int start, int end) {
+ public void putFloats(long[] time, float[] value, BitMap bitMap, int start,
int end) {
checkExpansion();
- int idx = start;
- updateMinTimeAndSorted(time, start, end);
+ int idx = start;
+ // constraint: time.length + timeIdxOffset == value.length
+ int timeIdxOffset = 0;
+ if (bitMap != null && !bitMap.isAllUnmarked()) {
+ // time array is a reference, should clone necessary time values
+ long[] clonedTime = new long[end - start];
+ System.arraycopy(time, start, clonedTime, 0, end - start);
+ time = clonedTime;
+ timeIdxOffset = start;
+ // drop null at the end of value array
+ int nullCnt =
+ dropNullValThenUpdateMinTimeAndSorted(time, value, bitMap, start,
end, timeIdxOffset);
+ end -= nullCnt;
+ } else {
+ updateMinTimeAndSorted(time, start, end);
+ }
while (idx < end) {
int inputRemaining = end - idx;
@@ -211,14 +228,16 @@ public class FloatTVList extends TVList {
int internalRemaining = ARRAY_SIZE - elementIdx;
if (internalRemaining >= inputRemaining) {
// the remaining inputs can fit the last array, copy all remaining
inputs into last array
- System.arraycopy(time, idx, timestamps.get(arrayIdx), elementIdx,
inputRemaining);
+ System.arraycopy(
+ time, idx - timeIdxOffset, timestamps.get(arrayIdx), elementIdx,
inputRemaining);
System.arraycopy(value, idx, values.get(arrayIdx), elementIdx,
inputRemaining);
size += inputRemaining;
break;
} else {
// the remaining inputs cannot fit the last array, fill the last array
and create a new
// one and enter the next loop
- System.arraycopy(time, idx, timestamps.get(arrayIdx), elementIdx,
internalRemaining);
+ System.arraycopy(
+ time, idx - timeIdxOffset, timestamps.get(arrayIdx), elementIdx,
internalRemaining);
System.arraycopy(value, idx, values.get(arrayIdx), elementIdx,
internalRemaining);
idx += internalRemaining;
size += internalRemaining;
@@ -227,6 +246,36 @@ public class FloatTVList extends TVList {
}
}
+ // move null values to the end of time array and value array, then return
number of null values
+ int dropNullValThenUpdateMinTimeAndSorted(
+ long[] time, float[] values, BitMap bitMap, int start, int end, int
tIdxOffset) {
+ long inPutMinTime = Long.MAX_VALUE;
+ boolean inputSorted = true;
+
+ int nullCnt = 0;
+ for (int vIdx = start; vIdx < end; vIdx++) {
+ if (bitMap.isMarked(vIdx)) {
+ nullCnt++;
+ continue;
+ }
+ // move value ahead to replace null
+ int tIdx = vIdx - tIdxOffset;
+ if (nullCnt != 0) {
+ time[tIdx - nullCnt] = time[tIdx];
+ values[vIdx - nullCnt] = values[vIdx];
+ }
+ // update minTime and sorted
+ tIdx = tIdx - nullCnt;
+ inPutMinTime = Math.min(inPutMinTime, time[tIdx]);
+ if (inputSorted && tIdx > 0 && time[tIdx - 1] > time[tIdx]) {
+ inputSorted = false;
+ }
+ }
+ minTime = Math.min(inPutMinTime, minTime);
+ sorted = sorted && inputSorted && (size == 0 || inPutMinTime >=
getTime(size - 1));
+ return nullCnt;
+ }
+
@Override
public TSDataType getDataType() {
return TSDataType.FLOAT;
diff --git
a/server/src/main/java/org/apache/iotdb/db/utils/datastructure/IntTVList.java
b/server/src/main/java/org/apache/iotdb/db/utils/datastructure/IntTVList.java
index caab7d9..7a7f35a 100644
---
a/server/src/main/java/org/apache/iotdb/db/utils/datastructure/IntTVList.java
+++
b/server/src/main/java/org/apache/iotdb/db/utils/datastructure/IntTVList.java
@@ -22,6 +22,7 @@ import org.apache.iotdb.db.rescon.PrimitiveArrayManager;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
import org.apache.iotdb.tsfile.read.TimeValuePair;
+import org.apache.iotdb.tsfile.utils.BitMap;
import org.apache.iotdb.tsfile.utils.TsPrimitiveType;
import java.util.ArrayList;
@@ -31,6 +32,8 @@ import static
org.apache.iotdb.db.rescon.PrimitiveArrayManager.ARRAY_SIZE;
public class IntTVList extends TVList {
+ // list of primitive array, add 1 when expanded -> int primitive array
+ // index relation: arrayIndex -> elementIndex
private List<int[]> values;
private int[][] sortedValues;
@@ -192,11 +195,25 @@ public class IntTVList extends TVList {
}
@Override
- public void putInts(long[] time, int[] value, int start, int end) {
+ public void putInts(long[] time, int[] value, BitMap bitMap, int start, int
end) {
checkExpansion();
- int idx = start;
- updateMinTimeAndSorted(time, start, end);
+ int idx = start;
+ // constraint: time.length + timeIdxOffset == value.length
+ int timeIdxOffset = 0;
+ if (bitMap != null && !bitMap.isAllUnmarked()) {
+ // time array is a reference, should clone necessary time values
+ long[] clonedTime = new long[end - start];
+ System.arraycopy(time, start, clonedTime, 0, end - start);
+ time = clonedTime;
+ timeIdxOffset = start;
+ // drop null at the end of value array
+ int nullCnt =
+ dropNullValThenUpdateMinTimeAndSorted(time, value, bitMap, start,
end, timeIdxOffset);
+ end -= nullCnt;
+ } else {
+ updateMinTimeAndSorted(time, start, end);
+ }
while (idx < end) {
int inputRemaining = end - idx;
@@ -205,14 +222,16 @@ public class IntTVList extends TVList {
int internalRemaining = ARRAY_SIZE - elementIdx;
if (internalRemaining >= inputRemaining) {
// the remaining inputs can fit the last array, copy all remaining
inputs into last array
- System.arraycopy(time, idx, timestamps.get(arrayIdx), elementIdx,
inputRemaining);
+ System.arraycopy(
+ time, idx - timeIdxOffset, timestamps.get(arrayIdx), elementIdx,
inputRemaining);
System.arraycopy(value, idx, values.get(arrayIdx), elementIdx,
inputRemaining);
size += inputRemaining;
break;
} else {
// the remaining inputs cannot fit the last array, fill the last array
and create a new
// one and enter the next loop
- System.arraycopy(time, idx, timestamps.get(arrayIdx), elementIdx,
internalRemaining);
+ System.arraycopy(
+ time, idx - timeIdxOffset, timestamps.get(arrayIdx), elementIdx,
internalRemaining);
System.arraycopy(value, idx, values.get(arrayIdx), elementIdx,
internalRemaining);
idx += internalRemaining;
size += internalRemaining;
@@ -221,6 +240,36 @@ public class IntTVList extends TVList {
}
}
+ // move null values to the end of time array and value array, then return
number of null values
+ int dropNullValThenUpdateMinTimeAndSorted(
+ long[] time, int[] values, BitMap bitMap, int start, int end, int
tIdxOffset) {
+ long inPutMinTime = Long.MAX_VALUE;
+ boolean inputSorted = true;
+
+ int nullCnt = 0;
+ for (int vIdx = start; vIdx < end; vIdx++) {
+ if (bitMap.isMarked(vIdx)) {
+ nullCnt++;
+ continue;
+ }
+ // move value ahead to replace null
+ int tIdx = vIdx - tIdxOffset;
+ if (nullCnt != 0) {
+ time[tIdx - nullCnt] = time[tIdx];
+ values[vIdx - nullCnt] = values[vIdx];
+ }
+ // update minTime and sorted
+ tIdx = tIdx - nullCnt;
+ inPutMinTime = Math.min(inPutMinTime, time[tIdx]);
+ if (inputSorted && tIdx > 0 && time[tIdx - 1] > time[tIdx]) {
+ inputSorted = false;
+ }
+ }
+ minTime = Math.min(inPutMinTime, minTime);
+ sorted = sorted && inputSorted && (size == 0 || inPutMinTime >=
getTime(size - 1));
+ return nullCnt;
+ }
+
@Override
public TSDataType getDataType() {
return TSDataType.INT32;
diff --git
a/server/src/main/java/org/apache/iotdb/db/utils/datastructure/LongTVList.java
b/server/src/main/java/org/apache/iotdb/db/utils/datastructure/LongTVList.java
index 1459e39..c8c8ddd 100644
---
a/server/src/main/java/org/apache/iotdb/db/utils/datastructure/LongTVList.java
+++
b/server/src/main/java/org/apache/iotdb/db/utils/datastructure/LongTVList.java
@@ -22,6 +22,7 @@ import org.apache.iotdb.db.rescon.PrimitiveArrayManager;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
import org.apache.iotdb.tsfile.read.TimeValuePair;
+import org.apache.iotdb.tsfile.utils.BitMap;
import org.apache.iotdb.tsfile.utils.TsPrimitiveType;
import java.util.ArrayList;
@@ -31,6 +32,8 @@ import static
org.apache.iotdb.db.rescon.PrimitiveArrayManager.ARRAY_SIZE;
public class LongTVList extends TVList {
+ // list of primitive array, add 1 when expanded -> long primitive array
+ // index relation: arrayIndex -> elementIndex
private List<long[]> values;
private long[][] sortedValues;
@@ -187,21 +190,30 @@ public class LongTVList extends TVList {
}
@Override
- public TSDataType getDataType() {
- return TSDataType.INT64;
- }
-
- @Override
protected void releaseLastValueArray() {
PrimitiveArrayManager.release(values.remove(values.size() - 1));
}
@Override
- public void putLongs(long[] time, long[] value, int start, int end) {
+ public void putLongs(long[] time, long[] value, BitMap bitMap, int start,
int end) {
checkExpansion();
- int idx = start;
- updateMinTimeAndSorted(time, start, end);
+ int idx = start;
+ // constraint: time.length + timeIdxOffset == value.length
+ int timeIdxOffset = 0;
+ if (bitMap != null && !bitMap.isAllUnmarked()) {
+ // time array is a reference, should clone necessary time values
+ long[] clonedTime = new long[end - start];
+ System.arraycopy(time, start, clonedTime, 0, end - start);
+ time = clonedTime;
+ timeIdxOffset = start;
+ // drop null at the end of value array
+ int nullCnt =
+ dropNullValThenUpdateMinTimeAndSorted(time, value, bitMap, start,
end, timeIdxOffset);
+ end -= nullCnt;
+ } else {
+ updateMinTimeAndSorted(time, start, end);
+ }
while (idx < end) {
int inputRemaining = end - idx;
@@ -210,14 +222,16 @@ public class LongTVList extends TVList {
int internalRemaining = ARRAY_SIZE - elementIdx;
if (internalRemaining >= inputRemaining) {
// the remaining inputs can fit the last array, copy all remaining
inputs into last array
- System.arraycopy(time, idx, timestamps.get(arrayIdx), elementIdx,
inputRemaining);
+ System.arraycopy(
+ time, idx - timeIdxOffset, timestamps.get(arrayIdx), elementIdx,
inputRemaining);
System.arraycopy(value, idx, values.get(arrayIdx), elementIdx,
inputRemaining);
size += inputRemaining;
break;
} else {
// the remaining inputs cannot fit the last array, fill the last array
and create a new
// one and enter the next loop
- System.arraycopy(time, idx, timestamps.get(arrayIdx), elementIdx,
internalRemaining);
+ System.arraycopy(
+ time, idx - timeIdxOffset, timestamps.get(arrayIdx), elementIdx,
internalRemaining);
System.arraycopy(value, idx, values.get(arrayIdx), elementIdx,
internalRemaining);
idx += internalRemaining;
size += internalRemaining;
@@ -225,4 +239,39 @@ public class LongTVList extends TVList {
}
}
}
+
+ // move null values to the end of time array and value array, then return
number of null values
+ int dropNullValThenUpdateMinTimeAndSorted(
+ long[] time, long[] values, BitMap bitMap, int start, int end, int
tIdxOffset) {
+ long inPutMinTime = Long.MAX_VALUE;
+ boolean inputSorted = true;
+
+ int nullCnt = 0;
+ for (int vIdx = start; vIdx < end; vIdx++) {
+ if (bitMap.isMarked(vIdx)) {
+ nullCnt++;
+ continue;
+ }
+ // move value ahead to replace null
+ int tIdx = vIdx - tIdxOffset;
+ if (nullCnt != 0) {
+ time[tIdx - nullCnt] = time[tIdx];
+ values[vIdx - nullCnt] = values[vIdx];
+ }
+ // update minTime and sorted
+ tIdx = tIdx - nullCnt;
+ inPutMinTime = Math.min(inPutMinTime, time[tIdx]);
+ if (inputSorted && tIdx > 0 && time[tIdx - 1] > time[tIdx]) {
+ inputSorted = false;
+ }
+ }
+ minTime = Math.min(inPutMinTime, minTime);
+ sorted = sorted && inputSorted && (size == 0 || inPutMinTime >=
getTime(size - 1));
+ return nullCnt;
+ }
+
+ @Override
+ public TSDataType getDataType() {
+ return TSDataType.INT64;
+ }
}
diff --git
a/server/src/main/java/org/apache/iotdb/db/utils/datastructure/TVList.java
b/server/src/main/java/org/apache/iotdb/db/utils/datastructure/TVList.java
index 5b960d0..3e78339 100644
--- a/server/src/main/java/org/apache/iotdb/db/utils/datastructure/TVList.java
+++ b/server/src/main/java/org/apache/iotdb/db/utils/datastructure/TVList.java
@@ -40,6 +40,8 @@ public abstract class TVList {
protected static final int SMALL_ARRAY_LENGTH = 32;
protected static final String ERR_DATATYPE_NOT_CONSISTENT = "DataType not
consistent";
+ // list of timestamp array, add 1 when expanded -> data point timestamp array
+ // index relation: arrayIndex -> elementIndex
protected List<long[]> timestamps;
protected int size;
@@ -165,31 +167,31 @@ public abstract class TVList {
throw new UnsupportedOperationException(ERR_DATATYPE_NOT_CONSISTENT);
}
- public void putLongs(long[] time, long[] value, int start, int end) {
+ public void putLongs(long[] time, long[] value, BitMap bitMap, int start,
int end) {
throw new UnsupportedOperationException(ERR_DATATYPE_NOT_CONSISTENT);
}
- public void putInts(long[] time, int[] value, int start, int end) {
+ public void putInts(long[] time, int[] value, BitMap bitMap, int start, int
end) {
throw new UnsupportedOperationException(ERR_DATATYPE_NOT_CONSISTENT);
}
- public void putFloats(long[] time, float[] value, int start, int end) {
+ public void putFloats(long[] time, float[] value, BitMap bitMap, int start,
int end) {
throw new UnsupportedOperationException(ERR_DATATYPE_NOT_CONSISTENT);
}
- public void putDoubles(long[] time, double[] value, int start, int end) {
+ public void putDoubles(long[] time, double[] value, BitMap bitMap, int
start, int end) {
throw new UnsupportedOperationException(ERR_DATATYPE_NOT_CONSISTENT);
}
- public void putBinaries(long[] time, Binary[] value, int start, int end) {
+ public void putBinaries(long[] time, Binary[] value, BitMap bitMap, int
start, int end) {
throw new UnsupportedOperationException(ERR_DATATYPE_NOT_CONSISTENT);
}
- public void putBooleans(long[] time, boolean[] value, int start, int end) {
+ public void putBooleans(long[] time, boolean[] value, BitMap bitMap, int
start, int end) {
throw new UnsupportedOperationException(ERR_DATATYPE_NOT_CONSISTENT);
}
- public void putVectors(long[] time, BitMap[] bitMaps, Object[] value, int
start, int end) {
+ public void putVectors(long[] time, Object[] value, BitMap[] bitMaps, int
start, int end) {
throw new UnsupportedOperationException(ERR_DATATYPE_NOT_CONSISTENT);
}
diff --git
a/server/src/main/java/org/apache/iotdb/db/utils/datastructure/VectorTVList.java
b/server/src/main/java/org/apache/iotdb/db/utils/datastructure/VectorTVList.java
index 1bb4cfe..05b30cd 100644
---
a/server/src/main/java/org/apache/iotdb/db/utils/datastructure/VectorTVList.java
+++
b/server/src/main/java/org/apache/iotdb/db/utils/datastructure/VectorTVList.java
@@ -34,12 +34,21 @@ import static
org.apache.iotdb.db.rescon.PrimitiveArrayManager.ARRAY_SIZE;
public class VectorTVList extends TVList {
+ // data types of this vector
private List<TSDataType> dataTypes;
+ // data type list -> list of TVList, add 1 when expanded -> primitive array
of basic type
+ // index relation: columnIndex(dataTypeIndex) -> arrayIndex -> elementIndex
private List<List<Object>> values;
+ // list of index array, add 1 when expanded -> data point index array
+ // index relation: arrayIndex -> elementIndex
+ // used in sort method, sort only changes indices
private List<int[]> indices;
+ // data type list -> list of BitMap, add 1 when expanded -> BitMap(maybe
null), marked means the
+ // value is null
+ // index relation: columnIndex(dataTypeIndex) -> arrayIndex -> elementIndex
private List<List<BitMap>> bitMaps;
private int[][] sortedIndices;
@@ -135,47 +144,52 @@ public class VectorTVList extends TVList {
int arrayIndex = valueIndex / ARRAY_SIZE;
int elementIndex = valueIndex % ARRAY_SIZE;
TsPrimitiveType[] vector = new TsPrimitiveType[values.size()];
- for (int i = 0; i < values.size(); i++) {
- List<Object> columnValues = values.get(i);
+ for (int columnIndex = 0; columnIndex < values.size(); columnIndex++) {
+ List<Object> columnValues = values.get(columnIndex);
if (validIndexesForTimeDuplicatedRows != null) {
- arrayIndex = validIndexesForTimeDuplicatedRows[i] / ARRAY_SIZE;
- elementIndex = validIndexesForTimeDuplicatedRows[i] % ARRAY_SIZE;
+ arrayIndex = validIndexesForTimeDuplicatedRows[columnIndex] /
ARRAY_SIZE;
+ elementIndex = validIndexesForTimeDuplicatedRows[columnIndex] %
ARRAY_SIZE;
}
if (bitMaps != null
- && bitMaps.get(i) != null
- && bitMaps.get(i).get(arrayIndex).isMarked(elementIndex)) {
+ && bitMaps.get(columnIndex) != null
+ && isValueMarked(valueIndex, columnIndex)) {
continue;
}
- switch (dataTypes.get(i)) {
+ switch (dataTypes.get(columnIndex)) {
case TEXT:
- vector[i] =
+ vector[columnIndex] =
TsPrimitiveType.getByType(
- dataTypes.get(i), ((Binary[])
columnValues.get(arrayIndex))[elementIndex]);
+ dataTypes.get(columnIndex),
+ ((Binary[]) columnValues.get(arrayIndex))[elementIndex]);
break;
case FLOAT:
- vector[i] =
+ vector[columnIndex] =
TsPrimitiveType.getByType(
- dataTypes.get(i), ((float[])
columnValues.get(arrayIndex))[elementIndex]);
+ dataTypes.get(columnIndex),
+ ((float[]) columnValues.get(arrayIndex))[elementIndex]);
break;
case INT32:
- vector[i] =
+ vector[columnIndex] =
TsPrimitiveType.getByType(
- dataTypes.get(i), ((int[])
columnValues.get(arrayIndex))[elementIndex]);
+ dataTypes.get(columnIndex), ((int[])
columnValues.get(arrayIndex))[elementIndex]);
break;
case INT64:
- vector[i] =
+ vector[columnIndex] =
TsPrimitiveType.getByType(
- dataTypes.get(i), ((long[])
columnValues.get(arrayIndex))[elementIndex]);
+ dataTypes.get(columnIndex),
+ ((long[]) columnValues.get(arrayIndex))[elementIndex]);
break;
case DOUBLE:
- vector[i] =
+ vector[columnIndex] =
TsPrimitiveType.getByType(
- dataTypes.get(i), ((double[])
columnValues.get(arrayIndex))[elementIndex]);
+ dataTypes.get(columnIndex),
+ ((double[]) columnValues.get(arrayIndex))[elementIndex]);
break;
case BOOLEAN:
- vector[i] =
+ vector[columnIndex] =
TsPrimitiveType.getByType(
- dataTypes.get(i), ((boolean[])
columnValues.get(arrayIndex))[elementIndex]);
+ dataTypes.get(columnIndex),
+ ((boolean[]) columnValues.get(arrayIndex))[elementIndex]);
break;
default:
throw new UnsupportedOperationException(ERR_DATATYPE_NOT_CONSISTENT);
@@ -306,7 +320,9 @@ public class VectorTVList extends TVList {
if (rowIndex >= size) {
return false;
}
- if (bitMaps == null || bitMaps.get(columnIndex) == null) {
+ if (bitMaps == null
+ || bitMaps.get(columnIndex) == null
+ || bitMaps.get(columnIndex).get(rowIndex / ARRAY_SIZE) == null) {
return false;
}
int arrayIndex = rowIndex / ARRAY_SIZE;
@@ -343,6 +359,7 @@ public class VectorTVList extends TVList {
for (Object valueArray : columnValues) {
cloneList.values.get(i).add(cloneValue(dataTypes.get(i), valueArray));
}
+ // clone bitmap in columnIndex
if (bitMaps != null && bitMaps.get(i) != null) {
List<BitMap> columnBitMaps = bitMaps.get(i);
if (cloneList.bitMaps == null) {
@@ -353,11 +370,11 @@ public class VectorTVList extends TVList {
}
if (cloneList.bitMaps.get(i) == null) {
List<BitMap> cloneColumnBitMaps = new ArrayList<>();
+ for (BitMap bitMap : columnBitMaps) {
+ cloneColumnBitMaps.add(bitMap == null ? null : bitMap.clone());
+ }
cloneList.bitMaps.set(i, cloneColumnBitMaps);
}
- for (BitMap bitMap : columnBitMaps) {
- cloneList.bitMaps.get(i).add(cloneBitMap(bitMap));
- }
}
}
return cloneList;
@@ -369,12 +386,6 @@ public class VectorTVList extends TVList {
return cloneArray;
}
- private BitMap cloneBitMap(BitMap bitMap) {
- byte[] cloneBytes = new byte[bitMap.getByteArray().length];
- System.arraycopy(bitMap.getByteArray(), 0, cloneBytes, 0,
bitMap.getByteArray().length);
- return new BitMap(bitMap.getSize(), cloneBytes);
- }
-
private Object cloneValue(TSDataType type, Object value) {
switch (type) {
case TEXT:
@@ -497,10 +508,10 @@ public class VectorTVList extends TVList {
protected void expandValues() {
indices.add((int[]) getPrimitiveArraysByType(TSDataType.INT32));
for (int i = 0; i < dataTypes.size(); i++) {
+ values.get(i).add(getPrimitiveArraysByType(dataTypes.get(i)));
if (bitMaps != null && bitMaps.get(i) != null) {
- bitMaps.get(i).add(new BitMap(ARRAY_SIZE));
+ bitMaps.get(i).add(null);
}
- values.get(i).add(getPrimitiveArraysByType(dataTypes.get(i)));
}
}
@@ -590,7 +601,7 @@ public class VectorTVList extends TVList {
@SuppressWarnings("squid:S3776") // Suppress high Cognitive Complexity
warning
@Override
- public void putVectors(long[] time, BitMap[] bitMaps, Object[] value, int
start, int end) {
+ public void putVectors(long[] time, Object[] value, BitMap[] bitMaps, int
start, int end) {
checkExpansion();
int idx = start;
@@ -686,11 +697,16 @@ public class VectorTVList extends TVList {
if (bitMaps.get(columnIndex) == null) {
List<BitMap> columnBitMaps = new ArrayList<>();
for (int i = 0; i < values.get(columnIndex).size(); i++) {
- columnBitMaps.add(new BitMap(ARRAY_SIZE));
+ columnBitMaps.add(null);
}
bitMaps.set(columnIndex, columnBitMaps);
}
+ // if the bitmap in arrayIndex is null, init the bitmap
+ if (bitMaps.get(columnIndex).get(arrayIndex) == null) {
+ bitMaps.get(columnIndex).set(arrayIndex, new BitMap(ARRAY_SIZE));
+ }
+
// mark the null value in the current bitmap
bitMaps.get(columnIndex).get(arrayIndex).mark(elementIndex);
}
diff --git
a/server/src/test/java/org/apache/iotdb/db/integration/IoTDBSelectIntoIT.java
b/server/src/test/java/org/apache/iotdb/db/integration/IoTDBSelectIntoIT.java
index 1b30344..f80b588 100644
---
a/server/src/test/java/org/apache/iotdb/db/integration/IoTDBSelectIntoIT.java
+++
b/server/src/test/java/org/apache/iotdb/db/integration/IoTDBSelectIntoIT.java
@@ -397,7 +397,7 @@ public class IoTDBSelectIntoIT {
try (ResultSet resultSet = statement.executeQuery("select gbf_s1 from
root.sg.d1")) {
assertEquals(1 + 1, resultSet.getMetaData().getColumnCount());
- for (int i = 1; i < 10; ++i) {
+ for (int i = 1; i < 5; ++i) {
assertTrue(resultSet.next());
for (int j = 0; j < 1 + 1; ++j) {
assertEquals(String.valueOf(i), resultSet.getString(1));
diff --git
a/server/src/test/java/org/apache/iotdb/db/qp/physical/InsertTabletPlanTest.java
b/server/src/test/java/org/apache/iotdb/db/qp/physical/InsertTabletPlanTest.java
index a3f7e3b..1fae60e 100644
---
a/server/src/test/java/org/apache/iotdb/db/qp/physical/InsertTabletPlanTest.java
+++
b/server/src/test/java/org/apache/iotdb/db/qp/physical/InsertTabletPlanTest.java
@@ -37,6 +37,7 @@ import
org.apache.iotdb.tsfile.exception.filter.QueryFilterOptimizationException
import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
+import org.apache.iotdb.tsfile.read.common.Field;
import org.apache.iotdb.tsfile.read.common.RowRecord;
import org.apache.iotdb.tsfile.read.query.dataset.QueryDataSet;
import org.apache.iotdb.tsfile.utils.Binary;
@@ -121,10 +122,80 @@ public class InsertTabletPlanTest {
}
@Test
+ public void testInsertNullableTabletPlan()
+ throws QueryProcessException, MetadataException, InterruptedException,
+ QueryFilterOptimizationException, StorageEngineException,
IOException {
+ long[] times = new long[] {110L, 111L, 112L, 113L};
+ List<Integer> dataTypes = new ArrayList<>();
+ dataTypes.add(TSDataType.DOUBLE.ordinal());
+ dataTypes.add(TSDataType.FLOAT.ordinal());
+ dataTypes.add(TSDataType.INT64.ordinal());
+ dataTypes.add(TSDataType.INT32.ordinal());
+ dataTypes.add(TSDataType.BOOLEAN.ordinal());
+ dataTypes.add(TSDataType.TEXT.ordinal());
+
+ Object[] columns = new Object[6];
+ columns[0] = new double[4];
+ columns[1] = new float[4];
+ columns[2] = new long[4];
+ columns[3] = new int[4];
+ columns[4] = new boolean[4];
+ columns[5] = new Binary[4];
+
+ for (int r = 0; r < 4; r++) {
+ ((double[]) columns[0])[r] = 1.0 + r;
+ ((float[]) columns[1])[r] = 2 + r;
+ ((long[]) columns[2])[r] = 10000 + r;
+ ((int[]) columns[3])[r] = 100 + r;
+ ((boolean[]) columns[4])[r] = (r % 2 == 0);
+ ((Binary[]) columns[5])[r] = new Binary("hh" + r);
+ }
+
+ BitMap[] bitMaps = new BitMap[dataTypes.size()];
+ for (int i = 0; i < dataTypes.size(); i++) {
+ if (bitMaps[i] == null) {
+ bitMaps[i] = new BitMap(times.length);
+ }
+ bitMaps[i].mark(i % times.length);
+ }
+
+ InsertTabletPlan tabletPlan =
+ new InsertTabletPlan(
+ new PartialPath("root.isp.d1"),
+ new String[] {"s1", "s2", "s3", "s4", "s5", "s6"},
+ dataTypes);
+ tabletPlan.setTimes(times);
+ tabletPlan.setColumns(columns);
+ tabletPlan.setRowCount(times.length);
+ tabletPlan.setBitMaps(bitMaps);
+
+ PlanExecutor executor = new PlanExecutor();
+ executor.insertTablet(tabletPlan);
+
+ QueryPlan queryPlan = (QueryPlan) processor.parseSQLToPhysicalPlan("select
* from root.isp.d1");
+ QueryDataSet dataSet = executor.processQuery(queryPlan,
EnvironmentUtils.TEST_QUERY_CONTEXT);
+ Assert.assertEquals(6, dataSet.getPaths().size());
+ int rowNum = 0;
+ while (dataSet.hasNext()) {
+ RowRecord record = dataSet.next();
+ Assert.assertEquals(6, record.getFields().size());
+ List<Field> fields = record.getFields();
+ for (int i = 0; i < 6; ++i) {
+ if (i % times.length == rowNum) {
+ Assert.assertNull(fields.get(i));
+ } else {
+ Assert.assertNotNull(fields.get(i));
+ }
+ }
+ rowNum++;
+ }
+ }
+
+ @Test
public void testInsertTabletPlanWithAlignedTimeseries()
throws QueryProcessException, MetadataException, InterruptedException,
QueryFilterOptimizationException, StorageEngineException,
IOException {
- InsertTabletPlan tabletPlan = getInsertTabletPlan();
+ InsertTabletPlan tabletPlan = getVectorInsertTabletPlan();
PlanExecutor executor = new PlanExecutor();
executor.insertTablet(tabletPlan);
@@ -146,10 +217,10 @@ public class InsertTabletPlanTest {
public void testInsertNullableTabletPlanWithAlignedTimeseries()
throws QueryProcessException, MetadataException, InterruptedException,
QueryFilterOptimizationException, StorageEngineException,
IOException {
- InsertTabletPlan tabletPlan = getInsertTabletPlan();
- tabletPlan.setBitMaps(new BitMap[6]);
+ InsertTabletPlan tabletPlan = getVectorInsertTabletPlan();
+ tabletPlan.setBitMaps(new BitMap[3]);
BitMap[] bitMaps = tabletPlan.getBitMaps();
- for (int i = 0; i < 4; i++) {
+ for (int i = 0; i < 3; i++) {
if (bitMaps[i] == null) {
bitMaps[i] = new BitMap(4);
}
@@ -180,7 +251,7 @@ public class InsertTabletPlanTest {
IoTDB.metaManager.createSchemaTemplate(plan);
IoTDB.metaManager.setSchemaTemplate(new SetSchemaTemplatePlan("template1",
"root.isp"));
- InsertTabletPlan tabletPlan = getInsertTabletPlan();
+ InsertTabletPlan tabletPlan = getVectorInsertTabletPlan();
PlanExecutor executor = new PlanExecutor();
@@ -259,7 +330,7 @@ public class InsertTabletPlanTest {
IoTDB.metaManager.createSchemaTemplate(plan);
IoTDB.metaManager.setSchemaTemplate(new SetSchemaTemplatePlan("template1",
"root.isp"));
- InsertTabletPlan tabletPlan = getInsertTabletPlan();
+ InsertTabletPlan tabletPlan = getVectorInsertTabletPlan();
PlanExecutor executor = new PlanExecutor();
executor.insertTablet(tabletPlan);
@@ -296,7 +367,7 @@ public class InsertTabletPlanTest {
@Test
public void testInsertTabletSerialization() throws IllegalPathException,
QueryProcessException {
- InsertTabletPlan plan1 = getInsertTabletPlan();
+ InsertTabletPlan plan1 = getVectorInsertTabletPlan();
PlanExecutor executor = new PlanExecutor();
executor.insertTablet(plan1);
@@ -317,7 +388,7 @@ public class InsertTabletPlanTest {
@Test
public void testInsertTabletWithBitMapsSerialization()
throws IllegalPathException, QueryProcessException {
- InsertTabletPlan plan1 = getInsertTabletPlan();
+ InsertTabletPlan plan1 = getVectorInsertTabletPlan();
plan1.setBitMaps(new BitMap[3]);
BitMap[] bitMaps = plan1.getBitMaps();
for (int i = 0; i < 3; i++) {
@@ -342,7 +413,7 @@ public class InsertTabletPlanTest {
Assert.assertEquals(plan1, plan2);
}
- private InsertTabletPlan getInsertTabletPlan() throws IllegalPathException {
+ private InsertTabletPlan getVectorInsertTabletPlan() throws
IllegalPathException {
long[] times = new long[] {110L, 111L, 112L, 113L};
List<Integer> dataTypes = new ArrayList<>();
dataTypes.add(TSDataType.DOUBLE.ordinal());
diff --git
a/server/src/test/java/org/apache/iotdb/db/utils/datastructure/BinaryTVListTest.java
b/server/src/test/java/org/apache/iotdb/db/utils/datastructure/BinaryTVListTest.java
index b46a2b9..8e09c7d 100644
---
a/server/src/test/java/org/apache/iotdb/db/utils/datastructure/BinaryTVListTest.java
+++
b/server/src/test/java/org/apache/iotdb/db/utils/datastructure/BinaryTVListTest.java
@@ -19,6 +19,7 @@
package org.apache.iotdb.db.utils.datastructure;
import org.apache.iotdb.tsfile.utils.Binary;
+import org.apache.iotdb.tsfile.utils.BitMap;
import org.apache.commons.lang3.ArrayUtils;
import org.junit.Assert;
@@ -42,17 +43,69 @@ public class BinaryTVListTest {
}
@Test
- public void testBinaryTVLists() {
+ public void testPutBinariesWithoutBitMap() {
BinaryTVList tvList = new BinaryTVList();
Binary[] binaryList = new Binary[1001];
List<Long> timeList = new ArrayList<>();
for (int i = 1000; i >= 0; i--) {
timeList.add((long) i);
- binaryList[i] = Binary.valueOf(String.valueOf(i));
+ binaryList[1000 - i] = Binary.valueOf(String.valueOf(i));
}
- tvList.putBinaries(ArrayUtils.toPrimitive(timeList.toArray(new Long[0])),
binaryList, 0, 1000);
+ tvList.putBinaries(
+ ArrayUtils.toPrimitive(timeList.toArray(new Long[0])), binaryList,
null, 0, 1000);
for (long i = 0; i < tvList.size; i++) {
Assert.assertEquals(tvList.size - i, tvList.getTime((int) i));
}
}
+
+ @Test
+ public void testPutBinariesWithBitMap() {
+ BinaryTVList tvList = new BinaryTVList();
+ Binary[] binaryList = new Binary[1001];
+ List<Long> timeList = new ArrayList<>();
+ BitMap bitMap = new BitMap(1001);
+ for (int i = 1000; i >= 0; i--) {
+ timeList.add((long) i);
+ binaryList[1000 - i] = Binary.valueOf(String.valueOf(i));
+ if (i % 100 == 0) {
+ bitMap.mark(i);
+ }
+ }
+ tvList.putBinaries(
+ ArrayUtils.toPrimitive(timeList.toArray(new Long[0])), binaryList,
bitMap, 0, 1000);
+ tvList.sort();
+ int nullCnt = 0;
+ for (long i = 1; i < binaryList.length; i++) {
+ if (i % 100 == 0) {
+ nullCnt++;
+ continue;
+ }
+ Assert.assertEquals(
+ Binary.valueOf(String.valueOf(i)), tvList.getBinary((int) i -
nullCnt - 1));
+ Assert.assertEquals(i, tvList.getTime((int) i - nullCnt - 1));
+ }
+ }
+
+ @Test
+ public void testClone() {
+ BinaryTVList tvList = new BinaryTVList();
+ Binary[] binaryList = new Binary[1001];
+ List<Long> timeList = new ArrayList<>();
+ BitMap bitMap = new BitMap(1001);
+ for (int i = 1000; i >= 0; i--) {
+ timeList.add((long) i);
+ binaryList[i] = Binary.valueOf(String.valueOf(i));
+ if (i % 100 == 0) {
+ bitMap.mark(i);
+ }
+ }
+ tvList.putBinaries(
+ ArrayUtils.toPrimitive(timeList.toArray(new Long[0])), binaryList,
bitMap, 0, 1000);
+ tvList.sort();
+ BinaryTVList clonedTvList = tvList.clone();
+ for (long i = 0; i < tvList.size; i++) {
+ Assert.assertEquals(tvList.getBinary((int) i),
clonedTvList.getBinary((int) i));
+ Assert.assertEquals(tvList.getTime((int) i), clonedTvList.getTime((int)
i));
+ }
+ }
}
diff --git
a/server/src/test/java/org/apache/iotdb/db/utils/datastructure/BooleanTVListTest.java
b/server/src/test/java/org/apache/iotdb/db/utils/datastructure/BooleanTVListTest.java
index 20c2796..09eb4ab 100644
---
a/server/src/test/java/org/apache/iotdb/db/utils/datastructure/BooleanTVListTest.java
+++
b/server/src/test/java/org/apache/iotdb/db/utils/datastructure/BooleanTVListTest.java
@@ -18,6 +18,8 @@
*/
package org.apache.iotdb.db.utils.datastructure;
+import org.apache.iotdb.tsfile.utils.BitMap;
+
import org.apache.commons.lang3.ArrayUtils;
import org.junit.Assert;
import org.junit.Test;
@@ -46,7 +48,7 @@ public class BooleanTVListTest {
}
@Test
- public void testBooleanTVLists() {
+ public void testPutBooleansWithoutBitMap() {
BooleanTVList tvList = new BooleanTVList();
List<Boolean> booleanList = new ArrayList<>();
List<Long> timeList = new ArrayList<>();
@@ -57,10 +59,69 @@ public class BooleanTVListTest {
tvList.putBooleans(
ArrayUtils.toPrimitive(timeList.toArray(new Long[0])),
ArrayUtils.toPrimitive(booleanList.toArray(new Boolean[0])),
+ null,
0,
1000);
for (long i = 0; i < tvList.size; i++) {
Assert.assertEquals(tvList.size - i, tvList.getTime((int) i));
}
}
+
+ @Test
+ public void testPutBooleansWithBitMap() {
+ BooleanTVList tvList = new BooleanTVList();
+ List<Boolean> booleanList = new ArrayList<>();
+ List<Long> timeList = new ArrayList<>();
+ BitMap bitMap = new BitMap(1001);
+ for (long i = 1000; i >= 0; i--) {
+ timeList.add((i));
+ booleanList.add(i % 2 == 0);
+ if (i % 100 == 0) {
+ bitMap.mark((int) i);
+ }
+ }
+ tvList.putBooleans(
+ ArrayUtils.toPrimitive(timeList.toArray(new Long[0])),
+ ArrayUtils.toPrimitive(booleanList.toArray(new Boolean[0])),
+ bitMap,
+ 0,
+ 1000);
+ tvList.sort();
+ int nullCnt = 0;
+ for (long i = 1; i < booleanList.size(); i++) {
+ if (i % 100 == 0) {
+ nullCnt++;
+ continue;
+ }
+ Assert.assertEquals(i % 2 == 0, tvList.getBoolean((int) i - nullCnt -
1));
+ Assert.assertEquals(i, tvList.getTime((int) i - nullCnt - 1));
+ }
+ }
+
+ @Test
+ public void testClone() {
+ BooleanTVList tvList = new BooleanTVList();
+ List<Boolean> booleanList = new ArrayList<>();
+ List<Long> timeList = new ArrayList<>();
+ BitMap bitMap = new BitMap(1001);
+ for (long i = 1000; i >= 0; i--) {
+ timeList.add((i));
+ booleanList.add(i % 2 == 0);
+ if (i % 100 == 0) {
+ bitMap.mark((int) i);
+ }
+ }
+ tvList.putBooleans(
+ ArrayUtils.toPrimitive(timeList.toArray(new Long[0])),
+ ArrayUtils.toPrimitive(booleanList.toArray(new Boolean[0])),
+ bitMap,
+ 0,
+ 1000);
+ tvList.sort();
+ BooleanTVList clonedTvList = tvList.clone();
+ for (long i = 0; i < tvList.size; i++) {
+ Assert.assertEquals(tvList.getBoolean((int) i),
clonedTvList.getBoolean((int) i));
+ Assert.assertEquals(tvList.getTime((int) i), clonedTvList.getTime((int)
i));
+ }
+ }
}
diff --git
a/server/src/test/java/org/apache/iotdb/db/utils/datastructure/DoubleTVListTest.java
b/server/src/test/java/org/apache/iotdb/db/utils/datastructure/DoubleTVListTest.java
index 47d5a9d..315c0a3 100644
---
a/server/src/test/java/org/apache/iotdb/db/utils/datastructure/DoubleTVListTest.java
+++
b/server/src/test/java/org/apache/iotdb/db/utils/datastructure/DoubleTVListTest.java
@@ -18,6 +18,8 @@
*/
package org.apache.iotdb.db.utils.datastructure;
+import org.apache.iotdb.tsfile.utils.BitMap;
+
import org.apache.commons.lang3.ArrayUtils;
import org.junit.Assert;
import org.junit.Test;
@@ -55,7 +57,7 @@ public class DoubleTVListTest {
}
@Test
- public void testDoubleTVLists() {
+ public void testPutDoublesWithoutBitMap() {
DoubleTVList tvList = new DoubleTVList();
List<Double> doubleList = new ArrayList<>();
List<Long> timeList = new ArrayList<>();
@@ -66,6 +68,7 @@ public class DoubleTVListTest {
tvList.putDoubles(
ArrayUtils.toPrimitive(timeList.toArray(new Long[0])),
ArrayUtils.toPrimitive(doubleList.toArray(new Double[0]), 0.0d),
+ null,
0,
1000);
for (long i = 0; i < tvList.size; i++) {
@@ -73,4 +76,62 @@ public class DoubleTVListTest {
Assert.assertEquals(tvList.size - i, tvList.getTime((int) i));
}
}
+
+ @Test
+ public void testPutDoublesWithBitMap() {
+ DoubleTVList tvList = new DoubleTVList();
+ List<Double> doubleList = new ArrayList<>();
+ List<Long> timeList = new ArrayList<>();
+ BitMap bitMap = new BitMap(1001);
+ for (long i = 1000; i >= 0; i--) {
+ timeList.add((i));
+ doubleList.add((double) i);
+ if (i % 100 == 0) {
+ bitMap.mark((int) i);
+ }
+ }
+ tvList.putDoubles(
+ ArrayUtils.toPrimitive(timeList.toArray(new Long[0])),
+ ArrayUtils.toPrimitive(doubleList.toArray(new Double[0]), 0.0d),
+ bitMap,
+ 0,
+ 1000);
+ tvList.sort();
+ int nullCnt = 0;
+ for (long i = 1; i < doubleList.size(); i++) {
+ if (i % 100 == 0) {
+ nullCnt++;
+ continue;
+ }
+ Assert.assertEquals(i, tvList.getDouble((int) i - nullCnt - 1), delta);
+ Assert.assertEquals(i, tvList.getTime((int) i - nullCnt - 1));
+ }
+ }
+
+ @Test
+ public void testClone() {
+ DoubleTVList tvList = new DoubleTVList();
+ List<Double> doubleList = new ArrayList<>();
+ List<Long> timeList = new ArrayList<>();
+ BitMap bitMap = new BitMap(1001);
+ for (long i = 1000; i >= 0; i--) {
+ timeList.add((i));
+ doubleList.add((double) i);
+ if (i % 100 == 0) {
+ bitMap.mark((int) i);
+ }
+ }
+ tvList.putDoubles(
+ ArrayUtils.toPrimitive(timeList.toArray(new Long[0])),
+ ArrayUtils.toPrimitive(doubleList.toArray(new Double[0]), 0.0d),
+ bitMap,
+ 0,
+ 1000);
+ tvList.sort();
+ DoubleTVList clonedTvList = tvList.clone();
+ for (long i = 0; i < tvList.size; i++) {
+ Assert.assertEquals(tvList.getDouble((int) i),
clonedTvList.getDouble((int) i), delta);
+ Assert.assertEquals(tvList.getTime((int) i), clonedTvList.getTime((int)
i));
+ }
+ }
}
diff --git
a/server/src/test/java/org/apache/iotdb/db/utils/datastructure/FloatTVListTest.java
b/server/src/test/java/org/apache/iotdb/db/utils/datastructure/FloatTVListTest.java
index a132f7a..90c1c12 100644
---
a/server/src/test/java/org/apache/iotdb/db/utils/datastructure/FloatTVListTest.java
+++
b/server/src/test/java/org/apache/iotdb/db/utils/datastructure/FloatTVListTest.java
@@ -18,6 +18,8 @@
*/
package org.apache.iotdb.db.utils.datastructure;
+import org.apache.iotdb.tsfile.utils.BitMap;
+
import org.apache.commons.lang3.ArrayUtils;
import org.junit.Assert;
import org.junit.Test;
@@ -55,7 +57,7 @@ public class FloatTVListTest {
}
@Test
- public void testFloatTVLists() {
+ public void testPutFloatsWithoutBitMap() {
FloatTVList tvList = new FloatTVList();
List<Float> floatList = new ArrayList<>();
List<Long> timeList = new ArrayList<>();
@@ -66,6 +68,7 @@ public class FloatTVListTest {
tvList.putFloats(
ArrayUtils.toPrimitive(timeList.toArray(new Long[0])),
ArrayUtils.toPrimitive(floatList.toArray(new Float[0]), 0.0F),
+ null,
0,
1000);
for (long i = 0; i < tvList.size; i++) {
@@ -73,4 +76,62 @@ public class FloatTVListTest {
Assert.assertEquals(tvList.size - i, tvList.getTime((int) i));
}
}
+
+ @Test
+ public void testPutFloatsWithBitMap() {
+ FloatTVList tvList = new FloatTVList();
+ List<Float> floatList = new ArrayList<>();
+ List<Long> timeList = new ArrayList<>();
+ BitMap bitMap = new BitMap(1001);
+ for (long i = 1000; i >= 0; i--) {
+ timeList.add(i);
+ floatList.add((float) i);
+ if (i % 100 == 0) {
+ bitMap.mark((int) i);
+ }
+ }
+ tvList.putFloats(
+ ArrayUtils.toPrimitive(timeList.toArray(new Long[0])),
+ ArrayUtils.toPrimitive(floatList.toArray(new Float[0]), 0.0F),
+ bitMap,
+ 0,
+ 1000);
+ tvList.sort();
+ int nullCnt = 0;
+ for (long i = 1; i < floatList.size(); i++) {
+ if (i % 100 == 0) {
+ nullCnt++;
+ continue;
+ }
+ Assert.assertEquals(i, tvList.getFloat((int) i - nullCnt - 1), delta);
+ Assert.assertEquals(i, tvList.getTime((int) i - nullCnt - 1));
+ }
+ }
+
+ @Test
+ public void testClone() {
+ FloatTVList tvList = new FloatTVList();
+ List<Float> floatList = new ArrayList<>();
+ List<Long> timeList = new ArrayList<>();
+ BitMap bitMap = new BitMap(1001);
+ for (long i = 1000; i >= 0; i--) {
+ timeList.add(i);
+ floatList.add((float) i);
+ if (i % 100 == 0) {
+ bitMap.mark((int) i);
+ }
+ }
+ tvList.putFloats(
+ ArrayUtils.toPrimitive(timeList.toArray(new Long[0])),
+ ArrayUtils.toPrimitive(floatList.toArray(new Float[0]), 0.0F),
+ bitMap,
+ 0,
+ 1000);
+ tvList.sort();
+ FloatTVList clonedTvList = tvList.clone();
+ for (long i = 0; i < tvList.size; i++) {
+ Assert.assertEquals(tvList.getFloat((int) i),
clonedTvList.getFloat((int) i), delta);
+ Assert.assertEquals(tvList.getTime((int) i), clonedTvList.getTime((int)
i));
+ }
+ }
}
diff --git
a/server/src/test/java/org/apache/iotdb/db/utils/datastructure/IntTVListTest.java
b/server/src/test/java/org/apache/iotdb/db/utils/datastructure/IntTVListTest.java
index 250ad5c..8384b80 100644
---
a/server/src/test/java/org/apache/iotdb/db/utils/datastructure/IntTVListTest.java
+++
b/server/src/test/java/org/apache/iotdb/db/utils/datastructure/IntTVListTest.java
@@ -18,6 +18,8 @@
*/
package org.apache.iotdb.db.utils.datastructure;
+import org.apache.iotdb.tsfile.utils.BitMap;
+
import org.apache.commons.lang3.ArrayUtils;
import org.junit.Assert;
import org.junit.Test;
@@ -54,7 +56,7 @@ public class IntTVListTest {
}
@Test
- public void testIntTVLists() {
+ public void testPutIntsWithoutBitMap() {
IntTVList tvList = new IntTVList();
List<Integer> intList = new ArrayList<>();
List<Long> timeList = new ArrayList<>();
@@ -65,6 +67,7 @@ public class IntTVListTest {
tvList.putInts(
ArrayUtils.toPrimitive(timeList.toArray(new Long[0])),
ArrayUtils.toPrimitive(intList.toArray(new Integer[0])),
+ null,
0,
1000);
for (long i = 0; i < tvList.size; i++) {
@@ -72,4 +75,62 @@ public class IntTVListTest {
Assert.assertEquals(tvList.size - i, tvList.getTime((int) i));
}
}
+
+ @Test
+ public void testPutIntsWithBitMap() {
+ IntTVList tvList = new IntTVList();
+ List<Integer> intList = new ArrayList<>();
+ List<Long> timeList = new ArrayList<>();
+ BitMap bitMap = new BitMap(1001);
+ for (int i = 1000; i >= 0; i--) {
+ timeList.add((long) i);
+ intList.add(i);
+ if (i % 100 == 0) {
+ bitMap.mark(i);
+ }
+ }
+ tvList.putInts(
+ ArrayUtils.toPrimitive(timeList.toArray(new Long[0])),
+ ArrayUtils.toPrimitive(intList.toArray(new Integer[0])),
+ bitMap,
+ 0,
+ 1000);
+ tvList.sort();
+ int nullCnt = 0;
+ for (long i = 1; i < intList.size(); i++) {
+ if (i % 100 == 0) {
+ nullCnt++;
+ continue;
+ }
+ Assert.assertEquals(i, tvList.getInt((int) i - nullCnt - 1));
+ Assert.assertEquals(i, tvList.getTime((int) i - nullCnt - 1));
+ }
+ }
+
+ @Test
+ public void testClone() {
+ IntTVList tvList = new IntTVList();
+ List<Integer> intList = new ArrayList<>();
+ List<Long> timeList = new ArrayList<>();
+ BitMap bitMap = new BitMap(1001);
+ for (int i = 1000; i >= 0; i--) {
+ timeList.add((long) i);
+ intList.add(i);
+ if (i % 100 == 0) {
+ bitMap.mark(i);
+ }
+ }
+ tvList.putInts(
+ ArrayUtils.toPrimitive(timeList.toArray(new Long[0])),
+ ArrayUtils.toPrimitive(intList.toArray(new Integer[0])),
+ bitMap,
+ 0,
+ 1000);
+ tvList.sort();
+ IntTVList clonedTvList = tvList.clone();
+ for (long i = 0; i < tvList.size; i++) {
+ Assert.assertEquals(tvList.getInt((int) i), clonedTvList.getInt((int)
i));
+ Assert.assertEquals(tvList.getTime((int) i), clonedTvList.getTime((int)
i));
+ }
+ }
}
diff --git
a/server/src/test/java/org/apache/iotdb/db/utils/datastructure/LongTVListTest.java
b/server/src/test/java/org/apache/iotdb/db/utils/datastructure/LongTVListTest.java
index fc63ec3..4af8cb7 100644
---
a/server/src/test/java/org/apache/iotdb/db/utils/datastructure/LongTVListTest.java
+++
b/server/src/test/java/org/apache/iotdb/db/utils/datastructure/LongTVListTest.java
@@ -19,6 +19,7 @@
package org.apache.iotdb.db.utils.datastructure;
import org.apache.iotdb.tsfile.read.TimeValuePair;
+import org.apache.iotdb.tsfile.utils.BitMap;
import org.apache.iotdb.tsfile.utils.TsPrimitiveType.TsLong;
import org.apache.commons.lang3.ArrayUtils;
@@ -77,7 +78,7 @@ public class LongTVListTest {
}
@Test
- public void testLongTVLists() {
+ public void testPutLongsWithoutBitMap() {
LongTVList tvList = new LongTVList();
List<Long> longList = new ArrayList<>();
List<Long> timeList = new ArrayList<>();
@@ -88,6 +89,7 @@ public class LongTVListTest {
tvList.putLongs(
ArrayUtils.toPrimitive(timeList.toArray(new Long[0])),
ArrayUtils.toPrimitive(longList.toArray(new Long[0])),
+ null,
0,
1000);
for (long i = 0; i < tvList.size; i++) {
@@ -95,4 +97,62 @@ public class LongTVListTest {
Assert.assertEquals(tvList.size - i, tvList.getTime((int) i));
}
}
+
+ @Test
+ public void testPutIntsWithBitMap() {
+ LongTVList tvList = new LongTVList();
+ List<Long> longList = new ArrayList<>();
+ List<Long> timeList = new ArrayList<>();
+ BitMap bitMap = new BitMap(1001);
+ for (long i = 1000; i >= 0; i--) {
+ timeList.add(i);
+ longList.add(i);
+ if (i % 100 == 0) {
+ bitMap.mark((int) i);
+ }
+ }
+ tvList.putLongs(
+ ArrayUtils.toPrimitive(timeList.toArray(new Long[0])),
+ ArrayUtils.toPrimitive(longList.toArray(new Long[0])),
+ bitMap,
+ 0,
+ 1000);
+ tvList.sort();
+ int nullCnt = 0;
+ for (long i = 1; i < longList.size(); i++) {
+ if (i % 100 == 0) {
+ nullCnt++;
+ continue;
+ }
+ Assert.assertEquals(i, tvList.getLong((int) i - nullCnt - 1));
+ Assert.assertEquals(i, tvList.getTime((int) i - nullCnt - 1));
+ }
+ }
+
+ @Test
+ public void testClone() {
+ LongTVList tvList = new LongTVList();
+ List<Long> longList = new ArrayList<>();
+ List<Long> timeList = new ArrayList<>();
+ BitMap bitMap = new BitMap(1001);
+ for (long i = 1000; i >= 0; i--) {
+ timeList.add(i);
+ longList.add(i);
+ if (i % 100 == 0) {
+ bitMap.mark((int) i);
+ }
+ }
+ tvList.putLongs(
+ ArrayUtils.toPrimitive(timeList.toArray(new Long[0])),
+ ArrayUtils.toPrimitive(longList.toArray(new Long[0])),
+ bitMap,
+ 0,
+ 1000);
+ tvList.sort();
+ LongTVList clonedTvList = tvList.clone();
+ for (long i = 0; i < tvList.size; i++) {
+ Assert.assertEquals(tvList.getLong((int) i), clonedTvList.getLong((int)
i));
+ Assert.assertEquals(tvList.getTime((int) i), clonedTvList.getTime((int)
i));
+ }
+ }
}
diff --git
a/server/src/test/java/org/apache/iotdb/db/utils/datastructure/VectorTVListTest.java
b/server/src/test/java/org/apache/iotdb/db/utils/datastructure/VectorTVListTest.java
index c85021f..e1c11e3 100644
---
a/server/src/test/java/org/apache/iotdb/db/utils/datastructure/VectorTVListTest.java
+++
b/server/src/test/java/org/apache/iotdb/db/utils/datastructure/VectorTVListTest.java
@@ -104,7 +104,7 @@ public class VectorTVListTest {
}
tvList.putVectors(
- ArrayUtils.toPrimitive(timeList.toArray(new Long[0])), null,
vectorArray, 0, 1000);
+ ArrayUtils.toPrimitive(timeList.toArray(new Long[0])), vectorArray,
null, 0, 1000);
for (long i = 0; i < tvList.size; i++) {
Assert.assertEquals(tvList.size - i, tvList.getTime((int) i));
}
@@ -132,7 +132,7 @@ public class VectorTVListTest {
}
tvList.putVectors(
- ArrayUtils.toPrimitive(timeList.toArray(new Long[0])), bitMaps,
vectorArray, 0, 1000);
+ ArrayUtils.toPrimitive(timeList.toArray(new Long[0])), vectorArray,
bitMaps, 0, 1000);
for (long i = 0; i < tvList.size; i++) {
Assert.assertEquals(tvList.size - i, tvList.getTime((int) i));
if (i % 100 == 0) {
@@ -140,4 +140,40 @@ public class VectorTVListTest {
}
}
}
+
+ @Test
+ public void testClone() {
+ List<TSDataType> dataTypes = new ArrayList<>();
+ BitMap[] bitMaps = new BitMap[5];
+ for (int i = 0; i < 5; i++) {
+ dataTypes.add(TSDataType.INT64);
+ bitMaps[i] = new BitMap(1001);
+ }
+ VectorTVList tvList = new VectorTVList(dataTypes);
+ long[][] vectorArray = new long[5][1001];
+ List<Long> timeList = new ArrayList<>();
+ for (int i = 1000; i >= 0; i--) {
+ timeList.add((long) i);
+ for (int j = 0; j < 5; j++) {
+ vectorArray[j][i] = (long) i;
+ if (i % 100 == 0) {
+ bitMaps[j].mark(i);
+ }
+ }
+ }
+
+ tvList.putVectors(
+ ArrayUtils.toPrimitive(timeList.toArray(new Long[0])), vectorArray,
bitMaps, 0, 1000);
+
+ VectorTVList clonedTvList = tvList.clone();
+ for (long i = 0; i < tvList.size; i++) {
+ Assert.assertEquals(tvList.getTime((int) i), clonedTvList.getTime((int)
i));
+ Assert.assertEquals(
+ tvList.getVector((int) i).toString(), clonedTvList.getVector((int)
i).toString());
+ for (int column = 0; i < 5; i++) {
+ Assert.assertEquals(
+ tvList.isValueMarked((int) i, column),
clonedTvList.isValueMarked((int) i, column));
+ }
+ }
+ }
}
diff --git
a/session/src/test/java/org/apache/iotdb/session/IoTDBSessionSimpleIT.java
b/session/src/test/java/org/apache/iotdb/session/IoTDBSessionSimpleIT.java
index aad0f2b..171f980 100644
--- a/session/src/test/java/org/apache/iotdb/session/IoTDBSessionSimpleIT.java
+++ b/session/src/test/java/org/apache/iotdb/session/IoTDBSessionSimpleIT.java
@@ -37,6 +37,7 @@ import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
import org.apache.iotdb.tsfile.read.common.Field;
import org.apache.iotdb.tsfile.read.common.RowRecord;
import org.apache.iotdb.tsfile.utils.Binary;
+import org.apache.iotdb.tsfile.utils.BitMap;
import org.apache.iotdb.tsfile.write.record.Tablet;
import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
import org.apache.iotdb.tsfile.write.schema.MeasurementSchema;
@@ -424,6 +425,58 @@ public class IoTDBSessionSimpleIT {
}
@Test
+ public void testInsertTabletWithNullValues()
+ throws IoTDBConnectionException, StatementExecutionException {
+ session = new Session("127.0.0.1", 6667, "root", "root");
+ session.open();
+ List<IMeasurementSchema> schemaList = new ArrayList<>();
+ schemaList.add(new MeasurementSchema("s0", TSDataType.DOUBLE,
TSEncoding.RLE));
+ schemaList.add(new MeasurementSchema("s1", TSDataType.FLOAT,
TSEncoding.RLE));
+ schemaList.add(new MeasurementSchema("s2", TSDataType.INT64,
TSEncoding.RLE));
+ schemaList.add(new MeasurementSchema("s3", TSDataType.INT32,
TSEncoding.RLE));
+ schemaList.add(new MeasurementSchema("s4", TSDataType.BOOLEAN,
TSEncoding.RLE));
+ schemaList.add(new MeasurementSchema("s5", TSDataType.TEXT,
TSEncoding.RLE));
+
+ Tablet tablet = new Tablet("root.sg1.d1", schemaList);
+ for (long time = 0; time < 10; time++) {
+ int rowIndex = tablet.rowSize++;
+ tablet.addTimestamp(rowIndex, time);
+
+ tablet.addValue(schemaList.get(0).getMeasurementId(), rowIndex, (double)
time);
+ tablet.addValue(schemaList.get(1).getMeasurementId(), rowIndex, (float)
time);
+ tablet.addValue(schemaList.get(2).getMeasurementId(), rowIndex, time);
+ tablet.addValue(schemaList.get(3).getMeasurementId(), rowIndex, (int)
time);
+ tablet.addValue(schemaList.get(4).getMeasurementId(), rowIndex, time % 2
== 0);
+ tablet.addValue(
+ schemaList.get(5).getMeasurementId(), rowIndex, new
Binary(String.valueOf(time)));
+ }
+
+ BitMap[] bitMaps = new BitMap[schemaList.size()];
+ for (int i = 0; i < schemaList.size(); i++) {
+ if (bitMaps[i] == null) {
+ bitMaps[i] = new BitMap(10);
+ }
+ bitMaps[i].mark(i);
+ }
+ tablet.bitMaps = bitMaps;
+
+ if (tablet.rowSize != 0) {
+ session.insertTablet(tablet);
+ tablet.reset();
+ }
+
+ SessionDataSet dataSet = session.executeQueryStatement("select count(*)
from root");
+ while (dataSet.hasNext()) {
+ RowRecord rowRecord = dataSet.next();
+ Assert.assertEquals(6L, rowRecord.getFields().size());
+ for (Field field : rowRecord.getFields()) {
+ Assert.assertEquals(9L, field.getLongV());
+ }
+ }
+ session.close();
+ }
+
+ @Test
public void createTimeSeriesWithDoubleTicks()
throws IoTDBConnectionException, StatementExecutionException {
session = new Session("127.0.0.1", 6667, "root", "root");
diff --git a/tsfile/src/main/java/org/apache/iotdb/tsfile/utils/BitMap.java
b/tsfile/src/main/java/org/apache/iotdb/tsfile/utils/BitMap.java
index 11e5ac1..a933f42 100644
--- a/tsfile/src/main/java/org/apache/iotdb/tsfile/utils/BitMap.java
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/utils/BitMap.java
@@ -124,6 +124,13 @@ public class BitMap {
return res.toString();
}
+ @Override
+ public BitMap clone() {
+ byte[] cloneBytes = new byte[this.bits.length];
+ System.arraycopy(this.bits, 0, cloneBytes, 0, this.bits.length);
+ return new BitMap(this.size, cloneBytes);
+ }
+
/** Copies the specified range of the BitMap into a new BitMap. */
public BitMap copyOfRange(int from, int to) {
int newLength = to - from;
diff --git
a/tsfile/src/main/java/org/apache/iotdb/tsfile/write/record/Tablet.java
b/tsfile/src/main/java/org/apache/iotdb/tsfile/write/record/Tablet.java
index bbe91fb..f136b68 100644
--- a/tsfile/src/main/java/org/apache/iotdb/tsfile/write/record/Tablet.java
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/write/record/Tablet.java
@@ -197,9 +197,16 @@ public class Tablet {
return maxRowNumber;
}
- /** Reset Tablet to the default state - set the rowSize to 0 */
+ /** Reset Tablet to the default state - set the rowSize to 0 and reset
bitMaps */
public void reset() {
rowSize = 0;
+ if (bitMaps != null) {
+ for (BitMap bitMap : bitMaps) {
+ if (bitMap != null) {
+ bitMap.reset();
+ }
+ }
+ }
}
private void createColumns() {