Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
8d89f4d
Check blank column name or table name (#471)
shuwenwei Apr 23, 2025
4b75866
Optimizations regarding chunk metadata sort & timeseries metadata ser…
jt2594838 Apr 23, 2025
b385b4f
Remove redundant conversion in TableResultSet (#473)
jt2594838 Apr 25, 2025
73ac55f
Fix CPP TsFile query with time filter error (#474)
HTHou Apr 27, 2025
c731ba0
add switch to disable native lz4 (#480)
jt2594838 Apr 29, 2025
4145395
Fix float RLBE encoding loss of precision (#484)
HTHou May 8, 2025
217cc3c
Add flush method for tsfile python writer (#487)
ycycse May 9, 2025
d2119c1
add table/column schema check. (#488)
ColinLeeo May 12, 2025
e795637
delete parameter encrypt_flag (#491)
zhujt20 May 12, 2025
6f08fb1
Colin fix config (#493)
ColinLeeo May 13, 2025
14cefc9
fix data lossing when page num exceed 1. (#495)
ColinLeeo May 15, 2025
cc8f363
Colin fix config (#472)
ColinLeeo May 19, 2025
dd603b4
Bump setuptools from 70.0.0 to 78.1.1 in /python (#497)
dependabot[bot] May 20, 2025
3a688ee
Add TsFileLastReader for retrieving last points in a TsFile (#498)
jt2594838 May 23, 2025
1856572
Update release information of TsFile v2.0.3 (#505)
HTHou Jun 3, 2025
a5424d3
Same name (case insensitive) in tablet / table. (#490)
ColinLeeo Jun 4, 2025
6672d2d
Fix (#508)
Caideyipi Jun 9, 2025
a71b8d4
fix minus encode and decode. (#511)
ColinLeeo Jun 12, 2025
7859080
Zjt/encrypt key from environment (#512)
zhujt20 Jun 12, 2025
2995362
Fix npe when closing a last reader that have not been used (#513)
jt2594838 Jun 16, 2025
6df6112
The TsFile-CPP query interface now validates column names before quer…
761417898 Jun 18, 2025
c501bf4
Resolved case sensitivity issue when reading column names. (#517)
761417898 Jun 18, 2025
af2a7ee
Fix tag empty error and disorder timestamp. (#489)
ColinLeeo Jun 19, 2025
caa77ac
[Java/C++/C] Resolved case sensitivity issue when reading column name…
761417898 Jun 19, 2025
58fa12f
fix read from iotdb data. (#520)
ColinLeeo Jun 20, 2025
04eb621
Fix bloom filter error.
ColinLeeo Jun 20, 2025
09015fa
[CPP]Fix/multi fileds column (#522)
761417898 Jun 24, 2025
de166a7
Support set default compression by data type (#523)
jt2594838 Jun 24, 2025
d2a906e
Fixes the issue where data with only timestamps could not be inserted…
ColinLeeo Jun 27, 2025
ed5b5dc
The column names in the addValue interface are case-insensitive (#526)
761417898 Jun 27, 2025
af0ec13
Use spotless to format CPP code (#528)
HTHou Jul 1, 2025
e7bdcad
fix some warning while compiling. (#527)
ColinLeeo Jul 2, 2025
6554a18
Correct the memroy calculation of BinaryColumnBuilder
JackieTien97 Jul 3, 2025
a2da0c9
[maven-release-plugin] prepare release v2.1.0
ColinLeeo Jul 4, 2025
efdba35
Revert "[maven-release-plugin] prepare release v2.1.0" (#533)
ColinLeeo Jul 4, 2025
7510d94
Fetch max tsblock line number each time from TSFileConfig
JackieTien97 Jul 7, 2025
c32e893
AbstractAlignedTimeSeriesMetadata.typeMatch always return true (#538)
shuwenwei Jul 8, 2025
4909442
Implement datatype TIMESTAMP BLOB TEXT DATE (#532)
761417898 Jul 9, 2025
a8e48ad
Ignore the null value passed in the Tablet.addValue method (#540)
shuwenwei Jul 9, 2025
110a5a2
Bump org.apache.commons:commons-lang3 from 3.15.0 to 3.18.0 in /java …
dependabot[bot] Jul 14, 2025
490d521
Update version info for tsfile v2.1.0 (#544)
ColinLeeo Jul 15, 2025
838d290
Implement extract time filters
Wei-hao-Li Jul 16, 2025
956d598
implement RLE DICTIONART ZIGZAG codec (#542)
761417898 Jul 17, 2025
d3eb61a
Init all series writer for AlignedChunkGroupWriter
shuwenwei Jul 18, 2025
04bbc0a
Check max tsfile version
shuwenwei Jul 21, 2025
898f1a6
include common in tsfile with shade (#510)
Inky19 Jul 22, 2025
ae3e8c8
Implement extract value filters
Wei-hao-Li Jul 22, 2025
ee647cb
fix wrong Private-Package declaration (#556)
Inky19 Jul 23, 2025
f1dad36
Feature/cpp codec sprintz (#553)
761417898 Jul 23, 2025
965f487
Avoid repeated calculation of shallow size of map
shuwenwei Jul 29, 2025
f3345b9
Refactor UnknownType to extend AbstractType
FearfulTomcat27 Jul 29, 2025
9ef4709
Add Tablet.append (#562)
jt2594838 Jul 30, 2025
f54f8b6
Provides complete implementation of all TagFilter operations
761417898 Aug 12, 2025
1dff37b
Add methods for RamUsageEstimator
shuwenwei Aug 12, 2025
b970e1f
implement new java writing interface for tree model
761417898 Aug 14, 2025
38a847d
generate main key (#519)
zhujt20 Aug 14, 2025
949a7a5
reduce zero-fill overhead on BitMap creation (#572)
luoluoyuyu Aug 15, 2025
858239f
Update release information after v2.1.1 released (#574)
HTHou Aug 18, 2025
95dbf6a
Feature/codec/camel (#560)
761417898 Aug 18, 2025
616e844
implement v4 tree-model read interface
761417898 Aug 18, 2025
c9838b0
Adjusted the sequence of measurements
761417898 Aug 18, 2025
94d5e06
Add licenses
761417898 Aug 18, 2025
550c482
Add support for alter column datatype (#567)
zerolbsony Aug 20, 2025
a426db2
Add v4 interface example
761417898 Aug 21, 2025
988beea
Add v4 PerformanceTest
761417898 Aug 22, 2025
01be82e
feat: add markRange / unmarkRange / merge for high-performance bit ma…
luoluoyuyu Aug 25, 2025
674a65c
perf: Optimize aligned object memory size calculation (#577)
luoluoyuyu Aug 27, 2025
a5fee93
[CPP/C] implement default encoding/compression configuration interfac…
761417898 Sep 1, 2025
dcdbcf8
Bump actions/first-interaction from 1.3.0 to 3.0.0 (#586)
dependabot[bot] Sep 3, 2025
fd1adb8
Bump actions/setup-java from 4 to 5 (#584)
dependabot[bot] Sep 3, 2025
5132d99
Alter column other type to string type (#588)
zerolbsony Sep 3, 2025
1dce1b0
Bump actions/checkout from 4 to 5 (#583)
dependabot[bot] Sep 4, 2025
39e55a3
Fix camel encoding error message and add check for each datatypes of …
HTHou Sep 18, 2025
83250e3
Modify the TsFileSequenceReaderTimeseriesMetadataIterator next functi…
luoluoyuyu Sep 28, 2025
c2a2937
add encrypt param for all the write/read struct initialization (#601)
zhujt20 Oct 10, 2025
1e5e7ef
Merge branch 'develop' into new_java_interfaces
761417898 Oct 16, 2025
84444eb
fix TableResultSet.Iterator unittest
761417898 Oct 16, 2025
12b4ce9
add license
761417898 Oct 17, 2025
a6d5696
spotless:apply
761417898 Oct 17, 2025
e1d0734
fix MeasurementSchemaBuilder getCompressor()
761417898 Oct 27, 2025
8ff0900
removed unused IDeviceID.toString()
761417898 Oct 27, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion java/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.15.0</version>
<version>3.18.0</version>
</dependency>
<dependency>
<groupId>org.lz4</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ public interface IDeviceID extends Comparable<IDeviceID>, Accountable, Serializa

boolean isTableModel();

String getDeviceID();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May just use toString().


/**
* @return the table name associated with the device. For a path-DeviceId, like "root.a.b.c.d", it
* is converted according to a fixed rule, like assuming the first three levels ("root.a.b")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,11 @@ public boolean isTableModel() {
return false;
}

@Override
public String getDeviceID() {
return deviceID;
}

@Override
public long ramBytesUsed() {
long size = INSTANCE_SIZE;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,11 @@ public boolean isTableModel() {
return !segments[0].startsWith(PATH_ROOT + PATH_SEPARATOR);
}

@Override
public String getDeviceID() {
return String.join(PATH_SEPARATOR, segments);
}

@Override
public String getTableName() {
return segments[0];
Expand Down
23 changes: 23 additions & 0 deletions java/tsfile/src/main/java/org/apache/tsfile/read/TsFileReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,23 @@
package org.apache.tsfile.read;

import org.apache.tsfile.annotations.TsFileApi;
import org.apache.tsfile.enums.TSDataType;
import org.apache.tsfile.file.metadata.IDeviceID;
import org.apache.tsfile.read.controller.CachedChunkLoaderImpl;
import org.apache.tsfile.read.controller.IChunkLoader;
import org.apache.tsfile.read.controller.IMetadataQuerier;
import org.apache.tsfile.read.controller.MetadataQuerierByFileImpl;
import org.apache.tsfile.read.expression.QueryExpression;
import org.apache.tsfile.read.query.dataset.QueryDataSet;
import org.apache.tsfile.read.query.executor.TsFileExecutor;
import org.apache.tsfile.write.schema.MeasurementSchema;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class TsFileReader implements AutoCloseable {

Expand Down Expand Up @@ -61,6 +68,22 @@ public QueryDataSet query(
return tsfileExecutor.execute(queryExpression, partitionStartOffset, partitionEndOffset);
}

public List<String> getAllDeviceIds() throws IOException {
List<IDeviceID> deviceIDList = fileReader.getAllDevices();
List<String> deviceIds = new ArrayList<>(deviceIDList.size());
for (IDeviceID deviceID : deviceIDList) {
deviceIds.add(deviceID.getDeviceID());
}
return deviceIds;
}

public List<MeasurementSchema> getMeasurement(IDeviceID deviceID) throws IOException {
Map<String, TSDataType> measurementMap = fileReader.getMeasurement(deviceID);
return measurementMap.entrySet().stream()
.map(entry -> new MeasurementSchema(entry.getKey(), entry.getValue()))
.collect(Collectors.toList());
}

@Override
@TsFileApi
public void close() throws IOException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2717,6 +2717,20 @@ public Map<String, TSDataType> getAllMeasurements() throws IOException {
return result;
}

/**
* get measurements for deviceID
*
* @return measurementSchema
*/
public Map<String, TSDataType> getMeasurement(IDeviceID deviceID) throws IOException {
Map<String, TSDataType> result = new HashMap<>();
Map<String, TimeseriesMetadata> timeseriesMetadataMap = readDeviceMetadata(deviceID);
for (TimeseriesMetadata timeseriesMetadata : timeseriesMetadataMap.values()) {
result.put(timeseriesMetadata.getMeasurementId(), timeseriesMetadata.getTsDataType());
}
return result;
}

/**
* get all types of measurements in this file
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,112 @@
package org.apache.tsfile.read.filter.factory;

import org.apache.tsfile.annotations.TsFileApi;
import org.apache.tsfile.common.regexp.LikePattern;
import org.apache.tsfile.file.metadata.TableSchema;
import org.apache.tsfile.read.filter.basic.Filter;
import org.apache.tsfile.read.filter.operator.And;
import org.apache.tsfile.read.filter.operator.Not;
import org.apache.tsfile.read.filter.operator.Or;
import org.apache.tsfile.read.filter.operator.TagFilterOperators;
import org.apache.tsfile.read.filter.operator.TagFilterOperators.ValueEq;
import org.apache.tsfile.write.schema.IMeasurementSchema;
import org.apache.tsfile.read.filter.operator.TagFilterOperators.ValueNotEq;

import java.util.Optional;
import java.util.regex.Pattern;

public class TagFilterBuilder {
private TableSchema tableSchema;
private final TableSchema tableSchema;

public TagFilterBuilder(TableSchema tableSchema) {
this.tableSchema = tableSchema;
}

@TsFileApi
public Filter eq(String columnName, Object value) {
private int getIdColumnIndex(String columnName) {
int idColumnOrder = tableSchema.findIdColumnOrder(columnName);
if (idColumnOrder == -1) {
throw new IllegalArgumentException("Column '" + columnName + "' is not a tag column");
}
IMeasurementSchema columnSchema = tableSchema.findColumnSchema(columnName);
return idColumnOrder + 1;
}

@TsFileApi
public Filter eq(String columnName, Object value) {
return new ValueEq(getIdColumnIndex(columnName), (String) value);
}

@TsFileApi
public Filter neq(String columnName, Object value) {
return new ValueNotEq(getIdColumnIndex(columnName), (String) value);
}

@TsFileApi
public Filter lt(String columnName, Object value) {
return new TagFilterOperators.ValueLt(getIdColumnIndex(columnName), (String) value);
}

@TsFileApi
public Filter lteq(String columnName, Object value) {
return new TagFilterOperators.ValueLtEq(getIdColumnIndex(columnName), (String) value);
}

@TsFileApi
public Filter gt(String columnName, Object value) {
return new TagFilterOperators.ValueGt(getIdColumnIndex(columnName), (String) value);
}

@TsFileApi
public Filter gteq(String columnName, Object value) {
return new TagFilterOperators.ValueGtEq(getIdColumnIndex(columnName), (String) value);
}

@TsFileApi
public Filter betweenAnd(String columnName, Object value1, Object value2) {
return new TagFilterOperators.ValueBetweenAnd(
getIdColumnIndex(columnName), (String) value1, (String) value2);
}

@TsFileApi
public Filter notBetweenAnd(String columnName, Object value1, Object value2) {
return new TagFilterOperators.ValueNotBetweenAnd(
getIdColumnIndex(columnName), (String) value1, (String) value2);
}

@TsFileApi
public Filter regExp(String columnName, String pattern) {
return new TagFilterOperators.ValueRegexp(
getIdColumnIndex(columnName), Pattern.compile(pattern));
}

@TsFileApi
public Filter notRegExp(String columnName, String pattern) {
return new TagFilterOperators.ValueNotRegexp(
getIdColumnIndex(columnName), Pattern.compile(pattern));
}

@TsFileApi
public Filter like(String columnName, String pattern) {
return new TagFilterOperators.ValueLike(
getIdColumnIndex(columnName), LikePattern.compile(pattern, Optional.empty()));
}

@TsFileApi
public Filter notLike(String columnName, String pattern) {
return new TagFilterOperators.ValueNotLike(
getIdColumnIndex(columnName), LikePattern.compile(pattern, Optional.empty()));
}

@TsFileApi
public Filter and(Filter left, Filter right) {
return new And(left, right);
}

@TsFileApi
public Filter or(Filter left, Filter right) {
return new Or(left, right);
}

// +1 for table name
return new ValueEq(idColumnOrder + 1, (String) value);
@TsFileApi
public Filter not(Filter value) {
return new Not(value);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,37 @@
package org.apache.tsfile.read.query.dataset;

import org.apache.tsfile.annotations.TsFileApi;
import org.apache.tsfile.file.metadata.StringArrayDeviceID;
import org.apache.tsfile.read.common.Field;
import org.apache.tsfile.read.common.Path;
import org.apache.tsfile.write.record.TSRecord;

import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class TreeResultSet extends AbstractResultSet {
private QueryDataSet queryDataSet;
private List<String> deviceList;
private List<String> measurementList;
private Map<Path, Integer> pathIndexMap;

public TreeResultSet(QueryDataSet queryDataSet) {
public TreeResultSet(
QueryDataSet queryDataSet, List<String> deviceIds, List<String> measurementNames) {
super(
queryDataSet.getPaths().stream().map(Path::toString).collect(Collectors.toList()),
queryDataSet.getDataTypes());
this.queryDataSet = queryDataSet;
this.deviceList = deviceIds;
this.measurementList = measurementNames;
List<Path> paths = queryDataSet.getPaths();
this.pathIndexMap =
IntStream.range(0, paths.size()).boxed().collect(Collectors.toMap(paths::get, i -> i));
}

@TsFileApi
Expand All @@ -56,6 +72,92 @@ public void close() {

@Override
public Iterator<TSRecord> recordIterator() {
return null;
return new TreeResultSet.RecordIterator();
}

private class RecordIterator implements Iterator<TSRecord> {
private final LinkedList<TSRecord> recordBuffer = new LinkedList<>();
private boolean exhausted = false;

@Override
public boolean hasNext() {
if (!recordBuffer.isEmpty()) {
return true;
}
if (exhausted) {
return false;
}

try {
return fetchRecords();
} catch (IOException e) {
throw new NoSuchElementException(e.toString());
}
}

private boolean fetchRecords() throws IOException {
boolean hasNewRecords = false;
while (TreeResultSet.this.next()) {
for (String device : deviceList) {
TSRecord record = new TSRecord(device, getLong("Time"));
record.addPoint("id", device);

for (String measurement : measurementList) {
Integer pathIdx =
pathIndexMap.get(new Path(new StringArrayDeviceID(device), measurement, false));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May cache the DeviceIds (or the paths) as a list. Recalculating them each time can be costly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

  private Map<String, Map<String, Path>> cachedPaths;

  // .......
    this.cachedPaths = new HashMap<>();
    for (String device : deviceList) {
      Map<String, Path> measurementPathMap = new HashMap<>();
      for (String measurement : measurementList) {
        measurementPathMap.put(measurement,
                new Path(new StringArrayDeviceID(device), measurement, false));
      }
      cachedPaths.put(device, measurementPathMap);
    }

if (pathIdx != null) {
Field field = currentRow.getField(pathIdx);
switch (field.getDataType()) {
case INT32:
case DATE:
record.addPoint(measurement, field.getIntV());
break;
case INT64:
case TIMESTAMP:
record.addPoint(measurement, field.getLongV());
break;
case FLOAT:
record.addPoint(measurement, field.getFloatV());
break;
case DOUBLE:
record.addPoint(measurement, field.getDoubleV());
break;
case STRING:
case TEXT:
record.addPoint(measurement, field.getStringValue());
break;
case BLOB:
record.addPoint(measurement, field.getBinaryV().getValues());
break;
case BOOLEAN:
record.addPoint(measurement, field.getBoolV());
break;
case VECTOR:
case UNKNOWN:
default:
break;
}
} else {
record.dataPointList.add(null);
}
}
recordBuffer.add(record);
hasNewRecords = true;
}
}
if (!hasNewRecords) {
exhausted = true;
return false;
}
return true;
}

@Override
public TSRecord next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return recordBuffer.poll();
}
}
}
Loading