From 761e9e5a16426b3c698e38a750c55d3c72bdb46e Mon Sep 17 00:00:00 2001 From: ColinLee Date: Thu, 25 Jun 2026 18:36:34 +0800 Subject: [PATCH 1/4] update dataframe series schema. --- .../develop/DataFrame/TsFileDataFrame.md | 25 +++++++++++-------- .../latest/DataFrame/TsFileDataFrame.md | 25 +++++++++++-------- .../develop/DataFrame/TsFileDataFrame.md | 7 +++--- .../latest/DataFrame/TsFileDataFrame.md | 7 +++--- 4 files changed, 36 insertions(+), 28 deletions(-) diff --git a/src/UserGuide/develop/DataFrame/TsFileDataFrame.md b/src/UserGuide/develop/DataFrame/TsFileDataFrame.md index db290bbd6..91a32ee8e 100644 --- a/src/UserGuide/develop/DataFrame/TsFileDataFrame.md +++ b/src/UserGuide/develop/DataFrame/TsFileDataFrame.md @@ -113,25 +113,28 @@ with `.`, in that order: {table_name}.{tag_value_1}.{tag_value_2}...{field_name} ``` -`list_timeseries()` returns series names; name-based indexing (`df[...]`) and -series selection in `df.loc[...]` both take a series name. +`list_timeseries()` returns `SeriesPath` objects — a `str` subclass whose value +is the escaped path above, so each works directly as a key in `df[...]` and +`df.loc[...]`. A `SeriesPath` also exposes its parts as `.table`, `.tags` (a +tuple, with `None` for a null tag), and `.field`. Examples: - `weather.Beijing.humidity` — table `weather`, tag `Beijing`, field `humidity` - `sensor.s1.pressure` — table `sensor`, tag `s1`, field `pressure` -**Dots inside a name.** Because `.` separates the parts, a `.` that belongs to a -table, tag, or field name is escaped with a backslash. `list_timeseries()` -returns the escaped form — e.g. a `weather` table with tag value `Bei.jing` and -field `humidity` is rendered as `weather.Bei\.jing.humidity` (a literal `\` -becomes `\\`). Selecting it needs the same escaped form: the unescaped -`weather.Bei.jing.humidity` would be read as two tags `Bei` and `jing`. Reuse the -string `list_timeseries()` returns, or type it as a raw string so Python keeps -the backslash: +**Escaping in a name.** `.` separates the parts, so a `.` inside a table, tag, or +field name is escaped with a backslash, and a null tag value is written as `\N` +(distinct from the literal string `"null"`). `list_timeseries()` returns this +escaped form — e.g. tag value `Bei.jing` in table `weather` renders as +`weather.Bei\.jing.humidity` (a literal `\` becomes `\\`). Selecting needs the +same escaped form, so reuse the `SeriesPath` from `list_timeseries()` (or read +its `.table` / `.tags` / `.field` parts) rather than hand-building it; if you do +type one, use a raw string so Python keeps the backslash: ```python -df[r"weather.Bei\.jing.humidity"] # selects the device whose tag is "Bei.jing" +df[r"weather.Bei\.jing.humidity"] # tag "Bei.jing" (the dot is part of the value) +df[r"weather.\N.Beijing.humidity"] # tags (null, "Beijing") ``` > A series name can be obtained from `list_timeseries()` and need not be diff --git a/src/UserGuide/latest/DataFrame/TsFileDataFrame.md b/src/UserGuide/latest/DataFrame/TsFileDataFrame.md index db290bbd6..91a32ee8e 100644 --- a/src/UserGuide/latest/DataFrame/TsFileDataFrame.md +++ b/src/UserGuide/latest/DataFrame/TsFileDataFrame.md @@ -113,25 +113,28 @@ with `.`, in that order: {table_name}.{tag_value_1}.{tag_value_2}...{field_name} ``` -`list_timeseries()` returns series names; name-based indexing (`df[...]`) and -series selection in `df.loc[...]` both take a series name. +`list_timeseries()` returns `SeriesPath` objects — a `str` subclass whose value +is the escaped path above, so each works directly as a key in `df[...]` and +`df.loc[...]`. A `SeriesPath` also exposes its parts as `.table`, `.tags` (a +tuple, with `None` for a null tag), and `.field`. Examples: - `weather.Beijing.humidity` — table `weather`, tag `Beijing`, field `humidity` - `sensor.s1.pressure` — table `sensor`, tag `s1`, field `pressure` -**Dots inside a name.** Because `.` separates the parts, a `.` that belongs to a -table, tag, or field name is escaped with a backslash. `list_timeseries()` -returns the escaped form — e.g. a `weather` table with tag value `Bei.jing` and -field `humidity` is rendered as `weather.Bei\.jing.humidity` (a literal `\` -becomes `\\`). Selecting it needs the same escaped form: the unescaped -`weather.Bei.jing.humidity` would be read as two tags `Bei` and `jing`. Reuse the -string `list_timeseries()` returns, or type it as a raw string so Python keeps -the backslash: +**Escaping in a name.** `.` separates the parts, so a `.` inside a table, tag, or +field name is escaped with a backslash, and a null tag value is written as `\N` +(distinct from the literal string `"null"`). `list_timeseries()` returns this +escaped form — e.g. tag value `Bei.jing` in table `weather` renders as +`weather.Bei\.jing.humidity` (a literal `\` becomes `\\`). Selecting needs the +same escaped form, so reuse the `SeriesPath` from `list_timeseries()` (or read +its `.table` / `.tags` / `.field` parts) rather than hand-building it; if you do +type one, use a raw string so Python keeps the backslash: ```python -df[r"weather.Bei\.jing.humidity"] # selects the device whose tag is "Bei.jing" +df[r"weather.Bei\.jing.humidity"] # tag "Bei.jing" (the dot is part of the value) +df[r"weather.\N.Beijing.humidity"] # tags (null, "Beijing") ``` > A series name can be obtained from `list_timeseries()` and need not be diff --git a/src/zh/UserGuide/develop/DataFrame/TsFileDataFrame.md b/src/zh/UserGuide/develop/DataFrame/TsFileDataFrame.md index 0a8876c9b..816a8cca6 100644 --- a/src/zh/UserGuide/develop/DataFrame/TsFileDataFrame.md +++ b/src/zh/UserGuide/develop/DataFrame/TsFileDataFrame.md @@ -106,17 +106,18 @@ TsFileDataFrame 以**序列名**(一个字符串)作为序列的唯一标识 {表名}.{标签值1}.{标签值2}...{字段名} ``` -`list_timeseries()` 返回的即为序列名;按名称索引(`df[...]`)与 `df.loc[...]` 中的序列选择均以序列名为参数。 +`list_timeseries()` 返回 `SeriesPath` 对象——`str` 的子类,其字符串值即上面的转义路径,可直接用作 `df[...]`、`df.loc[...]` 的键;它还以 `.table`、`.tags`(元组,`None` 表示空标签)、`.field` 暴露各组成部分。 示例: - `weather.Beijing.humidity` — 表 `weather`,标签 `Beijing`,字段 `humidity` - `sensor.s1.pressure` — 表 `sensor`,标签 `s1`,字段 `pressure` -**名称中含点号时。** 由于 `.` 用作分隔符,属于表名/标签/字段名本身的 `.` 会用反斜杠转义。`list_timeseries()` 返回的是转义后的形式——例如表 `weather`、标签值 `Bei.jing`、字段 `humidity`,渲染为 `weather.Bei\.jing.humidity`(字面 `\` 转义为 `\\`)。选取时也要用这种转义形式:若传未转义的 `weather.Bei.jing.humidity`,会被当成 `Bei`、`jing` 两个标签。直接复用 `list_timeseries()` 的返回值,或用 raw string 让 Python 保留反斜杠: +**名称中的转义。** `.` 用作分隔符,因此属于表名/标签/字段名本身的 `.` 会用反斜杠转义;空标签值写作 `\N`(与字面字符串 `"null"` 区分)。`list_timeseries()` 返回的就是这种转义形式——例如表 `weather` 中标签值 `Bei.jing`、字段 `humidity` 渲染为 `weather.Bei\.jing.humidity`(字面 `\` 转义为 `\\`)。选取时也要用这种转义形式,因此请直接复用 `list_timeseries()` 返回的 `SeriesPath`(或读取它的 `.table`/`.tags`/`.field`),不要手拼;若确需手写,请用 raw string 让 Python 保留反斜杠: ```python -df[r"weather.Bei\.jing.humidity"] # 选中标签为 "Bei.jing" 的设备 +df[r"weather.Bei\.jing.humidity"] # 标签 "Bei.jing"(点号是值的一部分) +df[r"weather.\N.Beijing.humidity"] # 标签 (null, "Beijing") ``` > 序列名可由 `list_timeseries()` 获取,无需手工构造;亦可改用整数索引(`df[0]`)或元数据过滤 diff --git a/src/zh/UserGuide/latest/DataFrame/TsFileDataFrame.md b/src/zh/UserGuide/latest/DataFrame/TsFileDataFrame.md index 0a8876c9b..816a8cca6 100644 --- a/src/zh/UserGuide/latest/DataFrame/TsFileDataFrame.md +++ b/src/zh/UserGuide/latest/DataFrame/TsFileDataFrame.md @@ -106,17 +106,18 @@ TsFileDataFrame 以**序列名**(一个字符串)作为序列的唯一标识 {表名}.{标签值1}.{标签值2}...{字段名} ``` -`list_timeseries()` 返回的即为序列名;按名称索引(`df[...]`)与 `df.loc[...]` 中的序列选择均以序列名为参数。 +`list_timeseries()` 返回 `SeriesPath` 对象——`str` 的子类,其字符串值即上面的转义路径,可直接用作 `df[...]`、`df.loc[...]` 的键;它还以 `.table`、`.tags`(元组,`None` 表示空标签)、`.field` 暴露各组成部分。 示例: - `weather.Beijing.humidity` — 表 `weather`,标签 `Beijing`,字段 `humidity` - `sensor.s1.pressure` — 表 `sensor`,标签 `s1`,字段 `pressure` -**名称中含点号时。** 由于 `.` 用作分隔符,属于表名/标签/字段名本身的 `.` 会用反斜杠转义。`list_timeseries()` 返回的是转义后的形式——例如表 `weather`、标签值 `Bei.jing`、字段 `humidity`,渲染为 `weather.Bei\.jing.humidity`(字面 `\` 转义为 `\\`)。选取时也要用这种转义形式:若传未转义的 `weather.Bei.jing.humidity`,会被当成 `Bei`、`jing` 两个标签。直接复用 `list_timeseries()` 的返回值,或用 raw string 让 Python 保留反斜杠: +**名称中的转义。** `.` 用作分隔符,因此属于表名/标签/字段名本身的 `.` 会用反斜杠转义;空标签值写作 `\N`(与字面字符串 `"null"` 区分)。`list_timeseries()` 返回的就是这种转义形式——例如表 `weather` 中标签值 `Bei.jing`、字段 `humidity` 渲染为 `weather.Bei\.jing.humidity`(字面 `\` 转义为 `\\`)。选取时也要用这种转义形式,因此请直接复用 `list_timeseries()` 返回的 `SeriesPath`(或读取它的 `.table`/`.tags`/`.field`),不要手拼;若确需手写,请用 raw string 让 Python 保留反斜杠: ```python -df[r"weather.Bei\.jing.humidity"] # 选中标签为 "Bei.jing" 的设备 +df[r"weather.Bei\.jing.humidity"] # 标签 "Bei.jing"(点号是值的一部分) +df[r"weather.\N.Beijing.humidity"] # 标签 (null, "Beijing") ``` > 序列名可由 `list_timeseries()` 获取,无需手工构造;亦可改用整数索引(`df[0]`)或元数据过滤 From c44b3897e8965ff233ff65daea14dc831275d7bf Mon Sep 17 00:00:00 2001 From: ColinLee Date: Thu, 9 Jul 2026 18:06:58 +0800 Subject: [PATCH 2/4] Update interface docs from develop --- .../develop/DataFrame/TsFileDataFrame.md | 21 +- .../InterfaceDefinition-C.md | 211 ++++++++++++++++- .../InterfaceDefinition-CPP.md | 147 +++++++++++- .../InterfaceDefinition-Python.md | 171 +++++++++++++- .../latest/DataFrame/TsFileDataFrame.md | 21 +- .../InterfaceDefinition-C.md | 211 ++++++++++++++++- .../InterfaceDefinition-CPP.md | 147 +++++++++++- .../InterfaceDefinition-Python.md | 171 +++++++++++++- .../develop/DataFrame/TsFileDataFrame.md | 21 +- .../InterfaceDefinition-C.md | 213 +++++++++++++++++- .../InterfaceDefinition-CPP.md | 145 +++++++++++- .../InterfaceDefinition-Python.md | 165 +++++++++++++- .../latest/DataFrame/TsFileDataFrame.md | 21 +- .../InterfaceDefinition-C.md | 213 +++++++++++++++++- .../InterfaceDefinition-CPP.md | 145 +++++++++++- .../InterfaceDefinition-Python.md | 165 +++++++++++++- 16 files changed, 2102 insertions(+), 86 deletions(-) diff --git a/src/UserGuide/develop/DataFrame/TsFileDataFrame.md b/src/UserGuide/develop/DataFrame/TsFileDataFrame.md index 91a32ee8e..dbd88160e 100644 --- a/src/UserGuide/develop/DataFrame/TsFileDataFrame.md +++ b/src/UserGuide/develop/DataFrame/TsFileDataFrame.md @@ -64,9 +64,11 @@ In the table below, `df` is a `TsFileDataFrame` instance, created with | Example | Operation | Returns | |---|---|---| -| `TsFileDataFrame(paths)` | Load a file / list of files / directory | `TsFileDataFrame` | +| `TsFileDataFrame(paths, show_progress=True)` | Load a file / list of files / directory. Set `show_progress=False` to silence loading progress on stderr | `TsFileDataFrame` | | `len(df)` | Number of time series | `int` | +| `df.model` | Loaded file model: `"table"` or `"tree"` | `str` | | `df.list_timeseries("weather")` | Series names, optionally filtered by prefix | `List[str]` | +| `df.list_timeseries_metadata("weather")` | Series metadata, optionally filtered by prefix | `pandas.DataFrame` | | `df["weather.Beijing.humidity"]`, `df[0]`, `df[-1]` | One series | `Timeseries` | | `df["city"]` | A metadata column (a tag / `field` / `start_time` / `end_time` / `count`) | `pandas.Series` | | `df[0:3]`, `df[[0, 2, 5]]` | Subset view by integer position: a contiguous range (`0:3`), or the listed positions (`[0, 2, 5]`); positions are the printed `index` column | `TsFileDataFrame` | @@ -150,6 +152,7 @@ from tsfile import TsFileDataFrame df = TsFileDataFrame(["data/weather.tsfile", "data/sensor.tsfile"]) df = TsFileDataFrame("data/") # recursively find every .tsfile under the directory +df = TsFileDataFrame("data/", show_progress=False) print(df) ``` @@ -203,7 +206,21 @@ optionally filtered by a prefix. Calling it with no argument returns all series. ``` To inspect metadata such as start/end time and count, print the DataFrame (or a -subset of it) — see [Displaying a DataFrame](#displaying-a-dataframe). +subset of it) — see [Displaying a DataFrame](#displaying-a-dataframe) — or call +`list_timeseries_metadata()`. + +## Inspecting metadata + +`list_timeseries_metadata(path_prefix="")` returns a pandas DataFrame indexed by +series name. It includes `field`, `start_time`, `end_time`, `count`, and the +device tag columns. For table-model files it also includes the `table` column. + +```python +meta = df.list_timeseries_metadata() +weather_meta = df.list_timeseries_metadata("weather") + +meta[["field", "start_time", "end_time", "count"]].head() +``` ## Selecting series diff --git a/src/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md b/src/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md index 0fb0c1e36..262cb5148 100644 --- a/src/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md +++ b/src/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md @@ -32,10 +32,12 @@ typedef enum { TS_DATATYPE_FLOAT = 3, TS_DATATYPE_DOUBLE = 4, TS_DATATYPE_TEXT = 5, + TS_DATATYPE_VECTOR = 6, TS_DATATYPE_TIMESTAMP = 8, TS_DATATYPE_DATE = 9, TS_DATATYPE_BLOB = 10, TS_DATATYPE_STRING = 11, + TS_DATATYPE_NULL_TYPE = 254, TS_DATATYPE_INVALID = 255 } TSDataType; @@ -44,10 +46,18 @@ typedef enum { TS_ENCODING_PLAIN = 0, TS_ENCODING_DICTIONARY = 1, TS_ENCODING_RLE = 2, + TS_ENCODING_DIFF = 3, TS_ENCODING_TS_2DIFF = 4, + TS_ENCODING_BITMAP = 5, + TS_ENCODING_GORILLA_V1 = 6, + TS_ENCODING_REGULAR = 7, TS_ENCODING_GORILLA = 8, TS_ENCODING_ZIGZAG = 9, + TS_ENCODING_FREQ = 10, + TS_ENCODING_CHIMP = 11, TS_ENCODING_SPRINTZ = 12, + TS_ENCODING_RLBE = 13, + TS_ENCODING_CAMEL = 14, TS_ENCODING_INVALID = 255 } TSEncoding; @@ -57,7 +67,12 @@ typedef enum { TS_COMPRESSION_SNAPPY = 1, TS_COMPRESSION_GZIP = 2, TS_COMPRESSION_LZO = 3, + TS_COMPRESSION_SDT = 4, + TS_COMPRESSION_PAA = 5, + TS_COMPRESSION_PLA = 6, TS_COMPRESSION_LZ4 = 7, + TS_COMPRESSION_ZSTD = 8, + TS_COMPRESSION_LZMA2 = 9, TS_COMPRESSION_INVALID = 255 } CompressionType; @@ -86,6 +101,19 @@ typedef struct table_schema { int column_num; } TableSchema; +typedef struct timeseries_schema { + char* timeseries_name; + TSDataType data_type; + TSEncoding encoding; + CompressionType compression; +} TimeseriesSchema; + +typedef struct device_schema { + char* device_name; + TimeseriesSchema* timeseries_schema; + int timeseries_num; +} DeviceSchema; + // ResultSetMetaData: Contains metadata for a result set, // such as column names and their data types. typedef struct result_set_meta_data { @@ -93,11 +121,73 @@ typedef struct result_set_meta_data { TSDataType* data_types; int column_num; } ResultSetMetaData; + +typedef struct arrow_schema ArrowSchema; +typedef struct arrow_array ArrowArray; + +typedef struct DeviceID { + char* path; + char* table_name; + uint32_t segment_count; + char** segments; +} DeviceID; + +typedef struct TsFileStatisticBase { + bool has_statistic; + TSDataType type; + int32_t row_count; + int64_t start_time; + int64_t end_time; +} TsFileStatisticBase; + +typedef struct TsFileBoolStatistic { TsFileStatisticBase base; double sum; bool first_bool; bool last_bool; } TsFileBoolStatistic; +typedef struct TsFileIntStatistic { TsFileStatisticBase base; double sum; int64_t min_int64; int64_t max_int64; int64_t first_int64; int64_t last_int64; } TsFileIntStatistic; +typedef struct TsFileFloatStatistic { TsFileStatisticBase base; double sum; double min_float64; double max_float64; double first_float64; double last_float64; } TsFileFloatStatistic; +typedef struct TsFileStringStatistic { TsFileStatisticBase base; char* str_min; char* str_max; char* str_first; char* str_last; } TsFileStringStatistic; +typedef struct TsFileTextStatistic { TsFileStatisticBase base; char* str_first; char* str_last; } TsFileTextStatistic; + +typedef union TimeseriesStatisticUnion { + TsFileBoolStatistic bool_s; + TsFileIntStatistic int_s; + TsFileFloatStatistic float_s; + TsFileStringStatistic string_s; + TsFileTextStatistic text_s; +} TimeseriesStatisticUnion; + +typedef struct TimeseriesStatistic { + TimeseriesStatisticUnion u; +} TimeseriesStatistic; + +#define tsfile_statistic_base(s) ((TsFileStatisticBase*)&(s)->u) + +typedef struct TimeseriesMetadata { + char* measurement_name; + TSDataType data_type; + int32_t chunk_meta_count; + TimeseriesStatistic statistic; + TimeseriesStatistic timeline_statistic; +} TimeseriesMetadata; + +typedef struct DeviceTimeseriesMetadataEntry { + DeviceID device; + TimeseriesMetadata* timeseries; + uint32_t timeseries_count; +} DeviceTimeseriesMetadataEntry; + +typedef struct DeviceTimeseriesMetadataMap { + DeviceTimeseriesMetadataEntry* entries; + uint32_t device_count; +} DeviceTimeseriesMetadataMap; ``` > `ColumnSchema` does not carry encoding/compression: on write, columns follow the > global defaults (see [Configuration](#configuration-encoding--compression)); on > read, each column is decoded with the file's actual settings. +> +> `TimeseriesStatistic` is a tagged union in `tsfile_cwrapper.h`. Read common +> fields through `tsfile_statistic_base(&metadata.statistic)` and then use the +> active typed member (`int_s`, `float_s`, `bool_s`, `string_s`, or `text_s`) +> according to the statistic data type. ## Write Interface @@ -220,9 +310,11 @@ ERRNO tablet_add_timestamp(Tablet tablet, uint32_t row_index, * @param value [in] Null-terminated string. Ownership remains with caller. * @return ERRNO. */ -ERRNO tablet_add_value_by_name_string(Tablet tablet, uint32_t row_index, - const char* column_name, - const char* value); +ERRNO tablet_add_value_by_name_string_with_len(Tablet tablet, + uint32_t row_index, + const char* column_name, + const char* value, + int value_len); // Supports multiple data types ERRNO tablet_add_value_by_name_int32_t(Tablet tablet, uint32_t row_index, @@ -250,9 +342,11 @@ ERRNO tablet_add_value_by_name_bool(Tablet tablet, uint32_t row_index, * * @param value [in] Null-terminated string. Copied internally. */ -ERRNO tablet_add_value_by_index_string(Tablet tablet, uint32_t row_index, - uint32_t column_index, - const char* value); +ERRNO tablet_add_value_by_index_string_with_len(Tablet tablet, + uint32_t row_index, + uint32_t column_index, + const char* value, + int value_len); // Supports multiple data types @@ -329,11 +423,13 @@ Allowed encodings per data type, and the default used when you do not change it: | Data type | Allowed encodings | Default | |---|---|---| | `BOOLEAN` | `PLAIN` | `PLAIN` | -| `INT32`, `INT64`, `DATE` | `PLAIN`, `TS_2DIFF`, `GORILLA`, `ZIGZAG`, `RLE`, `SPRINTZ` | `TS_2DIFF` | -| `FLOAT`, `DOUBLE` | `PLAIN`, `TS_2DIFF`, `GORILLA`, `SPRINTZ` | `GORILLA` | +| `INT32`, `INT64`, `TIMESTAMP`, `DATE` | `PLAIN`, `TS_2DIFF`, `GORILLA`, `ZIGZAG`, `RLE`, `SPRINTZ`, `CHIMP`, `RLBE` | `TS_2DIFF` | +| `FLOAT` | `PLAIN`, `TS_2DIFF`, `GORILLA`, `SPRINTZ`, `CHIMP`, `RLBE` | `GORILLA` | +| `DOUBLE` | `PLAIN`, `TS_2DIFF`, `GORILLA`, `SPRINTZ`, `CHIMP`, `RLBE`, `CAMEL` | `GORILLA` | | `STRING`, `TEXT` | `PLAIN`, `DICTIONARY` | `PLAIN` | -Compression applies to any data type: `UNCOMPRESSED`, `SNAPPY`, `GZIP`, `LZO`, or `LZ4` (default `LZ4`). +Compression applies to any data type: `UNCOMPRESSED`, `SNAPPY`, `GZIP`, `LZO`, +`LZ4`, `ZSTD`, or `LZMA2` (default `LZ4`). ```C // e.g. write every column with LZ4 compression @@ -412,6 +508,31 @@ void free_tsfile_result_set(ResultSet* result_set); ``` +### Tree queries + +```C +/** + * @brief Query tree-model data by measurement names within a time range. + */ +ResultSet tsfile_query_table_on_tree(TsFileReader reader, char** columns, + uint32_t column_num, Timestamp start_time, + Timestamp end_time, ERRNO* err_code); + +/** + * @brief Query tree-model data by row with offset/limit. + * + * @param device_ids Array of device identifiers. + * @param measurement_names Array of measurement names. + * @param offset Leading rows to skip (>= 0). + * @param limit Max rows to return; < 0 means unlimited. + */ +ResultSet tsfile_reader_query_tree_by_row(TsFileReader reader, + char** device_ids, int device_ids_len, + char** measurement_names, + int measurement_names_len, int offset, + int limit, ERRNO* err_code); +``` + ### Filtering by tag @@ -436,6 +557,8 @@ typedef enum { TAG_FILTER_GTEQ = 5, // column >= value TAG_FILTER_REGEXP = 6, // column matches the regex value TAG_FILTER_NOT_REGEXP = 7, // column does not match the regex value + TAG_FILTER_IS_NULL = 8, // column is null + TAG_FILTER_IS_NOT_NULL = 9, // column is not null } TagFilterOp; /** @@ -444,7 +567,7 @@ typedef enum { * @param reader [in] Valid TsFileReader handle. * @param table_name [in] Table whose schema defines the TAG columns. * @param column_name [in] Name of the TAG column to filter on. - * @param value [in] Comparison value (TAG columns are STRING). + * @param value [in] Comparison value (ignored for IS NULL / IS NOT NULL). * @param op [in] Comparison operator (TagFilterOp). * @param err_code [out] RET_OK(0) on success, or error code in errno_define_c.h. * @return TagFilterHandle on success; NULL on failure. @@ -465,6 +588,20 @@ TagFilterHandle tsfile_tag_filter_between(TsFileReader reader, const char* lower, const char* upper, bool is_not, ERRNO* err_code); +// Convenience builders for common single-column predicates. +TagFilterHandle tsfile_tag_filter_eq(TsFileReader reader, const char* table_name, + const char* column_name, const char* value); +TagFilterHandle tsfile_tag_filter_neq(TsFileReader reader, const char* table_name, + const char* column_name, const char* value); +TagFilterHandle tsfile_tag_filter_lt(TsFileReader reader, const char* table_name, + const char* column_name, const char* value); +TagFilterHandle tsfile_tag_filter_lteq(TsFileReader reader, const char* table_name, + const char* column_name, const char* value); +TagFilterHandle tsfile_tag_filter_gt(TsFileReader reader, const char* table_name, + const char* column_name, const char* value); +TagFilterHandle tsfile_tag_filter_gteq(TsFileReader reader, const char* table_name, + const char* column_name, const char* value); + // Combine predicates. AND/OR/NOT take ownership of their children; free the root only. TagFilterHandle tsfile_tag_filter_and(TagFilterHandle left, TagFilterHandle right); TagFilterHandle tsfile_tag_filter_or(TagFilterHandle left, TagFilterHandle right); @@ -522,6 +659,18 @@ ResultSet tsfile_query_table_with_tag_filter( TagFilterHandle tag_filter, int batch_size, ERRNO* err_code); ``` +### Read batch results as Arrow + +Batch query result sets (`batch_size > 0`) can be fetched as Arrow C Data +Interface arrays and schemas. The caller owns the returned Arrow objects and +must call their `release` callbacks when finished. + +```C +ERRNO tsfile_result_set_get_next_tsblock_as_arrow(ResultSet result_set, + ArrowArray* out_array, + ArrowSchema* out_schema); +``` + Example — read `temperature` only for devices whose `region` TAG equals `shanghai`: @@ -664,17 +813,59 @@ TableSchema tsfile_reader_get_table_schema(TsFileReader reader, TableSchema* tsfile_reader_get_all_table_schemas(TsFileReader reader, uint32_t* size); +/** + * @brief Gets all timeseries schema in the tsfile. + * @param size[out] number of DeviceSchema elements in the returned array. + * @return DeviceSchema*, an array of device schemas. + * @note The caller must call free_device_schema() on each element + * and free() the array pointer. + */ +DeviceSchema* tsfile_reader_get_all_timeseries_schemas(TsFileReader reader, + uint32_t* size); + /** * @brief Free the tableschema's space. * @param schema [in] the table schema to be freed. */ void free_table_schema(TableSchema schema); + +void free_device_schema(DeviceSchema schema); ``` +### Get Devices and Timeseries Metadata +```C +/** + * @brief Lists all devices in the file. + * + * @param out_devices[out] allocated array; free with tsfile_free_device_id_array(). + * @param out_length[out] number of devices in the returned array. + */ +ERRNO tsfile_reader_get_all_devices(TsFileReader reader, DeviceID** out_devices, + uint32_t* out_length); +void tsfile_free_device_id_array(DeviceID* devices, uint32_t length); +void tsfile_device_id_free_contents(DeviceID* d); +/** + * @brief Timeseries metadata for all devices in the file. + */ +ERRNO tsfile_reader_get_timeseries_metadata_all( + TsFileReader reader, DeviceTimeseriesMetadataMap* out_map); +/** + * @brief Timeseries metadata for the specified devices. + * + * length == 0 returns an empty map. For non-empty input, each DeviceID.path + * should contain the canonical device path. + */ +ERRNO tsfile_reader_get_timeseries_metadata_for_devices( + TsFileReader reader, const DeviceID* devices, uint32_t length, + DeviceTimeseriesMetadataMap* out_map); + +void tsfile_free_device_timeseries_metadata_map( + DeviceTimeseriesMetadataMap* map); +``` diff --git a/src/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md b/src/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md index 496e48aca..d37e00777 100644 --- a/src/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md +++ b/src/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md @@ -31,10 +31,14 @@ enum TSDataType : uint8_t { FLOAT = 3, DOUBLE = 4, TEXT = 5, + VECTOR = 6, + UNKNOWN = 7, TIMESTAMP = 8, DATE = 9, BLOB = 10, STRING = 11, + NULL_TYPE = 254, + INVALID_DATATYPE = 255, }; // Value encoding. See the table below for which encodings apply to which types. @@ -42,19 +46,35 @@ enum TSEncoding : uint8_t { PLAIN = 0, DICTIONARY = 1, RLE = 2, + DIFF = 3, TS_2DIFF = 4, + BITMAP = 5, + GORILLA_V1 = 6, + REGULAR = 7, GORILLA = 8, ZIGZAG = 9, + FREQ = 10, + CHIMP = 11, SPRINTZ = 12, + RLBE = 13, + CAMEL = 14, + INVALID_ENCODING = 255, }; -// Compression type. SNAPPY/GZIP/LZO/LZ4 depend on build options; LZ4 is the default. +// Compression type. SNAPPY/GZIP/LZO/LZ4/ZSTD/LZMA2 depend on build options; +// LZ4 is the default. enum CompressionType : uint8_t { UNCOMPRESSED = 0, SNAPPY = 1, GZIP = 2, LZO = 3, + SDT = 4, + PAA = 5, + PLA = 6, LZ4 = 7, + ZSTD = 8, + LZMA2 = 9, + INVALID_COMPRESSION = 255, }; // Column role within a table schema. @@ -72,6 +92,8 @@ Encodings applicable to each data type: | `GORILLA` | `INT32`, `INT64`, `TIMESTAMP`, `DATE`, `FLOAT`, `DOUBLE` | | `ZIGZAG` | `INT32`, `INT64` | | `SPRINTZ` | `INT32`, `INT64`, `FLOAT`, `DOUBLE` | +| `CHIMP`, `RLBE` | `INT32`, `INT64`, `TIMESTAMP`, `DATE`, `FLOAT`, `DOUBLE` | +| `CAMEL` | `DOUBLE` | Default value encoding per type: `BOOLEAN → PLAIN`, `INT32 / INT64 → TS_2DIFF`, `FLOAT / DOUBLE → GORILLA`, `TEXT / STRING / BLOB → PLAIN`. The default @@ -134,6 +156,65 @@ class TsFileTableWriter { }; ``` +### TsFileWriter + +`TsFileWriter` is the lower-level writer interface from `tsfile_writer.h`. It +supports both tree-model and table-model writes. + +```cpp +extern int libtsfile_init(); +extern void libtsfile_destroy(); + +// Writer configuration. Invalid values return common::E_INVALID_ARG and leave +// the previous value unchanged. +extern int set_page_max_point_count(uint32_t page_max_point_count); +extern int set_max_degree_of_index_node(uint32_t max_degree_of_index_node); + +class TsFileWriter { + public: + TsFileWriter(); + ~TsFileWriter(); + void destroy(); + + int open(const std::string& file_path, int flags, mode_t mode); + int open(const std::string& file_path); + int init(storage::WriteFile* write_file); + int init(storage::RestorableTsFileIOWriter* rw); + + void set_generate_table_schema(bool generate_table_schema); + + int register_timeseries(const std::string& device_id, + const MeasurementSchema& measurement_schema); + int register_timeseries( + const std::string& device_path, + const std::vector& measurement_schema_vec); + int register_aligned_timeseries( + const std::string& device_id, + const MeasurementSchema& measurement_schema); + int register_aligned_timeseries( + const std::string& device_id, + const std::vector& measurement_schemas); + int register_table(const std::shared_ptr& table_schema); + + int write_record(const TsRecord& record); + int write_tablet(const Tablet& tablet); + int write_record_aligned(const TsRecord& record); + int write_tablet_aligned(const Tablet& tablet); + int write_tree(const Tablet& tablet); + int write_tree(const TsRecord& record); + int write_table(Tablet& tablet); + + DeviceSchemasMap* get_schema_group_map(); + std::shared_ptr get_table_schema( + const std::string& table_name) const; + int64_t calculate_mem_size_for_all_group(); + int64_t calculate_meta_mem_size() const; + int check_memory_size_and_may_flush_chunks(); + int flush(); + int close(); +}; +``` + ### TableSchema Describe the data structure of the table schema @@ -300,8 +381,14 @@ uint8_t common::get_global_compression(); // Time-column encoding/compression (the data type is fixed to INT64). int common::set_global_time_encoding(uint8_t encoding); int common::set_global_time_compression(uint8_t compression); +uint8_t common::get_global_time_encoding(); +uint8_t common::get_global_time_compression(); ``` +Global compression accepts `UNCOMPRESSED`, `SNAPPY`, `GZIP`, `LZO`, `LZ4`, +`ZSTD`, and `LZMA2`. The codec enum also contains legacy values such as `SDT`, +`PAA`, and `PLA`, but the global compression setter rejects them. + ## Read Interface ### Tsfile Reader ```cpp @@ -339,6 +426,17 @@ class TsFileReader { * @return Returns 0 on success, or a non-zero error code on failure. */ int query(storage::QueryExpression *qe, ResultSet *&ret_qds); + /** + * @brief query the tsfile by the path list, start time and end time. + * This method is used to query the tree model. + * + * @param [in] path_list the full path list + * @param [in] start_time the start time + * @param [in] end_time the end time + * @param [out] result_set the result set + */ + int query(std::vector& path_list, int64_t start_time, + int64_t end_time, ResultSet*& result_set); /** * @brief query the tsfile by the table name, columns names, start time * and end time. @@ -351,7 +449,7 @@ class TsFileReader { */ int query(const std::string &table_name, const std::vector &columns_names, int64_t start_time, - int64_t end_time, ResultSet *&result_set); + int64_t end_time, ResultSet *&result_set, int batch_size = -1); /** * @brief query the tsfile by the table name, columns names, start time @@ -366,7 +464,14 @@ class TsFileReader { */ int query(const std::string& table_name, const std::vector& columns_names, int64_t start_time, - int64_t end_time, ResultSet*& result_set, Filter* tag_filter); + int64_t end_time, ResultSet*& result_set, Filter* tag_filter, + int batch_size = 0); + + /** + * @brief query tree-model time series by row with offset and limit. + */ + int queryByRow(std::vector& path_list, int offset, int limit, + ResultSet*& result_set); /** * @brief query a table by row, with offset/limit pushdown and an optional @@ -386,6 +491,13 @@ class TsFileReader { int limit, ResultSet*& result_set, Filter* tag_filter = nullptr, int batch_size = 0); + /** + * @brief query tree-model data by measurement names within a time range. + */ + int query_table_on_tree(const std::vector& measurement_names, + int64_t start_time, int64_t end_time, + ResultSet*& result_set); + /** * @brief destroy the result set, this method should be called after the * query is finished and result_set @@ -393,6 +505,26 @@ class TsFileReader { * @param qds the result set */ void destroy_query_data_set(ResultSet *qds); + + ResultSet* read_timeseries( + const std::shared_ptr& device_id, + const std::vector& measurement_name); + + std::vector> get_all_devices( + std::string table_name); + + std::vector> get_all_device_ids(); + + std::vector> get_all_devices(); + + int get_timeseries_schema(std::shared_ptr device_id, + std::vector& result); + + DeviceTimeseriesMetadataMap get_timeseries_metadata( + const std::vector>& device_ids); + + DeviceTimeseriesMetadataMap get_timeseries_metadata(); + /** * @brief get the table schema by the table name * @@ -409,6 +541,11 @@ class TsFileReader { std::vector> get_all_table_schemas(); }; ``` + +`DeviceTimeseriesMetadataMap` is the metadata map returned by +`get_timeseries_metadata()`: `std::map, +std::vector>, IDeviceIDComparator>`. + ### ResultSet ```cpp /** @@ -540,6 +677,8 @@ class TagFilterBuilder { Filter* reg_exp(const std::string& columnName, const std::string& value); Filter* not_reg_exp(const std::string& columnName, const std::string& value); + Filter* is_null(const std::string& columnName); + Filter* is_not_null(const std::string& columnName); Filter* between_and(const std::string& columnName, const std::string& lower, const std::string& upper); Filter* not_between_and(const std::string& columnName, @@ -550,4 +689,4 @@ class TagFilterBuilder { static Filter* or_filter(Filter* left, Filter* right); static Filter* not_filter(Filter* filter); }; -``` \ No newline at end of file +``` diff --git a/src/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md b/src/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md index bbcde49cf..806fa9115 100644 --- a/src/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md +++ b/src/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md @@ -47,10 +47,17 @@ class TSEncoding(IntEnum): PLAIN = 0 # all types DICTIONARY = 1 # STRING, TEXT RLE = 2 # INT32, INT64, TIMESTAMP, DATE + DIFF = 3 TS_2DIFF = 4 # INT32, INT64, TIMESTAMP, DATE, FLOAT, DOUBLE + BITMAP = 5 + GORILLA_V1 = 6 + REGULAR = 7 GORILLA = 8 # INT32, INT64, TIMESTAMP, DATE, FLOAT, DOUBLE ZIGZAG = 9 # INT32, INT64 + CHIMP = 11 # INT32, INT64, TIMESTAMP, DATE, FLOAT, DOUBLE SPRINTZ = 12 # INT32, INT64, FLOAT, DOUBLE + RLBE = 13 # INT32, INT64, TIMESTAMP, DATE, FLOAT, DOUBLE + CAMEL = 14 # DOUBLE class Compressor(IntEnum): """ @@ -60,7 +67,12 @@ class Compressor(IntEnum): SNAPPY = 1 GZIP = 2 LZO = 3 + SDT = 4 + PAA = 5 + PLA = 6 LZ4 = 7 + ZSTD = 8 + LZMA2 = 9 class ColumnCategory(IntEnum): """ @@ -103,13 +115,39 @@ class ResultSetMetaData: def __init__(self, column_list: List[str], data_types: List[TSDataType]) +@dataclass(frozen=True) +class DeviceID: + path: Optional[str] + table_name: Optional[str] + segments: tuple[Optional[str], ...] + +@dataclass(frozen=True) +class TimeseriesStatistic: + has_statistic: bool + row_count: int + start_time: int + end_time: int + +@dataclass(frozen=True) +class TimeseriesMetadata: + measurement_name: str + data_type: TSDataType + chunk_meta_count: int + statistic: TimeseriesStatistic + timeline_statistic: TimeseriesStatistic + +@dataclass(frozen=True) +class DeviceTimeseriesMetadataGroup: + table_name: Optional[str] + segments: tuple[Optional[str], ...] + timeseries: list[TimeseriesMetadata] ``` ## Write interface -### TsFileWriter +### TsFileTableWriter ```python class TsFileTableWriter: @@ -162,6 +200,48 @@ class TsFileTableWriter: def __exit__(self, exc_type, exc_val, exc_tb) ``` +### TsFileWriter + +`TsFileWriter` is the lower-level writer exposed from `writer.pyx`. It can write +tree-model data (`register_timeseries`, `register_device`, `write_tablet`, +`write_row_record`) and table-model data (`register_table`, `write_table`, +`write_dataframe`, `write_arrow_batch`). + +```python +class TsFileWriter: + """ + :param pathname: Destination TsFile path. + :param memory_threshold: bytes buffered before an automatic flush (default 128MB). + """ + def __init__(self, pathname: str, memory_threshold: int = 128 * 1024 * 1024) + + def register_timeseries(self, device_name: str, + timeseries_schema: TimeseriesSchema) + + def register_device(self, device_schema: DeviceSchema) + + def register_table(self, table_schema: TableSchema) + + def write_tablet(self, tablet: Tablet) + + def write_dataframe(self, target_table: str, dataframe: pandas.DataFrame, + tableschema: TableSchema) + + def write_row_record(self, record: RowRecord) + + def write_table(self, tablet: Tablet) + + def write_arrow_batch(self, table_name: str, data, + time_col_index: int = -1) + + def flush(self) + + def close(self) + + def __enter__(self) + def __exit__(self, exc_type, exc_val, exc_tb) +``` + ### Tablet definition @@ -231,11 +311,15 @@ encodings per data type, and the default used when you do not change it: | Data type | Allowed encodings | Default | |---|---|---| | `BOOLEAN` | `PLAIN` | `PLAIN` | -| `INT32`, `INT64`, `DATE` | `PLAIN`, `TS_2DIFF`, `GORILLA`, `ZIGZAG`, `RLE`, `SPRINTZ` | `TS_2DIFF` | -| `FLOAT`, `DOUBLE` | `PLAIN`, `TS_2DIFF`, `GORILLA`, `SPRINTZ` | `GORILLA` | +| `INT32`, `INT64`, `TIMESTAMP`, `DATE` | `PLAIN`, `TS_2DIFF`, `GORILLA`, `ZIGZAG`, `RLE`, `SPRINTZ`, `CHIMP`, `RLBE` | `TS_2DIFF` | +| `FLOAT` | `PLAIN`, `TS_2DIFF`, `GORILLA`, `SPRINTZ`, `CHIMP`, `RLBE` | `GORILLA` | +| `DOUBLE` | `PLAIN`, `TS_2DIFF`, `GORILLA`, `SPRINTZ`, `CHIMP`, `RLBE`, `CAMEL` | `GORILLA` | | `STRING`, `TEXT` | `PLAIN`, `DICTIONARY` | `PLAIN` | -Compression applies to any data type: `UNCOMPRESSED`, `SNAPPY`, `GZIP`, `LZO`, or `LZ4` (default `LZ4`). +Compression applies to any data type: `UNCOMPRESSED`, `SNAPPY`, `GZIP`, `LZO`, +`LZ4`, `ZSTD`, or `LZMA2` (default `LZ4`). The enum also exposes legacy values +such as `SDT`, `PAA`, and `PLA`, but the global configuration setter rejects +them. ## Read Interface @@ -262,11 +346,39 @@ class TsFileReader: :param column_names: A list of column names to retrieve. :param start_time: The start time of the query range (default: minimum int64 value). :param end_time: The end time of the query range (default: maximum int64 value). + :param tag_filter: Optional tag predicate for table-model TAG columns. + :param batch_size: <= 0 returns rows one by one; > 0 returns blocks of that size. :return: A query result set handler. """ def query_table(self, table_name : str, column_names : List[str], start_time : int = np.iinfo(np.int64).min, - end_time: int = np.iinfo(np.int64).max) -> ResultSet + end_time: int = np.iinfo(np.int64).max, + tag_filter = None, batch_size : int = 0) -> ResultSet + + """ + Execute a time range query on tree-model measurement columns. + + :param column_names: Measurement names to retrieve. + :param start_time: The start time of the query range. + :param end_time: The end time of the query range. + :return: A query result set handler. + """ + def query_table_on_tree(self, column_names : List[str], + start_time : int = np.iinfo(np.int64).min, + end_time : int = np.iinfo(np.int64).max) -> ResultSet + + """ + Execute tree-model query by row with offset/limit. + + :param device_ids: Device identifiers to query. + :param measurement_names: Measurement names to retrieve. + :param offset: Number of leading rows to skip. + :param limit: Maximum number of rows to return; < 0 means unlimited. + :return: A query result set handler. + """ + def query_tree_by_row(self, device_ids : List[str], + measurement_names : List[str], + offset : int = 0, limit : int = -1) -> ResultSet """ Execute a table query by row, with offset/limit pushdown and an optional @@ -287,6 +399,18 @@ class TsFileReader: offset : int = 0, limit : int = -1, tag_filter = None, batch_size : int = 0) -> ResultSet + """ + Execute a tree-model time range query for one device. + + :param device_name: Device identifier. + :param sensor_list: Measurement names to retrieve. + :param start_time: Query start time. + :param end_time: Query end time. + :return: A query result set handler. + """ + def query_timeseries(self, device_name : str, sensor_list : List[str], + start_time : int = 0, end_time : int = 0) -> ResultSet + """ Retrieves the schema of the specified table. @@ -303,6 +427,31 @@ class TsFileReader: """ def get_all_table_schemas(self) ->dict[str, TableSchema] + """ + Retrieves all tree-model timeseries schemas grouped by device. + + :return: A list of DeviceSchema objects. + """ + def get_all_timeseries_schemas(self) -> list[DeviceSchema] + + """ + Retrieves all device identifiers in the file. + + :return: A list of DeviceID(path, table_name, segments). + """ + def get_all_devices(self) -> List[DeviceID] + + """ + Retrieves per-timeseries metadata for all devices, or only the specified + devices. + + :param device_ids: None for all devices, [] for an empty result, or a list + of DeviceID / path-compatible device identifiers. + :return: dict mapping device segment tuples to DeviceTimeseriesMetadataGroup. + """ + def get_timeseries_metadata( + self, device_ids: Optional[List] = None + ) -> Dict[tuple, DeviceTimeseriesMetadataGroup] """ Closes the TsFile reader. If the reader has active result sets, they will be invalidated. @@ -346,6 +495,13 @@ class ResultSet: """ def read_data_frame(self, max_row_num : int = 1024) -> DataFrame + """ + Fetches the next batch result as a pyarrow.Table. Returns None when no more + TsBlock batches are available. This is only valid for result sets created + with batch_size > 0. + """ + def read_arrow_batch(self) -> Optional[pyarrow.Table] + """ Retrieves the value at the specified index from the query result set. @@ -397,6 +553,9 @@ class ResultSet: Closes the result set and releases any associated resources. """ def close(self) + + def __enter__(self) + def __exit__(self, exc_type, exc_val, exc_tb) ``` ### to_dataframe @@ -467,4 +626,4 @@ def to_dataframe(file_path: str, ColumnNotExistError If any specified column does not exist in the table schema. """ -``` \ No newline at end of file +``` diff --git a/src/UserGuide/latest/DataFrame/TsFileDataFrame.md b/src/UserGuide/latest/DataFrame/TsFileDataFrame.md index 91a32ee8e..dbd88160e 100644 --- a/src/UserGuide/latest/DataFrame/TsFileDataFrame.md +++ b/src/UserGuide/latest/DataFrame/TsFileDataFrame.md @@ -64,9 +64,11 @@ In the table below, `df` is a `TsFileDataFrame` instance, created with | Example | Operation | Returns | |---|---|---| -| `TsFileDataFrame(paths)` | Load a file / list of files / directory | `TsFileDataFrame` | +| `TsFileDataFrame(paths, show_progress=True)` | Load a file / list of files / directory. Set `show_progress=False` to silence loading progress on stderr | `TsFileDataFrame` | | `len(df)` | Number of time series | `int` | +| `df.model` | Loaded file model: `"table"` or `"tree"` | `str` | | `df.list_timeseries("weather")` | Series names, optionally filtered by prefix | `List[str]` | +| `df.list_timeseries_metadata("weather")` | Series metadata, optionally filtered by prefix | `pandas.DataFrame` | | `df["weather.Beijing.humidity"]`, `df[0]`, `df[-1]` | One series | `Timeseries` | | `df["city"]` | A metadata column (a tag / `field` / `start_time` / `end_time` / `count`) | `pandas.Series` | | `df[0:3]`, `df[[0, 2, 5]]` | Subset view by integer position: a contiguous range (`0:3`), or the listed positions (`[0, 2, 5]`); positions are the printed `index` column | `TsFileDataFrame` | @@ -150,6 +152,7 @@ from tsfile import TsFileDataFrame df = TsFileDataFrame(["data/weather.tsfile", "data/sensor.tsfile"]) df = TsFileDataFrame("data/") # recursively find every .tsfile under the directory +df = TsFileDataFrame("data/", show_progress=False) print(df) ``` @@ -203,7 +206,21 @@ optionally filtered by a prefix. Calling it with no argument returns all series. ``` To inspect metadata such as start/end time and count, print the DataFrame (or a -subset of it) — see [Displaying a DataFrame](#displaying-a-dataframe). +subset of it) — see [Displaying a DataFrame](#displaying-a-dataframe) — or call +`list_timeseries_metadata()`. + +## Inspecting metadata + +`list_timeseries_metadata(path_prefix="")` returns a pandas DataFrame indexed by +series name. It includes `field`, `start_time`, `end_time`, `count`, and the +device tag columns. For table-model files it also includes the `table` column. + +```python +meta = df.list_timeseries_metadata() +weather_meta = df.list_timeseries_metadata("weather") + +meta[["field", "start_time", "end_time", "count"]].head() +``` ## Selecting series diff --git a/src/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md b/src/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md index 0fb0c1e36..262cb5148 100644 --- a/src/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md +++ b/src/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md @@ -32,10 +32,12 @@ typedef enum { TS_DATATYPE_FLOAT = 3, TS_DATATYPE_DOUBLE = 4, TS_DATATYPE_TEXT = 5, + TS_DATATYPE_VECTOR = 6, TS_DATATYPE_TIMESTAMP = 8, TS_DATATYPE_DATE = 9, TS_DATATYPE_BLOB = 10, TS_DATATYPE_STRING = 11, + TS_DATATYPE_NULL_TYPE = 254, TS_DATATYPE_INVALID = 255 } TSDataType; @@ -44,10 +46,18 @@ typedef enum { TS_ENCODING_PLAIN = 0, TS_ENCODING_DICTIONARY = 1, TS_ENCODING_RLE = 2, + TS_ENCODING_DIFF = 3, TS_ENCODING_TS_2DIFF = 4, + TS_ENCODING_BITMAP = 5, + TS_ENCODING_GORILLA_V1 = 6, + TS_ENCODING_REGULAR = 7, TS_ENCODING_GORILLA = 8, TS_ENCODING_ZIGZAG = 9, + TS_ENCODING_FREQ = 10, + TS_ENCODING_CHIMP = 11, TS_ENCODING_SPRINTZ = 12, + TS_ENCODING_RLBE = 13, + TS_ENCODING_CAMEL = 14, TS_ENCODING_INVALID = 255 } TSEncoding; @@ -57,7 +67,12 @@ typedef enum { TS_COMPRESSION_SNAPPY = 1, TS_COMPRESSION_GZIP = 2, TS_COMPRESSION_LZO = 3, + TS_COMPRESSION_SDT = 4, + TS_COMPRESSION_PAA = 5, + TS_COMPRESSION_PLA = 6, TS_COMPRESSION_LZ4 = 7, + TS_COMPRESSION_ZSTD = 8, + TS_COMPRESSION_LZMA2 = 9, TS_COMPRESSION_INVALID = 255 } CompressionType; @@ -86,6 +101,19 @@ typedef struct table_schema { int column_num; } TableSchema; +typedef struct timeseries_schema { + char* timeseries_name; + TSDataType data_type; + TSEncoding encoding; + CompressionType compression; +} TimeseriesSchema; + +typedef struct device_schema { + char* device_name; + TimeseriesSchema* timeseries_schema; + int timeseries_num; +} DeviceSchema; + // ResultSetMetaData: Contains metadata for a result set, // such as column names and their data types. typedef struct result_set_meta_data { @@ -93,11 +121,73 @@ typedef struct result_set_meta_data { TSDataType* data_types; int column_num; } ResultSetMetaData; + +typedef struct arrow_schema ArrowSchema; +typedef struct arrow_array ArrowArray; + +typedef struct DeviceID { + char* path; + char* table_name; + uint32_t segment_count; + char** segments; +} DeviceID; + +typedef struct TsFileStatisticBase { + bool has_statistic; + TSDataType type; + int32_t row_count; + int64_t start_time; + int64_t end_time; +} TsFileStatisticBase; + +typedef struct TsFileBoolStatistic { TsFileStatisticBase base; double sum; bool first_bool; bool last_bool; } TsFileBoolStatistic; +typedef struct TsFileIntStatistic { TsFileStatisticBase base; double sum; int64_t min_int64; int64_t max_int64; int64_t first_int64; int64_t last_int64; } TsFileIntStatistic; +typedef struct TsFileFloatStatistic { TsFileStatisticBase base; double sum; double min_float64; double max_float64; double first_float64; double last_float64; } TsFileFloatStatistic; +typedef struct TsFileStringStatistic { TsFileStatisticBase base; char* str_min; char* str_max; char* str_first; char* str_last; } TsFileStringStatistic; +typedef struct TsFileTextStatistic { TsFileStatisticBase base; char* str_first; char* str_last; } TsFileTextStatistic; + +typedef union TimeseriesStatisticUnion { + TsFileBoolStatistic bool_s; + TsFileIntStatistic int_s; + TsFileFloatStatistic float_s; + TsFileStringStatistic string_s; + TsFileTextStatistic text_s; +} TimeseriesStatisticUnion; + +typedef struct TimeseriesStatistic { + TimeseriesStatisticUnion u; +} TimeseriesStatistic; + +#define tsfile_statistic_base(s) ((TsFileStatisticBase*)&(s)->u) + +typedef struct TimeseriesMetadata { + char* measurement_name; + TSDataType data_type; + int32_t chunk_meta_count; + TimeseriesStatistic statistic; + TimeseriesStatistic timeline_statistic; +} TimeseriesMetadata; + +typedef struct DeviceTimeseriesMetadataEntry { + DeviceID device; + TimeseriesMetadata* timeseries; + uint32_t timeseries_count; +} DeviceTimeseriesMetadataEntry; + +typedef struct DeviceTimeseriesMetadataMap { + DeviceTimeseriesMetadataEntry* entries; + uint32_t device_count; +} DeviceTimeseriesMetadataMap; ``` > `ColumnSchema` does not carry encoding/compression: on write, columns follow the > global defaults (see [Configuration](#configuration-encoding--compression)); on > read, each column is decoded with the file's actual settings. +> +> `TimeseriesStatistic` is a tagged union in `tsfile_cwrapper.h`. Read common +> fields through `tsfile_statistic_base(&metadata.statistic)` and then use the +> active typed member (`int_s`, `float_s`, `bool_s`, `string_s`, or `text_s`) +> according to the statistic data type. ## Write Interface @@ -220,9 +310,11 @@ ERRNO tablet_add_timestamp(Tablet tablet, uint32_t row_index, * @param value [in] Null-terminated string. Ownership remains with caller. * @return ERRNO. */ -ERRNO tablet_add_value_by_name_string(Tablet tablet, uint32_t row_index, - const char* column_name, - const char* value); +ERRNO tablet_add_value_by_name_string_with_len(Tablet tablet, + uint32_t row_index, + const char* column_name, + const char* value, + int value_len); // Supports multiple data types ERRNO tablet_add_value_by_name_int32_t(Tablet tablet, uint32_t row_index, @@ -250,9 +342,11 @@ ERRNO tablet_add_value_by_name_bool(Tablet tablet, uint32_t row_index, * * @param value [in] Null-terminated string. Copied internally. */ -ERRNO tablet_add_value_by_index_string(Tablet tablet, uint32_t row_index, - uint32_t column_index, - const char* value); +ERRNO tablet_add_value_by_index_string_with_len(Tablet tablet, + uint32_t row_index, + uint32_t column_index, + const char* value, + int value_len); // Supports multiple data types @@ -329,11 +423,13 @@ Allowed encodings per data type, and the default used when you do not change it: | Data type | Allowed encodings | Default | |---|---|---| | `BOOLEAN` | `PLAIN` | `PLAIN` | -| `INT32`, `INT64`, `DATE` | `PLAIN`, `TS_2DIFF`, `GORILLA`, `ZIGZAG`, `RLE`, `SPRINTZ` | `TS_2DIFF` | -| `FLOAT`, `DOUBLE` | `PLAIN`, `TS_2DIFF`, `GORILLA`, `SPRINTZ` | `GORILLA` | +| `INT32`, `INT64`, `TIMESTAMP`, `DATE` | `PLAIN`, `TS_2DIFF`, `GORILLA`, `ZIGZAG`, `RLE`, `SPRINTZ`, `CHIMP`, `RLBE` | `TS_2DIFF` | +| `FLOAT` | `PLAIN`, `TS_2DIFF`, `GORILLA`, `SPRINTZ`, `CHIMP`, `RLBE` | `GORILLA` | +| `DOUBLE` | `PLAIN`, `TS_2DIFF`, `GORILLA`, `SPRINTZ`, `CHIMP`, `RLBE`, `CAMEL` | `GORILLA` | | `STRING`, `TEXT` | `PLAIN`, `DICTIONARY` | `PLAIN` | -Compression applies to any data type: `UNCOMPRESSED`, `SNAPPY`, `GZIP`, `LZO`, or `LZ4` (default `LZ4`). +Compression applies to any data type: `UNCOMPRESSED`, `SNAPPY`, `GZIP`, `LZO`, +`LZ4`, `ZSTD`, or `LZMA2` (default `LZ4`). ```C // e.g. write every column with LZ4 compression @@ -412,6 +508,31 @@ void free_tsfile_result_set(ResultSet* result_set); ``` +### Tree queries + +```C +/** + * @brief Query tree-model data by measurement names within a time range. + */ +ResultSet tsfile_query_table_on_tree(TsFileReader reader, char** columns, + uint32_t column_num, Timestamp start_time, + Timestamp end_time, ERRNO* err_code); + +/** + * @brief Query tree-model data by row with offset/limit. + * + * @param device_ids Array of device identifiers. + * @param measurement_names Array of measurement names. + * @param offset Leading rows to skip (>= 0). + * @param limit Max rows to return; < 0 means unlimited. + */ +ResultSet tsfile_reader_query_tree_by_row(TsFileReader reader, + char** device_ids, int device_ids_len, + char** measurement_names, + int measurement_names_len, int offset, + int limit, ERRNO* err_code); +``` + ### Filtering by tag @@ -436,6 +557,8 @@ typedef enum { TAG_FILTER_GTEQ = 5, // column >= value TAG_FILTER_REGEXP = 6, // column matches the regex value TAG_FILTER_NOT_REGEXP = 7, // column does not match the regex value + TAG_FILTER_IS_NULL = 8, // column is null + TAG_FILTER_IS_NOT_NULL = 9, // column is not null } TagFilterOp; /** @@ -444,7 +567,7 @@ typedef enum { * @param reader [in] Valid TsFileReader handle. * @param table_name [in] Table whose schema defines the TAG columns. * @param column_name [in] Name of the TAG column to filter on. - * @param value [in] Comparison value (TAG columns are STRING). + * @param value [in] Comparison value (ignored for IS NULL / IS NOT NULL). * @param op [in] Comparison operator (TagFilterOp). * @param err_code [out] RET_OK(0) on success, or error code in errno_define_c.h. * @return TagFilterHandle on success; NULL on failure. @@ -465,6 +588,20 @@ TagFilterHandle tsfile_tag_filter_between(TsFileReader reader, const char* lower, const char* upper, bool is_not, ERRNO* err_code); +// Convenience builders for common single-column predicates. +TagFilterHandle tsfile_tag_filter_eq(TsFileReader reader, const char* table_name, + const char* column_name, const char* value); +TagFilterHandle tsfile_tag_filter_neq(TsFileReader reader, const char* table_name, + const char* column_name, const char* value); +TagFilterHandle tsfile_tag_filter_lt(TsFileReader reader, const char* table_name, + const char* column_name, const char* value); +TagFilterHandle tsfile_tag_filter_lteq(TsFileReader reader, const char* table_name, + const char* column_name, const char* value); +TagFilterHandle tsfile_tag_filter_gt(TsFileReader reader, const char* table_name, + const char* column_name, const char* value); +TagFilterHandle tsfile_tag_filter_gteq(TsFileReader reader, const char* table_name, + const char* column_name, const char* value); + // Combine predicates. AND/OR/NOT take ownership of their children; free the root only. TagFilterHandle tsfile_tag_filter_and(TagFilterHandle left, TagFilterHandle right); TagFilterHandle tsfile_tag_filter_or(TagFilterHandle left, TagFilterHandle right); @@ -522,6 +659,18 @@ ResultSet tsfile_query_table_with_tag_filter( TagFilterHandle tag_filter, int batch_size, ERRNO* err_code); ``` +### Read batch results as Arrow + +Batch query result sets (`batch_size > 0`) can be fetched as Arrow C Data +Interface arrays and schemas. The caller owns the returned Arrow objects and +must call their `release` callbacks when finished. + +```C +ERRNO tsfile_result_set_get_next_tsblock_as_arrow(ResultSet result_set, + ArrowArray* out_array, + ArrowSchema* out_schema); +``` + Example — read `temperature` only for devices whose `region` TAG equals `shanghai`: @@ -664,17 +813,59 @@ TableSchema tsfile_reader_get_table_schema(TsFileReader reader, TableSchema* tsfile_reader_get_all_table_schemas(TsFileReader reader, uint32_t* size); +/** + * @brief Gets all timeseries schema in the tsfile. + * @param size[out] number of DeviceSchema elements in the returned array. + * @return DeviceSchema*, an array of device schemas. + * @note The caller must call free_device_schema() on each element + * and free() the array pointer. + */ +DeviceSchema* tsfile_reader_get_all_timeseries_schemas(TsFileReader reader, + uint32_t* size); + /** * @brief Free the tableschema's space. * @param schema [in] the table schema to be freed. */ void free_table_schema(TableSchema schema); + +void free_device_schema(DeviceSchema schema); ``` +### Get Devices and Timeseries Metadata +```C +/** + * @brief Lists all devices in the file. + * + * @param out_devices[out] allocated array; free with tsfile_free_device_id_array(). + * @param out_length[out] number of devices in the returned array. + */ +ERRNO tsfile_reader_get_all_devices(TsFileReader reader, DeviceID** out_devices, + uint32_t* out_length); +void tsfile_free_device_id_array(DeviceID* devices, uint32_t length); +void tsfile_device_id_free_contents(DeviceID* d); +/** + * @brief Timeseries metadata for all devices in the file. + */ +ERRNO tsfile_reader_get_timeseries_metadata_all( + TsFileReader reader, DeviceTimeseriesMetadataMap* out_map); +/** + * @brief Timeseries metadata for the specified devices. + * + * length == 0 returns an empty map. For non-empty input, each DeviceID.path + * should contain the canonical device path. + */ +ERRNO tsfile_reader_get_timeseries_metadata_for_devices( + TsFileReader reader, const DeviceID* devices, uint32_t length, + DeviceTimeseriesMetadataMap* out_map); + +void tsfile_free_device_timeseries_metadata_map( + DeviceTimeseriesMetadataMap* map); +``` diff --git a/src/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md b/src/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md index 496e48aca..d37e00777 100644 --- a/src/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md +++ b/src/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md @@ -31,10 +31,14 @@ enum TSDataType : uint8_t { FLOAT = 3, DOUBLE = 4, TEXT = 5, + VECTOR = 6, + UNKNOWN = 7, TIMESTAMP = 8, DATE = 9, BLOB = 10, STRING = 11, + NULL_TYPE = 254, + INVALID_DATATYPE = 255, }; // Value encoding. See the table below for which encodings apply to which types. @@ -42,19 +46,35 @@ enum TSEncoding : uint8_t { PLAIN = 0, DICTIONARY = 1, RLE = 2, + DIFF = 3, TS_2DIFF = 4, + BITMAP = 5, + GORILLA_V1 = 6, + REGULAR = 7, GORILLA = 8, ZIGZAG = 9, + FREQ = 10, + CHIMP = 11, SPRINTZ = 12, + RLBE = 13, + CAMEL = 14, + INVALID_ENCODING = 255, }; -// Compression type. SNAPPY/GZIP/LZO/LZ4 depend on build options; LZ4 is the default. +// Compression type. SNAPPY/GZIP/LZO/LZ4/ZSTD/LZMA2 depend on build options; +// LZ4 is the default. enum CompressionType : uint8_t { UNCOMPRESSED = 0, SNAPPY = 1, GZIP = 2, LZO = 3, + SDT = 4, + PAA = 5, + PLA = 6, LZ4 = 7, + ZSTD = 8, + LZMA2 = 9, + INVALID_COMPRESSION = 255, }; // Column role within a table schema. @@ -72,6 +92,8 @@ Encodings applicable to each data type: | `GORILLA` | `INT32`, `INT64`, `TIMESTAMP`, `DATE`, `FLOAT`, `DOUBLE` | | `ZIGZAG` | `INT32`, `INT64` | | `SPRINTZ` | `INT32`, `INT64`, `FLOAT`, `DOUBLE` | +| `CHIMP`, `RLBE` | `INT32`, `INT64`, `TIMESTAMP`, `DATE`, `FLOAT`, `DOUBLE` | +| `CAMEL` | `DOUBLE` | Default value encoding per type: `BOOLEAN → PLAIN`, `INT32 / INT64 → TS_2DIFF`, `FLOAT / DOUBLE → GORILLA`, `TEXT / STRING / BLOB → PLAIN`. The default @@ -134,6 +156,65 @@ class TsFileTableWriter { }; ``` +### TsFileWriter + +`TsFileWriter` is the lower-level writer interface from `tsfile_writer.h`. It +supports both tree-model and table-model writes. + +```cpp +extern int libtsfile_init(); +extern void libtsfile_destroy(); + +// Writer configuration. Invalid values return common::E_INVALID_ARG and leave +// the previous value unchanged. +extern int set_page_max_point_count(uint32_t page_max_point_count); +extern int set_max_degree_of_index_node(uint32_t max_degree_of_index_node); + +class TsFileWriter { + public: + TsFileWriter(); + ~TsFileWriter(); + void destroy(); + + int open(const std::string& file_path, int flags, mode_t mode); + int open(const std::string& file_path); + int init(storage::WriteFile* write_file); + int init(storage::RestorableTsFileIOWriter* rw); + + void set_generate_table_schema(bool generate_table_schema); + + int register_timeseries(const std::string& device_id, + const MeasurementSchema& measurement_schema); + int register_timeseries( + const std::string& device_path, + const std::vector& measurement_schema_vec); + int register_aligned_timeseries( + const std::string& device_id, + const MeasurementSchema& measurement_schema); + int register_aligned_timeseries( + const std::string& device_id, + const std::vector& measurement_schemas); + int register_table(const std::shared_ptr& table_schema); + + int write_record(const TsRecord& record); + int write_tablet(const Tablet& tablet); + int write_record_aligned(const TsRecord& record); + int write_tablet_aligned(const Tablet& tablet); + int write_tree(const Tablet& tablet); + int write_tree(const TsRecord& record); + int write_table(Tablet& tablet); + + DeviceSchemasMap* get_schema_group_map(); + std::shared_ptr get_table_schema( + const std::string& table_name) const; + int64_t calculate_mem_size_for_all_group(); + int64_t calculate_meta_mem_size() const; + int check_memory_size_and_may_flush_chunks(); + int flush(); + int close(); +}; +``` + ### TableSchema Describe the data structure of the table schema @@ -300,8 +381,14 @@ uint8_t common::get_global_compression(); // Time-column encoding/compression (the data type is fixed to INT64). int common::set_global_time_encoding(uint8_t encoding); int common::set_global_time_compression(uint8_t compression); +uint8_t common::get_global_time_encoding(); +uint8_t common::get_global_time_compression(); ``` +Global compression accepts `UNCOMPRESSED`, `SNAPPY`, `GZIP`, `LZO`, `LZ4`, +`ZSTD`, and `LZMA2`. The codec enum also contains legacy values such as `SDT`, +`PAA`, and `PLA`, but the global compression setter rejects them. + ## Read Interface ### Tsfile Reader ```cpp @@ -339,6 +426,17 @@ class TsFileReader { * @return Returns 0 on success, or a non-zero error code on failure. */ int query(storage::QueryExpression *qe, ResultSet *&ret_qds); + /** + * @brief query the tsfile by the path list, start time and end time. + * This method is used to query the tree model. + * + * @param [in] path_list the full path list + * @param [in] start_time the start time + * @param [in] end_time the end time + * @param [out] result_set the result set + */ + int query(std::vector& path_list, int64_t start_time, + int64_t end_time, ResultSet*& result_set); /** * @brief query the tsfile by the table name, columns names, start time * and end time. @@ -351,7 +449,7 @@ class TsFileReader { */ int query(const std::string &table_name, const std::vector &columns_names, int64_t start_time, - int64_t end_time, ResultSet *&result_set); + int64_t end_time, ResultSet *&result_set, int batch_size = -1); /** * @brief query the tsfile by the table name, columns names, start time @@ -366,7 +464,14 @@ class TsFileReader { */ int query(const std::string& table_name, const std::vector& columns_names, int64_t start_time, - int64_t end_time, ResultSet*& result_set, Filter* tag_filter); + int64_t end_time, ResultSet*& result_set, Filter* tag_filter, + int batch_size = 0); + + /** + * @brief query tree-model time series by row with offset and limit. + */ + int queryByRow(std::vector& path_list, int offset, int limit, + ResultSet*& result_set); /** * @brief query a table by row, with offset/limit pushdown and an optional @@ -386,6 +491,13 @@ class TsFileReader { int limit, ResultSet*& result_set, Filter* tag_filter = nullptr, int batch_size = 0); + /** + * @brief query tree-model data by measurement names within a time range. + */ + int query_table_on_tree(const std::vector& measurement_names, + int64_t start_time, int64_t end_time, + ResultSet*& result_set); + /** * @brief destroy the result set, this method should be called after the * query is finished and result_set @@ -393,6 +505,26 @@ class TsFileReader { * @param qds the result set */ void destroy_query_data_set(ResultSet *qds); + + ResultSet* read_timeseries( + const std::shared_ptr& device_id, + const std::vector& measurement_name); + + std::vector> get_all_devices( + std::string table_name); + + std::vector> get_all_device_ids(); + + std::vector> get_all_devices(); + + int get_timeseries_schema(std::shared_ptr device_id, + std::vector& result); + + DeviceTimeseriesMetadataMap get_timeseries_metadata( + const std::vector>& device_ids); + + DeviceTimeseriesMetadataMap get_timeseries_metadata(); + /** * @brief get the table schema by the table name * @@ -409,6 +541,11 @@ class TsFileReader { std::vector> get_all_table_schemas(); }; ``` + +`DeviceTimeseriesMetadataMap` is the metadata map returned by +`get_timeseries_metadata()`: `std::map, +std::vector>, IDeviceIDComparator>`. + ### ResultSet ```cpp /** @@ -540,6 +677,8 @@ class TagFilterBuilder { Filter* reg_exp(const std::string& columnName, const std::string& value); Filter* not_reg_exp(const std::string& columnName, const std::string& value); + Filter* is_null(const std::string& columnName); + Filter* is_not_null(const std::string& columnName); Filter* between_and(const std::string& columnName, const std::string& lower, const std::string& upper); Filter* not_between_and(const std::string& columnName, @@ -550,4 +689,4 @@ class TagFilterBuilder { static Filter* or_filter(Filter* left, Filter* right); static Filter* not_filter(Filter* filter); }; -``` \ No newline at end of file +``` diff --git a/src/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md b/src/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md index bbcde49cf..806fa9115 100644 --- a/src/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md +++ b/src/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md @@ -47,10 +47,17 @@ class TSEncoding(IntEnum): PLAIN = 0 # all types DICTIONARY = 1 # STRING, TEXT RLE = 2 # INT32, INT64, TIMESTAMP, DATE + DIFF = 3 TS_2DIFF = 4 # INT32, INT64, TIMESTAMP, DATE, FLOAT, DOUBLE + BITMAP = 5 + GORILLA_V1 = 6 + REGULAR = 7 GORILLA = 8 # INT32, INT64, TIMESTAMP, DATE, FLOAT, DOUBLE ZIGZAG = 9 # INT32, INT64 + CHIMP = 11 # INT32, INT64, TIMESTAMP, DATE, FLOAT, DOUBLE SPRINTZ = 12 # INT32, INT64, FLOAT, DOUBLE + RLBE = 13 # INT32, INT64, TIMESTAMP, DATE, FLOAT, DOUBLE + CAMEL = 14 # DOUBLE class Compressor(IntEnum): """ @@ -60,7 +67,12 @@ class Compressor(IntEnum): SNAPPY = 1 GZIP = 2 LZO = 3 + SDT = 4 + PAA = 5 + PLA = 6 LZ4 = 7 + ZSTD = 8 + LZMA2 = 9 class ColumnCategory(IntEnum): """ @@ -103,13 +115,39 @@ class ResultSetMetaData: def __init__(self, column_list: List[str], data_types: List[TSDataType]) +@dataclass(frozen=True) +class DeviceID: + path: Optional[str] + table_name: Optional[str] + segments: tuple[Optional[str], ...] + +@dataclass(frozen=True) +class TimeseriesStatistic: + has_statistic: bool + row_count: int + start_time: int + end_time: int + +@dataclass(frozen=True) +class TimeseriesMetadata: + measurement_name: str + data_type: TSDataType + chunk_meta_count: int + statistic: TimeseriesStatistic + timeline_statistic: TimeseriesStatistic + +@dataclass(frozen=True) +class DeviceTimeseriesMetadataGroup: + table_name: Optional[str] + segments: tuple[Optional[str], ...] + timeseries: list[TimeseriesMetadata] ``` ## Write interface -### TsFileWriter +### TsFileTableWriter ```python class TsFileTableWriter: @@ -162,6 +200,48 @@ class TsFileTableWriter: def __exit__(self, exc_type, exc_val, exc_tb) ``` +### TsFileWriter + +`TsFileWriter` is the lower-level writer exposed from `writer.pyx`. It can write +tree-model data (`register_timeseries`, `register_device`, `write_tablet`, +`write_row_record`) and table-model data (`register_table`, `write_table`, +`write_dataframe`, `write_arrow_batch`). + +```python +class TsFileWriter: + """ + :param pathname: Destination TsFile path. + :param memory_threshold: bytes buffered before an automatic flush (default 128MB). + """ + def __init__(self, pathname: str, memory_threshold: int = 128 * 1024 * 1024) + + def register_timeseries(self, device_name: str, + timeseries_schema: TimeseriesSchema) + + def register_device(self, device_schema: DeviceSchema) + + def register_table(self, table_schema: TableSchema) + + def write_tablet(self, tablet: Tablet) + + def write_dataframe(self, target_table: str, dataframe: pandas.DataFrame, + tableschema: TableSchema) + + def write_row_record(self, record: RowRecord) + + def write_table(self, tablet: Tablet) + + def write_arrow_batch(self, table_name: str, data, + time_col_index: int = -1) + + def flush(self) + + def close(self) + + def __enter__(self) + def __exit__(self, exc_type, exc_val, exc_tb) +``` + ### Tablet definition @@ -231,11 +311,15 @@ encodings per data type, and the default used when you do not change it: | Data type | Allowed encodings | Default | |---|---|---| | `BOOLEAN` | `PLAIN` | `PLAIN` | -| `INT32`, `INT64`, `DATE` | `PLAIN`, `TS_2DIFF`, `GORILLA`, `ZIGZAG`, `RLE`, `SPRINTZ` | `TS_2DIFF` | -| `FLOAT`, `DOUBLE` | `PLAIN`, `TS_2DIFF`, `GORILLA`, `SPRINTZ` | `GORILLA` | +| `INT32`, `INT64`, `TIMESTAMP`, `DATE` | `PLAIN`, `TS_2DIFF`, `GORILLA`, `ZIGZAG`, `RLE`, `SPRINTZ`, `CHIMP`, `RLBE` | `TS_2DIFF` | +| `FLOAT` | `PLAIN`, `TS_2DIFF`, `GORILLA`, `SPRINTZ`, `CHIMP`, `RLBE` | `GORILLA` | +| `DOUBLE` | `PLAIN`, `TS_2DIFF`, `GORILLA`, `SPRINTZ`, `CHIMP`, `RLBE`, `CAMEL` | `GORILLA` | | `STRING`, `TEXT` | `PLAIN`, `DICTIONARY` | `PLAIN` | -Compression applies to any data type: `UNCOMPRESSED`, `SNAPPY`, `GZIP`, `LZO`, or `LZ4` (default `LZ4`). +Compression applies to any data type: `UNCOMPRESSED`, `SNAPPY`, `GZIP`, `LZO`, +`LZ4`, `ZSTD`, or `LZMA2` (default `LZ4`). The enum also exposes legacy values +such as `SDT`, `PAA`, and `PLA`, but the global configuration setter rejects +them. ## Read Interface @@ -262,11 +346,39 @@ class TsFileReader: :param column_names: A list of column names to retrieve. :param start_time: The start time of the query range (default: minimum int64 value). :param end_time: The end time of the query range (default: maximum int64 value). + :param tag_filter: Optional tag predicate for table-model TAG columns. + :param batch_size: <= 0 returns rows one by one; > 0 returns blocks of that size. :return: A query result set handler. """ def query_table(self, table_name : str, column_names : List[str], start_time : int = np.iinfo(np.int64).min, - end_time: int = np.iinfo(np.int64).max) -> ResultSet + end_time: int = np.iinfo(np.int64).max, + tag_filter = None, batch_size : int = 0) -> ResultSet + + """ + Execute a time range query on tree-model measurement columns. + + :param column_names: Measurement names to retrieve. + :param start_time: The start time of the query range. + :param end_time: The end time of the query range. + :return: A query result set handler. + """ + def query_table_on_tree(self, column_names : List[str], + start_time : int = np.iinfo(np.int64).min, + end_time : int = np.iinfo(np.int64).max) -> ResultSet + + """ + Execute tree-model query by row with offset/limit. + + :param device_ids: Device identifiers to query. + :param measurement_names: Measurement names to retrieve. + :param offset: Number of leading rows to skip. + :param limit: Maximum number of rows to return; < 0 means unlimited. + :return: A query result set handler. + """ + def query_tree_by_row(self, device_ids : List[str], + measurement_names : List[str], + offset : int = 0, limit : int = -1) -> ResultSet """ Execute a table query by row, with offset/limit pushdown and an optional @@ -287,6 +399,18 @@ class TsFileReader: offset : int = 0, limit : int = -1, tag_filter = None, batch_size : int = 0) -> ResultSet + """ + Execute a tree-model time range query for one device. + + :param device_name: Device identifier. + :param sensor_list: Measurement names to retrieve. + :param start_time: Query start time. + :param end_time: Query end time. + :return: A query result set handler. + """ + def query_timeseries(self, device_name : str, sensor_list : List[str], + start_time : int = 0, end_time : int = 0) -> ResultSet + """ Retrieves the schema of the specified table. @@ -303,6 +427,31 @@ class TsFileReader: """ def get_all_table_schemas(self) ->dict[str, TableSchema] + """ + Retrieves all tree-model timeseries schemas grouped by device. + + :return: A list of DeviceSchema objects. + """ + def get_all_timeseries_schemas(self) -> list[DeviceSchema] + + """ + Retrieves all device identifiers in the file. + + :return: A list of DeviceID(path, table_name, segments). + """ + def get_all_devices(self) -> List[DeviceID] + + """ + Retrieves per-timeseries metadata for all devices, or only the specified + devices. + + :param device_ids: None for all devices, [] for an empty result, or a list + of DeviceID / path-compatible device identifiers. + :return: dict mapping device segment tuples to DeviceTimeseriesMetadataGroup. + """ + def get_timeseries_metadata( + self, device_ids: Optional[List] = None + ) -> Dict[tuple, DeviceTimeseriesMetadataGroup] """ Closes the TsFile reader. If the reader has active result sets, they will be invalidated. @@ -346,6 +495,13 @@ class ResultSet: """ def read_data_frame(self, max_row_num : int = 1024) -> DataFrame + """ + Fetches the next batch result as a pyarrow.Table. Returns None when no more + TsBlock batches are available. This is only valid for result sets created + with batch_size > 0. + """ + def read_arrow_batch(self) -> Optional[pyarrow.Table] + """ Retrieves the value at the specified index from the query result set. @@ -397,6 +553,9 @@ class ResultSet: Closes the result set and releases any associated resources. """ def close(self) + + def __enter__(self) + def __exit__(self, exc_type, exc_val, exc_tb) ``` ### to_dataframe @@ -467,4 +626,4 @@ def to_dataframe(file_path: str, ColumnNotExistError If any specified column does not exist in the table schema. """ -``` \ No newline at end of file +``` diff --git a/src/zh/UserGuide/develop/DataFrame/TsFileDataFrame.md b/src/zh/UserGuide/develop/DataFrame/TsFileDataFrame.md index 816a8cca6..2a7bf9616 100644 --- a/src/zh/UserGuide/develop/DataFrame/TsFileDataFrame.md +++ b/src/zh/UserGuide/develop/DataFrame/TsFileDataFrame.md @@ -59,9 +59,11 @@ data.values # -> np.ndarray, shape (N, 2):N | 示例 | 操作 | 返回类型 | |---|---|---| -| `TsFileDataFrame(paths)` | 加载文件 / 文件列表 / 目录 | `TsFileDataFrame` | +| `TsFileDataFrame(paths, show_progress=True)` | 加载文件 / 文件列表 / 目录。设置 `show_progress=False` 可关闭 stderr 上的加载进度 | `TsFileDataFrame` | | `len(df)` | 时间序列总数 | `int` | +| `df.model` | 已加载文件模型:`"table"` 或 `"tree"` | `str` | | `df.list_timeseries("weather")` | 获取序列名,可按前缀筛选 | `List[str]` | +| `df.list_timeseries_metadata("weather")` | 获取序列元数据,可按前缀筛选 | `pandas.DataFrame` | | `df["weather.Beijing.humidity"]`、`df[0]`、`df[-1]` | 获取单条序列 | `Timeseries` | | `df["city"]` | 获取某元数据列(标签 / `field` / `start_time` / `end_time` / `count`) | `pandas.Series` | | `df[0:3]`、`df[[0, 2, 5]]` | 按整数位置取子集视图:连续区间(`0:3`)或所列位置(`[0, 2, 5]`);位置即打印的 `index` 列 | `TsFileDataFrame` | @@ -132,6 +134,7 @@ from tsfile import TsFileDataFrame df = TsFileDataFrame(["data/weather.tsfile", "data/sensor.tsfile"]) df = TsFileDataFrame("data/") # 递归查找目录下所有 .tsfile +df = TsFileDataFrame("data/", show_progress=False) print(df) ``` @@ -172,7 +175,21 @@ TsFileDataFrame(table model, 972 time series, 5 files) ['weather.Beijing.humidity', 'weather.Beijing.temperature'] ``` -若需查看起止时间、点数等元信息,可打印 DataFrame(或其子集)——见[DataFrame 的展示](#dataframe-的展示)。 +若需查看起止时间、点数等元信息,可打印 DataFrame(或其子集)——见[DataFrame 的展示](#dataframe-的展示)——也可以调用 +`list_timeseries_metadata()`。 + +## 查看元数据 + +`list_timeseries_metadata(path_prefix="")` 返回以序列名为索引的 pandas DataFrame。 +其中包含 `field`、`start_time`、`end_time`、`count` 以及设备标签列。对于 +table 模型文件,还会包含 `table` 列。 + +```python +meta = df.list_timeseries_metadata() +weather_meta = df.list_timeseries_metadata("weather") + +meta[["field", "start_time", "end_time", "count"]].head() +``` ## 选取序列 diff --git a/src/zh/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md b/src/zh/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md index de6d39796..1edc34e54 100644 --- a/src/zh/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md +++ b/src/zh/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md @@ -32,10 +32,12 @@ typedef enum { TS_DATATYPE_FLOAT = 3, TS_DATATYPE_DOUBLE = 4, TS_DATATYPE_TEXT = 5, + TS_DATATYPE_VECTOR = 6, TS_DATATYPE_TIMESTAMP = 8, TS_DATATYPE_DATE = 9, TS_DATATYPE_BLOB = 10, TS_DATATYPE_STRING = 11, + TS_DATATYPE_NULL_TYPE = 254, TS_DATATYPE_INVALID = 255 } TSDataType; @@ -44,10 +46,18 @@ typedef enum { TS_ENCODING_PLAIN = 0, TS_ENCODING_DICTIONARY = 1, TS_ENCODING_RLE = 2, + TS_ENCODING_DIFF = 3, TS_ENCODING_TS_2DIFF = 4, + TS_ENCODING_BITMAP = 5, + TS_ENCODING_GORILLA_V1 = 6, + TS_ENCODING_REGULAR = 7, TS_ENCODING_GORILLA = 8, TS_ENCODING_ZIGZAG = 9, + TS_ENCODING_FREQ = 10, + TS_ENCODING_CHIMP = 11, TS_ENCODING_SPRINTZ = 12, + TS_ENCODING_RLBE = 13, + TS_ENCODING_CAMEL = 14, TS_ENCODING_INVALID = 255 } TSEncoding; @@ -57,7 +67,12 @@ typedef enum { TS_COMPRESSION_SNAPPY = 1, TS_COMPRESSION_GZIP = 2, TS_COMPRESSION_LZO = 3, + TS_COMPRESSION_SDT = 4, + TS_COMPRESSION_PAA = 5, + TS_COMPRESSION_PLA = 6, TS_COMPRESSION_LZ4 = 7, + TS_COMPRESSION_ZSTD = 8, + TS_COMPRESSION_LZMA2 = 9, TS_COMPRESSION_INVALID = 255 } CompressionType; @@ -83,15 +98,89 @@ typedef struct table_schema { int column_num; } TableSchema; +typedef struct timeseries_schema { + char* timeseries_name; + TSDataType data_type; + TSEncoding encoding; + CompressionType compression; +} TimeseriesSchema; + +typedef struct device_schema { + char* device_name; + TimeseriesSchema* timeseries_schema; + int timeseries_num; +} DeviceSchema; + // ResultSetMetaData:结果集的元数据,包括列名和数据类型。 typedef struct result_set_meta_data { char** column_names; TSDataType* data_types; int column_num; } ResultSetMetaData; + +typedef struct arrow_schema ArrowSchema; +typedef struct arrow_array ArrowArray; + +typedef struct DeviceID { + char* path; + char* table_name; + uint32_t segment_count; + char** segments; +} DeviceID; + +typedef struct TsFileStatisticBase { + bool has_statistic; + TSDataType type; + int32_t row_count; + int64_t start_time; + int64_t end_time; +} TsFileStatisticBase; + +typedef struct TsFileBoolStatistic { TsFileStatisticBase base; double sum; bool first_bool; bool last_bool; } TsFileBoolStatistic; +typedef struct TsFileIntStatistic { TsFileStatisticBase base; double sum; int64_t min_int64; int64_t max_int64; int64_t first_int64; int64_t last_int64; } TsFileIntStatistic; +typedef struct TsFileFloatStatistic { TsFileStatisticBase base; double sum; double min_float64; double max_float64; double first_float64; double last_float64; } TsFileFloatStatistic; +typedef struct TsFileStringStatistic { TsFileStatisticBase base; char* str_min; char* str_max; char* str_first; char* str_last; } TsFileStringStatistic; +typedef struct TsFileTextStatistic { TsFileStatisticBase base; char* str_first; char* str_last; } TsFileTextStatistic; + +typedef union TimeseriesStatisticUnion { + TsFileBoolStatistic bool_s; + TsFileIntStatistic int_s; + TsFileFloatStatistic float_s; + TsFileStringStatistic string_s; + TsFileTextStatistic text_s; +} TimeseriesStatisticUnion; + +typedef struct TimeseriesStatistic { + TimeseriesStatisticUnion u; +} TimeseriesStatistic; + +#define tsfile_statistic_base(s) ((TsFileStatisticBase*)&(s)->u) + +typedef struct TimeseriesMetadata { + char* measurement_name; + TSDataType data_type; + int32_t chunk_meta_count; + TimeseriesStatistic statistic; + TimeseriesStatistic timeline_statistic; +} TimeseriesMetadata; + +typedef struct DeviceTimeseriesMetadataEntry { + DeviceID device; + TimeseriesMetadata* timeseries; + uint32_t timeseries_count; +} DeviceTimeseriesMetadataEntry; + +typedef struct DeviceTimeseriesMetadataMap { + DeviceTimeseriesMetadataEntry* entries; + uint32_t device_count; +} DeviceTimeseriesMetadataMap; ``` > `ColumnSchema` 不携带编码/压缩:写入时列遵循全局默认值(见[配置](#配置编码与压缩)),读取时按文件中的实际配置解码。 +> +> `TimeseriesStatistic` 是 `tsfile_cwrapper.h` 中的带标签 union。可通过 +> `tsfile_statistic_base(&metadata.statistic)` 读取通用字段,再根据数据类型读取 +> `int_s`、`float_s`、`bool_s`、`string_s` 或 `text_s`。 ## 写入接口 @@ -207,9 +296,11 @@ ERRNO tablet_add_timestamp(Tablet tablet, uint32_t row_index, * * @param value [输入] 以 '\0' 结尾的字符串,调用者保留所有权。 */ -ERRNO tablet_add_value_by_name_string(Tablet tablet, uint32_t row_index, - const char* column_name, - const char* value); +ERRNO tablet_add_value_by_name_string_with_len(Tablet tablet, + uint32_t row_index, + const char* column_name, + const char* value, + int value_len); // 支持多种数据类型插入 ERRNO tablet_add_value_by_name_int32_t(Tablet tablet, uint32_t row_index, @@ -236,9 +327,11 @@ ERRNO tablet_add_value_by_name_bool(Tablet tablet, uint32_t row_index, * * @param value [输入] 字符串会被内部复制。 */ -ERRNO tablet_add_value_by_index_string(Tablet tablet, uint32_t row_index, - uint32_t column_index, - const char* value); +ERRNO tablet_add_value_by_index_string_with_len(Tablet tablet, + uint32_t row_index, + uint32_t column_index, + const char* value, + int value_len); ERRNO tablet_add_value_by_index_int32_t(Tablet tablet, uint32_t row_index, @@ -310,11 +403,12 @@ uint8_t get_global_time_compression(); | 数据类型 | 允许的编码 | 默认值 | |---|---|---| | `BOOLEAN` | `PLAIN` | `PLAIN` | -| `INT32`、`INT64`、`DATE` | `PLAIN`、`TS_2DIFF`、`GORILLA`、`ZIGZAG`、`RLE`、`SPRINTZ` | `TS_2DIFF` | -| `FLOAT`、`DOUBLE` | `PLAIN`、`TS_2DIFF`、`GORILLA`、`SPRINTZ` | `GORILLA` | +| `INT32`、`INT64`、`TIMESTAMP`、`DATE` | `PLAIN`、`TS_2DIFF`、`GORILLA`、`ZIGZAG`、`RLE`、`SPRINTZ`、`CHIMP`、`RLBE` | `TS_2DIFF` | +| `FLOAT` | `PLAIN`、`TS_2DIFF`、`GORILLA`、`SPRINTZ`、`CHIMP`、`RLBE` | `GORILLA` | +| `DOUBLE` | `PLAIN`、`TS_2DIFF`、`GORILLA`、`SPRINTZ`、`CHIMP`、`RLBE`、`CAMEL` | `GORILLA` | | `STRING`、`TEXT` | `PLAIN`、`DICTIONARY` | `PLAIN` | -压缩适用于所有数据类型:`UNCOMPRESSED`、`SNAPPY`、`GZIP`、`LZO`、`LZ4`(默认 `LZ4`)。 +压缩适用于所有数据类型:`UNCOMPRESSED`、`SNAPPY`、`GZIP`、`LZO`、`LZ4`、`ZSTD`、`LZMA2`(默认 `LZ4`)。 ```C // 例如:所有列均以 LZ4 压缩写入 @@ -387,6 +481,31 @@ bool tsfile_result_set_next(ResultSet result_set, ERRNO* error_code); void free_tsfile_result_set(ResultSet* result_set); ``` +### Tree 查询 + +```C +/** + * @brief 按测点名在时间范围内查询 tree 模型数据。 + */ +ResultSet tsfile_query_table_on_tree(TsFileReader reader, char** columns, + uint32_t column_num, Timestamp start_time, + Timestamp end_time, ERRNO* err_code); + +/** + * @brief 按行查询 tree 模型数据,支持 offset/limit。 + * + * @param device_ids 设备标识数组。 + * @param measurement_names 测点名数组。 + * @param offset 需要跳过的起始行数(>= 0)。 + * @param limit 最多返回行数;< 0 表示不限制。 + */ +ResultSet tsfile_reader_query_tree_by_row(TsFileReader reader, + char** device_ids, int device_ids_len, + char** measurement_names, + int measurement_names_len, int offset, + int limit, ERRNO* err_code); +``` + ### 按标签过滤 @@ -409,6 +528,8 @@ typedef enum { TAG_FILTER_GTEQ = 5, // 列 >= 值 TAG_FILTER_REGEXP = 6, // 列匹配正则 值 TAG_FILTER_NOT_REGEXP = 7, // 列不匹配正则 值 + TAG_FILTER_IS_NULL = 8, // 列为空 + TAG_FILTER_IS_NOT_NULL = 9, // 列不为空 } TagFilterOp; /** @@ -417,7 +538,7 @@ typedef enum { * @param reader [输入] 有效的 TsFileReader 句柄。 * @param table_name [输入] 其 schema 定义了这些标签列的表名。 * @param column_name [输入] 要过滤的标签列名。 - * @param value [输入] 比较值(标签列为 STRING 类型)。 + * @param value [输入] 比较值(IS NULL / IS NOT NULL 会忽略该参数)。 * @param op [输入] 比较运算符(TagFilterOp)。 * @param err_code [输出] 成功返回 RET_OK(0),否则返回 errno_define_c.h 中的错误码。 * @return 成功返回 TagFilterHandle,失败返回 NULL。 @@ -437,6 +558,20 @@ TagFilterHandle tsfile_tag_filter_between(TsFileReader reader, const char* lower, const char* upper, bool is_not, ERRNO* err_code); +// 常用单列谓词的便捷构造函数。 +TagFilterHandle tsfile_tag_filter_eq(TsFileReader reader, const char* table_name, + const char* column_name, const char* value); +TagFilterHandle tsfile_tag_filter_neq(TsFileReader reader, const char* table_name, + const char* column_name, const char* value); +TagFilterHandle tsfile_tag_filter_lt(TsFileReader reader, const char* table_name, + const char* column_name, const char* value); +TagFilterHandle tsfile_tag_filter_lteq(TsFileReader reader, const char* table_name, + const char* column_name, const char* value); +TagFilterHandle tsfile_tag_filter_gt(TsFileReader reader, const char* table_name, + const char* column_name, const char* value); +TagFilterHandle tsfile_tag_filter_gteq(TsFileReader reader, const char* table_name, + const char* column_name, const char* value); + // 组合谓词。AND/OR/NOT 会接管其子节点的所有权,只需释放根节点。 TagFilterHandle tsfile_tag_filter_and(TagFilterHandle left, TagFilterHandle right); TagFilterHandle tsfile_tag_filter_or(TagFilterHandle left, TagFilterHandle right); @@ -493,6 +628,18 @@ ResultSet tsfile_query_table_with_tag_filter( TagFilterHandle tag_filter, int batch_size, ERRNO* err_code); ``` +### 将批结果读取为 Arrow + +对 `batch_size > 0` 创建的批查询结果集,可以使用 Arrow C Data Interface 读取 +`ArrowArray` 和 `ArrowSchema`。调用者拥有返回的 Arrow 对象,使用完后必须调用 +它们的 `release` 回调。 + +```C +ERRNO tsfile_result_set_get_next_tsblock_as_arrow(ResultSet result_set, + ArrowArray* out_array, + ArrowSchema* out_schema); +``` + 示例——只读取 `region` 标签等于 `shanghai` 的设备的 `temperature`: ```C @@ -640,6 +787,17 @@ TableSchema tsfile_reader_get_table_schema(TsFileReader reader, TableSchema* tsfile_reader_get_all_table_schemas(TsFileReader reader, uint32_t* size); +/** + * @brief 获取 TsFile 中所有 timeseries schema。 + * + * @param size [输出] 返回的 DeviceSchema 数组中的元素数量。 + * @return DeviceSchema* 设备 schema 数组指针。 + * @note 调用者必须对数组中的每个元素调用 free_device_schema(), + * 并对整个数组指针调用 free() 进行释放。 + */ +DeviceSchema* tsfile_reader_get_all_timeseries_schemas(TsFileReader reader, + uint32_t* size); + /** * @brief 释放 TableSchema 占用的内存空间。 * @@ -647,5 +805,40 @@ TableSchema* tsfile_reader_get_all_table_schemas(TsFileReader reader, */ void free_table_schema(TableSchema schema); + +void free_device_schema(DeviceSchema schema); ``` +### 获取设备与 Timeseries Metadata + +```C +/** + * @brief 列出文件中的所有设备。 + * + * @param out_devices [输出] 分配出的设备数组;用 tsfile_free_device_id_array() 释放。 + * @param out_length [输出] 返回数组中的设备数量。 + */ +ERRNO tsfile_reader_get_all_devices(TsFileReader reader, DeviceID** out_devices, + uint32_t* out_length); + +void tsfile_free_device_id_array(DeviceID* devices, uint32_t length); +void tsfile_device_id_free_contents(DeviceID* d); + +/** + * @brief 获取文件中所有设备的 timeseries metadata。 + */ +ERRNO tsfile_reader_get_timeseries_metadata_all( + TsFileReader reader, DeviceTimeseriesMetadataMap* out_map); + +/** + * @brief 获取指定设备的 timeseries metadata。 + * + * length == 0 返回空 map。非空输入中每个 DeviceID.path 应包含规范设备路径。 + */ +ERRNO tsfile_reader_get_timeseries_metadata_for_devices( + TsFileReader reader, const DeviceID* devices, uint32_t length, + DeviceTimeseriesMetadataMap* out_map); + +void tsfile_free_device_timeseries_metadata_map( + DeviceTimeseriesMetadataMap* map); +``` diff --git a/src/zh/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md b/src/zh/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md index 50de78b47..f337c46ec 100644 --- a/src/zh/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md +++ b/src/zh/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md @@ -31,10 +31,14 @@ enum TSDataType : uint8_t { FLOAT = 3, DOUBLE = 4, TEXT = 5, + VECTOR = 6, + UNKNOWN = 7, TIMESTAMP = 8, DATE = 9, BLOB = 10, STRING = 11, + NULL_TYPE = 254, + INVALID_DATATYPE = 255, }; // 值编码。各编码适用于哪些类型见下表。 @@ -42,19 +46,35 @@ enum TSEncoding : uint8_t { PLAIN = 0, DICTIONARY = 1, RLE = 2, + DIFF = 3, TS_2DIFF = 4, + BITMAP = 5, + GORILLA_V1 = 6, + REGULAR = 7, GORILLA = 8, ZIGZAG = 9, + FREQ = 10, + CHIMP = 11, SPRINTZ = 12, + RLBE = 13, + CAMEL = 14, + INVALID_ENCODING = 255, }; -// 压缩类型。SNAPPY/GZIP/LZO/LZ4 取决于构建选项;默认压缩为 LZ4。 +// 压缩类型。SNAPPY/GZIP/LZO/LZ4/ZSTD/LZMA2 取决于构建选项; +// 默认压缩为 LZ4。 enum CompressionType : uint8_t { UNCOMPRESSED = 0, SNAPPY = 1, GZIP = 2, LZO = 3, + SDT = 4, + PAA = 5, + PLA = 6, LZ4 = 7, + ZSTD = 8, + LZMA2 = 9, + INVALID_COMPRESSION = 255, }; // 列在表 schema 内的角色。 @@ -72,6 +92,8 @@ enum class ColumnCategory { TAG = 0, FIELD = 1, ATTRIBUTE = 2, TIME = 3 }; | `GORILLA` | `INT32`、`INT64`、`TIMESTAMP`、`DATE`、`FLOAT`、`DOUBLE` | | `ZIGZAG` | `INT32`、`INT64` | | `SPRINTZ` | `INT32`、`INT64`、`FLOAT`、`DOUBLE` | +| `CHIMP`、`RLBE` | `INT32`、`INT64`、`TIMESTAMP`、`DATE`、`FLOAT`、`DOUBLE` | +| `CAMEL` | `DOUBLE` | 各类型的默认值编码:`BOOLEAN → PLAIN`、`INT32 / INT64 → TS_2DIFF`、 `FLOAT / DOUBLE → GORILLA`、`TEXT / STRING / BLOB → PLAIN`。默认压缩为 `LZ4`。 @@ -135,6 +157,64 @@ class TsFileTableWriter { }; ``` +### TsFileWriter + +`TsFileWriter` 是 `tsfile_writer.h` 中的低层写入接口,支持 tree 模型和 table +模型写入。 + +```cpp +extern int libtsfile_init(); +extern void libtsfile_destroy(); + +// 写入器配置。非法值返回 common::E_INVALID_ARG,并保持原配置不变。 +extern int set_page_max_point_count(uint32_t page_max_point_count); +extern int set_max_degree_of_index_node(uint32_t max_degree_of_index_node); + +class TsFileWriter { + public: + TsFileWriter(); + ~TsFileWriter(); + void destroy(); + + int open(const std::string& file_path, int flags, mode_t mode); + int open(const std::string& file_path); + int init(storage::WriteFile* write_file); + int init(storage::RestorableTsFileIOWriter* rw); + + void set_generate_table_schema(bool generate_table_schema); + + int register_timeseries(const std::string& device_id, + const MeasurementSchema& measurement_schema); + int register_timeseries( + const std::string& device_path, + const std::vector& measurement_schema_vec); + int register_aligned_timeseries( + const std::string& device_id, + const MeasurementSchema& measurement_schema); + int register_aligned_timeseries( + const std::string& device_id, + const std::vector& measurement_schemas); + int register_table(const std::shared_ptr& table_schema); + + int write_record(const TsRecord& record); + int write_tablet(const Tablet& tablet); + int write_record_aligned(const TsRecord& record); + int write_tablet_aligned(const Tablet& tablet); + int write_tree(const Tablet& tablet); + int write_tree(const TsRecord& record); + int write_table(Tablet& tablet); + + DeviceSchemasMap* get_schema_group_map(); + std::shared_ptr get_table_schema( + const std::string& table_name) const; + int64_t calculate_mem_size_for_all_group(); + int64_t calculate_meta_mem_size() const; + int check_memory_size_and_may_flush_chunks(); + int flush(); + int close(); +}; +``` + ### TableSchema 描述表模式(schema)的数据结构。 @@ -297,8 +377,14 @@ uint8_t common::get_global_compression(); // 时间列的编码/压缩(数据类型固定为 INT64)。 int common::set_global_time_encoding(uint8_t encoding); int common::set_global_time_compression(uint8_t compression); +uint8_t common::get_global_time_encoding(); +uint8_t common::get_global_time_compression(); ``` +全局压缩支持 `UNCOMPRESSED`、`SNAPPY`、`GZIP`、`LZO`、`LZ4`、`ZSTD` +和 `LZMA2`。压缩枚举中也包含 `SDT`、`PAA`、`PLA` 等历史值,但全局压缩 +setter 会拒绝这些值。 + ## 读取接口 ### Tsfile Reader ```cpp @@ -335,6 +421,16 @@ class TsFileReader { * @return 成功时返回 0,失败时返回 errno_define.h 中的非零错误码。 */ int query(storage::QueryExpression *qe, ResultSet *&ret_qds); + /** + * @brief 通过路径列表、起始时间和结束时间查询 tsfile。用于 tree 模型。 + * + * @param [in] path_list 完整路径列表。 + * @param [in] start_time 起始时间。 + * @param [in] end_time 结束时间。 + * @param [out] result_set 查询结果集。 + */ + int query(std::vector& path_list, int64_t start_time, + int64_t end_time, ResultSet*& result_set); /** * @brief 通过表名、列名、起始时间和结束时间查询 tsfile。 * @@ -346,7 +442,7 @@ class TsFileReader { */ int query(const std::string &table_name, const std::vector &columns_names, int64_t start_time, - int64_t end_time, ResultSet *&result_set); + int64_t end_time, ResultSet *&result_set, int batch_size = -1); /** * @brief 通过表名、列名、开始时间、结束时间和标签过滤器查询 tsfile。 @@ -360,7 +456,14 @@ class TsFileReader { */ int query(const std::string& table_name, const std::vector& columns_names, int64_t start_time, - int64_t end_time, ResultSet*& result_set, Filter* tag_filter); + int64_t end_time, ResultSet*& result_set, Filter* tag_filter, + int batch_size = 0); + + /** + * @brief 按行查询 tree 模型序列,支持 offset/limit。 + */ + int queryByRow(std::vector& path_list, int offset, int limit, + ResultSet*& result_set); /** * @brief 按行查询表,支持偏移量/行数限制下推与可选的标签过滤。 @@ -379,12 +482,39 @@ class TsFileReader { int limit, ResultSet*& result_set, Filter* tag_filter = nullptr, int batch_size = 0); + /** + * @brief 按测点名在时间范围内查询 tree 模型数据。 + */ + int query_table_on_tree(const std::vector& measurement_names, + int64_t start_time, int64_t end_time, + ResultSet*& result_set); + /** * @brief 销毁结果集,该方法应在查询完成并使用完 result_set 后调用。 * * @param qds 查询结果集。 */ void destroy_query_data_set(ResultSet *qds); + + ResultSet* read_timeseries( + const std::shared_ptr& device_id, + const std::vector& measurement_name); + + std::vector> get_all_devices( + std::string table_name); + + std::vector> get_all_device_ids(); + + std::vector> get_all_devices(); + + int get_timeseries_schema(std::shared_ptr device_id, + std::vector& result); + + DeviceTimeseriesMetadataMap get_timeseries_metadata( + const std::vector>& device_ids); + + DeviceTimeseriesMetadataMap get_timeseries_metadata(); + /** * @brief 根据表名获取表的模式信息。 * @@ -401,6 +531,11 @@ class TsFileReader { std::vector> get_all_table_schemas(); }; ``` + +`DeviceTimeseriesMetadataMap` 是 `get_timeseries_metadata()` 返回的元数据 +map:`std::map, +std::vector>, IDeviceIDComparator>`。 + ### ResultSet ```cpp /** @@ -540,6 +675,8 @@ class TagFilterBuilder { Filter* reg_exp(const std::string& columnName, const std::string& value); Filter* not_reg_exp(const std::string& columnName, const std::string& value); + Filter* is_null(const std::string& columnName); + Filter* is_not_null(const std::string& columnName); Filter* between_and(const std::string& columnName, const std::string& lower, const std::string& upper); Filter* not_between_and(const std::string& columnName, @@ -550,4 +687,4 @@ class TagFilterBuilder { static Filter* or_filter(Filter* left, Filter* right); static Filter* not_filter(Filter* filter); }; -``` \ No newline at end of file +``` diff --git a/src/zh/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md b/src/zh/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md index c94b690c7..1d3e875b1 100644 --- a/src/zh/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md +++ b/src/zh/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md @@ -45,10 +45,17 @@ class TSEncoding(IntEnum): PLAIN = 0 # 所有类型 DICTIONARY = 1 # STRING、TEXT RLE = 2 # INT32、INT64、TIMESTAMP、DATE + DIFF = 3 TS_2DIFF = 4 # INT32、INT64、TIMESTAMP、DATE、FLOAT、DOUBLE + BITMAP = 5 + GORILLA_V1 = 6 + REGULAR = 7 GORILLA = 8 # INT32、INT64、TIMESTAMP、DATE、FLOAT、DOUBLE ZIGZAG = 9 # INT32、INT64 + CHIMP = 11 # INT32、INT64、TIMESTAMP、DATE、FLOAT、DOUBLE SPRINTZ = 12 # INT32、INT64、FLOAT、DOUBLE + RLBE = 13 # INT32、INT64、TIMESTAMP、DATE、FLOAT、DOUBLE + CAMEL = 14 # DOUBLE class Compressor(IntEnum): """ @@ -58,7 +65,12 @@ class Compressor(IntEnum): SNAPPY = 1 GZIP = 2 LZO = 3 + SDT = 4 + PAA = 5 + PLA = 6 LZ4 = 7 + ZSTD = 8 + LZMA2 = 9 class ColumnCategory(IntEnum): """ @@ -99,6 +111,32 @@ class ResultSetMetaData: def __init__(self, column_list: List[str], data_types: List[TSDataType]) +@dataclass(frozen=True) +class DeviceID: + path: Optional[str] + table_name: Optional[str] + segments: tuple[Optional[str], ...] + +@dataclass(frozen=True) +class TimeseriesStatistic: + has_statistic: bool + row_count: int + start_time: int + end_time: int + +@dataclass(frozen=True) +class TimeseriesMetadata: + measurement_name: str + data_type: TSDataType + chunk_meta_count: int + statistic: TimeseriesStatistic + timeline_statistic: TimeseriesStatistic + +@dataclass(frozen=True) +class DeviceTimeseriesMetadataGroup: + table_name: Optional[str] + segments: tuple[Optional[str], ...] + timeseries: list[TimeseriesMetadata] ``` @@ -106,7 +144,7 @@ class ResultSetMetaData: ## 写入接口 -### TsFileWriter +### TsFileTableWriter ```python class TsFileTableWriter: @@ -157,6 +195,48 @@ class TsFileTableWriter: ``` +### TsFileWriter + +`TsFileWriter` 是 `writer.pyx` 暴露的低层写入接口。它可以写入 tree 模型数据 +(`register_timeseries`、`register_device`、`write_tablet`、`write_row_record`), +也可以写入 table 模型数据(`register_table`、`write_table`、`write_dataframe`、 +`write_arrow_batch`)。 + +```python +class TsFileWriter: + """ + :param pathname: 目标 TsFile 路径。 + :param memory_threshold: 触发自动刷盘前缓冲的字节数(默认 128MB)。 + """ + def __init__(self, pathname: str, memory_threshold: int = 128 * 1024 * 1024) + + def register_timeseries(self, device_name: str, + timeseries_schema: TimeseriesSchema) + + def register_device(self, device_schema: DeviceSchema) + + def register_table(self, table_schema: TableSchema) + + def write_tablet(self, tablet: Tablet) + + def write_dataframe(self, target_table: str, dataframe: pandas.DataFrame, + tableschema: TableSchema) + + def write_row_record(self, record: RowRecord) + + def write_table(self, tablet: Tablet) + + def write_arrow_batch(self, table_name: str, data, + time_col_index: int = -1) + + def flush(self) + + def close(self) + + def __enter__(self) + def __exit__(self, exc_type, exc_val, exc_tb) +``` + ### Tablet definition @@ -223,11 +303,12 @@ set_tsfile_config({ | 数据类型 | 允许的编码 | 默认值 | |---|---|---| | `BOOLEAN` | `PLAIN` | `PLAIN` | -| `INT32`、`INT64`、`DATE` | `PLAIN`、`TS_2DIFF`、`GORILLA`、`ZIGZAG`、`RLE`、`SPRINTZ` | `TS_2DIFF` | -| `FLOAT`、`DOUBLE` | `PLAIN`、`TS_2DIFF`、`GORILLA`、`SPRINTZ` | `GORILLA` | +| `INT32`、`INT64`、`TIMESTAMP`、`DATE` | `PLAIN`、`TS_2DIFF`、`GORILLA`、`ZIGZAG`、`RLE`、`SPRINTZ`、`CHIMP`、`RLBE` | `TS_2DIFF` | +| `FLOAT` | `PLAIN`、`TS_2DIFF`、`GORILLA`、`SPRINTZ`、`CHIMP`、`RLBE` | `GORILLA` | +| `DOUBLE` | `PLAIN`、`TS_2DIFF`、`GORILLA`、`SPRINTZ`、`CHIMP`、`RLBE`、`CAMEL` | `GORILLA` | | `STRING`、`TEXT` | `PLAIN`、`DICTIONARY` | `PLAIN` | -压缩适用于所有数据类型:`UNCOMPRESSED`、`SNAPPY`、`GZIP`、`LZO`、`LZ4`(默认 `LZ4`)。 +压缩适用于所有数据类型:`UNCOMPRESSED`、`SNAPPY`、`GZIP`、`LZO`、`LZ4`、`ZSTD`、`LZMA2`(默认 `LZ4`)。枚举还暴露 `SDT`、`PAA`、`PLA` 等历史值,但全局配置 setter 会拒绝这些值。 ## 读取接口 @@ -253,11 +334,39 @@ class TsFileReader: :param column_names: 要检索的列名列表。 :param start_time: 查询范围的起始时间(默认:int64 最小值)。 :param end_time: 查询范围的结束时间(默认:int64 最大值)。 + :param tag_filter: 可选的 table 模型 TAG 列谓词。 + :param batch_size: <= 0 逐行返回;> 0 按该大小返回数据块。 :return: 查询结果集处理器。 """ def query_table(self, table_name : str, column_names : List[str], start_time : int = np.iinfo(np.int64).min, - end_time: int = np.iinfo(np.int64).max) -> ResultSet + end_time: int = np.iinfo(np.int64).max, + tag_filter = None, batch_size : int = 0) -> ResultSet + + """ + 对 tree 模型测点列执行时间范围查询。 + + :param column_names: 要检索的测点名列表。 + :param start_time: 查询范围的起始时间。 + :param end_time: 查询范围的结束时间。 + :return: 查询结果集处理器。 + """ + def query_table_on_tree(self, column_names : List[str], + start_time : int = np.iinfo(np.int64).min, + end_time : int = np.iinfo(np.int64).max) -> ResultSet + + """ + 按行查询 tree 模型数据,支持 offset/limit。 + + :param device_ids: 要查询的设备标识列表。 + :param measurement_names: 要检索的测点名列表。 + :param offset: 需要跳过的起始行数。 + :param limit: 最多返回行数;< 0 表示不限制。 + :return: 查询结果集处理器。 + """ + def query_tree_by_row(self, device_ids : List[str], + measurement_names : List[str], + offset : int = 0, limit : int = -1) -> ResultSet """ 按行查询表,支持偏移量/行数限制下推与可选的标签过滤。标签谓词把查询限定到 @@ -277,6 +386,18 @@ class TsFileReader: offset : int = 0, limit : int = -1, tag_filter = None, batch_size : int = 0) -> ResultSet + """ + 对单个设备执行 tree 模型时间范围查询。 + + :param device_name: 设备标识。 + :param sensor_list: 要检索的测点名列表。 + :param start_time: 查询起始时间。 + :param end_time: 查询结束时间。 + :return: 查询结果集处理器。 + """ + def query_timeseries(self, device_name : str, sensor_list : List[str], + start_time : int = 0, end_time : int = 0) -> ResultSet + """ 获取指定表的模式信息。 @@ -292,6 +413,31 @@ class TsFileReader: """ def get_all_table_schemas(self) -> dict[str, TableSchema] + """ + 获取所有 tree 模型 timeseries schema,按设备分组。 + + :return: DeviceSchema 对象列表。 + """ + def get_all_timeseries_schemas(self) -> list[DeviceSchema] + + """ + 获取文件中的所有设备标识。 + + :return: DeviceID(path, table_name, segments) 列表。 + """ + def get_all_devices(self) -> List[DeviceID] + + """ + 获取所有设备或指定设备的 per-timeseries metadata。 + + :param device_ids: None 表示全部设备,[] 表示空结果,或传入 DeviceID / + 路径兼容的设备标识列表。 + :return: dict,key 为设备 segment tuple,value 为 DeviceTimeseriesMetadataGroup。 + """ + def get_timeseries_metadata( + self, device_ids: Optional[List] = None + ) -> Dict[tuple, DeviceTimeseriesMetadataGroup] + """ 关闭 TsFile 读取器。如果读取器中有活动的结果集,它们将失效。 """ @@ -332,6 +478,12 @@ class ResultSet: """ def read_data_frame(self, max_row_num : int = 1024) -> DataFrame + """ + 将下一个批结果读取为 pyarrow.Table。没有更多 TsBlock 批时返回 None。 + 仅适用于通过 batch_size > 0 创建的结果集。 + """ + def read_arrow_batch(self) -> Optional[pyarrow.Table] + """ 从查询结果集中按索引获取值。 @@ -376,6 +528,9 @@ class ResultSet: """ def close(self) + def __enter__(self) + def __exit__(self, exc_type, exc_val, exc_tb) + ``` diff --git a/src/zh/UserGuide/latest/DataFrame/TsFileDataFrame.md b/src/zh/UserGuide/latest/DataFrame/TsFileDataFrame.md index 816a8cca6..2a7bf9616 100644 --- a/src/zh/UserGuide/latest/DataFrame/TsFileDataFrame.md +++ b/src/zh/UserGuide/latest/DataFrame/TsFileDataFrame.md @@ -59,9 +59,11 @@ data.values # -> np.ndarray, shape (N, 2):N | 示例 | 操作 | 返回类型 | |---|---|---| -| `TsFileDataFrame(paths)` | 加载文件 / 文件列表 / 目录 | `TsFileDataFrame` | +| `TsFileDataFrame(paths, show_progress=True)` | 加载文件 / 文件列表 / 目录。设置 `show_progress=False` 可关闭 stderr 上的加载进度 | `TsFileDataFrame` | | `len(df)` | 时间序列总数 | `int` | +| `df.model` | 已加载文件模型:`"table"` 或 `"tree"` | `str` | | `df.list_timeseries("weather")` | 获取序列名,可按前缀筛选 | `List[str]` | +| `df.list_timeseries_metadata("weather")` | 获取序列元数据,可按前缀筛选 | `pandas.DataFrame` | | `df["weather.Beijing.humidity"]`、`df[0]`、`df[-1]` | 获取单条序列 | `Timeseries` | | `df["city"]` | 获取某元数据列(标签 / `field` / `start_time` / `end_time` / `count`) | `pandas.Series` | | `df[0:3]`、`df[[0, 2, 5]]` | 按整数位置取子集视图:连续区间(`0:3`)或所列位置(`[0, 2, 5]`);位置即打印的 `index` 列 | `TsFileDataFrame` | @@ -132,6 +134,7 @@ from tsfile import TsFileDataFrame df = TsFileDataFrame(["data/weather.tsfile", "data/sensor.tsfile"]) df = TsFileDataFrame("data/") # 递归查找目录下所有 .tsfile +df = TsFileDataFrame("data/", show_progress=False) print(df) ``` @@ -172,7 +175,21 @@ TsFileDataFrame(table model, 972 time series, 5 files) ['weather.Beijing.humidity', 'weather.Beijing.temperature'] ``` -若需查看起止时间、点数等元信息,可打印 DataFrame(或其子集)——见[DataFrame 的展示](#dataframe-的展示)。 +若需查看起止时间、点数等元信息,可打印 DataFrame(或其子集)——见[DataFrame 的展示](#dataframe-的展示)——也可以调用 +`list_timeseries_metadata()`。 + +## 查看元数据 + +`list_timeseries_metadata(path_prefix="")` 返回以序列名为索引的 pandas DataFrame。 +其中包含 `field`、`start_time`、`end_time`、`count` 以及设备标签列。对于 +table 模型文件,还会包含 `table` 列。 + +```python +meta = df.list_timeseries_metadata() +weather_meta = df.list_timeseries_metadata("weather") + +meta[["field", "start_time", "end_time", "count"]].head() +``` ## 选取序列 diff --git a/src/zh/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md b/src/zh/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md index de6d39796..1edc34e54 100644 --- a/src/zh/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md +++ b/src/zh/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md @@ -32,10 +32,12 @@ typedef enum { TS_DATATYPE_FLOAT = 3, TS_DATATYPE_DOUBLE = 4, TS_DATATYPE_TEXT = 5, + TS_DATATYPE_VECTOR = 6, TS_DATATYPE_TIMESTAMP = 8, TS_DATATYPE_DATE = 9, TS_DATATYPE_BLOB = 10, TS_DATATYPE_STRING = 11, + TS_DATATYPE_NULL_TYPE = 254, TS_DATATYPE_INVALID = 255 } TSDataType; @@ -44,10 +46,18 @@ typedef enum { TS_ENCODING_PLAIN = 0, TS_ENCODING_DICTIONARY = 1, TS_ENCODING_RLE = 2, + TS_ENCODING_DIFF = 3, TS_ENCODING_TS_2DIFF = 4, + TS_ENCODING_BITMAP = 5, + TS_ENCODING_GORILLA_V1 = 6, + TS_ENCODING_REGULAR = 7, TS_ENCODING_GORILLA = 8, TS_ENCODING_ZIGZAG = 9, + TS_ENCODING_FREQ = 10, + TS_ENCODING_CHIMP = 11, TS_ENCODING_SPRINTZ = 12, + TS_ENCODING_RLBE = 13, + TS_ENCODING_CAMEL = 14, TS_ENCODING_INVALID = 255 } TSEncoding; @@ -57,7 +67,12 @@ typedef enum { TS_COMPRESSION_SNAPPY = 1, TS_COMPRESSION_GZIP = 2, TS_COMPRESSION_LZO = 3, + TS_COMPRESSION_SDT = 4, + TS_COMPRESSION_PAA = 5, + TS_COMPRESSION_PLA = 6, TS_COMPRESSION_LZ4 = 7, + TS_COMPRESSION_ZSTD = 8, + TS_COMPRESSION_LZMA2 = 9, TS_COMPRESSION_INVALID = 255 } CompressionType; @@ -83,15 +98,89 @@ typedef struct table_schema { int column_num; } TableSchema; +typedef struct timeseries_schema { + char* timeseries_name; + TSDataType data_type; + TSEncoding encoding; + CompressionType compression; +} TimeseriesSchema; + +typedef struct device_schema { + char* device_name; + TimeseriesSchema* timeseries_schema; + int timeseries_num; +} DeviceSchema; + // ResultSetMetaData:结果集的元数据,包括列名和数据类型。 typedef struct result_set_meta_data { char** column_names; TSDataType* data_types; int column_num; } ResultSetMetaData; + +typedef struct arrow_schema ArrowSchema; +typedef struct arrow_array ArrowArray; + +typedef struct DeviceID { + char* path; + char* table_name; + uint32_t segment_count; + char** segments; +} DeviceID; + +typedef struct TsFileStatisticBase { + bool has_statistic; + TSDataType type; + int32_t row_count; + int64_t start_time; + int64_t end_time; +} TsFileStatisticBase; + +typedef struct TsFileBoolStatistic { TsFileStatisticBase base; double sum; bool first_bool; bool last_bool; } TsFileBoolStatistic; +typedef struct TsFileIntStatistic { TsFileStatisticBase base; double sum; int64_t min_int64; int64_t max_int64; int64_t first_int64; int64_t last_int64; } TsFileIntStatistic; +typedef struct TsFileFloatStatistic { TsFileStatisticBase base; double sum; double min_float64; double max_float64; double first_float64; double last_float64; } TsFileFloatStatistic; +typedef struct TsFileStringStatistic { TsFileStatisticBase base; char* str_min; char* str_max; char* str_first; char* str_last; } TsFileStringStatistic; +typedef struct TsFileTextStatistic { TsFileStatisticBase base; char* str_first; char* str_last; } TsFileTextStatistic; + +typedef union TimeseriesStatisticUnion { + TsFileBoolStatistic bool_s; + TsFileIntStatistic int_s; + TsFileFloatStatistic float_s; + TsFileStringStatistic string_s; + TsFileTextStatistic text_s; +} TimeseriesStatisticUnion; + +typedef struct TimeseriesStatistic { + TimeseriesStatisticUnion u; +} TimeseriesStatistic; + +#define tsfile_statistic_base(s) ((TsFileStatisticBase*)&(s)->u) + +typedef struct TimeseriesMetadata { + char* measurement_name; + TSDataType data_type; + int32_t chunk_meta_count; + TimeseriesStatistic statistic; + TimeseriesStatistic timeline_statistic; +} TimeseriesMetadata; + +typedef struct DeviceTimeseriesMetadataEntry { + DeviceID device; + TimeseriesMetadata* timeseries; + uint32_t timeseries_count; +} DeviceTimeseriesMetadataEntry; + +typedef struct DeviceTimeseriesMetadataMap { + DeviceTimeseriesMetadataEntry* entries; + uint32_t device_count; +} DeviceTimeseriesMetadataMap; ``` > `ColumnSchema` 不携带编码/压缩:写入时列遵循全局默认值(见[配置](#配置编码与压缩)),读取时按文件中的实际配置解码。 +> +> `TimeseriesStatistic` 是 `tsfile_cwrapper.h` 中的带标签 union。可通过 +> `tsfile_statistic_base(&metadata.statistic)` 读取通用字段,再根据数据类型读取 +> `int_s`、`float_s`、`bool_s`、`string_s` 或 `text_s`。 ## 写入接口 @@ -207,9 +296,11 @@ ERRNO tablet_add_timestamp(Tablet tablet, uint32_t row_index, * * @param value [输入] 以 '\0' 结尾的字符串,调用者保留所有权。 */ -ERRNO tablet_add_value_by_name_string(Tablet tablet, uint32_t row_index, - const char* column_name, - const char* value); +ERRNO tablet_add_value_by_name_string_with_len(Tablet tablet, + uint32_t row_index, + const char* column_name, + const char* value, + int value_len); // 支持多种数据类型插入 ERRNO tablet_add_value_by_name_int32_t(Tablet tablet, uint32_t row_index, @@ -236,9 +327,11 @@ ERRNO tablet_add_value_by_name_bool(Tablet tablet, uint32_t row_index, * * @param value [输入] 字符串会被内部复制。 */ -ERRNO tablet_add_value_by_index_string(Tablet tablet, uint32_t row_index, - uint32_t column_index, - const char* value); +ERRNO tablet_add_value_by_index_string_with_len(Tablet tablet, + uint32_t row_index, + uint32_t column_index, + const char* value, + int value_len); ERRNO tablet_add_value_by_index_int32_t(Tablet tablet, uint32_t row_index, @@ -310,11 +403,12 @@ uint8_t get_global_time_compression(); | 数据类型 | 允许的编码 | 默认值 | |---|---|---| | `BOOLEAN` | `PLAIN` | `PLAIN` | -| `INT32`、`INT64`、`DATE` | `PLAIN`、`TS_2DIFF`、`GORILLA`、`ZIGZAG`、`RLE`、`SPRINTZ` | `TS_2DIFF` | -| `FLOAT`、`DOUBLE` | `PLAIN`、`TS_2DIFF`、`GORILLA`、`SPRINTZ` | `GORILLA` | +| `INT32`、`INT64`、`TIMESTAMP`、`DATE` | `PLAIN`、`TS_2DIFF`、`GORILLA`、`ZIGZAG`、`RLE`、`SPRINTZ`、`CHIMP`、`RLBE` | `TS_2DIFF` | +| `FLOAT` | `PLAIN`、`TS_2DIFF`、`GORILLA`、`SPRINTZ`、`CHIMP`、`RLBE` | `GORILLA` | +| `DOUBLE` | `PLAIN`、`TS_2DIFF`、`GORILLA`、`SPRINTZ`、`CHIMP`、`RLBE`、`CAMEL` | `GORILLA` | | `STRING`、`TEXT` | `PLAIN`、`DICTIONARY` | `PLAIN` | -压缩适用于所有数据类型:`UNCOMPRESSED`、`SNAPPY`、`GZIP`、`LZO`、`LZ4`(默认 `LZ4`)。 +压缩适用于所有数据类型:`UNCOMPRESSED`、`SNAPPY`、`GZIP`、`LZO`、`LZ4`、`ZSTD`、`LZMA2`(默认 `LZ4`)。 ```C // 例如:所有列均以 LZ4 压缩写入 @@ -387,6 +481,31 @@ bool tsfile_result_set_next(ResultSet result_set, ERRNO* error_code); void free_tsfile_result_set(ResultSet* result_set); ``` +### Tree 查询 + +```C +/** + * @brief 按测点名在时间范围内查询 tree 模型数据。 + */ +ResultSet tsfile_query_table_on_tree(TsFileReader reader, char** columns, + uint32_t column_num, Timestamp start_time, + Timestamp end_time, ERRNO* err_code); + +/** + * @brief 按行查询 tree 模型数据,支持 offset/limit。 + * + * @param device_ids 设备标识数组。 + * @param measurement_names 测点名数组。 + * @param offset 需要跳过的起始行数(>= 0)。 + * @param limit 最多返回行数;< 0 表示不限制。 + */ +ResultSet tsfile_reader_query_tree_by_row(TsFileReader reader, + char** device_ids, int device_ids_len, + char** measurement_names, + int measurement_names_len, int offset, + int limit, ERRNO* err_code); +``` + ### 按标签过滤 @@ -409,6 +528,8 @@ typedef enum { TAG_FILTER_GTEQ = 5, // 列 >= 值 TAG_FILTER_REGEXP = 6, // 列匹配正则 值 TAG_FILTER_NOT_REGEXP = 7, // 列不匹配正则 值 + TAG_FILTER_IS_NULL = 8, // 列为空 + TAG_FILTER_IS_NOT_NULL = 9, // 列不为空 } TagFilterOp; /** @@ -417,7 +538,7 @@ typedef enum { * @param reader [输入] 有效的 TsFileReader 句柄。 * @param table_name [输入] 其 schema 定义了这些标签列的表名。 * @param column_name [输入] 要过滤的标签列名。 - * @param value [输入] 比较值(标签列为 STRING 类型)。 + * @param value [输入] 比较值(IS NULL / IS NOT NULL 会忽略该参数)。 * @param op [输入] 比较运算符(TagFilterOp)。 * @param err_code [输出] 成功返回 RET_OK(0),否则返回 errno_define_c.h 中的错误码。 * @return 成功返回 TagFilterHandle,失败返回 NULL。 @@ -437,6 +558,20 @@ TagFilterHandle tsfile_tag_filter_between(TsFileReader reader, const char* lower, const char* upper, bool is_not, ERRNO* err_code); +// 常用单列谓词的便捷构造函数。 +TagFilterHandle tsfile_tag_filter_eq(TsFileReader reader, const char* table_name, + const char* column_name, const char* value); +TagFilterHandle tsfile_tag_filter_neq(TsFileReader reader, const char* table_name, + const char* column_name, const char* value); +TagFilterHandle tsfile_tag_filter_lt(TsFileReader reader, const char* table_name, + const char* column_name, const char* value); +TagFilterHandle tsfile_tag_filter_lteq(TsFileReader reader, const char* table_name, + const char* column_name, const char* value); +TagFilterHandle tsfile_tag_filter_gt(TsFileReader reader, const char* table_name, + const char* column_name, const char* value); +TagFilterHandle tsfile_tag_filter_gteq(TsFileReader reader, const char* table_name, + const char* column_name, const char* value); + // 组合谓词。AND/OR/NOT 会接管其子节点的所有权,只需释放根节点。 TagFilterHandle tsfile_tag_filter_and(TagFilterHandle left, TagFilterHandle right); TagFilterHandle tsfile_tag_filter_or(TagFilterHandle left, TagFilterHandle right); @@ -493,6 +628,18 @@ ResultSet tsfile_query_table_with_tag_filter( TagFilterHandle tag_filter, int batch_size, ERRNO* err_code); ``` +### 将批结果读取为 Arrow + +对 `batch_size > 0` 创建的批查询结果集,可以使用 Arrow C Data Interface 读取 +`ArrowArray` 和 `ArrowSchema`。调用者拥有返回的 Arrow 对象,使用完后必须调用 +它们的 `release` 回调。 + +```C +ERRNO tsfile_result_set_get_next_tsblock_as_arrow(ResultSet result_set, + ArrowArray* out_array, + ArrowSchema* out_schema); +``` + 示例——只读取 `region` 标签等于 `shanghai` 的设备的 `temperature`: ```C @@ -640,6 +787,17 @@ TableSchema tsfile_reader_get_table_schema(TsFileReader reader, TableSchema* tsfile_reader_get_all_table_schemas(TsFileReader reader, uint32_t* size); +/** + * @brief 获取 TsFile 中所有 timeseries schema。 + * + * @param size [输出] 返回的 DeviceSchema 数组中的元素数量。 + * @return DeviceSchema* 设备 schema 数组指针。 + * @note 调用者必须对数组中的每个元素调用 free_device_schema(), + * 并对整个数组指针调用 free() 进行释放。 + */ +DeviceSchema* tsfile_reader_get_all_timeseries_schemas(TsFileReader reader, + uint32_t* size); + /** * @brief 释放 TableSchema 占用的内存空间。 * @@ -647,5 +805,40 @@ TableSchema* tsfile_reader_get_all_table_schemas(TsFileReader reader, */ void free_table_schema(TableSchema schema); + +void free_device_schema(DeviceSchema schema); ``` +### 获取设备与 Timeseries Metadata + +```C +/** + * @brief 列出文件中的所有设备。 + * + * @param out_devices [输出] 分配出的设备数组;用 tsfile_free_device_id_array() 释放。 + * @param out_length [输出] 返回数组中的设备数量。 + */ +ERRNO tsfile_reader_get_all_devices(TsFileReader reader, DeviceID** out_devices, + uint32_t* out_length); + +void tsfile_free_device_id_array(DeviceID* devices, uint32_t length); +void tsfile_device_id_free_contents(DeviceID* d); + +/** + * @brief 获取文件中所有设备的 timeseries metadata。 + */ +ERRNO tsfile_reader_get_timeseries_metadata_all( + TsFileReader reader, DeviceTimeseriesMetadataMap* out_map); + +/** + * @brief 获取指定设备的 timeseries metadata。 + * + * length == 0 返回空 map。非空输入中每个 DeviceID.path 应包含规范设备路径。 + */ +ERRNO tsfile_reader_get_timeseries_metadata_for_devices( + TsFileReader reader, const DeviceID* devices, uint32_t length, + DeviceTimeseriesMetadataMap* out_map); + +void tsfile_free_device_timeseries_metadata_map( + DeviceTimeseriesMetadataMap* map); +``` diff --git a/src/zh/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md b/src/zh/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md index 50de78b47..f337c46ec 100644 --- a/src/zh/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md +++ b/src/zh/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md @@ -31,10 +31,14 @@ enum TSDataType : uint8_t { FLOAT = 3, DOUBLE = 4, TEXT = 5, + VECTOR = 6, + UNKNOWN = 7, TIMESTAMP = 8, DATE = 9, BLOB = 10, STRING = 11, + NULL_TYPE = 254, + INVALID_DATATYPE = 255, }; // 值编码。各编码适用于哪些类型见下表。 @@ -42,19 +46,35 @@ enum TSEncoding : uint8_t { PLAIN = 0, DICTIONARY = 1, RLE = 2, + DIFF = 3, TS_2DIFF = 4, + BITMAP = 5, + GORILLA_V1 = 6, + REGULAR = 7, GORILLA = 8, ZIGZAG = 9, + FREQ = 10, + CHIMP = 11, SPRINTZ = 12, + RLBE = 13, + CAMEL = 14, + INVALID_ENCODING = 255, }; -// 压缩类型。SNAPPY/GZIP/LZO/LZ4 取决于构建选项;默认压缩为 LZ4。 +// 压缩类型。SNAPPY/GZIP/LZO/LZ4/ZSTD/LZMA2 取决于构建选项; +// 默认压缩为 LZ4。 enum CompressionType : uint8_t { UNCOMPRESSED = 0, SNAPPY = 1, GZIP = 2, LZO = 3, + SDT = 4, + PAA = 5, + PLA = 6, LZ4 = 7, + ZSTD = 8, + LZMA2 = 9, + INVALID_COMPRESSION = 255, }; // 列在表 schema 内的角色。 @@ -72,6 +92,8 @@ enum class ColumnCategory { TAG = 0, FIELD = 1, ATTRIBUTE = 2, TIME = 3 }; | `GORILLA` | `INT32`、`INT64`、`TIMESTAMP`、`DATE`、`FLOAT`、`DOUBLE` | | `ZIGZAG` | `INT32`、`INT64` | | `SPRINTZ` | `INT32`、`INT64`、`FLOAT`、`DOUBLE` | +| `CHIMP`、`RLBE` | `INT32`、`INT64`、`TIMESTAMP`、`DATE`、`FLOAT`、`DOUBLE` | +| `CAMEL` | `DOUBLE` | 各类型的默认值编码:`BOOLEAN → PLAIN`、`INT32 / INT64 → TS_2DIFF`、 `FLOAT / DOUBLE → GORILLA`、`TEXT / STRING / BLOB → PLAIN`。默认压缩为 `LZ4`。 @@ -135,6 +157,64 @@ class TsFileTableWriter { }; ``` +### TsFileWriter + +`TsFileWriter` 是 `tsfile_writer.h` 中的低层写入接口,支持 tree 模型和 table +模型写入。 + +```cpp +extern int libtsfile_init(); +extern void libtsfile_destroy(); + +// 写入器配置。非法值返回 common::E_INVALID_ARG,并保持原配置不变。 +extern int set_page_max_point_count(uint32_t page_max_point_count); +extern int set_max_degree_of_index_node(uint32_t max_degree_of_index_node); + +class TsFileWriter { + public: + TsFileWriter(); + ~TsFileWriter(); + void destroy(); + + int open(const std::string& file_path, int flags, mode_t mode); + int open(const std::string& file_path); + int init(storage::WriteFile* write_file); + int init(storage::RestorableTsFileIOWriter* rw); + + void set_generate_table_schema(bool generate_table_schema); + + int register_timeseries(const std::string& device_id, + const MeasurementSchema& measurement_schema); + int register_timeseries( + const std::string& device_path, + const std::vector& measurement_schema_vec); + int register_aligned_timeseries( + const std::string& device_id, + const MeasurementSchema& measurement_schema); + int register_aligned_timeseries( + const std::string& device_id, + const std::vector& measurement_schemas); + int register_table(const std::shared_ptr& table_schema); + + int write_record(const TsRecord& record); + int write_tablet(const Tablet& tablet); + int write_record_aligned(const TsRecord& record); + int write_tablet_aligned(const Tablet& tablet); + int write_tree(const Tablet& tablet); + int write_tree(const TsRecord& record); + int write_table(Tablet& tablet); + + DeviceSchemasMap* get_schema_group_map(); + std::shared_ptr get_table_schema( + const std::string& table_name) const; + int64_t calculate_mem_size_for_all_group(); + int64_t calculate_meta_mem_size() const; + int check_memory_size_and_may_flush_chunks(); + int flush(); + int close(); +}; +``` + ### TableSchema 描述表模式(schema)的数据结构。 @@ -297,8 +377,14 @@ uint8_t common::get_global_compression(); // 时间列的编码/压缩(数据类型固定为 INT64)。 int common::set_global_time_encoding(uint8_t encoding); int common::set_global_time_compression(uint8_t compression); +uint8_t common::get_global_time_encoding(); +uint8_t common::get_global_time_compression(); ``` +全局压缩支持 `UNCOMPRESSED`、`SNAPPY`、`GZIP`、`LZO`、`LZ4`、`ZSTD` +和 `LZMA2`。压缩枚举中也包含 `SDT`、`PAA`、`PLA` 等历史值,但全局压缩 +setter 会拒绝这些值。 + ## 读取接口 ### Tsfile Reader ```cpp @@ -335,6 +421,16 @@ class TsFileReader { * @return 成功时返回 0,失败时返回 errno_define.h 中的非零错误码。 */ int query(storage::QueryExpression *qe, ResultSet *&ret_qds); + /** + * @brief 通过路径列表、起始时间和结束时间查询 tsfile。用于 tree 模型。 + * + * @param [in] path_list 完整路径列表。 + * @param [in] start_time 起始时间。 + * @param [in] end_time 结束时间。 + * @param [out] result_set 查询结果集。 + */ + int query(std::vector& path_list, int64_t start_time, + int64_t end_time, ResultSet*& result_set); /** * @brief 通过表名、列名、起始时间和结束时间查询 tsfile。 * @@ -346,7 +442,7 @@ class TsFileReader { */ int query(const std::string &table_name, const std::vector &columns_names, int64_t start_time, - int64_t end_time, ResultSet *&result_set); + int64_t end_time, ResultSet *&result_set, int batch_size = -1); /** * @brief 通过表名、列名、开始时间、结束时间和标签过滤器查询 tsfile。 @@ -360,7 +456,14 @@ class TsFileReader { */ int query(const std::string& table_name, const std::vector& columns_names, int64_t start_time, - int64_t end_time, ResultSet*& result_set, Filter* tag_filter); + int64_t end_time, ResultSet*& result_set, Filter* tag_filter, + int batch_size = 0); + + /** + * @brief 按行查询 tree 模型序列,支持 offset/limit。 + */ + int queryByRow(std::vector& path_list, int offset, int limit, + ResultSet*& result_set); /** * @brief 按行查询表,支持偏移量/行数限制下推与可选的标签过滤。 @@ -379,12 +482,39 @@ class TsFileReader { int limit, ResultSet*& result_set, Filter* tag_filter = nullptr, int batch_size = 0); + /** + * @brief 按测点名在时间范围内查询 tree 模型数据。 + */ + int query_table_on_tree(const std::vector& measurement_names, + int64_t start_time, int64_t end_time, + ResultSet*& result_set); + /** * @brief 销毁结果集,该方法应在查询完成并使用完 result_set 后调用。 * * @param qds 查询结果集。 */ void destroy_query_data_set(ResultSet *qds); + + ResultSet* read_timeseries( + const std::shared_ptr& device_id, + const std::vector& measurement_name); + + std::vector> get_all_devices( + std::string table_name); + + std::vector> get_all_device_ids(); + + std::vector> get_all_devices(); + + int get_timeseries_schema(std::shared_ptr device_id, + std::vector& result); + + DeviceTimeseriesMetadataMap get_timeseries_metadata( + const std::vector>& device_ids); + + DeviceTimeseriesMetadataMap get_timeseries_metadata(); + /** * @brief 根据表名获取表的模式信息。 * @@ -401,6 +531,11 @@ class TsFileReader { std::vector> get_all_table_schemas(); }; ``` + +`DeviceTimeseriesMetadataMap` 是 `get_timeseries_metadata()` 返回的元数据 +map:`std::map, +std::vector>, IDeviceIDComparator>`。 + ### ResultSet ```cpp /** @@ -540,6 +675,8 @@ class TagFilterBuilder { Filter* reg_exp(const std::string& columnName, const std::string& value); Filter* not_reg_exp(const std::string& columnName, const std::string& value); + Filter* is_null(const std::string& columnName); + Filter* is_not_null(const std::string& columnName); Filter* between_and(const std::string& columnName, const std::string& lower, const std::string& upper); Filter* not_between_and(const std::string& columnName, @@ -550,4 +687,4 @@ class TagFilterBuilder { static Filter* or_filter(Filter* left, Filter* right); static Filter* not_filter(Filter* filter); }; -``` \ No newline at end of file +``` diff --git a/src/zh/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md b/src/zh/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md index c94b690c7..1d3e875b1 100644 --- a/src/zh/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md +++ b/src/zh/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md @@ -45,10 +45,17 @@ class TSEncoding(IntEnum): PLAIN = 0 # 所有类型 DICTIONARY = 1 # STRING、TEXT RLE = 2 # INT32、INT64、TIMESTAMP、DATE + DIFF = 3 TS_2DIFF = 4 # INT32、INT64、TIMESTAMP、DATE、FLOAT、DOUBLE + BITMAP = 5 + GORILLA_V1 = 6 + REGULAR = 7 GORILLA = 8 # INT32、INT64、TIMESTAMP、DATE、FLOAT、DOUBLE ZIGZAG = 9 # INT32、INT64 + CHIMP = 11 # INT32、INT64、TIMESTAMP、DATE、FLOAT、DOUBLE SPRINTZ = 12 # INT32、INT64、FLOAT、DOUBLE + RLBE = 13 # INT32、INT64、TIMESTAMP、DATE、FLOAT、DOUBLE + CAMEL = 14 # DOUBLE class Compressor(IntEnum): """ @@ -58,7 +65,12 @@ class Compressor(IntEnum): SNAPPY = 1 GZIP = 2 LZO = 3 + SDT = 4 + PAA = 5 + PLA = 6 LZ4 = 7 + ZSTD = 8 + LZMA2 = 9 class ColumnCategory(IntEnum): """ @@ -99,6 +111,32 @@ class ResultSetMetaData: def __init__(self, column_list: List[str], data_types: List[TSDataType]) +@dataclass(frozen=True) +class DeviceID: + path: Optional[str] + table_name: Optional[str] + segments: tuple[Optional[str], ...] + +@dataclass(frozen=True) +class TimeseriesStatistic: + has_statistic: bool + row_count: int + start_time: int + end_time: int + +@dataclass(frozen=True) +class TimeseriesMetadata: + measurement_name: str + data_type: TSDataType + chunk_meta_count: int + statistic: TimeseriesStatistic + timeline_statistic: TimeseriesStatistic + +@dataclass(frozen=True) +class DeviceTimeseriesMetadataGroup: + table_name: Optional[str] + segments: tuple[Optional[str], ...] + timeseries: list[TimeseriesMetadata] ``` @@ -106,7 +144,7 @@ class ResultSetMetaData: ## 写入接口 -### TsFileWriter +### TsFileTableWriter ```python class TsFileTableWriter: @@ -157,6 +195,48 @@ class TsFileTableWriter: ``` +### TsFileWriter + +`TsFileWriter` 是 `writer.pyx` 暴露的低层写入接口。它可以写入 tree 模型数据 +(`register_timeseries`、`register_device`、`write_tablet`、`write_row_record`), +也可以写入 table 模型数据(`register_table`、`write_table`、`write_dataframe`、 +`write_arrow_batch`)。 + +```python +class TsFileWriter: + """ + :param pathname: 目标 TsFile 路径。 + :param memory_threshold: 触发自动刷盘前缓冲的字节数(默认 128MB)。 + """ + def __init__(self, pathname: str, memory_threshold: int = 128 * 1024 * 1024) + + def register_timeseries(self, device_name: str, + timeseries_schema: TimeseriesSchema) + + def register_device(self, device_schema: DeviceSchema) + + def register_table(self, table_schema: TableSchema) + + def write_tablet(self, tablet: Tablet) + + def write_dataframe(self, target_table: str, dataframe: pandas.DataFrame, + tableschema: TableSchema) + + def write_row_record(self, record: RowRecord) + + def write_table(self, tablet: Tablet) + + def write_arrow_batch(self, table_name: str, data, + time_col_index: int = -1) + + def flush(self) + + def close(self) + + def __enter__(self) + def __exit__(self, exc_type, exc_val, exc_tb) +``` + ### Tablet definition @@ -223,11 +303,12 @@ set_tsfile_config({ | 数据类型 | 允许的编码 | 默认值 | |---|---|---| | `BOOLEAN` | `PLAIN` | `PLAIN` | -| `INT32`、`INT64`、`DATE` | `PLAIN`、`TS_2DIFF`、`GORILLA`、`ZIGZAG`、`RLE`、`SPRINTZ` | `TS_2DIFF` | -| `FLOAT`、`DOUBLE` | `PLAIN`、`TS_2DIFF`、`GORILLA`、`SPRINTZ` | `GORILLA` | +| `INT32`、`INT64`、`TIMESTAMP`、`DATE` | `PLAIN`、`TS_2DIFF`、`GORILLA`、`ZIGZAG`、`RLE`、`SPRINTZ`、`CHIMP`、`RLBE` | `TS_2DIFF` | +| `FLOAT` | `PLAIN`、`TS_2DIFF`、`GORILLA`、`SPRINTZ`、`CHIMP`、`RLBE` | `GORILLA` | +| `DOUBLE` | `PLAIN`、`TS_2DIFF`、`GORILLA`、`SPRINTZ`、`CHIMP`、`RLBE`、`CAMEL` | `GORILLA` | | `STRING`、`TEXT` | `PLAIN`、`DICTIONARY` | `PLAIN` | -压缩适用于所有数据类型:`UNCOMPRESSED`、`SNAPPY`、`GZIP`、`LZO`、`LZ4`(默认 `LZ4`)。 +压缩适用于所有数据类型:`UNCOMPRESSED`、`SNAPPY`、`GZIP`、`LZO`、`LZ4`、`ZSTD`、`LZMA2`(默认 `LZ4`)。枚举还暴露 `SDT`、`PAA`、`PLA` 等历史值,但全局配置 setter 会拒绝这些值。 ## 读取接口 @@ -253,11 +334,39 @@ class TsFileReader: :param column_names: 要检索的列名列表。 :param start_time: 查询范围的起始时间(默认:int64 最小值)。 :param end_time: 查询范围的结束时间(默认:int64 最大值)。 + :param tag_filter: 可选的 table 模型 TAG 列谓词。 + :param batch_size: <= 0 逐行返回;> 0 按该大小返回数据块。 :return: 查询结果集处理器。 """ def query_table(self, table_name : str, column_names : List[str], start_time : int = np.iinfo(np.int64).min, - end_time: int = np.iinfo(np.int64).max) -> ResultSet + end_time: int = np.iinfo(np.int64).max, + tag_filter = None, batch_size : int = 0) -> ResultSet + + """ + 对 tree 模型测点列执行时间范围查询。 + + :param column_names: 要检索的测点名列表。 + :param start_time: 查询范围的起始时间。 + :param end_time: 查询范围的结束时间。 + :return: 查询结果集处理器。 + """ + def query_table_on_tree(self, column_names : List[str], + start_time : int = np.iinfo(np.int64).min, + end_time : int = np.iinfo(np.int64).max) -> ResultSet + + """ + 按行查询 tree 模型数据,支持 offset/limit。 + + :param device_ids: 要查询的设备标识列表。 + :param measurement_names: 要检索的测点名列表。 + :param offset: 需要跳过的起始行数。 + :param limit: 最多返回行数;< 0 表示不限制。 + :return: 查询结果集处理器。 + """ + def query_tree_by_row(self, device_ids : List[str], + measurement_names : List[str], + offset : int = 0, limit : int = -1) -> ResultSet """ 按行查询表,支持偏移量/行数限制下推与可选的标签过滤。标签谓词把查询限定到 @@ -277,6 +386,18 @@ class TsFileReader: offset : int = 0, limit : int = -1, tag_filter = None, batch_size : int = 0) -> ResultSet + """ + 对单个设备执行 tree 模型时间范围查询。 + + :param device_name: 设备标识。 + :param sensor_list: 要检索的测点名列表。 + :param start_time: 查询起始时间。 + :param end_time: 查询结束时间。 + :return: 查询结果集处理器。 + """ + def query_timeseries(self, device_name : str, sensor_list : List[str], + start_time : int = 0, end_time : int = 0) -> ResultSet + """ 获取指定表的模式信息。 @@ -292,6 +413,31 @@ class TsFileReader: """ def get_all_table_schemas(self) -> dict[str, TableSchema] + """ + 获取所有 tree 模型 timeseries schema,按设备分组。 + + :return: DeviceSchema 对象列表。 + """ + def get_all_timeseries_schemas(self) -> list[DeviceSchema] + + """ + 获取文件中的所有设备标识。 + + :return: DeviceID(path, table_name, segments) 列表。 + """ + def get_all_devices(self) -> List[DeviceID] + + """ + 获取所有设备或指定设备的 per-timeseries metadata。 + + :param device_ids: None 表示全部设备,[] 表示空结果,或传入 DeviceID / + 路径兼容的设备标识列表。 + :return: dict,key 为设备 segment tuple,value 为 DeviceTimeseriesMetadataGroup。 + """ + def get_timeseries_metadata( + self, device_ids: Optional[List] = None + ) -> Dict[tuple, DeviceTimeseriesMetadataGroup] + """ 关闭 TsFile 读取器。如果读取器中有活动的结果集,它们将失效。 """ @@ -332,6 +478,12 @@ class ResultSet: """ def read_data_frame(self, max_row_num : int = 1024) -> DataFrame + """ + 将下一个批结果读取为 pyarrow.Table。没有更多 TsBlock 批时返回 None。 + 仅适用于通过 batch_size > 0 创建的结果集。 + """ + def read_arrow_batch(self) -> Optional[pyarrow.Table] + """ 从查询结果集中按索引获取值。 @@ -376,6 +528,9 @@ class ResultSet: """ def close(self) + def __enter__(self) + def __exit__(self, exc_type, exc_val, exc_tb) + ``` From fb9f4ae306e31571f13318e8012fee0910d8ce59 Mon Sep 17 00:00:00 2001 From: ColinLee Date: Thu, 9 Jul 2026 18:20:31 +0800 Subject: [PATCH 3/4] Align interface docs with origin develop --- .../InterfaceDefinition/InterfaceDefinition-C.md | 16 ++++++---------- .../InterfaceDefinition-CPP.md | 16 ++++------------ .../InterfaceDefinition-Python.md | 15 ++++++++------- .../InterfaceDefinition/InterfaceDefinition-C.md | 16 ++++++---------- .../InterfaceDefinition-CPP.md | 16 ++++------------ .../InterfaceDefinition-Python.md | 15 ++++++++------- .../InterfaceDefinition/InterfaceDefinition-C.md | 14 +++++--------- .../InterfaceDefinition-CPP.md | 15 +++------------ .../InterfaceDefinition-Python.md | 10 +++++----- .../InterfaceDefinition/InterfaceDefinition-C.md | 14 +++++--------- .../InterfaceDefinition-CPP.md | 15 +++------------ .../InterfaceDefinition-Python.md | 10 +++++----- 12 files changed, 62 insertions(+), 110 deletions(-) diff --git a/src/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md b/src/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md index 262cb5148..7ee9e74ed 100644 --- a/src/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md +++ b/src/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md @@ -54,10 +54,7 @@ typedef enum { TS_ENCODING_GORILLA = 8, TS_ENCODING_ZIGZAG = 9, TS_ENCODING_FREQ = 10, - TS_ENCODING_CHIMP = 11, TS_ENCODING_SPRINTZ = 12, - TS_ENCODING_RLBE = 13, - TS_ENCODING_CAMEL = 14, TS_ENCODING_INVALID = 255 } TSEncoding; @@ -71,8 +68,6 @@ typedef enum { TS_COMPRESSION_PAA = 5, TS_COMPRESSION_PLA = 6, TS_COMPRESSION_LZ4 = 7, - TS_COMPRESSION_ZSTD = 8, - TS_COMPRESSION_LZMA2 = 9, TS_COMPRESSION_INVALID = 255 } CompressionType; @@ -423,13 +418,15 @@ Allowed encodings per data type, and the default used when you do not change it: | Data type | Allowed encodings | Default | |---|---|---| | `BOOLEAN` | `PLAIN` | `PLAIN` | -| `INT32`, `INT64`, `TIMESTAMP`, `DATE` | `PLAIN`, `TS_2DIFF`, `GORILLA`, `ZIGZAG`, `RLE`, `SPRINTZ`, `CHIMP`, `RLBE` | `TS_2DIFF` | -| `FLOAT` | `PLAIN`, `TS_2DIFF`, `GORILLA`, `SPRINTZ`, `CHIMP`, `RLBE` | `GORILLA` | -| `DOUBLE` | `PLAIN`, `TS_2DIFF`, `GORILLA`, `SPRINTZ`, `CHIMP`, `RLBE`, `CAMEL` | `GORILLA` | +| `INT32`, `INT64`, `DATE` | `PLAIN`, `TS_2DIFF`, `GORILLA`, `ZIGZAG`, `RLE`, `SPRINTZ` | `TS_2DIFF` | +| `FLOAT`, `DOUBLE` | `PLAIN`, `TS_2DIFF`, `GORILLA`, `SPRINTZ` | `GORILLA` | | `STRING`, `TEXT` | `PLAIN`, `DICTIONARY` | `PLAIN` | +The time column uses the global time configuration and accepts `PLAIN`, +`TS_2DIFF`, `GORILLA`, `ZIGZAG`, `RLE`, or `SPRINTZ`. + Compression applies to any data type: `UNCOMPRESSED`, `SNAPPY`, `GZIP`, `LZO`, -`LZ4`, `ZSTD`, or `LZMA2` (default `LZ4`). +or `LZ4` (default `LZ4`). ```C // e.g. write every column with LZ4 compression @@ -868,4 +865,3 @@ void tsfile_free_device_timeseries_metadata_map( ``` - diff --git a/src/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md b/src/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md index d37e00777..b95ccbcaf 100644 --- a/src/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md +++ b/src/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md @@ -54,15 +54,11 @@ enum TSEncoding : uint8_t { GORILLA = 8, ZIGZAG = 9, FREQ = 10, - CHIMP = 11, SPRINTZ = 12, - RLBE = 13, - CAMEL = 14, INVALID_ENCODING = 255, }; -// Compression type. SNAPPY/GZIP/LZO/LZ4/ZSTD/LZMA2 depend on build options; -// LZ4 is the default. +// Compression type. SNAPPY/GZIP/LZO/LZ4 depend on build options; LZ4 is the default. enum CompressionType : uint8_t { UNCOMPRESSED = 0, SNAPPY = 1, @@ -72,8 +68,6 @@ enum CompressionType : uint8_t { PAA = 5, PLA = 6, LZ4 = 7, - ZSTD = 8, - LZMA2 = 9, INVALID_COMPRESSION = 255, }; @@ -92,8 +86,6 @@ Encodings applicable to each data type: | `GORILLA` | `INT32`, `INT64`, `TIMESTAMP`, `DATE`, `FLOAT`, `DOUBLE` | | `ZIGZAG` | `INT32`, `INT64` | | `SPRINTZ` | `INT32`, `INT64`, `FLOAT`, `DOUBLE` | -| `CHIMP`, `RLBE` | `INT32`, `INT64`, `TIMESTAMP`, `DATE`, `FLOAT`, `DOUBLE` | -| `CAMEL` | `DOUBLE` | Default value encoding per type: `BOOLEAN → PLAIN`, `INT32 / INT64 → TS_2DIFF`, `FLOAT / DOUBLE → GORILLA`, `TEXT / STRING / BLOB → PLAIN`. The default @@ -385,9 +377,9 @@ uint8_t common::get_global_time_encoding(); uint8_t common::get_global_time_compression(); ``` -Global compression accepts `UNCOMPRESSED`, `SNAPPY`, `GZIP`, `LZO`, `LZ4`, -`ZSTD`, and `LZMA2`. The codec enum also contains legacy values such as `SDT`, -`PAA`, and `PLA`, but the global compression setter rejects them. +Global compression accepts `UNCOMPRESSED`, `SNAPPY`, `GZIP`, `LZO`, and `LZ4`. +The codec enum also contains legacy values such as `SDT`, `PAA`, and `PLA`, but +the global compression setter rejects them. ## Read Interface ### Tsfile Reader diff --git a/src/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md b/src/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md index 806fa9115..d0c039107 100644 --- a/src/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md +++ b/src/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md @@ -57,7 +57,6 @@ class TSEncoding(IntEnum): CHIMP = 11 # INT32, INT64, TIMESTAMP, DATE, FLOAT, DOUBLE SPRINTZ = 12 # INT32, INT64, FLOAT, DOUBLE RLBE = 13 # INT32, INT64, TIMESTAMP, DATE, FLOAT, DOUBLE - CAMEL = 14 # DOUBLE class Compressor(IntEnum): """ @@ -311,15 +310,17 @@ encodings per data type, and the default used when you do not change it: | Data type | Allowed encodings | Default | |---|---|---| | `BOOLEAN` | `PLAIN` | `PLAIN` | -| `INT32`, `INT64`, `TIMESTAMP`, `DATE` | `PLAIN`, `TS_2DIFF`, `GORILLA`, `ZIGZAG`, `RLE`, `SPRINTZ`, `CHIMP`, `RLBE` | `TS_2DIFF` | -| `FLOAT` | `PLAIN`, `TS_2DIFF`, `GORILLA`, `SPRINTZ`, `CHIMP`, `RLBE` | `GORILLA` | -| `DOUBLE` | `PLAIN`, `TS_2DIFF`, `GORILLA`, `SPRINTZ`, `CHIMP`, `RLBE`, `CAMEL` | `GORILLA` | +| `INT32`, `INT64`, `DATE` | `PLAIN`, `TS_2DIFF`, `GORILLA`, `ZIGZAG`, `RLE`, `SPRINTZ` | `TS_2DIFF` | +| `FLOAT`, `DOUBLE` | `PLAIN`, `TS_2DIFF`, `GORILLA`, `SPRINTZ` | `GORILLA` | | `STRING`, `TEXT` | `PLAIN`, `DICTIONARY` | `PLAIN` | +The time column uses the global time configuration and accepts `PLAIN`, +`TS_2DIFF`, `GORILLA`, `ZIGZAG`, `RLE`, or `SPRINTZ`. + Compression applies to any data type: `UNCOMPRESSED`, `SNAPPY`, `GZIP`, `LZO`, -`LZ4`, `ZSTD`, or `LZMA2` (default `LZ4`). The enum also exposes legacy values -such as `SDT`, `PAA`, and `PLA`, but the global configuration setter rejects -them. +or `LZ4` (default `LZ4`). The Python enum also exposes values such as `CHIMP`, +`RLBE`, `ZSTD`, and `LZMA2`, but the current writer/config conversion on +`origin/develop` rejects them. ## Read Interface diff --git a/src/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md b/src/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md index 262cb5148..7ee9e74ed 100644 --- a/src/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md +++ b/src/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md @@ -54,10 +54,7 @@ typedef enum { TS_ENCODING_GORILLA = 8, TS_ENCODING_ZIGZAG = 9, TS_ENCODING_FREQ = 10, - TS_ENCODING_CHIMP = 11, TS_ENCODING_SPRINTZ = 12, - TS_ENCODING_RLBE = 13, - TS_ENCODING_CAMEL = 14, TS_ENCODING_INVALID = 255 } TSEncoding; @@ -71,8 +68,6 @@ typedef enum { TS_COMPRESSION_PAA = 5, TS_COMPRESSION_PLA = 6, TS_COMPRESSION_LZ4 = 7, - TS_COMPRESSION_ZSTD = 8, - TS_COMPRESSION_LZMA2 = 9, TS_COMPRESSION_INVALID = 255 } CompressionType; @@ -423,13 +418,15 @@ Allowed encodings per data type, and the default used when you do not change it: | Data type | Allowed encodings | Default | |---|---|---| | `BOOLEAN` | `PLAIN` | `PLAIN` | -| `INT32`, `INT64`, `TIMESTAMP`, `DATE` | `PLAIN`, `TS_2DIFF`, `GORILLA`, `ZIGZAG`, `RLE`, `SPRINTZ`, `CHIMP`, `RLBE` | `TS_2DIFF` | -| `FLOAT` | `PLAIN`, `TS_2DIFF`, `GORILLA`, `SPRINTZ`, `CHIMP`, `RLBE` | `GORILLA` | -| `DOUBLE` | `PLAIN`, `TS_2DIFF`, `GORILLA`, `SPRINTZ`, `CHIMP`, `RLBE`, `CAMEL` | `GORILLA` | +| `INT32`, `INT64`, `DATE` | `PLAIN`, `TS_2DIFF`, `GORILLA`, `ZIGZAG`, `RLE`, `SPRINTZ` | `TS_2DIFF` | +| `FLOAT`, `DOUBLE` | `PLAIN`, `TS_2DIFF`, `GORILLA`, `SPRINTZ` | `GORILLA` | | `STRING`, `TEXT` | `PLAIN`, `DICTIONARY` | `PLAIN` | +The time column uses the global time configuration and accepts `PLAIN`, +`TS_2DIFF`, `GORILLA`, `ZIGZAG`, `RLE`, or `SPRINTZ`. + Compression applies to any data type: `UNCOMPRESSED`, `SNAPPY`, `GZIP`, `LZO`, -`LZ4`, `ZSTD`, or `LZMA2` (default `LZ4`). +or `LZ4` (default `LZ4`). ```C // e.g. write every column with LZ4 compression @@ -868,4 +865,3 @@ void tsfile_free_device_timeseries_metadata_map( ``` - diff --git a/src/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md b/src/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md index d37e00777..b95ccbcaf 100644 --- a/src/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md +++ b/src/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md @@ -54,15 +54,11 @@ enum TSEncoding : uint8_t { GORILLA = 8, ZIGZAG = 9, FREQ = 10, - CHIMP = 11, SPRINTZ = 12, - RLBE = 13, - CAMEL = 14, INVALID_ENCODING = 255, }; -// Compression type. SNAPPY/GZIP/LZO/LZ4/ZSTD/LZMA2 depend on build options; -// LZ4 is the default. +// Compression type. SNAPPY/GZIP/LZO/LZ4 depend on build options; LZ4 is the default. enum CompressionType : uint8_t { UNCOMPRESSED = 0, SNAPPY = 1, @@ -72,8 +68,6 @@ enum CompressionType : uint8_t { PAA = 5, PLA = 6, LZ4 = 7, - ZSTD = 8, - LZMA2 = 9, INVALID_COMPRESSION = 255, }; @@ -92,8 +86,6 @@ Encodings applicable to each data type: | `GORILLA` | `INT32`, `INT64`, `TIMESTAMP`, `DATE`, `FLOAT`, `DOUBLE` | | `ZIGZAG` | `INT32`, `INT64` | | `SPRINTZ` | `INT32`, `INT64`, `FLOAT`, `DOUBLE` | -| `CHIMP`, `RLBE` | `INT32`, `INT64`, `TIMESTAMP`, `DATE`, `FLOAT`, `DOUBLE` | -| `CAMEL` | `DOUBLE` | Default value encoding per type: `BOOLEAN → PLAIN`, `INT32 / INT64 → TS_2DIFF`, `FLOAT / DOUBLE → GORILLA`, `TEXT / STRING / BLOB → PLAIN`. The default @@ -385,9 +377,9 @@ uint8_t common::get_global_time_encoding(); uint8_t common::get_global_time_compression(); ``` -Global compression accepts `UNCOMPRESSED`, `SNAPPY`, `GZIP`, `LZO`, `LZ4`, -`ZSTD`, and `LZMA2`. The codec enum also contains legacy values such as `SDT`, -`PAA`, and `PLA`, but the global compression setter rejects them. +Global compression accepts `UNCOMPRESSED`, `SNAPPY`, `GZIP`, `LZO`, and `LZ4`. +The codec enum also contains legacy values such as `SDT`, `PAA`, and `PLA`, but +the global compression setter rejects them. ## Read Interface ### Tsfile Reader diff --git a/src/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md b/src/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md index 806fa9115..d0c039107 100644 --- a/src/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md +++ b/src/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md @@ -57,7 +57,6 @@ class TSEncoding(IntEnum): CHIMP = 11 # INT32, INT64, TIMESTAMP, DATE, FLOAT, DOUBLE SPRINTZ = 12 # INT32, INT64, FLOAT, DOUBLE RLBE = 13 # INT32, INT64, TIMESTAMP, DATE, FLOAT, DOUBLE - CAMEL = 14 # DOUBLE class Compressor(IntEnum): """ @@ -311,15 +310,17 @@ encodings per data type, and the default used when you do not change it: | Data type | Allowed encodings | Default | |---|---|---| | `BOOLEAN` | `PLAIN` | `PLAIN` | -| `INT32`, `INT64`, `TIMESTAMP`, `DATE` | `PLAIN`, `TS_2DIFF`, `GORILLA`, `ZIGZAG`, `RLE`, `SPRINTZ`, `CHIMP`, `RLBE` | `TS_2DIFF` | -| `FLOAT` | `PLAIN`, `TS_2DIFF`, `GORILLA`, `SPRINTZ`, `CHIMP`, `RLBE` | `GORILLA` | -| `DOUBLE` | `PLAIN`, `TS_2DIFF`, `GORILLA`, `SPRINTZ`, `CHIMP`, `RLBE`, `CAMEL` | `GORILLA` | +| `INT32`, `INT64`, `DATE` | `PLAIN`, `TS_2DIFF`, `GORILLA`, `ZIGZAG`, `RLE`, `SPRINTZ` | `TS_2DIFF` | +| `FLOAT`, `DOUBLE` | `PLAIN`, `TS_2DIFF`, `GORILLA`, `SPRINTZ` | `GORILLA` | | `STRING`, `TEXT` | `PLAIN`, `DICTIONARY` | `PLAIN` | +The time column uses the global time configuration and accepts `PLAIN`, +`TS_2DIFF`, `GORILLA`, `ZIGZAG`, `RLE`, or `SPRINTZ`. + Compression applies to any data type: `UNCOMPRESSED`, `SNAPPY`, `GZIP`, `LZO`, -`LZ4`, `ZSTD`, or `LZMA2` (default `LZ4`). The enum also exposes legacy values -such as `SDT`, `PAA`, and `PLA`, but the global configuration setter rejects -them. +or `LZ4` (default `LZ4`). The Python enum also exposes values such as `CHIMP`, +`RLBE`, `ZSTD`, and `LZMA2`, but the current writer/config conversion on +`origin/develop` rejects them. ## Read Interface diff --git a/src/zh/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md b/src/zh/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md index 1edc34e54..52eae5377 100644 --- a/src/zh/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md +++ b/src/zh/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md @@ -54,10 +54,7 @@ typedef enum { TS_ENCODING_GORILLA = 8, TS_ENCODING_ZIGZAG = 9, TS_ENCODING_FREQ = 10, - TS_ENCODING_CHIMP = 11, TS_ENCODING_SPRINTZ = 12, - TS_ENCODING_RLBE = 13, - TS_ENCODING_CAMEL = 14, TS_ENCODING_INVALID = 255 } TSEncoding; @@ -71,8 +68,6 @@ typedef enum { TS_COMPRESSION_PAA = 5, TS_COMPRESSION_PLA = 6, TS_COMPRESSION_LZ4 = 7, - TS_COMPRESSION_ZSTD = 8, - TS_COMPRESSION_LZMA2 = 9, TS_COMPRESSION_INVALID = 255 } CompressionType; @@ -403,12 +398,13 @@ uint8_t get_global_time_compression(); | 数据类型 | 允许的编码 | 默认值 | |---|---|---| | `BOOLEAN` | `PLAIN` | `PLAIN` | -| `INT32`、`INT64`、`TIMESTAMP`、`DATE` | `PLAIN`、`TS_2DIFF`、`GORILLA`、`ZIGZAG`、`RLE`、`SPRINTZ`、`CHIMP`、`RLBE` | `TS_2DIFF` | -| `FLOAT` | `PLAIN`、`TS_2DIFF`、`GORILLA`、`SPRINTZ`、`CHIMP`、`RLBE` | `GORILLA` | -| `DOUBLE` | `PLAIN`、`TS_2DIFF`、`GORILLA`、`SPRINTZ`、`CHIMP`、`RLBE`、`CAMEL` | `GORILLA` | +| `INT32`、`INT64`、`DATE` | `PLAIN`、`TS_2DIFF`、`GORILLA`、`ZIGZAG`、`RLE`、`SPRINTZ` | `TS_2DIFF` | +| `FLOAT`、`DOUBLE` | `PLAIN`、`TS_2DIFF`、`GORILLA`、`SPRINTZ` | `GORILLA` | | `STRING`、`TEXT` | `PLAIN`、`DICTIONARY` | `PLAIN` | -压缩适用于所有数据类型:`UNCOMPRESSED`、`SNAPPY`、`GZIP`、`LZO`、`LZ4`、`ZSTD`、`LZMA2`(默认 `LZ4`)。 +时间列使用全局时间配置,支持 `PLAIN`、`TS_2DIFF`、`GORILLA`、`ZIGZAG`、`RLE` 或 `SPRINTZ`。 + +压缩适用于所有数据类型:`UNCOMPRESSED`、`SNAPPY`、`GZIP`、`LZO`、`LZ4`(默认 `LZ4`)。 ```C // 例如:所有列均以 LZ4 压缩写入 diff --git a/src/zh/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md b/src/zh/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md index f337c46ec..43d5cfcf9 100644 --- a/src/zh/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md +++ b/src/zh/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md @@ -54,15 +54,11 @@ enum TSEncoding : uint8_t { GORILLA = 8, ZIGZAG = 9, FREQ = 10, - CHIMP = 11, SPRINTZ = 12, - RLBE = 13, - CAMEL = 14, INVALID_ENCODING = 255, }; -// 压缩类型。SNAPPY/GZIP/LZO/LZ4/ZSTD/LZMA2 取决于构建选项; -// 默认压缩为 LZ4。 +// 压缩类型。SNAPPY/GZIP/LZO/LZ4 取决于构建选项;默认压缩为 LZ4。 enum CompressionType : uint8_t { UNCOMPRESSED = 0, SNAPPY = 1, @@ -72,8 +68,6 @@ enum CompressionType : uint8_t { PAA = 5, PLA = 6, LZ4 = 7, - ZSTD = 8, - LZMA2 = 9, INVALID_COMPRESSION = 255, }; @@ -92,8 +86,6 @@ enum class ColumnCategory { TAG = 0, FIELD = 1, ATTRIBUTE = 2, TIME = 3 }; | `GORILLA` | `INT32`、`INT64`、`TIMESTAMP`、`DATE`、`FLOAT`、`DOUBLE` | | `ZIGZAG` | `INT32`、`INT64` | | `SPRINTZ` | `INT32`、`INT64`、`FLOAT`、`DOUBLE` | -| `CHIMP`、`RLBE` | `INT32`、`INT64`、`TIMESTAMP`、`DATE`、`FLOAT`、`DOUBLE` | -| `CAMEL` | `DOUBLE` | 各类型的默认值编码:`BOOLEAN → PLAIN`、`INT32 / INT64 → TS_2DIFF`、 `FLOAT / DOUBLE → GORILLA`、`TEXT / STRING / BLOB → PLAIN`。默认压缩为 `LZ4`。 @@ -381,9 +373,8 @@ uint8_t common::get_global_time_encoding(); uint8_t common::get_global_time_compression(); ``` -全局压缩支持 `UNCOMPRESSED`、`SNAPPY`、`GZIP`、`LZO`、`LZ4`、`ZSTD` -和 `LZMA2`。压缩枚举中也包含 `SDT`、`PAA`、`PLA` 等历史值,但全局压缩 -setter 会拒绝这些值。 +全局压缩支持 `UNCOMPRESSED`、`SNAPPY`、`GZIP`、`LZO` 和 `LZ4`。 +压缩枚举中也包含 `SDT`、`PAA`、`PLA` 等历史值,但全局压缩 setter 会拒绝这些值。 ## 读取接口 ### Tsfile Reader diff --git a/src/zh/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md b/src/zh/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md index 1d3e875b1..a2d6c145b 100644 --- a/src/zh/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md +++ b/src/zh/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md @@ -55,7 +55,6 @@ class TSEncoding(IntEnum): CHIMP = 11 # INT32、INT64、TIMESTAMP、DATE、FLOAT、DOUBLE SPRINTZ = 12 # INT32、INT64、FLOAT、DOUBLE RLBE = 13 # INT32、INT64、TIMESTAMP、DATE、FLOAT、DOUBLE - CAMEL = 14 # DOUBLE class Compressor(IntEnum): """ @@ -303,12 +302,13 @@ set_tsfile_config({ | 数据类型 | 允许的编码 | 默认值 | |---|---|---| | `BOOLEAN` | `PLAIN` | `PLAIN` | -| `INT32`、`INT64`、`TIMESTAMP`、`DATE` | `PLAIN`、`TS_2DIFF`、`GORILLA`、`ZIGZAG`、`RLE`、`SPRINTZ`、`CHIMP`、`RLBE` | `TS_2DIFF` | -| `FLOAT` | `PLAIN`、`TS_2DIFF`、`GORILLA`、`SPRINTZ`、`CHIMP`、`RLBE` | `GORILLA` | -| `DOUBLE` | `PLAIN`、`TS_2DIFF`、`GORILLA`、`SPRINTZ`、`CHIMP`、`RLBE`、`CAMEL` | `GORILLA` | +| `INT32`、`INT64`、`DATE` | `PLAIN`、`TS_2DIFF`、`GORILLA`、`ZIGZAG`、`RLE`、`SPRINTZ` | `TS_2DIFF` | +| `FLOAT`、`DOUBLE` | `PLAIN`、`TS_2DIFF`、`GORILLA`、`SPRINTZ` | `GORILLA` | | `STRING`、`TEXT` | `PLAIN`、`DICTIONARY` | `PLAIN` | -压缩适用于所有数据类型:`UNCOMPRESSED`、`SNAPPY`、`GZIP`、`LZO`、`LZ4`、`ZSTD`、`LZMA2`(默认 `LZ4`)。枚举还暴露 `SDT`、`PAA`、`PLA` 等历史值,但全局配置 setter 会拒绝这些值。 +时间列使用全局时间配置,支持 `PLAIN`、`TS_2DIFF`、`GORILLA`、`ZIGZAG`、`RLE` 或 `SPRINTZ`。 + +压缩适用于所有数据类型:`UNCOMPRESSED`、`SNAPPY`、`GZIP`、`LZO`、`LZ4`(默认 `LZ4`)。Python 枚举还暴露 `CHIMP`、`RLBE`、`ZSTD`、`LZMA2` 等值,但 `origin/develop` 当前的 writer/config 转换会拒绝它们。 ## 读取接口 diff --git a/src/zh/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md b/src/zh/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md index 1edc34e54..52eae5377 100644 --- a/src/zh/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md +++ b/src/zh/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md @@ -54,10 +54,7 @@ typedef enum { TS_ENCODING_GORILLA = 8, TS_ENCODING_ZIGZAG = 9, TS_ENCODING_FREQ = 10, - TS_ENCODING_CHIMP = 11, TS_ENCODING_SPRINTZ = 12, - TS_ENCODING_RLBE = 13, - TS_ENCODING_CAMEL = 14, TS_ENCODING_INVALID = 255 } TSEncoding; @@ -71,8 +68,6 @@ typedef enum { TS_COMPRESSION_PAA = 5, TS_COMPRESSION_PLA = 6, TS_COMPRESSION_LZ4 = 7, - TS_COMPRESSION_ZSTD = 8, - TS_COMPRESSION_LZMA2 = 9, TS_COMPRESSION_INVALID = 255 } CompressionType; @@ -403,12 +398,13 @@ uint8_t get_global_time_compression(); | 数据类型 | 允许的编码 | 默认值 | |---|---|---| | `BOOLEAN` | `PLAIN` | `PLAIN` | -| `INT32`、`INT64`、`TIMESTAMP`、`DATE` | `PLAIN`、`TS_2DIFF`、`GORILLA`、`ZIGZAG`、`RLE`、`SPRINTZ`、`CHIMP`、`RLBE` | `TS_2DIFF` | -| `FLOAT` | `PLAIN`、`TS_2DIFF`、`GORILLA`、`SPRINTZ`、`CHIMP`、`RLBE` | `GORILLA` | -| `DOUBLE` | `PLAIN`、`TS_2DIFF`、`GORILLA`、`SPRINTZ`、`CHIMP`、`RLBE`、`CAMEL` | `GORILLA` | +| `INT32`、`INT64`、`DATE` | `PLAIN`、`TS_2DIFF`、`GORILLA`、`ZIGZAG`、`RLE`、`SPRINTZ` | `TS_2DIFF` | +| `FLOAT`、`DOUBLE` | `PLAIN`、`TS_2DIFF`、`GORILLA`、`SPRINTZ` | `GORILLA` | | `STRING`、`TEXT` | `PLAIN`、`DICTIONARY` | `PLAIN` | -压缩适用于所有数据类型:`UNCOMPRESSED`、`SNAPPY`、`GZIP`、`LZO`、`LZ4`、`ZSTD`、`LZMA2`(默认 `LZ4`)。 +时间列使用全局时间配置,支持 `PLAIN`、`TS_2DIFF`、`GORILLA`、`ZIGZAG`、`RLE` 或 `SPRINTZ`。 + +压缩适用于所有数据类型:`UNCOMPRESSED`、`SNAPPY`、`GZIP`、`LZO`、`LZ4`(默认 `LZ4`)。 ```C // 例如:所有列均以 LZ4 压缩写入 diff --git a/src/zh/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md b/src/zh/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md index f337c46ec..43d5cfcf9 100644 --- a/src/zh/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md +++ b/src/zh/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md @@ -54,15 +54,11 @@ enum TSEncoding : uint8_t { GORILLA = 8, ZIGZAG = 9, FREQ = 10, - CHIMP = 11, SPRINTZ = 12, - RLBE = 13, - CAMEL = 14, INVALID_ENCODING = 255, }; -// 压缩类型。SNAPPY/GZIP/LZO/LZ4/ZSTD/LZMA2 取决于构建选项; -// 默认压缩为 LZ4。 +// 压缩类型。SNAPPY/GZIP/LZO/LZ4 取决于构建选项;默认压缩为 LZ4。 enum CompressionType : uint8_t { UNCOMPRESSED = 0, SNAPPY = 1, @@ -72,8 +68,6 @@ enum CompressionType : uint8_t { PAA = 5, PLA = 6, LZ4 = 7, - ZSTD = 8, - LZMA2 = 9, INVALID_COMPRESSION = 255, }; @@ -92,8 +86,6 @@ enum class ColumnCategory { TAG = 0, FIELD = 1, ATTRIBUTE = 2, TIME = 3 }; | `GORILLA` | `INT32`、`INT64`、`TIMESTAMP`、`DATE`、`FLOAT`、`DOUBLE` | | `ZIGZAG` | `INT32`、`INT64` | | `SPRINTZ` | `INT32`、`INT64`、`FLOAT`、`DOUBLE` | -| `CHIMP`、`RLBE` | `INT32`、`INT64`、`TIMESTAMP`、`DATE`、`FLOAT`、`DOUBLE` | -| `CAMEL` | `DOUBLE` | 各类型的默认值编码:`BOOLEAN → PLAIN`、`INT32 / INT64 → TS_2DIFF`、 `FLOAT / DOUBLE → GORILLA`、`TEXT / STRING / BLOB → PLAIN`。默认压缩为 `LZ4`。 @@ -381,9 +373,8 @@ uint8_t common::get_global_time_encoding(); uint8_t common::get_global_time_compression(); ``` -全局压缩支持 `UNCOMPRESSED`、`SNAPPY`、`GZIP`、`LZO`、`LZ4`、`ZSTD` -和 `LZMA2`。压缩枚举中也包含 `SDT`、`PAA`、`PLA` 等历史值,但全局压缩 -setter 会拒绝这些值。 +全局压缩支持 `UNCOMPRESSED`、`SNAPPY`、`GZIP`、`LZO` 和 `LZ4`。 +压缩枚举中也包含 `SDT`、`PAA`、`PLA` 等历史值,但全局压缩 setter 会拒绝这些值。 ## 读取接口 ### Tsfile Reader diff --git a/src/zh/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md b/src/zh/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md index 1d3e875b1..a2d6c145b 100644 --- a/src/zh/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md +++ b/src/zh/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md @@ -55,7 +55,6 @@ class TSEncoding(IntEnum): CHIMP = 11 # INT32、INT64、TIMESTAMP、DATE、FLOAT、DOUBLE SPRINTZ = 12 # INT32、INT64、FLOAT、DOUBLE RLBE = 13 # INT32、INT64、TIMESTAMP、DATE、FLOAT、DOUBLE - CAMEL = 14 # DOUBLE class Compressor(IntEnum): """ @@ -303,12 +302,13 @@ set_tsfile_config({ | 数据类型 | 允许的编码 | 默认值 | |---|---|---| | `BOOLEAN` | `PLAIN` | `PLAIN` | -| `INT32`、`INT64`、`TIMESTAMP`、`DATE` | `PLAIN`、`TS_2DIFF`、`GORILLA`、`ZIGZAG`、`RLE`、`SPRINTZ`、`CHIMP`、`RLBE` | `TS_2DIFF` | -| `FLOAT` | `PLAIN`、`TS_2DIFF`、`GORILLA`、`SPRINTZ`、`CHIMP`、`RLBE` | `GORILLA` | -| `DOUBLE` | `PLAIN`、`TS_2DIFF`、`GORILLA`、`SPRINTZ`、`CHIMP`、`RLBE`、`CAMEL` | `GORILLA` | +| `INT32`、`INT64`、`DATE` | `PLAIN`、`TS_2DIFF`、`GORILLA`、`ZIGZAG`、`RLE`、`SPRINTZ` | `TS_2DIFF` | +| `FLOAT`、`DOUBLE` | `PLAIN`、`TS_2DIFF`、`GORILLA`、`SPRINTZ` | `GORILLA` | | `STRING`、`TEXT` | `PLAIN`、`DICTIONARY` | `PLAIN` | -压缩适用于所有数据类型:`UNCOMPRESSED`、`SNAPPY`、`GZIP`、`LZO`、`LZ4`、`ZSTD`、`LZMA2`(默认 `LZ4`)。枚举还暴露 `SDT`、`PAA`、`PLA` 等历史值,但全局配置 setter 会拒绝这些值。 +时间列使用全局时间配置,支持 `PLAIN`、`TS_2DIFF`、`GORILLA`、`ZIGZAG`、`RLE` 或 `SPRINTZ`。 + +压缩适用于所有数据类型:`UNCOMPRESSED`、`SNAPPY`、`GZIP`、`LZO`、`LZ4`(默认 `LZ4`)。Python 枚举还暴露 `CHIMP`、`RLBE`、`ZSTD`、`LZMA2` 等值,但 `origin/develop` 当前的 writer/config 转换会拒绝它们。 ## 读取接口 From d0de0fd93f928d3ac118ff3588fc23dea2dc19cb Mon Sep 17 00:00:00 2001 From: ColinLee Date: Fri, 10 Jul 2026 09:36:49 +0800 Subject: [PATCH 4/4] Refine interface docs for public APIs --- .../InterfaceDefinition-C.md | 104 +----------------- .../InterfaceDefinition-CPP.md | 59 ---------- .../InterfaceDefinition-Python.md | 52 ++------- .../InterfaceDefinition-C.md | 104 +----------------- .../InterfaceDefinition-CPP.md | 59 ---------- .../InterfaceDefinition-Python.md | 52 ++------- .../InterfaceDefinition-C.md | 97 +--------------- .../InterfaceDefinition-CPP.md | 58 ---------- .../InterfaceDefinition-Python.md | 51 ++------- .../InterfaceDefinition-C.md | 97 +--------------- .../InterfaceDefinition-CPP.md | 58 ---------- .../InterfaceDefinition-Python.md | 51 ++------- 12 files changed, 46 insertions(+), 796 deletions(-) diff --git a/src/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md b/src/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md index 7ee9e74ed..e3fdf0b54 100644 --- a/src/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md +++ b/src/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md @@ -46,14 +46,9 @@ typedef enum { TS_ENCODING_PLAIN = 0, TS_ENCODING_DICTIONARY = 1, TS_ENCODING_RLE = 2, - TS_ENCODING_DIFF = 3, TS_ENCODING_TS_2DIFF = 4, - TS_ENCODING_BITMAP = 5, - TS_ENCODING_GORILLA_V1 = 6, - TS_ENCODING_REGULAR = 7, TS_ENCODING_GORILLA = 8, TS_ENCODING_ZIGZAG = 9, - TS_ENCODING_FREQ = 10, TS_ENCODING_SPRINTZ = 12, TS_ENCODING_INVALID = 255 } TSEncoding; @@ -64,9 +59,6 @@ typedef enum { TS_COMPRESSION_SNAPPY = 1, TS_COMPRESSION_GZIP = 2, TS_COMPRESSION_LZO = 3, - TS_COMPRESSION_SDT = 4, - TS_COMPRESSION_PAA = 5, - TS_COMPRESSION_PLA = 6, TS_COMPRESSION_LZ4 = 7, TS_COMPRESSION_INVALID = 255 } CompressionType; @@ -96,19 +88,6 @@ typedef struct table_schema { int column_num; } TableSchema; -typedef struct timeseries_schema { - char* timeseries_name; - TSDataType data_type; - TSEncoding encoding; - CompressionType compression; -} TimeseriesSchema; - -typedef struct device_schema { - char* device_name; - TimeseriesSchema* timeseries_schema; - int timeseries_num; -} DeviceSchema; - // ResultSetMetaData: Contains metadata for a result set, // such as column names and their data types. typedef struct result_set_meta_data { @@ -120,13 +99,6 @@ typedef struct result_set_meta_data { typedef struct arrow_schema ArrowSchema; typedef struct arrow_array ArrowArray; -typedef struct DeviceID { - char* path; - char* table_name; - uint32_t segment_count; - char** segments; -} DeviceID; - typedef struct TsFileStatisticBase { bool has_statistic; TSDataType type; @@ -154,35 +126,18 @@ typedef struct TimeseriesStatistic { } TimeseriesStatistic; #define tsfile_statistic_base(s) ((TsFileStatisticBase*)&(s)->u) - -typedef struct TimeseriesMetadata { - char* measurement_name; - TSDataType data_type; - int32_t chunk_meta_count; - TimeseriesStatistic statistic; - TimeseriesStatistic timeline_statistic; -} TimeseriesMetadata; - -typedef struct DeviceTimeseriesMetadataEntry { - DeviceID device; - TimeseriesMetadata* timeseries; - uint32_t timeseries_count; -} DeviceTimeseriesMetadataEntry; - -typedef struct DeviceTimeseriesMetadataMap { - DeviceTimeseriesMetadataEntry* entries; - uint32_t device_count; -} DeviceTimeseriesMetadataMap; ``` > `ColumnSchema` does not carry encoding/compression: on write, columns follow the > global defaults (see [Configuration](#configuration-encoding--compression)); on > read, each column is decoded with the file's actual settings. +> The encoding and compression constants listed above are the values accepted by +> the current writer/configuration path. > > `TimeseriesStatistic` is a tagged union in `tsfile_cwrapper.h`. Read common -> fields through `tsfile_statistic_base(&metadata.statistic)` and then use the -> active typed member (`int_s`, `float_s`, `bool_s`, `string_s`, or `text_s`) -> according to the statistic data type. +> fields through `tsfile_statistic_base(&statistic)` and then use the active +> typed member (`int_s`, `float_s`, `bool_s`, `string_s`, or `text_s`) according +> to the statistic data type. ## Write Interface @@ -810,58 +765,9 @@ TableSchema tsfile_reader_get_table_schema(TsFileReader reader, TableSchema* tsfile_reader_get_all_table_schemas(TsFileReader reader, uint32_t* size); -/** - * @brief Gets all timeseries schema in the tsfile. - * @param size[out] number of DeviceSchema elements in the returned array. - * @return DeviceSchema*, an array of device schemas. - * @note The caller must call free_device_schema() on each element - * and free() the array pointer. - */ -DeviceSchema* tsfile_reader_get_all_timeseries_schemas(TsFileReader reader, - uint32_t* size); - /** * @brief Free the tableschema's space. * @param schema [in] the table schema to be freed. */ void free_table_schema(TableSchema schema); - -void free_device_schema(DeviceSchema schema); ``` - -### Get Devices and Timeseries Metadata - -```C -/** - * @brief Lists all devices in the file. - * - * @param out_devices[out] allocated array; free with tsfile_free_device_id_array(). - * @param out_length[out] number of devices in the returned array. - */ -ERRNO tsfile_reader_get_all_devices(TsFileReader reader, DeviceID** out_devices, - uint32_t* out_length); - -void tsfile_free_device_id_array(DeviceID* devices, uint32_t length); -void tsfile_device_id_free_contents(DeviceID* d); - -/** - * @brief Timeseries metadata for all devices in the file. - */ -ERRNO tsfile_reader_get_timeseries_metadata_all( - TsFileReader reader, DeviceTimeseriesMetadataMap* out_map); - -/** - * @brief Timeseries metadata for the specified devices. - * - * length == 0 returns an empty map. For non-empty input, each DeviceID.path - * should contain the canonical device path. - */ -ERRNO tsfile_reader_get_timeseries_metadata_for_devices( - TsFileReader reader, const DeviceID* devices, uint32_t length, - DeviceTimeseriesMetadataMap* out_map); - -void tsfile_free_device_timeseries_metadata_map( - DeviceTimeseriesMetadataMap* map); -``` - - diff --git a/src/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md b/src/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md index b95ccbcaf..559cb2b7c 100644 --- a/src/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md +++ b/src/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md @@ -148,65 +148,6 @@ class TsFileTableWriter { }; ``` -### TsFileWriter - -`TsFileWriter` is the lower-level writer interface from `tsfile_writer.h`. It -supports both tree-model and table-model writes. - -```cpp -extern int libtsfile_init(); -extern void libtsfile_destroy(); - -// Writer configuration. Invalid values return common::E_INVALID_ARG and leave -// the previous value unchanged. -extern int set_page_max_point_count(uint32_t page_max_point_count); -extern int set_max_degree_of_index_node(uint32_t max_degree_of_index_node); - -class TsFileWriter { - public: - TsFileWriter(); - ~TsFileWriter(); - void destroy(); - - int open(const std::string& file_path, int flags, mode_t mode); - int open(const std::string& file_path); - int init(storage::WriteFile* write_file); - int init(storage::RestorableTsFileIOWriter* rw); - - void set_generate_table_schema(bool generate_table_schema); - - int register_timeseries(const std::string& device_id, - const MeasurementSchema& measurement_schema); - int register_timeseries( - const std::string& device_path, - const std::vector& measurement_schema_vec); - int register_aligned_timeseries( - const std::string& device_id, - const MeasurementSchema& measurement_schema); - int register_aligned_timeseries( - const std::string& device_id, - const std::vector& measurement_schemas); - int register_table(const std::shared_ptr& table_schema); - - int write_record(const TsRecord& record); - int write_tablet(const Tablet& tablet); - int write_record_aligned(const TsRecord& record); - int write_tablet_aligned(const Tablet& tablet); - int write_tree(const Tablet& tablet); - int write_tree(const TsRecord& record); - int write_table(Tablet& tablet); - - DeviceSchemasMap* get_schema_group_map(); - std::shared_ptr get_table_schema( - const std::string& table_name) const; - int64_t calculate_mem_size_for_all_group(); - int64_t calculate_meta_mem_size() const; - int check_memory_size_and_may_flush_chunks(); - int flush(); - int close(); -}; -``` - ### TableSchema Describe the data structure of the table schema diff --git a/src/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md b/src/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md index d0c039107..f44bbc353 100644 --- a/src/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md +++ b/src/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md @@ -180,6 +180,14 @@ class TsFileTableWriter: """ def write_dataframe(self, dataframe: pandas.DataFrame) + """ + Write a pyarrow RecordBatch or Table into the table. The data must include a + time column and columns matching the table schema. + :param data: pyarrow.RecordBatch or pyarrow.Table. + :return: no return value. + """ + def write_arrow_batch(self, data) + """ Flush buffered data to disk. :return: no return value. @@ -199,50 +207,6 @@ class TsFileTableWriter: def __exit__(self, exc_type, exc_val, exc_tb) ``` -### TsFileWriter - -`TsFileWriter` is the lower-level writer exposed from `writer.pyx`. It can write -tree-model data (`register_timeseries`, `register_device`, `write_tablet`, -`write_row_record`) and table-model data (`register_table`, `write_table`, -`write_dataframe`, `write_arrow_batch`). - -```python -class TsFileWriter: - """ - :param pathname: Destination TsFile path. - :param memory_threshold: bytes buffered before an automatic flush (default 128MB). - """ - def __init__(self, pathname: str, memory_threshold: int = 128 * 1024 * 1024) - - def register_timeseries(self, device_name: str, - timeseries_schema: TimeseriesSchema) - - def register_device(self, device_schema: DeviceSchema) - - def register_table(self, table_schema: TableSchema) - - def write_tablet(self, tablet: Tablet) - - def write_dataframe(self, target_table: str, dataframe: pandas.DataFrame, - tableschema: TableSchema) - - def write_row_record(self, record: RowRecord) - - def write_table(self, tablet: Tablet) - - def write_arrow_batch(self, table_name: str, data, - time_col_index: int = -1) - - def flush(self) - - def close(self) - - def __enter__(self) - def __exit__(self, exc_type, exc_val, exc_tb) -``` - - - ### Tablet definition ```Python diff --git a/src/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md b/src/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md index 7ee9e74ed..e3fdf0b54 100644 --- a/src/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md +++ b/src/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md @@ -46,14 +46,9 @@ typedef enum { TS_ENCODING_PLAIN = 0, TS_ENCODING_DICTIONARY = 1, TS_ENCODING_RLE = 2, - TS_ENCODING_DIFF = 3, TS_ENCODING_TS_2DIFF = 4, - TS_ENCODING_BITMAP = 5, - TS_ENCODING_GORILLA_V1 = 6, - TS_ENCODING_REGULAR = 7, TS_ENCODING_GORILLA = 8, TS_ENCODING_ZIGZAG = 9, - TS_ENCODING_FREQ = 10, TS_ENCODING_SPRINTZ = 12, TS_ENCODING_INVALID = 255 } TSEncoding; @@ -64,9 +59,6 @@ typedef enum { TS_COMPRESSION_SNAPPY = 1, TS_COMPRESSION_GZIP = 2, TS_COMPRESSION_LZO = 3, - TS_COMPRESSION_SDT = 4, - TS_COMPRESSION_PAA = 5, - TS_COMPRESSION_PLA = 6, TS_COMPRESSION_LZ4 = 7, TS_COMPRESSION_INVALID = 255 } CompressionType; @@ -96,19 +88,6 @@ typedef struct table_schema { int column_num; } TableSchema; -typedef struct timeseries_schema { - char* timeseries_name; - TSDataType data_type; - TSEncoding encoding; - CompressionType compression; -} TimeseriesSchema; - -typedef struct device_schema { - char* device_name; - TimeseriesSchema* timeseries_schema; - int timeseries_num; -} DeviceSchema; - // ResultSetMetaData: Contains metadata for a result set, // such as column names and their data types. typedef struct result_set_meta_data { @@ -120,13 +99,6 @@ typedef struct result_set_meta_data { typedef struct arrow_schema ArrowSchema; typedef struct arrow_array ArrowArray; -typedef struct DeviceID { - char* path; - char* table_name; - uint32_t segment_count; - char** segments; -} DeviceID; - typedef struct TsFileStatisticBase { bool has_statistic; TSDataType type; @@ -154,35 +126,18 @@ typedef struct TimeseriesStatistic { } TimeseriesStatistic; #define tsfile_statistic_base(s) ((TsFileStatisticBase*)&(s)->u) - -typedef struct TimeseriesMetadata { - char* measurement_name; - TSDataType data_type; - int32_t chunk_meta_count; - TimeseriesStatistic statistic; - TimeseriesStatistic timeline_statistic; -} TimeseriesMetadata; - -typedef struct DeviceTimeseriesMetadataEntry { - DeviceID device; - TimeseriesMetadata* timeseries; - uint32_t timeseries_count; -} DeviceTimeseriesMetadataEntry; - -typedef struct DeviceTimeseriesMetadataMap { - DeviceTimeseriesMetadataEntry* entries; - uint32_t device_count; -} DeviceTimeseriesMetadataMap; ``` > `ColumnSchema` does not carry encoding/compression: on write, columns follow the > global defaults (see [Configuration](#configuration-encoding--compression)); on > read, each column is decoded with the file's actual settings. +> The encoding and compression constants listed above are the values accepted by +> the current writer/configuration path. > > `TimeseriesStatistic` is a tagged union in `tsfile_cwrapper.h`. Read common -> fields through `tsfile_statistic_base(&metadata.statistic)` and then use the -> active typed member (`int_s`, `float_s`, `bool_s`, `string_s`, or `text_s`) -> according to the statistic data type. +> fields through `tsfile_statistic_base(&statistic)` and then use the active +> typed member (`int_s`, `float_s`, `bool_s`, `string_s`, or `text_s`) according +> to the statistic data type. ## Write Interface @@ -810,58 +765,9 @@ TableSchema tsfile_reader_get_table_schema(TsFileReader reader, TableSchema* tsfile_reader_get_all_table_schemas(TsFileReader reader, uint32_t* size); -/** - * @brief Gets all timeseries schema in the tsfile. - * @param size[out] number of DeviceSchema elements in the returned array. - * @return DeviceSchema*, an array of device schemas. - * @note The caller must call free_device_schema() on each element - * and free() the array pointer. - */ -DeviceSchema* tsfile_reader_get_all_timeseries_schemas(TsFileReader reader, - uint32_t* size); - /** * @brief Free the tableschema's space. * @param schema [in] the table schema to be freed. */ void free_table_schema(TableSchema schema); - -void free_device_schema(DeviceSchema schema); ``` - -### Get Devices and Timeseries Metadata - -```C -/** - * @brief Lists all devices in the file. - * - * @param out_devices[out] allocated array; free with tsfile_free_device_id_array(). - * @param out_length[out] number of devices in the returned array. - */ -ERRNO tsfile_reader_get_all_devices(TsFileReader reader, DeviceID** out_devices, - uint32_t* out_length); - -void tsfile_free_device_id_array(DeviceID* devices, uint32_t length); -void tsfile_device_id_free_contents(DeviceID* d); - -/** - * @brief Timeseries metadata for all devices in the file. - */ -ERRNO tsfile_reader_get_timeseries_metadata_all( - TsFileReader reader, DeviceTimeseriesMetadataMap* out_map); - -/** - * @brief Timeseries metadata for the specified devices. - * - * length == 0 returns an empty map. For non-empty input, each DeviceID.path - * should contain the canonical device path. - */ -ERRNO tsfile_reader_get_timeseries_metadata_for_devices( - TsFileReader reader, const DeviceID* devices, uint32_t length, - DeviceTimeseriesMetadataMap* out_map); - -void tsfile_free_device_timeseries_metadata_map( - DeviceTimeseriesMetadataMap* map); -``` - - diff --git a/src/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md b/src/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md index b95ccbcaf..559cb2b7c 100644 --- a/src/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md +++ b/src/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md @@ -148,65 +148,6 @@ class TsFileTableWriter { }; ``` -### TsFileWriter - -`TsFileWriter` is the lower-level writer interface from `tsfile_writer.h`. It -supports both tree-model and table-model writes. - -```cpp -extern int libtsfile_init(); -extern void libtsfile_destroy(); - -// Writer configuration. Invalid values return common::E_INVALID_ARG and leave -// the previous value unchanged. -extern int set_page_max_point_count(uint32_t page_max_point_count); -extern int set_max_degree_of_index_node(uint32_t max_degree_of_index_node); - -class TsFileWriter { - public: - TsFileWriter(); - ~TsFileWriter(); - void destroy(); - - int open(const std::string& file_path, int flags, mode_t mode); - int open(const std::string& file_path); - int init(storage::WriteFile* write_file); - int init(storage::RestorableTsFileIOWriter* rw); - - void set_generate_table_schema(bool generate_table_schema); - - int register_timeseries(const std::string& device_id, - const MeasurementSchema& measurement_schema); - int register_timeseries( - const std::string& device_path, - const std::vector& measurement_schema_vec); - int register_aligned_timeseries( - const std::string& device_id, - const MeasurementSchema& measurement_schema); - int register_aligned_timeseries( - const std::string& device_id, - const std::vector& measurement_schemas); - int register_table(const std::shared_ptr& table_schema); - - int write_record(const TsRecord& record); - int write_tablet(const Tablet& tablet); - int write_record_aligned(const TsRecord& record); - int write_tablet_aligned(const Tablet& tablet); - int write_tree(const Tablet& tablet); - int write_tree(const TsRecord& record); - int write_table(Tablet& tablet); - - DeviceSchemasMap* get_schema_group_map(); - std::shared_ptr get_table_schema( - const std::string& table_name) const; - int64_t calculate_mem_size_for_all_group(); - int64_t calculate_meta_mem_size() const; - int check_memory_size_and_may_flush_chunks(); - int flush(); - int close(); -}; -``` - ### TableSchema Describe the data structure of the table schema diff --git a/src/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md b/src/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md index d0c039107..f44bbc353 100644 --- a/src/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md +++ b/src/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md @@ -180,6 +180,14 @@ class TsFileTableWriter: """ def write_dataframe(self, dataframe: pandas.DataFrame) + """ + Write a pyarrow RecordBatch or Table into the table. The data must include a + time column and columns matching the table schema. + :param data: pyarrow.RecordBatch or pyarrow.Table. + :return: no return value. + """ + def write_arrow_batch(self, data) + """ Flush buffered data to disk. :return: no return value. @@ -199,50 +207,6 @@ class TsFileTableWriter: def __exit__(self, exc_type, exc_val, exc_tb) ``` -### TsFileWriter - -`TsFileWriter` is the lower-level writer exposed from `writer.pyx`. It can write -tree-model data (`register_timeseries`, `register_device`, `write_tablet`, -`write_row_record`) and table-model data (`register_table`, `write_table`, -`write_dataframe`, `write_arrow_batch`). - -```python -class TsFileWriter: - """ - :param pathname: Destination TsFile path. - :param memory_threshold: bytes buffered before an automatic flush (default 128MB). - """ - def __init__(self, pathname: str, memory_threshold: int = 128 * 1024 * 1024) - - def register_timeseries(self, device_name: str, - timeseries_schema: TimeseriesSchema) - - def register_device(self, device_schema: DeviceSchema) - - def register_table(self, table_schema: TableSchema) - - def write_tablet(self, tablet: Tablet) - - def write_dataframe(self, target_table: str, dataframe: pandas.DataFrame, - tableschema: TableSchema) - - def write_row_record(self, record: RowRecord) - - def write_table(self, tablet: Tablet) - - def write_arrow_batch(self, table_name: str, data, - time_col_index: int = -1) - - def flush(self) - - def close(self) - - def __enter__(self) - def __exit__(self, exc_type, exc_val, exc_tb) -``` - - - ### Tablet definition ```Python diff --git a/src/zh/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md b/src/zh/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md index 52eae5377..9d3b5ea71 100644 --- a/src/zh/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md +++ b/src/zh/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md @@ -46,14 +46,9 @@ typedef enum { TS_ENCODING_PLAIN = 0, TS_ENCODING_DICTIONARY = 1, TS_ENCODING_RLE = 2, - TS_ENCODING_DIFF = 3, TS_ENCODING_TS_2DIFF = 4, - TS_ENCODING_BITMAP = 5, - TS_ENCODING_GORILLA_V1 = 6, - TS_ENCODING_REGULAR = 7, TS_ENCODING_GORILLA = 8, TS_ENCODING_ZIGZAG = 9, - TS_ENCODING_FREQ = 10, TS_ENCODING_SPRINTZ = 12, TS_ENCODING_INVALID = 255 } TSEncoding; @@ -64,9 +59,6 @@ typedef enum { TS_COMPRESSION_SNAPPY = 1, TS_COMPRESSION_GZIP = 2, TS_COMPRESSION_LZO = 3, - TS_COMPRESSION_SDT = 4, - TS_COMPRESSION_PAA = 5, - TS_COMPRESSION_PLA = 6, TS_COMPRESSION_LZ4 = 7, TS_COMPRESSION_INVALID = 255 } CompressionType; @@ -93,19 +85,6 @@ typedef struct table_schema { int column_num; } TableSchema; -typedef struct timeseries_schema { - char* timeseries_name; - TSDataType data_type; - TSEncoding encoding; - CompressionType compression; -} TimeseriesSchema; - -typedef struct device_schema { - char* device_name; - TimeseriesSchema* timeseries_schema; - int timeseries_num; -} DeviceSchema; - // ResultSetMetaData:结果集的元数据,包括列名和数据类型。 typedef struct result_set_meta_data { char** column_names; @@ -116,13 +95,6 @@ typedef struct result_set_meta_data { typedef struct arrow_schema ArrowSchema; typedef struct arrow_array ArrowArray; -typedef struct DeviceID { - char* path; - char* table_name; - uint32_t segment_count; - char** segments; -} DeviceID; - typedef struct TsFileStatisticBase { bool has_statistic; TSDataType type; @@ -150,31 +122,13 @@ typedef struct TimeseriesStatistic { } TimeseriesStatistic; #define tsfile_statistic_base(s) ((TsFileStatisticBase*)&(s)->u) - -typedef struct TimeseriesMetadata { - char* measurement_name; - TSDataType data_type; - int32_t chunk_meta_count; - TimeseriesStatistic statistic; - TimeseriesStatistic timeline_statistic; -} TimeseriesMetadata; - -typedef struct DeviceTimeseriesMetadataEntry { - DeviceID device; - TimeseriesMetadata* timeseries; - uint32_t timeseries_count; -} DeviceTimeseriesMetadataEntry; - -typedef struct DeviceTimeseriesMetadataMap { - DeviceTimeseriesMetadataEntry* entries; - uint32_t device_count; -} DeviceTimeseriesMetadataMap; ``` > `ColumnSchema` 不携带编码/压缩:写入时列遵循全局默认值(见[配置](#配置编码与压缩)),读取时按文件中的实际配置解码。 +> 上面列出的编码和压缩常量是当前 writer/configuration 路径实际接受的值。 > > `TimeseriesStatistic` 是 `tsfile_cwrapper.h` 中的带标签 union。可通过 -> `tsfile_statistic_base(&metadata.statistic)` 读取通用字段,再根据数据类型读取 +> `tsfile_statistic_base(&statistic)` 读取通用字段,再根据数据类型读取 > `int_s`、`float_s`、`bool_s`、`string_s` 或 `text_s`。 ## 写入接口 @@ -783,17 +737,6 @@ TableSchema tsfile_reader_get_table_schema(TsFileReader reader, TableSchema* tsfile_reader_get_all_table_schemas(TsFileReader reader, uint32_t* size); -/** - * @brief 获取 TsFile 中所有 timeseries schema。 - * - * @param size [输出] 返回的 DeviceSchema 数组中的元素数量。 - * @return DeviceSchema* 设备 schema 数组指针。 - * @note 调用者必须对数组中的每个元素调用 free_device_schema(), - * 并对整个数组指针调用 free() 进行释放。 - */ -DeviceSchema* tsfile_reader_get_all_timeseries_schemas(TsFileReader reader, - uint32_t* size); - /** * @brief 释放 TableSchema 占用的内存空间。 * @@ -801,40 +744,4 @@ DeviceSchema* tsfile_reader_get_all_timeseries_schemas(TsFileReader reader, */ void free_table_schema(TableSchema schema); - -void free_device_schema(DeviceSchema schema); -``` - -### 获取设备与 Timeseries Metadata - -```C -/** - * @brief 列出文件中的所有设备。 - * - * @param out_devices [输出] 分配出的设备数组;用 tsfile_free_device_id_array() 释放。 - * @param out_length [输出] 返回数组中的设备数量。 - */ -ERRNO tsfile_reader_get_all_devices(TsFileReader reader, DeviceID** out_devices, - uint32_t* out_length); - -void tsfile_free_device_id_array(DeviceID* devices, uint32_t length); -void tsfile_device_id_free_contents(DeviceID* d); - -/** - * @brief 获取文件中所有设备的 timeseries metadata。 - */ -ERRNO tsfile_reader_get_timeseries_metadata_all( - TsFileReader reader, DeviceTimeseriesMetadataMap* out_map); - -/** - * @brief 获取指定设备的 timeseries metadata。 - * - * length == 0 返回空 map。非空输入中每个 DeviceID.path 应包含规范设备路径。 - */ -ERRNO tsfile_reader_get_timeseries_metadata_for_devices( - TsFileReader reader, const DeviceID* devices, uint32_t length, - DeviceTimeseriesMetadataMap* out_map); - -void tsfile_free_device_timeseries_metadata_map( - DeviceTimeseriesMetadataMap* map); ``` diff --git a/src/zh/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md b/src/zh/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md index 43d5cfcf9..5e18d2dac 100644 --- a/src/zh/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md +++ b/src/zh/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md @@ -149,64 +149,6 @@ class TsFileTableWriter { }; ``` -### TsFileWriter - -`TsFileWriter` 是 `tsfile_writer.h` 中的低层写入接口,支持 tree 模型和 table -模型写入。 - -```cpp -extern int libtsfile_init(); -extern void libtsfile_destroy(); - -// 写入器配置。非法值返回 common::E_INVALID_ARG,并保持原配置不变。 -extern int set_page_max_point_count(uint32_t page_max_point_count); -extern int set_max_degree_of_index_node(uint32_t max_degree_of_index_node); - -class TsFileWriter { - public: - TsFileWriter(); - ~TsFileWriter(); - void destroy(); - - int open(const std::string& file_path, int flags, mode_t mode); - int open(const std::string& file_path); - int init(storage::WriteFile* write_file); - int init(storage::RestorableTsFileIOWriter* rw); - - void set_generate_table_schema(bool generate_table_schema); - - int register_timeseries(const std::string& device_id, - const MeasurementSchema& measurement_schema); - int register_timeseries( - const std::string& device_path, - const std::vector& measurement_schema_vec); - int register_aligned_timeseries( - const std::string& device_id, - const MeasurementSchema& measurement_schema); - int register_aligned_timeseries( - const std::string& device_id, - const std::vector& measurement_schemas); - int register_table(const std::shared_ptr& table_schema); - - int write_record(const TsRecord& record); - int write_tablet(const Tablet& tablet); - int write_record_aligned(const TsRecord& record); - int write_tablet_aligned(const Tablet& tablet); - int write_tree(const Tablet& tablet); - int write_tree(const TsRecord& record); - int write_table(Tablet& tablet); - - DeviceSchemasMap* get_schema_group_map(); - std::shared_ptr get_table_schema( - const std::string& table_name) const; - int64_t calculate_mem_size_for_all_group(); - int64_t calculate_meta_mem_size() const; - int check_memory_size_and_may_flush_chunks(); - int flush(); - int close(); -}; -``` - ### TableSchema 描述表模式(schema)的数据结构。 diff --git a/src/zh/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md b/src/zh/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md index a2d6c145b..6eb0d9f3c 100644 --- a/src/zh/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md +++ b/src/zh/UserGuide/develop/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md @@ -174,6 +174,14 @@ class TsFileTableWriter: """ def write_dataframe(self, dataframe: pandas.DataFrame) + """ + 将 pyarrow RecordBatch 或 Table 写入表中。数据必须包含时间列,并且列需要与表 + schema 匹配。 + :param data: pyarrow.RecordBatch 或 pyarrow.Table。 + :return: 无返回值。 + """ + def write_arrow_batch(self, data) + """ 将缓冲数据刷新到磁盘。 :return: 无返回值。 @@ -194,49 +202,6 @@ class TsFileTableWriter: ``` -### TsFileWriter - -`TsFileWriter` 是 `writer.pyx` 暴露的低层写入接口。它可以写入 tree 模型数据 -(`register_timeseries`、`register_device`、`write_tablet`、`write_row_record`), -也可以写入 table 模型数据(`register_table`、`write_table`、`write_dataframe`、 -`write_arrow_batch`)。 - -```python -class TsFileWriter: - """ - :param pathname: 目标 TsFile 路径。 - :param memory_threshold: 触发自动刷盘前缓冲的字节数(默认 128MB)。 - """ - def __init__(self, pathname: str, memory_threshold: int = 128 * 1024 * 1024) - - def register_timeseries(self, device_name: str, - timeseries_schema: TimeseriesSchema) - - def register_device(self, device_schema: DeviceSchema) - - def register_table(self, table_schema: TableSchema) - - def write_tablet(self, tablet: Tablet) - - def write_dataframe(self, target_table: str, dataframe: pandas.DataFrame, - tableschema: TableSchema) - - def write_row_record(self, record: RowRecord) - - def write_table(self, tablet: Tablet) - - def write_arrow_batch(self, table_name: str, data, - time_col_index: int = -1) - - def flush(self) - - def close(self) - - def __enter__(self) - def __exit__(self, exc_type, exc_val, exc_tb) -``` - - ### Tablet definition diff --git a/src/zh/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md b/src/zh/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md index 52eae5377..9d3b5ea71 100644 --- a/src/zh/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md +++ b/src/zh/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-C.md @@ -46,14 +46,9 @@ typedef enum { TS_ENCODING_PLAIN = 0, TS_ENCODING_DICTIONARY = 1, TS_ENCODING_RLE = 2, - TS_ENCODING_DIFF = 3, TS_ENCODING_TS_2DIFF = 4, - TS_ENCODING_BITMAP = 5, - TS_ENCODING_GORILLA_V1 = 6, - TS_ENCODING_REGULAR = 7, TS_ENCODING_GORILLA = 8, TS_ENCODING_ZIGZAG = 9, - TS_ENCODING_FREQ = 10, TS_ENCODING_SPRINTZ = 12, TS_ENCODING_INVALID = 255 } TSEncoding; @@ -64,9 +59,6 @@ typedef enum { TS_COMPRESSION_SNAPPY = 1, TS_COMPRESSION_GZIP = 2, TS_COMPRESSION_LZO = 3, - TS_COMPRESSION_SDT = 4, - TS_COMPRESSION_PAA = 5, - TS_COMPRESSION_PLA = 6, TS_COMPRESSION_LZ4 = 7, TS_COMPRESSION_INVALID = 255 } CompressionType; @@ -93,19 +85,6 @@ typedef struct table_schema { int column_num; } TableSchema; -typedef struct timeseries_schema { - char* timeseries_name; - TSDataType data_type; - TSEncoding encoding; - CompressionType compression; -} TimeseriesSchema; - -typedef struct device_schema { - char* device_name; - TimeseriesSchema* timeseries_schema; - int timeseries_num; -} DeviceSchema; - // ResultSetMetaData:结果集的元数据,包括列名和数据类型。 typedef struct result_set_meta_data { char** column_names; @@ -116,13 +95,6 @@ typedef struct result_set_meta_data { typedef struct arrow_schema ArrowSchema; typedef struct arrow_array ArrowArray; -typedef struct DeviceID { - char* path; - char* table_name; - uint32_t segment_count; - char** segments; -} DeviceID; - typedef struct TsFileStatisticBase { bool has_statistic; TSDataType type; @@ -150,31 +122,13 @@ typedef struct TimeseriesStatistic { } TimeseriesStatistic; #define tsfile_statistic_base(s) ((TsFileStatisticBase*)&(s)->u) - -typedef struct TimeseriesMetadata { - char* measurement_name; - TSDataType data_type; - int32_t chunk_meta_count; - TimeseriesStatistic statistic; - TimeseriesStatistic timeline_statistic; -} TimeseriesMetadata; - -typedef struct DeviceTimeseriesMetadataEntry { - DeviceID device; - TimeseriesMetadata* timeseries; - uint32_t timeseries_count; -} DeviceTimeseriesMetadataEntry; - -typedef struct DeviceTimeseriesMetadataMap { - DeviceTimeseriesMetadataEntry* entries; - uint32_t device_count; -} DeviceTimeseriesMetadataMap; ``` > `ColumnSchema` 不携带编码/压缩:写入时列遵循全局默认值(见[配置](#配置编码与压缩)),读取时按文件中的实际配置解码。 +> 上面列出的编码和压缩常量是当前 writer/configuration 路径实际接受的值。 > > `TimeseriesStatistic` 是 `tsfile_cwrapper.h` 中的带标签 union。可通过 -> `tsfile_statistic_base(&metadata.statistic)` 读取通用字段,再根据数据类型读取 +> `tsfile_statistic_base(&statistic)` 读取通用字段,再根据数据类型读取 > `int_s`、`float_s`、`bool_s`、`string_s` 或 `text_s`。 ## 写入接口 @@ -783,17 +737,6 @@ TableSchema tsfile_reader_get_table_schema(TsFileReader reader, TableSchema* tsfile_reader_get_all_table_schemas(TsFileReader reader, uint32_t* size); -/** - * @brief 获取 TsFile 中所有 timeseries schema。 - * - * @param size [输出] 返回的 DeviceSchema 数组中的元素数量。 - * @return DeviceSchema* 设备 schema 数组指针。 - * @note 调用者必须对数组中的每个元素调用 free_device_schema(), - * 并对整个数组指针调用 free() 进行释放。 - */ -DeviceSchema* tsfile_reader_get_all_timeseries_schemas(TsFileReader reader, - uint32_t* size); - /** * @brief 释放 TableSchema 占用的内存空间。 * @@ -801,40 +744,4 @@ DeviceSchema* tsfile_reader_get_all_timeseries_schemas(TsFileReader reader, */ void free_table_schema(TableSchema schema); - -void free_device_schema(DeviceSchema schema); -``` - -### 获取设备与 Timeseries Metadata - -```C -/** - * @brief 列出文件中的所有设备。 - * - * @param out_devices [输出] 分配出的设备数组;用 tsfile_free_device_id_array() 释放。 - * @param out_length [输出] 返回数组中的设备数量。 - */ -ERRNO tsfile_reader_get_all_devices(TsFileReader reader, DeviceID** out_devices, - uint32_t* out_length); - -void tsfile_free_device_id_array(DeviceID* devices, uint32_t length); -void tsfile_device_id_free_contents(DeviceID* d); - -/** - * @brief 获取文件中所有设备的 timeseries metadata。 - */ -ERRNO tsfile_reader_get_timeseries_metadata_all( - TsFileReader reader, DeviceTimeseriesMetadataMap* out_map); - -/** - * @brief 获取指定设备的 timeseries metadata。 - * - * length == 0 返回空 map。非空输入中每个 DeviceID.path 应包含规范设备路径。 - */ -ERRNO tsfile_reader_get_timeseries_metadata_for_devices( - TsFileReader reader, const DeviceID* devices, uint32_t length, - DeviceTimeseriesMetadataMap* out_map); - -void tsfile_free_device_timeseries_metadata_map( - DeviceTimeseriesMetadataMap* map); ``` diff --git a/src/zh/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md b/src/zh/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md index 43d5cfcf9..5e18d2dac 100644 --- a/src/zh/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md +++ b/src/zh/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-CPP.md @@ -149,64 +149,6 @@ class TsFileTableWriter { }; ``` -### TsFileWriter - -`TsFileWriter` 是 `tsfile_writer.h` 中的低层写入接口,支持 tree 模型和 table -模型写入。 - -```cpp -extern int libtsfile_init(); -extern void libtsfile_destroy(); - -// 写入器配置。非法值返回 common::E_INVALID_ARG,并保持原配置不变。 -extern int set_page_max_point_count(uint32_t page_max_point_count); -extern int set_max_degree_of_index_node(uint32_t max_degree_of_index_node); - -class TsFileWriter { - public: - TsFileWriter(); - ~TsFileWriter(); - void destroy(); - - int open(const std::string& file_path, int flags, mode_t mode); - int open(const std::string& file_path); - int init(storage::WriteFile* write_file); - int init(storage::RestorableTsFileIOWriter* rw); - - void set_generate_table_schema(bool generate_table_schema); - - int register_timeseries(const std::string& device_id, - const MeasurementSchema& measurement_schema); - int register_timeseries( - const std::string& device_path, - const std::vector& measurement_schema_vec); - int register_aligned_timeseries( - const std::string& device_id, - const MeasurementSchema& measurement_schema); - int register_aligned_timeseries( - const std::string& device_id, - const std::vector& measurement_schemas); - int register_table(const std::shared_ptr& table_schema); - - int write_record(const TsRecord& record); - int write_tablet(const Tablet& tablet); - int write_record_aligned(const TsRecord& record); - int write_tablet_aligned(const Tablet& tablet); - int write_tree(const Tablet& tablet); - int write_tree(const TsRecord& record); - int write_table(Tablet& tablet); - - DeviceSchemasMap* get_schema_group_map(); - std::shared_ptr get_table_schema( - const std::string& table_name) const; - int64_t calculate_mem_size_for_all_group(); - int64_t calculate_meta_mem_size() const; - int check_memory_size_and_may_flush_chunks(); - int flush(); - int close(); -}; -``` - ### TableSchema 描述表模式(schema)的数据结构。 diff --git a/src/zh/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md b/src/zh/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md index a2d6c145b..6eb0d9f3c 100644 --- a/src/zh/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md +++ b/src/zh/UserGuide/latest/QuickStart/InterfaceDefinition/InterfaceDefinition-Python.md @@ -174,6 +174,14 @@ class TsFileTableWriter: """ def write_dataframe(self, dataframe: pandas.DataFrame) + """ + 将 pyarrow RecordBatch 或 Table 写入表中。数据必须包含时间列,并且列需要与表 + schema 匹配。 + :param data: pyarrow.RecordBatch 或 pyarrow.Table。 + :return: 无返回值。 + """ + def write_arrow_batch(self, data) + """ 将缓冲数据刷新到磁盘。 :return: 无返回值。 @@ -194,49 +202,6 @@ class TsFileTableWriter: ``` -### TsFileWriter - -`TsFileWriter` 是 `writer.pyx` 暴露的低层写入接口。它可以写入 tree 模型数据 -(`register_timeseries`、`register_device`、`write_tablet`、`write_row_record`), -也可以写入 table 模型数据(`register_table`、`write_table`、`write_dataframe`、 -`write_arrow_batch`)。 - -```python -class TsFileWriter: - """ - :param pathname: 目标 TsFile 路径。 - :param memory_threshold: 触发自动刷盘前缓冲的字节数(默认 128MB)。 - """ - def __init__(self, pathname: str, memory_threshold: int = 128 * 1024 * 1024) - - def register_timeseries(self, device_name: str, - timeseries_schema: TimeseriesSchema) - - def register_device(self, device_schema: DeviceSchema) - - def register_table(self, table_schema: TableSchema) - - def write_tablet(self, tablet: Tablet) - - def write_dataframe(self, target_table: str, dataframe: pandas.DataFrame, - tableschema: TableSchema) - - def write_row_record(self, record: RowRecord) - - def write_table(self, tablet: Tablet) - - def write_arrow_batch(self, table_name: str, data, - time_col_index: int = -1) - - def flush(self) - - def close(self) - - def __enter__(self) - def __exit__(self, exc_type, exc_val, exc_tb) -``` - - ### Tablet definition