diff --git a/Jenkinsfile2 b/Jenkinsfile2
index 754617f99f..12e806c87a 100644
--- a/Jenkinsfile2
+++ b/Jenkinsfile2
@@ -43,6 +43,7 @@ def pre_test(){
cd ${WKC}
git reset --hard
git clean -fxd
+ rm -rf examples/rust/
git remote prune origin
git fetch
'''
diff --git a/cmake/cmake.install b/cmake/cmake.install
index 4e3d0b166a..6dc6864975 100644
--- a/cmake/cmake.install
+++ b/cmake/cmake.install
@@ -1,38 +1,8 @@
-IF (EXISTS /var/lib/taos/dnode/dnodeCfg.json)
- INSTALL(CODE "MESSAGE(\"The default data directory /var/lib/taos contains old data of tdengine 2.x, please clear it before installing!\")")
-ELSEIF (EXISTS C:/TDengine/data/dnode/dnodeCfg.json)
- INSTALL(CODE "MESSAGE(\"The default data directory C:/TDengine/data contains old data of tdengine 2.x, please clear it before installing!\")")
-ELSEIF (TD_LINUX)
+IF (TD_LINUX)
SET(TD_MAKE_INSTALL_SH "${TD_SOURCE_DIR}/packaging/tools/make_install.sh")
INSTALL(CODE "MESSAGE(\"make install script: ${TD_MAKE_INSTALL_SH}\")")
INSTALL(CODE "execute_process(COMMAND bash ${TD_MAKE_INSTALL_SH} ${TD_SOURCE_DIR} ${PROJECT_BINARY_DIR} Linux ${TD_VER_NUMBER})")
ELSEIF (TD_WINDOWS)
- SET(CMAKE_INSTALL_PREFIX C:/TDengine)
-
- # INSTALL(DIRECTORY ${TD_SOURCE_DIR}/src/connector/go DESTINATION connector)
- # INSTALL(DIRECTORY ${TD_SOURCE_DIR}/src/connector/nodejs DESTINATION connector)
- # INSTALL(DIRECTORY ${TD_SOURCE_DIR}/src/connector/python DESTINATION connector)
- # INSTALL(DIRECTORY ${TD_SOURCE_DIR}/src/connector/C\# DESTINATION connector)
- # INSTALL(DIRECTORY ${TD_SOURCE_DIR}/examples DESTINATION .)
- INSTALL(CODE "IF (NOT EXISTS ${CMAKE_INSTALL_PREFIX}/cfg/taos.cfg)
- execute_process(COMMAND ${CMAKE_COMMAND} -E copy ${TD_SOURCE_DIR}/packaging/cfg/taos.cfg ${CMAKE_INSTALL_PREFIX}/cfg/taos.cfg)
- ENDIF ()")
- INSTALL(FILES ${TD_SOURCE_DIR}/include/client/taos.h DESTINATION include)
- INSTALL(FILES ${TD_SOURCE_DIR}/include/util/taoserror.h DESTINATION include)
- INSTALL(FILES ${TD_SOURCE_DIR}/include/libs/function/taosudf.h DESTINATION include)
- INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos.lib DESTINATION driver)
- INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos_static.lib DESTINATION driver)
- INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos.dll DESTINATION driver)
- INSTALL(FILES ${EXECUTABLE_OUTPUT_PATH}/taos.exe DESTINATION .)
- INSTALL(FILES ${EXECUTABLE_OUTPUT_PATH}/taosd.exe DESTINATION .)
- INSTALL(FILES ${EXECUTABLE_OUTPUT_PATH}/udfd.exe DESTINATION .)
- IF (BUILD_TOOLS)
- INSTALL(FILES ${EXECUTABLE_OUTPUT_PATH}/taosBenchmark.exe DESTINATION .)
- ENDIF ()
-
- IF (TD_MVN_INSTALLED)
- INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos-jdbcdriver-2.0.38-dist.jar DESTINATION connector/jdbc)
- ENDIF ()
SET(TD_MAKE_INSTALL_SH "${TD_SOURCE_DIR}/packaging/tools/make_install.bat")
INSTALL(CODE "MESSAGE(\"make install script: ${TD_MAKE_INSTALL_SH}\")")
INSTALL(CODE "execute_process(COMMAND ${TD_MAKE_INSTALL_SH} :needAdmin ${TD_SOURCE_DIR} ${PROJECT_BINARY_DIR} Windows ${TD_VER_NUMBER})")
diff --git a/cmake/taosadapter_CMakeLists.txt.in b/cmake/taosadapter_CMakeLists.txt.in
index ed8216be91..f182beed33 100644
--- a/cmake/taosadapter_CMakeLists.txt.in
+++ b/cmake/taosadapter_CMakeLists.txt.in
@@ -2,7 +2,7 @@
# taosadapter
ExternalProject_Add(taosadapter
GIT_REPOSITORY https://github.com/taosdata/taosadapter.git
- GIT_TAG 3d21433
+ GIT_TAG abed566
SOURCE_DIR "${TD_SOURCE_DIR}/tools/taosadapter"
BINARY_DIR ""
#BUILD_IN_SOURCE TRUE
diff --git a/contrib/CMakeLists.txt b/contrib/CMakeLists.txt
index a1eec81ee0..2dc7622f46 100644
--- a/contrib/CMakeLists.txt
+++ b/contrib/CMakeLists.txt
@@ -135,24 +135,6 @@ execute_process(COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" .
WORKING_DIRECTORY "${TD_CONTRIB_DIR}/deps-download")
execute_process(COMMAND "${CMAKE_COMMAND}" --build .
WORKING_DIRECTORY "${TD_CONTRIB_DIR}/deps-download")
-
-# clear submodule
-execute_process(COMMAND git submodule deinit -f tools/taos-tools
- WORKING_DIRECTORY "${TD_SOURCE_DIR}")
-execute_process(COMMAND git rm --cached tools/taos-tools
- WORKING_DIRECTORY "${TD_SOURCE_DIR}")
-execute_process(COMMAND git submodule deinit -f tools/taosadapter
- WORKING_DIRECTORY "${TD_SOURCE_DIR}")
-execute_process(COMMAND git rm --cached tools/taosadapter
- WORKING_DIRECTORY "${TD_SOURCE_DIR}")
-execute_process(COMMAND git submodule deinit -f tools/taosws-rs
- WORKING_DIRECTORY "${TD_SOURCE_DIR}")
-execute_process(COMMAND git rm --cached tools/taosws-rs
- WORKING_DIRECTORY "${TD_SOURCE_DIR}")
-execute_process(COMMAND git submodule deinit -f examples/rust
- WORKING_DIRECTORY "${TD_SOURCE_DIR}")
-execute_process(COMMAND git rm --cached examples/rust
- WORKING_DIRECTORY "${TD_SOURCE_DIR}")
# ================================================================================================
# Build
@@ -349,9 +331,11 @@ endif(${BUILD_WITH_TRAFT})
# LIBUV
if(${BUILD_WITH_UV})
- if (NOT ${CMAKE_SYSTEM_NAME} MATCHES "Windows")
- MESSAGE("Windows need set no-sign-compare")
- add_compile_options(-Wno-sign-compare)
+ if (TD_WINDOWS)
+ # There is no GetHostNameW function on win7.
+ file(READ "libuv/src/win/util.c" LIBUV_WIN_UTIL_CONTENT)
+ string(REPLACE "if (GetHostNameW(buf, UV_MAXHOSTNAMESIZE" "DWORD nSize = UV_MAXHOSTNAMESIZE;\n if (GetComputerNameW(buf, &nSize" LIBUV_WIN_UTIL_CONTENT "${LIBUV_WIN_UTIL_CONTENT}")
+ file(WRITE "libuv/src/win/util.c" "${LIBUV_WIN_UTIL_CONTENT}")
endif ()
add_subdirectory(libuv EXCLUDE_FROM_ALL)
endif(${BUILD_WITH_UV})
diff --git a/docs/en/01-index.md b/docs/en/01-index.md
index f5b7f3e0f6..4c2f9b02b9 100644
--- a/docs/en/01-index.md
+++ b/docs/en/01-index.md
@@ -4,7 +4,8 @@ sidebar_label: Documentation Home
slug: /
---
-TDengine is a [high-performance](https://tdengine.com/fast), [scalable](https://tdengine.com/scalable) time series database with [SQL support](https://tdengine.com/sql-support). This document is the TDengine user manual. It introduces the basic, as well as novel concepts, in TDengine, and also talks in detail about installation, features, SQL, APIs, operation, maintenance, kernel design and other topics. It’s written mainly for architects, developers and system administrators.
+
+TDengine is an open source, cloud native time-series database optimized for Internet of Things (IoT), Connected Cars, and Industrial IoT. It enables efficient, real-time data ingestion, processing, and monitoring of TB and even PB scale data per day, generated by billions of sensors and data collectors. This document is the TDengine user manual. It introduces the basic, as well as novel concepts, in TDengine, and also talks in detail about installation, features, SQL, APIs, operation, maintenance, kernel design and other topics. It’s written mainly for architects, developers and system administrators.
To get an overview of TDengine, such as a feature list, benchmarks, and competitive advantages, please browse through the [Introduction](./intro) section.
diff --git a/docs/en/02-intro/index.md b/docs/en/02-intro/index.md
index f6766f910f..23a79aa229 100644
--- a/docs/en/02-intro/index.md
+++ b/docs/en/02-intro/index.md
@@ -3,7 +3,7 @@ title: Introduction
toc_max_heading_level: 2
---
-TDengine is a high-performance, scalable time-series database with SQL support. Its code, including its cluster feature is open source under GNU AGPL v3.0. Besides the database engine, it provides [caching](/develop/cache), [stream processing](/develop/continuous-query), [data subscription](/develop/subscribe) and other functionalities to reduce the complexity and cost of development and operation.
+TDengine is an open source, high-performance, cloud native time-series database optimized for Internet of Things (IoT), Connected Cars, and Industrial IoT. Its code, including its cluster feature is open source under GNU AGPL v3.0. Besides the database engine, it provides [caching](/develop/cache), [stream processing](/develop/continuous-query), [data subscription](/develop/subscribe) and other functionalities to reduce the system complexity and cost of development and operation.
This section introduces the major features, competitive advantages, typical use-cases and benchmarks to help you get a high level overview of TDengine.
@@ -31,25 +31,21 @@ For more details on features, please read through the entire documentation.
## Competitive Advantages
-Time-series data is structured, not transactional, and is rarely deleted or updated. TDengine makes full use of [these characteristics of time series data](https://tdengine.com/2019/07/09/86.html) to build its own innovative storage engine and computing engine to differentiate itself from other time series databases, with the following advantages.
+By making full use of [characteristics of time series data](https://tdengine.com/tsdb/characteristics-of-time-series-data/), TDengine differentiates itself from other time series databases, with the following advantages.
-- **[High Performance](https://tdengine.com/fast)**: With an innovatively designed and purpose-built storage engine, TDengine outperforms other time series databases in data ingestion and querying while significantly reducing storage costs and compute costs.
+- **High-Performance**: TDengine is the only time-series database to solve the high cardinality issue to support billions of data collection points while out performing other time-series databases for data ingestion, querying and data compression.
-- **[Scalable](https://tdengine.com/scalable)**: TDengine provides out-of-box scalability and high-availability through its native distributed design. Nodes can be added through simple configuration to achieve greater data processing power. In addition, this feature is open source.
+- **Simplified Solution**: Through built-in caching, stream processing and data subscription features, TDengine provides a simplified solution for time-series data processing. It reduces system design complexity and operation costs significantly.
-- **[SQL Support](https://tdengine.com/sql-support)**: TDengine uses SQL as the query language, thereby reducing learning and migration costs, while adding SQL extensions to better handle time-series. Keeping NoSQL developers in mind, TDengine also supports convenient and flexible, schemaless data ingestion.
+- **Cloud Native**: Through native distributed design, sharding and partitioning, separation of compute and storage, RAFT, support for kubernetes deployment and full observability, TDengine is a cloud native Time-Series Database and can be deployed on public, private or hybrid clouds.
-- **All in One**: TDengine has built-in caching, stream processing and data subscription functions. It is no longer necessary to integrate Kafka/Redis/HBase/Spark or other software in some scenarios. It makes the system architecture much simpler, cost-effective and easier to maintain.
+- **Ease of Use**: For administrators, TDengine significantly reduces the effort to deploy and maintain. For developers, it provides a simple interface, simplified solution and seamless integrations for third party tools. For data users, it gives easy data access.
-- **Seamless Integration**: Without a single line of code, TDengine provide seamless, configurable integration with third-party tools such as Telegraf, Grafana, EMQX, Prometheus, StatsD, collectd, etc. More third-party tools are being integrated.
+- **Easy Data Analytics**: Through super tables, storage and compute separation, data partitioning by time interval, pre-computation and other means, TDengine makes it easy to explore, format, and get access to data in a highly efficient way.
-- **Zero Management**: Installation and cluster setup can be done in seconds. Data partitioning and sharding are executed automatically. TDengine’s running status can be monitored via Grafana or other DevOps tools.
+- **Open Source**: TDengine’s core modules, including cluster feature, are all available under open source licenses. It has gathered 18.8k stars on GitHub. There is an active developer community, and over 139k running instances worldwide.
-- **Zero Learning Costs**: With SQL as the query language and support for ubiquitous tools like Python, Java, C/C++, Go, Rust, and Node.js connectors, and a REST API, there are zero learning costs.
-
-- **Interactive Console**: TDengine provides convenient console access to the database, through a CLI, to run ad hoc queries, maintain the database, or manage the cluster, without any programming.
-
-With TDengine, the total cost of ownership of your time-series data platform can be greatly reduced. 1: With its superior performance, the computing and storage resources are reduced significantly 2: With SQL support, it can be seamlessly integrated with many third party tools, and learning costs/migration costs are reduced significantly 3: With its simple architecture and zero management, the operation and maintenance costs are reduced.
+With TDengine, the total cost of ownership of your time-series data platform can be greatly reduced. 1: With its superior performance, the computing and storage resources are reduced significantly;2: With SQL support, it can be seamlessly integrated with many third party tools, and learning costs/migration costs are reduced significantly;3: With its simplified solution and nearly zero management, the operation and maintenance costs are reduced significantly.
## Technical Ecosystem
This is how TDengine would be situated, in a typical time-series data processing platform:
diff --git a/docs/en/04-concept/index.md b/docs/en/04-concept/index.md
index 307bf2a989..44dcad82fc 100644
--- a/docs/en/04-concept/index.md
+++ b/docs/en/04-concept/index.md
@@ -2,7 +2,7 @@
title: Concepts
---
-In order to explain the basic concepts and provide some sample code, the TDengine documentation smart meters as a typical time series use case. We assume the following: 1. Each smart meter collects three metrics i.e. current, voltage, and phase 2. There are multiple smart meters, and 3. Each meter has static attributes like location and group ID. Based on this, collected data will look similar to the following table:
+In order to explain the basic concepts and provide some sample code, the TDengine documentation smart meters as a typical time series use case. We assume the following: 1. Each smart meter collects three metrics i.e. current, voltage, and phase; 2. There are multiple smart meters; 3. Each meter has static attributes like location and group ID. Based on this, collected data will look similar to the following table:
diff --git a/docs/en/07-develop/02-model/index.mdx b/docs/en/07-develop/02-model/index.mdx
index 83fc7da15e..3c16ed2df1 100644
--- a/docs/en/07-develop/02-model/index.mdx
+++ b/docs/en/07-develop/02-model/index.mdx
@@ -2,7 +2,9 @@
title: Data Model
---
-The data model employed by TDengine is similar to that of a relational database. You have to create databases and tables. You must design the data model based on your own business and application requirements. You should design the STable (an abbreviation for super table) schema to fit your data. This chapter will explain the big picture without getting into syntactical details.
+The data model employed by TDengine is similar to that of a relational database. You have to create databases and tables. You must design the data model based on your own business and application requirements. You should design the [STable](/concept/#super-table-stable) (an abbreviation for super table) schema to fit your data. This chapter will explain the big picture without getting into syntactical details.
+
+Note: before you read this chapter, please make sure you have already read through [Key Concepts](/concept/), since TDengine introduces new concepts like "one table for one [data collection point](/concept/#data-collection-point)" and "[super table](/concept/#super-table-stable)".
@@ -11,7 +13,7 @@ The data model employed by TDengine is similar to that of a relational database.
The characteristics of time-series data from different data collection points may be different. Characteristics include collection frequency, retention policy and others which determine how you create and configure the database. For e.g. days to keep, number of replicas, data block size, whether data updates are allowed and other configurable parameters would be determined by the characteristics of your data and your business requirements. For TDengine to operate with the best performance, we strongly recommend that you create and configure different databases for data with different characteristics. This allows you, for example, to set up different storage and retention policies. When creating a database, there are a lot of parameters that can be configured such as, the days to keep data, the number of replicas, the size of the cache, time precision, the minimum and maximum number of rows in each data block, whether compression is enabled, the time range of the data in single data file and so on. An example is shown as follows:
```sql
-CREATE DATABASE power KEEP 365 DURATION 10 BUFFER 16 VGROUPS 100 WAL 1;
+CREATE DATABASE power KEEP 365 DURATION 10 BUFFER 16 WAL_LEVEL 1;
```
In the above SQL statement:
diff --git a/docs/en/07-develop/04-query-data/index.mdx b/docs/en/07-develop/04-query-data/index.mdx
index e23973c704..d530c59185 100644
--- a/docs/en/07-develop/04-query-data/index.mdx
+++ b/docs/en/07-develop/04-query-data/index.mdx
@@ -54,21 +54,21 @@ In most use cases, there are always multiple kinds of data collection points. A
In TDengine CLI `taos`, use the SQL below to get the average voltage of all the meters in California grouped by location.
```
-taos> SELECT AVG(voltage) FROM meters GROUP BY location;
- avg(voltage) | location |
-=============================================================
- 222.000000000 | California.LosAngeles |
- 219.200000000 | California.SanFrancisco |
-Query OK, 2 row(s) in set (0.002136s)
+taos> SELECT AVG(voltage), location FROM meters GROUP BY location;
+ avg(voltage) | location |
+===============================================================================================
+ 219.200000000 | California.SanFrancisco |
+ 221.666666667 | California.LosAngeles |
+Query OK, 2 rows in database (0.005995s)
```
### Example 2
-In TDengine CLI `taos`, use the SQL below to get the number of rows and the maximum current in the past 24 hours from meters whose groupId is 2.
+In TDengine CLI `taos`, use the SQL below to get the number of rows and the maximum current from meters whose groupId is 2.
```
-taos> SELECT count(*), max(current) FROM meters where groupId = 2 and ts > now - 24h;
- cunt(*) | max(current) |
+taos> SELECT count(*), max(current) FROM meters where groupId = 2;
+ count(*) | max(current) |
==================================
5 | 13.4 |
Query OK, 1 row(s) in set (0.002136s)
@@ -81,40 +81,41 @@ In [Select](../../taos-sql././select), all query operations are marked as to whe
In IoT use cases, down sampling is widely used to aggregate data by time range. The `INTERVAL` keyword in TDengine can be used to simplify the query by time window. For example, the SQL statement below can be used to get the sum of current every 10 seconds from meters table d1001.
```
-taos> SELECT sum(current) FROM d1001 INTERVAL(10s);
- ts | sum(current) |
+taos> SELECT _wstart, sum(current) FROM d1001 INTERVAL(10s);
+ _wstart | sum(current) |
======================================================
2018-10-03 14:38:00.000 | 10.300000191 |
2018-10-03 14:38:10.000 | 24.900000572 |
-Query OK, 2 row(s) in set (0.000883s)
+Query OK, 2 rows in database (0.003139s)
```
Down sampling can also be used for STable. For example, the below SQL statement can be used to get the sum of current from all meters in California.
```
-taos> SELECT SUM(current) FROM meters where location like "California%" INTERVAL(1s);
- ts | sum(current) |
+taos> SELECT _wstart, SUM(current) FROM meters where location like "California%" INTERVAL(1s);
+ _wstart | sum(current) |
======================================================
2018-10-03 14:38:04.000 | 10.199999809 |
- 2018-10-03 14:38:05.000 | 32.900000572 |
+ 2018-10-03 14:38:05.000 | 23.699999809 |
2018-10-03 14:38:06.000 | 11.500000000 |
2018-10-03 14:38:15.000 | 12.600000381 |
- 2018-10-03 14:38:16.000 | 36.000000000 |
-Query OK, 5 row(s) in set (0.001538s)
+ 2018-10-03 14:38:16.000 | 34.400000572 |
+Query OK, 5 rows in database (0.007413s)
```
Down sampling also supports time offset. For example, the below SQL statement can be used to get the sum of current from all meters but each time window must start at the boundary of 500 milliseconds.
```
-taos> SELECT SUM(current) FROM meters INTERVAL(1s, 500a);
- ts | sum(current) |
+taos> SELECT _wstart, SUM(current) FROM meters INTERVAL(1s, 500a);
+ _wstart | sum(current) |
======================================================
- 2018-10-03 14:38:04.500 | 11.189999809 |
- 2018-10-03 14:38:05.500 | 31.900000572 |
- 2018-10-03 14:38:06.500 | 11.600000000 |
- 2018-10-03 14:38:15.500 | 12.300000381 |
- 2018-10-03 14:38:16.500 | 35.000000000 |
-Query OK, 5 row(s) in set (0.001521s)
+ 2018-10-03 14:38:03.500 | 10.199999809 |
+ 2018-10-03 14:38:04.500 | 10.300000191 |
+ 2018-10-03 14:38:05.500 | 13.399999619 |
+ 2018-10-03 14:38:06.500 | 11.500000000 |
+ 2018-10-03 14:38:14.500 | 12.600000381 |
+ 2018-10-03 14:38:16.500 | 34.400000572 |
+Query OK, 6 rows in database (0.005515s)
```
In many use cases, it's hard to align the timestamp of the data collected by each collection point. However, a lot of algorithms like FFT require the data to be aligned with same time interval and application programs have to handle this by themselves. In TDengine, it's easy to achieve the alignment using down sampling.
diff --git a/docs/examples/node/nativeexample/subscribe_demo.js b/docs/examples/node/nativeexample/subscribe_demo.js
index 5b65e1c907..53cbe55d26 100644
--- a/docs/examples/node/nativeexample/subscribe_demo.js
+++ b/docs/examples/node/nativeexample/subscribe_demo.js
@@ -28,8 +28,7 @@ function runConsumer() {
console.log(msg.topicPartition);
console.log(msg.block);
console.log(msg.fields)
- // fixme(@xiaolei): commented temp, should be fixed.
- //consumer.commit(msg);
+ consumer.commit(msg);
console.log(`=======consumer ${i} done`)
}
diff --git a/docs/examples/node/package.json b/docs/examples/node/package.json
index 36d3f016b5..d00d71d99f 100644
--- a/docs/examples/node/package.json
+++ b/docs/examples/node/package.json
@@ -4,7 +4,7 @@
"main": "index.js",
"license": "MIT",
"dependencies": {
- "@tdengine/client": "^3.0.0",
+ "@tdengine/client": "^3.0.1",
"@tdengine/rest": "^3.0.0"
}
}
diff --git a/docs/zh/07-develop/02-model/index.mdx b/docs/zh/07-develop/02-model/index.mdx
index be545e8813..1609eb5362 100644
--- a/docs/zh/07-develop/02-model/index.mdx
+++ b/docs/zh/07-develop/02-model/index.mdx
@@ -11,10 +11,10 @@ TDengine 采用类关系型数据模型,需要建库、建表。因此对于
不同类型的数据采集点往往具有不同的数据特征,包括数据采集频率的高低,数据保留时间的长短,副本的数目,数据块的大小,是否允许更新数据等等。为了在各种场景下 TDengine 都能最大效率的工作,TDengine 建议将不同数据特征的表创建在不同的库里,因为每个库可以配置不同的存储策略。创建一个库时,除 SQL 标准的选项外,还可以指定保留时长、副本数、缓存大小、时间精度、文件块里最大最小记录条数、是否压缩、一个数据文件覆盖的天数等多种参数。比如:
```sql
-CREATE DATABASE power KEEP 365 DURATION 10 BUFFER 16 VGROUPS 100 WAL 1;
+CREATE DATABASE power KEEP 365 DURATION 10 BUFFER 16 WAL_LEVEL 1;
```
-上述语句将创建一个名为 power 的库,这个库的数据将保留 365 天(超过 365 天将被自动删除),每 10 天一个数据文件,每个 VNODE 的写入内存池的大小为 16 MB,数据库的 VGROUPS 数量,对该数据库入会写 WAL 但不执行 FSYNC。详细的语法及参数请见 [数据库管理](/taos-sql/database) 章节。
+上述语句将创建一个名为 power 的库,这个库的数据将保留 365 天(超过 365 天将被自动删除),每 10 天一个数据文件,每个 VNODE 的写入内存池的大小为 16 MB,对该数据库入会写 WAL 但不执行 FSYNC。详细的语法及参数请见 [数据库管理](/taos-sql/database) 章节。
创建库之后,需要使用 SQL 命令 `USE` 将当前库切换过来,例如:
diff --git a/docs/zh/07-develop/04-query-data/index.mdx b/docs/zh/07-develop/04-query-data/index.mdx
index 68f49d9f2b..2631d147a5 100644
--- a/docs/zh/07-develop/04-query-data/index.mdx
+++ b/docs/zh/07-develop/04-query-data/index.mdx
@@ -54,20 +54,20 @@ Query OK, 2 row(s) in set (0.001100s)
在 TAOS Shell,查找加利福尼亚州所有智能电表采集的电压平均值,并按照 location 分组。
```
-taos> SELECT AVG(voltage) FROM meters GROUP BY location;
- avg(voltage) | location |
-=============================================================
- 222.000000000 | California.LosAngeles |
- 219.200000000 | California.SanFrancisco |
-Query OK, 2 row(s) in set (0.002136s)
+taos> SELECT AVG(voltage), location FROM meters GROUP BY location;
+ avg(voltage) | location |
+===============================================================================================
+ 219.200000000 | California.SanFrancisco |
+ 221.666666667 | California.LosAngeles |
+Query OK, 2 rows in database (0.005995s)
```
### 示例二
-在 TAOS shell, 查找 groupId 为 2 的所有智能电表过去 24 小时的记录条数,电流的最大值。
+在 TAOS shell, 查找 groupId 为 2 的所有智能电表的记录条数,电流的最大值。
```
-taos> SELECT count(*), max(current) FROM meters where groupId = 2 and ts > now - 24h;
+taos> SELECT count(*), max(current) FROM meters where groupId = 2;
cunt(*) | max(current) |
==================================
5 | 13.4 |
@@ -81,40 +81,41 @@ Query OK, 1 row(s) in set (0.002136s)
物联网场景里,经常需要通过降采样(down sampling)将采集的数据按时间段进行聚合。TDengine 提供了一个简便的关键词 interval 让按照时间窗口的查询操作变得极为简单。比如,将智能电表 d1001 采集的电流值每 10 秒钟求和
```
-taos> SELECT sum(current) FROM d1001 INTERVAL(10s);
- ts | sum(current) |
+taos> SELECT _wstart, sum(current) FROM d1001 INTERVAL(10s);
+ _wstart | sum(current) |
======================================================
2018-10-03 14:38:00.000 | 10.300000191 |
2018-10-03 14:38:10.000 | 24.900000572 |
-Query OK, 2 row(s) in set (0.000883s)
+Query OK, 2 rows in database (0.003139s)
```
降采样操作也适用于超级表,比如:将加利福尼亚州所有智能电表采集的电流值每秒钟求和
```
-taos> SELECT SUM(current) FROM meters where location like "California%" INTERVAL(1s);
- ts | sum(current) |
+taos> SELECT _wstart, SUM(current) FROM meters where location like "California%" INTERVAL(1s);
+ _wstart | sum(current) |
======================================================
2018-10-03 14:38:04.000 | 10.199999809 |
- 2018-10-03 14:38:05.000 | 32.900000572 |
+ 2018-10-03 14:38:05.000 | 23.699999809 |
2018-10-03 14:38:06.000 | 11.500000000 |
2018-10-03 14:38:15.000 | 12.600000381 |
- 2018-10-03 14:38:16.000 | 36.000000000 |
-Query OK, 5 row(s) in set (0.001538s)
+ 2018-10-03 14:38:16.000 | 34.400000572 |
+Query OK, 5 rows in database (0.007413s)
```
降采样操作也支持时间偏移,比如:将所有智能电表采集的电流值每秒钟求和,但要求每个时间窗口从 500 毫秒开始
```
-taos> SELECT SUM(current) FROM meters INTERVAL(1s, 500a);
- ts | sum(current) |
+taos> SELECT _wstart, SUM(current) FROM meters INTERVAL(1s, 500a);
+ _wstart | sum(current) |
======================================================
- 2018-10-03 14:38:04.500 | 11.189999809 |
- 2018-10-03 14:38:05.500 | 31.900000572 |
- 2018-10-03 14:38:06.500 | 11.600000000 |
- 2018-10-03 14:38:15.500 | 12.300000381 |
- 2018-10-03 14:38:16.500 | 35.000000000 |
-Query OK, 5 row(s) in set (0.001521s)
+ 2018-10-03 14:38:03.500 | 10.199999809 |
+ 2018-10-03 14:38:04.500 | 10.300000191 |
+ 2018-10-03 14:38:05.500 | 13.399999619 |
+ 2018-10-03 14:38:06.500 | 11.500000000 |
+ 2018-10-03 14:38:14.500 | 12.600000381 |
+ 2018-10-03 14:38:16.500 | 34.400000572 |
+Query OK, 6 rows in database (0.005515s)
```
物联网场景里,每个数据采集点采集数据的时间是难同步的,但很多分析算法(比如 FFT)需要把采集的数据严格按照时间等间隔的对齐,在很多系统里,需要应用自己写程序来处理,但使用 TDengine 的降采样操作就轻松解决。
diff --git a/docs/zh/12-taos-sql/03-table.md b/docs/zh/12-taos-sql/03-table.md
index 1e20f73541..0e104bb7b6 100644
--- a/docs/zh/12-taos-sql/03-table.md
+++ b/docs/zh/12-taos-sql/03-table.md
@@ -110,7 +110,7 @@ alter_table_option: {
对普通表可以进行如下修改操作
1. ADD COLUMN:添加列。
2. DROP COLUMN:删除列。
-3. ODIFY COLUMN:修改列定义,如果数据列的类型是可变长类型,那么可以使用此指令修改其宽度,只能改大,不能改小。
+3. MODIFY COLUMN:修改列定义,如果数据列的类型是可变长类型,那么可以使用此指令修改其宽度,只能改大,不能改小。
4. RENAME COLUMN:修改列名称。
### 增加列
@@ -195,4 +195,4 @@ SHOW CREATE TABLE tb_name;
```
DESCRIBE [db_name.]tb_name;
-```
\ No newline at end of file
+```
diff --git a/docs/zh/14-reference/11-docker/index.md b/docs/zh/14-reference/11-docker/index.md
index c03990ede2..743fc2d32f 100644
--- a/docs/zh/14-reference/11-docker/index.md
+++ b/docs/zh/14-reference/11-docker/index.md
@@ -25,10 +25,11 @@ curl -u root:taosdata -d "show databases" localhost:6041/rest/sql
$ docker exec -it tdengine taos
taos> show databases;
- name | created_time | ntables | vgroups | replica | quorum | days | keep | cache(MB) | blocks | minrows | maxrows | wallevel | fsync | comp | cachelast | precision | update | status |
-====================================================================================================================================================================================================================================================================================
- log | 2022-01-17 13:57:22.270 | 10 | 1 | 1 | 1 | 10 | 30 | 1 | 3 | 100 | 4096 | 1 | 3000 | 2 | 0 | us | 0 | ready |
-Query OK, 1 row(s) in set (0.002843s)
+ name |
+=================================
+ information_schema |
+ performance_schema |
+Query OK, 2 rows in database (0.033802s)
```
因为运行在容器中的 TDengine 服务端使用容器的 hostname 建立连接,使用 taos shell 或者各种连接器(例如 JDBC-JNI)从容器外访问容器内的 TDengine 比较复杂,所以上述方式是访问容器中 TDengine 服务的最简单的方法,适用于一些简单场景。如果在一些复杂场景下想要从容器化使用 taos shell 或者各种连接器访问容器中的 TDengine 服务,请参考下一节。
@@ -45,10 +46,11 @@ docker run -d --name tdengine --network host tdengine/tdengine
$ taos
taos> show dnodes;
- id | end_point | vnodes | cores | status | role | create_time | offline reason |
-======================================================================================================================================
- 1 | myhost:6030 | 1 | 8 | ready | any | 2022-01-17 22:10:32.619 | |
-Query OK, 1 row(s) in set (0.003233s)
+ id | endpoint | vnodes | support_vnodes | status | create_time | note |
+=================================================================================================================================================
+ 1 | vm98:6030 | 0 | 32 | ready | 2022-08-19 14:50:05.337 | |
+Query OK, 1 rows in database (0.010654s)
+
```
## 以指定的 hostname 和 port 启动 TDengine
@@ -59,12 +61,13 @@ Query OK, 1 row(s) in set (0.003233s)
docker run -d \
--name tdengine \
-e TAOS_FQDN=tdengine \
- -p 6030-6049:6030-6049 \
- -p 6030-6049:6030-6049/udp \
+ -p 6030:6030 \
+ -p 6041-6049:6041-6049 \
+ -p 6041-6049:6041-6049/udp \
tdengine/tdengine
```
-上面的命令在容器中启动一个 TDengine 服务,其所监听的 hostname 为 tdengine ,并将容器的 6030 到 6049 端口段映射到主机的 6030 到 6049 端口段 (tcp 和 udp 都需要映射)。如果主机上该端口段已经被占用,可以修改上述命令指定一个主机上空闲的端口段。如果 `rpcForceTcp` 被设置为 `1` ,可以只映射 tcp 协议。
+上面的命令在容器中启动一个 TDengine 服务,其所监听的 hostname 为 tdengine ,并将容器的 6030 端口映射到主机的 6030 端口(TCP,只能映射主机 6030 端口),6041-6049 端口段映射到主机 6041-6049 端口段(tcp 和 udp 都需要映射,如果主机上该端口段已经被占用,可以修改上述命令指定一个主机上空闲的端口段)。
接下来,要确保 "tdengine" 这个 hostname 在 `/etc/hosts` 中可解析。
@@ -103,9 +106,9 @@ taos -h tdengine -P 6030
3. 在同一网络上的另一容器中启动 TDengine 客户端
```shell
- docker run --rm -it --network td-net -e TAOS_FIRST_EP=tdengine tdengine/tdengine taos
+ docker run --rm -it --network td-net -e TAOS_FIRST_EP=tdengine --entrypoint=taos tdengine/tdengine
# or
- #docker run --rm -it --network td-net -e tdengine/tdengine taos -h tdengine
+ #docker run --rm -it --network td-net --entrypoint=taos tdengine/tdengine -h tdengine
```
## 在容器中启动客户端应用
@@ -115,7 +118,7 @@ taos -h tdengine -P 6030
```docker
FROM ubuntu:20.04
RUN apt-get update && apt-get install -y wget
-ENV TDENGINE_VERSION=2.4.0.0
+ENV TDENGINE_VERSION=3.0.0.0
RUN wget -c https://www.taosdata.com/assets-download/TDengine-client-${TDENGINE_VERSION}-Linux-x64.tar.gz \
&& tar xvf TDengine-client-${TDENGINE_VERSION}-Linux-x64.tar.gz \
&& cd TDengine-client-${TDENGINE_VERSION} \
@@ -129,6 +132,14 @@ RUN wget -c https://www.taosdata.com/assets-download/TDengine-client-${TDENGINE_
以下是一个 go 应用程序的示例:
+* 创建 go mod 项目:
+
+```bash
+go mod init app
+```
+
+* 创建 main.go:
+
```go
/*
* In this test program, we'll create a database and insert 4 records then select out.
@@ -212,12 +223,18 @@ func checkErr(err error, prompt string) {
}
```
-如下是完整版本的 dockerfile
+* 更新 go mod
-```docker
-FROM golang:1.17.6-buster as builder
-ENV TDENGINE_VERSION=2.4.0.0
-RUN wget -c https://www.taosdata.com/assets-download/TDengine-client-${TDENGINE_VERSION}-Linux-x64.tar.gz \
+```bash
+go mod tidy
+```
+
+如下是完整版本的 dockerfile:
+
+```dockerfile
+FROM golang:1.19.0-buster as builder
+ENV TDENGINE_VERSION=3.0.0.0
+RUN wget -c https://www.taosdata.com/assets-download/3.0/TDengine-client-${TDENGINE_VERSION}-Linux-x64.tar.gz \
&& tar xvf TDengine-client-${TDENGINE_VERSION}-Linux-x64.tar.gz \
&& cd TDengine-client-${TDENGINE_VERSION} \
&& ./install_client.sh \
@@ -232,8 +249,8 @@ RUN go build
FROM ubuntu:20.04
RUN apt-get update && apt-get install -y wget
-ENV TDENGINE_VERSION=2.4.0.0
-RUN wget -c https://www.taosdata.com/assets-download/TDengine-client-${TDENGINE_VERSION}-Linux-x64.tar.gz \
+ENV TDENGINE_VERSION=3.0.0.0
+RUN wget -c https://www.taosdata.com/assets-download/3.0/TDengine-client-${TDENGINE_VERSION}-Linux-x64.tar.gz \
&& tar xvf TDengine-client-${TDENGINE_VERSION}-Linux-x64.tar.gz \
&& cd TDengine-client-${TDENGINE_VERSION} \
&& ./install_client.sh \
@@ -248,113 +265,112 @@ CMD ["app"]
目前我们已经有了 `main.go`, `go.mod`, `go.sum`, `app.dockerfile`, 现在可以构建出这个应用程序并在 `td-net` 网络上启动它
```shell
-$ docker build -t app -f app.dockerfile
-$ docker run --rm --network td-net app -h tdengine -p 6030
+$ docker build -t app -f app.dockerfile .
+$ docker run --rm --network td-net app app -h tdengine -p 6030
============= args parse result: =============
hostName: tdengine
serverPort: 6030
usr: root
password: taosdata
================================================
-2022-01-17 15:56:55.48 +0000 UTC 0
-2022-01-17 15:56:56.48 +0000 UTC 1
-2022-01-17 15:56:57.48 +0000 UTC 2
-2022-01-17 15:56:58.48 +0000 UTC 3
-2022-01-17 15:58:01.842 +0000 UTC 0
-2022-01-17 15:58:02.842 +0000 UTC 1
-2022-01-17 15:58:03.842 +0000 UTC 2
-2022-01-17 15:58:04.842 +0000 UTC 3
-2022-01-18 01:43:48.029 +0000 UTC 0
-2022-01-18 01:43:49.029 +0000 UTC 1
-2022-01-18 01:43:50.029 +0000 UTC 2
-2022-01-18 01:43:51.029 +0000 UTC 3
+2022-08-19 07:43:51.68 +0000 UTC 0
+2022-08-19 07:43:52.68 +0000 UTC 1
+2022-08-19 07:43:53.68 +0000 UTC 2
+2022-08-19 07:43:54.68 +0000 UTC 3
```
## 用 docker-compose 启动 TDengine 集群
-1. 如下 docker-compose 文件启动一个 2 副本、2 管理节点、2 数据节点以及 1 个 arbitrator 的 TDengine 集群。
+1. 如下 docker-compose 文件启动一个 三节点 TDengine 集群。
- ```docker
- version: "3"
- services:
- arbitrator:
- image: tdengine/tdengine:$VERSION
- command: tarbitrator
- td-1:
- image: tdengine/tdengine:$VERSION
- environment:
- TAOS_FQDN: "td-1"
- TAOS_FIRST_EP: "td-1"
- TAOS_NUM_OF_MNODES: "2"
- TAOS_REPLICA: "2"
- TAOS_ARBITRATOR: arbitrator:6042
- volumes:
- - taosdata-td1:/var/lib/taos/
- - taoslog-td1:/var/log/taos/
- td-2:
- image: tdengine/tdengine:$VERSION
- environment:
- TAOS_FQDN: "td-2"
- TAOS_FIRST_EP: "td-1"
- TAOS_NUM_OF_MNODES: "2"
- TAOS_REPLICA: "2"
- TAOS_ARBITRATOR: arbitrator:6042
- volumes:
- - taosdata-td2:/var/lib/taos/
- - taoslog-td2:/var/log/taos/
- volumes:
- taosdata-td1:
- taoslog-td1:
- taosdata-td2:
- taoslog-td2:
- ```
+```yml
+version: "3"
+services:
+ td-1:
+ image: tdengine/tdengine:$VERSION
+ environment:
+ TAOS_FQDN: "td-1"
+ TAOS_FIRST_EP: "td-1"
+ volumes:
+ - taosdata-td1:/var/lib/taos/
+ - taoslog-td1:/var/log/taos/
+ td-2:
+ image: tdengine/tdengine:$VERSION
+ environment:
+ TAOS_FQDN: "td-2"
+ TAOS_FIRST_EP: "td-1"
+ volumes:
+ - taosdata-td2:/var/lib/taos/
+ - taoslog-td2:/var/log/taos/
+ td-3:
+ image: tdengine/tdengine:$VERSION
+ environment:
+ TAOS_FQDN: "td-3"
+ TAOS_FIRST_EP: "td-1"
+ volumes:
+ - taosdata-td3:/var/lib/taos/
+ - taoslog-td3:/var/log/taos/
+volumes:
+ taosdata-td1:
+ taoslog-td1:
+ taosdata-td2:
+ taoslog-td2:
+ taosdata-td3:
+ taoslog-td3:
+```
:::note
-- `VERSION` 环境变量被用来设置 tdengine image tag
-- 在新创建的实例上必须设置 `TAOS_FIRST_EP` 以使其能够加入 TDengine 集群;如果有高可用需求,则需要同时使用 `TAOS_SECOND_EP`
-- `TAOS_REPLICA` 用来设置缺省的数据库副本数量,其取值范围为[1,3]
- 在双副本环境下,推荐使用 arbitrator, 用 TAOS_ARBITRATOR 来设置
- :::
+* `VERSION` 环境变量被用来设置 tdengine image tag
+* 在新创建的实例上必须设置 `TAOS_FIRST_EP` 以使其能够加入 TDengine 集群;如果有高可用需求,则需要同时使用 `TAOS_SECOND_EP`
+:::
2. 启动集群
- ```shell
- $ VERSION=2.4.0.0 docker-compose up -d
- Creating network "test_default" with the default driver
- Creating volume "test_taosdata-td1" with default driver
- Creating volume "test_taoslog-td1" with default driver
- Creating volume "test_taosdata-td2" with default driver
- Creating volume "test_taoslog-td2" with default driver
- Creating test_td-1_1 ... done
- Creating test_arbitrator_1 ... done
- Creating test_td-2_1 ... done
- ```
+```shell
+$ VERSION=3.0.0.0 docker-compose up -d
+Creating network "test-docker_default" with the default driver
+Creating volume "test-docker_taosdata-td1" with default driver
+Creating volume "test-docker_taoslog-td1" with default driver
+Creating volume "test-docker_taosdata-td2" with default driver
+Creating volume "test-docker_taoslog-td2" with default driver
+Creating volume "test-docker_taosdata-td3" with default driver
+Creating volume "test-docker_taoslog-td3" with default driver
+
+Creating test-docker_td-3_1 ... done
+Creating test-docker_td-1_1 ... done
+Creating test-docker_td-2_1 ... done
+```
3. 查看节点状态
- ```shell
- $ docker-compose ps
- Name Command State Ports
- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- test_arbitrator_1 /usr/bin/entrypoint.sh tar ... Up 6030/tcp, 6031/tcp, 6032/tcp, 6033/tcp, 6034/tcp, 6035/tcp, 6036/tcp, 6037/tcp, 6038/tcp, 6039/tcp, 6040/tcp, 6041/tcp, 6042/tcp
- test_td-1_1 /usr/bin/entrypoint.sh taosd Up 6030/tcp, 6031/tcp, 6032/tcp, 6033/tcp, 6034/tcp, 6035/tcp, 6036/tcp, 6037/tcp, 6038/tcp, 6039/tcp, 6040/tcp, 6041/tcp, 6042/tcp
- test_td-2_1 /usr/bin/entrypoint.sh taosd Up 6030/tcp, 6031/tcp, 6032/tcp, 6033/tcp, 6034/tcp, 6035/tcp, 6036/tcp, 6037/tcp, 6038/tcp, 6039/tcp, 6040/tcp, 6041/tcp, 6042/tcp
- ```
+```shell
+ docker-compose ps
+ Name Command State Ports
+
+-------------------------------------------------------------------
+test-docker_td-1_1 /tini -- /usr/bin/entrypoi ... Up
+test-docker_td-2_1 /tini -- /usr/bin/entrypoi ... Up
+test-docker_td-3_1 /tini -- /usr/bin/entrypoi ... Up
+```
4. 用 taos shell 查看 dnodes
- ```shell
- $ docker-compose exec td-1 taos -s "show dnodes"
+```shell
- taos> show dnodes
- id | end_point | vnodes | cores | status | role | create_time | offline reason |
- ======================================================================================================================================
- 1 | td-1:6030 | 1 | 8 | ready | any | 2022-01-18 02:47:42.871 | |
- 2 | td-2:6030 | 0 | 8 | ready | any | 2022-01-18 02:47:43.518 | |
- 0 | arbitrator:6042 | 0 | 0 | ready | arb | 2022-01-18 02:47:43.633 | - |
- Query OK, 3 row(s) in set (0.000811s)
- ```
+$ docker-compose exec td-1 taos -s "show dnodes"
+
+taos> show dnodes
+
+ id | endpoint | vnodes | support_vnodes | status | create_time | note |
+=================================================================================================================================================
+
+ 1 | td-1:6030 | 0 | 32 | ready | 2022-08-19 07:57:29.971 | |
+ 2 | td-2:6030 | 0 | 32 | ready | 2022-08-19 07:57:31.415 | |
+ 3 | td-3:6030 | 0 | 32 | ready | 2022-08-19 07:57:31.417 | |
+Query OK, 3 rows in database (0.021262s)
+
+```
## taosAdapter
@@ -362,93 +378,80 @@ password: taosdata
2. 同时为了部署灵活起见,可以在独立的容器中启动 taosAdapter
- ```docker
- services:
- # ...
- adapter:
- image: tdengine/tdengine:$VERSION
- command: taosadapter
- ```
+```docker
+services:
+ # ...
+ adapter:
+ image: tdengine/tdengine:$VERSION
+ command: taosadapter
+```
- 如果要部署多个 taosAdapter 来提高吞吐量并提供高可用性,推荐配置方式为使用 nginx 等反向代理来提供统一的访问入口。具体配置方法请参考 nginx 的官方文档。如下是示例:
+如果要部署多个 taosAdapter 来提高吞吐量并提供高可用性,推荐配置方式为使用 nginx 等反向代理来提供统一的访问入口。具体配置方法请参考 nginx 的官方文档。如下是示例:
- ```docker
- version: "3"
+```yml
+version: "3"
- networks:
- inter:
- api:
+networks:
+ inter:
- services:
- arbitrator:
- image: tdengine/tdengine:$VERSION
- command: tarbitrator
- networks:
- - inter
- td-1:
- image: tdengine/tdengine:$VERSION
- networks:
- - inter
- environment:
- TAOS_FQDN: "td-1"
- TAOS_FIRST_EP: "td-1"
- TAOS_NUM_OF_MNODES: "2"
- TAOS_REPLICA: "2"
- TAOS_ARBITRATOR: arbitrator:6042
- volumes:
- - taosdata-td1:/var/lib/taos/
- - taoslog-td1:/var/log/taos/
- td-2:
- image: tdengine/tdengine:$VERSION
- networks:
- - inter
- environment:
- TAOS_FQDN: "td-2"
- TAOS_FIRST_EP: "td-1"
- TAOS_NUM_OF_MNODES: "2"
- TAOS_REPLICA: "2"
- TAOS_ARBITRATOR: arbitrator:6042
- volumes:
- - taosdata-td2:/var/lib/taos/
- - taoslog-td2:/var/log/taos/
- adapter:
- image: tdengine/tdengine:$VERSION
- command: taosadapter
- networks:
- - inter
- environment:
- TAOS_FIRST_EP: "td-1"
- TAOS_SECOND_EP: "td-2"
- deploy:
- replicas: 4
- nginx:
- image: nginx
- depends_on:
- - adapter
- networks:
- - inter
- - api
- ports:
- - 6041:6041
- - 6044:6044/udp
- command: [
- "sh",
- "-c",
- "while true;
- do curl -s http://adapter:6041/-/ping >/dev/null && break;
- done;
- printf 'server{listen 6041;location /{proxy_pass http://adapter:6041;}}'
- > /etc/nginx/conf.d/rest.conf;
- printf 'stream{server{listen 6044 udp;proxy_pass adapter:6044;}}'
- >> /etc/nginx/nginx.conf;cat /etc/nginx/nginx.conf;
- nginx -g 'daemon off;'",
- ]
- volumes:
- taosdata-td1:
- taoslog-td1:
- taosdata-td2:
- taoslog-td2:
- ```
+services:
+ td-1:
+ image: tdengine/tdengine:$VERSION
+ networks:
+ - inter
+ environment:
+ TAOS_FQDN: "td-1"
+ TAOS_FIRST_EP: "td-1"
+ volumes:
+ - taosdata-td1:/var/lib/taos/
+ - taoslog-td1:/var/log/taos/
+ td-2:
+ image: tdengine/tdengine:$VERSION
+ networks:
+ - inter
+ environment:
+ TAOS_FQDN: "td-2"
+ TAOS_FIRST_EP: "td-1"
+ volumes:
+ - taosdata-td2:/var/lib/taos/
+ - taoslog-td2:/var/log/taos/
+ adapter:
+ image: tdengine/tdengine:$VERSION
+ entrypoint: "taosadapter"
+ networks:
+ - inter
+ environment:
+ TAOS_FIRST_EP: "td-1"
+ TAOS_SECOND_EP: "td-2"
+ deploy:
+ replicas: 4
+ nginx:
+ image: nginx
+ depends_on:
+ - adapter
+ networks:
+ - inter
+ ports:
+ - 6041:6041
+ - 6044:6044/udp
+ command: [
+ "sh",
+ "-c",
+ "while true;
+ do curl -s http://adapter:6041/-/ping >/dev/null && break;
+ done;
+ printf 'server{listen 6041;location /{proxy_pass http://adapter:6041;}}'
+ > /etc/nginx/conf.d/rest.conf;
+ printf 'stream{server{listen 6044 udp;proxy_pass adapter:6044;}}'
+ >> /etc/nginx/nginx.conf;cat /etc/nginx/nginx.conf;
+ nginx -g 'daemon off;'",
+ ]
+volumes:
+ taosdata-td1:
+ taoslog-td1:
+ taosdata-td2:
+ taoslog-td2:
+```
## 使用 docker swarm 部署
@@ -457,50 +460,46 @@ password: taosdata
docker-compose 文件可以参考上节。下面是使用 docker swarm 启动 TDengine 的命令:
```shell
-$ VERSION=2.4.0 docker stack deploy -c docker-compose.yml taos
+$ VERSION=3.0.0.0 docker stack deploy -c docker-compose.yml taos
Creating network taos_inter
-Creating network taos_api
-Creating service taos_arbitrator
+Creating service taos_nginx
Creating service taos_td-1
Creating service taos_td-2
Creating service taos_adapter
-Creating service taos_nginx
```
查看和管理
```shell
$ docker stack ps taos
-ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
-79ni8temw59n taos_nginx.1 nginx:latest TM1701 Running Running about a minute ago
-3e94u72msiyg taos_adapter.1 tdengine/tdengine:2.4.0 TM1702 Running Running 56 seconds ago
-100amjkwzsc6 taos_td-2.1 tdengine/tdengine:2.4.0 TM1703 Running Running about a minute ago
-pkjehr2vvaaa taos_td-1.1 tdengine/tdengine:2.4.0 TM1704 Running Running 2 minutes ago
-tpzvgpsr1qkt taos_arbitrator.1 tdengine/tdengine:2.4.0 TM1705 Running Running 2 minutes ago
-rvss3g5yg6fa taos_adapter.2 tdengine/tdengine:2.4.0 TM1706 Running Running 56 seconds ago
-i2augxamfllf taos_adapter.3 tdengine/tdengine:2.4.0 TM1707 Running Running 56 seconds ago
-lmjyhzccpvpg taos_adapter.4 tdengine/tdengine:2.4.0 TM1708 Running Running 56 seconds ago
+ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
+7m3sbf532bqp taos_adapter.1 tdengine/tdengine:3.0.0.0 vm98 Running Running about a minute ago
+pj403n6ofmmh taos_adapter.2 tdengine/tdengine:3.0.0.0 vm98 Running Running about a minute ago
+rxqfwsyk5q1h taos_adapter.3 tdengine/tdengine:3.0.0.0 vm98 Running Running about a minute ago
+qj40lpxr40oc taos_adapter.4 tdengine/tdengine:3.0.0.0 vm98 Running Running about a minute ago
+oe3455ulxpze taos_nginx.1 nginx:latest vm98 Running Running about a minute ago
+o0tsg70nrrc6 taos_td-1.1 tdengine/tdengine:3.0.0.0 vm98 Running Running about a minute ago
+q5m1oxs589cp taos_td-2.1 tdengine/tdengine:3.0.0.0 vm98 Running Running about a minute ago
$ docker service ls
-ID NAME MODE REPLICAS IMAGE PORTS
-561t4lu6nfw6 taos_adapter replicated 4/4 tdengine/tdengine:2.4.0
-3hk5ct3q90sm taos_arbitrator replicated 1/1 tdengine/tdengine:2.4.0
-d8qr52envqzu taos_nginx replicated 1/1 nginx:latest *:6041->6041/tcp, *:6044->6044/udp
-2isssfvjk747 taos_td-1 replicated 1/1 tdengine/tdengine:2.4.0
-9pzw7u02ichv taos_td-2 replicated 1/1 tdengine/tdengine:2.4.0
+ID NAME MODE REPLICAS IMAGE PORTS
+ozuklorgl8bs taos_adapter replicated 4/4 tdengine/tdengine:3.0.0.0
+crmhdjw6vxw0 taos_nginx replicated 1/1 nginx:latest *:6041->6041/tcp, *:6044->6044/udp
+o86ngy7csv5n taos_td-1 replicated 1/1 tdengine/tdengine:3.0.0.0
+rma040ny4tb0 taos_td-2 replicated 1/1 tdengine/tdengine:3.0.0.0
```
-从上面的输出可以看到有两个 dnode, 和两个 taosAdapter,以及一个 nginx 反向代理服务。
+从上面的输出可以看到有两个 dnode, 和四个 taosAdapter,以及一个 nginx 反向代理服务。
接下来,我们可以减少 taosAdapter 服务的数量
```shell
$ docker service scale taos_adapter=1
taos_adapter scaled to 1
-overall progress: 1 out of 1 tasks
-1/1: running [==================================================>]
+overall progress: 1 out of 1 tasks
+1/1: running [==================================================>]
verify: Service converged
$ docker service ls -f name=taos_adapter
-ID NAME MODE REPLICAS IMAGE PORTS
-561t4lu6nfw6 taos_adapter replicated 1/1 tdengine/tdengine:2.4.0
+ID NAME MODE REPLICAS IMAGE PORTS
+ozuklorgl8bs taos_adapter replicated 1/1 tdengine/tdengine:3.0.0.0
```
diff --git a/docs/zh/17-operation/03-tolerance.md b/docs/zh/17-operation/03-tolerance.md
index 2cfd4b6484..1ce485b042 100644
--- a/docs/zh/17-operation/03-tolerance.md
+++ b/docs/zh/17-operation/03-tolerance.md
@@ -26,5 +26,3 @@ TDengine 集群中的时序数据的副本数是与数据库关联的,一个
TDengine 集群的节点数必须大于等于副本数,否则创建表时将报错。
当 TDengine 集群中的节点部署在不同的物理机上,并设置多个副本数时,就实现了系统的高可靠性,无需再使用其他软件或工具。TDengine 企业版还可以将副本部署在不同机房,从而实现异地容灾。
-
-另外一种灾备方式是通过 `taosX` 将一个 TDengine 集群的数据同步复制到物理上位于不同数据中心的另一个 TDengine 集群。其详细使用方法请参考 [taosX 参考手册](../../reference/taosX)
diff --git a/examples/c/stream_demo.c b/examples/c/stream_demo.c
index dd4fbc8d2d..2fcf4dd62c 100644
--- a/examples/c/stream_demo.c
+++ b/examples/c/stream_demo.c
@@ -98,10 +98,9 @@ int32_t create_stream() {
/*const char* sql = "select min(k), max(k), sum(k) as sum_of_k from st1";*/
/*const char* sql = "select sum(k) from tu1 interval(10m)";*/
/*pRes = tmq_create_stream(pConn, "stream1", "out1", sql);*/
- pRes =
- taos_query(pConn,
- "create stream stream1 trigger max_delay 10s into outstb as select _wstart, sum(k) from st1 partition "
- "by tbname session(ts, 10s) ");
+ pRes = taos_query(pConn,
+ "create stream stream1 trigger max_delay 10s watermark 10s into outstb as select _wstart start, "
+ "count(k) from st1 partition by tbname interval(20s) ");
if (taos_errno(pRes) != 0) {
printf("failed to create stream stream1, reason:%s\n", taos_errstr(pRes));
return -1;
diff --git a/include/common/tcommon.h b/include/common/tcommon.h
index e04d9d5e86..dbe020f7ec 100644
--- a/include/common/tcommon.h
+++ b/include/common/tcommon.h
@@ -60,6 +60,7 @@ enum {
STREAM_INPUT__DATA_RETRIEVE,
STREAM_INPUT__GET_RES,
STREAM_INPUT__CHECKPOINT,
+ STREAM_INPUT__DESTROY,
};
typedef enum EStreamType {
diff --git a/include/common/tdataformat.h b/include/common/tdataformat.h
index 3679b3773b..af7c88acde 100644
--- a/include/common/tdataformat.h
+++ b/include/common/tdataformat.h
@@ -38,22 +38,18 @@ typedef struct STagVal STagVal;
typedef struct STag STag;
// bitmap
-#define N1(n) ((1 << (n)) - 1)
-#define BIT1_SIZE(n) (((n)-1) / 8 + 1)
-#define BIT2_SIZE(n) (((n)-1) / 4 + 1)
-#define SET_BIT1(p, i, v) \
- do { \
- (p)[(i) / 8] &= N1((i) % 8); \
- (p)[(i) / 8] |= (((uint8_t)(v)) << (((i) % 8))); \
- } while (0)
+const static uint8_t BIT2_MAP[4][4] = {{0b00000000, 0b00000001, 0b00000010, 0},
+ {0b00000000, 0b00000100, 0b00001000, 2},
+ {0b00000000, 0b00010000, 0b00100000, 4},
+ {0b00000000, 0b01000000, 0b10000000, 6}};
-#define GET_BIT1(p, i) (((p)[(i) / 8] >> ((i) % 8)) & ((uint8_t)1))
-#define SET_BIT2(p, i, v) \
- do { \
- p[(i) / 4] &= N1((i) % 4 * 2); \
- (p)[(i) / 4] |= (((uint8_t)(v)) << (((i) % 4) * 2)); \
- } while (0)
-#define GET_BIT2(p, i) (((p)[(i) / 4] >> (((i) % 4) * 2)) & ((uint8_t)3))
+#define N1(n) ((((uint8_t)1) << (n)) - 1)
+#define BIT1_SIZE(n) ((((n)-1) >> 3) + 1)
+#define BIT2_SIZE(n) ((((n)-1) >> 2) + 1)
+#define SET_BIT1(p, i, v) ((p)[(i) >> 3] = (p)[(i) >> 3] & N1((i)&7) | (((uint8_t)(v)) << ((i)&7)))
+#define GET_BIT1(p, i) (((p)[(i) >> 3] >> ((i)&7)) & ((uint8_t)1))
+#define SET_BIT2(p, i, v) ((p)[(i) >> 2] = (p)[(i) >> 2] & N1(BIT2_MAP[(i)&3][3]) | BIT2_MAP[(i)&3][(v)])
+#define GET_BIT2(p, i) (((p)[(i) >> 2] >> BIT2_MAP[(i)&3][3]) & ((uint8_t)3))
// STSchema
int32_t tTSchemaCreate(int32_t sver, SSchema *pSchema, int32_t nCols, STSchema **ppTSchema);
@@ -171,7 +167,7 @@ struct SColVal {
#pragma pack(push, 1)
struct STagVal {
-// char colName[TSDB_COL_NAME_LEN]; // only used for tmq_get_meta
+ // char colName[TSDB_COL_NAME_LEN]; // only used for tmq_get_meta
union {
int16_t cid;
char *pKey;
diff --git a/include/common/tmsg.h b/include/common/tmsg.h
index fa6f4b6c79..8f199c72f7 100644
--- a/include/common/tmsg.h
+++ b/include/common/tmsg.h
@@ -2664,29 +2664,8 @@ typedef struct {
} SVgEpSet;
typedef struct {
- int64_t suid;
- int8_t level;
-} SRSmaFetchMsg;
-
-static FORCE_INLINE int32_t tEncodeSRSmaFetchMsg(SEncoder* pCoder, const SRSmaFetchMsg* pReq) {
- if (tStartEncode(pCoder) < 0) return -1;
-
- if (tEncodeI64(pCoder, pReq->suid) < 0) return -1;
- if (tEncodeI8(pCoder, pReq->level) < 0) return -1;
-
- tEndEncode(pCoder);
- return 0;
-}
-
-static FORCE_INLINE int32_t tDecodeSRSmaFetchMsg(SDecoder* pCoder, SRSmaFetchMsg* pReq) {
- if (tStartDecode(pCoder) < 0) return -1;
-
- if (tDecodeI64(pCoder, &pReq->suid) < 0) return -1;
- if (tDecodeI8(pCoder, &pReq->level) < 0) return -1;
-
- tEndDecode(pCoder);
- return 0;
-}
+ int32_t padding;
+} SRSmaExecMsg;
typedef struct {
int8_t version; // for compatibility(default 0)
diff --git a/include/common/tmsgdef.h b/include/common/tmsgdef.h
index b16df0e885..e2bb3e2ae1 100644
--- a/include/common/tmsgdef.h
+++ b/include/common/tmsgdef.h
@@ -201,7 +201,8 @@ enum {
TD_DEF_MSG_TYPE(TDMT_VND_CANCEL_SMA, "vnode-cancel-sma", NULL, NULL)
TD_DEF_MSG_TYPE(TDMT_VND_DROP_SMA, "vnode-drop-sma", NULL, NULL)
TD_DEF_MSG_TYPE(TDMT_VND_SUBMIT_RSMA, "vnode-submit-rsma", SSubmitReq, SSubmitRsp)
- TD_DEF_MSG_TYPE(TDMT_VND_FETCH_RSMA, "vnode-fetch-rsma", SRSmaFetchMsg, NULL)
+ TD_DEF_MSG_TYPE(TDMT_VND_FETCH_RSMA, "vnode-fetch-rsma", NULL, NULL)
+ TD_DEF_MSG_TYPE(TDMT_VND_EXEC_RSMA, "vnode-exec-rsma", NULL, NULL)
TD_DEF_MSG_TYPE(TDMT_VND_DELETE, "delete-data", SVDeleteReq, SVDeleteRsp)
TD_DEF_MSG_TYPE(TDMT_VND_BATCH_DEL, "batch-delete", SBatchDeleteReq, NULL)
TD_DEF_MSG_TYPE(TDMT_VND_ALTER_CONFIG, "alter-config", NULL, NULL)
diff --git a/include/libs/nodes/nodes.h b/include/libs/nodes/nodes.h
index bb75efa00a..5743d33608 100644
--- a/include/libs/nodes/nodes.h
+++ b/include/libs/nodes/nodes.h
@@ -105,7 +105,7 @@ typedef enum ENodeType {
QUERY_NODE_COLUMN_REF,
// Statement nodes are used in parser and planner module.
- QUERY_NODE_SET_OPERATOR,
+ QUERY_NODE_SET_OPERATOR = 100,
QUERY_NODE_SELECT_STMT,
QUERY_NODE_VNODE_MODIF_STMT,
QUERY_NODE_CREATE_DATABASE_STMT,
@@ -198,7 +198,7 @@ typedef enum ENodeType {
QUERY_NODE_QUERY,
// logic plan node
- QUERY_NODE_LOGIC_PLAN_SCAN,
+ QUERY_NODE_LOGIC_PLAN_SCAN = 1000,
QUERY_NODE_LOGIC_PLAN_JOIN,
QUERY_NODE_LOGIC_PLAN_AGG,
QUERY_NODE_LOGIC_PLAN_PROJECT,
@@ -215,7 +215,7 @@ typedef enum ENodeType {
QUERY_NODE_LOGIC_PLAN,
// physical plan node
- QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN,
+ QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN = 1100,
QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN,
QUERY_NODE_PHYSICAL_PLAN_TABLE_SEQ_SCAN,
QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN,
diff --git a/include/libs/nodes/querynodes.h b/include/libs/nodes/querynodes.h
index 088da73a1a..e1f86bae58 100644
--- a/include/libs/nodes/querynodes.h
+++ b/include/libs/nodes/querynodes.h
@@ -428,6 +428,9 @@ void nodesValueNodeToVariant(const SValueNode* pNode, SVariant* pVal);
char* nodesGetFillModeString(EFillMode mode);
int32_t nodesMergeConds(SNode** pDst, SNodeList** pSrc);
+const char* operatorTypeStr(EOperatorType type);
+const char* logicConditionTypeStr(ELogicConditionType type);
+
#ifdef __cplusplus
}
#endif
diff --git a/include/libs/stream/tstream.h b/include/libs/stream/tstream.h
index e6fcb021d5..384c6a289f 100644
--- a/include/libs/stream/tstream.h
+++ b/include/libs/stream/tstream.h
@@ -53,6 +53,7 @@ enum {
TASK_SCHED_STATUS__WAITING,
TASK_SCHED_STATUS__ACTIVE,
TASK_SCHED_STATUS__FAILED,
+ TASK_SCHED_STATUS__DROPPING,
};
enum {
@@ -127,6 +128,10 @@ typedef struct {
int8_t type;
} SStreamCheckpoint;
+typedef struct {
+ int8_t type;
+} SStreamTaskDestroy;
+
typedef struct {
int8_t type;
SSDataBlock* pBlock;
@@ -211,7 +216,6 @@ typedef struct {
void* vnode;
FTbSink* tbSinkFunc;
STSchema* pTSchema;
- SHashObj* pHash; // groupId to tbuid
} STaskSinkTb;
typedef void FSmaSink(void* vnode, int64_t smaId, const SArray* data);
diff --git a/include/libs/sync/sync.h b/include/libs/sync/sync.h
index 952066df46..e6a4dd1d49 100644
--- a/include/libs/sync/sync.h
+++ b/include/libs/sync/sync.h
@@ -33,7 +33,8 @@ extern bool gRaftDetailLog;
#define SYNC_MAX_READ_RANGE 2
#define SYNC_MAX_PROGRESS_WAIT_MS 4000
#define SYNC_MAX_START_TIME_RANGE_MS (1000 * 20)
-#define SYNC_MAX_RECV_TIME_RANGE_MS 1000
+#define SYNC_MAX_RECV_TIME_RANGE_MS 1200
+#define SYNC_ADD_QUORUM_COUNT 3
#define SYNC_MAX_BATCH_SIZE 1
#define SYNC_INDEX_BEGIN 0
diff --git a/include/util/taoserror.h b/include/util/taoserror.h
index d7ec3697af..12d6127165 100644
--- a/include/util/taoserror.h
+++ b/include/util/taoserror.h
@@ -291,6 +291,7 @@ int32_t* taosGetErrno();
#define TSDB_CODE_MND_STREAM_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x03F1)
#define TSDB_CODE_MND_INVALID_STREAM_OPTION TAOS_DEF_ERROR_CODE(0, 0x03F2)
#define TSDB_CODE_MND_STREAM_MUST_BE_DELETED TAOS_DEF_ERROR_CODE(0, 0x03F3)
+#define TSDB_CODE_MND_STREAM_TASK_DROPPED TAOS_DEF_ERROR_CODE(0, 0x03F4)
// mnode-sma
#define TSDB_CODE_MND_SMA_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x0480)
@@ -614,6 +615,7 @@ int32_t* taosGetErrno();
#define TSDB_CODE_RSMA_REMOVE_EXISTS TAOS_DEF_ERROR_CODE(0, 0x3154)
#define TSDB_CODE_RSMA_FETCH_MSG_MSSED_UP TAOS_DEF_ERROR_CODE(0, 0x3155)
#define TSDB_CODE_RSMA_EMPTY_INFO TAOS_DEF_ERROR_CODE(0, 0x3156)
+#define TSDB_CODE_RSMA_INVALID_SCHEMA TAOS_DEF_ERROR_CODE(0, 0x3157)
//index
#define TSDB_CODE_INDEX_REBUILDING TAOS_DEF_ERROR_CODE(0, 0x3200)
diff --git a/include/util/tdef.h b/include/util/tdef.h
index a3deb73fd4..6ce1571656 100644
--- a/include/util/tdef.h
+++ b/include/util/tdef.h
@@ -132,15 +132,14 @@ typedef enum EOperatorType {
OP_TYPE_DIV,
OP_TYPE_REM,
// unary arithmetic operator
- OP_TYPE_MINUS,
- OP_TYPE_ASSIGN,
+ OP_TYPE_MINUS = 20,
// bitwise operator
- OP_TYPE_BIT_AND,
+ OP_TYPE_BIT_AND = 30,
OP_TYPE_BIT_OR,
// binary comparison operator
- OP_TYPE_GREATER_THAN,
+ OP_TYPE_GREATER_THAN = 40,
OP_TYPE_GREATER_EQUAL,
OP_TYPE_LOWER_THAN,
OP_TYPE_LOWER_EQUAL,
@@ -153,7 +152,7 @@ typedef enum EOperatorType {
OP_TYPE_MATCH,
OP_TYPE_NMATCH,
// unary comparison operator
- OP_TYPE_IS_NULL,
+ OP_TYPE_IS_NULL = 100,
OP_TYPE_IS_NOT_NULL,
OP_TYPE_IS_TRUE,
OP_TYPE_IS_FALSE,
@@ -163,8 +162,11 @@ typedef enum EOperatorType {
OP_TYPE_IS_NOT_UNKNOWN,
// json operator
- OP_TYPE_JSON_GET_VALUE,
- OP_TYPE_JSON_CONTAINS
+ OP_TYPE_JSON_GET_VALUE = 150,
+ OP_TYPE_JSON_CONTAINS,
+
+ // internal operator
+ OP_TYPE_ASSIGN = 200
} EOperatorType;
#define OP_TYPE_CALC_MAX OP_TYPE_BIT_OR
diff --git a/include/util/tqueue.h b/include/util/tqueue.h
index 0f4f1db9ee..da409a90bb 100644
--- a/include/util/tqueue.h
+++ b/include/util/tqueue.h
@@ -76,6 +76,7 @@ void taosFreeQall(STaosQall *qall);
int32_t taosReadAllQitems(STaosQueue *queue, STaosQall *qall);
int32_t taosGetQitem(STaosQall *qall, void **ppItem);
void taosResetQitems(STaosQall *qall);
+int32_t taosQallItemSize(STaosQall *qall);
STaosQset *taosOpenQset();
void taosCloseQset(STaosQset *qset);
diff --git a/packaging/tools/make_install.bat b/packaging/tools/make_install.bat
index 0f9e836ae2..d4dde391c8 100644
--- a/packaging/tools/make_install.bat
+++ b/packaging/tools/make_install.bat
@@ -1,7 +1,57 @@
@echo off
goto %1
:needAdmin
+
+if exist C:\\TDengine\\data\\dnode\\dnodeCfg.json (
+ echo The default data directory C:/TDengine/data contains old data of tdengine 2.x, please clear it before installing!
+)
+set source_dir=%2
+set source_dir=%source_dir:/=\\%
+set binary_dir=%3
+set binary_dir=%binary_dir:/=\\%
+set osType=%4
+set verNumber=%5
+set tagert_dir=C:\\TDengine
+
+if not exist %tagert_dir% (
+ mkdir %tagert_dir%
+)
+if not exist %tagert_dir%\\cfg (
+ mkdir %tagert_dir%\\cfg
+)
+if not exist %tagert_dir%\\include (
+ mkdir %tagert_dir%\\include
+)
+if not exist %tagert_dir%\\driver (
+ mkdir %tagert_dir%\\driver
+)
+if not exist C:\\TDengine\\cfg\\taos.cfg (
+ copy %source_dir%\\packaging\\cfg\\taos.cfg %tagert_dir%\\cfg\\taos.cfg > nul
+)
+
+if exist %binary_dir%\\test\\cfg\\taosadapter.toml (
+ if not exist %tagert_dir%\\cfg\\taosadapter.toml (
+ copy %binary_dir%\\test\\cfg\\taosadapter.toml %tagert_dir%\\cfg\\taosadapter.toml > nul
+ )
+)
+
+copy %source_dir%\\include\\client\\taos.h %tagert_dir%\\include > nul
+copy %source_dir%\\include\\util\\taoserror.h %tagert_dir%\\include > nul
+copy %source_dir%\\include\\libs\\function\\taosudf.h %tagert_dir%\\include > nul
+copy %binary_dir%\\build\\lib\\taos.lib %tagert_dir%\\driver > nul
+copy %binary_dir%\\build\\lib\\taos_static.lib %tagert_dir%\\driver > nul
+copy %binary_dir%\\build\\lib\\taos.dll %tagert_dir%\\driver > nul
+copy %binary_dir%\\build\\bin\\taos.exe %tagert_dir% > nul
+copy %binary_dir%\\build\\bin\\taosd.exe %tagert_dir% > nul
+copy %binary_dir%\\build\\bin\\udfd.exe %tagert_dir% > nul
+if exist %binary_dir%\\build\\bin\\taosBenchmark.exe (
+ copy %binary_dir%\\build\\bin\\taosBenchmark.exe %tagert_dir% > nul
+)
+if exist %binary_dir%\\build\\bin\\taosadapter.exe (
+ copy %binary_dir%\\build\\bin\\taosadapter.exe %tagert_dir% > nul
+)
+
mshta vbscript:createobject("shell.application").shellexecute("%~s0",":hasAdmin","","runas",1)(window.close)&& echo To start/stop TDengine with administrator privileges: sc start/stop taosd &goto :eof
:hasAdmin
-cp -f C:\\TDengine\\driver\\taos.dll C:\\Windows\\System32
+copy /y C:\\TDengine\\driver\\taos.dll C:\\Windows\\System32 > nul
sc query "taosd" >nul || sc create "taosd" binPath= "C:\\TDengine\\taosd.exe --win_service" start= DEMAND
diff --git a/packaging/tools/make_install.sh b/packaging/tools/make_install.sh
index d8d4c5bf2a..6a95ace99e 100755
--- a/packaging/tools/make_install.sh
+++ b/packaging/tools/make_install.sh
@@ -664,7 +664,9 @@ function install_TDengine() {
## ==============================Main program starts from here============================
echo source directory: $1
echo binary directory: $2
-if [ "$osType" != "Darwin" ]; then
+if [ -x ${data_dir}/dnode/dnodeCfg.json ]; then
+ echo -e "\033[44;31;5mThe default data directory ${data_dir} contains old data of tdengine 2.x, please clear it before installing!\033[0m"
+elif [ "$osType" != "Darwin" ]; then
if [ -x ${bin_dir}/${clientName} ]; then
update_TDengine
else
diff --git a/source/client/test/clientTests.cpp b/source/client/test/clientTests.cpp
index ec270889e2..4ea5443678 100644
--- a/source/client/test/clientTests.cpp
+++ b/source/client/test/clientTests.cpp
@@ -123,7 +123,7 @@ void createNewTable(TAOS* pConn, int32_t index) {
}
taos_free_result(pRes);
- for(int32_t i = 0; i < 100000; i += 20) {
+ for(int32_t i = 0; i < 3280; i += 20) {
char sql[1024] = {0};
sprintf(sql,
"insert into tu%d values(now+%da, %d)(now+%da, %d)(now+%da, %d)(now+%da, %d)"
@@ -679,30 +679,28 @@ TEST(testCase, projection_query_tables) {
TAOS_RES* pRes = taos_query(pConn, "use abc1");
taos_free_result(pRes);
- pRes = taos_query(pConn, "explain verbose true select _wstart,count(*),a from st1 partition by a interval(1s)");
- printResult(pRes);
-// pRes = taos_query(pConn, "create stable st1 (ts timestamp, k int) tags(a int)");
-// if (taos_errno(pRes) != 0) {
-// printf("failed to create table tu, reason:%s\n", taos_errstr(pRes));
-// }
-// taos_free_result(pRes);
-//
-// pRes = taos_query(pConn, "create stable st2 (ts timestamp, k int) tags(a int)");
-// if (taos_errno(pRes) != 0) {
-// printf("failed to create table tu, reason:%s\n", taos_errstr(pRes));
-// }
-// taos_free_result(pRes);
-//
-// pRes = taos_query(pConn, "create table tu using st1 tags(1)");
-// if (taos_errno(pRes) != 0) {
-// printf("failed to create table tu, reason:%s\n", taos_errstr(pRes));
-// }
-// taos_free_result(pRes);
-//
-// for(int32_t i = 0; i < 1; ++i) {
-// printf("create table :%d\n", i);
-// createNewTable(pConn, i);
-// }
+ pRes = taos_query(pConn, "create stable st1 (ts timestamp, k int) tags(a int)");
+ if (taos_errno(pRes) != 0) {
+ printf("failed to create table tu, reason:%s\n", taos_errstr(pRes));
+ }
+ taos_free_result(pRes);
+
+ pRes = taos_query(pConn, "create stable st2 (ts timestamp, k int) tags(a int)");
+ if (taos_errno(pRes) != 0) {
+ printf("failed to create table tu, reason:%s\n", taos_errstr(pRes));
+ }
+ taos_free_result(pRes);
+
+ pRes = taos_query(pConn, "create table tu using st1 tags(1)");
+ if (taos_errno(pRes) != 0) {
+ printf("failed to create table tu, reason:%s\n", taos_errstr(pRes));
+ }
+ taos_free_result(pRes);
+
+ for(int32_t i = 0; i < 2; ++i) {
+ printf("create table :%d\n", i);
+ createNewTable(pConn, i);
+ }
//
// pRes = taos_query(pConn, "select * from tu");
// if (taos_errno(pRes) != 0) {
diff --git a/source/common/src/systable.c b/source/common/src/systable.c
index 6dddcc2f74..65041e1f12 100644
--- a/source/common/src/systable.c
+++ b/source/common/src/systable.c
@@ -88,7 +88,7 @@ static const SSysDbTableSchema userDBSchema[] = {
{.name = "comp", .bytes = 1, .type = TSDB_DATA_TYPE_TINYINT},
{.name = "precision", .bytes = 2 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR},
{.name = "status", .bytes = 10 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR},
- {.name = "retention", .bytes = 60 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR},
+ {.name = "retentions", .bytes = 60 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR},
{.name = "single_stable", .bytes = 1, .type = TSDB_DATA_TYPE_BOOL},
{.name = "cachemodel", .bytes = TSDB_CACHE_MODEL_STR_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR},
{.name = "cachesize", .bytes = 4, .type = TSDB_DATA_TYPE_INT},
diff --git a/source/common/src/tglobal.c b/source/common/src/tglobal.c
index c763bbed9c..adc5af1a17 100644
--- a/source/common/src/tglobal.c
+++ b/source/common/src/tglobal.c
@@ -75,7 +75,7 @@ int32_t tsMonitorMaxLogs = 100;
bool tsMonitorComp = false;
// telem
-bool tsEnableTelem = false;
+bool tsEnableTelem = true;
int32_t tsTelemInterval = 86400;
char tsTelemServer[TSDB_FQDN_LEN] = "telemetry.taosdata.com";
uint16_t tsTelemPort = 80;
@@ -166,7 +166,7 @@ int32_t tsTtlPushInterval = 86400;
int32_t tsGrantHBInterval = 60;
#ifndef _STORAGE
-int32_t taosSetTfsCfg(SConfig *pCfg) {
+int32_t taosSetTfsCfg(SConfig *pCfg) {
SConfigItem *pItem = cfgGetItem(pCfg, "dataDir");
memset(tsDataDir, 0, PATH_MAX);
@@ -180,7 +180,7 @@ int32_t taosSetTfsCfg(SConfig *pCfg) {
uError("failed to create dataDir:%s", tsDataDir);
return -1;
}
- return 0;
+ return 0;
}
#else
int32_t taosSetTfsCfg(SConfig *pCfg);
diff --git a/source/common/src/ttypes.c b/source/common/src/ttypes.c
index 156b66ae86..fee89e2f37 100644
--- a/source/common/src/ttypes.c
+++ b/source/common/src/ttypes.c
@@ -392,10 +392,10 @@ tDataTypeDescriptor tDataTypes[TSDB_DATA_TYPE_MAX] = {
getStatics_i64},
{TSDB_DATA_TYPE_FLOAT, 5, FLOAT_BYTES, "FLOAT", 0, 0, tsCompressFloat, tsDecompressFloat, getStatics_f},
{TSDB_DATA_TYPE_DOUBLE, 6, DOUBLE_BYTES, "DOUBLE", 0, 0, tsCompressDouble, tsDecompressDouble, getStatics_d},
- {TSDB_DATA_TYPE_VARCHAR, 6, 0, "VARCHAR", 0, 0, tsCompressString, tsDecompressString, getStatics_bin},
+ {TSDB_DATA_TYPE_VARCHAR, 6, 1, "VARCHAR", 0, 0, tsCompressString, tsDecompressString, getStatics_bin},
{TSDB_DATA_TYPE_TIMESTAMP, 9, LONG_BYTES, "TIMESTAMP", INT64_MIN, INT64_MAX, tsCompressTimestamp,
tsDecompressTimestamp, getStatics_i64},
- {TSDB_DATA_TYPE_NCHAR, 5, 8, "NCHAR", 0, 0, tsCompressString, tsDecompressString, getStatics_nchr},
+ {TSDB_DATA_TYPE_NCHAR, 5, 1, "NCHAR", 0, 0, tsCompressString, tsDecompressString, getStatics_nchr},
{TSDB_DATA_TYPE_UTINYINT, 16, CHAR_BYTES, "TINYINT UNSIGNED", 0, UINT8_MAX, tsCompressTinyint, tsDecompressTinyint,
getStatics_u8},
{TSDB_DATA_TYPE_USMALLINT, 17, SHORT_BYTES, "SMALLINT UNSIGNED", 0, UINT16_MAX, tsCompressSmallint,
diff --git a/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c b/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c
index 8eb3ed3901..e610b41a04 100644
--- a/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c
+++ b/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c
@@ -338,6 +338,7 @@ SArray *vmGetMsgHandles() {
if (dmSetMgmtHandle(pArray, TDMT_SCH_MERGE_QUERY, vmPutMsgToQueryQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_SCH_QUERY_CONTINUE, vmPutMsgToQueryQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_VND_FETCH_RSMA, vmPutMsgToQueryQueue, 0) == NULL) goto _OVER;
+ if (dmSetMgmtHandle(pArray, TDMT_VND_EXEC_RSMA, vmPutMsgToQueryQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_SCH_FETCH, vmPutMsgToFetchQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_SCH_MERGE_FETCH, vmPutMsgToFetchQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_VND_ALTER_TABLE, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
diff --git a/source/dnode/mnode/impl/inc/mndDef.h b/source/dnode/mnode/impl/inc/mndDef.h
index 455da6a40e..8cff7fe48e 100644
--- a/source/dnode/mnode/impl/inc/mndDef.h
+++ b/source/dnode/mnode/impl/inc/mndDef.h
@@ -636,6 +636,7 @@ typedef struct {
int32_t tEncodeSStreamObj(SEncoder* pEncoder, const SStreamObj* pObj);
int32_t tDecodeSStreamObj(SDecoder* pDecoder, SStreamObj* pObj);
+void tFreeStreamObj(SStreamObj* pObj);
typedef struct {
char streamName[TSDB_STREAM_FNAME_LEN];
diff --git a/source/dnode/mnode/impl/inc/mndStb.h b/source/dnode/mnode/impl/inc/mndStb.h
index 44a7fdadde..010199a89f 100644
--- a/source/dnode/mnode/impl/inc/mndStb.h
+++ b/source/dnode/mnode/impl/inc/mndStb.h
@@ -34,6 +34,7 @@ int32_t mndCheckCreateStbReq(SMCreateStbReq *pCreate);
SDbObj *mndAcquireDbByStb(SMnode *pMnode, const char *stbName);
int32_t mndBuildStbFromReq(SMnode *pMnode, SStbObj *pDst, SMCreateStbReq *pCreate, SDbObj *pDb);
int32_t mndAddStbToTrans(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb);
+void mndFreeStb(SStbObj *pStb);
void mndExtractDbNameFromStbFullName(const char *stbFullName, char *dst);
void mndExtractTbNameFromStbFullName(const char *stbFullName, char *dst, int32_t dstSize);
diff --git a/source/dnode/mnode/impl/src/mndDef.c b/source/dnode/mnode/impl/src/mndDef.c
index 08ce161409..e6f1a40993 100644
--- a/source/dnode/mnode/impl/src/mndDef.c
+++ b/source/dnode/mnode/impl/src/mndDef.c
@@ -116,6 +116,25 @@ int32_t tDecodeSStreamObj(SDecoder *pDecoder, SStreamObj *pObj) {
return 0;
}
+void tFreeStreamObj(SStreamObj *pStream) {
+ taosMemoryFree(pStream->sql);
+ taosMemoryFree(pStream->ast);
+ taosMemoryFree(pStream->physicalPlan);
+ if (pStream->outputSchema.nCols) taosMemoryFree(pStream->outputSchema.pSchema);
+
+ int32_t sz = taosArrayGetSize(pStream->tasks);
+ for (int32_t i = 0; i < sz; i++) {
+ SArray *pLevel = taosArrayGetP(pStream->tasks, i);
+ int32_t taskSz = taosArrayGetSize(pLevel);
+ for (int32_t j = 0; j < taskSz; j++) {
+ SStreamTask *pTask = taosArrayGetP(pLevel, j);
+ tFreeSStreamTask(pTask);
+ }
+ taosArrayDestroy(pLevel);
+ }
+ taosArrayDestroy(pStream->tasks);
+}
+
SMqVgEp *tCloneSMqVgEp(const SMqVgEp *pVgEp) {
SMqVgEp *pVgEpNew = taosMemoryMalloc(sizeof(SMqVgEp));
if (pVgEpNew == NULL) return NULL;
diff --git a/source/dnode/mnode/impl/src/mndScheduler.c b/source/dnode/mnode/impl/src/mndScheduler.c
index a24b7ef459..3bfd7eb596 100644
--- a/source/dnode/mnode/impl/src/mndScheduler.c
+++ b/source/dnode/mnode/impl/src/mndScheduler.c
@@ -424,6 +424,8 @@ int32_t mndScheduleStream(SMnode* pMnode, SStreamObj* pStream) {
}
mndAddTaskToTaskSet(taskSourceLevel, pTask);
+ pTask->triggerParam = 0;
+
// source
pTask->taskLevel = TASK_LEVEL__SOURCE;
diff --git a/source/dnode/mnode/impl/src/mndSma.c b/source/dnode/mnode/impl/src/mndSma.c
index 006d9e749c..2fb934aaad 100644
--- a/source/dnode/mnode/impl/src/mndSma.c
+++ b/source/dnode/mnode/impl/src/mndSma.c
@@ -489,7 +489,7 @@ static int32_t mndCreateSma(SMnode *pMnode, SRpcMsg *pReq, SMCreateSmaReq *pCrea
smaObj.uid = mndGenerateUid(pCreate->name, TSDB_TABLE_FNAME_LEN);
ASSERT(smaObj.uid != 0);
char resultTbName[TSDB_TABLE_FNAME_LEN + 16] = {0};
- snprintf(resultTbName, TSDB_TABLE_FNAME_LEN + 16, "%s_td_tsma_rst_tb",pCreate->name);
+ snprintf(resultTbName, TSDB_TABLE_FNAME_LEN + 16, "%s_td_tsma_rst_tb", pCreate->name);
memcpy(smaObj.dstTbName, resultTbName, TSDB_TABLE_FNAME_LEN);
smaObj.dstTbUid = mndGenerateUid(smaObj.dstTbName, TSDB_TABLE_FNAME_LEN);
smaObj.stbUid = pStb->uid;
@@ -530,7 +530,7 @@ static int32_t mndCreateSma(SMnode *pMnode, SRpcMsg *pReq, SMCreateSmaReq *pCrea
streamObj.sourceDbUid = pDb->uid;
streamObj.targetDbUid = pDb->uid;
streamObj.version = 1;
- streamObj.sql = pCreate->sql;
+ streamObj.sql = strdup(pCreate->sql);
streamObj.smaId = smaObj.uid;
streamObj.watermark = pCreate->watermark;
streamObj.trigger = STREAM_TRIGGER_WINDOW_CLOSE;
@@ -585,6 +585,7 @@ static int32_t mndCreateSma(SMnode *pMnode, SRpcMsg *pReq, SMCreateSmaReq *pCrea
return -1;
}
if (pAst != NULL) nodesDestroyNode(pAst);
+ nodesDestroyNode((SNode *)pPlan);
int32_t code = -1;
STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_DB, pReq);
@@ -609,6 +610,7 @@ static int32_t mndCreateSma(SMnode *pMnode, SRpcMsg *pReq, SMCreateSmaReq *pCrea
code = 0;
_OVER:
+ tFreeStreamObj(&streamObj);
mndDestroySmaObj(&smaObj);
mndTransDrop(pTrans);
return code;
diff --git a/source/dnode/mnode/impl/src/mndStb.c b/source/dnode/mnode/impl/src/mndStb.c
index dd2b595c29..ebec3d5ea6 100644
--- a/source/dnode/mnode/impl/src/mndStb.c
+++ b/source/dnode/mnode/impl/src/mndStb.c
@@ -266,6 +266,15 @@ _OVER:
return pRow;
}
+void mndFreeStb(SStbObj *pStb) {
+ taosArrayDestroy(pStb->pFuncs);
+ taosMemoryFreeClear(pStb->pColumns);
+ taosMemoryFreeClear(pStb->pTags);
+ taosMemoryFreeClear(pStb->comment);
+ taosMemoryFreeClear(pStb->pAst1);
+ taosMemoryFreeClear(pStb->pAst2);
+}
+
static int32_t mndStbActionInsert(SSdb *pSdb, SStbObj *pStb) {
mTrace("stb:%s, perform insert action, row:%p", pStb->name, pStb);
return 0;
@@ -273,12 +282,7 @@ static int32_t mndStbActionInsert(SSdb *pSdb, SStbObj *pStb) {
static int32_t mndStbActionDelete(SSdb *pSdb, SStbObj *pStb) {
mTrace("stb:%s, perform delete action, row:%p", pStb->name, pStb);
- taosArrayDestroy(pStb->pFuncs);
- taosMemoryFreeClear(pStb->pColumns);
- taosMemoryFreeClear(pStb->pTags);
- taosMemoryFreeClear(pStb->comment);
- taosMemoryFreeClear(pStb->pAst1);
- taosMemoryFreeClear(pStb->pAst2);
+ mndFreeStb(pStb);
return 0;
}
@@ -438,6 +442,8 @@ static void *mndBuildVCreateStbReq(SMnode *pMnode, SVgObj *pVgroup, SStbObj *pSt
if (req.rollup) {
req.rsmaParam.maxdelay[0] = pStb->maxdelay[0];
req.rsmaParam.maxdelay[1] = pStb->maxdelay[1];
+ req.rsmaParam.watermark[0] = pStb->watermark[0];
+ req.rsmaParam.watermark[1] = pStb->watermark[1];
if (pStb->ast1Len > 0) {
if (mndConvertRsmaTask(&req.rsmaParam.qmsg[0], &req.rsmaParam.qmsgLen[0], pStb->pAst1, pStb->uid,
STREAM_TRIGGER_WINDOW_CLOSE, req.rsmaParam.watermark[0]) < 0) {
@@ -2021,8 +2027,7 @@ static int32_t mndCheckDropStbForTopic(SMnode *pMnode, const char *stbFullName,
FOREACH(pNode, pNodeList) {
SColumnNode *pCol = (SColumnNode *)pNode;
- if (pCol->tableId != suid) {
- mDebug("topic:%s, check colId:%d passed", pTopic->name, pCol->colId);
+ if (pCol->tableId == suid) {
sdbRelease(pSdb, pTopic);
nodesDestroyNode(pAst);
return -1;
@@ -2045,6 +2050,16 @@ static int32_t mndCheckDropStbForStream(SMnode *pMnode, const char *stbFullName,
pIter = sdbFetch(pSdb, SDB_STREAM, pIter, (void **)&pStream);
if (pIter == NULL) break;
+ if (pStream->smaId != 0) {
+ sdbRelease(pSdb, pStream);
+ continue;
+ }
+
+ if (pStream->targetStbUid == suid) {
+ sdbRelease(pSdb, pStream);
+ return -1;
+ }
+
SNode *pAst = NULL;
if (nodesStringToNode(pStream->ast, &pAst) != 0) {
ASSERT(0);
@@ -2057,8 +2072,7 @@ static int32_t mndCheckDropStbForStream(SMnode *pMnode, const char *stbFullName,
FOREACH(pNode, pNodeList) {
SColumnNode *pCol = (SColumnNode *)pNode;
- if (pCol->tableId != suid) {
- mDebug("stream:%s, check colId:%d passed", pStream->name, pCol->colId);
+ if (pCol->tableId == suid) {
sdbRelease(pSdb, pStream);
nodesDestroyNode(pAst);
return -1;
diff --git a/source/dnode/mnode/impl/src/mndStream.c b/source/dnode/mnode/impl/src/mndStream.c
index 8c453e0c88..6dc8e2072b 100644
--- a/source/dnode/mnode/impl/src/mndStream.c
+++ b/source/dnode/mnode/impl/src/mndStream.c
@@ -167,6 +167,9 @@ static int32_t mndStreamActionInsert(SSdb *pSdb, SStreamObj *pStream) {
static int32_t mndStreamActionDelete(SSdb *pSdb, SStreamObj *pStream) {
mTrace("stream:%s, perform delete action", pStream->name);
+ taosWLockLatch(&pStream->lock);
+ tFreeStreamObj(pStream);
+ taosWUnLockLatch(&pStream->lock);
return 0;
}
@@ -493,10 +496,17 @@ static int32_t mndCreateStbForStream(SMnode *pMnode, STrans *pTrans, const SStre
stbObj.uid = pStream->targetStbUid;
- if (mndAddStbToTrans(pMnode, pTrans, pDb, &stbObj) < 0) goto _OVER;
+ if (mndAddStbToTrans(pMnode, pTrans, pDb, &stbObj) < 0) {
+ mndFreeStb(&stbObj);
+ goto _OVER;
+ }
+
+ tFreeSMCreateStbReq(&createReq);
+ mndFreeStb(&stbObj);
return 0;
_OVER:
+ tFreeSMCreateStbReq(&createReq);
mndReleaseStb(pMnode, pStb);
mndReleaseDb(pMnode, pDb);
return -1;
@@ -715,6 +725,7 @@ _OVER:
mndReleaseDb(pMnode, pDb);
tFreeSCMCreateStreamReq(&createStreamReq);
+ tFreeStreamObj(&streamObj);
return code;
}
diff --git a/source/dnode/mnode/impl/src/mndVgroup.c b/source/dnode/mnode/impl/src/mndVgroup.c
index 0567ec4e14..09eed7fb32 100644
--- a/source/dnode/mnode/impl/src/mndVgroup.c
+++ b/source/dnode/mnode/impl/src/mndVgroup.c
@@ -509,6 +509,7 @@ int32_t mndAllocSmaVgroup(SMnode *pMnode, SDbObj *pDb, SVgObj *pVgroup) {
pVgroup->replica = 1;
if (mndGetAvailableDnode(pMnode, pDb, pVgroup, pArray) != 0) return -1;
+ taosArrayDestroy(pArray);
mInfo("db:%s, sma vgId:%d is alloced", pDb->name, pVgroup->vgId);
return 0;
@@ -1862,4 +1863,4 @@ _OVER:
#endif
}
-bool mndVgroupInDb(SVgObj *pVgroup, int64_t dbUid) { return !pVgroup->isTsma && pVgroup->dbUid == dbUid; }
\ No newline at end of file
+bool mndVgroupInDb(SVgObj *pVgroup, int64_t dbUid) { return !pVgroup->isTsma && pVgroup->dbUid == dbUid; }
diff --git a/source/dnode/vnode/inc/vnode.h b/source/dnode/vnode/inc/vnode.h
index c224f6ce7f..ec27ba8ce6 100644
--- a/source/dnode/vnode/inc/vnode.h
+++ b/source/dnode/vnode/inc/vnode.h
@@ -63,6 +63,7 @@ void vnodeGetInfo(SVnode *pVnode, const char **dbname, int32_t *vgId);
int32_t vnodeProcessCreateTSma(SVnode *pVnode, void *pCont, uint32_t contLen);
int32_t vnodeGetAllTableList(SVnode *pVnode, uint64_t uid, SArray *list);
int32_t vnodeGetCtbIdList(SVnode *pVnode, int64_t suid, SArray *list);
+int32_t vnodeGetStbIdList(SVnode *pVnode, int64_t suid, SArray* list);
void *vnodeGetIdx(SVnode *pVnode);
void *vnodeGetIvtIdx(SVnode *pVnode);
@@ -95,6 +96,7 @@ int32_t metaGetTableTags(SMeta *pMeta, uint64_t suid, SArray *uidList, SHash
int32_t metaReadNext(SMetaReader *pReader);
const void *metaGetTableTagVal(void *tag, int16_t type, STagVal *tagVal);
int metaGetTableNameByUid(void *meta, uint64_t uid, char *tbName);
+bool metaIsTableExist(SMeta *pMeta, tb_uid_t uid);
typedef struct SMetaFltParam {
tb_uid_t suid;
diff --git a/source/dnode/vnode/src/inc/meta.h b/source/dnode/vnode/src/inc/meta.h
index 2efc33a8ee..adfbb91920 100644
--- a/source/dnode/vnode/src/inc/meta.h
+++ b/source/dnode/vnode/src/inc/meta.h
@@ -66,7 +66,6 @@ int32_t metaCacheOpen(SMeta* pMeta);
void metaCacheClose(SMeta* pMeta);
int32_t metaCacheUpsert(SMeta* pMeta, SMetaInfo* pInfo);
int32_t metaCacheDrop(SMeta* pMeta, int64_t uid);
-int32_t metaCacheGet(SMeta* pMeta, int64_t uid, SMetaInfo* pInfo);
struct SMeta {
TdThreadRwlock lock;
diff --git a/source/dnode/vnode/src/inc/sma.h b/source/dnode/vnode/src/inc/sma.h
index 944d7759b2..ca77042bb2 100644
--- a/source/dnode/vnode/src/inc/sma.h
+++ b/source/dnode/vnode/src/inc/sma.h
@@ -32,7 +32,8 @@ extern "C" {
#define smaTrace(...) do { if (smaDebugFlag & DEBUG_TRACE) { taosPrintLog("SMA ", DEBUG_TRACE, tsdbDebugFlag, __VA_ARGS__); }} while(0)
// clang-format on
-#define RSMA_TASK_INFO_HASH_SLOT 8
+#define RSMA_TASK_INFO_HASH_SLOT (8)
+#define RSMA_EXECUTOR_MAX (1)
typedef struct SSmaEnv SSmaEnv;
typedef struct SSmaStat SSmaStat;
@@ -57,9 +58,10 @@ typedef struct {
void *tmrHandle; // shared by all fetch tasks
} SSmaMgmt;
-#define SMA_ENV_LOCK(env) (&(env)->lock)
-#define SMA_ENV_TYPE(env) ((env)->type)
-#define SMA_ENV_STAT(env) ((env)->pStat)
+#define SMA_ENV_LOCK(env) (&(env)->lock)
+#define SMA_ENV_TYPE(env) ((env)->type)
+#define SMA_ENV_STAT(env) ((env)->pStat)
+#define SMA_RSMA_STAT(sma) ((SRSmaStat *)SMA_ENV_STAT((SSmaEnv *)(sma)->pRSmaEnv))
struct STSmaStat {
int8_t state; // ETsdbSmaStat
@@ -86,15 +88,17 @@ struct SQTaskFWriter {
};
struct SRSmaStat {
- SSma *pSma;
- int64_t commitAppliedVer; // vnode applied version for async commit
- int64_t refId; // shared by fetch tasks
- SRWLatch lock; // r/w lock for rsma fs(e.g. qtaskinfo)
- int8_t triggerStat; // shared by fetch tasks
- int8_t commitStat; // 0 not in committing, 1 in committing
- SArray *aTaskFile; // qTaskFiles committed recently(for recovery/snapshot r/w)
- SHashObj *rsmaInfoHash; // key: stbUid, value: SRSmaInfo;
- SHashObj *iRsmaInfoHash; // key: stbUid, value: SRSmaInfo; immutable rsmaInfoHash
+ SSma *pSma;
+ int64_t commitAppliedVer; // vnode applied version for async commit
+ int64_t refId; // shared by fetch tasks
+ volatile int64_t nBufItems; // number of items in queue buffer
+ SRWLatch lock; // r/w lock for rsma fs(e.g. qtaskinfo)
+ volatile int8_t nExecutor; // [1, max(half of query threads, 4)]
+ int8_t triggerStat; // shared by fetch tasks
+ int8_t commitStat; // 0 not in committing, 1 in committing
+ SArray *aTaskFile; // qTaskFiles committed recently(for recovery/snapshot r/w)
+ SHashObj *infoHash; // key: suid, value: SRSmaInfo
+ tsem_t notEmpty; // has items in queue buffer
};
struct SSmaStat {
@@ -105,34 +109,42 @@ struct SSmaStat {
T_REF_DECLARE()
};
-#define SMA_TSMA_STAT(s) (&(s)->tsmaStat)
-#define SMA_RSMA_STAT(s) (&(s)->rsmaStat)
-#define RSMA_INFO_HASH(r) ((r)->rsmaInfoHash)
-#define RSMA_IMU_INFO_HASH(r) ((r)->iRsmaInfoHash)
-#define RSMA_TRIGGER_STAT(r) (&(r)->triggerStat)
-#define RSMA_COMMIT_STAT(r) (&(r)->commitStat)
-#define RSMA_REF_ID(r) ((r)->refId)
-#define RSMA_FS_LOCK(r) (&(r)->lock)
+#define SMA_STAT_TSMA(s) (&(s)->tsmaStat)
+#define SMA_STAT_RSMA(s) (&(s)->rsmaStat)
+#define RSMA_INFO_HASH(r) ((r)->infoHash)
+#define RSMA_TRIGGER_STAT(r) (&(r)->triggerStat)
+#define RSMA_COMMIT_STAT(r) (&(r)->commitStat)
+#define RSMA_REF_ID(r) ((r)->refId)
+#define RSMA_FS_LOCK(r) (&(r)->lock)
struct SRSmaInfoItem {
- int8_t level;
- int8_t triggerStat;
- int32_t maxDelay;
- tmr_h tmrId;
+ int8_t level : 4;
+ int8_t fetchLevel : 4;
+ int8_t triggerStat;
+ uint16_t nSkipped;
+ int32_t maxDelay; // ms
+ tmr_h tmrId;
};
struct SRSmaInfo {
STSchema *pTSchema;
int64_t suid;
- int64_t refId; // refId of SRSmaStat
+ int64_t refId; // refId of SRSmaStat
+ int64_t lastRecv; // ms
+ int8_t assigned; // 0 idle, 1 assgined for exec
int8_t delFlag;
+ int16_t padding;
T_REF_DECLARE()
SRSmaInfoItem items[TSDB_RETENTION_L2];
void *taskInfo[TSDB_RETENTION_L2]; // qTaskInfo_t
- void *iTaskInfo[TSDB_RETENTION_L2]; // immutable
+ STaosQueue *queue; // buffer queue of SubmitReq
+ STaosQall *qall; // buffer qall of SubmitReq
+ void *iTaskInfo[TSDB_RETENTION_L2]; // immutable qTaskInfo_t
+ STaosQueue *iQueue; // immutable buffer queue of SubmitReq
+ STaosQall *iQall; // immutable buffer qall of SubmitReq
};
-#define RSMA_INFO_HEAD_LEN 32
+#define RSMA_INFO_HEAD_LEN offsetof(SRSmaInfo, items)
#define RSMA_INFO_IS_DEL(r) ((r)->delFlag == 1)
#define RSMA_INFO_SET_DEL(r) ((r)->delFlag = 1)
#define RSMA_INFO_QTASK(r, i) ((r)->taskInfo[i])
@@ -161,6 +173,12 @@ enum {
RSMA_RESTORE_SYNC = 2,
};
+typedef enum {
+ RSMA_EXEC_OVERFLOW = 1, // triggered by queue buf overflow
+ RSMA_EXEC_TIMEOUT = 2, // triggered by timer
+ RSMA_EXEC_COMMIT = 3, // triggered by commit
+} ERsmaExecType;
+
void tdDestroySmaEnv(SSmaEnv *pSmaEnv);
void *tdFreeSmaEnv(SSmaEnv *pSmaEnv);
@@ -228,12 +246,13 @@ static FORCE_INLINE void tdSmaStatSetDropped(STSmaStat *pTStat) {
void tdRSmaQTaskInfoGetFileName(int32_t vid, int64_t version, char *outputName);
void tdRSmaQTaskInfoGetFullName(int32_t vid, int64_t version, const char *path, char *outputName);
-int32_t tdCloneRSmaInfo(SSma *pSma, SRSmaInfo **pDest, SRSmaInfo *pSrc);
+int32_t tdCloneRSmaInfo(SSma *pSma, SRSmaInfo *pInfo);
void tdFreeQTaskInfo(qTaskInfo_t *taskHandle, int32_t vgId, int32_t level);
static int32_t tdDestroySmaState(SSmaStat *pSmaStat, int8_t smaType);
void *tdFreeSmaState(SSmaStat *pSmaStat, int8_t smaType);
void *tdFreeRSmaInfo(SSma *pSma, SRSmaInfo *pInfo, bool isDeepFree);
int32_t tdRSmaPersistExecImpl(SRSmaStat *pRSmaStat, SHashObj *pInfoHash);
+int32_t tdRSmaProcessExecImpl(SSma *pSma, ERsmaExecType type);
int32_t tdProcessRSmaCreateImpl(SSma *pSma, SRSmaParam *param, int64_t suid, const char *tbName);
int32_t tdProcessRSmaRestoreImpl(SSma *pSma, int8_t type, int64_t qtaskFileVer);
diff --git a/source/dnode/vnode/src/inc/tsdb.h b/source/dnode/vnode/src/inc/tsdb.h
index f1e980c026..d1f5cfb122 100644
--- a/source/dnode/vnode/src/inc/tsdb.h
+++ b/source/dnode/vnode/src/inc/tsdb.h
@@ -45,7 +45,7 @@ typedef struct SBlockIdx SBlockIdx;
typedef struct SBlock SBlock;
typedef struct SBlockL SBlockL;
typedef struct SColData SColData;
-typedef struct SBlockDataHdr SBlockDataHdr;
+typedef struct SDiskDataHdr SDiskDataHdr;
typedef struct SBlockData SBlockData;
typedef struct SDelFile SDelFile;
typedef struct SHeadFile SHeadFile;
@@ -61,7 +61,11 @@ typedef struct SRowIter SRowIter;
typedef struct STsdbFS STsdbFS;
typedef struct SRowMerger SRowMerger;
typedef struct STsdbReadSnap STsdbReadSnap;
+typedef struct SBlockInfo SBlockInfo;
+typedef struct SSmaInfo SSmaInfo;
+typedef struct SBlockCol SBlockCol;
+#define TSDB_FILE_DLMT ((uint32_t)0xF00AFA0F)
#define TSDB_MAX_SUBBLOCKS 8
#define TSDB_FHDR_SIZE 512
@@ -113,10 +117,14 @@ int32_t tPutBlock(uint8_t *p, void *ph);
int32_t tGetBlock(uint8_t *p, void *ph);
int32_t tBlockCmprFn(const void *p1, const void *p2);
bool tBlockHasSma(SBlock *pBlock);
+// SBlockL
+int32_t tPutBlockL(uint8_t *p, void *ph);
+int32_t tGetBlockL(uint8_t *p, void *ph);
// SBlockIdx
int32_t tPutBlockIdx(uint8_t *p, void *ph);
int32_t tGetBlockIdx(uint8_t *p, void *ph);
int32_t tCmprBlockIdx(void const *lhs, void const *rhs);
+int32_t tCmprBlockL(void const *lhs, void const *rhs);
// SColdata
void tColDataInit(SColData *pColData, int16_t cid, int8_t type, int8_t smaOn);
void tColDataReset(SColData *pColData);
@@ -131,20 +139,25 @@ int32_t tGetColData(uint8_t *p, SColData *pColData);
#define tBlockDataLastRow(PBLOCKDATA) tsdbRowFromBlockData(PBLOCKDATA, (PBLOCKDATA)->nRow - 1)
#define tBlockDataFirstKey(PBLOCKDATA) TSDBROW_KEY(&tBlockDataFirstRow(PBLOCKDATA))
#define tBlockDataLastKey(PBLOCKDATA) TSDBROW_KEY(&tBlockDataLastRow(PBLOCKDATA))
-int32_t tBlockDataInit(SBlockData *pBlockData);
+
+int32_t tBlockDataCreate(SBlockData *pBlockData);
+void tBlockDataDestroy(SBlockData *pBlockData, int8_t deepClear);
+int32_t tBlockDataInit(SBlockData *pBlockData, int64_t suid, int64_t uid, STSchema *pTSchema);
+int32_t tBlockDataInitEx(SBlockData *pBlockData, SBlockData *pBlockDataFrom);
void tBlockDataReset(SBlockData *pBlockData);
-int32_t tBlockDataSetSchema(SBlockData *pBlockData, STSchema *pTSchema);
-int32_t tBlockDataCorrectSchema(SBlockData *pBlockData, SBlockData *pBlockDataFrom);
-void tBlockDataClearData(SBlockData *pBlockData);
-void tBlockDataClear(SBlockData *pBlockData, int8_t deepClear);
-int32_t tBlockDataAddColData(SBlockData *pBlockData, int32_t iColData, SColData **ppColData);
-int32_t tBlockDataAppendRow(SBlockData *pBlockData, TSDBROW *pRow, STSchema *pTSchema);
-int32_t tBlockDataMerge(SBlockData *pBlockData1, SBlockData *pBlockData2, SBlockData *pBlockData);
-int32_t tBlockDataCopy(SBlockData *pBlockDataSrc, SBlockData *pBlockDataDest);
+int32_t tBlockDataAppendRow(SBlockData *pBlockData, TSDBROW *pRow, STSchema *pTSchema, int64_t uid);
+void tBlockDataClear(SBlockData *pBlockData);
SColData *tBlockDataGetColDataByIdx(SBlockData *pBlockData, int32_t idx);
void tBlockDataGetColData(SBlockData *pBlockData, int16_t cid, SColData **ppColData);
-int32_t tPutBlockData(uint8_t *p, SBlockData *pBlockData);
-int32_t tGetBlockData(uint8_t *p, SBlockData *pBlockData);
+int32_t tBlockDataCopy(SBlockData *pBlockDataSrc, SBlockData *pBlockDataDest);
+int32_t tBlockDataMerge(SBlockData *pBlockData1, SBlockData *pBlockData2, SBlockData *pBlockData);
+int32_t tBlockDataAddColData(SBlockData *pBlockData, int32_t iColData, SColData **ppColData);
+int32_t tCmprBlockData(SBlockData *pBlockData, int8_t cmprAlg, uint8_t **ppOut, int32_t *szOut, uint8_t *aBuf[],
+ int32_t aBufN[]);
+int32_t tDecmprBlockData(uint8_t *pIn, int32_t szIn, SBlockData *pBlockData, uint8_t *aBuf[]);
+// SDiskDataHdr
+int32_t tPutDiskDataHdr(uint8_t *p, void *ph);
+int32_t tGetDiskDataHdr(uint8_t *p, void *ph);
// SDelIdx
int32_t tPutDelIdx(uint8_t *p, void *ph);
int32_t tGetDelIdx(uint8_t *p, void *ph);
@@ -168,13 +181,25 @@ void tsdbFidKeyRange(int32_t fid, int32_t minutes, int8_t precision, TSKEY *m
int32_t tsdbFidLevel(int32_t fid, STsdbKeepCfg *pKeepCfg, int64_t now);
int32_t tsdbBuildDeleteSkyline(SArray *aDelData, int32_t sidx, int32_t eidx, SArray *aSkyline);
void tsdbCalcColDataSMA(SColData *pColData, SColumnDataAgg *pColAgg);
+int32_t tPutColumnDataAgg(uint8_t *p, SColumnDataAgg *pColAgg);
+int32_t tGetColumnDataAgg(uint8_t *p, SColumnDataAgg *pColAgg);
+int32_t tsdbCmprData(uint8_t *pIn, int32_t szIn, int8_t type, int8_t cmprAlg, uint8_t **ppOut, int32_t nOut,
+ int32_t *szOut, uint8_t **ppBuf);
+int32_t tsdbDecmprData(uint8_t *pIn, int32_t szIn, int8_t type, int8_t cmprAlg, uint8_t **ppOut, int32_t szOut,
+ uint8_t **ppBuf);
+int32_t tsdbCmprColData(SColData *pColData, int8_t cmprAlg, SBlockCol *pBlockCol, uint8_t **ppOut, int32_t nOut,
+ uint8_t **ppBuf);
+int32_t tsdbDecmprColData(uint8_t *pIn, SBlockCol *pBlockCol, int8_t cmprAlg, int32_t nVal, SColData *pColData,
+ uint8_t **ppBuf);
+int32_t tsdbReadAndCheck(TdFilePtr pFD, int64_t offset, uint8_t **ppOut, int32_t size, int8_t toCheck);
// tsdbMemTable ==============================================================================================
// SMemTable
-int32_t tsdbMemTableCreate(STsdb *pTsdb, SMemTable **ppMemTable);
-void tsdbMemTableDestroy(SMemTable *pMemTable);
-void tsdbGetTbDataFromMemTable(SMemTable *pMemTable, tb_uid_t suid, tb_uid_t uid, STbData **ppTbData);
-void tsdbRefMemTable(SMemTable *pMemTable);
-void tsdbUnrefMemTable(SMemTable *pMemTable);
+int32_t tsdbMemTableCreate(STsdb *pTsdb, SMemTable **ppMemTable);
+void tsdbMemTableDestroy(SMemTable *pMemTable);
+STbData *tsdbGetTbDataFromMemTable(SMemTable *pMemTable, tb_uid_t suid, tb_uid_t uid);
+void tsdbRefMemTable(SMemTable *pMemTable);
+void tsdbUnrefMemTable(SMemTable *pMemTable);
+SArray *tsdbMemTableGetTbDataArray(SMemTable *pMemTable);
// STbDataIter
int32_t tsdbTbDataIterCreate(STbData *pTbData, TSDBKEY *pFrom, int8_t backward, STbDataIter **ppIter);
void *tsdbTbDataIterDestroy(STbDataIter *pIter);
@@ -223,33 +248,33 @@ int32_t tsdbFSUpsertDelFile(STsdbFS *pFS, SDelFile *pDelFile);
int32_t tsdbDataFWriterOpen(SDataFWriter **ppWriter, STsdb *pTsdb, SDFileSet *pSet);
int32_t tsdbDataFWriterClose(SDataFWriter **ppWriter, int8_t sync);
int32_t tsdbUpdateDFileSetHeader(SDataFWriter *pWriter);
-int32_t tsdbWriteBlockIdx(SDataFWriter *pWriter, SArray *aBlockIdx, uint8_t **ppBuf);
-int32_t tsdbWriteBlock(SDataFWriter *pWriter, SMapData *pMapData, uint8_t **ppBuf, SBlockIdx *pBlockIdx);
-int32_t tsdbWriteBlockData(SDataFWriter *pWriter, SBlockData *pBlockData, uint8_t **ppBuf1, uint8_t **ppBuf2,
- SBlockIdx *pBlockIdx, SBlock *pBlock, int8_t cmprAlg);
+int32_t tsdbWriteBlockIdx(SDataFWriter *pWriter, SArray *aBlockIdx);
+int32_t tsdbWriteBlock(SDataFWriter *pWriter, SMapData *pMapData, SBlockIdx *pBlockIdx);
+int32_t tsdbWriteBlockL(SDataFWriter *pWriter, SArray *aBlockL);
+int32_t tsdbWriteBlockData(SDataFWriter *pWriter, SBlockData *pBlockData, SBlockInfo *pBlkInfo, SSmaInfo *pSmaInfo,
+ int8_t cmprAlg, int8_t toLast);
int32_t tsdbDFileSetCopy(STsdb *pTsdb, SDFileSet *pSetFrom, SDFileSet *pSetTo);
// SDataFReader
int32_t tsdbDataFReaderOpen(SDataFReader **ppReader, STsdb *pTsdb, SDFileSet *pSet);
int32_t tsdbDataFReaderClose(SDataFReader **ppReader);
-int32_t tsdbReadBlockIdx(SDataFReader *pReader, SArray *aBlockIdx, uint8_t **ppBuf);
-int32_t tsdbReadBlock(SDataFReader *pReader, SBlockIdx *pBlockIdx, SMapData *pMapData, uint8_t **ppBuf);
-int32_t tsdbReadColData(SDataFReader *pReader, SBlockIdx *pBlockIdx, SBlock *pBlock, int16_t *aColId, int32_t nCol,
- SBlockData *pBlockData, uint8_t **ppBuf1, uint8_t **ppBuf2);
-int32_t tsdbReadBlockData(SDataFReader *pReader, SBlockIdx *pBlockIdx, SBlock *pBlock, SBlockData *pBlockData,
- uint8_t **ppBuf1, uint8_t **ppBuf2);
-int32_t tsdbReadBlockSma(SDataFReader *pReader, SBlock *pBlock, SArray *aColumnDataAgg, uint8_t **ppBuf);
+int32_t tsdbReadBlockIdx(SDataFReader *pReader, SArray *aBlockIdx);
+int32_t tsdbReadBlock(SDataFReader *pReader, SBlockIdx *pBlockIdx, SMapData *pMapData);
+int32_t tsdbReadBlockL(SDataFReader *pReader, SArray *aBlockL);
+int32_t tsdbReadBlockSma(SDataFReader *pReader, SBlock *pBlock, SArray *aColumnDataAgg);
+int32_t tsdbReadDataBlock(SDataFReader *pReader, SBlock *pBlock, SBlockData *pBlockData);
+int32_t tsdbReadLastBlock(SDataFReader *pReader, SBlockL *pBlockL, SBlockData *pBlockData);
// SDelFWriter
int32_t tsdbDelFWriterOpen(SDelFWriter **ppWriter, SDelFile *pFile, STsdb *pTsdb);
int32_t tsdbDelFWriterClose(SDelFWriter **ppWriter, int8_t sync);
-int32_t tsdbWriteDelData(SDelFWriter *pWriter, SArray *aDelData, uint8_t **ppBuf, SDelIdx *pDelIdx);
-int32_t tsdbWriteDelIdx(SDelFWriter *pWriter, SArray *aDelIdx, uint8_t **ppBuf);
+int32_t tsdbWriteDelData(SDelFWriter *pWriter, SArray *aDelData, SDelIdx *pDelIdx);
+int32_t tsdbWriteDelIdx(SDelFWriter *pWriter, SArray *aDelIdx);
int32_t tsdbUpdateDelFileHdr(SDelFWriter *pWriter);
// SDelFReader
-int32_t tsdbDelFReaderOpen(SDelFReader **ppReader, SDelFile *pFile, STsdb *pTsdb, uint8_t **ppBuf);
+int32_t tsdbDelFReaderOpen(SDelFReader **ppReader, SDelFile *pFile, STsdb *pTsdb);
int32_t tsdbDelFReaderClose(SDelFReader **ppReader);
-int32_t tsdbReadDelData(SDelFReader *pReader, SDelIdx *pDelIdx, SArray *aDelData, uint8_t **ppBuf);
-int32_t tsdbReadDelIdx(SDelFReader *pReader, SArray *aDelIdx, uint8_t **ppBuf);
+int32_t tsdbReadDelData(SDelFReader *pReader, SDelIdx *pDelIdx, SArray *aDelData);
+int32_t tsdbReadDelIdx(SDelFReader *pReader, SArray *aDelIdx);
// tsdbRead.c ==============================================================================================
int32_t tsdbTakeReadSnap(STsdb *pTsdb, STsdbReadSnap **ppSnap);
void tsdbUntakeReadSnap(STsdb *pTsdb, STsdbReadSnap *pSnap);
@@ -260,7 +285,7 @@ void tsdbUntakeReadSnap(STsdb *pTsdb, STsdbReadSnap *pSnap);
// tsdbCache
int32_t tsdbOpenCache(STsdb *pTsdb);
-void tsdbCloseCache(SLRUCache *pCache);
+void tsdbCloseCache(STsdb *pTsdb);
int32_t tsdbCacheInsertLast(SLRUCache *pCache, tb_uid_t uid, STSRow *row, STsdb *pTsdb);
int32_t tsdbCacheInsertLastrow(SLRUCache *pCache, STsdb *pTsdb, tb_uid_t uid, STSRow *row, bool dup);
int32_t tsdbCacheGetLastH(SLRUCache *pCache, tb_uid_t uid, STsdb *pTsdb, LRUHandle **h);
@@ -277,13 +302,6 @@ size_t tsdbCacheGetCapacity(SVnode *pVnode);
int32_t tsdbCacheLastArray2Row(SArray *pLastArray, STSRow **ppRow, STSchema *pSchema);
// structs =======================
-typedef struct {
- int minFid;
- int midFid;
- int maxFid;
- TSKEY minKey;
-} SRtn;
-
struct STsdbFS {
SDelFile *pDelFile;
SArray *aDFileSet; // SArray
@@ -298,6 +316,7 @@ struct STsdb {
SMemTable *imem;
STsdbFS fs;
SLRUCache *lruCache;
+ TdThreadMutex lruMutex;
};
struct TSDBKEY {
@@ -311,30 +330,23 @@ struct SMemSkipListNode {
SMemSkipListNode *forwards[0];
};
typedef struct SMemSkipList {
- uint32_t seed;
int64_t size;
+ uint32_t seed;
int8_t maxLevel;
int8_t level;
SMemSkipListNode *pHead;
SMemSkipListNode *pTail;
} SMemSkipList;
-struct SDelDataInfo {
- tb_uid_t suid;
- tb_uid_t uid;
-};
-
struct STbData {
tb_uid_t suid;
tb_uid_t uid;
TSKEY minKey;
TSKEY maxKey;
- int64_t minVersion;
- int64_t maxVersion;
- int32_t maxSkmVer;
SDelData *pHead;
SDelData *pTail;
SMemSkipList sl;
+ STbData *next;
};
struct SMemTable {
@@ -344,11 +356,13 @@ struct SMemTable {
volatile int32_t nRef;
TSKEY minKey;
TSKEY maxKey;
- int64_t minVersion;
- int64_t maxVersion;
int64_t nRow;
int64_t nDel;
- SArray *aTbData; // SArray
+ struct {
+ int32_t nTbData;
+ int32_t nBucket;
+ STbData **aBucket;
+ };
};
struct TSDBROW {
@@ -379,63 +393,51 @@ struct SMapData {
uint8_t *pData;
};
-typedef struct {
+struct SBlockCol {
int16_t cid;
int8_t type;
int8_t smaOn;
- int8_t flag; // HAS_NONE|HAS_NULL|HAS_VALUE
- int32_t offset;
- int32_t szBitmap; // bitmap size
- int32_t szOffset; // size of offset, only for variant-length data type
- int32_t szValue; // compressed column value size
+ int8_t flag; // HAS_NONE|HAS_NULL|HAS_VALUE
int32_t szOrigin; // original column value size (only save for variant data type)
-} SBlockCol;
+ int32_t szBitmap; // bitmap size, 0 only for flag == HAS_VAL
+ int32_t szOffset; // offset size, 0 only for non-variant-length type
+ int32_t szValue; // value size, 0 when flag == (HAS_NULL | HAS_NONE)
+ int32_t offset;
+};
-typedef struct {
- int32_t nRow;
- int8_t cmprAlg;
- int64_t offset; // block data offset
- int32_t szBlockCol; // SBlockCol size
- int32_t szVersion; // VERSION size
- int32_t szTSKEY; // TSKEY size
- int32_t szBlock; // total block size
- int64_t sOffset; // sma offset
- int32_t nSma; // sma size
-} SSubBlock;
+struct SBlockInfo {
+ int64_t offset; // block data offset
+ int32_t szBlock;
+ int32_t szKey;
+};
+
+struct SSmaInfo {
+ int64_t offset;
+ int32_t size;
+};
struct SBlock {
- TSDBKEY minKey;
- TSDBKEY maxKey;
- int64_t minVersion;
- int64_t maxVersion;
- int32_t nRow;
- int8_t last;
- int8_t hasDup;
- int8_t nSubBlock;
- SSubBlock aSubBlock[TSDB_MAX_SUBBLOCKS];
+ TSDBKEY minKey;
+ TSDBKEY maxKey;
+ int64_t minVer;
+ int64_t maxVer;
+ int32_t nRow;
+ int8_t hasDup;
+ int8_t nSubBlock;
+ SBlockInfo aSubBlock[TSDB_MAX_SUBBLOCKS];
+ SSmaInfo smaInfo;
};
struct SBlockL {
- struct {
- int64_t uid;
- int64_t version;
- TSKEY ts;
- } minKey;
- struct {
- int64_t uid;
- int64_t version;
- TSKEY ts;
- } maxKey;
- int64_t minVer;
- int64_t maxVer;
- int32_t nRow;
- int8_t cmprAlg;
- int64_t offset;
- int32_t szBlock;
- int32_t szBlockCol;
- int32_t szUid;
- int32_t szVer;
- int32_t szTSKEY;
+ int64_t suid;
+ int64_t minUid;
+ int64_t maxUid;
+ TSKEY minKey;
+ TSKEY maxKey;
+ int64_t minVer;
+ int64_t maxVer;
+ int32_t nRow;
+ SBlockInfo bInfo;
};
struct SColData {
@@ -450,10 +452,17 @@ struct SColData {
uint8_t *pData;
};
+// (SBlockData){.suid = 0, .uid = 0}: block data not initialized
+// (SBlockData){.suid = suid, .uid = uid}: block data for ONE child table int .data file
+// (SBlockData){.suid = suid, .uid = 0}: block data for N child tables int .last file
+// (SBlockData){.suid = 0, .uid = uid}: block data for 1 normal table int .last/.data file
struct SBlockData {
- int32_t nRow;
- int64_t *aVersion;
- TSKEY *aTSKEY;
+ int64_t suid; // 0 means normal table block data, otherwise child table block data
+ int64_t uid; // 0 means block data in .last file, otherwise in .data file
+ int32_t nRow; // number of rows
+ int64_t *aUid; // uids of each row, only exist in block data in .last file (uid == 0)
+ int64_t *aVersion; // versions of each row
+ TSKEY *aTSKEY; // timestamp of each row
SArray *aIdx; // SArray
SArray *aColData; // SArray
};
@@ -491,13 +500,18 @@ struct SDelIdx {
int64_t size;
};
-#pragma pack(push, 1)
-struct SBlockDataHdr {
+struct SDiskDataHdr {
uint32_t delimiter;
+ uint32_t fmtVer;
int64_t suid;
int64_t uid;
+ int32_t szUid;
+ int32_t szVer;
+ int32_t szKey;
+ int32_t szBlkCol;
+ int32_t nRow;
+ int8_t cmprAlg;
};
-#pragma pack(pop)
struct SDelFile {
volatile int32_t nRef;
@@ -527,6 +541,7 @@ struct SLastFile {
int64_t commitID;
int64_t size;
+ int64_t offset;
};
struct SSmaFile {
@@ -561,6 +576,8 @@ struct SDelFWriter {
STsdb *pTsdb;
SDelFile fDel;
TdFilePtr pWriteH;
+
+ uint8_t *aBuf[1];
};
struct SDataFWriter {
@@ -576,6 +593,8 @@ struct SDataFWriter {
SDataFile fData;
SLastFile fLast;
SSmaFile fSma;
+
+ uint8_t *aBuf[4];
};
struct STsdbReadSnap {
diff --git a/source/dnode/vnode/src/inc/vnd.h b/source/dnode/vnode/src/inc/vnd.h
index 5164e22474..898e79928b 100644
--- a/source/dnode/vnode/src/inc/vnd.h
+++ b/source/dnode/vnode/src/inc/vnd.h
@@ -65,6 +65,7 @@ struct SVBufPool {
SVBufPool* next;
SVnode* pVnode;
volatile int32_t nRef;
+ TdThreadSpinlock lock;
int64_t size;
uint8_t* ptr;
SVBufPoolNode* pTail;
diff --git a/source/dnode/vnode/src/inc/vnodeInt.h b/source/dnode/vnode/src/inc/vnodeInt.h
index 0c7a08a2b5..39c5f3873e 100644
--- a/source/dnode/vnode/src/inc/vnodeInt.h
+++ b/source/dnode/vnode/src/inc/vnodeInt.h
@@ -189,6 +189,7 @@ SSubmitReq* tqBlockToSubmit(SVnode* pVnode, const SArray* pBlocks, const STSchem
int32_t smaInit();
void smaCleanUp();
int32_t smaOpen(SVnode* pVnode);
+int32_t smaPreClose(SSma* pSma);
int32_t smaClose(SSma* pSma);
int32_t smaBegin(SSma* pSma);
int32_t smaSyncPreCommit(SSma* pSma);
@@ -198,7 +199,7 @@ int32_t smaAsyncPreCommit(SSma* pSma);
int32_t smaAsyncCommit(SSma* pSma);
int32_t smaAsyncPostCommit(SSma* pSma);
int32_t smaDoRetention(SSma* pSma, int64_t now);
-int32_t smaProcessFetch(SSma* pSma, void* pMsg);
+int32_t smaProcessExec(SSma* pSma, void* pMsg);
int32_t tdProcessTSmaCreate(SSma* pSma, int64_t version, const char* msg);
int32_t tdProcessTSmaInsert(SSma* pSma, int64_t indexUid, const char* msg);
@@ -322,6 +323,7 @@ struct SVnode {
TdThreadMutex lock;
bool blocked;
bool restored;
+ bool inClose;
tsem_t syncSem;
SQHandle* pQuery;
};
@@ -368,6 +370,7 @@ struct SSma {
void smaHandleRes(void* pVnode, int64_t smaId, const SArray* data);
enum {
+ SNAP_DATA_CFG = 0,
SNAP_DATA_META = 1,
SNAP_DATA_TSDB = 2,
SNAP_DATA_DEL = 3,
diff --git a/source/dnode/vnode/src/meta/metaQuery.c b/source/dnode/vnode/src/meta/metaQuery.c
index 4e85cde7ca..805bc24d8c 100644
--- a/source/dnode/vnode/src/meta/metaQuery.c
+++ b/source/dnode/vnode/src/meta/metaQuery.c
@@ -127,6 +127,15 @@ _err:
// return 0;
// }
+bool metaIsTableExist(SMeta *pMeta, tb_uid_t uid) {
+ // query uid.idx
+ if (tdbTbGet(pMeta->pUidIdx, &uid, sizeof(uid), NULL, NULL) < 0) {
+ return false;
+ }
+
+ return true;
+}
+
int metaGetTableEntryByUid(SMetaReader *pReader, tb_uid_t uid) {
SMeta *pMeta = pReader->pMeta;
int64_t version;
@@ -503,18 +512,65 @@ STSchema *metaGetTbTSchema(SMeta *pMeta, tb_uid_t uid, int32_t sver) {
}
int32_t metaGetTbTSchemaEx(SMeta *pMeta, tb_uid_t suid, tb_uid_t uid, int32_t sver, STSchema **ppTSchema) {
- int32_t code = 0;
- STSchema *pTSchema = NULL;
- SSkmDbKey skmDbKey = {.uid = suid ? suid : uid, .sver = sver};
+ int32_t code = 0;
+
void *pData = NULL;
int nData = 0;
+ SSkmDbKey skmDbKey;
+ if (sver <= 0) {
+ SMetaInfo info;
+ if (metaGetInfo(pMeta, suid ? suid : uid, &info) == 0) {
+ sver = info.skmVer;
+ } else {
+ TBC *pSkmDbC = NULL;
+ int c;
- // query
+ skmDbKey.uid = suid ? suid : uid;
+ skmDbKey.sver = INT32_MAX;
+
+ tdbTbcOpen(pMeta->pSkmDb, &pSkmDbC, NULL);
+ metaRLock(pMeta);
+
+ if (tdbTbcMoveTo(pSkmDbC, &skmDbKey, sizeof(skmDbKey), &c) < 0) {
+ metaULock(pMeta);
+ tdbTbcClose(pSkmDbC);
+ code = TSDB_CODE_NOT_FOUND;
+ goto _exit;
+ }
+
+ ASSERT(c);
+
+ if (c < 0) {
+ tdbTbcMoveToPrev(pSkmDbC);
+ }
+
+ const void *pKey = NULL;
+ int32_t nKey = 0;
+ tdbTbcGet(pSkmDbC, &pKey, &nKey, NULL, NULL);
+
+ if (((SSkmDbKey *)pKey)->uid != skmDbKey.uid) {
+ metaULock(pMeta);
+ tdbTbcClose(pSkmDbC);
+ code = TSDB_CODE_NOT_FOUND;
+ goto _exit;
+ }
+
+ sver = ((SSkmDbKey *)pKey)->sver;
+
+ metaULock(pMeta);
+ tdbTbcClose(pSkmDbC);
+ }
+ }
+
+ ASSERT(sver > 0);
+
+ skmDbKey.uid = suid ? suid : uid;
+ skmDbKey.sver = sver;
metaRLock(pMeta);
- if (tdbTbGet(pMeta->pSkmDb, &skmDbKey, sizeof(skmDbKey), &pData, &nData) < 0) {
- code = TSDB_CODE_NOT_FOUND;
+ if (tdbTbGet(pMeta->pSkmDb, &skmDbKey, sizeof(SSkmDbKey), &pData, &nData) < 0) {
metaULock(pMeta);
- goto _err;
+ code = TSDB_CODE_NOT_FOUND;
+ goto _exit;
}
metaULock(pMeta);
@@ -536,15 +592,13 @@ int32_t metaGetTbTSchemaEx(SMeta *pMeta, tb_uid_t suid, tb_uid_t uid, int32_t sv
SSchema *pSchema = pSchemaWrapper->pSchema + i;
tdAddColToSchema(&sb, pSchema->type, pSchema->flags, pSchema->colId, pSchema->bytes);
}
- pTSchema = tdGetSchemaFromBuilder(&sb);
+ STSchema *pTSchema = tdGetSchemaFromBuilder(&sb);
tdDestroyTSchemaBuilder(&sb);
*ppTSchema = pTSchema;
taosMemoryFree(pSchemaWrapper->pSchema);
- return code;
-_err:
- *ppTSchema = NULL;
+_exit:
return code;
}
@@ -997,6 +1051,8 @@ int32_t metaGetTableTags(SMeta *pMeta, uint64_t suid, SArray *uidList, SHashObj
return TSDB_CODE_SUCCESS;
}
+int32_t metaCacheGet(SMeta *pMeta, int64_t uid, SMetaInfo *pInfo);
+
int32_t metaGetInfo(SMeta *pMeta, int64_t uid, SMetaInfo *pInfo) {
int32_t code = 0;
void *pData = NULL;
diff --git a/source/dnode/vnode/src/meta/metaTable.c b/source/dnode/vnode/src/meta/metaTable.c
index c1e59adbb0..aa107ab253 100644
--- a/source/dnode/vnode/src/meta/metaTable.c
+++ b/source/dnode/vnode/src/meta/metaTable.c
@@ -357,10 +357,7 @@ int metaAlterSTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) {
metaSaveToTbDb(pMeta, &nStbEntry);
// update uid index
- SMetaInfo info;
- metaGetEntryInfo(&nStbEntry, &info);
- tdbTbcUpsert(pUidIdxc, &pReq->suid, sizeof(tb_uid_t),
- &(SUidIdxVal){.suid = info.suid, .version = info.version, .skmVer = info.skmVer}, sizeof(SUidIdxVal), 0);
+ metaUpdateUidIdx(pMeta, &nStbEntry);
if (oStbEntry.pBuf) taosMemoryFree(oStbEntry.pBuf);
metaULock(pMeta);
@@ -884,7 +881,8 @@ static int metaUpdateTableTagVal(SMeta *pMeta, int64_t version, SVAlterTbReq *pA
}
SCtbIdxKey ctbIdxKey = {.suid = ctbEntry.ctbEntry.suid, .uid = uid};
- tdbTbUpsert(pMeta->pCtbIdx, &ctbIdxKey, sizeof(ctbIdxKey), ctbEntry.ctbEntry.pTags, ((STag*)(ctbEntry.ctbEntry.pTags))->len, &pMeta->txn);
+ tdbTbUpsert(pMeta->pCtbIdx, &ctbIdxKey, sizeof(ctbIdxKey), ctbEntry.ctbEntry.pTags,
+ ((STag *)(ctbEntry.ctbEntry.pTags))->len, &pMeta->txn);
tDecoderClear(&dc1);
tDecoderClear(&dc2);
@@ -1091,7 +1089,8 @@ static int metaUpdateTtlIdx(SMeta *pMeta, const SMetaEntry *pME) {
static int metaUpdateCtbIdx(SMeta *pMeta, const SMetaEntry *pME) {
SCtbIdxKey ctbIdxKey = {.suid = pME->ctbEntry.suid, .uid = pME->uid};
- return tdbTbInsert(pMeta->pCtbIdx, &ctbIdxKey, sizeof(ctbIdxKey), pME->ctbEntry.pTags, ((STag*)(pME->ctbEntry.pTags))->len, &pMeta->txn);
+ return tdbTbInsert(pMeta->pCtbIdx, &ctbIdxKey, sizeof(ctbIdxKey), pME->ctbEntry.pTags,
+ ((STag *)(pME->ctbEntry.pTags))->len, &pMeta->txn);
}
int metaCreateTagIdxKey(tb_uid_t suid, int32_t cid, const void *pTagData, int32_t nTagData, int8_t type, tb_uid_t uid,
diff --git a/source/dnode/vnode/src/sma/smaCommit.c b/source/dnode/vnode/src/sma/smaCommit.c
index 373cfdfb47..ca5367f397 100644
--- a/source/dnode/vnode/src/sma/smaCommit.c
+++ b/source/dnode/vnode/src/sma/smaCommit.c
@@ -83,8 +83,7 @@ int32_t smaBegin(SSma *pSma) {
return TSDB_CODE_SUCCESS;
}
- SSmaStat *pStat = SMA_ENV_STAT(pSmaEnv);
- SRSmaStat *pRSmaStat = SMA_RSMA_STAT(pStat);
+ SRSmaStat *pRSmaStat = (SRSmaStat *)SMA_ENV_STAT(pSmaEnv);
int8_t rsmaTriggerStat =
atomic_val_compare_exchange_8(RSMA_TRIGGER_STAT(pRSmaStat), TASK_TRIGGER_STAT_PAUSED, TASK_TRIGGER_STAT_ACTIVE);
@@ -110,7 +109,7 @@ int32_t smaBegin(SSma *pSma) {
/**
* @brief pre-commit for rollup sma(sync commit).
* 1) set trigger stat of rsma timer TASK_TRIGGER_STAT_PAUSED.
- * 2) wait all triggered fetch tasks finished
+ * 2) wait for all triggered fetch tasks to finish
* 3) perform persist task for qTaskInfo
*
* @param pSma
@@ -123,19 +122,19 @@ static int32_t tdProcessRSmaSyncPreCommitImpl(SSma *pSma) {
}
SSmaStat *pStat = SMA_ENV_STAT(pSmaEnv);
- SRSmaStat *pRSmaStat = SMA_RSMA_STAT(pStat);
+ SRSmaStat *pRSmaStat = SMA_STAT_RSMA(pStat);
// step 1: set rsma stat paused
atomic_store_8(RSMA_TRIGGER_STAT(pRSmaStat), TASK_TRIGGER_STAT_PAUSED);
- // step 2: wait all triggered fetch tasks finished
+ // step 2: wait for all triggered fetch tasks to finish
int32_t nLoops = 0;
while (1) {
if (T_REF_VAL_GET(pStat) == 0) {
- smaDebug("vgId:%d, rsma fetch tasks all finished", SMA_VID(pSma));
+ smaDebug("vgId:%d, rsma fetch tasks are all finished", SMA_VID(pSma));
break;
} else {
- smaDebug("vgId:%d, rsma fetch tasks not all finished yet", SMA_VID(pSma));
+ smaDebug("vgId:%d, rsma fetch tasks are not all finished yet", SMA_VID(pSma));
}
++nLoops;
if (nLoops > 1000) {
@@ -289,8 +288,7 @@ static int32_t tdProcessRSmaSyncPostCommitImpl(SSma *pSma) {
return TSDB_CODE_SUCCESS;
}
- SSmaEnv *pSmaEnv = SMA_RSMA_ENV(pSma);
- SRSmaStat *pRSmaStat = SMA_RSMA_STAT(SMA_ENV_STAT(pSmaEnv));
+ SRSmaStat *pRSmaStat = SMA_RSMA_STAT(pSma);
// cleanup outdated qtaskinfo files
tdCleanupQTaskInfoFiles(pSma, pRSmaStat);
@@ -299,10 +297,9 @@ static int32_t tdProcessRSmaSyncPostCommitImpl(SSma *pSma) {
}
/**
- * @brief Rsma async commit implementation
+ * @brief Rsma async commit implementation(only do some necessary light weighted task)
* 1) set rsma stat TASK_TRIGGER_STAT_PAUSED
* 2) Wait all running fetch task finish to fetch and put submitMsg into level 2/3 wQueue(blocking level 1 write)
- * 3)
*
* @param pSma
* @return int32_t
@@ -314,20 +311,22 @@ static int32_t tdProcessRSmaAsyncPreCommitImpl(SSma *pSma) {
}
SSmaStat *pStat = SMA_ENV_STAT(pEnv);
- SRSmaStat *pRSmaStat = SMA_RSMA_STAT(pStat);
+ SRSmaStat *pRSmaStat = SMA_STAT_RSMA(pStat);
// step 1: set rsma stat
atomic_store_8(RSMA_TRIGGER_STAT(pRSmaStat), TASK_TRIGGER_STAT_PAUSED);
atomic_store_8(RSMA_COMMIT_STAT(pRSmaStat), 1);
+ pRSmaStat->commitAppliedVer = pSma->pVnode->state.applied;
+ ASSERT(pRSmaStat->commitAppliedVer > 0);
- // step 2: wait all triggered fetch tasks finished
+ // step 2: wait for all triggered fetch tasks to finish
int32_t nLoops = 0;
while (1) {
if (T_REF_VAL_GET(pStat) == 0) {
- smaDebug("vgId:%d, rsma fetch tasks all finished", SMA_VID(pSma));
+ smaDebug("vgId:%d, rsma commit, fetch tasks are all finished", SMA_VID(pSma));
break;
} else {
- smaDebug("vgId:%d, rsma fetch tasks not all finished yet", SMA_VID(pSma));
+ smaDebug("vgId:%d, rsma commit, fetch tasks are not all finished yet", SMA_VID(pSma));
}
++nLoops;
if (nLoops > 1000) {
@@ -336,29 +335,51 @@ static int32_t tdProcessRSmaAsyncPreCommitImpl(SSma *pSma) {
}
}
- // step 3: swap rsmaInfoHash and iRsmaInfoHash
- // lock
- taosWLockLatch(SMA_ENV_LOCK(pEnv));
-
- ASSERT(RSMA_INFO_HASH(pRSmaStat));
- ASSERT(!RSMA_IMU_INFO_HASH(pRSmaStat));
-
- RSMA_IMU_INFO_HASH(pRSmaStat) = RSMA_INFO_HASH(pRSmaStat);
- RSMA_INFO_HASH(pRSmaStat) =
- taosHashInit(RSMA_TASK_INFO_HASH_SLOT, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, HASH_ENTRY_LOCK);
-
- if (!RSMA_INFO_HASH(pRSmaStat)) {
- // unlock
- taosWUnLockLatch(SMA_ENV_LOCK(pEnv));
- smaError("vgId:%d, rsma async commit failed since %s", SMA_VID(pSma), terrstr());
+ /**
+ * @brief step 3: consume the SubmitReq in buffer
+ * 1) This is high cost task and should not put in asyncPreCommit originally.
+ * 2) But, if put in asyncCommit, would trigger taskInfo cloning frequently.
+ */
+ if (tdRSmaProcessExecImpl(pSma, RSMA_EXEC_COMMIT) < 0) {
return TSDB_CODE_FAILED;
}
- // unlock
- taosWUnLockLatch(SMA_ENV_LOCK(pEnv));
+ smaInfo("vgId:%d, rsma commit, wait for all items to be consumed, TID:%p", SMA_VID(pSma), (void*)taosGetSelfPthreadId());
+ nLoops = 0;
+ while (atomic_load_64(&pRSmaStat->nBufItems) > 0) {
+ ++nLoops;
+ if (nLoops > 1000) {
+ sched_yield();
+ nLoops = 0;
+ }
+ }
+ smaInfo("vgId:%d, rsma commit, all items are consumed, TID:%p", SMA_VID(pSma), (void *)taosGetSelfPthreadId());
+ if (tdRSmaPersistExecImpl(pRSmaStat, RSMA_INFO_HASH(pRSmaStat)) < 0) {
+ return TSDB_CODE_FAILED;
+ }
+ smaInfo("vgId:%d, rsma commit, operator state commited, TID:%p", SMA_VID(pSma), (void *)taosGetSelfPthreadId());
- // step 4: others
- pRSmaStat->commitAppliedVer = pSma->pVnode->state.applied;
+#if 0 // consuming task of qTaskInfo clone
+ // step 4: swap queue/qall and iQueue/iQall
+ // lock
+ // taosWLockLatch(SMA_ENV_LOCK(pEnv));
+
+ ASSERT(RSMA_INFO_HASH(pRSmaStat));
+
+ void *pIter = taosHashIterate(RSMA_INFO_HASH(pRSmaStat), NULL);
+
+ while (pIter) {
+ SRSmaInfo *pInfo = *(SRSmaInfo **)pIter;
+ TSWAP(pInfo->iQall, pInfo->qall);
+ TSWAP(pInfo->iQueue, pInfo->queue);
+ TSWAP(pInfo->iTaskInfo[0], pInfo->taskInfo[0]);
+ TSWAP(pInfo->iTaskInfo[1], pInfo->taskInfo[1]);
+ pIter = taosHashIterate(RSMA_INFO_HASH(pRSmaStat), pIter);
+ }
+
+ // unlock
+ // taosWUnLockLatch(SMA_ENV_LOCK(pEnv));
+#endif
return TSDB_CODE_SUCCESS;
}
@@ -374,18 +395,20 @@ static int32_t tdProcessRSmaAsyncCommitImpl(SSma *pSma) {
if (!pSmaEnv) {
return TSDB_CODE_SUCCESS;
}
+#if 0
+ SRSmaStat *pRSmaStat = (SRSmaStat *)SMA_ENV_STAT(pSmaEnv);
- SSmaStat *pStat = SMA_ENV_STAT(pSmaEnv);
- SRSmaStat *pRSmaStat = SMA_RSMA_STAT(pStat);
-
- // perform persist task for qTaskInfo
- tdRSmaPersistExecImpl(pRSmaStat, RSMA_IMU_INFO_HASH(pRSmaStat));
+ // perform persist task for qTaskInfo operator
+ if (tdRSmaPersistExecImpl(pRSmaStat, RSMA_INFO_HASH(pRSmaStat)) < 0) {
+ return TSDB_CODE_FAILED;
+ }
+#endif
return TSDB_CODE_SUCCESS;
}
/**
- * @brief Migrate rsmaInfo from iRsmaInfo to rsmaInfo if rsmaInfoHash not empty.
+ * @brief Migrate rsmaInfo from iRsmaInfo to rsmaInfo if rsma infoHash not empty.
*
* @param pSma
* @return int32_t
@@ -396,68 +419,66 @@ static int32_t tdProcessRSmaAsyncPostCommitImpl(SSma *pSma) {
return TSDB_CODE_SUCCESS;
}
- SSmaStat *pStat = SMA_ENV_STAT(pEnv);
- SRSmaStat *pRSmaStat = SMA_RSMA_STAT(pStat);
+ SRSmaStat *pRSmaStat = (SRSmaStat *)SMA_ENV_STAT(pEnv);
+ SArray *rsmaDeleted = NULL;
- // step 1: merge rsmaInfoHash and iRsmaInfoHash
+ // step 1: merge qTaskInfo and iQTaskInfo
// lock
- taosWLockLatch(SMA_ENV_LOCK(pEnv));
-#if 0
- if (taosHashGetSize(RSMA_INFO_HASH(pRSmaStat)) <= 0) {
- // just switch the hash pointer if rsmaInfoHash is empty
- if (taosHashGetSize(RSMA_IMU_INFO_HASH(pRSmaStat)) > 0) {
- SHashObj *infoHash = RSMA_INFO_HASH(pRSmaStat);
- RSMA_INFO_HASH(pRSmaStat) = RSMA_IMU_INFO_HASH(pRSmaStat);
- RSMA_IMU_INFO_HASH(pRSmaStat) = infoHash;
- }
- } else {
-#endif
-#if 1
- void *pIter = taosHashIterate(RSMA_IMU_INFO_HASH(pRSmaStat), NULL);
- while (pIter) {
- tb_uid_t *pSuid = (tb_uid_t *)taosHashGetKey(pIter, NULL);
+ // taosWLockLatch(SMA_ENV_LOCK(pEnv));
- if (!taosHashGet(RSMA_INFO_HASH(pRSmaStat), pSuid, sizeof(tb_uid_t))) {
- SRSmaInfo *pRSmaInfo = *(SRSmaInfo **)pIter;
- if (RSMA_INFO_IS_DEL(pRSmaInfo)) {
- int32_t refVal = T_REF_VAL_GET(pRSmaInfo);
- if (refVal == 0) {
- tdFreeRSmaInfo(pSma, pRSmaInfo, true);
- smaDebug(
- "vgId:%d, rsma async post commit, free rsma info since already deleted and ref is 0 for "
- "table:%" PRIi64,
- SMA_VID(pSma), *pSuid);
- } else {
- smaDebug(
- "vgId:%d, rsma async post commit, not free rsma info since ref is %d although already deleted for "
- "table:%" PRIi64,
- SMA_VID(pSma), refVal, *pSuid);
+ void *pIter = NULL;
+ while ((pIter = taosHashIterate(RSMA_INFO_HASH(pRSmaStat), pIter))) {
+ tb_uid_t *pSuid = (tb_uid_t *)taosHashGetKey(pIter, NULL);
+ SRSmaInfo *pRSmaInfo = *(SRSmaInfo **)pIter;
+ if (RSMA_INFO_IS_DEL(pRSmaInfo)) {
+ int32_t refVal = T_REF_VAL_GET(pRSmaInfo);
+ if (refVal == 0) {
+ if (!rsmaDeleted) {
+ if ((rsmaDeleted = taosArrayInit(1, sizeof(tb_uid_t)))) {
+ taosArrayPush(rsmaDeleted, pSuid);
+ }
}
-
- pIter = taosHashIterate(RSMA_IMU_INFO_HASH(pRSmaStat), pIter);
- continue;
+ } else {
+ smaDebug(
+ "vgId:%d, rsma async post commit, not free rsma info since ref is %d although already deleted for "
+ "table:%" PRIi64,
+ SMA_VID(pSma), refVal, *pSuid);
+ }
+
+ continue;
+ }
+#if 0
+ if (pRSmaInfo->taskInfo[0]) {
+ if (pRSmaInfo->iTaskInfo[0]) {
+ SRSmaInfo *pRSmaInfo = *(SRSmaInfo **)pRSmaInfo->iTaskInfo[0];
+ tdFreeRSmaInfo(pSma, pRSmaInfo, false);
+ pRSmaInfo->iTaskInfo[0] = NULL;
}
- taosHashPut(RSMA_INFO_HASH(pRSmaStat), pSuid, sizeof(tb_uid_t), pIter, sizeof(pIter));
- smaDebug("vgId:%d, rsma async post commit, migrated from iRsmaInfoHash for table:%" PRIi64, SMA_VID(pSma),
- *pSuid);
} else {
- // free the resources
- SRSmaInfo *pRSmaInfo = *(SRSmaInfo **)pIter;
- tdFreeRSmaInfo(pSma, pRSmaInfo, false);
- smaDebug("vgId:%d, rsma async post commit, free rsma info since already COW for table:%" PRIi64, SMA_VID(pSma),
- *pSuid);
+ TSWAP(pRSmaInfo->taskInfo[0], pRSmaInfo->iTaskInfo[0]);
}
- pIter = taosHashIterate(RSMA_IMU_INFO_HASH(pRSmaStat), pIter);
- }
+ taosHashPut(RSMA_INFO_HASH(pRSmaStat), pSuid, sizeof(tb_uid_t), pIter, sizeof(pIter));
+ smaDebug("vgId:%d, rsma async post commit, migrated from iRsmaInfoHash for table:%" PRIi64, SMA_VID(pSma), *pSuid);
#endif
- // }
+ }
- taosHashCleanup(RSMA_IMU_INFO_HASH(pRSmaStat));
- RSMA_IMU_INFO_HASH(pRSmaStat) = NULL;
+ for (int32_t i = 0; i < taosArrayGetSize(rsmaDeleted); ++i) {
+ tb_uid_t *pSuid = taosArrayGet(rsmaDeleted, i);
+ void *pRSmaInfo = taosHashGet(RSMA_INFO_HASH(pRSmaStat), pSuid, sizeof(tb_uid_t));
+ if ((pRSmaInfo = *(SRSmaInfo **)pRSmaInfo)) {
+ tdFreeRSmaInfo(pSma, pRSmaInfo, true);
+ smaDebug(
+ "vgId:%d, rsma async post commit, free rsma info since already deleted and ref is 0 for "
+ "table:%" PRIi64,
+ SMA_VID(pSma), *pSuid);
+ }
+ taosHashRemove(RSMA_INFO_HASH(pRSmaStat), pSuid, sizeof(tb_uid_t));
+ }
+ taosArrayDestroy(rsmaDeleted);
// unlock
- taosWUnLockLatch(SMA_ENV_LOCK(pEnv));
+ // taosWUnLockLatch(SMA_ENV_LOCK(pEnv));
// step 2: cleanup outdated qtaskinfo files
tdCleanupQTaskInfoFiles(pSma, pRSmaStat);
diff --git a/source/dnode/vnode/src/sma/smaEnv.c b/source/dnode/vnode/src/sma/smaEnv.c
index ccb6ad3a72..e3b83f9955 100644
--- a/source/dnode/vnode/src/sma/smaEnv.c
+++ b/source/dnode/vnode/src/sma/smaEnv.c
@@ -171,7 +171,7 @@ int32_t tdUnRefSmaStat(SSma *pSma, SSmaStat *pStat) {
int32_t tdRefRSmaInfo(SSma *pSma, SRSmaInfo *pRSmaInfo) {
if (!pRSmaInfo) return 0;
-
+
int ref = T_REF_INC(pRSmaInfo);
smaDebug("vgId:%d, ref rsma info:%p, val:%d", SMA_VID(pSma), pRSmaInfo, ref);
return 0;
@@ -209,6 +209,7 @@ static int32_t tdInitSmaStat(SSmaStat **pSmaStat, int8_t smaType, const SSma *pS
SRSmaStat *pRSmaStat = (SRSmaStat *)(*pSmaStat);
pRSmaStat->pSma = (SSma *)pSma;
atomic_store_8(RSMA_TRIGGER_STAT(pRSmaStat), TASK_TRIGGER_STAT_INIT);
+ tsem_init(&pRSmaStat->notEmpty, 0, 0);
// init smaMgmt
smaInit();
@@ -228,7 +229,6 @@ static int32_t tdInitSmaStat(SSmaStat **pSmaStat, int8_t smaType, const SSma *pS
RSMA_INFO_HASH(pRSmaStat) = taosHashInit(
RSMA_TASK_INFO_HASH_SLOT, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, HASH_ENTRY_LOCK);
if (!RSMA_INFO_HASH(pRSmaStat)) {
- taosMemoryFreeClear(*pSmaStat);
return TSDB_CODE_FAILED;
}
} else if (smaType == TSDB_SMA_TYPE_TIME_RANGE) {
@@ -262,10 +262,9 @@ static void tdDestroyRSmaStat(void *pRSmaStat) {
smaDebug("vgId:%d, destroy rsma stat %p", SMA_VID(pSma), pRSmaStat);
// step 1: set rsma trigger stat cancelled
atomic_store_8(RSMA_TRIGGER_STAT(pStat), TASK_TRIGGER_STAT_CANCELLED);
+ tsem_destroy(&(pStat->notEmpty));
// step 2: destroy the rsma info and associated fetch tasks
- // TODO: use taosHashSetFreeFp when taosHashSetFreeFp is ready.
-#if 1
if (taosHashGetSize(RSMA_INFO_HASH(pStat)) > 0) {
void *infoHash = taosHashIterate(RSMA_INFO_HASH(pStat), NULL);
while (infoHash) {
@@ -274,17 +273,16 @@ static void tdDestroyRSmaStat(void *pRSmaStat) {
infoHash = taosHashIterate(RSMA_INFO_HASH(pStat), infoHash);
}
}
-#endif
taosHashCleanup(RSMA_INFO_HASH(pStat));
- // step 3: wait all triggered fetch tasks finished
+ // step 3: wait for all triggered fetch tasks to finish
int32_t nLoops = 0;
while (1) {
if (T_REF_VAL_GET((SSmaStat *)pStat) == 0) {
- smaDebug("vgId:%d, rsma fetch tasks all finished", SMA_VID(pSma));
+ smaDebug("vgId:%d, rsma fetch tasks are all finished", SMA_VID(pSma));
break;
} else {
- smaDebug("vgId:%d, rsma fetch tasks not all finished yet", SMA_VID(pSma));
+ smaDebug("vgId:%d, rsma fetch tasks are not all finished yet", SMA_VID(pSma));
}
++nLoops;
if (nLoops > 1000) {
@@ -293,7 +291,7 @@ static void tdDestroyRSmaStat(void *pRSmaStat) {
}
}
- // step 4: free pStat
+ // step 5: free pStat
taosMemoryFreeClear(pStat);
}
}
@@ -318,9 +316,9 @@ void *tdFreeSmaState(SSmaStat *pSmaStat, int8_t smaType) {
int32_t tdDestroySmaState(SSmaStat *pSmaStat, int8_t smaType) {
if (pSmaStat) {
if (smaType == TSDB_SMA_TYPE_TIME_RANGE) {
- tdDestroyTSmaStat(SMA_TSMA_STAT(pSmaStat));
+ tdDestroyTSmaStat(SMA_STAT_TSMA(pSmaStat));
} else if (smaType == TSDB_SMA_TYPE_ROLLUP) {
- SRSmaStat *pRSmaStat = SMA_RSMA_STAT(pSmaStat);
+ SRSmaStat *pRSmaStat = &pSmaStat->rsmaStat;
int32_t vid = SMA_VID(pRSmaStat->pSma);
int64_t refId = RSMA_REF_ID(pRSmaStat);
if (taosRemoveRef(smaMgmt.rsetId, RSMA_REF_ID(pRSmaStat)) < 0) {
diff --git a/source/dnode/vnode/src/sma/smaOpen.c b/source/dnode/vnode/src/sma/smaOpen.c
index 235fb1f941..e2710b26e3 100644
--- a/source/dnode/vnode/src/sma/smaOpen.c
+++ b/source/dnode/vnode/src/sma/smaOpen.c
@@ -146,6 +146,20 @@ int32_t smaClose(SSma *pSma) {
return 0;
}
+int32_t smaPreClose(SSma *pSma) {
+ if (pSma && VND_IS_RSMA(pSma->pVnode)) {
+ SSmaEnv *pEnv = NULL;
+ SRSmaStat *pStat = NULL;
+ if (!(pEnv = SMA_RSMA_ENV(pSma)) || !(pStat = (SRSmaStat *)SMA_ENV_STAT(pEnv))) {
+ return 0;
+ }
+ for (int32_t i = 0; i < RSMA_EXECUTOR_MAX; ++i) {
+ tsem_post(&(pStat->notEmpty));
+ }
+ }
+ return 0;
+}
+
/**
* @brief rsma env restore
*
diff --git a/source/dnode/vnode/src/sma/smaRollup.c b/source/dnode/vnode/src/sma/smaRollup.c
index b7a2efd489..448b8ab508 100644
--- a/source/dnode/vnode/src/sma/smaRollup.c
+++ b/source/dnode/vnode/src/sma/smaRollup.c
@@ -15,8 +15,12 @@
#include "sma.h"
-#define RSMA_QTASKINFO_BUFSIZE 32768
-#define RSMA_QTASKINFO_HEAD_LEN (sizeof(int32_t) + sizeof(int8_t) + sizeof(int64_t)) // len + type + suid
+#define RSMA_QTASKINFO_BUFSIZE (32768) // size
+#define RSMA_QTASKINFO_HEAD_LEN (sizeof(int32_t) + sizeof(int8_t) + sizeof(int64_t)) // len + type + suid
+#define RSMA_QTASKEXEC_SMOOTH_SIZE (100) // cnt
+#define RSMA_SUBMIT_BATCH_SIZE (1024) // cnt
+#define RSMA_FETCH_DELAY_MAX (900000) // ms
+#define RSMA_FETCH_ACTIVE_MAX (1800) // ms
SSmaMgmt smaMgmt = {
.inited = 0,
@@ -27,19 +31,21 @@ SSmaMgmt smaMgmt = {
#define TD_RSMAINFO_DEL_FILE "rsmainfo.del"
typedef struct SRSmaQTaskInfoItem SRSmaQTaskInfoItem;
typedef struct SRSmaQTaskInfoIter SRSmaQTaskInfoIter;
+typedef struct SRSmaExecQItem SRSmaExecQItem;
static int32_t tdUidStorePut(STbUidStore *pStore, tb_uid_t suid, tb_uid_t *uid);
static int32_t tdUpdateTbUidListImpl(SSma *pSma, tb_uid_t *suid, SArray *tbUids);
static int32_t tdSetRSmaInfoItemParams(SSma *pSma, SRSmaParam *param, SRSmaStat *pStat, SRSmaInfo *pRSmaInfo,
int8_t idx);
-static int32_t tdExecuteRSmaImpl(SSma *pSma, const void *pMsg, int32_t inputType, SRSmaInfo *pInfo, tb_uid_t suid,
- int8_t level);
+static int32_t tdExecuteRSmaImpl(SSma *pSma, const void *pMsg, int32_t msgSize, int32_t inputType, SRSmaInfo *pInfo,
+ ERsmaExecType type, int8_t level);
static SRSmaInfo *tdAcquireRSmaInfoBySuid(SSma *pSma, int64_t suid);
static void tdReleaseRSmaInfo(SSma *pSma, SRSmaInfo *pInfo);
-static int32_t tdRSmaFetchAndSubmitResult(SSma *pSma, qTaskInfo_t taskInfo, SRSmaInfoItem *pItem, STSchema *pTSchema,
- int64_t suid, int8_t blkType);
+static void tdFreeRSmaSubmitItems(SArray *pItems);
+static int32_t tdRSmaFetchAllResult(SSma *pSma, SRSmaInfo *pInfo, SArray *pSubmitArr);
+static int32_t tdRSmaExecAndSubmitResult(SSma *pSma, qTaskInfo_t taskInfo, SRSmaInfoItem *pItem, STSchema *pTSchema,
+ int64_t suid);
static void tdRSmaFetchTrigger(void *param, void *tmrId);
-static int32_t tdRSmaFetchSend(SSma *pSma, SRSmaInfo *pInfo, int8_t level);
static int32_t tdRSmaQTaskInfoIterInit(SRSmaQTaskInfoIter *pIter, STFile *pTFile);
static int32_t tdRSmaQTaskInfoIterNextBlock(SRSmaQTaskInfoIter *pIter, bool *isFinish);
static int32_t tdRSmaQTaskInfoRestore(SSma *pSma, int8_t type, SRSmaQTaskInfoIter *pIter);
@@ -76,6 +82,11 @@ struct SRSmaQTaskInfoIter {
int32_t nBufPos;
};
+struct SRSmaExecQItem {
+ void *pRSmaInfo;
+ void *qall;
+};
+
void tdRSmaQTaskInfoGetFileName(int32_t vgId, int64_t version, char *outputName) {
tdGetVndFileName(vgId, NULL, VNODE_RSMA_DIR, TD_QTASKINFO_FNAME_PREFIX, version, outputName);
}
@@ -139,6 +150,18 @@ void *tdFreeRSmaInfo(SSma *pSma, SRSmaInfo *pInfo, bool isDeepFree) {
if (isDeepFree) {
taosMemoryFreeClear(pInfo->pTSchema);
}
+
+ if (isDeepFree) {
+ if (pInfo->queue) taosCloseQueue(pInfo->queue);
+ if (pInfo->qall) taosFreeQall(pInfo->qall);
+ if (pInfo->iQueue) taosCloseQueue(pInfo->iQueue);
+ if (pInfo->iQall) taosFreeQall(pInfo->iQall);
+ pInfo->queue = NULL;
+ pInfo->qall = NULL;
+ pInfo->iQueue = NULL;
+ pInfo->iQall = NULL;
+ }
+
taosMemoryFree(pInfo);
}
@@ -179,7 +202,7 @@ static int32_t tdUpdateTbUidListImpl(SSma *pSma, tb_uid_t *suid, SArray *tbUids)
for (int32_t i = 0; i < TSDB_RETENTION_L2; ++i) {
if (pRSmaInfo->taskInfo[i]) {
- if ((qUpdateQualifiedTableId(pRSmaInfo->taskInfo[i], tbUids, true) < 0)) {
+ if (((terrno = qUpdateQualifiedTableId(pRSmaInfo->taskInfo[i], tbUids, true)) < 0)) {
tdReleaseRSmaInfo(pSma, pRSmaInfo);
smaError("vgId:%d, update tbUidList failed for uid:%" PRIi64 " level %d since %s", SMA_VID(pSma), *suid, i,
terrstr());
@@ -351,6 +374,19 @@ int32_t tdProcessRSmaCreateImpl(SSma *pSma, SRSmaParam *param, int64_t suid, con
goto _err;
}
pRSmaInfo->pTSchema = pTSchema;
+ if (!(pRSmaInfo->queue = taosOpenQueue())) {
+ goto _err;
+ }
+
+ if (!(pRSmaInfo->qall = taosAllocateQall())) {
+ goto _err;
+ }
+ if (!(pRSmaInfo->iQueue = taosOpenQueue())) {
+ goto _err;
+ }
+ if (!(pRSmaInfo->iQall = taosAllocateQall())) {
+ goto _err;
+ }
pRSmaInfo->suid = suid;
pRSmaInfo->refId = RSMA_REF_ID(pStat);
T_REF_INIT_VAL(pRSmaInfo, 1);
@@ -419,8 +455,7 @@ int32_t tdProcessRSmaDrop(SSma *pSma, SVDropStbReq *pReq) {
return TSDB_CODE_SUCCESS;
}
- SSmaStat *pStat = SMA_ENV_STAT(pSmaEnv);
- SRSmaStat *pRSmaStat = SMA_RSMA_STAT(pStat);
+ SRSmaStat *pRSmaStat = (SRSmaStat *)SMA_ENV_STAT(pSmaEnv);
SRSmaInfo *pRSmaInfo = tdAcquireRSmaInfoBySuid(pSma, pReq->suid);
@@ -528,6 +563,14 @@ void *tdUidStoreFree(STbUidStore *pStore) {
return NULL;
}
+/**
+ * @brief The SubmitReq for rsma L2/L3 is inserted by tsdbInsertData method directly while not by WriteQ, as the queue
+ * would be freed when close Vnode, thus lock should be used if with race condition.
+ * @param pTsdb
+ * @param version
+ * @param pReq
+ * @return int32_t
+ */
static int32_t tdProcessSubmitReq(STsdb *pTsdb, int64_t version, void *pReq) {
if (!pReq) {
terrno = TSDB_CODE_INVALID_PTR;
@@ -535,7 +578,7 @@ static int32_t tdProcessSubmitReq(STsdb *pTsdb, int64_t version, void *pReq) {
}
SSubmitReq *pSubmitReq = (SSubmitReq *)pReq;
-
+ // TODO: spin lock for race conditiond
if (tsdbInsertData(pTsdb, version, pSubmitReq, NULL) < 0) {
return TSDB_CODE_FAILED;
}
@@ -569,17 +612,6 @@ static int32_t tdFetchSubmitReqSuids(SSubmitReq *pMsg, STbUidStore *pStore) {
return 0;
}
-static void tdDestroySDataBlockArray(SArray *pArray) {
- // TODO
-#if 0
- for (int32_t i = 0; i < taosArrayGetSize(pArray); ++i) {
- SSDataBlock *pDataBlock = taosArrayGet(pArray, i);
- blockDestroyInner(pDataBlock);
- }
-#endif
- taosArrayDestroy(pArray);
-}
-
/**
* @brief retention of rsma1/rsma2
*
@@ -604,8 +636,8 @@ _end:
return code;
}
-static int32_t tdRSmaFetchAndSubmitResult(SSma *pSma, qTaskInfo_t taskInfo, SRSmaInfoItem *pItem, STSchema *pTSchema,
- int64_t suid, int8_t blkType) {
+static int32_t tdRSmaExecAndSubmitResult(SSma *pSma, qTaskInfo_t taskInfo, SRSmaInfoItem *pItem, STSchema *pTSchema,
+ int64_t suid) {
SArray *pResList = taosArrayInit(1, POINTER_BYTES);
if (pResList == NULL) {
terrno = TSDB_CODE_OUT_OF_MEMORY;
@@ -615,7 +647,7 @@ static int32_t tdRSmaFetchAndSubmitResult(SSma *pSma, qTaskInfo_t taskInfo, SRSm
while (1) {
uint64_t ts;
int32_t code = qExecTaskOpt(taskInfo, pResList, &ts);
- if (code < 0) {
+ if (code < 0) {
if (code == TSDB_CODE_QRY_IN_EXEC) {
break;
} else {
@@ -637,8 +669,7 @@ static int32_t tdRSmaFetchAndSubmitResult(SSma *pSma, qTaskInfo_t taskInfo, SRSm
} else {
smaDebug("vgId:%d, rsma %" PRIi8 " data fetched", SMA_VID(pSma), pItem->level);
}
-
-#if 1
+#if 0
char flag[10] = {0};
snprintf(flag, 10, "level %" PRIi8, pItem->level);
blockDebugShowDataBlocks(pResList, flag);
@@ -662,10 +693,9 @@ static int32_t tdRSmaFetchAndSubmitResult(SSma *pSma, qTaskInfo_t taskInfo, SRSm
goto _err;
}
taosMemoryFreeClear(pReq);
-
+
smaDebug("vgId:%d, process submit req for rsma table %" PRIi64 " level %" PRIi8 " version:%" PRIi64,
SMA_VID(pSma), suid, pItem->level, output->info.version);
-
}
}
@@ -677,34 +707,115 @@ _err:
return TSDB_CODE_FAILED;
}
-static int32_t tdExecuteRSmaImpl(SSma *pSma, const void *pMsg, int32_t inputType, SRSmaInfo *pInfo, tb_uid_t suid,
- int8_t level) {
+/**
+ * @brief Copy msg to rsmaQueueBuffer for batch process
+ *
+ * @param pSma
+ * @param pMsg
+ * @param inputType
+ * @param pInfo
+ * @param suid
+ * @return int32_t
+ */
+static int32_t tdExecuteRSmaImplAsync(SSma *pSma, const void *pMsg, int32_t inputType, SRSmaInfo *pInfo,
+ tb_uid_t suid) {
+ const SSubmitReq *pReq = (const SSubmitReq *)pMsg;
+
+ void *qItem = taosAllocateQitem(pReq->header.contLen, DEF_QITEM);
+ if (!qItem) {
+ return TSDB_CODE_FAILED;
+ }
+
+ memcpy(qItem, pMsg, pReq->header.contLen);
+
+ taosWriteQitem(pInfo->queue, qItem);
+
+ pInfo->lastRecv = taosGetTimestampMs();
+
+ SRSmaStat *pRSmaStat = SMA_RSMA_STAT(pSma);
+
+ tsem_post(&(pRSmaStat->notEmpty));
+
+ int64_t nItems = atomic_fetch_add_64(&pRSmaStat->nBufItems, 1);
+
+ // smoothing consume
+ int32_t n = nItems / RSMA_QTASKEXEC_SMOOTH_SIZE;
+ if (n > 1) {
+ if (n > 10) {
+ n = 10;
+ }
+ taosMsleep(n << 3);
+ if (n > 5) {
+ smaWarn("vgId:%d, pInfo->queue itemSize:%d, memSize:%" PRIi64 ", sleep %d ms", SMA_VID(pSma),
+ taosQueueItemSize(pInfo->queue), taosQueueMemorySize(pInfo->queue), n << 3);
+ }
+ }
+
+ return TSDB_CODE_SUCCESS;
+}
+
+static int32_t tdRsmaPrintSubmitReq(SSma *pSma, SSubmitReq *pReq) {
+ SSubmitMsgIter msgIter = {0};
+ SSubmitBlkIter blkIter = {0};
+ STSRow *row = NULL;
+ if (tInitSubmitMsgIter(pReq, &msgIter) < 0) return -1;
+ while (true) {
+ SSubmitBlk *pBlock = NULL;
+ if (tGetSubmitMsgNext(&msgIter, &pBlock) < 0) return -1;
+ if (pBlock == NULL) break;
+ tInitSubmitBlkIter(&msgIter, pBlock, &blkIter);
+ while ((row = tGetSubmitBlkNext(&blkIter)) != NULL) {
+ smaDebug("vgId:%d, numOfRows:%d, suid:%" PRIi64 ", uid:%" PRIi64 ", version:%" PRIi64 ", ts:%" PRIi64,
+ SMA_VID(pSma), msgIter.numOfRows, msgIter.suid, msgIter.uid, pReq->version, row->ts);
+ }
+ }
+ return 0;
+}
+
+/**
+ * @brief sync mode
+ *
+ * @param pSma
+ * @param pMsg
+ * @param msgSize
+ * @param inputType
+ * @param pInfo
+ * @param type
+ * @param level
+ * @return int32_t
+ */
+static int32_t tdExecuteRSmaImpl(SSma *pSma, const void *pMsg, int32_t msgSize, int32_t inputType, SRSmaInfo *pInfo,
+ ERsmaExecType type, int8_t level) {
int32_t idx = level - 1;
- if (!pInfo || !RSMA_INFO_QTASK(pInfo, idx)) {
- smaDebug("vgId:%d, no qTaskInfo to execute rsma %" PRIi8 " task for suid:%" PRIu64, SMA_VID(pSma), level, suid);
+
+ void *qTaskInfo = (type == RSMA_EXEC_COMMIT) ? RSMA_INFO_IQTASK(pInfo, idx) : RSMA_INFO_QTASK(pInfo, idx);
+ if (!qTaskInfo) {
+ smaDebug("vgId:%d, no qTaskInfo to execute rsma %" PRIi8 " task for suid:%" PRIu64, SMA_VID(pSma), level,
+ pInfo->suid);
return TSDB_CODE_SUCCESS;
}
if (!pInfo->pTSchema) {
- smaWarn("vgId:%d, no schema to execute rsma %" PRIi8 " task for suid:%" PRIu64, SMA_VID(pSma), level, suid);
+ smaWarn("vgId:%d, no schema to execute rsma %" PRIi8 " task for suid:%" PRIu64, SMA_VID(pSma), level, pInfo->suid);
return TSDB_CODE_FAILED;
}
smaDebug("vgId:%d, execute rsma %" PRIi8 " task for qTaskInfo:%p suid:%" PRIu64, SMA_VID(pSma), level,
- RSMA_INFO_QTASK(pInfo, idx), suid);
+ RSMA_INFO_QTASK(pInfo, idx), pInfo->suid);
- if (qSetMultiStreamInput(RSMA_INFO_QTASK(pInfo, idx), pMsg, 1, inputType) < 0) { // INPUT__DATA_SUBMIT
+#if 0
+ for (int32_t i = 0; i < msgSize; ++i) {
+ SSubmitReq *pReq = *(SSubmitReq **)((char *)pMsg + i * sizeof(void *));
+ smaDebug("vgId:%d, [%d][%d] version %" PRIi64, SMA_VID(pSma), msgSize, i, pReq->version);
+ tdRsmaPrintSubmitReq(pSma, pReq);
+ }
+#endif
+ if (qSetMultiStreamInput(qTaskInfo, pMsg, msgSize, inputType) < 0) {
smaError("vgId:%d, rsma %" PRIi8 " qSetStreamInput failed since %s", SMA_VID(pSma), level, tstrerror(terrno));
return TSDB_CODE_FAILED;
}
SRSmaInfoItem *pItem = RSMA_INFO_ITEM(pInfo, idx);
- tdRSmaFetchAndSubmitResult(pSma, RSMA_INFO_QTASK(pInfo, idx), pItem, pInfo->pTSchema, suid,
- STREAM_INPUT__DATA_SUBMIT);
- atomic_store_8(&pItem->triggerStat, TASK_TRIGGER_STAT_ACTIVE);
-
- if (smaMgmt.tmrHandle) {
- taosTmrReset(tdRSmaFetchTrigger, pItem->maxDelay, pItem, smaMgmt.tmrHandle, &pItem->tmrId);
- }
+ tdRSmaExecAndSubmitResult(pSma, qTaskInfo, pItem, pInfo->pTSchema, pInfo->suid);
return TSDB_CODE_SUCCESS;
}
@@ -732,58 +843,27 @@ static SRSmaInfo *tdAcquireRSmaInfoBySuid(SSma *pSma, int64_t suid) {
return NULL;
}
- taosRLockLatch(SMA_ENV_LOCK(pEnv));
+ // taosRLockLatch(SMA_ENV_LOCK(pEnv));
pRSmaInfo = taosHashGet(RSMA_INFO_HASH(pStat), &suid, sizeof(tb_uid_t));
if (pRSmaInfo && (pRSmaInfo = *(SRSmaInfo **)pRSmaInfo)) {
if (RSMA_INFO_IS_DEL(pRSmaInfo)) {
- taosRUnLockLatch(SMA_ENV_LOCK(pEnv));
+ // taosRUnLockLatch(SMA_ENV_LOCK(pEnv));
return NULL;
}
- tdRefRSmaInfo(pSma, pRSmaInfo);
- taosRUnLockLatch(SMA_ENV_LOCK(pEnv));
- return pRSmaInfo;
- }
- taosRUnLockLatch(SMA_ENV_LOCK(pEnv));
-
- if (RSMA_COMMIT_STAT(pStat) == 0) { // return NULL if not in committing stat
- return NULL;
- }
-
- // clone the SRSmaInfo from iRsmaInfoHash to rsmaInfoHash if in committing stat
- SRSmaInfo *pCowRSmaInfo = NULL;
- // lock
- taosWLockLatch(SMA_ENV_LOCK(pEnv));
- if (!(pCowRSmaInfo = taosHashGet(RSMA_INFO_HASH(pStat), &suid, sizeof(tb_uid_t)))) { // 2-phase lock
- void *iRSmaInfo = taosHashGet(RSMA_IMU_INFO_HASH(pStat), &suid, sizeof(tb_uid_t));
- if (iRSmaInfo) {
- SRSmaInfo *pIRSmaInfo = *(SRSmaInfo **)iRSmaInfo;
- if (pIRSmaInfo && !RSMA_INFO_IS_DEL(pIRSmaInfo)) {
- if (tdCloneRSmaInfo(pSma, &pCowRSmaInfo, pIRSmaInfo) < 0) {
- // unlock
- taosWUnLockLatch(SMA_ENV_LOCK(pEnv));
- smaError("vgId:%d, clone rsma info failed for suid:%" PRIu64 " since %s", SMA_VID(pSma), suid, terrstr());
- return NULL;
- }
- smaDebug("vgId:%d, clone rsma info succeed for suid:%" PRIu64, SMA_VID(pSma), suid);
- if (taosHashPut(RSMA_INFO_HASH(pStat), &suid, sizeof(tb_uid_t), &pCowRSmaInfo, sizeof(pCowRSmaInfo)) < 0) {
- // unlock
- taosWUnLockLatch(SMA_ENV_LOCK(pEnv));
- smaError("vgId:%d, clone rsma info failed for suid:%" PRIu64 " since %s", SMA_VID(pSma), suid, terrstr());
- return NULL;
- }
+ if (!pRSmaInfo->taskInfo[0]) {
+ if (tdCloneRSmaInfo(pSma, pRSmaInfo) < 0) {
+ // taosRUnLockLatch(SMA_ENV_LOCK(pEnv));
+ return NULL;
}
}
- } else {
- pCowRSmaInfo = *(SRSmaInfo **)pCowRSmaInfo;
- ASSERT(!pCowRSmaInfo);
+ tdRefRSmaInfo(pSma, pRSmaInfo);
+ // taosRUnLockLatch(SMA_ENV_LOCK(pEnv));
+ ASSERT(pRSmaInfo->suid == suid);
+ return pRSmaInfo;
}
+ // taosRUnLockLatch(SMA_ENV_LOCK(pEnv));
- if (pCowRSmaInfo) {
- tdRefRSmaInfo(pSma, pCowRSmaInfo);
- }
- // unlock
- taosWUnLockLatch(SMA_ENV_LOCK(pEnv));
- return pCowRSmaInfo;
+ return NULL;
}
static FORCE_INLINE void tdReleaseRSmaInfo(SSma *pSma, SRSmaInfo *pInfo) {
@@ -792,29 +872,85 @@ static FORCE_INLINE void tdReleaseRSmaInfo(SSma *pSma, SRSmaInfo *pInfo) {
}
}
-static int32_t tdExecuteRSma(SSma *pSma, const void *pMsg, int32_t inputType, tb_uid_t suid) {
+/**
+ * @brief async mode
+ *
+ * @param pSma
+ * @param pMsg
+ * @param inputType
+ * @param suid
+ * @return int32_t
+ */
+static int32_t tdExecuteRSmaAsync(SSma *pSma, const void *pMsg, int32_t inputType, tb_uid_t suid) {
SRSmaInfo *pRSmaInfo = tdAcquireRSmaInfoBySuid(pSma, suid);
if (!pRSmaInfo) {
- smaError("vgId:%d, execute rsma, no rsma info for suid:%" PRIu64, SMA_VID(pSma), suid);
+ smaDebug("vgId:%d, execute rsma, no rsma info for suid:%" PRIu64, SMA_VID(pSma), suid);
return TSDB_CODE_SUCCESS;
}
if (inputType == STREAM_INPUT__DATA_SUBMIT) {
- tdExecuteRSmaImpl(pSma, pMsg, inputType, pRSmaInfo, suid, TSDB_RETENTION_L1);
- tdExecuteRSmaImpl(pSma, pMsg, inputType, pRSmaInfo, suid, TSDB_RETENTION_L2);
+ if (tdExecuteRSmaImplAsync(pSma, pMsg, inputType, pRSmaInfo, suid) < 0) {
+ tdReleaseRSmaInfo(pSma, pRSmaInfo);
+ return TSDB_CODE_FAILED;
+ }
+ if (smaMgmt.tmrHandle) {
+ SRSmaInfoItem *pItem = RSMA_INFO_ITEM(pRSmaInfo, 0);
+ if (pItem->level > 0) {
+ atomic_store_8(&pItem->triggerStat, TASK_TRIGGER_STAT_ACTIVE);
+ }
+ pItem = RSMA_INFO_ITEM(pRSmaInfo, 1);
+ if (pItem->level > 0) {
+ atomic_store_8(&pItem->triggerStat, TASK_TRIGGER_STAT_ACTIVE);
+ }
+ }
+ } else {
+ ASSERT(0);
}
tdReleaseRSmaInfo(pSma, pRSmaInfo);
return TSDB_CODE_SUCCESS;
}
+static int32_t tdRSmaExecCheck(SSma *pSma) {
+ SRSmaStat *pRSmaStat = SMA_RSMA_STAT(pSma);
+
+ if (atomic_load_8(&pRSmaStat->nExecutor) >= TMIN(RSMA_EXECUTOR_MAX, tsNumOfVnodeQueryThreads / 2)) {
+ return TSDB_CODE_SUCCESS;
+ }
+
+ SRSmaExecMsg fetchMsg;
+ int32_t contLen = sizeof(SMsgHead);
+ void *pBuf = rpcMallocCont(0 + contLen);
+
+ ((SMsgHead *)pBuf)->vgId = SMA_VID(pSma);
+ ((SMsgHead *)pBuf)->contLen = sizeof(SMsgHead);
+
+ SRpcMsg rpcMsg = {
+ .code = 0,
+ .msgType = TDMT_VND_EXEC_RSMA,
+ .pCont = pBuf,
+ .contLen = contLen,
+ };
+
+ if ((terrno = tmsgPutToQueue(&pSma->pVnode->msgCb, QUERY_QUEUE, &rpcMsg)) != 0) {
+ smaError("vgId:%d, failed to put rsma exec msg into query-queue since %s", SMA_VID(pSma), terrstr());
+ goto _err;
+ }
+
+ smaDebug("vgId:%d, success to put rsma fetch msg into query-queue", SMA_VID(pSma));
+
+ return TSDB_CODE_SUCCESS;
+_err:
+ return TSDB_CODE_FAILED;
+}
+
int32_t tdProcessRSmaSubmit(SSma *pSma, void *pMsg, int32_t inputType) {
SSmaEnv *pEnv = SMA_RSMA_ENV(pSma);
if (!pEnv) {
// only applicable when rsma env exists
return TSDB_CODE_SUCCESS;
}
-
+ STbUidStore uidStore = {0};
SRetention *pRetention = SMA_RETENTION(pSma);
if (!RETENTION_VALID(pRetention + 1)) {
// return directly if retention level 1 is invalid
@@ -822,49 +958,75 @@ int32_t tdProcessRSmaSubmit(SSma *pSma, void *pMsg, int32_t inputType) {
}
if (inputType == STREAM_INPUT__DATA_SUBMIT) {
- STbUidStore uidStore = {0};
- tdFetchSubmitReqSuids(pMsg, &uidStore);
+ if (tdFetchSubmitReqSuids(pMsg, &uidStore) < 0) {
+ goto _err;
+ }
if (uidStore.suid != 0) {
- tdExecuteRSma(pSma, pMsg, inputType, uidStore.suid);
-
- void *pIter = taosHashIterate(uidStore.uidHash, NULL);
- while (pIter) {
- tb_uid_t *pTbSuid = (tb_uid_t *)taosHashGetKey(pIter, NULL);
- tdExecuteRSma(pSma, pMsg, inputType, *pTbSuid);
- pIter = taosHashIterate(uidStore.uidHash, pIter);
+ if (tdExecuteRSmaAsync(pSma, pMsg, inputType, uidStore.suid) < 0) {
+ goto _err;
}
- tdUidStoreDestory(&uidStore);
+ void *pIter = NULL;
+ while ((pIter = taosHashIterate(uidStore.uidHash, pIter))) {
+ tb_uid_t *pTbSuid = (tb_uid_t *)taosHashGetKey(pIter, NULL);
+ if (tdExecuteRSmaAsync(pSma, pMsg, inputType, *pTbSuid) < 0) {
+ goto _err;
+ }
+ }
+
+ if (tdRSmaExecCheck(pSma) < 0) {
+ goto _err;
+ }
}
}
+ tdUidStoreDestory(&uidStore);
return TSDB_CODE_SUCCESS;
+_err:
+ tdUidStoreDestory(&uidStore);
+ smaError("vgId:%d, failed to process rsma submit since: %s", SMA_VID(pSma), terrstr());
+ return TSDB_CODE_FAILED;
}
+/**
+ * @brief retrieve rsma meta and init
+ *
+ * @param pSma
+ * @param nTables number of tables of rsma
+ * @return int32_t
+ */
static int32_t tdRSmaRestoreQTaskInfoInit(SSma *pSma, int64_t *nTables) {
- SVnode *pVnode = pSma->pVnode;
+ SVnode *pVnode = pSma->pVnode;
+ SArray *suidList = NULL;
+ STbUidStore uidStore = {0};
+ SMetaReader mr = {0};
- SArray *suidList = taosArrayInit(1, sizeof(tb_uid_t));
- if (tsdbGetStbIdList(SMA_META(pSma), 0, suidList) < 0) {
- taosArrayDestroy(suidList);
+ if (!(suidList = taosArrayInit(1, sizeof(tb_uid_t)))) {
+ terrno = TSDB_CODE_OUT_OF_MEMORY;
+ goto _err;
+ }
+
+ if (vnodeGetStbIdList(pSma->pVnode, 0, suidList) < 0) {
smaError("vgId:%d, failed to restore rsma env since get stb id list error: %s", TD_VID(pVnode), terrstr());
- return TSDB_CODE_FAILED;
+ goto _err;
}
int64_t arrSize = taosArrayGetSize(suidList);
- if (nTables) {
- *nTables = arrSize;
- }
-
if (arrSize == 0) {
+ if (nTables) {
+ *nTables = 0;
+ }
taosArrayDestroy(suidList);
smaDebug("vgId:%d, no need to restore rsma env since empty stb id list", TD_VID(pVnode));
return TSDB_CODE_SUCCESS;
}
- SMetaReader mr = {0};
+ int64_t nRsmaTables = 0;
metaReaderInit(&mr, SMA_META(pSma), 0);
+ if (!(uidStore.tbUids = taosArrayInit(1024, sizeof(tb_uid_t)))) {
+ goto _err;
+ }
for (int64_t i = 0; i < arrSize; ++i) {
tb_uid_t suid = *(tb_uid_t *)taosArrayGet(suidList, i);
smaDebug("vgId:%d, rsma restore, suid is %" PRIi64, TD_VID(pVnode), suid);
@@ -877,6 +1039,7 @@ static int32_t tdRSmaRestoreQTaskInfoInit(SSma *pSma, int64_t *nTables) {
ASSERT(mr.me.type == TSDB_SUPER_TABLE);
ASSERT(mr.me.uid == suid);
if (TABLE_IS_ROLLUP(mr.me.flags)) {
+ ++nRsmaTables;
SRSmaParam *param = &mr.me.stbEntry.rsmaParam;
for (int i = 0; i < TSDB_RETENTION_L2; ++i) {
smaDebug("vgId:%d, rsma restore, table:%" PRIi64 " level:%d, maxdelay:%" PRIi64 " watermark:%" PRIi64
@@ -887,17 +1050,40 @@ static int32_t tdRSmaRestoreQTaskInfoInit(SSma *pSma, int64_t *nTables) {
smaError("vgId:%d, rsma restore env failed for %" PRIi64 " since %s", TD_VID(pVnode), suid, terrstr());
goto _err;
}
+
+ // reload all ctbUids for suid
+ uidStore.suid = suid;
+ if (vnodeGetCtbIdList(pVnode, suid, uidStore.tbUids) < 0) {
+ smaError("vgId:%d, rsma restore, get ctb idlist failed for %" PRIi64 " since %s", TD_VID(pVnode), suid,
+ terrstr());
+ goto _err;
+ }
+
+ if (tdUpdateTbUidList(pVnode->pSma, &uidStore) < 0) {
+ smaError("vgId:%d, rsma restore, update tb uid list failed for %" PRIi64 " since %s", TD_VID(pVnode), suid,
+ terrstr());
+ goto _err;
+ }
+
+ taosArrayClear(uidStore.tbUids);
+
smaDebug("vgId:%d, rsma restore env success for %" PRIi64, TD_VID(pVnode), suid);
}
}
metaReaderClear(&mr);
taosArrayDestroy(suidList);
+ tdUidStoreDestory(&uidStore);
+
+ if (nTables) {
+ *nTables = nRsmaTables;
+ }
return TSDB_CODE_SUCCESS;
_err:
metaReaderClear(&mr);
taosArrayDestroy(suidList);
+ tdUidStoreDestory(&uidStore);
return TSDB_CODE_FAILED;
}
@@ -1230,6 +1416,9 @@ int32_t tdRSmaPersistExecImpl(SRSmaStat *pRSmaStat, SHashObj *pInfoHash) {
}
for (int32_t i = 0; i < TSDB_RETENTION_L2; ++i) {
+#if 0
+ qTaskInfo_t taskInfo = RSMA_INFO_IQTASK(pRSmaInfo, i);
+#endif
qTaskInfo_t taskInfo = RSMA_INFO_QTASK(pRSmaInfo, i);
if (!taskInfo) {
smaDebug("vgId:%d, rsma, table %" PRIi64 " level %d qTaskInfo is NULL", vid, pRSmaInfo->suid, i + 1);
@@ -1367,7 +1556,16 @@ static void tdRSmaFetchTrigger(void *param, void *tmrId) {
smaDebug("vgId:%d, rsma fetch task started for level:%" PRIi8 " suid:%" PRIi64 " since stat is active",
SMA_VID(pSma), pItem->level, pRSmaInfo->suid);
// async process
- tdRSmaFetchSend(pSma, pRSmaInfo, pItem->level);
+ pItem->fetchLevel = pItem->level;
+#if 0
+ SRSmaInfo *qInfo = tdAcquireRSmaInfoBySuid(pSma, pRSmaInfo->suid);
+ SRSmaInfoItem *qItem = RSMA_INFO_ITEM(qInfo, pItem->level - 1);
+ ASSERT(qItem->level == pItem->level);
+ ASSERT(qItem->fetchLevel == pItem->fetchLevel);
+#endif
+ tsem_post(&(pStat->notEmpty));
+ smaInfo("vgId:%d, rsma fetch task planned for level:%" PRIi8 " suid:%" PRIi64, SMA_VID(pSma), pItem->level,
+ pRSmaInfo->suid);
} break;
case TASK_TRIGGER_STAT_PAUSED: {
smaDebug("vgId:%d, rsma fetch task not start for level:%" PRIi8 " suid:%" PRIi64 " since stat is paused",
@@ -1382,127 +1580,268 @@ static void tdRSmaFetchTrigger(void *param, void *tmrId) {
SMA_VID(pSma), pItem->level, pRSmaInfo->suid);
} break;
default: {
- smaWarn("vgId:%d, rsma fetch task not start for level:%" PRIi8 " suid:%" PRIi64 " since stat is unknown",
- SMA_VID(pSma), pItem->level, pRSmaInfo->suid);
+ smaDebug("vgId:%d, rsma fetch task not start for level:%" PRIi8 " suid:%" PRIi64 " since stat is unknown",
+ SMA_VID(pSma), pItem->level, pRSmaInfo->suid);
} break;
}
_end:
- // taosTmrReset(tdRSmaFetchTrigger, pItem->maxDelay, pItem, smaMgmt.tmrHandle, &pItem->tmrId);
+ taosTmrReset(tdRSmaFetchTrigger, pItem->maxDelay, pItem, smaMgmt.tmrHandle, &pItem->tmrId);
tdReleaseSmaRef(smaMgmt.rsetId, pRSmaInfo->refId);
}
+static void tdFreeRSmaSubmitItems(SArray *pItems) {
+ for (int32_t i = 0; i < taosArrayGetSize(pItems); ++i) {
+ taosFreeQitem(*(void **)taosArrayGet(pItems, i));
+ }
+}
+
/**
- * @brief put rsma fetch msg to fetch queue
+ * @brief fetch rsma result(consider the efficiency and functionality)
*
* @param pSma
* @param pInfo
- * @param level
+ * @param pSubmitArr
* @return int32_t
*/
-int32_t tdRSmaFetchSend(SSma *pSma, SRSmaInfo *pInfo, int8_t level) {
- SRSmaFetchMsg fetchMsg = {.suid = pInfo->suid, .level = level};
- int32_t ret = 0;
- int32_t contLen = 0;
- SEncoder encoder = {0};
- tEncodeSize(tEncodeSRSmaFetchMsg, &fetchMsg, contLen, ret);
- if (ret < 0) {
- terrno = TSDB_CODE_OUT_OF_MEMORY;
- tEncoderClear(&encoder);
- goto _err;
+static int32_t tdRSmaFetchAllResult(SSma *pSma, SRSmaInfo *pInfo, SArray *pSubmitArr) {
+ SSDataBlock dataBlock = {.info.type = STREAM_GET_ALL};
+ for (int8_t i = 1; i <= TSDB_RETENTION_L2; ++i) {
+ SRSmaInfoItem *pItem = RSMA_INFO_ITEM(pInfo, i - 1);
+ if (pItem->fetchLevel) {
+ pItem->fetchLevel = 0;
+ qTaskInfo_t taskInfo = RSMA_INFO_QTASK(pInfo, i - 1);
+ if (!taskInfo) {
+ continue;
+ }
+
+ int64_t curMs = taosGetTimestampMs();
+ if ((pItem->nSkipped * pItem->maxDelay) > RSMA_FETCH_DELAY_MAX) {
+ smaInfo("vgId:%d, suid:%" PRIi64 " level:%" PRIi8 " nSkipped:%" PRIi8 " maxDelay:%d, fetch executed",
+ SMA_VID(pSma), pInfo->suid, i, pItem->nSkipped, pItem->maxDelay);
+ } else if (((curMs - pInfo->lastRecv) < RSMA_FETCH_ACTIVE_MAX)) {
+ ++pItem->nSkipped;
+ smaDebug("vgId:%d, suid:%" PRIi64 " level:%" PRIi8 " curMs:%" PRIi64 " lastRecv:%" PRIi64 ", fetch skipped ",
+ SMA_VID(pSma), pInfo->suid, i, curMs, pInfo->lastRecv);
+ continue;
+ } else {
+ smaInfo("vgId:%d, suid:%" PRIi64 " level:%" PRIi8 " curMs:%" PRIi64 " lastRecv:%" PRIi64 ", fetch executed ",
+ SMA_VID(pSma), pInfo->suid, i, curMs, pInfo->lastRecv);
+ }
+
+ pItem->nSkipped = 0;
+
+ if ((terrno = qSetMultiStreamInput(taskInfo, &dataBlock, 1, STREAM_INPUT__DATA_BLOCK)) < 0) {
+ goto _err;
+ }
+ if (tdRSmaExecAndSubmitResult(pSma, taskInfo, pItem, pInfo->pTSchema, pInfo->suid) < 0) {
+ tdCleanupStreamInputDataBlock(taskInfo);
+ goto _err;
+ }
+
+ tdCleanupStreamInputDataBlock(taskInfo);
+ smaInfo("vgId:%d, suid:%" PRIi64 " level:%" PRIi8 " nSkipped:%" PRIi8 " maxDelay:%d, fetch finished",
+ SMA_VID(pSma), pInfo->suid, i, pItem->nSkipped, pItem->maxDelay);
+ } else {
+ smaDebug("vgId:%d, suid:%" PRIi64 " level:%" PRIi8 " nSkipped:%" PRIi8
+ " maxDelay:%d, fetch not executed as fetch level is %" PRIi8,
+ SMA_VID(pSma), pInfo->suid, i, pItem->nSkipped, pItem->maxDelay, pItem->fetchLevel);
+ }
}
- void *pBuf = rpcMallocCont(contLen + sizeof(SMsgHead));
- tEncoderInit(&encoder, POINTER_SHIFT(pBuf, sizeof(SMsgHead)), contLen);
- if (tEncodeSRSmaFetchMsg(&encoder, &fetchMsg) < 0) {
- terrno = TSDB_CODE_OUT_OF_MEMORY;
- tEncoderClear(&encoder);
- }
- tEncoderClear(&encoder);
-
- ((SMsgHead *)pBuf)->vgId = SMA_VID(pSma);
- ((SMsgHead *)pBuf)->contLen = contLen + sizeof(SMsgHead);
-
- SRpcMsg rpcMsg = {
- .code = 0,
- .msgType = TDMT_VND_FETCH_RSMA,
- .pCont = pBuf,
- .contLen = contLen,
- };
-
- if ((terrno = tmsgPutToQueue(&pSma->pVnode->msgCb, QUERY_QUEUE, &rpcMsg)) != 0) {
- smaError("vgId:%d, failed to put rsma fetch msg into fetch-queue for suid:%" PRIi64 " level:%" PRIi8 " since %s",
- SMA_VID(pSma), pInfo->suid, level, terrstr());
- goto _err;
- }
-
- smaDebug("vgId:%d, success to put rsma fetch msg into fetch-queue for suid:%" PRIi64 " level:%" PRIi8, SMA_VID(pSma),
- pInfo->suid, level);
-
+_end:
+ tdReleaseRSmaInfo(pSma, pInfo);
return TSDB_CODE_SUCCESS;
_err:
+ tdReleaseRSmaInfo(pSma, pInfo);
+ return TSDB_CODE_FAILED;
+}
+
+static int32_t tdRSmaBatchExec(SSma *pSma, SRSmaInfo *pInfo, STaosQall *qall, SArray *pSubmitArr, ERsmaExecType type) {
+ taosArrayClear(pSubmitArr);
+ while (1) {
+ void *msg = NULL;
+ taosGetQitem(qall, (void **)&msg);
+ if (msg) {
+ if (taosArrayPush(pSubmitArr, &msg) < 0) {
+ tdFreeRSmaSubmitItems(pSubmitArr);
+ goto _err;
+ }
+ } else {
+ break;
+ }
+ }
+
+ int32_t size = taosArrayGetSize(pSubmitArr);
+ if (size > 0) {
+ for (int32_t i = 1; i <= TSDB_RETENTION_L2; ++i) {
+ if (tdExecuteRSmaImpl(pSma, pSubmitArr->pData, size, STREAM_INPUT__MERGED_SUBMIT, pInfo, type, i) < 0) {
+ tdFreeRSmaSubmitItems(pSubmitArr);
+ goto _err;
+ }
+ }
+ tdFreeRSmaSubmitItems(pSubmitArr);
+ }
+ return TSDB_CODE_SUCCESS;
+_err:
+ while (1) {
+ void *msg = NULL;
+ taosGetQitem(qall, (void **)&msg);
+ if (msg) {
+ taosFreeQitem(msg);
+ } else {
+ break;
+ }
+ }
return TSDB_CODE_FAILED;
}
/**
- * @brief fetch rsma data of level 2/3 and submit
+ * @brief
+ *
+ * @param pSma
+ * @param type
+ * @return int32_t
+ */
+int32_t tdRSmaProcessExecImpl(SSma *pSma, ERsmaExecType type) {
+ SVnode *pVnode = pSma->pVnode;
+ SSmaEnv *pEnv = SMA_RSMA_ENV(pSma);
+ SRSmaStat *pRSmaStat = (SRSmaStat *)SMA_ENV_STAT(pEnv);
+ SHashObj *infoHash = NULL;
+ SArray *pSubmitArr = NULL;
+ bool isFetchAll = false;
+
+ if (!pRSmaStat || !(infoHash = RSMA_INFO_HASH(pRSmaStat))) {
+ terrno = TSDB_CODE_RSMA_INVALID_STAT;
+ goto _err;
+ }
+
+ if (!(pSubmitArr =
+ taosArrayInit(TMIN(RSMA_SUBMIT_BATCH_SIZE, atomic_load_64(&pRSmaStat->nBufItems)), POINTER_BYTES))) {
+ terrno = TSDB_CODE_OUT_OF_MEMORY;
+ goto _err;
+ }
+
+ bool isBusy = false;
+ while (true) {
+ isBusy = false;
+ // step 1: rsma exec - consume data in buffer queue for all suids
+ if (type == RSMA_EXEC_OVERFLOW || type == RSMA_EXEC_COMMIT) {
+ void *pIter = taosHashIterate(infoHash, NULL); // infoHash has r/w lock
+ while (pIter) {
+ SRSmaInfo *pInfo = *(SRSmaInfo **)pIter;
+ int64_t itemSize = 0;
+ if ((itemSize = taosQueueItemSize(pInfo->queue)) || RSMA_INFO_ITEM(pInfo, 0)->fetchLevel ||
+ RSMA_INFO_ITEM(pInfo, 1)->fetchLevel) {
+ smaDebug("vgId:%d, queueItemSize is %" PRIi64 " execType:%" PRIi8, SMA_VID(pSma), itemSize, type);
+ if (atomic_val_compare_exchange_8(&pInfo->assigned, 0, 1) == 0) {
+ taosReadAllQitems(pInfo->queue, pInfo->qall); // queue has mutex lock
+ int32_t qallItemSize = taosQallItemSize(pInfo->qall);
+ if (qallItemSize > 0) {
+ tdRSmaBatchExec(pSma, pInfo, pInfo->qall, pSubmitArr, type);
+ }
+
+ if (type == RSMA_EXEC_OVERFLOW) {
+ tdRSmaFetchAllResult(pSma, pInfo, pSubmitArr);
+ }
+
+ if (qallItemSize > 0) {
+ // subtract the item size after the task finished, commit should wait for all items be consumed
+ atomic_fetch_sub_64(&pRSmaStat->nBufItems, qallItemSize);
+ isBusy = true;
+ }
+ ASSERT(1 == atomic_val_compare_exchange_8(&pInfo->assigned, 1, 0));
+ }
+ }
+ pIter = taosHashIterate(infoHash, pIter);
+ }
+ if (type == RSMA_EXEC_COMMIT) {
+ break;
+ }
+ }
+#if 0
+ else if (type == RSMA_EXEC_COMMIT) {
+ while (pIter) {
+ SRSmaInfo *pInfo = *(SRSmaInfo **)pIter;
+ if (taosQueueItemSize(pInfo->iQueue)) {
+ if (atomic_val_compare_exchange_8(&pInfo->assigned, 0, 1) == 0) {
+ taosReadAllQitems(pInfo->iQueue, pInfo->iQall); // queue has mutex lock
+ int32_t qallItemSize = taosQallItemSize(pInfo->iQall);
+ if (qallItemSize > 0) {
+ atomic_fetch_sub_64(&pRSmaStat->nBufItems, qallItemSize);
+ nIdle = 0;
+
+ // batch exec
+ tdRSmaBatchExec(pSma, pInfo, pInfo->qall, pSubmitArr, type);
+ }
+
+ // tdRSmaFetchAllResult(pSma, pInfo, pSubmitArr);
+ ASSERT(1 == atomic_val_compare_exchange_8(&pInfo->assigned, 1, 0));
+ }
+ }
+ ASSERT(taosQueueItemSize(pInfo->iQueue) == 0);
+ pIter = taosHashIterate(infoHash, pIter);
+ }
+ break;
+ }
+#endif
+ else {
+ ASSERT(0);
+ }
+
+ if (atomic_load_64(&pRSmaStat->nBufItems) <= 0) {
+ if (pVnode->inClose) {
+ break;
+ }
+ tsem_wait(&pRSmaStat->notEmpty);
+ if (pVnode->inClose && (atomic_load_64(&pRSmaStat->nBufItems) <= 0)) {
+ smaInfo("vgId:%d, exec task end, inClose:%d, nBufItems:%" PRIi64, SMA_VID(pSma), pVnode->inClose,
+ atomic_load_64(&pRSmaStat->nBufItems));
+ break;
+ }
+ }
+ } // end of while(true)
+
+_end:
+ taosArrayDestroy(pSubmitArr);
+ return TSDB_CODE_SUCCESS;
+_err:
+ taosArrayDestroy(pSubmitArr);
+ return TSDB_CODE_FAILED;
+}
+
+/**
+ * @brief exec rsma level 1data, fetch result of level 2/3 and submit
*
* @param pSma
* @param pMsg
* @return int32_t
*/
-int32_t smaProcessFetch(SSma *pSma, void *pMsg) {
- SRpcMsg *pRpcMsg = (SRpcMsg *)pMsg;
- SRSmaFetchMsg req = {0};
- SDecoder decoder = {0};
- void *pBuf = NULL;
- SRSmaInfo *pInfo = NULL;
- SRSmaInfoItem *pItem = NULL;
+int32_t smaProcessExec(SSma *pSma, void *pMsg) {
+ SRpcMsg *pRpcMsg = (SRpcMsg *)pMsg;
+ SRSmaStat *pRSmaStat = SMA_RSMA_STAT(pSma);
if (!pRpcMsg || pRpcMsg->contLen < sizeof(SMsgHead)) {
terrno = TSDB_CODE_RSMA_FETCH_MSG_MSSED_UP;
goto _err;
}
+ smaDebug("vgId:%d, begin to process rsma exec msg by TID:%p", SMA_VID(pSma), (void *)taosGetSelfPthreadId());
- pBuf = POINTER_SHIFT(pRpcMsg->pCont, sizeof(SMsgHead));
+ int8_t nOld = atomic_fetch_add_8(&pRSmaStat->nExecutor, 1);
- tDecoderInit(&decoder, pBuf, pRpcMsg->contLen);
- if (tDecodeSRSmaFetchMsg(&decoder, &req) < 0) {
- terrno = TSDB_CODE_INVALID_MSG;
- goto _err;
- }
-
- pInfo = tdAcquireRSmaInfoBySuid(pSma, req.suid);
- if (!pInfo) {
- if (terrno == TSDB_CODE_SUCCESS) {
- terrno = TSDB_CODE_RSMA_EMPTY_INFO;
+ if (nOld < TMIN(RSMA_EXECUTOR_MAX, tsNumOfVnodeQueryThreads / 2)) {
+ if (tdRSmaProcessExecImpl(pSma, RSMA_EXEC_OVERFLOW) < 0) {
+ goto _err;
}
- smaWarn("vgId:%d, failed to process rsma fetch msg for suid:%" PRIi64 " level:%" PRIi8 " since %s", SMA_VID(pSma),
- req.suid, req.level, terrstr());
- goto _err;
+ } else {
+ atomic_fetch_sub_8(&pRSmaStat->nExecutor, 1);
}
- pItem = RSMA_INFO_ITEM(pInfo, req.level - 1);
-
- SSDataBlock dataBlock = {.info.type = STREAM_GET_ALL};
- qTaskInfo_t taskInfo = RSMA_INFO_QTASK(pInfo, req.level - 1);
- if ((terrno = qSetMultiStreamInput(taskInfo, &dataBlock, 1, STREAM_INPUT__DATA_BLOCK)) < 0) {
- goto _err;
- }
- if (tdRSmaFetchAndSubmitResult(pSma, taskInfo, pItem, pInfo->pTSchema, pInfo->suid, STREAM_INPUT__DATA_BLOCK) < 0) {
- goto _err;
- }
-
- tdCleanupStreamInputDataBlock(taskInfo);
-
- tdReleaseRSmaInfo(pSma, pInfo);
- tDecoderClear(&decoder);
- smaDebug("vgId:%d, success to process rsma fetch msg for suid:%" PRIi64 " level:%" PRIi8, SMA_VID(pSma), req.suid,
- req.level);
+ smaDebug("vgId:%d, success to process rsma exec msg by TID:%p", SMA_VID(pSma), (void *)taosGetSelfPthreadId());
return TSDB_CODE_SUCCESS;
_err:
- tdReleaseRSmaInfo(pSma, pInfo);
- tDecoderClear(&decoder);
- smaError("vgId:%d, failed to process rsma fetch msg since %s", SMA_VID(pSma), terrstr());
+ atomic_fetch_sub_8(&pRSmaStat->nExecutor, 1);
+ smaError("vgId:%d, failed to process rsma exec msg by TID:%p since %s", SMA_VID(pSma), (void *)taosGetSelfPthreadId(),
+ terrstr());
return TSDB_CODE_FAILED;
}
diff --git a/source/dnode/vnode/src/sma/smaSnapshot.c b/source/dnode/vnode/src/sma/smaSnapshot.c
index fbcd2af751..335c15a539 100644
--- a/source/dnode/vnode/src/sma/smaSnapshot.c
+++ b/source/dnode/vnode/src/sma/smaSnapshot.c
@@ -139,7 +139,6 @@ static int32_t rsmaSnapReadQTaskInfo(SRsmaSnapReader* pReader, uint8_t** ppBuf)
smaInfo("vgId:%d, vnode snapshot rsma read qtaskinfo, size:%" PRIi64, SMA_VID(pSma), size);
-
SSnapDataHdr* pHdr = (SSnapDataHdr*)(*ppBuf);
pHdr->type = SNAP_DATA_QTASK;
pHdr->size = size;
@@ -279,7 +278,8 @@ int32_t rsmaSnapWriterOpen(SSma* pSma, int64_t sver, int64_t ever, SRsmaSnapWrit
TdFilePtr qTaskF = taosCreateFile(qTaskInfoFullName, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC);
if (!qTaskF) {
code = TAOS_SYSTEM_ERROR(errno);
- smaError("vgId:%d, rsma snapshot writer open %s failed since %s", TD_VID(pSma->pVnode), qTaskInfoFullName, tstrerror(code));
+ smaError("vgId:%d, rsma snapshot writer open %s failed since %s", TD_VID(pSma->pVnode), qTaskInfoFullName,
+ tstrerror(code));
goto _err;
}
qWriter->pWriteH = qTaskF;
@@ -309,7 +309,7 @@ int32_t rsmaSnapWriterClose(SRsmaSnapWriter** ppWriter, int8_t rollback) {
if (rollback) {
// TODO: rsma1/rsma2
// qtaskinfo
- if(pWriter->pQTaskFWriter) {
+ if (pWriter->pQTaskFWriter) {
taosRemoveFile(pWriter->pQTaskFWriter->fname);
}
} else {
diff --git a/source/dnode/vnode/src/sma/smaTimeRange.c b/source/dnode/vnode/src/sma/smaTimeRange.c
index b09d7e3c23..1687cd46a0 100644
--- a/source/dnode/vnode/src/sma/smaTimeRange.c
+++ b/source/dnode/vnode/src/sma/smaTimeRange.c
@@ -175,7 +175,7 @@ int32_t tdProcessTSmaInsertImpl(SSma *pSma, int64_t indexUid, const char *msg) {
}
tdRefSmaStat(pSma, pStat);
- pTsmaStat = SMA_TSMA_STAT(pStat);
+ pTsmaStat = SMA_STAT_TSMA(pStat);
if (!pTsmaStat->pTSma) {
STSma *pTSma = metaGetSmaInfoByIndex(SMA_META(pSma), indexUid);
diff --git a/source/dnode/vnode/src/sma/smaUtil.c b/source/dnode/vnode/src/sma/smaUtil.c
index d9f38ffd09..d771797963 100644
--- a/source/dnode/vnode/src/sma/smaUtil.c
+++ b/source/dnode/vnode/src/sma/smaUtil.c
@@ -350,49 +350,48 @@ _err:
}
/**
- * @brief pTSchema is shared
+ * @brief Clone qTaskInfo of SRSmaInfo
*
* @param pSma
- * @param pDest
- * @param pSrc
+ * @param pInfo
* @return int32_t
*/
-int32_t tdCloneRSmaInfo(SSma *pSma, SRSmaInfo **pDest, SRSmaInfo *pSrc) {
- SVnode *pVnode = pSma->pVnode;
+int32_t tdCloneRSmaInfo(SSma *pSma, SRSmaInfo *pInfo) {
SRSmaParam *param = NULL;
- if (!pSrc) {
- *pDest = NULL;
+ if (!pInfo) {
return TSDB_CODE_SUCCESS;
}
SMetaReader mr = {0};
metaReaderInit(&mr, SMA_META(pSma), 0);
- smaDebug("vgId:%d, rsma clone, suid is %" PRIi64, TD_VID(pVnode), pSrc->suid);
- if (metaGetTableEntryByUid(&mr, pSrc->suid) < 0) {
- smaError("vgId:%d, rsma clone, failed to get table meta for %" PRIi64 " since %s", TD_VID(pVnode), pSrc->suid,
+ smaDebug("vgId:%d, rsma clone qTaskInfo for suid:%" PRIi64, SMA_VID(pSma), pInfo->suid);
+ if (metaGetTableEntryByUid(&mr, pInfo->suid) < 0) {
+ smaError("vgId:%d, rsma clone, failed to get table meta for %" PRIi64 " since %s", SMA_VID(pSma), pInfo->suid,
terrstr());
goto _err;
}
ASSERT(mr.me.type == TSDB_SUPER_TABLE);
- ASSERT(mr.me.uid == pSrc->suid);
+ ASSERT(mr.me.uid == pInfo->suid);
if (TABLE_IS_ROLLUP(mr.me.flags)) {
param = &mr.me.stbEntry.rsmaParam;
for (int32_t i = 0; i < TSDB_RETENTION_L2; ++i) {
- if (tdCloneQTaskInfo(pSma, pSrc->iTaskInfo[i], pSrc->taskInfo[i], param, pSrc->suid, i) < 0) {
+ if (!pInfo->iTaskInfo[i]) {
+ continue;
+ }
+ if (tdCloneQTaskInfo(pSma, pInfo->taskInfo[i], pInfo->iTaskInfo[i], param, pInfo->suid, i) < 0) {
goto _err;
}
}
- smaDebug("vgId:%d, rsma clone env success for %" PRIi64, TD_VID(pVnode), pSrc->suid);
+ smaDebug("vgId:%d, rsma clone env success for %" PRIi64, SMA_VID(pSma), pInfo->suid);
+ } else {
+ terrno = TSDB_CODE_RSMA_INVALID_SCHEMA;
+ goto _err;
}
metaReaderClear(&mr);
-
- *pDest = pSrc; // pointer copy
-
return TSDB_CODE_SUCCESS;
_err:
- *pDest = NULL;
metaReaderClear(&mr);
- smaError("vgId:%d, rsma clone env failed for %" PRIi64 " since %s", TD_VID(pVnode), pSrc->suid, terrstr());
+ smaError("vgId:%d, rsma clone env failed for %" PRIi64 " since %s", SMA_VID(pSma), pInfo->suid, terrstr());
return TSDB_CODE_FAILED;
}
\ No newline at end of file
diff --git a/source/dnode/vnode/src/tq/tq.c b/source/dnode/vnode/src/tq/tq.c
index a98fea1988..c6bc8e6e59 100644
--- a/source/dnode/vnode/src/tq/tq.c
+++ b/source/dnode/vnode/src/tq/tq.c
@@ -628,8 +628,6 @@ int32_t tqProcessVgChangeReq(STQ* pTq, int64_t version, char* msg, int32_t msgLe
}
int32_t tqExpandTask(STQ* pTq, SStreamTask* pTask) {
- int32_t code = 0;
-
if (pTask->taskLevel == TASK_LEVEL__AGG) {
ASSERT(taosArrayGetSize(pTask->childEpInfo) != 0);
}
@@ -640,8 +638,7 @@ int32_t tqExpandTask(STQ* pTq, SStreamTask* pTask) {
pTask->outputQueue = streamQueueOpen();
if (pTask->inputQueue == NULL || pTask->outputQueue == NULL) {
- code = -1;
- goto FAIL;
+ return -1;
}
pTask->inputStatus = TASK_INPUT_STATUS__NORMAL;
@@ -686,14 +683,9 @@ int32_t tqExpandTask(STQ* pTq, SStreamTask* pTask) {
streamSetupTrigger(pTask);
- tqInfo("deploy stream task on vg %d, task id %d, child id %d", TD_VID(pTq->pVnode), pTask->taskId,
+ tqInfo("expand stream task on vg %d, task id %d, child id %d", TD_VID(pTq->pVnode), pTask->taskId,
pTask->selfChildId);
-
-FAIL:
- if (pTask->inputQueue) streamQueueClose(pTask->inputQueue);
- if (pTask->outputQueue) streamQueueClose(pTask->outputQueue);
- // TODO free executor
- return code;
+ return 0;
}
int32_t tqProcessTaskDeployReq(STQ* pTq, int64_t version, char* msg, int32_t msgLen) {
diff --git a/source/dnode/vnode/src/tq/tqRead.c b/source/dnode/vnode/src/tq/tqRead.c
index b8803b20fc..e6a331f20e 100644
--- a/source/dnode/vnode/src/tq/tqRead.c
+++ b/source/dnode/vnode/src/tq/tqRead.c
@@ -341,7 +341,7 @@ FAIL:
return -1;
}
-void tqReaderSetColIdList(STqReader* pReadHandle, SArray* pColIdList) { pReadHandle->pColIdList = pColIdList; }
+void tqReaderSetColIdList(STqReader* pReader, SArray* pColIdList) { pReader->pColIdList = pColIdList; }
int tqReaderSetTbUidList(STqReader* pReader, const SArray* tbUidList) {
if (pReader->tbIdHash) {
diff --git a/source/dnode/vnode/src/tq/tqSink.c b/source/dnode/vnode/src/tq/tqSink.c
index 55630511bf..522bf46aa1 100644
--- a/source/dnode/vnode/src/tq/tqSink.c
+++ b/source/dnode/vnode/src/tq/tqSink.c
@@ -231,34 +231,35 @@ void tqTableSink(SStreamTask* pTask, void* vnode, int64_t ver, void* data) {
ASSERT(pTask->tbSink.pTSchema);
deleteReq.deleteReqs = taosArrayInit(0, sizeof(SSingleDeleteReq));
- SSubmitReq* pReq = tqBlockToSubmit(pVnode, pRes, pTask->tbSink.pTSchema, true, pTask->tbSink.stbUid,
- pTask->tbSink.stbFullName, &deleteReq);
+ SSubmitReq* submitReq = tqBlockToSubmit(pVnode, pRes, pTask->tbSink.pTSchema, true, pTask->tbSink.stbUid,
+ pTask->tbSink.stbFullName, &deleteReq);
tqDebug("vgId:%d, task %d convert blocks over, put into write-queue", TD_VID(pVnode), pTask->taskId);
- int32_t code;
- int32_t len;
- tEncodeSize(tEncodeSBatchDeleteReq, &deleteReq, len, code);
- if (code < 0) {
- //
- ASSERT(0);
- }
- SEncoder encoder;
- void* buf = rpcMallocCont(len + sizeof(SMsgHead));
- void* abuf = POINTER_SHIFT(buf, sizeof(SMsgHead));
- tEncoderInit(&encoder, abuf, len);
- tEncodeSBatchDeleteReq(&encoder, &deleteReq);
- tEncoderClear(&encoder);
-
- ((SMsgHead*)buf)->vgId = pVnode->config.vgId;
-
if (taosArrayGetSize(deleteReq.deleteReqs) != 0) {
+ int32_t code;
+ int32_t len;
+ tEncodeSize(tEncodeSBatchDeleteReq, &deleteReq, len, code);
+ if (code < 0) {
+ //
+ ASSERT(0);
+ }
+ SEncoder encoder;
+ void* serializedDeleteReq = rpcMallocCont(len + sizeof(SMsgHead));
+ void* abuf = POINTER_SHIFT(serializedDeleteReq, sizeof(SMsgHead));
+ tEncoderInit(&encoder, abuf, len);
+ tEncodeSBatchDeleteReq(&encoder, &deleteReq);
+ tEncoderClear(&encoder);
+
+ ((SMsgHead*)serializedDeleteReq)->vgId = pVnode->config.vgId;
+
SRpcMsg msg = {
.msgType = TDMT_VND_BATCH_DEL,
- .pCont = buf,
+ .pCont = serializedDeleteReq,
.contLen = len + sizeof(SMsgHead),
};
if (tmsgPutToQueue(&pVnode->msgCb, WRITE_QUEUE, &msg) != 0) {
+ rpcFreeCont(serializedDeleteReq);
tqDebug("failed to put into write-queue since %s", terrstr());
}
}
@@ -268,11 +269,12 @@ void tqTableSink(SStreamTask* pTask, void* vnode, int64_t ver, void* data) {
// build write msg
SRpcMsg msg = {
.msgType = TDMT_VND_SUBMIT,
- .pCont = pReq,
- .contLen = ntohl(pReq->length),
+ .pCont = submitReq,
+ .contLen = ntohl(submitReq->length),
};
if (tmsgPutToQueue(&pVnode->msgCb, WRITE_QUEUE, &msg) != 0) {
+ rpcFreeCont(submitReq);
tqDebug("failed to put into write-queue since %s", terrstr());
}
}
diff --git a/source/dnode/vnode/src/tsdb/tsdbCache.c b/source/dnode/vnode/src/tsdb/tsdbCache.c
index f03b02af27..ed25783e9f 100644
--- a/source/dnode/vnode/src/tsdb/tsdbCache.c
+++ b/source/dnode/vnode/src/tsdb/tsdbCache.c
@@ -33,16 +33,21 @@ int32_t tsdbOpenCache(STsdb *pTsdb) {
taosLRUCacheSetStrictCapacity(pCache, true);
+ taosThreadMutexInit(&pTsdb->lruMutex, NULL);
+
_err:
pTsdb->lruCache = pCache;
return code;
}
-void tsdbCloseCache(SLRUCache *pCache) {
+void tsdbCloseCache(STsdb *pTsdb) {
+ SLRUCache *pCache = pTsdb->lruCache;
if (pCache) {
taosLRUCacheEraseUnrefEntries(pCache);
taosLRUCacheCleanup(pCache);
+
+ taosThreadMutexDestroy(&pTsdb->lruMutex);
}
}
@@ -261,14 +266,14 @@ int32_t tsdbCacheInsertLast(SLRUCache *pCache, tb_uid_t uid, STSRow *row, STsdb
}
for (++iCol; iCol < nCol; ++iCol) {
- SLastCol *tTsVal = (SLastCol *)taosArrayGet(pLast, iCol);
- if (keyTs >= tTsVal->ts) {
- SColVal *tColVal = &tTsVal->colVal;
+ SLastCol *tTsVal1 = (SLastCol *)taosArrayGet(pLast, iCol);
+ if (keyTs >= tTsVal1->ts) {
+ SColVal *tColVal = &tTsVal1->colVal;
SColVal colVal = {0};
tTSRowGetVal(row, pTSchema, iCol, &colVal);
if (colVal.isNone || colVal.isNull) {
- if (keyTs == tTsVal->ts && !tColVal->isNone && !tColVal->isNull) {
+ if (keyTs == tTsVal1->ts && !tColVal->isNone && !tColVal->isNull) {
invalidate = true;
break;
@@ -279,6 +284,7 @@ int32_t tsdbCacheInsertLast(SLRUCache *pCache, tb_uid_t uid, STSRow *row, STsdb
}
}
+ _invalidate:
taosMemoryFreeClear(pTSchema);
taosLRUCacheRelease(pCache, h, invalidate);
@@ -317,7 +323,7 @@ static int32_t getTableDelDataFromDelIdx(SDelFReader *pDelReader, SDelIdx *pDelI
int32_t code = 0;
if (pDelIdx) {
- code = tsdbReadDelData(pDelReader, pDelIdx, aDelData, NULL);
+ code = tsdbReadDelData(pDelReader, pDelIdx, aDelData);
}
return code;
@@ -388,8 +394,7 @@ static int32_t getTableDelIdx(SDelFReader *pDelFReader, tb_uid_t suid, tb_uid_t
SDelIdx idx = {.suid = suid, .uid = uid};
// tMapDataReset(&delIdxMap);
- // code = tsdbReadDelIdx(pDelFReader, &delIdxMap, NULL);
- code = tsdbReadDelIdx(pDelFReader, pDelIdxArray, NULL);
+ code = tsdbReadDelIdx(pDelFReader, pDelIdxArray);
if (code) goto _err;
// code = tMapDataSearch(&delIdxMap, &idx, tGetDelIdx, tCmprDelIdx, pDelIdx);
@@ -405,6 +410,178 @@ _err:
return code;
}
+typedef enum {
+ SFSLASTNEXTROW_FS,
+ SFSLASTNEXTROW_FILESET,
+ SFSLASTNEXTROW_BLOCKDATA,
+ SFSLASTNEXTROW_BLOCKROW
+} SFSLASTNEXTROWSTATES;
+
+typedef struct {
+ SFSLASTNEXTROWSTATES state; // [input]
+ STsdb *pTsdb; // [input]
+ SBlockIdx *pBlockIdxExp; // [input]
+ STSchema *pTSchema; // [input]
+ int32_t nFileSet;
+ int32_t iFileSet;
+ SArray *aDFileSet;
+ SDataFReader *pDataFReader;
+ SArray *aBlockL;
+ SBlockL *pBlockL;
+ SBlockData *pBlockDataL;
+ SBlockData blockDataL;
+ int32_t nRow;
+ int32_t iRow;
+ TSDBROW row;
+ /*
+ SArray *aBlockIdx;
+ SBlockIdx *pBlockIdx;
+ SMapData blockMap;
+ int32_t nBlock;
+ int32_t iBlock;
+ SBlock block;
+ */
+} SFSLastNextRowIter;
+
+static int32_t getNextRowFromFSLast(void *iter, TSDBROW **ppRow) {
+ SFSLastNextRowIter *state = (SFSLastNextRowIter *)iter;
+ int32_t code = 0;
+
+ switch (state->state) {
+ case SFSLASTNEXTROW_FS:
+ // state->aDFileSet = state->pTsdb->pFS->cState->aDFileSet;
+ state->nFileSet = taosArrayGetSize(state->aDFileSet);
+ state->iFileSet = state->nFileSet;
+
+ state->pBlockDataL = NULL;
+
+ case SFSLASTNEXTROW_FILESET: {
+ SDFileSet *pFileSet = NULL;
+ _next_fileset:
+ if (--state->iFileSet >= 0) {
+ pFileSet = (SDFileSet *)taosArrayGet(state->aDFileSet, state->iFileSet);
+ } else {
+ if (state->pBlockDataL) {
+ tBlockDataDestroy(state->pBlockDataL, 1);
+ state->pBlockDataL = NULL;
+ }
+
+ *ppRow = NULL;
+ return code;
+ }
+
+ code = tsdbDataFReaderOpen(&state->pDataFReader, state->pTsdb, pFileSet);
+ if (code) goto _err;
+
+ if (!state->aBlockL) {
+ state->aBlockL = taosArrayInit(0, sizeof(SBlockIdx));
+ } else {
+ taosArrayClear(state->aBlockL);
+ }
+
+ code = tsdbReadBlockL(state->pDataFReader, state->aBlockL);
+ if (code) goto _err;
+
+ // SBlockL *pBlockL = (SBlockL *)taosArrayGet(state->aBlockL, state->iBlockL);
+
+ state->pBlockL = taosArraySearch(state->aBlockL, state->pBlockIdxExp, tCmprBlockL, TD_EQ);
+ if (!state->pBlockL) {
+ goto _next_fileset;
+ }
+
+ int64_t suid = state->pBlockL->suid;
+ int64_t uid = state->pBlockL->maxUid;
+
+ if (!state->pBlockDataL) {
+ state->pBlockDataL = &state->blockDataL;
+ }
+ code = tBlockDataInit(state->pBlockDataL, suid, suid ? 0 : uid, state->pTSchema);
+ if (code) goto _err;
+ }
+ case SFSLASTNEXTROW_BLOCKDATA:
+ code = tsdbReadLastBlock(state->pDataFReader, state->pBlockL, state->pBlockDataL);
+ if (code) goto _err;
+
+ state->nRow = state->blockDataL.nRow;
+ state->iRow = state->nRow - 1;
+
+ if (!state->pBlockDataL->uid) {
+ while (state->pBlockIdxExp->uid != state->pBlockDataL->aUid[state->iRow]) {
+ --state->iRow;
+ }
+ }
+
+ state->state = SFSLASTNEXTROW_BLOCKROW;
+ case SFSLASTNEXTROW_BLOCKROW:
+ if (state->pBlockDataL->uid) {
+ if (state->iRow >= 0) {
+ state->row = tsdbRowFromBlockData(state->pBlockDataL, state->iRow);
+ *ppRow = &state->row;
+
+ if (--state->iRow < 0) {
+ state->state = SFSLASTNEXTROW_FILESET;
+ }
+ }
+ } else {
+ if (state->iRow >= 0 && state->pBlockIdxExp->uid == state->pBlockDataL->aUid[state->iRow]) {
+ state->row = tsdbRowFromBlockData(state->pBlockDataL, state->iRow);
+ *ppRow = &state->row;
+
+ if (--state->iRow < 0 || state->pBlockIdxExp->uid != state->pBlockDataL->aUid[state->iRow]) {
+ state->state = SFSLASTNEXTROW_FILESET;
+ }
+ }
+ }
+
+ return code;
+ default:
+ ASSERT(0);
+ break;
+ }
+
+_err:
+ if (state->pDataFReader) {
+ tsdbDataFReaderClose(&state->pDataFReader);
+ state->pDataFReader = NULL;
+ }
+ if (state->aBlockL) {
+ taosArrayDestroy(state->aBlockL);
+ state->aBlockL = NULL;
+ }
+ if (state->pBlockDataL) {
+ tBlockDataDestroy(state->pBlockDataL, 1);
+ state->pBlockDataL = NULL;
+ }
+
+ *ppRow = NULL;
+
+ return code;
+}
+
+int32_t clearNextRowFromFSLast(void *iter) {
+ SFSLastNextRowIter *state = (SFSLastNextRowIter *)iter;
+ int32_t code = 0;
+
+ if (!state) {
+ return code;
+ }
+
+ if (state->pDataFReader) {
+ tsdbDataFReaderClose(&state->pDataFReader);
+ state->pDataFReader = NULL;
+ }
+ if (state->aBlockL) {
+ taosArrayDestroy(state->aBlockL);
+ state->aBlockL = NULL;
+ }
+ if (state->pBlockDataL) {
+ tBlockDataDestroy(state->pBlockDataL, 1);
+ state->pBlockDataL = NULL;
+ }
+
+ return code;
+}
+
typedef enum SFSNEXTROWSTATES {
SFSNEXTROW_FS,
SFSNEXTROW_FILESET,
@@ -451,9 +628,9 @@ static int32_t getNextRowFromFS(void *iter, TSDBROW **ppRow) {
if (--state->iFileSet >= 0) {
pFileSet = (SDFileSet *)taosArrayGet(state->aDFileSet, state->iFileSet);
} else {
- // tBlockDataClear(&state->blockData, 1);
+ // tBlockDataDestroy(&state->blockData, 1);
if (state->pBlockData) {
- tBlockDataClear(state->pBlockData, 1);
+ tBlockDataDestroy(state->pBlockData, 1);
state->pBlockData = NULL;
}
@@ -465,13 +642,12 @@ static int32_t getNextRowFromFS(void *iter, TSDBROW **ppRow) {
if (code) goto _err;
// tMapDataReset(&state->blockIdxMap);
- // code = tsdbReadBlockIdx(state->pDataFReader, &state->blockIdxMap, NULL);
if (!state->aBlockIdx) {
state->aBlockIdx = taosArrayInit(0, sizeof(SBlockIdx));
} else {
taosArrayClear(state->aBlockIdx);
}
- code = tsdbReadBlockIdx(state->pDataFReader, state->aBlockIdx, NULL);
+ code = tsdbReadBlockIdx(state->pDataFReader, state->aBlockIdx);
if (code) goto _err;
/* if (state->pBlockIdx) { */
@@ -487,8 +663,7 @@ static int32_t getNextRowFromFS(void *iter, TSDBROW **ppRow) {
}
tMapDataReset(&state->blockMap);
- code = tsdbReadBlock(state->pDataFReader, state->pBlockIdx, &state->blockMap, NULL);
- /* code = tsdbReadBlock(state->pDataFReader, &state->blockIdx, &state->blockMap, NULL); */
+ code = tsdbReadBlock(state->pDataFReader, state->pBlockIdx, &state->blockMap);
if (code) goto _err;
state->nBlock = state->blockMap.nItem;
@@ -497,7 +672,7 @@ static int32_t getNextRowFromFS(void *iter, TSDBROW **ppRow) {
if (!state->pBlockData) {
state->pBlockData = &state->blockData;
- tBlockDataInit(&state->blockData);
+ tBlockDataCreate(&state->blockData);
}
}
case SFSNEXTROW_BLOCKDATA:
@@ -510,7 +685,7 @@ static int32_t getNextRowFromFS(void *iter, TSDBROW **ppRow) {
tMapDataGetItemByIdx(&state->blockMap, state->iBlock, &block, tGetBlock);
/* code = tsdbReadBlockData(state->pDataFReader, &state->blockIdx, &block, &state->blockData, NULL, NULL); */
- code = tsdbReadBlockData(state->pDataFReader, state->pBlockIdx, &block, state->pBlockData, NULL, NULL);
+ code = tsdbReadDataBlock(state->pDataFReader, &block, state->pBlockData);
if (code) goto _err;
state->nRow = state->blockData.nRow;
@@ -555,8 +730,8 @@ _err:
state->aBlockIdx = NULL;
}
if (state->pBlockData) {
- // tBlockDataClear(&state->blockData, 1);
- tBlockDataClear(state->pBlockData, 1);
+ // tBlockDataDestroy(&state->blockData, 1);
+ tBlockDataDestroy(state->pBlockData, 1);
state->pBlockData = NULL;
}
@@ -582,8 +757,8 @@ int32_t clearNextRowFromFS(void *iter) {
state->aBlockIdx = NULL;
}
if (state->pBlockData) {
- // tBlockDataClear(&state->blockData, 1);
- tBlockDataClear(state->pBlockData, 1);
+ // tBlockDataDestroy(&state->blockData, 1);
+ tBlockDataDestroy(state->pBlockData, 1);
state->pBlockData = NULL;
}
@@ -725,18 +900,19 @@ typedef struct {
SArray *pSkyline;
int64_t iSkyline;
- SBlockIdx idx;
- SMemNextRowIter memState;
- SMemNextRowIter imemState;
- SFSNextRowIter fsState;
- TSDBROW memRow, imemRow, fsRow;
+ SBlockIdx idx;
+ SMemNextRowIter memState;
+ SMemNextRowIter imemState;
+ SFSLastNextRowIter fsLastState;
+ SFSNextRowIter fsState;
+ TSDBROW memRow, imemRow, fsLastRow, fsRow;
- TsdbNextRowState input[3];
+ TsdbNextRowState input[4];
STsdbReadSnap *pReadSnap;
STsdb *pTsdb;
} CacheNextRowIter;
-static int32_t nextRowIterOpen(CacheNextRowIter *pIter, tb_uid_t uid, STsdb *pTsdb) {
+static int32_t nextRowIterOpen(CacheNextRowIter *pIter, tb_uid_t uid, STsdb *pTsdb, STSchema *pTSchema) {
int code = 0;
tb_uid_t suid = getTableSuidByUid(uid, pTsdb);
@@ -745,12 +921,12 @@ static int32_t nextRowIterOpen(CacheNextRowIter *pIter, tb_uid_t uid, STsdb *pTs
STbData *pMem = NULL;
if (pIter->pReadSnap->pMem) {
- tsdbGetTbDataFromMemTable(pIter->pReadSnap->pMem, suid, uid, &pMem);
+ pMem = tsdbGetTbDataFromMemTable(pIter->pReadSnap->pMem, suid, uid);
}
STbData *pIMem = NULL;
if (pIter->pReadSnap->pIMem) {
- tsdbGetTbDataFromMemTable(pIter->pReadSnap->pIMem, suid, uid, &pIMem);
+ pIMem = tsdbGetTbDataFromMemTable(pIter->pReadSnap->pIMem, suid, uid);
}
pIter->pTsdb = pTsdb;
@@ -763,7 +939,7 @@ static int32_t nextRowIterOpen(CacheNextRowIter *pIter, tb_uid_t uid, STsdb *pTs
if (pDelFile) {
SDelFReader *pDelFReader;
- code = tsdbDelFReaderOpen(&pDelFReader, pDelFile, pTsdb, NULL);
+ code = tsdbDelFReaderOpen(&pDelFReader, pDelFile, pTsdb);
if (code) goto _err;
code = getTableDelIdx(pDelFReader, suid, uid, &delIdx);
@@ -782,6 +958,12 @@ static int32_t nextRowIterOpen(CacheNextRowIter *pIter, tb_uid_t uid, STsdb *pTs
pIter->idx = (SBlockIdx){.suid = suid, .uid = uid};
+ pIter->fsLastState.state = (SFSLASTNEXTROWSTATES) SFSNEXTROW_FS;
+ pIter->fsLastState.pTsdb = pTsdb;
+ pIter->fsLastState.aDFileSet = pIter->pReadSnap->fs.aDFileSet;
+ pIter->fsLastState.pBlockIdxExp = &pIter->idx;
+ pIter->fsLastState.pTSchema = pTSchema;
+
pIter->fsState.state = SFSNEXTROW_FS;
pIter->fsState.pTsdb = pTsdb;
pIter->fsState.aDFileSet = pIter->pReadSnap->fs.aDFileSet;
@@ -789,7 +971,9 @@ static int32_t nextRowIterOpen(CacheNextRowIter *pIter, tb_uid_t uid, STsdb *pTs
pIter->input[0] = (TsdbNextRowState){&pIter->memRow, true, false, &pIter->memState, getNextRowFromMem, NULL};
pIter->input[1] = (TsdbNextRowState){&pIter->imemRow, true, false, &pIter->imemState, getNextRowFromMem, NULL};
- pIter->input[2] =
+ pIter->input[2] = (TsdbNextRowState){&pIter->fsLastRow, false, true, &pIter->fsLastState, getNextRowFromFSLast,
+ clearNextRowFromFSLast};
+ pIter->input[3] =
(TsdbNextRowState){&pIter->fsRow, false, true, &pIter->fsState, getNextRowFromFS, clearNextRowFromFS};
if (pMem) {
@@ -814,7 +998,7 @@ _err:
static int32_t nextRowIterClose(CacheNextRowIter *pIter) {
int code = 0;
- for (int i = 0; i < 3; ++i) {
+ for (int i = 0; i < 4; ++i) {
if (pIter->input[i].nextRowClearFn) {
pIter->input[i].nextRowClearFn(pIter->input[i].iter);
}
@@ -826,7 +1010,6 @@ static int32_t nextRowIterClose(CacheNextRowIter *pIter) {
tsdbUntakeReadSnap(pIter->pTsdb, pIter->pReadSnap);
- return code;
_err:
return code;
}
@@ -835,7 +1018,7 @@ _err:
static int32_t nextRowIterGet(CacheNextRowIter *pIter, TSDBROW **ppRow) {
int code = 0;
- for (int i = 0; i < 3; ++i) {
+ for (int i = 0; i < 4; ++i) {
if (pIter->input[i].next && !pIter->input[i].stop) {
code = pIter->input[i].nextRowFn(pIter->input[i].iter, &pIter->input[i].pRow);
if (code) goto _err;
@@ -847,18 +1030,18 @@ static int32_t nextRowIterGet(CacheNextRowIter *pIter, TSDBROW **ppRow) {
}
}
- if (pIter->input[0].stop && pIter->input[1].stop && pIter->input[2].stop) {
+ if (pIter->input[0].stop && pIter->input[1].stop && pIter->input[2].stop && pIter->input[3].stop) {
*ppRow = NULL;
return code;
}
- // select maxpoint(s) from mem, imem, fs
- TSDBROW *max[3] = {0};
- int iMax[3] = {-1, -1, -1};
+ // select maxpoint(s) from mem, imem, fs and last
+ TSDBROW *max[4] = {0};
+ int iMax[4] = {-1, -1, -1, -1};
int nMax = 0;
TSKEY maxKey = TSKEY_MIN;
- for (int i = 0; i < 3; ++i) {
+ for (int i = 0; i < 4; ++i) {
if (!pIter->input[i].stop && pIter->input[i].pRow != NULL) {
TSDBKEY key = TSDBROW_KEY(pIter->input[i].pRow);
@@ -876,13 +1059,13 @@ static int32_t nextRowIterGet(CacheNextRowIter *pIter, TSDBROW **ppRow) {
}
// delete detection
- TSDBROW *merge[3] = {0};
- int iMerge[3] = {-1, -1, -1};
+ TSDBROW *merge[4] = {0};
+ int iMerge[4] = {-1, -1, -1, -1};
int nMerge = 0;
for (int i = 0; i < nMax; ++i) {
- TSDBKEY maxKey = TSDBROW_KEY(max[i]);
+ TSDBKEY maxKey1 = TSDBROW_KEY(max[i]);
- bool deleted = tsdbKeyDeleted(&maxKey, pIter->pSkyline, &pIter->iSkyline);
+ bool deleted = tsdbKeyDeleted(&maxKey1, pIter->pSkyline, &pIter->iSkyline);
if (!deleted) {
iMerge[nMerge] = iMax[i];
merge[nMerge++] = max[i];
@@ -918,7 +1101,7 @@ static int32_t mergeLastRow(tb_uid_t uid, STsdb *pTsdb, bool *dup, STSRow **ppRo
TSKEY lastRowTs = TSKEY_MAX;
CacheNextRowIter iter = {0};
- nextRowIterOpen(&iter, uid, pTsdb);
+ nextRowIterOpen(&iter, uid, pTsdb, pTSchema);
do {
TSDBROW *pRow = NULL;
@@ -1015,7 +1198,7 @@ static int32_t mergeLast(tb_uid_t uid, STsdb *pTsdb, SArray **ppLastArray) {
TSKEY lastRowTs = TSKEY_MAX;
CacheNextRowIter iter = {0};
- nextRowIterOpen(&iter, uid, pTsdb);
+ nextRowIterOpen(&iter, uid, pTsdb, pTSchema);
do {
TSDBROW *pRow = NULL;
@@ -1100,29 +1283,40 @@ int32_t tsdbCacheGetLastrowH(SLRUCache *pCache, tb_uid_t uid, STsdb *pTsdb, LRUH
// getTableCacheKeyS(uid, "lr", key, &keyLen);
getTableCacheKey(uid, 0, key, &keyLen);
LRUHandle *h = taosLRUCacheLookup(pCache, key, keyLen);
- if (h) {
- } else {
- STSRow *pRow = NULL;
- bool dup = false; // which is always false for now
- code = mergeLastRow(uid, pTsdb, &dup, &pRow);
- // if table's empty or error, return code of -1
- if (code < 0 || pRow == NULL) {
- if (!dup && pRow) {
- taosMemoryFree(pRow);
- }
-
- *handle = NULL;
- return 0;
- }
-
- _taos_lru_deleter_t deleter = deleteTableCacheLastrow;
- LRUStatus status =
- taosLRUCacheInsert(pCache, key, keyLen, pRow, TD_ROW_LEN(pRow), deleter, NULL, TAOS_LRU_PRIORITY_LOW);
- if (status != TAOS_LRU_STATUS_OK) {
- code = -1;
- }
+ if (!h) {
+ taosThreadMutexLock(&pTsdb->lruMutex);
h = taosLRUCacheLookup(pCache, key, keyLen);
+ if (!h) {
+ STSRow *pRow = NULL;
+ bool dup = false; // which is always false for now
+ code = mergeLastRow(uid, pTsdb, &dup, &pRow);
+ // if table's empty or error, return code of -1
+ if (code < 0 || pRow == NULL) {
+ if (!dup && pRow) {
+ taosMemoryFree(pRow);
+ }
+
+ taosThreadMutexUnlock(&pTsdb->lruMutex);
+
+ *handle = NULL;
+
+ return 0;
+ }
+
+ _taos_lru_deleter_t deleter = deleteTableCacheLastrow;
+ LRUStatus status =
+ taosLRUCacheInsert(pCache, key, keyLen, pRow, TD_ROW_LEN(pRow), deleter, NULL, TAOS_LRU_PRIORITY_LOW);
+ if (status != TAOS_LRU_STATUS_OK) {
+ code = -1;
+ }
+
+ taosThreadMutexUnlock(&pTsdb->lruMutex);
+
+ h = taosLRUCacheLookup(pCache, key, keyLen);
+ } else {
+ taosThreadMutexUnlock(&pTsdb->lruMutex);
+ }
}
*handle = h;
diff --git a/source/dnode/vnode/src/tsdb/tsdbCommit.c b/source/dnode/vnode/src/tsdb/tsdbCommit.c
index 6e25166203..020f3b0bc6 100644
--- a/source/dnode/vnode/src/tsdb/tsdbCommit.c
+++ b/source/dnode/vnode/src/tsdb/tsdbCommit.c
@@ -20,6 +20,12 @@ typedef struct {
STSchema *pTSchema;
} SSkmInfo;
+typedef struct {
+ int64_t suid;
+ int64_t uid;
+ TSDBROW row;
+} SRowInfo;
+
typedef struct {
STsdb *pTsdb;
/* commit data */
@@ -29,6 +35,7 @@ typedef struct {
int32_t minRow;
int32_t maxRow;
int8_t cmprAlg;
+ SArray *aTbDataP;
STsdbFS fs;
// --------------
TSKEY nextKey; // reset by each table commit
@@ -38,15 +45,27 @@ typedef struct {
// commit file data
struct {
SDataFReader *pReader;
- SArray *aBlockIdx; // SArray
- SMapData mBlock; // SMapData, read from reader
- SBlockData bData;
+ // data
+ SArray *aBlockIdx; // SArray
+ int32_t iBlockIdx;
+ SBlockIdx *pBlockIdx;
+ SMapData mBlock; // SMapData
+ SBlockData bData;
+ // last
+ SArray *aBlockL; // SArray
+ int32_t iBlockL;
+ SBlockData bDatal;
+ int32_t iRow;
+ SRowInfo *pRowInfo;
+ SRowInfo rowInfo;
} dReader;
struct {
SDataFWriter *pWriter;
SArray *aBlockIdx; // SArray
+ SArray *aBlockL; // SArray
SMapData mBlock; // SMapData
SBlockData bData;
+ SBlockData bDatal;
} dWriter;
SSkmInfo skmTable;
SSkmInfo skmRow;
@@ -162,10 +181,10 @@ static int32_t tsdbCommitDelStart(SCommitter *pCommitter) {
SDelFile *pDelFileR = pCommitter->fs.pDelFile;
if (pDelFileR) {
- code = tsdbDelFReaderOpen(&pCommitter->pDelFReader, pDelFileR, pTsdb, NULL);
+ code = tsdbDelFReaderOpen(&pCommitter->pDelFReader, pDelFileR, pTsdb);
if (code) goto _err;
- code = tsdbReadDelIdx(pCommitter->pDelFReader, pCommitter->aDelIdx, NULL);
+ code = tsdbReadDelIdx(pCommitter->pDelFReader, pCommitter->aDelIdx);
if (code) goto _err;
}
@@ -202,7 +221,7 @@ static int32_t tsdbCommitTableDel(SCommitter *pCommitter, STbData *pTbData, SDel
suid = pDelIdx->suid;
uid = pDelIdx->uid;
- code = tsdbReadDelData(pCommitter->pDelFReader, pDelIdx, pCommitter->aDelData, NULL);
+ code = tsdbReadDelData(pCommitter->pDelFReader, pDelIdx, pCommitter->aDelData);
if (code) goto _err;
} else {
taosArrayClear(pCommitter->aDelData);
@@ -222,7 +241,7 @@ static int32_t tsdbCommitTableDel(SCommitter *pCommitter, STbData *pTbData, SDel
}
// write
- code = tsdbWriteDelData(pCommitter->pDelFWriter, pCommitter->aDelData, NULL, &delIdx);
+ code = tsdbWriteDelData(pCommitter->pDelFWriter, pCommitter->aDelData, &delIdx);
if (code) goto _err;
// put delIdx
@@ -243,7 +262,7 @@ static int32_t tsdbCommitDelEnd(SCommitter *pCommitter) {
int32_t code = 0;
STsdb *pTsdb = pCommitter->pTsdb;
- code = tsdbWriteDelIdx(pCommitter->pDelFWriter, pCommitter->aDelIdxN, NULL);
+ code = tsdbWriteDelIdx(pCommitter->pDelFWriter, pCommitter->aDelIdxN);
if (code) goto _err;
code = tsdbUpdateDelFileHdr(pCommitter->pDelFWriter);
@@ -271,87 +290,19 @@ _err:
return code;
}
-static int32_t tsdbCommitFileDataStart(SCommitter *pCommitter) {
- int32_t code = 0;
- STsdb *pTsdb = pCommitter->pTsdb;
- SDFileSet *pRSet = NULL;
-
- // memory
- pCommitter->nextKey = TSKEY_MAX;
-
- // old
- taosArrayClear(pCommitter->dReader.aBlockIdx);
- tMapDataReset(&pCommitter->dReader.mBlock);
- tBlockDataReset(&pCommitter->dReader.bData);
- pRSet = (SDFileSet *)taosArraySearch(pCommitter->fs.aDFileSet, &(SDFileSet){.fid = pCommitter->commitFid},
- tDFileSetCmprFn, TD_EQ);
- if (pRSet) {
- code = tsdbDataFReaderOpen(&pCommitter->dReader.pReader, pTsdb, pRSet);
- if (code) goto _err;
-
- code = tsdbReadBlockIdx(pCommitter->dReader.pReader, pCommitter->dReader.aBlockIdx, NULL);
- if (code) goto _err;
- }
-
- // new
- SHeadFile fHead;
- SDataFile fData;
- SLastFile fLast;
- SSmaFile fSma;
- SDFileSet wSet = {.pHeadF = &fHead, .pDataF = &fData, .pLastF = &fLast, .pSmaF = &fSma};
-
- taosArrayClear(pCommitter->dWriter.aBlockIdx);
- tMapDataReset(&pCommitter->dWriter.mBlock);
- tBlockDataReset(&pCommitter->dWriter.bData);
- if (pRSet) {
- wSet.diskId = pRSet->diskId;
- wSet.fid = pCommitter->commitFid;
- fHead = (SHeadFile){.commitID = pCommitter->commitID, .offset = 0, .size = 0};
- fData = *pRSet->pDataF;
- fLast = (SLastFile){.commitID = pCommitter->commitID, .size = 0};
- fSma = *pRSet->pSmaF;
- } else {
- SDiskID did = {0};
-
- tfsAllocDisk(pTsdb->pVnode->pTfs, 0, &did);
-
- tfsMkdirRecurAt(pTsdb->pVnode->pTfs, pTsdb->path, did);
-
- wSet.diskId = did;
- wSet.fid = pCommitter->commitFid;
- fHead = (SHeadFile){.commitID = pCommitter->commitID, .offset = 0, .size = 0};
- fData = (SDataFile){.commitID = pCommitter->commitID, .size = 0};
- fLast = (SLastFile){.commitID = pCommitter->commitID, .size = 0};
- fSma = (SSmaFile){.commitID = pCommitter->commitID, .size = 0};
- }
- code = tsdbDataFWriterOpen(&pCommitter->dWriter.pWriter, pTsdb, &wSet);
- if (code) goto _err;
-
-_exit:
- return code;
-
-_err:
- tsdbError("vgId:%d, commit file data start failed since %s", TD_VID(pTsdb->pVnode), tstrerror(code));
- return code;
-}
-
-static int32_t tsdbCommitterUpdateTableSchema(SCommitter *pCommitter, int64_t suid, int64_t uid, int32_t sver) {
+static int32_t tsdbCommitterUpdateTableSchema(SCommitter *pCommitter, int64_t suid, int64_t uid) {
int32_t code = 0;
- if (pCommitter->skmTable.pTSchema) {
- if (pCommitter->skmTable.suid == suid) {
- if (suid == 0) {
- if (pCommitter->skmTable.uid == uid && sver == pCommitter->skmTable.pTSchema->version) goto _exit;
- } else {
- if (sver == pCommitter->skmTable.pTSchema->version) goto _exit;
- }
- }
+ if (suid) {
+ if (pCommitter->skmTable.suid == suid) goto _exit;
+ } else {
+ if (pCommitter->skmTable.uid == uid) goto _exit;
}
pCommitter->skmTable.suid = suid;
pCommitter->skmTable.uid = uid;
tTSchemaDestroy(pCommitter->skmTable.pTSchema);
- code = metaGetTbTSchemaEx(pCommitter->pTsdb->pVnode->pMeta, suid, uid, sver, &pCommitter->skmTable.pTSchema);
+ code = metaGetTbTSchemaEx(pCommitter->pTsdb->pVnode->pMeta, suid, uid, -1, &pCommitter->skmTable.pTSchema);
if (code) goto _exit;
_exit:
@@ -383,152 +334,355 @@ _exit:
return code;
}
-static int32_t tsdbCommitBlockData(SCommitter *pCommitter, SBlockData *pBlockData, SBlock *pBlock, SBlockIdx *pBlockIdx,
- int8_t toDataOnly) {
+static int32_t tsdbCommitterNextLastRow(SCommitter *pCommitter) {
int32_t code = 0;
- if (pBlock->nSubBlock == 0) {
- if (!toDataOnly && pBlockData->nRow < pCommitter->minRow) {
- pBlock->last = 1;
+ ASSERT(pCommitter->dReader.pReader);
+ ASSERT(pCommitter->dReader.pRowInfo);
+
+ SBlockData *pBlockDatal = &pCommitter->dReader.bDatal;
+ pCommitter->dReader.iRow++;
+ if (pCommitter->dReader.iRow < pBlockDatal->nRow) {
+ if (pBlockDatal->uid) {
+ pCommitter->dReader.pRowInfo->uid = pBlockDatal->uid;
} else {
- pBlock->last = 0;
+ pCommitter->dReader.pRowInfo->uid = pBlockDatal->aUid[pCommitter->dReader.iRow];
+ }
+ pCommitter->dReader.pRowInfo->row = tsdbRowFromBlockData(pBlockDatal, pCommitter->dReader.iRow);
+ } else {
+ pCommitter->dReader.iBlockL++;
+ if (pCommitter->dReader.iBlockL < taosArrayGetSize(pCommitter->dReader.aBlockL)) {
+ SBlockL *pBlockL = (SBlockL *)taosArrayGet(pCommitter->dReader.aBlockL, pCommitter->dReader.iBlockL);
+ int64_t suid = pBlockL->suid;
+ int64_t uid = pBlockL->maxUid;
+
+ code = tsdbCommitterUpdateTableSchema(pCommitter, suid, uid);
+ if (code) goto _exit;
+
+ code = tBlockDataInit(pBlockDatal, suid, suid ? 0 : uid, pCommitter->skmTable.pTSchema);
+ if (code) goto _exit;
+
+ code = tsdbReadLastBlock(pCommitter->dReader.pReader, pBlockL, pBlockDatal);
+ if (code) goto _exit;
+
+ pCommitter->dReader.iRow = 0;
+ pCommitter->dReader.pRowInfo->suid = pBlockDatal->suid;
+ if (pBlockDatal->uid) {
+ pCommitter->dReader.pRowInfo->uid = pBlockDatal->uid;
+ } else {
+ pCommitter->dReader.pRowInfo->uid = pBlockDatal->aUid[0];
+ }
+ pCommitter->dReader.pRowInfo->row = tsdbRowFromBlockData(pBlockDatal, pCommitter->dReader.iRow);
+ } else {
+ pCommitter->dReader.pRowInfo = NULL;
}
}
- code =
- tsdbWriteBlockData(pCommitter->dWriter.pWriter, pBlockData, NULL, NULL, pBlockIdx, pBlock, pCommitter->cmprAlg);
+_exit:
+ return code;
+}
+
+static int32_t tsdbCommitterNextTableData(SCommitter *pCommitter) {
+ int32_t code = 0;
+
+ ASSERT(pCommitter->dReader.pBlockIdx);
+
+ pCommitter->dReader.iBlockIdx++;
+ if (pCommitter->dReader.iBlockIdx < taosArrayGetSize(pCommitter->dReader.aBlockIdx)) {
+ pCommitter->dReader.pBlockIdx =
+ (SBlockIdx *)taosArrayGet(pCommitter->dReader.aBlockIdx, pCommitter->dReader.iBlockIdx);
+
+ code = tsdbReadBlock(pCommitter->dReader.pReader, pCommitter->dReader.pBlockIdx, &pCommitter->dReader.mBlock);
+ if (code) goto _exit;
+
+ ASSERT(pCommitter->dReader.mBlock.nItem > 0);
+ } else {
+ pCommitter->dReader.pBlockIdx = NULL;
+ }
+
+_exit:
+ return code;
+}
+
+static int32_t tsdbCommitFileDataStart(SCommitter *pCommitter) {
+ int32_t code = 0;
+ STsdb *pTsdb = pCommitter->pTsdb;
+ SDFileSet *pRSet = NULL;
+
+ // memory
+ pCommitter->commitFid = tsdbKeyFid(pCommitter->nextKey, pCommitter->minutes, pCommitter->precision);
+ tsdbFidKeyRange(pCommitter->commitFid, pCommitter->minutes, pCommitter->precision, &pCommitter->minKey,
+ &pCommitter->maxKey);
+ pCommitter->nextKey = TSKEY_MAX;
+
+ // Reader
+ pRSet = (SDFileSet *)taosArraySearch(pCommitter->fs.aDFileSet, &(SDFileSet){.fid = pCommitter->commitFid},
+ tDFileSetCmprFn, TD_EQ);
+ if (pRSet) {
+ code = tsdbDataFReaderOpen(&pCommitter->dReader.pReader, pTsdb, pRSet);
+ if (code) goto _err;
+
+ // data
+ code = tsdbReadBlockIdx(pCommitter->dReader.pReader, pCommitter->dReader.aBlockIdx);
+ if (code) goto _err;
+
+ pCommitter->dReader.iBlockIdx = 0;
+ if (pCommitter->dReader.iBlockIdx < taosArrayGetSize(pCommitter->dReader.aBlockIdx)) {
+ pCommitter->dReader.pBlockIdx =
+ (SBlockIdx *)taosArrayGet(pCommitter->dReader.aBlockIdx, pCommitter->dReader.iBlockIdx);
+
+ code = tsdbReadBlock(pCommitter->dReader.pReader, pCommitter->dReader.pBlockIdx, &pCommitter->dReader.mBlock);
+ if (code) goto _err;
+ } else {
+ pCommitter->dReader.pBlockIdx = NULL;
+ }
+ tBlockDataReset(&pCommitter->dReader.bData);
+
+ // last
+ code = tsdbReadBlockL(pCommitter->dReader.pReader, pCommitter->dReader.aBlockL);
+ if (code) goto _err;
+
+ pCommitter->dReader.iBlockL = -1;
+ pCommitter->dReader.iRow = -1;
+ pCommitter->dReader.pRowInfo = &pCommitter->dReader.rowInfo;
+ tBlockDataReset(&pCommitter->dReader.bDatal);
+ code = tsdbCommitterNextLastRow(pCommitter);
+ if (code) goto _err;
+ } else {
+ pCommitter->dReader.pBlockIdx = NULL;
+ pCommitter->dReader.pRowInfo = NULL;
+ }
+
+ // Writer
+ SHeadFile fHead;
+ SDataFile fData;
+ SLastFile fLast;
+ SSmaFile fSma;
+ SDFileSet wSet = {.pHeadF = &fHead, .pDataF = &fData, .pLastF = &fLast, .pSmaF = &fSma};
+ if (pRSet) {
+ wSet.diskId = pRSet->diskId;
+ wSet.fid = pCommitter->commitFid;
+ fHead = (SHeadFile){.commitID = pCommitter->commitID, .size = 0, .offset = 0};
+ fData = *pRSet->pDataF;
+ fLast = (SLastFile){.commitID = pCommitter->commitID, .size = 0, .offset = 0};
+ fSma = *pRSet->pSmaF;
+ } else {
+ SDiskID did = {0};
+
+ tfsAllocDisk(pTsdb->pVnode->pTfs, 0, &did);
+
+ tfsMkdirRecurAt(pTsdb->pVnode->pTfs, pTsdb->path, did);
+
+ wSet.diskId = did;
+ wSet.fid = pCommitter->commitFid;
+ fHead = (SHeadFile){.commitID = pCommitter->commitID, .size = 0, .offset = 0};
+ fData = (SDataFile){.commitID = pCommitter->commitID, .size = 0};
+ fLast = (SLastFile){.commitID = pCommitter->commitID, .size = 0, .offset = 0};
+ fSma = (SSmaFile){.commitID = pCommitter->commitID, .size = 0};
+ }
+ code = tsdbDataFWriterOpen(&pCommitter->dWriter.pWriter, pTsdb, &wSet);
if (code) goto _err;
- code = tMapDataPutItem(&pCommitter->dWriter.mBlock, pBlock, tPutBlock);
+ taosArrayClear(pCommitter->dWriter.aBlockIdx);
+ taosArrayClear(pCommitter->dWriter.aBlockL);
+ tMapDataReset(&pCommitter->dWriter.mBlock);
+ tBlockDataReset(&pCommitter->dWriter.bData);
+ tBlockDataReset(&pCommitter->dWriter.bDatal);
+
+_exit:
+ return code;
+
+_err:
+ tsdbError("vgId:%d, commit file data start failed since %s", TD_VID(pTsdb->pVnode), tstrerror(code));
+ return code;
+}
+
+static int32_t tsdbCommitDataBlock(SCommitter *pCommitter, SBlock *pBlock) {
+ int32_t code = 0;
+ SBlockData *pBlockData = &pCommitter->dWriter.bData;
+ SBlock block;
+
+ ASSERT(pBlockData->nRow > 0);
+
+ if (pBlock) {
+ block = *pBlock; // as a subblock
+ } else {
+ tBlockReset(&block); // as a new block
+ }
+
+ // info
+ block.nRow += pBlockData->nRow;
+ for (int32_t iRow = 0; iRow < pBlockData->nRow; iRow++) {
+ TSDBKEY key = {.ts = pBlockData->aTSKEY[iRow], .version = pBlockData->aVersion[iRow]};
+
+ if (iRow == 0) {
+ if (tsdbKeyCmprFn(&block.minKey, &key) > 0) {
+ block.minKey = key;
+ }
+ } else {
+ if (pBlockData->aTSKEY[iRow] == pBlockData->aTSKEY[iRow - 1]) {
+ block.hasDup = 1;
+ }
+ }
+
+ if (iRow == pBlockData->nRow - 1 && tsdbKeyCmprFn(&block.maxKey, &key) < 0) {
+ block.maxKey = key;
+ }
+
+ block.minVer = TMIN(block.minVer, key.version);
+ block.maxVer = TMAX(block.maxVer, key.version);
+ }
+
+ // write
+ block.nSubBlock++;
+ code = tsdbWriteBlockData(pCommitter->dWriter.pWriter, pBlockData, &block.aSubBlock[block.nSubBlock - 1],
+ ((block.nSubBlock == 1) && !block.hasDup) ? &block.smaInfo : NULL, pCommitter->cmprAlg, 0);
if (code) goto _err;
+ // put SBlock
+ code = tMapDataPutItem(&pCommitter->dWriter.mBlock, &block, tPutBlock);
+ if (code) goto _err;
+
+ // clear
+ tBlockDataClear(pBlockData);
+
return code;
_err:
+ tsdbError("vgId:%d tsdb commit data block failed since %s", TD_VID(pCommitter->pTsdb->pVnode), tstrerror(code));
return code;
}
-static int32_t tsdbMergeTableData(SCommitter *pCommitter, STbDataIter *pIter, SBlock *pBlockMerge, TSDBKEY toKey,
- int8_t toDataOnly) {
+static int32_t tsdbCommitLastBlock(SCommitter *pCommitter) {
int32_t code = 0;
- SBlockIdx *pBlockIdx = &(SBlockIdx){.suid = pIter->pTbData->suid, .uid = pIter->pTbData->uid};
- SBlockData *pBlockDataMerge = &pCommitter->dReader.bData;
- SBlockData *pBlockData = &pCommitter->dWriter.bData;
- SBlock block;
- SBlock *pBlock = █
- TSDBROW *pRow1;
- TSDBROW row2;
- TSDBROW *pRow2 = &row2;
+ SBlockL blockL;
+ SBlockData *pBlockData = &pCommitter->dWriter.bDatal;
- // read SBlockData
- code = tsdbReadBlockData(pCommitter->dReader.pReader, pBlockIdx, pBlockMerge, pBlockDataMerge, NULL, NULL);
+ ASSERT(pBlockData->nRow > 0);
+
+ // info
+ blockL.suid = pBlockData->suid;
+ blockL.nRow = pBlockData->nRow;
+ blockL.minKey = TSKEY_MAX;
+ blockL.maxKey = TSKEY_MIN;
+ blockL.minVer = VERSION_MAX;
+ blockL.maxVer = VERSION_MIN;
+ for (int32_t iRow = 0; iRow < pBlockData->nRow; iRow++) {
+ blockL.minKey = TMIN(blockL.minKey, pBlockData->aTSKEY[iRow]);
+ blockL.maxKey = TMAX(blockL.maxKey, pBlockData->aTSKEY[iRow]);
+ blockL.minVer = TMIN(blockL.minVer, pBlockData->aVersion[iRow]);
+ blockL.maxVer = TMAX(blockL.maxVer, pBlockData->aVersion[iRow]);
+ }
+ blockL.minUid = pBlockData->uid ? pBlockData->uid : pBlockData->aUid[0];
+ blockL.maxUid = pBlockData->uid ? pBlockData->uid : pBlockData->aUid[pBlockData->nRow - 1];
+
+ // write
+ code = tsdbWriteBlockData(pCommitter->dWriter.pWriter, pBlockData, &blockL.bInfo, NULL, pCommitter->cmprAlg, 1);
if (code) goto _err;
- code = tBlockDataSetSchema(pBlockData, pCommitter->skmTable.pTSchema);
+ // push SBlockL
+ if (taosArrayPush(pCommitter->dWriter.aBlockL, &blockL) == NULL) {
+ code = TSDB_CODE_OUT_OF_MEMORY;
+ goto _err;
+ }
+
+ // clear
+ tBlockDataClear(pBlockData);
+
+ return code;
+
+_err:
+ tsdbError("vgId:%d tsdb commit last block failed since %s", TD_VID(pCommitter->pTsdb->pVnode), tstrerror(code));
+ return code;
+}
+
+static int32_t tsdbMergeCommitData(SCommitter *pCommitter, STbDataIter *pIter, SBlock *pBlock) {
+ int32_t code = 0;
+ STbData *pTbData = pIter->pTbData;
+ SBlockData *pBlockDataR = &pCommitter->dReader.bData;
+ SBlockData *pBlockDataW = &pCommitter->dWriter.bData;
+
+ code = tsdbReadDataBlock(pCommitter->dReader.pReader, pBlock, pBlockDataR);
if (code) goto _err;
- // loop to merge
- pRow1 = tsdbTbDataIterGet(pIter);
- *pRow2 = tsdbRowFromBlockData(pBlockDataMerge, 0);
- ASSERT(pRow1 && tsdbKeyCmprFn(&TSDBROW_KEY(pRow1), &toKey) < 0);
- ASSERT(tsdbKeyCmprFn(&TSDBROW_KEY(pRow2), &toKey) < 0);
- code = tsdbCommitterUpdateRowSchema(pCommitter, pBlockIdx->suid, pBlockIdx->uid, TSDBROW_SVERSION(pRow1));
- if (code) goto _err;
+ tBlockDataClear(pBlockDataW);
+ int32_t iRow = 0;
+ TSDBROW row;
+ TSDBROW *pRow1 = tsdbTbDataIterGet(pIter);
+ TSDBROW *pRow2 = &row;
+ *pRow2 = tsdbRowFromBlockData(pBlockDataR, iRow);
+ while (pRow1 && pRow2) {
+ int32_t c = tsdbRowCmprFn(pRow1, pRow2);
- tBlockReset(pBlock);
- tBlockDataClearData(pBlockData);
- while (true) {
- if (pRow1 == NULL && pRow2 == NULL) {
- if (pBlockData->nRow == 0) {
- break;
+ if (c < 0) {
+ code = tsdbCommitterUpdateRowSchema(pCommitter, pTbData->suid, pTbData->uid, TSDBROW_SVERSION(pRow1));
+ if (code) goto _err;
+
+ code = tBlockDataAppendRow(pBlockDataW, pRow1, pCommitter->skmRow.pTSchema, pTbData->uid);
+ if (code) goto _err;
+
+ // next
+ tsdbTbDataIterNext(pIter);
+ pRow1 = tsdbTbDataIterGet(pIter);
+ } else if (c > 0) {
+ code = tBlockDataAppendRow(pBlockDataW, pRow2, NULL, pTbData->uid);
+ if (code) goto _err;
+
+ iRow++;
+ if (iRow < pBlockDataR->nRow) {
+ *pRow2 = tsdbRowFromBlockData(pBlockDataR, iRow);
} else {
- goto _write_block;
+ pRow2 = NULL;
}
- }
-
- if (pRow1 && pRow2) {
- int32_t c = tsdbRowCmprFn(pRow1, pRow2);
- if (c < 0) {
- goto _append_mem_row;
- } else if (c > 0) {
- goto _append_block_row;
- } else {
- ASSERT(0);
- }
- } else if (pRow1) {
- goto _append_mem_row;
} else {
- goto _append_block_row;
+ ASSERT(0);
}
- _append_mem_row:
- code = tBlockDataAppendRow(pBlockData, pRow1, pCommitter->skmRow.pTSchema);
+ // check
+ if (pBlockDataW->nRow >= pCommitter->maxRow * 4 / 5) {
+ code = tsdbCommitDataBlock(pCommitter, NULL);
+ if (code) goto _err;
+ }
+ }
+
+ while (pRow2) {
+ code = tBlockDataAppendRow(pBlockDataW, pRow2, NULL, pTbData->uid);
if (code) goto _err;
- tsdbTbDataIterNext(pIter);
- pRow1 = tsdbTbDataIterGet(pIter);
- if (pRow1) {
- if (tsdbKeyCmprFn(&TSDBROW_KEY(pRow1), &toKey) < 0) {
- code = tsdbCommitterUpdateRowSchema(pCommitter, pBlockIdx->suid, pBlockIdx->uid, TSDBROW_SVERSION(pRow1));
- if (code) goto _err;
- } else {
- pRow1 = NULL;
- }
- }
-
- if (pBlockData->nRow >= pCommitter->maxRow * 4 / 5) {
- goto _write_block;
- } else {
- continue;
- }
-
- _append_block_row:
- code = tBlockDataAppendRow(pBlockData, pRow2, NULL);
- if (code) goto _err;
-
- if (pRow2->iRow + 1 < pBlockDataMerge->nRow) {
- *pRow2 = tsdbRowFromBlockData(pBlockDataMerge, pRow2->iRow + 1);
+ iRow++;
+ if (iRow < pBlockDataR->nRow) {
+ *pRow2 = tsdbRowFromBlockData(pBlockDataR, iRow);
} else {
pRow2 = NULL;
}
- if (pBlockData->nRow >= pCommitter->maxRow * 4 / 5) {
- goto _write_block;
- } else {
- continue;
+ // check
+ if (pBlockDataW->nRow >= pCommitter->maxRow * 4 / 5) {
+ code = tsdbCommitDataBlock(pCommitter, NULL);
+ if (code) goto _err;
}
+ }
- _write_block:
- code = tsdbCommitBlockData(pCommitter, pBlockData, pBlock, pBlockIdx, toDataOnly);
+ // check
+ if (pBlockDataW->nRow > 0) {
+ code = tsdbCommitDataBlock(pCommitter, NULL);
if (code) goto _err;
-
- tBlockReset(pBlock);
- tBlockDataClearData(pBlockData);
}
return code;
_err:
- tsdbError("vgId:%d, tsdb merge block and mem failed since %s", TD_VID(pCommitter->pTsdb->pVnode), tstrerror(code));
+ tsdbError("vgId:%d, tsdb merge commit data failed since %s", TD_VID(pCommitter->pTsdb->pVnode), tstrerror(code));
return code;
}
-static int32_t tsdbCommitTableMemData(SCommitter *pCommitter, STbDataIter *pIter, TSDBKEY toKey, int8_t toDataOnly) {
+static int32_t tsdbCommitTableMemData(SCommitter *pCommitter, STbDataIter *pIter, TSDBKEY toKey) {
int32_t code = 0;
- TSDBROW *pRow;
- SBlock block;
- SBlock *pBlock = █
+ STbData *pTbData = pIter->pTbData;
SBlockData *pBlockData = &pCommitter->dWriter.bData;
- int64_t suid = pIter->pTbData->suid;
- int64_t uid = pIter->pTbData->uid;
- code = tBlockDataSetSchema(pBlockData, pCommitter->skmTable.pTSchema);
- if (code) goto _err;
-
- tBlockReset(pBlock);
- tBlockDataClearData(pBlockData);
- pRow = tsdbTbDataIterGet(pIter);
- ASSERT(pRow && tsdbKeyCmprFn(&TSDBROW_KEY(pRow), &toKey) < 0);
+ tBlockDataClear(pBlockData);
+ TSDBROW *pRow = tsdbTbDataIterGet(pIter);
while (true) {
if (pRow == NULL) {
if (pBlockData->nRow > 0) {
@@ -539,33 +693,27 @@ static int32_t tsdbCommitTableMemData(SCommitter *pCommitter, STbDataIter *pIter
}
// update schema
- code = tsdbCommitterUpdateRowSchema(pCommitter, suid, uid, TSDBROW_SVERSION(pRow));
+ code = tsdbCommitterUpdateRowSchema(pCommitter, pTbData->suid, pTbData->uid, TSDBROW_SVERSION(pRow));
if (code) goto _err;
// append
- code = tBlockDataAppendRow(pBlockData, pRow, pCommitter->skmRow.pTSchema);
+ code = tBlockDataAppendRow(pBlockData, pRow, pCommitter->skmRow.pTSchema, pTbData->uid);
if (code) goto _err;
tsdbTbDataIterNext(pIter);
pRow = tsdbTbDataIterGet(pIter);
- // if (pRow && tsdbKeyCmprFn(&TSDBROW_KEY(pRow), &toKey) >= 0) pRow = NULL;
- // crash on CI, use the block following
if (pRow) {
- TSDBKEY tmpKey = TSDBROW_KEY(pRow);
- if (tsdbKeyCmprFn(&tmpKey, &toKey) >= 0) {
+ TSDBKEY rowKey = TSDBROW_KEY(pRow);
+ if (tsdbKeyCmprFn(&rowKey, &toKey) >= 0) {
pRow = NULL;
}
}
- if (pBlockData->nRow >= pCommitter->maxRow * 4 / 5) goto _write_block;
- continue;
-
- _write_block:
- code = tsdbCommitBlockData(pCommitter, pBlockData, pBlock, &(SBlockIdx){.suid = suid, .uid = uid}, toDataOnly);
- if (code) goto _err;
-
- tBlockReset(pBlock);
- tBlockDataClearData(pBlockData);
+ if (pBlockData->nRow >= pCommitter->maxRow * 4 / 5) {
+ _write_block:
+ code = tsdbCommitDataBlock(pCommitter, NULL);
+ if (code) goto _err;
+ }
}
return code;
@@ -575,65 +723,16 @@ _err:
return code;
}
-static int32_t tsdbCommitTableDiskData(SCommitter *pCommitter, SBlock *pBlock, SBlockIdx *pBlockIdx) {
- int32_t code = 0;
- SBlock block;
+static int32_t tsdbGetNumOfRowsLessThan(STbDataIter *pIter, TSDBKEY key) {
+ int32_t nRow = 0;
- if (pBlock->last) {
- code = tsdbReadBlockData(pCommitter->dReader.pReader, pBlockIdx, pBlock, &pCommitter->dReader.bData, NULL, NULL);
- if (code) goto _err;
-
- tBlockReset(&block);
- code = tsdbCommitBlockData(pCommitter, &pCommitter->dReader.bData, &block, pBlockIdx, 0);
- if (code) goto _err;
- } else {
- code = tMapDataPutItem(&pCommitter->dWriter.mBlock, pBlock, tPutBlock);
- if (code) goto _err;
- }
-
- return code;
-
-_err:
- tsdbError("vgId:%d, tsdb commit table disk data failed since %s", TD_VID(pCommitter->pTsdb->pVnode), tstrerror(code));
- return code;
-}
-
-static int32_t tsdbCommitTableDataEnd(SCommitter *pCommitter, int64_t suid, int64_t uid) {
- int32_t code = 0;
- SBlockIdx blockIdx = {.suid = suid, .uid = uid};
- SBlockIdx *pBlockIdx = &blockIdx;
-
- code = tsdbWriteBlock(pCommitter->dWriter.pWriter, &pCommitter->dWriter.mBlock, NULL, pBlockIdx);
- if (code) goto _err;
-
- if (taosArrayPush(pCommitter->dWriter.aBlockIdx, pBlockIdx) == NULL) {
- code = TSDB_CODE_OUT_OF_MEMORY;
- goto _err;
- }
-
- return code;
-
-_err:
- tsdbError("vgId:%d, commit table data end failed since %s", TD_VID(pCommitter->pTsdb->pVnode), tstrerror(code));
- return code;
-}
-
-static int32_t tsdbGetOvlpNRow(STbDataIter *pIter, SBlock *pBlock) {
- int32_t nRow = 0;
- TSDBROW *pRow;
- TSDBKEY key;
- int32_t c = 0;
STbDataIter iter = *pIter;
-
- iter.pRow = NULL;
while (true) {
- pRow = tsdbTbDataIterGet(&iter);
-
+ TSDBROW *pRow = tsdbTbDataIterGet(&iter);
if (pRow == NULL) break;
- key = TSDBROW_KEY(pRow);
- c = tBlockCmprFn(&(SBlock){.maxKey = key, .minKey = key}, pBlock);
- if (c == 0) {
+ int32_t c = tsdbKeyCmprFn(&TSDBROW_KEY(pRow), &key);
+ if (c < 0) {
nRow++;
tsdbTbDataIterNext(&iter);
} else if (c > 0) {
@@ -648,42 +747,33 @@ static int32_t tsdbGetOvlpNRow(STbDataIter *pIter, SBlock *pBlock) {
static int32_t tsdbMergeAsSubBlock(SCommitter *pCommitter, STbDataIter *pIter, SBlock *pBlock) {
int32_t code = 0;
+ STbData *pTbData = pIter->pTbData;
SBlockData *pBlockData = &pCommitter->dWriter.bData;
- SBlockIdx *pBlockIdx = &(SBlockIdx){.suid = pIter->pTbData->suid, .uid = pIter->pTbData->uid};
- SBlock block;
- TSDBROW *pRow;
- code = tBlockDataSetSchema(pBlockData, pCommitter->skmTable.pTSchema);
- if (code) goto _err;
-
- pRow = tsdbTbDataIterGet(pIter);
- code = tsdbCommitterUpdateRowSchema(pCommitter, pBlockIdx->suid, pBlockIdx->uid, TSDBROW_SVERSION(pRow));
- if (code) goto _err;
+ tBlockDataClear(pBlockData);
+ TSDBROW *pRow = tsdbTbDataIterGet(pIter);
while (true) {
if (pRow == NULL) break;
- code = tBlockDataAppendRow(pBlockData, pRow, pCommitter->skmRow.pTSchema);
+
+ code = tsdbCommitterUpdateRowSchema(pCommitter, pTbData->suid, pTbData->uid, TSDBROW_SVERSION(pRow));
+ if (code) goto _err;
+
+ code = tBlockDataAppendRow(pBlockData, pRow, pCommitter->skmRow.pTSchema, pTbData->uid);
if (code) goto _err;
tsdbTbDataIterNext(pIter);
pRow = tsdbTbDataIterGet(pIter);
if (pRow) {
- TSDBKEY key = TSDBROW_KEY(pRow);
- int32_t c = tBlockCmprFn(&(SBlock){.minKey = key, .maxKey = key}, pBlock);
-
- if (c == 0) {
- code =
- tsdbCommitterUpdateRowSchema(pCommitter, pIter->pTbData->suid, pIter->pTbData->uid, TSDBROW_SVERSION(pRow));
- if (code) goto _err;
- } else if (c > 0) {
+ TSDBKEY rowKey = TSDBROW_KEY(pRow);
+ if (tsdbKeyCmprFn(&rowKey, &pBlock->maxKey) > 0) {
pRow = NULL;
- } else {
- ASSERT(0);
}
}
}
- block = *pBlock;
- code = tsdbCommitBlockData(pCommitter, pBlockData, &block, pBlockIdx, 0);
+ ASSERT(pBlockData->nRow > 0 && pBlock->nRow + pBlockData->nRow <= pCommitter->maxRow);
+
+ code = tsdbCommitDataBlock(pCommitter, pBlock);
if (code) goto _err;
return code;
@@ -693,176 +783,307 @@ _err:
return code;
}
-static int32_t tsdbCommitTableData(SCommitter *pCommitter, STbData *pTbData, SBlockIdx *pBlockIdx) {
- int32_t code = 0;
- STbDataIter iter = {0};
- STbDataIter *pIter = &iter;
- TSDBROW *pRow;
- int32_t iBlock;
- int32_t nBlock;
- int64_t suid;
- int64_t uid;
+static int32_t tsdbMergeCommitLast(SCommitter *pCommitter, STbDataIter *pIter) {
+ int32_t code = 0;
+ STbData *pTbData = pIter->pTbData;
+ int32_t nRow = tsdbGetNumOfRowsLessThan(pIter, (TSDBKEY){.ts = pCommitter->maxKey + 1, .version = VERSION_MIN});
- if (pTbData) {
- tsdbTbDataIterOpen(pTbData, &(TSDBKEY){.ts = pCommitter->minKey, .version = VERSION_MIN}, 0, pIter);
- pRow = tsdbTbDataIterGet(pIter);
- if (pRow && TSDBROW_TS(pRow) > pCommitter->maxKey) pRow = NULL;
+ if (pCommitter->dReader.pRowInfo && tTABLEIDCmprFn(pTbData, pCommitter->dReader.pRowInfo) == 0) {
+ if (pCommitter->dReader.pRowInfo->suid) { // super table
+ for (int32_t iRow = pCommitter->dReader.iRow; iRow < pCommitter->dReader.bDatal.nRow; iRow++) {
+ if (pTbData->uid != pCommitter->dReader.bDatal.aUid[iRow]) break;
+ nRow++;
+ }
+ } else { // normal table
+ ASSERT(pCommitter->dReader.iRow == 0);
+ nRow += pCommitter->dReader.bDatal.nRow;
+ }
+ }
- suid = pTbData->suid;
- uid = pTbData->uid;
- } else {
- pIter = NULL;
+ if (nRow == 0) goto _exit;
+
+ TSDBROW *pRow = tsdbTbDataIterGet(pIter);
+ if (pRow && TSDBROW_TS(pRow) > pCommitter->maxKey) {
pRow = NULL;
}
- if (pBlockIdx) {
- code = tsdbReadBlock(pCommitter->dReader.pReader, pBlockIdx, &pCommitter->dReader.mBlock, NULL);
- if (code) goto _err;
-
- nBlock = pCommitter->dReader.mBlock.nItem;
- ASSERT(nBlock > 0);
-
- suid = pBlockIdx->suid;
- uid = pBlockIdx->uid;
- } else {
- nBlock = 0;
+ SRowInfo *pRowInfo = pCommitter->dReader.pRowInfo;
+ if (pRowInfo && pRowInfo->uid != pTbData->uid) {
+ pRowInfo = NULL;
}
- if (pRow == NULL && nBlock == 0) goto _exit;
+ while (nRow) {
+ SBlockData *pBlockData;
+ int8_t toData;
- // start ===========
- tMapDataReset(&pCommitter->dWriter.mBlock);
+ if (nRow < pCommitter->minRow) { // to .last
+ toData = 0;
+ pBlockData = &pCommitter->dWriter.bDatal;
+
+ // commit and reset block data schema if need
+ // QUESTION: Is there a case that pBlockData->nRow == 0 but need to change schema ?
+ if (pBlockData->suid || pBlockData->uid) {
+ if (pBlockData->suid != pTbData->suid || pBlockData->suid == 0) {
+ if (pBlockData->nRow > 0) {
+ code = tsdbCommitLastBlock(pCommitter);
+ if (code) goto _err;
+ }
+
+ tBlockDataReset(pBlockData);
+ }
+ }
+
+ // set block data schema if need
+ if (pBlockData->suid == 0 && pBlockData->uid == 0) {
+ code =
+ tBlockDataInit(pBlockData, pTbData->suid, pTbData->suid ? 0 : pTbData->uid, pCommitter->skmTable.pTSchema);
+ if (code) goto _err;
+ }
+
+ if (pBlockData->nRow + nRow > pCommitter->maxRow) {
+ code = tsdbCommitLastBlock(pCommitter);
+ if (code) goto _err;
+ }
+ } else { // to .data
+ toData = 1;
+ pBlockData = &pCommitter->dWriter.bData;
+ ASSERT(pBlockData->nRow == 0);
+ }
+
+ while (pRow && pRowInfo) {
+ int32_t c = tsdbRowCmprFn(pRow, &pRowInfo->row);
+ if (c < 0) {
+ code = tsdbCommitterUpdateRowSchema(pCommitter, pTbData->suid, pTbData->uid, TSDBROW_SVERSION(pRow));
+ if (code) goto _err;
+
+ code = tBlockDataAppendRow(pBlockData, pRow, pCommitter->skmRow.pTSchema, pTbData->uid);
+ if (code) goto _err;
+
+ tsdbTbDataIterNext(pIter);
+ pRow = tsdbTbDataIterGet(pIter);
+ if (pRow && TSDBROW_TS(pRow) > pCommitter->maxKey) {
+ pRow = NULL;
+ }
+ } else if (c > 0) {
+ code = tBlockDataAppendRow(pBlockData, &pRowInfo->row, NULL, pTbData->uid);
+ if (code) goto _err;
+
+ code = tsdbCommitterNextLastRow(pCommitter);
+ if (code) goto _err;
+
+ pRowInfo = pCommitter->dReader.pRowInfo;
+ if (pRowInfo && pRowInfo->uid != pTbData->uid) {
+ pRowInfo = NULL;
+ }
+ } else {
+ ASSERT(0);
+ }
+
+ nRow--;
+ if (toData) {
+ if (nRow == 0 || pBlockData->nRow >= pCommitter->maxRow * 4 / 5) {
+ code = tsdbCommitDataBlock(pCommitter, NULL);
+ if (code) goto _err;
+ goto _outer_break;
+ }
+ }
+ }
+
+ while (pRow) {
+ code = tsdbCommitterUpdateRowSchema(pCommitter, pTbData->suid, pTbData->uid, TSDBROW_SVERSION(pRow));
+ if (code) goto _err;
+
+ code = tBlockDataAppendRow(pBlockData, pRow, pCommitter->skmRow.pTSchema, pTbData->uid);
+ if (code) goto _err;
+
+ tsdbTbDataIterNext(pIter);
+ pRow = tsdbTbDataIterGet(pIter);
+ if (pRow && TSDBROW_TS(pRow) > pCommitter->maxKey) {
+ pRow = NULL;
+ }
+
+ nRow--;
+ if (toData) {
+ if (nRow == 0 || pBlockData->nRow >= pCommitter->maxRow * 4 / 5) {
+ code = tsdbCommitDataBlock(pCommitter, NULL);
+ if (code) goto _err;
+ goto _outer_break;
+ }
+ }
+ }
+
+ while (pRowInfo) {
+ code = tBlockDataAppendRow(pBlockData, &pRowInfo->row, NULL, pTbData->uid);
+ if (code) goto _err;
+
+ code = tsdbCommitterNextLastRow(pCommitter);
+ if (code) goto _err;
+
+ pRowInfo = pCommitter->dReader.pRowInfo;
+ if (pRowInfo && pRowInfo->uid != pTbData->uid) {
+ pRowInfo = NULL;
+ }
+
+ nRow--;
+ if (toData) {
+ if (nRow == 0 || pBlockData->nRow >= pCommitter->maxRow * 4 / 5) {
+ code = tsdbCommitDataBlock(pCommitter, NULL);
+ if (code) goto _err;
+ goto _outer_break;
+ }
+ }
+ }
+
+ _outer_break:
+ ASSERT(nRow >= 0);
+ }
+
+_exit:
+ return code;
+
+_err:
+ tsdbError("vgId:%d tsdb merge commit last failed since %s", TD_VID(pCommitter->pTsdb->pVnode), tstrerror(code));
+ return code;
+}
+
+static int32_t tsdbCommitTableData(SCommitter *pCommitter, STbData *pTbData) {
+ int32_t code = 0;
+
+ ASSERT(pCommitter->dReader.pBlockIdx == NULL || tTABLEIDCmprFn(pCommitter->dReader.pBlockIdx, pTbData) >= 0);
+ ASSERT(pCommitter->dReader.pRowInfo == NULL || tTABLEIDCmprFn(pCommitter->dReader.pRowInfo, pTbData) >= 0);
+
+ // merge commit table data
+ STbDataIter iter = {0};
+ STbDataIter *pIter = &iter;
+ TSDBROW *pRow;
+
+ tsdbTbDataIterOpen(pTbData, &(TSDBKEY){.ts = pCommitter->minKey, .version = VERSION_MIN}, 0, pIter);
+ pRow = tsdbTbDataIterGet(pIter);
+ if (pRow && TSDBROW_TS(pRow) > pCommitter->maxKey) {
+ pRow = NULL;
+ }
+
+ if (pRow == NULL) goto _exit;
+
+ int32_t iBlock = 0;
SBlock block;
SBlock *pBlock = █
-
- iBlock = 0;
- if (iBlock < nBlock) {
+ if (pCommitter->dReader.pBlockIdx && tTABLEIDCmprFn(pTbData, pCommitter->dReader.pBlockIdx) == 0) {
tMapDataGetItemByIdx(&pCommitter->dReader.mBlock, iBlock, pBlock, tGetBlock);
} else {
pBlock = NULL;
}
- if (pRow) {
- code = tsdbCommitterUpdateTableSchema(pCommitter, pTbData->suid, pTbData->uid, pTbData->maxSkmVer);
- if (code) goto _err;
- }
+ code = tsdbCommitterUpdateTableSchema(pCommitter, pTbData->suid, pTbData->uid);
+ if (code) goto _err;
- // merge ===========
- while (true) {
- if (pRow == NULL && pBlock == NULL) break;
+ tMapDataReset(&pCommitter->dWriter.mBlock);
+ code = tBlockDataInit(&pCommitter->dReader.bData, pTbData->suid, pTbData->uid, pCommitter->skmTable.pTSchema);
+ if (code) goto _err;
+ code = tBlockDataInit(&pCommitter->dWriter.bData, pTbData->suid, pTbData->uid, pCommitter->skmTable.pTSchema);
+ if (code) goto _err;
- if (pRow && pBlock) {
- if (pBlock->last) {
- code = tsdbMergeTableData(pCommitter, pIter, pBlock,
- (TSDBKEY){.ts = pCommitter->maxKey + 1, .version = VERSION_MIN}, 0);
- if (code) goto _err;
-
- pRow = tsdbTbDataIterGet(pIter);
- if (pRow && TSDBROW_TS(pRow) > pCommitter->maxKey) pRow = NULL;
- iBlock++;
- if (iBlock < nBlock) {
- tMapDataGetItemByIdx(&pCommitter->dReader.mBlock, iBlock, pBlock, tGetBlock);
- } else {
- pBlock = NULL;
- }
-
- ASSERT(pRow == NULL && pBlock == NULL);
- } else {
- int32_t c = tBlockCmprFn(&(SBlock){.maxKey = TSDBROW_KEY(pRow), .minKey = TSDBROW_KEY(pRow)}, pBlock);
- if (c > 0) {
- // only disk data
- code = tsdbCommitTableDiskData(pCommitter, pBlock, pBlockIdx);
- if (code) goto _err;
-
- iBlock++;
- if (iBlock < nBlock) {
- tMapDataGetItemByIdx(&pCommitter->dReader.mBlock, iBlock, pBlock, tGetBlock);
- } else {
- pBlock = NULL;
- }
- } else if (c < 0) {
- // only memory data
- code = tsdbCommitTableMemData(pCommitter, pIter, pBlock->minKey, 1);
- if (code) goto _err;
-
- pRow = tsdbTbDataIterGet(pIter);
- if (pRow && TSDBROW_TS(pRow) > pCommitter->maxKey) pRow = NULL;
- } else {
- // merge memory and disk
- int32_t nOvlp = tsdbGetOvlpNRow(pIter, pBlock);
- ASSERT(nOvlp);
- if (pBlock->nRow + nOvlp <= pCommitter->maxRow && pBlock->nSubBlock < TSDB_MAX_SUBBLOCKS) {
- code = tsdbMergeAsSubBlock(pCommitter, pIter, pBlock);
- if (code) goto _err;
- } else {
- TSDBKEY toKey = {.ts = pCommitter->maxKey + 1, .version = VERSION_MIN};
- int8_t toDataOnly = 0;
-
- if (iBlock < nBlock - 1) {
- toDataOnly = 1;
-
- SBlock nextBlock = {0};
- tBlockReset(&nextBlock);
- tMapDataGetItemByIdx(&pCommitter->dReader.mBlock, iBlock + 1, &nextBlock, tGetBlock);
- toKey = nextBlock.minKey;
- }
-
- code = tsdbMergeTableData(pCommitter, pIter, pBlock, toKey, toDataOnly);
- if (code) goto _err;
- }
-
- pRow = tsdbTbDataIterGet(pIter);
- if (pRow && TSDBROW_TS(pRow) > pCommitter->maxKey) pRow = NULL;
- iBlock++;
- if (iBlock < nBlock) {
- tMapDataGetItemByIdx(&pCommitter->dReader.mBlock, iBlock, pBlock, tGetBlock);
- } else {
- pBlock = NULL;
- }
- }
- }
- } else if (pBlock) {
- code = tsdbCommitTableDiskData(pCommitter, pBlock, pBlockIdx);
+ // .data merge
+ while (pBlock && pRow) {
+ int32_t c = tBlockCmprFn(pBlock, &(SBlock){.minKey = TSDBROW_KEY(pRow), .maxKey = TSDBROW_KEY(pRow)});
+ if (c < 0) { // disk
+ code = tMapDataPutItem(&pCommitter->dWriter.mBlock, pBlock, tPutBlock);
if (code) goto _err;
+ // next
iBlock++;
- if (iBlock < nBlock) {
+ if (iBlock < pCommitter->dReader.mBlock.nItem) {
tMapDataGetItemByIdx(&pCommitter->dReader.mBlock, iBlock, pBlock, tGetBlock);
} else {
pBlock = NULL;
}
- } else {
- code =
- tsdbCommitTableMemData(pCommitter, pIter, (TSDBKEY){.ts = pCommitter->maxKey + 1, .version = VERSION_MIN}, 0);
+ } else if (c > 0) { // memory
+ code = tsdbCommitTableMemData(pCommitter, pIter, pBlock->minKey);
if (code) goto _err;
+ // next
pRow = tsdbTbDataIterGet(pIter);
- if (pRow && TSDBROW_TS(pRow) > pCommitter->maxKey) pRow = NULL;
- ASSERT(pRow == NULL);
+ if (pRow && TSDBROW_TS(pRow) > pCommitter->maxKey) {
+ pRow = NULL;
+ }
+ } else { // merge
+ int32_t nOvlp = tsdbGetNumOfRowsLessThan(pIter, pBlock->maxKey);
+
+ ASSERT(nOvlp > 0);
+
+ if (pBlock->nRow + nOvlp <= pCommitter->maxRow && pBlock->nSubBlock < TSDB_MAX_SUBBLOCKS) {
+ code = tsdbMergeAsSubBlock(pCommitter, pIter, pBlock);
+ if (code) goto _err;
+ } else {
+ code = tsdbMergeCommitData(pCommitter, pIter, pBlock);
+ if (code) goto _err;
+ }
+
+ // next
+ pRow = tsdbTbDataIterGet(pIter);
+ if (pRow && TSDBROW_TS(pRow) > pCommitter->maxKey) {
+ pRow = NULL;
+ }
+ iBlock++;
+ if (iBlock < pCommitter->dReader.mBlock.nItem) {
+ tMapDataGetItemByIdx(&pCommitter->dReader.mBlock, iBlock, pBlock, tGetBlock);
+ } else {
+ pBlock = NULL;
+ }
}
}
- // end =====================
- code = tsdbCommitTableDataEnd(pCommitter, suid, uid);
+ while (pBlock) {
+ code = tMapDataPutItem(&pCommitter->dWriter.mBlock, pBlock, tPutBlock);
+ if (code) goto _err;
+
+ // next
+ iBlock++;
+ if (iBlock < pCommitter->dReader.mBlock.nItem) {
+ tMapDataGetItemByIdx(&pCommitter->dReader.mBlock, iBlock, pBlock, tGetBlock);
+ } else {
+ pBlock = NULL;
+ }
+ }
+
+ // .data append and .last merge
+ code = tsdbMergeCommitLast(pCommitter, pIter);
if (code) goto _err;
-_exit:
- if (pIter) {
- pRow = tsdbTbDataIterGet(pIter);
- if (pRow) pCommitter->nextKey = TMIN(pCommitter->nextKey, TSDBROW_TS(pRow));
+ // end
+ if (pCommitter->dWriter.mBlock.nItem > 0) {
+ SBlockIdx blockIdx = {.suid = pTbData->suid, .uid = pTbData->uid};
+ code = tsdbWriteBlock(pCommitter->dWriter.pWriter, &pCommitter->dWriter.mBlock, &blockIdx);
+ if (code) goto _err;
+
+ if (taosArrayPush(pCommitter->dWriter.aBlockIdx, &blockIdx) == NULL) {
+ code = TSDB_CODE_OUT_OF_MEMORY;
+ goto _err;
+ }
}
+
+_exit:
+ pRow = tsdbTbDataIterGet(pIter);
+ if (pRow) {
+ pCommitter->nextKey = TMIN(pCommitter->nextKey, TSDBROW_TS(pRow));
+ }
+
return code;
_err:
- tsdbError("vgId:%d, tsdb commit table data failed since %s", TD_VID(pCommitter->pTsdb->pVnode), tstrerror(code));
+ tsdbError("vgId:%d tsdb commit table data failed since %s", TD_VID(pCommitter->pTsdb->pVnode), tstrerror(code));
return code;
}
static int32_t tsdbCommitFileDataEnd(SCommitter *pCommitter) {
int32_t code = 0;
- // write blockIdx
- code = tsdbWriteBlockIdx(pCommitter->dWriter.pWriter, pCommitter->dWriter.aBlockIdx, NULL);
+ // write aBlockIdx
+ code = tsdbWriteBlockIdx(pCommitter->dWriter.pWriter, pCommitter->dWriter.aBlockIdx);
+ if (code) goto _err;
+
+ // write aBlockL
+ code = tsdbWriteBlockL(pCommitter->dWriter.pWriter, pCommitter->dWriter.aBlockL);
if (code) goto _err;
// update file header
@@ -890,6 +1111,98 @@ _err:
return code;
}
+static int32_t tsdbMoveCommitData(SCommitter *pCommitter, TABLEID toTable) {
+ int32_t code = 0;
+
+ // .data
+ while (true) {
+ if (pCommitter->dReader.pBlockIdx == NULL || tTABLEIDCmprFn(pCommitter->dReader.pBlockIdx, &toTable) >= 0) break;
+
+ SBlockIdx blockIdx = *pCommitter->dReader.pBlockIdx;
+ code = tsdbWriteBlock(pCommitter->dWriter.pWriter, &pCommitter->dReader.mBlock, &blockIdx);
+ if (code) goto _err;
+
+ if (taosArrayPush(pCommitter->dWriter.aBlockIdx, &blockIdx) == NULL) {
+ code = TSDB_CODE_OUT_OF_MEMORY;
+ goto _err;
+ }
+
+ code = tsdbCommitterNextTableData(pCommitter);
+ if (code) goto _err;
+ }
+
+ // .last
+ while (true) {
+ if (pCommitter->dReader.pRowInfo == NULL || tTABLEIDCmprFn(pCommitter->dReader.pRowInfo, &toTable) >= 0) break;
+
+ SBlockData *pBlockDataR = &pCommitter->dReader.bDatal;
+ SBlockData *pBlockDataW = &pCommitter->dWriter.bDatal;
+ tb_uid_t suid = pCommitter->dReader.pRowInfo->suid;
+ tb_uid_t uid = pCommitter->dReader.pRowInfo->uid;
+
+ ASSERT((pBlockDataR->suid && !pBlockDataR->uid) || (!pBlockDataR->suid && pBlockDataR->uid));
+ ASSERT(pBlockDataR->nRow > 0);
+
+ // commit and reset block data schema if need
+ if (pBlockDataW->suid || pBlockDataW->uid) {
+ if (pBlockDataW->suid != suid || pBlockDataW->suid == 0) {
+ if (pBlockDataW->nRow > 0) {
+ code = tsdbCommitLastBlock(pCommitter);
+ if (code) goto _err;
+ }
+ tBlockDataReset(pBlockDataW);
+ }
+ }
+
+ // set block data schema if need
+ if (pBlockDataW->suid == 0 && pBlockDataW->uid == 0) {
+ code = tsdbCommitterUpdateTableSchema(pCommitter, suid, uid);
+ if (code) goto _err;
+
+ code = tBlockDataInit(pBlockDataW, suid, suid ? 0 : uid, pCommitter->skmTable.pTSchema);
+ if (code) goto _err;
+ }
+
+ // check if it can make sure that one table data in one block
+ int32_t nRow = 0;
+ if (pBlockDataR->suid) {
+ int32_t iRow = pCommitter->dReader.iRow;
+ while ((iRow < pBlockDataR->nRow) && (pBlockDataR->aUid[iRow] == uid)) {
+ nRow++;
+ iRow++;
+ }
+ } else {
+ ASSERT(pCommitter->dReader.iRow == 0);
+ nRow = pBlockDataR->nRow;
+ }
+
+ ASSERT(nRow > 0 && nRow < pCommitter->minRow);
+
+ if (pBlockDataW->nRow + nRow > pCommitter->maxRow) {
+ ASSERT(pBlockDataW->nRow > 0);
+
+ code = tsdbCommitLastBlock(pCommitter);
+ if (code) goto _err;
+ }
+
+ while (nRow > 0) {
+ code = tBlockDataAppendRow(pBlockDataW, &pCommitter->dReader.pRowInfo->row, NULL, uid);
+ if (code) goto _err;
+
+ code = tsdbCommitterNextLastRow(pCommitter);
+ if (code) goto _err;
+
+ nRow--;
+ }
+ }
+
+ return code;
+
+_err:
+ tsdbError("vgId:%d tsdb move commit data failed since %s", TD_VID(pCommitter->pTsdb->pVnode), tstrerror(code));
+ return code;
+}
+
static int32_t tsdbCommitFileData(SCommitter *pCommitter) {
int32_t code = 0;
STsdb *pTsdb = pCommitter->pTsdb;
@@ -900,59 +1213,30 @@ static int32_t tsdbCommitFileData(SCommitter *pCommitter) {
if (code) goto _err;
// commit file data impl
- int32_t iTbData = 0;
- int32_t nTbData = taosArrayGetSize(pMemTable->aTbData);
- int32_t iBlockIdx = 0;
- int32_t nBlockIdx = taosArrayGetSize(pCommitter->dReader.aBlockIdx);
- STbData *pTbData;
- SBlockIdx *pBlockIdx;
+ for (int32_t iTbData = 0; iTbData < taosArrayGetSize(pCommitter->aTbDataP); iTbData++) {
+ STbData *pTbData = (STbData *)taosArrayGetP(pCommitter->aTbDataP, iTbData);
- ASSERT(nTbData > 0);
+ // move commit until current (suid, uid)
+ code = tsdbMoveCommitData(pCommitter, *(TABLEID *)pTbData);
+ if (code) goto _err;
- pTbData = (STbData *)taosArrayGetP(pMemTable->aTbData, iTbData);
- pBlockIdx = (iBlockIdx < nBlockIdx) ? (SBlockIdx *)taosArrayGet(pCommitter->dReader.aBlockIdx, iBlockIdx) : NULL;
- while (pTbData || pBlockIdx) {
- if (pTbData && pBlockIdx) {
- int32_t c = tTABLEIDCmprFn(pTbData, pBlockIdx);
+ // commit current table data
+ code = tsdbCommitTableData(pCommitter, pTbData);
+ if (code) goto _err;
- if (c == 0) {
- goto _commit_table_mem_and_disk;
- } else if (c < 0) {
- goto _commit_table_mem_data;
- } else {
- goto _commit_table_disk_data;
- }
- } else if (pBlockIdx) {
- goto _commit_table_disk_data;
- } else {
- goto _commit_table_mem_data;
+ // move next reader table data if need
+ if (pCommitter->dReader.pBlockIdx && tTABLEIDCmprFn(pTbData, pCommitter->dReader.pBlockIdx) == 0) {
+ code = tsdbCommitterNextTableData(pCommitter);
+ if (code) goto _err;
}
+ }
- _commit_table_mem_data:
- code = tsdbCommitTableData(pCommitter, pTbData, NULL);
+ code = tsdbMoveCommitData(pCommitter, (TABLEID){.suid = INT64_MAX, .uid = INT64_MAX});
+ if (code) goto _err;
+
+ if (pCommitter->dWriter.bDatal.nRow > 0) {
+ code = tsdbCommitLastBlock(pCommitter);
if (code) goto _err;
-
- iTbData++;
- pTbData = (iTbData < nTbData) ? (STbData *)taosArrayGetP(pMemTable->aTbData, iTbData) : NULL;
- continue;
-
- _commit_table_disk_data:
- code = tsdbCommitTableData(pCommitter, NULL, pBlockIdx);
- if (code) goto _err;
-
- iBlockIdx++;
- pBlockIdx = (iBlockIdx < nBlockIdx) ? (SBlockIdx *)taosArrayGet(pCommitter->dReader.aBlockIdx, iBlockIdx) : NULL;
- continue;
-
- _commit_table_mem_and_disk:
- code = tsdbCommitTableData(pCommitter, pTbData, pBlockIdx);
- if (code) goto _err;
-
- iBlockIdx++;
- pBlockIdx = (iBlockIdx < nBlockIdx) ? (SBlockIdx *)taosArrayGet(pCommitter->dReader.aBlockIdx, iBlockIdx) : NULL;
- iTbData++;
- pTbData = (iTbData < nTbData) ? (STbData *)taosArrayGetP(pMemTable->aTbData, iTbData) : NULL;
- continue;
}
// commit file data end
@@ -987,6 +1271,11 @@ static int32_t tsdbStartCommit(STsdb *pTsdb, SCommitter *pCommitter) {
pCommitter->minRow = pTsdb->pVnode->config.tsdbCfg.minRows;
pCommitter->maxRow = pTsdb->pVnode->config.tsdbCfg.maxRows;
pCommitter->cmprAlg = pTsdb->pVnode->config.tsdbCfg.compression;
+ pCommitter->aTbDataP = tsdbMemTableGetTbDataArray(pTsdb->imem);
+ if (pCommitter->aTbDataP == NULL) {
+ code = TSDB_CODE_OUT_OF_MEMORY;
+ goto _err;
+ }
code = tsdbFSCopy(pTsdb, &pCommitter->fs);
if (code) goto _err;
@@ -1001,22 +1290,42 @@ _err:
static int32_t tsdbCommitDataStart(SCommitter *pCommitter) {
int32_t code = 0;
+ // Reader
pCommitter->dReader.aBlockIdx = taosArrayInit(0, sizeof(SBlockIdx));
if (pCommitter->dReader.aBlockIdx == NULL) {
code = TSDB_CODE_OUT_OF_MEMORY;
goto _exit;
}
+ code = tBlockDataCreate(&pCommitter->dReader.bData);
+ if (code) goto _exit;
+
+ pCommitter->dReader.aBlockL = taosArrayInit(0, sizeof(SBlockL));
+ if (pCommitter->dReader.aBlockL == NULL) {
+ code = TSDB_CODE_OUT_OF_MEMORY;
+ goto _exit;
+ }
+
+ code = tBlockDataCreate(&pCommitter->dReader.bDatal);
+ if (code) goto _exit;
+
+ // Writer
pCommitter->dWriter.aBlockIdx = taosArrayInit(0, sizeof(SBlockIdx));
if (pCommitter->dWriter.aBlockIdx == NULL) {
code = TSDB_CODE_OUT_OF_MEMORY;
goto _exit;
}
- code = tBlockDataInit(&pCommitter->dReader.bData);
+ pCommitter->dWriter.aBlockL = taosArrayInit(0, sizeof(SBlockL));
+ if (pCommitter->dWriter.aBlockL == NULL) {
+ code = TSDB_CODE_OUT_OF_MEMORY;
+ goto _exit;
+ }
+
+ code = tBlockDataCreate(&pCommitter->dWriter.bData);
if (code) goto _exit;
- code = tBlockDataInit(&pCommitter->dWriter.bData);
+ code = tBlockDataCreate(&pCommitter->dWriter.bDatal);
if (code) goto _exit;
_exit:
@@ -1024,12 +1333,19 @@ _exit:
}
static void tsdbCommitDataEnd(SCommitter *pCommitter) {
+ // Reader
taosArrayDestroy(pCommitter->dReader.aBlockIdx);
tMapDataClear(&pCommitter->dReader.mBlock);
- tBlockDataClear(&pCommitter->dReader.bData, 1);
+ tBlockDataDestroy(&pCommitter->dReader.bData, 1);
+ taosArrayDestroy(pCommitter->dReader.aBlockL);
+ tBlockDataDestroy(&pCommitter->dReader.bDatal, 1);
+
+ // Writer
taosArrayDestroy(pCommitter->dWriter.aBlockIdx);
+ taosArrayDestroy(pCommitter->dWriter.aBlockL);
tMapDataClear(&pCommitter->dWriter.mBlock);
- tBlockDataClear(&pCommitter->dWriter.bData, 1);
+ tBlockDataDestroy(&pCommitter->dWriter.bData, 1);
+ tBlockDataDestroy(&pCommitter->dWriter.bDatal, 1);
tTSchemaDestroy(pCommitter->skmTable.pTSchema);
tTSchemaDestroy(pCommitter->skmRow.pTSchema);
}
@@ -1049,9 +1365,6 @@ static int32_t tsdbCommitData(SCommitter *pCommitter) {
// impl ====================
pCommitter->nextKey = pMemTable->minKey;
while (pCommitter->nextKey < TSKEY_MAX) {
- pCommitter->commitFid = tsdbKeyFid(pCommitter->nextKey, pCommitter->minutes, pCommitter->precision);
- tsdbFidKeyRange(pCommitter->commitFid, pCommitter->minutes, pCommitter->precision, &pCommitter->minKey,
- &pCommitter->maxKey);
code = tsdbCommitFileData(pCommitter);
if (code) goto _err;
}
@@ -1088,13 +1401,13 @@ static int32_t tsdbCommitDel(SCommitter *pCommitter) {
int32_t iDelIdx = 0;
int32_t nDelIdx = taosArrayGetSize(pCommitter->aDelIdx);
int32_t iTbData = 0;
- int32_t nTbData = taosArrayGetSize(pMemTable->aTbData);
+ int32_t nTbData = taosArrayGetSize(pCommitter->aTbDataP);
STbData *pTbData;
SDelIdx *pDelIdx;
ASSERT(nTbData > 0);
- pTbData = (STbData *)taosArrayGetP(pMemTable->aTbData, iTbData);
+ pTbData = (STbData *)taosArrayGetP(pCommitter->aTbDataP, iTbData);
pDelIdx = (iDelIdx < nDelIdx) ? (SDelIdx *)taosArrayGet(pCommitter->aDelIdx, iDelIdx) : NULL;
while (true) {
if (pTbData == NULL && pDelIdx == NULL) break;
@@ -1120,7 +1433,7 @@ static int32_t tsdbCommitDel(SCommitter *pCommitter) {
if (code) goto _err;
iTbData++;
- pTbData = (iTbData < nTbData) ? (STbData *)taosArrayGetP(pMemTable->aTbData, iTbData) : NULL;
+ pTbData = (iTbData < nTbData) ? (STbData *)taosArrayGetP(pCommitter->aTbDataP, iTbData) : NULL;
continue;
_commit_disk_del:
@@ -1136,7 +1449,7 @@ static int32_t tsdbCommitDel(SCommitter *pCommitter) {
if (code) goto _err;
iTbData++;
- pTbData = (iTbData < nTbData) ? (STbData *)taosArrayGetP(pMemTable->aTbData, iTbData) : NULL;
+ pTbData = (iTbData < nTbData) ? (STbData *)taosArrayGetP(pCommitter->aTbDataP, iTbData) : NULL;
iDelIdx++;
pDelIdx = (iDelIdx < nDelIdx) ? (SDelIdx *)taosArrayGet(pCommitter->aDelIdx, iDelIdx) : NULL;
continue;
@@ -1184,6 +1497,7 @@ static int32_t tsdbEndCommit(SCommitter *pCommitter, int32_t eno) {
tsdbUnrefMemTable(pMemTable);
tsdbFSDestroy(&pCommitter->fs);
+ taosArrayDestroy(pCommitter->aTbDataP);
tsdbInfo("vgId:%d, tsdb end commit", TD_VID(pTsdb->pVnode));
return code;
diff --git a/source/dnode/vnode/src/tsdb/tsdbFS.c b/source/dnode/vnode/src/tsdb/tsdbFS.c
index 74f1aef1fc..247de99338 100644
--- a/source/dnode/vnode/src/tsdb/tsdbFS.c
+++ b/source/dnode/vnode/src/tsdb/tsdbFS.c
@@ -576,10 +576,7 @@ int32_t tsdbFSCopy(STsdb *pTsdb, STsdbFS *pFS) {
code = TSDB_CODE_OUT_OF_MEMORY;
goto _exit;
}
- fSet.pHeadF->nRef = 0;
- fSet.pHeadF->commitID = pSet->pHeadF->commitID;
- fSet.pHeadF->size = pSet->pHeadF->size;
- fSet.pHeadF->offset = pSet->pHeadF->offset;
+ *fSet.pHeadF = *pSet->pHeadF;
// data
fSet.pDataF = (SDataFile *)taosMemoryMalloc(sizeof(SDataFile));
@@ -587,9 +584,7 @@ int32_t tsdbFSCopy(STsdb *pTsdb, STsdbFS *pFS) {
code = TSDB_CODE_OUT_OF_MEMORY;
goto _exit;
}
- fSet.pDataF->nRef = 0;
- fSet.pDataF->commitID = pSet->pDataF->commitID;
- fSet.pDataF->size = pSet->pDataF->size;
+ *fSet.pDataF = *pSet->pDataF;
// data
fSet.pLastF = (SLastFile *)taosMemoryMalloc(sizeof(SLastFile));
@@ -597,9 +592,7 @@ int32_t tsdbFSCopy(STsdb *pTsdb, STsdbFS *pFS) {
code = TSDB_CODE_OUT_OF_MEMORY;
goto _exit;
}
- fSet.pLastF->nRef = 0;
- fSet.pLastF->commitID = pSet->pLastF->commitID;
- fSet.pLastF->size = pSet->pLastF->size;
+ *fSet.pLastF = *pSet->pLastF;
// last
fSet.pSmaF = (SSmaFile *)taosMemoryMalloc(sizeof(SSmaFile));
@@ -607,9 +600,7 @@ int32_t tsdbFSCopy(STsdb *pTsdb, STsdbFS *pFS) {
code = TSDB_CODE_OUT_OF_MEMORY;
goto _exit;
}
- fSet.pSmaF->nRef = 0;
- fSet.pSmaF->commitID = pSet->pSmaF->commitID;
- fSet.pSmaF->size = pSet->pSmaF->size;
+ *fSet.pSmaF = *pSet->pSmaF;
if (taosArrayPush(pFS->aDFileSet, &fSet) == NULL) {
code = TSDB_CODE_OUT_OF_MEMORY;
diff --git a/source/dnode/vnode/src/tsdb/tsdbFile.c b/source/dnode/vnode/src/tsdb/tsdbFile.c
index 52a102f911..00d2ac848f 100644
--- a/source/dnode/vnode/src/tsdb/tsdbFile.c
+++ b/source/dnode/vnode/src/tsdb/tsdbFile.c
@@ -58,6 +58,7 @@ int32_t tPutLastFile(uint8_t *p, SLastFile *pLastFile) {
n += tPutI64v(p ? p + n : p, pLastFile->commitID);
n += tPutI64v(p ? p + n : p, pLastFile->size);
+ n += tPutI64v(p ? p + n : p, pLastFile->offset);
return n;
}
@@ -67,6 +68,7 @@ static int32_t tGetLastFile(uint8_t *p, SLastFile *pLastFile) {
n += tGetI64v(p + n, &pLastFile->commitID);
n += tGetI64v(p + n, &pLastFile->size);
+ n += tGetI64v(p + n, &pLastFile->offset);
return n;
}
@@ -186,11 +188,16 @@ int32_t tPutDFileSet(uint8_t *p, SDFileSet *pSet) {
n += tPutI32v(p ? p + n : p, pSet->diskId.level);
n += tPutI32v(p ? p + n : p, pSet->diskId.id);
n += tPutI32v(p ? p + n : p, pSet->fid);
+
+ // data
n += tPutHeadFile(p ? p + n : p, pSet->pHeadF);
n += tPutDataFile(p ? p + n : p, pSet->pDataF);
- n += tPutLastFile(p ? p + n : p, pSet->pLastF);
n += tPutSmaFile(p ? p + n : p, pSet->pSmaF);
+ // last
+ n += tPutU8(p ? p + n : p, 1); // for future compatibility
+ n += tPutLastFile(p ? p + n : p, pSet->pLastF);
+
return n;
}
@@ -200,11 +207,17 @@ int32_t tGetDFileSet(uint8_t *p, SDFileSet *pSet) {
n += tGetI32v(p + n, &pSet->diskId.level);
n += tGetI32v(p + n, &pSet->diskId.id);
n += tGetI32v(p + n, &pSet->fid);
+
+ // data
n += tGetHeadFile(p + n, pSet->pHeadF);
n += tGetDataFile(p + n, pSet->pDataF);
- n += tGetLastFile(p + n, pSet->pLastF);
n += tGetSmaFile(p + n, pSet->pSmaF);
+ // last
+ uint8_t nLast;
+ n += tGetU8(p + n, &nLast);
+ n += tGetLastFile(p + n, pSet->pLastF);
+
return n;
}
diff --git a/source/dnode/vnode/src/tsdb/tsdbMemTable.c b/source/dnode/vnode/src/tsdb/tsdbMemTable.c
index 34b37ffe9b..a6628463f8 100644
--- a/source/dnode/vnode/src/tsdb/tsdbMemTable.c
+++ b/source/dnode/vnode/src/tsdb/tsdbMemTable.c
@@ -15,6 +15,7 @@
#include "tsdb.h"
+#define MEM_MIN_HASH 1024
#define SL_MAX_LEVEL 5
#define SL_NODE_SIZE(l) (sizeof(SMemSkipListNode) + sizeof(SMemSkipListNode *) * (l)*2)
@@ -45,12 +46,12 @@ int32_t tsdbMemTableCreate(STsdb *pTsdb, SMemTable **ppMemTable) {
pMemTable->nRef = 1;
pMemTable->minKey = TSKEY_MAX;
pMemTable->maxKey = TSKEY_MIN;
- pMemTable->minVersion = VERSION_MAX;
- pMemTable->maxVersion = VERSION_MIN;
pMemTable->nRow = 0;
pMemTable->nDel = 0;
- pMemTable->aTbData = taosArrayInit(128, sizeof(STbData *));
- if (pMemTable->aTbData == NULL) {
+ pMemTable->nTbData = 0;
+ pMemTable->nBucket = MEM_MIN_HASH;
+ pMemTable->aBucket = (STbData **)taosMemoryCalloc(pMemTable->nBucket, sizeof(STbData *));
+ if (pMemTable->aBucket == NULL) {
code = TSDB_CODE_OUT_OF_MEMORY;
taosMemoryFree(pMemTable);
goto _err;
@@ -68,37 +69,30 @@ _err:
void tsdbMemTableDestroy(SMemTable *pMemTable) {
if (pMemTable) {
vnodeBufPoolUnRef(pMemTable->pPool);
- taosArrayDestroy(pMemTable->aTbData);
+ taosMemoryFree(pMemTable->aBucket);
taosMemoryFree(pMemTable);
}
}
-static int32_t tbDataPCmprFn(const void *p1, const void *p2) {
- STbData *pTbData1 = *(STbData **)p1;
- STbData *pTbData2 = *(STbData **)p2;
+static FORCE_INLINE STbData *tsdbGetTbDataFromMemTableImpl(SMemTable *pMemTable, tb_uid_t suid, tb_uid_t uid) {
+ STbData *pTbData = pMemTable->aBucket[TABS(uid) % pMemTable->nBucket];
- if (pTbData1->suid < pTbData2->suid) {
- return -1;
- } else if (pTbData1->suid > pTbData2->suid) {
- return 1;
+ while (pTbData) {
+ if (pTbData->uid == uid) break;
+ pTbData = pTbData->next;
}
- if (pTbData1->uid < pTbData2->uid) {
- return -1;
- } else if (pTbData1->uid > pTbData2->uid) {
- return 1;
- }
-
- return 0;
+ return pTbData;
}
-void tsdbGetTbDataFromMemTable(SMemTable *pMemTable, tb_uid_t suid, tb_uid_t uid, STbData **ppTbData) {
- STbData *pTbData = &(STbData){.suid = suid, .uid = uid};
+
+STbData *tsdbGetTbDataFromMemTable(SMemTable *pMemTable, tb_uid_t suid, tb_uid_t uid) {
+ STbData *pTbData;
taosRLockLatch(&pMemTable->latch);
- void *p = taosArraySearch(pMemTable->aTbData, &pTbData, tbDataPCmprFn, TD_EQ);
+ pTbData = tsdbGetTbDataFromMemTableImpl(pMemTable, suid, uid);
taosRUnLockLatch(&pMemTable->latch);
- *ppTbData = p ? *(STbData **)p : NULL;
+ return pTbData;
}
int32_t tsdbInsertTableData(STsdb *pTsdb, int64_t version, SSubmitMsgIter *pMsgIter, SSubmitBlk *pBlock,
@@ -184,10 +178,6 @@ int32_t tsdbDeleteTableData(STsdb *pTsdb, int64_t version, tb_uid_t suid, tb_uid
pTbData->pTail = pDelData;
}
- // update the state of pMemTable and other (todo)
-
- pMemTable->minVersion = TMIN(pMemTable->minVersion, version);
- pMemTable->maxVersion = TMAX(pMemTable->maxVersion, version);
pMemTable->nDel++;
if (TSDB_CACHE_LAST_ROW(pMemTable->pTsdb->pVnode->config) && tsdbKeyCmprFn(&lastKey, &pTbData->maxKey) >= 0) {
@@ -320,18 +310,44 @@ _exit:
return pIter->pRow;
}
+static int32_t tsdbMemTableRehash(SMemTable *pMemTable) {
+ int32_t code = 0;
+
+ int32_t nBucket = pMemTable->nBucket * 2;
+ STbData **aBucket = (STbData **)taosMemoryCalloc(nBucket, sizeof(STbData *));
+ if (aBucket == NULL) {
+ code = TSDB_CODE_OUT_OF_MEMORY;
+ goto _exit;
+ }
+
+ for (int32_t iBucket = 0; iBucket < pMemTable->nBucket; iBucket++) {
+ STbData *pTbData = pMemTable->aBucket[iBucket];
+
+ while (pTbData) {
+ STbData *pNext = pTbData->next;
+
+ int32_t idx = TABS(pTbData->uid) % nBucket;
+ pTbData->next = aBucket[idx];
+ aBucket[idx] = pTbData;
+
+ pTbData = pNext;
+ }
+ }
+
+ taosMemoryFree(pMemTable->aBucket);
+ pMemTable->nBucket = nBucket;
+ pMemTable->aBucket = aBucket;
+
+_exit:
+ return code;
+}
+
static int32_t tsdbGetOrCreateTbData(SMemTable *pMemTable, tb_uid_t suid, tb_uid_t uid, STbData **ppTbData) {
- int32_t code = 0;
- int32_t idx = 0;
- STbData *pTbData = NULL;
- STbData *pTbDataT = &(STbData){.suid = suid, .uid = uid};
+ int32_t code = 0;
// get
- idx = taosArraySearchIdx(pMemTable->aTbData, &pTbDataT, tbDataPCmprFn, TD_GE);
- if (idx >= 0) {
- pTbData = (STbData *)taosArrayGetP(pMemTable->aTbData, idx);
- if (tbDataPCmprFn(&pTbDataT, &pTbData) == 0) goto _exit;
- }
+ STbData *pTbData = tsdbGetTbDataFromMemTableImpl(pMemTable, suid, uid);
+ if (pTbData) goto _exit;
// create
SVBufPool *pPool = pMemTable->pTsdb->pVnode->inUse;
@@ -346,9 +362,6 @@ static int32_t tsdbGetOrCreateTbData(SMemTable *pMemTable, tb_uid_t suid, tb_uid
pTbData->uid = uid;
pTbData->minKey = TSKEY_MAX;
pTbData->maxKey = TSKEY_MIN;
- pTbData->minVersion = VERSION_MAX;
- pTbData->maxVersion = VERSION_MIN;
- pTbData->maxSkmVer = -1;
pTbData->pHead = NULL;
pTbData->pTail = NULL;
pTbData->sl.seed = taosRand();
@@ -367,21 +380,23 @@ static int32_t tsdbGetOrCreateTbData(SMemTable *pMemTable, tb_uid_t suid, tb_uid
SL_NODE_FORWARD(pTbData->sl.pTail, iLevel) = NULL;
}
- void *p;
- if (idx < 0) {
- idx = taosArrayGetSize(pMemTable->aTbData);
+ taosWLockLatch(&pMemTable->latch);
+
+ if (pMemTable->nTbData >= pMemTable->nBucket) {
+ code = tsdbMemTableRehash(pMemTable);
+ if (code) {
+ taosWUnLockLatch(&pMemTable->latch);
+ goto _err;
+ }
}
- taosWLockLatch(&pMemTable->latch);
- p = taosArrayInsert(pMemTable->aTbData, idx, &pTbData);
+ int32_t idx = TABS(uid) % pMemTable->nBucket;
+ pTbData->next = pMemTable->aBucket[idx];
+ pMemTable->aBucket[idx] = pTbData;
+ pMemTable->nTbData++;
+
taosWUnLockLatch(&pMemTable->latch);
- tsdbDebug("vgId:%d, add table data %p at idx:%d", TD_VID(pMemTable->pTsdb->pVnode), pTbData, idx);
-
- if (p == NULL) {
- code = TSDB_CODE_OUT_OF_MEMORY;
- goto _err;
- }
_exit:
*ppTbData = pTbData;
return code;
@@ -591,15 +606,9 @@ static int32_t tsdbInsertTableDataImpl(SMemTable *pMemTable, STbData *pTbData, i
tsdbCacheInsertLast(pMemTable->pTsdb->lruCache, pTbData->uid, pLastRow, pMemTable->pTsdb);
}
- pTbData->minVersion = TMIN(pTbData->minVersion, version);
- pTbData->maxVersion = TMAX(pTbData->maxVersion, version);
- pTbData->maxSkmVer = TMAX(pTbData->maxSkmVer, pMsgIter->sversion);
-
// SMemTable
pMemTable->minKey = TMIN(pMemTable->minKey, pTbData->minKey);
pMemTable->maxKey = TMAX(pMemTable->maxKey, pTbData->maxKey);
- pMemTable->minVersion = TMIN(pMemTable->minVersion, pTbData->minVersion);
- pMemTable->maxVersion = TMAX(pMemTable->maxVersion, pTbData->maxVersion);
pMemTable->nRow += nRow;
pRsp->numOfRows = nRow;
@@ -624,3 +633,41 @@ void tsdbUnrefMemTable(SMemTable *pMemTable) {
tsdbMemTableDestroy(pMemTable);
}
}
+
+static FORCE_INLINE int32_t tbDataPCmprFn(const void *p1, const void *p2) {
+ STbData *pTbData1 = *(STbData **)p1;
+ STbData *pTbData2 = *(STbData **)p2;
+
+ if (pTbData1->suid < pTbData2->suid) {
+ return -1;
+ } else if (pTbData1->suid > pTbData2->suid) {
+ return 1;
+ }
+
+ if (pTbData1->uid < pTbData2->uid) {
+ return -1;
+ } else if (pTbData1->uid > pTbData2->uid) {
+ return 1;
+ }
+
+ return 0;
+}
+
+SArray *tsdbMemTableGetTbDataArray(SMemTable *pMemTable) {
+ SArray *aTbDataP = taosArrayInit(pMemTable->nTbData, sizeof(STbData *));
+ if (aTbDataP == NULL) goto _exit;
+
+ for (int32_t iBucket = 0; iBucket < pMemTable->nBucket; iBucket++) {
+ STbData *pTbData = pMemTable->aBucket[iBucket];
+
+ while (pTbData) {
+ taosArrayPush(aTbDataP, &pTbData);
+ pTbData = pTbData->next;
+ }
+ }
+
+ taosArraySort(aTbDataP, tbDataPCmprFn);
+
+_exit:
+ return aTbDataP;
+}
diff --git a/source/dnode/vnode/src/tsdb/tsdbOpen.c b/source/dnode/vnode/src/tsdb/tsdbOpen.c
index be2828d187..ec760e3c57 100644
--- a/source/dnode/vnode/src/tsdb/tsdbOpen.c
+++ b/source/dnode/vnode/src/tsdb/tsdbOpen.c
@@ -86,7 +86,7 @@ int tsdbClose(STsdb **pTsdb) {
if (*pTsdb) {
taosThreadRwlockDestroy(&(*pTsdb)->rwLock);
tsdbFSClose(*pTsdb);
- tsdbCloseCache((*pTsdb)->lruCache);
+ tsdbCloseCache(*pTsdb);
taosMemoryFreeClear(*pTsdb);
}
return 0;
diff --git a/source/dnode/vnode/src/tsdb/tsdbRead.c b/source/dnode/vnode/src/tsdb/tsdbRead.c
index 0831f3d75a..336053911e 100644
--- a/source/dnode/vnode/src/tsdb/tsdbRead.c
+++ b/source/dnode/vnode/src/tsdb/tsdbRead.c
@@ -15,7 +15,10 @@
#include "osDef.h"
#include "tsdb.h"
+
#define ASCENDING_TRAVERSE(o) (o == TSDB_ORDER_ASC)
+#define ALL_ROWS_CHECKED_INDEX (INT16_MIN)
+#define DEFAULT_ROW_INDEX_VAL (-1)
typedef enum {
EXTERNAL_ROWS_PREV = 0x1,
@@ -29,16 +32,23 @@ typedef struct {
bool hasVal;
} SIterInfo;
+typedef struct {
+ int32_t numOfBlocks;
+ int32_t numOfLastBlocks;
+} SBlockNumber;
+
typedef struct STableBlockScanInfo {
uint64_t uid;
TSKEY lastKey;
- SMapData mapData; // block info (compressed)
- SArray* pBlockList; // block data index list
- SIterInfo iter; // mem buffer skip list iterator
- SIterInfo iiter; // imem buffer skip list iterator
- SArray* delSkyline; // delete info for this table
- int32_t fileDelIndex;
- bool iterInit; // whether to initialize the in-memory skip list iterator or not
+ SMapData mapData; // block info (compressed)
+ SArray* pBlockList; // block data index list
+ SIterInfo iter; // mem buffer skip list iterator
+ SIterInfo iiter; // imem buffer skip list iterator
+ SArray* delSkyline; // delete info for this table
+ int32_t fileDelIndex; // file block delete index
+ int32_t lastBlockDelIndex;// delete index for last block
+ bool iterInit; // whether to initialize the in-memory skip list iterator or not
+ int16_t indexInBlockL;// row position in last block
} STableBlockScanInfo;
typedef struct SBlockOrderWrapper {
@@ -71,11 +81,28 @@ typedef struct SBlockLoadSuppInfo {
char** buildBuf; // build string tmp buffer, todo remove it later after all string format being updated.
} SBlockLoadSuppInfo;
+typedef struct SVersionRange {
+ uint64_t minVer;
+ uint64_t maxVer;
+} SVersionRange;
+
+typedef struct SLastBlockReader {
+ SArray* pBlockL;
+ int32_t currentBlockIndex;
+ SBlockData lastBlockData;
+ STimeWindow window;
+ SVersionRange verRange;
+ int32_t order;
+ uint64_t uid;
+ int16_t* rowIndex; // row index ptr, usually from the STableBlockScanInfo->indexInBlockL
+} SLastBlockReader;
+
typedef struct SFilesetIter {
- int32_t numOfFiles; // number of total files
- int32_t index; // current accessed index in the list
- SArray* pFileList; // data file list
+ int32_t numOfFiles; // number of total files
+ int32_t index; // current accessed index in the list
+ SArray* pFileList; // data file list
int32_t order;
+ SLastBlockReader* pLastBlockReader; // last file block reader
} SFilesetIter;
typedef struct SFileDataBlockInfo {
@@ -87,9 +114,9 @@ typedef struct SFileDataBlockInfo {
typedef struct SDataBlockIter {
int32_t numOfBlocks;
int32_t index;
- SArray* blockList; // SArray
+ SArray* blockList; // SArray
int32_t order;
- SBlock block; // current SBlock data
+ SBlock block; // current SBlock data
SHashObj* pTableMap;
} SDataBlockIter;
@@ -100,11 +127,6 @@ typedef struct SFileBlockDumpInfo {
bool allDumped;
} SFileBlockDumpInfo;
-typedef struct SVersionRange {
- uint64_t minVer;
- uint64_t maxVer;
-} SVersionRange;
-
typedef struct SReaderStatus {
bool loadFromFile; // check file stage
SHashObj* pTableMap; // SHash
@@ -145,10 +167,11 @@ static int buildDataBlockFromBufImpl(STableBlockScanInfo* pBlockScanInfo, i
static TSDBROW* getValidRow(SIterInfo* pIter, const SArray* pDelList, STsdbReader* pReader);
static int32_t doMergeRowsInFileBlocks(SBlockData* pBlockData, STableBlockScanInfo* pScanInfo, STsdbReader* pReader,
SRowMerger* pMerger);
+static int32_t doMergeRowsInLastBlock(SLastBlockReader* pLastBlockReader, STableBlockScanInfo* pScanInfo, int64_t ts, SRowMerger* pMerger);
static int32_t doMergeRowsInBuf(SIterInfo* pIter, uint64_t uid, int64_t ts, SArray* pDelList, SRowMerger* pMerger,
STsdbReader* pReader);
static int32_t doAppendRowFromTSRow(SSDataBlock* pBlock, STsdbReader* pReader, STSRow* pTSRow, uint64_t uid);
-static int32_t doAppendRowFromBlock(SSDataBlock* pResBlock, STsdbReader* pReader, SBlockData* pBlockData,
+static int32_t doAppendRowFromFileBlock(SSDataBlock* pResBlock, STsdbReader* pReader, SBlockData* pBlockData,
int32_t rowIndex);
static void setComposedBlockFlag(STsdbReader* pReader, bool composed);
static bool hasBeenDropped(const SArray* pDelList, int32_t* index, TSDBKEY* pKey, int32_t order);
@@ -162,6 +185,9 @@ static int32_t initDelSkylineIterator(STableBlockScanInfo* pBlockScanInfo, STsdb
static STsdb* getTsdbByRetentions(SVnode* pVnode, TSKEY winSKey, SRetention* retentions, const char* idstr,
int8_t* pLevel);
static SVersionRange getQueryVerRange(SVnode* pVnode, SQueryTableDataCond* pCond, int8_t level);
+static int64_t getCurrentKeyInLastBlock(SLastBlockReader* pLastBlockReader);
+static bool hasDataInLastBlock(SLastBlockReader* pLastBlockReader);
+static int32_t doBuildDataBlock(STsdbReader* pReader);
static int32_t setColumnIdSlotList(STsdbReader* pReader, SSDataBlock* pBlock) {
SBlockLoadSuppInfo* pSupInfo = &pReader->suppInfo;
@@ -182,7 +208,6 @@ static int32_t setColumnIdSlotList(STsdbReader* pReader, SSDataBlock* pBlock) {
if (IS_VAR_DATA_TYPE(pCol->info.type)) {
pSupInfo->buildBuf[i] = taosMemoryMalloc(pCol->info.bytes);
- // tsdbInfo("-------------------%d\n", pCol->info.bytes);
}
}
@@ -199,7 +224,7 @@ static SHashObj* createDataBlockScanInfo(STsdbReader* pTsdbReader, const STableK
}
for (int32_t j = 0; j < numOfTables; ++j) {
- STableBlockScanInfo info = {.lastKey = 0, .uid = idList[j].uid};
+ STableBlockScanInfo info = {.lastKey = 0, .uid = idList[j].uid, .indexInBlockL = DEFAULT_ROW_INDEX_VAL};
if (ASCENDING_TRAVERSE(pTsdbReader->order)) {
if (info.lastKey == INT64_MIN || info.lastKey < pTsdbReader->window.skey) {
info.lastKey = pTsdbReader->window.skey;
@@ -293,15 +318,36 @@ static void limitOutputBufferSize(const SQueryTableDataCond* pCond, int32_t* cap
}
// init file iterator
-static int32_t initFilesetIterator(SFilesetIter* pIter, SArray* aDFileSet, int32_t order, const char* idstr) {
+static int32_t initFilesetIterator(SFilesetIter* pIter, SArray* aDFileSet, STsdbReader* pReader/*int32_t order, const char* idstr*/) {
size_t numOfFileset = taosArrayGetSize(aDFileSet);
- pIter->index = ASCENDING_TRAVERSE(order) ? -1 : numOfFileset;
- pIter->order = order;
+ pIter->index = ASCENDING_TRAVERSE(pReader->order) ? -1 : numOfFileset;
+ pIter->order = pReader->order;
pIter->pFileList = aDFileSet;
pIter->numOfFiles = numOfFileset;
- tsdbDebug("init fileset iterator, total files:%d %s", pIter->numOfFiles, idstr);
+ if (pIter->pLastBlockReader == NULL) {
+ pIter->pLastBlockReader = taosMemoryCalloc(1, sizeof(struct SLastBlockReader));
+ if (pIter->pLastBlockReader == NULL) {
+ int32_t code = TSDB_CODE_OUT_OF_MEMORY;
+ tsdbError("failed to prepare the last block iterator, code:%d %s", tstrerror(code), pReader->idStr);
+ return code;
+ }
+
+ SLastBlockReader* pLReader = pIter->pLastBlockReader;
+ pLReader->pBlockL = taosArrayInit(4, sizeof(SBlockL));
+ pLReader->order = pReader->order;
+ pLReader->window = pReader->window;
+ pLReader->verRange = pReader->verRange;
+ pLReader->currentBlockIndex = -1;
+
+ int32_t code = tBlockDataCreate(&pLReader->lastBlockData);
+ if (code != TSDB_CODE_SUCCESS) {
+ return code;
+ }
+ }
+
+ tsdbDebug("init fileset iterator, total files:%d %s", pIter->numOfFiles, pReader->idStr);
return TSDB_CODE_SUCCESS;
}
@@ -361,7 +407,7 @@ _err:
static void resetDataBlockIterator(SDataBlockIter* pIter, int32_t order, SHashObj* pTableMap) {
pIter->order = order;
pIter->index = -1;
- pIter->numOfBlocks = -1;
+ pIter->numOfBlocks = 0;
if (pIter->blockList == NULL) {
pIter->blockList = taosArrayInit(4, sizeof(SFileDataBlockInfo));
} else {
@@ -419,7 +465,7 @@ static int32_t tsdbReaderCreate(SVnode* pVnode, SQueryTableDataCond* pCond, STsd
pReader->pTsdb = getTsdbByRetentions(pVnode, pCond->twindows.skey, pVnode->config.tsdbCfg.retentions, idstr, &level);
pReader->suid = pCond->suid;
pReader->order = pCond->order;
- pReader->capacity = capacity;
+ pReader->capacity = 4096;
pReader->idStr = (idstr != NULL) ? strdup(idstr) : NULL;
pReader->verRange = getQueryVerRange(pVnode, pCond, level);
pReader->type = pCond->type;
@@ -440,7 +486,7 @@ static int32_t tsdbReaderCreate(SVnode* pVnode, SQueryTableDataCond* pCond, STsd
pSup->tsColAgg.colId = PRIMARYKEY_TIMESTAMP_COL_ID;
- code = tBlockDataInit(&pReader->status.fileBlockData);
+ code = tBlockDataCreate(&pReader->status.fileBlockData);
if (code != TSDB_CODE_SUCCESS) {
terrno = code;
goto _end;
@@ -547,14 +593,14 @@ static int32_t doLoadBlockIndex(STsdbReader* pReader, SDataFReader* pFileReader,
SArray* aBlockIdx = taosArrayInit(8, sizeof(SBlockIdx));
int64_t st = taosGetTimestampUs();
- int32_t code = tsdbReadBlockIdx(pFileReader, aBlockIdx, NULL);
+ int32_t code = tsdbReadBlockIdx(pFileReader, aBlockIdx);
if (code != TSDB_CODE_SUCCESS) {
goto _end;
}
size_t num = taosArrayGetSize(aBlockIdx);
if (num == 0) {
- taosArrayClear(aBlockIdx);
+ taosArrayDestroy(aBlockIdx);
return TSDB_CODE_SUCCESS;
}
@@ -594,24 +640,29 @@ _end:
return code;
}
-static int32_t doLoadFileBlock(STsdbReader* pReader, SArray* pIndexList, uint32_t* numOfValidTables,
- int32_t* numOfBlocks) {
- size_t numOfTables = taosArrayGetSize(pIndexList);
- *numOfValidTables = 0;
-
- int64_t st = taosGetTimestampUs();
- size_t size = 0;
-
+static void cleanupTableScanInfo(SHashObj* pTableMap) {
STableBlockScanInfo* px = NULL;
while (1) {
- px = taosHashIterate(pReader->status.pTableMap, px);
+ px = taosHashIterate(pTableMap, px);
if (px == NULL) {
break;
}
+ // reset the index in last block when handing a new file
+ px->indexInBlockL = -1;
tMapDataClear(&px->mapData);
taosArrayClear(px->pBlockList);
}
+}
+
+static int32_t doLoadFileBlock(STsdbReader* pReader, SArray* pIndexList, SArray* pLastBlockIndex,
+ SBlockNumber * pBlockNum, SArray* pQualifiedLastBlock) {
+ int32_t numOfQTable = 0;
+ size_t sizeInDisk = 0;
+ size_t numOfTables = taosArrayGetSize(pIndexList);
+
+ int64_t st = taosGetTimestampUs();
+ cleanupTableScanInfo(pReader->status.pTableMap);
for (int32_t i = 0; i < numOfTables; ++i) {
SBlockIdx* pBlockIdx = taosArrayGet(pIndexList, i);
@@ -619,9 +670,9 @@ static int32_t doLoadFileBlock(STsdbReader* pReader, SArray* pIndexList, uint32_
STableBlockScanInfo* pScanInfo = taosHashGet(pReader->status.pTableMap, &pBlockIdx->uid, sizeof(int64_t));
tMapDataReset(&pScanInfo->mapData);
- tsdbReadBlock(pReader->pFileReader, pBlockIdx, &pScanInfo->mapData, NULL);
+ tsdbReadBlock(pReader->pFileReader, pBlockIdx, &pScanInfo->mapData);
- size += pScanInfo->mapData.nData;
+ sizeInDisk += pScanInfo->mapData.nData;
for (int32_t j = 0; j < pScanInfo->mapData.nItem; ++j) {
SBlock block = {0};
tMapDataGetItemByIdx(&pScanInfo->mapData, j, &block, tGetBlock);
@@ -632,7 +683,7 @@ static int32_t doLoadFileBlock(STsdbReader* pReader, SArray* pIndexList, uint32_
}
// 2. version range check
- if (block.minVersion > pReader->verRange.maxVer || block.maxVersion < pReader->verRange.minVer) {
+ if (block.minVer > pReader->verRange.maxVer || block.maxVer < pReader->verRange.minVer) {
continue;
}
@@ -642,30 +693,54 @@ static int32_t doLoadFileBlock(STsdbReader* pReader, SArray* pIndexList, uint32_
return TSDB_CODE_OUT_OF_MEMORY;
}
- (*numOfBlocks) += 1;
+ pBlockNum->numOfBlocks += 1;
}
if (pScanInfo->pBlockList != NULL && taosArrayGetSize(pScanInfo->pBlockList) > 0) {
- (*numOfValidTables) += 1;
+ numOfQTable += 1;
}
}
- double el = (taosGetTimestampUs() - st) / 1000.0;
- tsdbDebug("load block of %d tables completed, blocks:%d in %d tables, size:%.2f Kb, elapsed time:%.2f ms %s",
- numOfTables, *numOfBlocks, *numOfValidTables, size / 1000.0, el, pReader->idStr);
+ size_t numOfLast = taosArrayGetSize(pLastBlockIndex);
+ for(int32_t i = 0; i < numOfLast; ++i) {
+ SBlockL* pLastBlock = taosArrayGet(pLastBlockIndex, i);
+ if (pLastBlock->suid != pReader->suid) {
+ continue;
+ }
- pReader->cost.numOfBlocks += (*numOfBlocks);
+ {
+ // 1. time range check
+ if (pLastBlock->minKey > pReader->window.ekey || pLastBlock->maxKey < pReader->window.skey) {
+ continue;
+ }
+
+ // 2. version range check
+ if (pLastBlock->minVer > pReader->verRange.maxVer || pLastBlock->maxVer < pReader->verRange.minVer) {
+ continue;
+ }
+
+ pBlockNum->numOfLastBlocks += 1;
+ taosArrayPush(pQualifiedLastBlock, pLastBlock);
+ }
+ }
+
+ int32_t total = pBlockNum->numOfLastBlocks + pBlockNum->numOfBlocks;
+
+ double el = (taosGetTimestampUs() - st) / 1000.0;
+ tsdbDebug("load block of %d tables completed, blocks:%d in %d tables, lastBlock:%d, size:%.2f Kb, elapsed time:%.2f ms %s",
+ numOfTables, total, numOfQTable, pBlockNum->numOfLastBlocks, sizeInDisk
+ / 1000.0, el, pReader->idStr);
+
+ pReader->cost.numOfBlocks += total;
pReader->cost.headFileLoadTime += el;
return TSDB_CODE_SUCCESS;
}
-// todo remove pblock parameter
-static void setBlockAllDumped(SFileBlockDumpInfo* pDumpInfo, SBlock* pBlock, int32_t order) {
+static void setBlockAllDumped(SFileBlockDumpInfo* pDumpInfo, int64_t maxKey, int32_t order) {
int32_t step = ASCENDING_TRAVERSE(order) ? 1 : -1;
-
pDumpInfo->allDumped = true;
- pDumpInfo->lastKey = pBlock->maxKey.ts + step;
+ pDumpInfo->lastKey = maxKey + step;
}
static void doCopyColVal(SColumnInfoData* pColInfoData, int32_t rowIndex, int32_t colIndex, SColVal* pColVal,
@@ -685,8 +760,13 @@ static void doCopyColVal(SColumnInfoData* pColInfoData, int32_t rowIndex, int32_
}
static SFileDataBlockInfo* getCurrentBlockInfo(SDataBlockIter* pBlockIter) {
- SFileDataBlockInfo* pFBlockInfo = taosArrayGet(pBlockIter->blockList, pBlockIter->index);
- return pFBlockInfo;
+ if (taosArrayGetSize(pBlockIter->blockList) == 0) {
+ ASSERT(pBlockIter->numOfBlocks == taosArrayGetSize(pBlockIter->blockList));
+ return NULL;
+ }
+
+ SFileDataBlockInfo* pBlockInfo = taosArrayGet(pBlockIter->blockList, pBlockIter->index);
+ return pBlockInfo;
}
static SBlock* getCurrentBlock(SDataBlockIter* pBlockIter) { return &pBlockIter->block; }
@@ -736,19 +816,20 @@ static int32_t copyBlockDataToSDataBlock(STsdbReader* pReader, STableBlockScanIn
pColData = taosArrayGet(pResBlock->pDataBlock, i);
SColData* pData = tBlockDataGetColDataByIdx(pBlockData, colIndex);
-
- if (pData->cid == pColData->info.colId) {
+ if (pData->cid < pColData->info.colId) {
+ colIndex += 1;
+ } else if (pData->cid == pColData->info.colId) {
for (int32_t j = pDumpInfo->rowIndex; j < endIndex && j >= 0; j += step) {
tColDataGetValue(pData, j, &cv);
doCopyColVal(pColData, rowIndex++, i, &cv, pSupInfo);
}
colIndex += 1;
+ i += 1;
ASSERT(rowIndex == remain);
} else { // the specified column does not exist in file block, fill with null data
colDataAppendNNULL(pColData, 0, remain);
+ i += 1;
}
-
- i += 1;
}
while (i < numOfOutputCols) {
@@ -760,7 +841,7 @@ static int32_t copyBlockDataToSDataBlock(STsdbReader* pReader, STableBlockScanIn
pResBlock->info.rows = remain;
pDumpInfo->rowIndex += step * remain;
- setBlockAllDumped(pDumpInfo, pBlock, pReader->order);
+ setBlockAllDumped(pDumpInfo, pBlock->maxKey.ts, pReader->order);
double elapsedTime = (taosGetTimestampUs() - st) / 1000.0;
pReader->cost.blockLoadTime += elapsedTime;
@@ -769,47 +850,77 @@ static int32_t copyBlockDataToSDataBlock(STsdbReader* pReader, STableBlockScanIn
tsdbDebug("%p copy file block to sdatablock, global index:%d, table index:%d, brange:%" PRId64 "-%" PRId64
", rows:%d, remain:%d, minVer:%" PRId64 ", maxVer:%" PRId64 ", elapsed time:%.2f ms, %s",
pReader, pBlockIter->index, pFBlock->tbBlockIdx, pBlock->minKey.ts, pBlock->maxKey.ts, remain, unDumpedRows,
- pBlock->minVersion, pBlock->maxVersion, elapsedTime, pReader->idStr);
+ pBlock->minVer, pBlock->maxVer, elapsedTime, pReader->idStr);
return TSDB_CODE_SUCCESS;
}
-static int32_t doLoadFileBlockData(STsdbReader* pReader, SDataBlockIter* pBlockIter,
- STableBlockScanInfo* pBlockScanInfo, SBlockData* pBlockData) {
+static int32_t doLoadFileBlockData(STsdbReader* pReader, SDataBlockIter* pBlockIter, SBlockData* pBlockData) {
int64_t st = taosGetTimestampUs();
+ double elapsedTime = 0;
+ int32_t code = 0;
- SFileDataBlockInfo* pFBlock = getCurrentBlockInfo(pBlockIter);
- SBlock* pBlock = getCurrentBlock(pBlockIter);
-
- SSDataBlock* pResBlock = pReader->pResBlock;
- int32_t numOfCols = blockDataGetNumOfCols(pResBlock);
-
- SBlockLoadSuppInfo* pSupInfo = &pReader->suppInfo;
+ SFileDataBlockInfo* pBlockInfo = getCurrentBlockInfo(pBlockIter);
SFileBlockDumpInfo* pDumpInfo = &pReader->status.fBlockDumpInfo;
- SBlockIdx blockIdx = {.suid = pReader->suid, .uid = pBlockScanInfo->uid};
- int32_t code =
- tsdbReadColData(pReader->pFileReader, &blockIdx, pBlock, pSupInfo->colIds, numOfCols, pBlockData, NULL, NULL);
- if (code != TSDB_CODE_SUCCESS) {
- goto _error;
+ if (pBlockInfo != NULL) {
+ SBlock* pBlock = getCurrentBlock(pBlockIter);
+ code = tsdbReadDataBlock(pReader->pFileReader, pBlock, pBlockData);
+ if (code != TSDB_CODE_SUCCESS) {
+ tsdbError("%p error occurs in loading file block, global index:%d, table index:%d, brange:%" PRId64 "-%" PRId64
+ ", rows:%d, code:%s %s",
+ pReader, pBlockIter->index, pBlockInfo->tbBlockIdx, pBlock->minKey.ts, pBlock->maxKey.ts, pBlock->nRow,
+ tstrerror(code), pReader->idStr);
+ goto _error;
+ }
+
+ elapsedTime = (taosGetTimestampUs() - st) / 1000.0;
+
+ tsdbDebug("%p load file block into buffer, global index:%d, table index:%d, brange:%" PRId64 "-%" PRId64
+ ", rows:%d, minVer:%" PRId64 ", maxVer:%" PRId64 ", elapsed time:%.2f ms, %s",
+ pReader, pBlockIter->index, pBlockInfo->tbBlockIdx, pBlock->minKey.ts, pBlock->maxKey.ts, pBlock->nRow,
+ pBlock->minVer, pBlock->maxVer, elapsedTime, pReader->idStr);
+ } else {
+#if 0
+ SLastBlockReader* pLastBlockReader = pReader->status.fileIter.pLastBlockReader;
+
+ uint64_t uid = pBlockInfo->uid;
+ SArray* pBlocks = pLastBlockReader->pBlockL;
+
+ pLastBlockReader->currentBlockIndex = -1;
+
+ // find the correct SBlockL
+ for(int32_t i = 0; i < taosArrayGetSize(pBlocks); ++i) {
+ SBlockL* pBlock = taosArrayGet(pBlocks, i);
+ if (pBlock->minUid >= uid && pBlock->maxUid <= uid) {
+ pLastBlockReader->currentBlockIndex = i;
+ break;
+ }
+ }
+
+// SBlockL* pBlockL = taosArrayGet(pLastBlockReader->pBlockL, *index);
+ code = tsdbReadLastBlock(pReader->pFileReader, pBlockL, pBlockData);
+ if (code != TSDB_CODE_SUCCESS) {
+ tsdbDebug("%p error occurs in loading last block into buffer, last block index:%d, total:%d brange:%" PRId64 "-%" PRId64
+ ", rows:%d, minVer:%" PRId64 ", maxVer:%" PRId64 ", code:%s %s",
+ pReader, *index, pBlockIter->numOfBlocks.numOfLastBlocks, 0, 0, pBlockL->nRow,
+ pBlockL->minVer, pBlockL->maxVer, tstrerror(code), pReader->idStr);
+ goto _error;
+ }
+
+ tsdbDebug("%p load last file block into buffer, last block index:%d, total:%d brange:%" PRId64 "-%" PRId64
+ ", rows:%d, minVer:%" PRId64 ", maxVer:%" PRId64 ", elapsed time:%.2f ms, %s",
+ pReader, *index, pBlockIter->numOfBlocks.numOfLastBlocks, 0, 0, pBlockL->nRow,
+ pBlockL->minVer, pBlockL->maxVer, elapsedTime, pReader->idStr);
+#endif
}
- double elapsedTime = (taosGetTimestampUs() - st) / 1000.0;
pReader->cost.blockLoadTime += elapsedTime;
-
pDumpInfo->allDumped = false;
- tsdbDebug("%p load file block into buffer, global index:%d, table index:%d, brange:%" PRId64 "-%" PRId64
- ", rows:%d, minVer:%" PRId64 ", maxVer:%" PRId64 ", elapsed time:%.2f ms, %s",
- pReader, pBlockIter->index, pFBlock->tbBlockIdx, pBlock->minKey.ts, pBlock->maxKey.ts, pBlock->nRow,
- pBlock->minVersion, pBlock->maxVersion, elapsedTime, pReader->idStr);
return TSDB_CODE_SUCCESS;
_error:
- tsdbError("%p error occurs in loading file block, global index:%d, table index:%d, brange:%" PRId64 "-%" PRId64
- ", rows:%d, %s",
- pReader, pBlockIter->index, pFBlock->tbBlockIdx, pBlock->minKey.ts, pBlock->maxKey.ts, pBlock->nRow,
- pReader->idStr);
return code;
}
@@ -865,10 +976,11 @@ static int32_t fileDataBlockOrderCompar(const void* pLeft, const void* pRight, v
static int32_t doSetCurrentBlock(SDataBlockIter* pBlockIter) {
SFileDataBlockInfo* pFBlock = getCurrentBlockInfo(pBlockIter);
- STableBlockScanInfo* pScanInfo = taosHashGet(pBlockIter->pTableMap, &pFBlock->uid, sizeof(pFBlock->uid));
-
- int32_t* mapDataIndex = taosArrayGet(pScanInfo->pBlockList, pFBlock->tbBlockIdx);
- tMapDataGetItemByIdx(&pScanInfo->mapData, *mapDataIndex, &pBlockIter->block, tGetBlock);
+ if (pFBlock != NULL) {
+ STableBlockScanInfo* pScanInfo = taosHashGet(pBlockIter->pTableMap, &pFBlock->uid, sizeof(pFBlock->uid));
+ int32_t* mapDataIndex = taosArrayGet(pScanInfo->pBlockList, pFBlock->tbBlockIdx);
+ tMapDataGetItemByIdx(&pScanInfo->mapData, *mapDataIndex, &pBlockIter->block, tGetBlock);
+ }
#if 0
qDebug("check file block, table uid:%"PRIu64" index:%d offset:%"PRId64", ", pScanInfo->uid, *mapDataIndex, pBlockIter->block.aSubBlock[0].offset);
@@ -945,7 +1057,7 @@ static int32_t initBlockIterator(STsdbReader* pReader, SDataBlockIter* pBlockIte
int64_t et = taosGetTimestampUs();
tsdbDebug("%p create blocks info struct completed for one table, %d blocks not sorted, elapsed time:%.2f ms %s",
- pReader, cnt, (et - st) / 1000.0, pReader->idStr);
+ pReader, numOfBlocks, (et - st) / 1000.0, pReader->idStr);
pBlockIter->index = asc ? 0 : (numOfBlocks - 1);
cleanupBlockOrderSupporter(&sup);
@@ -956,7 +1068,7 @@ static int32_t initBlockIterator(STsdbReader* pReader, SDataBlockIter* pBlockIte
tsdbDebug("%p create data blocks info struct completed, %d blocks in %d tables %s", pReader, cnt, sup.numOfTables,
pReader->idStr);
- assert(cnt <= numOfBlocks && sup.numOfTables <= numOfTables);
+ ASSERT(cnt <= numOfBlocks && sup.numOfTables <= numOfTables);
SMultiwayMergeTreeInfo* pTree = NULL;
uint8_t ret = tMergeTreeCreate(&pTree, sup.numOfTables, &sup, fileDataBlockOrderCompar);
@@ -983,7 +1095,7 @@ static int32_t initBlockIterator(STsdbReader* pReader, SDataBlockIter* pBlockIte
}
int64_t et = taosGetTimestampUs();
- tsdbDebug("%p %d data blocks access order completed, elapsed time:%.2f ms %s", pReader, cnt, (et - st) / 1000.0,
+ tsdbDebug("%p %d data blocks access order completed, elapsed time:%.2f ms %s", pReader, numOfBlocks, (et - st) / 1000.0,
pReader->idStr);
cleanupBlockOrderSupporter(&sup);
taosMemoryFree(pTree);
@@ -1014,8 +1126,8 @@ static bool blockIteratorNext(SDataBlockIter* pBlockIter) {
static int32_t dataBlockPartiallyRequired(STimeWindow* pWindow, SVersionRange* pVerRange, SBlock* pBlock) {
return (pWindow->ekey < pBlock->maxKey.ts && pWindow->ekey >= pBlock->minKey.ts) ||
(pWindow->skey > pBlock->minKey.ts && pWindow->skey <= pBlock->maxKey.ts) ||
- (pVerRange->minVer > pBlock->minVersion && pVerRange->minVer <= pBlock->maxVersion) ||
- (pVerRange->maxVer < pBlock->maxVersion && pVerRange->maxVer >= pBlock->minVersion);
+ (pVerRange->minVer > pBlock->minVer && pVerRange->minVer <= pBlock->maxVer) ||
+ (pVerRange->maxVer < pBlock->maxVer && pVerRange->maxVer >= pBlock->minVer);
}
static SBlock* getNeighborBlockOfSameTable(SFileDataBlockInfo* pFBlockInfo, STableBlockScanInfo* pTableBlockScanInfo,
@@ -1095,8 +1207,8 @@ static bool bufferDataInFileBlockGap(int32_t order, TSDBKEY key, SBlock* pBlock)
}
static bool keyOverlapFileBlock(TSDBKEY key, SBlock* pBlock, SVersionRange* pVerRange) {
- return (key.ts >= pBlock->minKey.ts && key.ts <= pBlock->maxKey.ts) && (pBlock->maxVersion >= pVerRange->minVer) &&
- (pBlock->minVersion <= pVerRange->maxVer);
+ return (key.ts >= pBlock->minKey.ts && key.ts <= pBlock->maxKey.ts) && (pBlock->maxVer >= pVerRange->minVer) &&
+ (pBlock->minVer <= pVerRange->maxVer);
}
static bool doCheckforDatablockOverlap(STableBlockScanInfo* pBlockScanInfo, const SBlock* pBlock) {
@@ -1105,11 +1217,11 @@ static bool doCheckforDatablockOverlap(STableBlockScanInfo* pBlockScanInfo, cons
for (int32_t i = pBlockScanInfo->fileDelIndex; i < num; i += 1) {
TSDBKEY* p = taosArrayGet(pBlockScanInfo->delSkyline, i);
if (p->ts >= pBlock->minKey.ts && p->ts <= pBlock->maxKey.ts) {
- if (p->version >= pBlock->minVersion) {
+ if (p->version >= pBlock->minVer) {
return true;
}
} else if (p->ts < pBlock->minKey.ts) { // p->ts < pBlock->minKey.ts
- if (p->version >= pBlock->minVersion) {
+ if (p->version >= pBlock->minVer) {
if (i < num - 1) {
TSDBKEY* pnext = taosArrayGet(pBlockScanInfo->delSkyline, i + 1);
if (i + 1 == num - 1) { // pnext is the last point
@@ -1117,7 +1229,7 @@ static bool doCheckforDatablockOverlap(STableBlockScanInfo* pBlockScanInfo, cons
return true;
}
} else {
- if (pnext->ts >= pBlock->minKey.ts && pnext->version >= pBlock->minVersion) {
+ if (pnext->ts >= pBlock->minKey.ts && pnext->version >= pBlock->minVer) {
return true;
}
}
@@ -1169,7 +1281,7 @@ static bool overlapWithDelSkyline(STableBlockScanInfo* pBlockScanInfo, const SBl
// 4. output buffer should be large enough to hold all rows in current block
// 5. delete info should not overlap with current block data
static bool fileBlockShouldLoad(STsdbReader* pReader, SFileDataBlockInfo* pFBlock, SBlock* pBlock,
- STableBlockScanInfo* pScanInfo, TSDBKEY key) {
+ STableBlockScanInfo* pScanInfo, TSDBKEY key, SLastBlockReader* pLastBlockReader) {
int32_t neighborIndex = 0;
SBlock* pNeighbor = getNeighborBlockOfSameTable(pFBlock, pScanInfo, &neighborIndex, pReader->order);
@@ -1184,8 +1296,16 @@ static bool fileBlockShouldLoad(STsdbReader* pReader, SFileDataBlockInfo* pFBloc
bool hasDup = (pBlock->nSubBlock == 1) ? pBlock->hasDup : true;
bool overlapWithDel = overlapWithDelSkyline(pScanInfo, pBlock, pReader->order);
+ // todo here we need to each key in the last files to identify if it is really overlapped with last block
+ bool overlapWithlastBlock = false;
+ if (taosArrayGetSize(pLastBlockReader->pBlockL) > 0 && (pLastBlockReader->currentBlockIndex != -1)) {
+ SBlockL *pBlockL = taosArrayGet(pLastBlockReader->pBlockL, pLastBlockReader->currentBlockIndex);
+ overlapWithlastBlock = !(pBlock->maxKey.ts < pBlockL->minKey || pBlock->minKey.ts > pBlockL->maxKey);
+ }
+
return (overlapWithNeighbor || hasDup || dataBlockPartiallyRequired(&pReader->window, &pReader->verRange, pBlock) ||
- keyOverlapFileBlock(key, pBlock, &pReader->verRange) || (pBlock->nRow > pReader->capacity) || overlapWithDel);
+ keyOverlapFileBlock(key, pBlock, &pReader->verRange) || (pBlock->nRow > pReader->capacity) ||
+ overlapWithDel || overlapWithlastBlock);
}
static int32_t buildDataBlockFromBuf(STsdbReader* pReader, STableBlockScanInfo* pBlockScanInfo, int64_t endKey) {
@@ -1224,7 +1344,7 @@ static bool tryCopyDistinctRowFromFileBlock(STsdbReader* pReader, SBlockData* pB
int64_t nextKey = pBlockData->aTSKEY[pDumpInfo->rowIndex + step];
if (nextKey != key) { // merge is not needed
- doAppendRowFromBlock(pReader->pResBlock, pReader, pBlockData, pDumpInfo->rowIndex);
+ doAppendRowFromFileBlock(pReader->pResBlock, pReader, pBlockData, pDumpInfo->rowIndex);
pDumpInfo->rowIndex += step;
return true;
}
@@ -1258,8 +1378,124 @@ static FORCE_INLINE STSchema* doGetSchemaForTSRow(int32_t sversion, STsdbReader*
return pReader->pMemSchema;
}
+static int32_t doMergeBufAndFileRows_Rv(STsdbReader* pReader, STableBlockScanInfo* pBlockScanInfo, TSDBROW* pRow,
+ SIterInfo* pIter, int64_t key, SLastBlockReader* pLastBlockReader) {
+ SRowMerger merge = {0};
+ STSRow* pTSRow = NULL;
+ SBlockData* pBlockData = &pReader->status.fileBlockData;
+ SFileBlockDumpInfo* pDumpInfo = &pReader->status.fBlockDumpInfo;
+
+ int64_t tsLast = INT64_MIN;
+ if (pLastBlockReader->lastBlockData.nRow > 0) {
+ tsLast = getCurrentKeyInLastBlock(pLastBlockReader);
+ }
+
+ TSDBKEY k = TSDBROW_KEY(pRow);
+ TSDBROW fRow = tsdbRowFromBlockData(pBlockData, pDumpInfo->rowIndex);
+
+ SBlockData* pLastBlockData = &pLastBlockReader->lastBlockData;
+
+ int64_t minKey = 0;
+ if (pReader->order == TSDB_ORDER_ASC) {
+ minKey = INT64_MAX; // chosen the minimum value
+ if (minKey > tsLast && pLastBlockReader->lastBlockData.nRow > 0) {
+ minKey = tsLast;
+ }
+
+ if (minKey > k.ts) {
+ minKey = k.ts;
+ }
+
+ if (minKey > key && pBlockData->nRow > 0) {
+ minKey = key;
+ }
+ } else {
+ minKey = INT64_MIN;
+ if (minKey < tsLast && pLastBlockReader->lastBlockData.nRow > 0) {
+ minKey = tsLast;
+ }
+
+ if (minKey < k.ts) {
+ minKey = k.ts;
+ }
+
+ if (minKey < key && pBlockData->nRow > 0) {
+ minKey = key;
+ }
+ }
+
+ bool init = false;
+
+ // ASC: file block ---> last block -----> imem -----> mem
+ //DESC: mem -----> imem -----> last block -----> file block
+ if (pReader->order == TSDB_ORDER_ASC) {
+ if (minKey == key) {
+ init = true;
+ tRowMergerInit(&merge, &fRow, pReader->pSchema);
+ doMergeRowsInFileBlocks(pBlockData, pBlockScanInfo, pReader, &merge);
+ }
+
+ if (minKey == tsLast) {
+ TSDBROW fRow1 = tsdbRowFromBlockData(pLastBlockData, *pLastBlockReader->rowIndex);
+ if (init) {
+ tRowMerge(&merge, &fRow1);
+ } else {
+ init = true;
+ tRowMergerInit(&merge, &fRow1, pReader->pSchema);
+ }
+ doMergeRowsInLastBlock(pLastBlockReader, pBlockScanInfo, tsLast, &merge);
+ }
+
+ if (minKey == k.ts) {
+ if (init) {
+ tRowMerge(&merge, pRow);
+ } else {
+ init = true;
+ STSchema* pSchema = doGetSchemaForTSRow(TSDBROW_SVERSION(pRow), pReader, pBlockScanInfo->uid);
+ tRowMergerInit(&merge, pRow, pSchema);
+ }
+ doMergeRowsInBuf(pIter, pBlockScanInfo->uid, k.ts, pBlockScanInfo->delSkyline, &merge, pReader);
+ }
+ } else {
+ if (minKey == k.ts) {
+ init = true;
+ STSchema* pSchema = doGetSchemaForTSRow(TSDBROW_SVERSION(pRow), pReader, pBlockScanInfo->uid);
+ tRowMergerInit(&merge, pRow, pSchema);
+ doMergeRowsInBuf(pIter, pBlockScanInfo->uid, k.ts, pBlockScanInfo->delSkyline, &merge, pReader);
+ }
+
+ if (minKey == tsLast) {
+ TSDBROW fRow1 = tsdbRowFromBlockData(pLastBlockData, *pLastBlockReader->rowIndex);
+ if (init) {
+ tRowMerge(&merge, &fRow1);
+ } else {
+ init = true;
+ tRowMergerInit(&merge, &fRow1, pReader->pSchema);
+ }
+ doMergeRowsInLastBlock(pLastBlockReader, pBlockScanInfo, tsLast, &merge);
+ }
+
+ if (minKey == key) {
+ if (init) {
+ tRowMerge(&merge, &fRow);
+ } else {
+ init = true;
+ tRowMergerInit(&merge, &fRow, pReader->pSchema);
+ }
+ doMergeRowsInFileBlocks(pBlockData, pBlockScanInfo, pReader, &merge);
+ }
+ }
+
+ tRowMergerGetRow(&merge, &pTSRow);
+ doAppendRowFromTSRow(pReader->pResBlock, pReader, pTSRow, pBlockScanInfo->uid);
+
+ taosMemoryFree(pTSRow);
+ tRowMergerClear(&merge);
+ return TSDB_CODE_SUCCESS;
+}
+
static int32_t doMergeBufAndFileRows(STsdbReader* pReader, STableBlockScanInfo* pBlockScanInfo, TSDBROW* pRow,
- SIterInfo* pIter, int64_t key) {
+ SIterInfo* pIter, int64_t key, SLastBlockReader* pLastBlockReader) {
SRowMerger merge = {0};
STSRow* pTSRow = NULL;
SBlockData* pBlockData = &pReader->status.fileBlockData;
@@ -1331,12 +1567,159 @@ static int32_t doMergeBufAndFileRows(STsdbReader* pReader, STableBlockScanInfo*
return TSDB_CODE_SUCCESS;
}
-static int32_t doMergeThreeLevelRows(STsdbReader* pReader, STableBlockScanInfo* pBlockScanInfo) {
+static int32_t doMergeMultiLevelRowsRv(STsdbReader* pReader, STableBlockScanInfo* pBlockScanInfo, SBlockData* pBlockData, SLastBlockReader* pLastBlockReader) {
+ SRowMerger merge = {0};
+ STSRow* pTSRow = NULL;
+
+ SFileBlockDumpInfo* pDumpInfo = &pReader->status.fBlockDumpInfo;
+ SArray* pDelList = pBlockScanInfo->delSkyline;
+
+ TSDBROW* pRow = getValidRow(&pBlockScanInfo->iter, pDelList, pReader);
+ TSDBROW* piRow = getValidRow(&pBlockScanInfo->iiter, pDelList, pReader);
+ ASSERT(pRow != NULL && piRow != NULL);
+
+ SBlockData* pLastBlockData = &pLastBlockReader->lastBlockData;
+ int64_t tsLast = getCurrentKeyInLastBlock(pLastBlockReader);
+
+ int64_t key = pBlockData->aTSKEY[pDumpInfo->rowIndex];
+
+ TSDBKEY k = TSDBROW_KEY(pRow);
+ TSDBKEY ik = TSDBROW_KEY(piRow);
+
+ int64_t minKey = 0;//INT64_MAX;
+ if (ASCENDING_TRAVERSE(pReader->order)) {
+ minKey = INT64_MAX; // let's find the minimum
+ if (minKey > k.ts) {
+ minKey = k.ts;
+ }
+
+ if (minKey > ik.ts) {
+ minKey = ik.ts;
+ }
+
+ if (minKey > key && pBlockData->nRow > 0) {
+ minKey = key;
+ }
+
+ if (minKey > tsLast && pLastBlockData->nRow > 0) {
+ minKey = tsLast;
+ }
+ } else {
+ minKey = INT64_MIN; // let find the maximum ts value
+ if (minKey < k.ts) {
+ minKey = k.ts;
+ }
+
+ if (minKey < ik.ts) {
+ minKey = ik.ts;
+ }
+
+ if (minKey < key && pBlockData->nRow > 0) {
+ minKey = key;
+ }
+
+ if (minKey < tsLast && pLastBlockData->nRow > 0) {
+ minKey = tsLast;
+ }
+ }
+
+ bool init = false;
+
+ // ASC: file block -----> last block -----> imem -----> mem
+ // DESC: mem -----> imem -----> last block -----> file block
+ if (ASCENDING_TRAVERSE(pReader->order)) {
+ if (minKey == key) {
+ init = true;
+ TSDBROW fRow = tsdbRowFromBlockData(pBlockData, pDumpInfo->rowIndex);
+ tRowMergerInit(&merge, &fRow, pReader->pSchema);
+ doMergeRowsInFileBlocks(pBlockData, pBlockScanInfo, pReader, &merge);
+ }
+
+ if (minKey == tsLast) {
+ TSDBROW fRow1 = tsdbRowFromBlockData(pLastBlockData, *pLastBlockReader->rowIndex);
+ if (init) {
+ tRowMerge(&merge, &fRow1);
+ } else {
+ init = true;
+ tRowMergerInit(&merge, &fRow1, pReader->pSchema);
+ }
+ doMergeRowsInLastBlock(pLastBlockReader, pBlockScanInfo, tsLast, &merge);
+ }
+
+ if (minKey == ik.ts) {
+ if (init) {
+ tRowMerge(&merge, piRow);
+ } else {
+ init = true;
+ STSchema* pSchema = doGetSchemaForTSRow(TSDBROW_SVERSION(piRow), pReader, pBlockScanInfo->uid);
+ tRowMergerInit(&merge, piRow, pSchema);
+ }
+ doMergeRowsInBuf(&pBlockScanInfo->iiter, pBlockScanInfo->uid, ik.ts, pBlockScanInfo->delSkyline, &merge, pReader);
+ }
+
+ if (minKey == k.ts) {
+ if (init) {
+ tRowMerge(&merge, pRow);
+ } else {
+ STSchema* pSchema = doGetSchemaForTSRow(TSDBROW_SVERSION(pRow), pReader, pBlockScanInfo->uid);
+ tRowMergerInit(&merge, pRow, pSchema);
+ }
+ doMergeRowsInBuf(&pBlockScanInfo->iter, pBlockScanInfo->uid, k.ts, pBlockScanInfo->delSkyline, &merge, pReader);
+ }
+ } else {
+ if (minKey == k.ts) {
+ init = true;
+ STSchema* pSchema = doGetSchemaForTSRow(TSDBROW_SVERSION(pRow), pReader, pBlockScanInfo->uid);
+ tRowMergerInit(&merge, pRow, pSchema);
+ doMergeRowsInBuf(&pBlockScanInfo->iter, pBlockScanInfo->uid, k.ts, pBlockScanInfo->delSkyline, &merge, pReader);
+ }
+
+ if (minKey == ik.ts) {
+ if (init) {
+ tRowMerge(&merge, piRow);
+ } else {
+ init = true;
+ STSchema* pSchema = doGetSchemaForTSRow(TSDBROW_SVERSION(piRow), pReader, pBlockScanInfo->uid);
+ tRowMergerInit(&merge, piRow, pSchema);
+ }
+ doMergeRowsInBuf(&pBlockScanInfo->iiter, pBlockScanInfo->uid, ik.ts, pBlockScanInfo->delSkyline, &merge, pReader);
+ }
+
+ if (minKey == tsLast) {
+ TSDBROW fRow1 = tsdbRowFromBlockData(pLastBlockData, *pLastBlockReader->rowIndex);
+ if (init) {
+ tRowMerge(&merge, &fRow1);
+ } else {
+ init = true;
+ tRowMergerInit(&merge, &fRow1, pReader->pSchema);
+ }
+ doMergeRowsInLastBlock(pLastBlockReader, pBlockScanInfo, tsLast, &merge);
+ }
+
+ if (minKey == key) {
+ TSDBROW fRow = tsdbRowFromBlockData(pBlockData, pDumpInfo->rowIndex);
+ if (!init) {
+ tRowMergerInit(&merge, &fRow, pReader->pSchema);
+ } else {
+ tRowMerge(&merge, &fRow);
+ }
+ doMergeRowsInFileBlocks(pBlockData, pBlockScanInfo, pReader, &merge);
+ }
+ }
+
+ tRowMergerGetRow(&merge, &pTSRow);
+ doAppendRowFromTSRow(pReader->pResBlock, pReader, pTSRow, pBlockScanInfo->uid);
+
+ taosMemoryFree(pTSRow);
+ tRowMergerClear(&merge);
+ return TSDB_CODE_SUCCESS;
+}
+
+static int32_t doMergeThreeLevelRows(STsdbReader* pReader, STableBlockScanInfo* pBlockScanInfo, SBlockData* pBlockData) {
SRowMerger merge = {0};
STSRow* pTSRow = NULL;
SFileBlockDumpInfo* pDumpInfo = &pReader->status.fBlockDumpInfo;
- SBlockData* pBlockData = &pReader->status.fileBlockData;
SArray* pDelList = pBlockScanInfo->delSkyline;
TSDBROW* pRow = getValidRow(&pBlockScanInfo->iter, pDelList, pReader);
@@ -1477,6 +1860,14 @@ static int32_t doMergeThreeLevelRows(STsdbReader* pReader, STableBlockScanInfo*
static bool isValidFileBlockRow(SBlockData* pBlockData, SFileBlockDumpInfo* pDumpInfo,
STableBlockScanInfo* pBlockScanInfo, STsdbReader* pReader) {
+ // it is an multi-table data block
+ if (pBlockData->aUid != NULL) {
+ uint64_t uid = pBlockData->aUid[pDumpInfo->rowIndex];
+ if (uid != pBlockScanInfo->uid) { // move to next row
+ return false;
+ }
+ }
+
// check for version and time range
int64_t ver = pBlockData->aVersion[pDumpInfo->rowIndex];
if (ver > pReader->verRange.maxVer || ver < pReader->verRange.minVer) {
@@ -1498,39 +1889,191 @@ static bool isValidFileBlockRow(SBlockData* pBlockData, SFileBlockDumpInfo* pDum
static bool outOfTimeWindow(int64_t ts, STimeWindow* pWindow) { return (ts > pWindow->ekey) || (ts < pWindow->skey); }
-static int32_t buildComposedDataBlockImpl(STsdbReader* pReader, STableBlockScanInfo* pBlockScanInfo) {
- SFileBlockDumpInfo* pDumpInfo = &pReader->status.fBlockDumpInfo;
- SBlockData* pBlockData = &pReader->status.fileBlockData;
+static void initLastBlockReader(SLastBlockReader* pLastBlockReader, uint64_t uid, int16_t* startPos) {
+ pLastBlockReader->uid = uid;
+ pLastBlockReader->rowIndex = startPos;
- int64_t key = pBlockData->aTSKEY[pDumpInfo->rowIndex];
+ if (*startPos == -1) {
+ if (ASCENDING_TRAVERSE(pLastBlockReader->order)) {
+ // do nothing
+ } else {
+ *startPos = pLastBlockReader->lastBlockData.nRow;
+ }
+ }
+}
+
+static void setAllRowsChecked(SLastBlockReader *pLastBlockReader) {
+ *pLastBlockReader->rowIndex = ALL_ROWS_CHECKED_INDEX;
+}
+
+static bool nextRowInLastBlock(SLastBlockReader *pLastBlockReader, STableBlockScanInfo* pBlockScanInfo) {
+ int32_t step = (pLastBlockReader->order == TSDB_ORDER_ASC) ? 1 : -1;
+ if (*pLastBlockReader->rowIndex == ALL_ROWS_CHECKED_INDEX) {
+ return false;
+ }
+
+ *(pLastBlockReader->rowIndex) += step;
+
+ SBlockData* pBlockData = &pLastBlockReader->lastBlockData;
+ for(int32_t i = *(pLastBlockReader->rowIndex); i < pBlockData->nRow && i >= 0; i += step) {
+ if (pBlockData->aUid != NULL && pBlockData->aUid[i] != pLastBlockReader->uid) {
+ continue;
+ }
+
+ int64_t ts = pBlockData->aTSKEY[i];
+ if (ts < pLastBlockReader->window.skey) {
+ continue;
+ }
+
+ int64_t ver = pBlockData->aVersion[i];
+ if (ver < pLastBlockReader->verRange.minVer) {
+ continue;
+ }
+
+ // no data any more, todo opt handle desc case
+ if (ts > pLastBlockReader->window.ekey) {
+ continue;
+ }
+
+ // todo opt handle desc case
+ if (ver > pLastBlockReader->verRange.maxVer) {
+ continue;
+ }
+
+ TSDBKEY k = {.ts = ts, .version = ver};
+ if (hasBeenDropped(pBlockScanInfo->delSkyline, &pBlockScanInfo->lastBlockDelIndex, &k, pLastBlockReader->order)) {
+ continue;
+ }
+
+ *(pLastBlockReader->rowIndex) = i;
+ return true;
+ }
+
+ // set all data is consumed in last block
+ setAllRowsChecked(pLastBlockReader);
+ return false;
+}
+
+static int64_t getCurrentKeyInLastBlock(SLastBlockReader* pLastBlockReader) {
+ SBlockData* pBlockData = &pLastBlockReader->lastBlockData;
+ return pBlockData->aTSKEY[*pLastBlockReader->rowIndex];
+}
+
+static bool hasDataInLastBlock(SLastBlockReader* pLastBlockReader) {
+ if (*pLastBlockReader->rowIndex == ALL_ROWS_CHECKED_INDEX) {
+ return false;
+ }
+ return true;
+}
+
+// todo refactor
+static int32_t buildComposedDataBlockImpl(STsdbReader* pReader, STableBlockScanInfo* pBlockScanInfo,
+ SBlockData* pBlockData, SLastBlockReader* pLastBlockReader) {
+ SFileBlockDumpInfo* pDumpInfo = &pReader->status.fBlockDumpInfo;
+
+ int64_t key = (pBlockData->nRow > 0)? pBlockData->aTSKEY[pDumpInfo->rowIndex]:INT64_MIN;
TSDBROW* pRow = getValidRow(&pBlockScanInfo->iter, pBlockScanInfo->delSkyline, pReader);
TSDBROW* piRow = getValidRow(&pBlockScanInfo->iiter, pBlockScanInfo->delSkyline, pReader);
if (pBlockScanInfo->iter.hasVal && pBlockScanInfo->iiter.hasVal) {
- return doMergeThreeLevelRows(pReader, pBlockScanInfo);
+ return doMergeMultiLevelRowsRv(pReader, pBlockScanInfo, pBlockData, pLastBlockReader);
} else {
- // imem + file
+ // imem + file + last block
if (pBlockScanInfo->iiter.hasVal) {
- return doMergeBufAndFileRows(pReader, pBlockScanInfo, piRow, &pBlockScanInfo->iiter, key);
+ return doMergeBufAndFileRows_Rv(pReader, pBlockScanInfo, piRow, &pBlockScanInfo->iiter, key, pLastBlockReader);
}
// mem + file
if (pBlockScanInfo->iter.hasVal) {
- return doMergeBufAndFileRows(pReader, pBlockScanInfo, pRow, &pBlockScanInfo->iter, key);
+ return doMergeBufAndFileRows_Rv(pReader, pBlockScanInfo, pRow, &pBlockScanInfo->iter, key, pLastBlockReader);
}
- // imem & mem are all empty, only file exist
- if (tryCopyDistinctRowFromFileBlock(pReader, pBlockData, key, pDumpInfo)) {
- return TSDB_CODE_SUCCESS;
- } else {
+ if (pBlockData->nRow > 0) {
TSDBROW fRow = tsdbRowFromBlockData(pBlockData, pDumpInfo->rowIndex);
+ // no last block
+ if (pLastBlockReader->lastBlockData.nRow == 0) {
+ if (tryCopyDistinctRowFromFileBlock(pReader, pBlockData, key, pDumpInfo)) {
+ return TSDB_CODE_SUCCESS;
+ } else {
+ STSRow* pTSRow = NULL;
+ SRowMerger merge = {0};
+
+ tRowMergerInit(&merge, &fRow, pReader->pSchema);
+ doMergeRowsInFileBlocks(pBlockData, pBlockScanInfo, pReader, &merge);
+ tRowMergerGetRow(&merge, &pTSRow);
+ doAppendRowFromTSRow(pReader->pResBlock, pReader, pTSRow, pBlockScanInfo->uid);
+
+ taosMemoryFree(pTSRow);
+ tRowMergerClear(&merge);
+ return TSDB_CODE_SUCCESS;
+ }
+ }
+
+ // row in last file block
+ int64_t ts = getCurrentKeyInLastBlock(pLastBlockReader);
+ if (ts < key) { // save rows in last block
+ SBlockData* pLastBlockData = &pLastBlockReader->lastBlockData;
+
+ STSRow* pTSRow = NULL;
+ SRowMerger merge = {0};
+
+ TSDBROW fRow1 = tsdbRowFromBlockData(pLastBlockData, *pLastBlockReader->rowIndex);
+
+ tRowMergerInit(&merge, &fRow1, pReader->pSchema);
+ doMergeRowsInLastBlock(pLastBlockReader, pBlockScanInfo, ts, &merge);
+ tRowMergerGetRow(&merge, &pTSRow);
+
+ doAppendRowFromTSRow(pReader->pResBlock, pReader, pTSRow, pBlockScanInfo->uid);
+
+ taosMemoryFree(pTSRow);
+ tRowMergerClear(&merge);
+ return TSDB_CODE_SUCCESS;
+ } else if (ts == key) {
+ STSRow* pTSRow = NULL;
+ SRowMerger merge = {0};
+
+ tRowMergerInit(&merge, &fRow, pReader->pSchema);
+ doMergeRowsInFileBlocks(pBlockData, pBlockScanInfo, pReader, &merge);
+ doMergeRowsInLastBlock(pLastBlockReader, pBlockScanInfo, ts, &merge);
+
+ tRowMergerGetRow(&merge, &pTSRow);
+ doAppendRowFromTSRow(pReader->pResBlock, pReader, pTSRow, pBlockScanInfo->uid);
+
+ taosMemoryFree(pTSRow);
+ tRowMergerClear(&merge);
+ return TSDB_CODE_SUCCESS;
+ } else { // ts > key, asc; todo handle desc
+ // imem & mem are all empty, only file exist
+ if (tryCopyDistinctRowFromFileBlock(pReader, pBlockData, key, pDumpInfo)) {
+ return TSDB_CODE_SUCCESS;
+ } else {
+ STSRow* pTSRow = NULL;
+ SRowMerger merge = {0};
+
+ tRowMergerInit(&merge, &fRow, pReader->pSchema);
+ doMergeRowsInFileBlocks(pBlockData, pBlockScanInfo, pReader, &merge);
+ tRowMergerGetRow(&merge, &pTSRow);
+ doAppendRowFromTSRow(pReader->pResBlock, pReader, pTSRow, pBlockScanInfo->uid);
+
+ taosMemoryFree(pTSRow);
+ tRowMergerClear(&merge);
+ return TSDB_CODE_SUCCESS;
+ }
+ }
+ } else { // only last block exists
+ SBlockData* pLastBlockData = &pLastBlockReader->lastBlockData;
+ int64_t tsLastBlock = getCurrentKeyInLastBlock(pLastBlockReader);
+
STSRow* pTSRow = NULL;
SRowMerger merge = {0};
+ TSDBROW fRow = tsdbRowFromBlockData(pLastBlockData, *pLastBlockReader->rowIndex);
+
tRowMergerInit(&merge, &fRow, pReader->pSchema);
- doMergeRowsInFileBlocks(pBlockData, pBlockScanInfo, pReader, &merge);
+ doMergeRowsInLastBlock(pLastBlockReader, pBlockScanInfo, tsLastBlock, &merge);
tRowMergerGetRow(&merge, &pTSRow);
+
doAppendRowFromTSRow(pReader->pResBlock, pReader, pTSRow, pBlockScanInfo->uid);
taosMemoryFree(pTSRow);
@@ -1540,41 +2083,59 @@ static int32_t buildComposedDataBlockImpl(STsdbReader* pReader, STableBlockScanI
}
}
-static int32_t buildComposedDataBlock(STsdbReader* pReader, STableBlockScanInfo* pBlockScanInfo) {
+static int32_t buildComposedDataBlock(STsdbReader* pReader) {
SSDataBlock* pResBlock = pReader->pResBlock;
+ SFileDataBlockInfo* pBlockInfo = getCurrentBlockInfo(&pReader->status.blockIter);
+
+ STableBlockScanInfo* pBlockScanInfo = NULL;
+ if (pBlockInfo != NULL) {
+ pBlockScanInfo = taosHashGet(pReader->status.pTableMap, &pBlockInfo->uid, sizeof(pBlockInfo->uid));
+ } else {
+ pBlockScanInfo = pReader->status.pTableIter;
+ }
+
+ SLastBlockReader* pLastBlockReader = pReader->status.fileIter.pLastBlockReader;
SFileBlockDumpInfo* pDumpInfo = &pReader->status.fBlockDumpInfo;
SBlockData* pBlockData = &pReader->status.fileBlockData;
int32_t step = ASCENDING_TRAVERSE(pReader->order) ? 1 : -1;
- int32_t numOfSub = 1;
-
int64_t st = taosGetTimestampUs();
while (1) {
// todo check the validate of row in file block
{
- if (!isValidFileBlockRow(pBlockData, pDumpInfo, pBlockScanInfo, pReader)) {
- pDumpInfo->rowIndex += step;
+ bool hasBlockData = false;
- SBlock* pBlock = getCurrentBlock(&pReader->status.blockIter);
- numOfSub = pBlock->nSubBlock;
-
- if (pDumpInfo->rowIndex >= pBlock->nRow || pDumpInfo->rowIndex < 0) {
- setBlockAllDumped(pDumpInfo, pBlock, pReader->order);
+ while (pBlockData->nRow > 0) { // find the first qualified row in data block
+ if (isValidFileBlockRow(pBlockData, pDumpInfo, pBlockScanInfo, pReader)) {
+ hasBlockData = true;
break;
}
- continue;
+ pDumpInfo->rowIndex += step;
+
+ SBlock* pBlock = getCurrentBlock(&pReader->status.blockIter);
+ if (pDumpInfo->rowIndex >= pBlock->nRow || pDumpInfo->rowIndex < 0) {
+ setBlockAllDumped(pDumpInfo, pBlock->maxKey.ts, pReader->order);
+ break;
+ }
+ }
+
+ bool hasBlockLData = hasDataInLastBlock(pLastBlockReader);
+
+ // no data in last block and block, no need to proceed.
+ if ((hasBlockData == false) && (hasBlockLData == false)) {
+ break;
}
}
- buildComposedDataBlockImpl(pReader, pBlockScanInfo);
- SBlock* pBlock = getCurrentBlock(&pReader->status.blockIter);
+ buildComposedDataBlockImpl(pReader, pBlockScanInfo, pBlockData, pLastBlockReader);
// currently loaded file data block is consumed
- if (pDumpInfo->rowIndex >= pBlock->nRow || pDumpInfo->rowIndex < 0) {
- setBlockAllDumped(pDumpInfo, pBlock, pReader->order);
+ if ((pBlockData->nRow > 0) && (pDumpInfo->rowIndex >= pBlockData->nRow || pDumpInfo->rowIndex < 0)) {
+ SBlock* pBlock = getCurrentBlock(&pReader->status.blockIter);
+ setBlockAllDumped(pDumpInfo, pBlock->maxKey.ts, pReader->order);
break;
}
@@ -1589,9 +2150,8 @@ static int32_t buildComposedDataBlock(STsdbReader* pReader, STableBlockScanInfo*
setComposedBlockFlag(pReader, true);
int64_t et = taosGetTimestampUs();
- tsdbDebug("%p uid:%" PRIu64 ", composed data block created, subBlock:%d, brange:%" PRIu64 "-%" PRIu64
- " rows:%d, elapsed time:%.2f ms %s",
- pReader, pBlockScanInfo->uid, numOfSub, pResBlock->info.window.skey, pResBlock->info.window.ekey,
+ tsdbDebug("%p uid:%" PRIu64 ", composed data block created, brange:%" PRIu64 "-%" PRIu64 " rows:%d, elapsed time:%.2f ms %s",
+ pReader, pBlockScanInfo->uid, pResBlock->info.window.skey, pResBlock->info.window.ekey,
pResBlock->info.rows, (et - st) / 1000.0, pReader->idStr);
return TSDB_CODE_SUCCESS;
@@ -1617,7 +2177,7 @@ static int32_t initMemDataIterator(STableBlockScanInfo* pBlockScanInfo, STsdbRea
STbData* d = NULL;
if (pReader->pReadSnap->pMem != NULL) {
- tsdbGetTbDataFromMemTable(pReader->pReadSnap->pMem, pReader->suid, pBlockScanInfo->uid, &d);
+ d = tsdbGetTbDataFromMemTable(pReader->pReadSnap->pMem, pReader->suid, pBlockScanInfo->uid);
if (d != NULL) {
code = tsdbTbDataIterCreate(d, &startKey, backward, &pBlockScanInfo->iter.iter);
if (code == TSDB_CODE_SUCCESS) {
@@ -1638,7 +2198,7 @@ static int32_t initMemDataIterator(STableBlockScanInfo* pBlockScanInfo, STsdbRea
STbData* di = NULL;
if (pReader->pReadSnap->pIMem != NULL) {
- tsdbGetTbDataFromMemTable(pReader->pReadSnap->pIMem, pReader->suid, pBlockScanInfo->uid, &di);
+ di = tsdbGetTbDataFromMemTable(pReader->pReadSnap->pIMem, pReader->suid, pBlockScanInfo->uid);
if (di != NULL) {
code = tsdbTbDataIterCreate(di, &startKey, backward, &pBlockScanInfo->iiter.iter);
if (code == TSDB_CODE_SUCCESS) {
@@ -1677,7 +2237,7 @@ int32_t initDelSkylineIterator(STableBlockScanInfo* pBlockScanInfo, STsdbReader*
SDelFile* pDelFile = pReader->pReadSnap->fs.pDelFile;
if (pDelFile) {
SDelFReader* pDelFReader = NULL;
- code = tsdbDelFReaderOpen(&pDelFReader, pDelFile, pTsdb, NULL);
+ code = tsdbDelFReaderOpen(&pDelFReader, pDelFile, pTsdb);
if (code != TSDB_CODE_SUCCESS) {
goto _err;
}
@@ -1688,7 +2248,7 @@ int32_t initDelSkylineIterator(STableBlockScanInfo* pBlockScanInfo, STsdbReader*
goto _err;
}
- code = tsdbReadDelIdx(pDelFReader, aDelIdx, NULL);
+ code = tsdbReadDelIdx(pDelFReader, aDelIdx);
if (code != TSDB_CODE_SUCCESS) {
taosArrayDestroy(aDelIdx);
tsdbDelFReaderClose(&pDelFReader);
@@ -1699,7 +2259,7 @@ int32_t initDelSkylineIterator(STableBlockScanInfo* pBlockScanInfo, STsdbReader*
SDelIdx* pIdx = taosArraySearch(aDelIdx, &idx, tCmprDelIdx, TD_EQ);
if (pIdx != NULL) {
- code = tsdbReadDelData(pDelFReader, pIdx, pDelData, NULL);
+ code = tsdbReadDelData(pDelFReader, pIdx, pDelData);
}
taosArrayDestroy(aDelIdx);
@@ -1737,6 +2297,7 @@ int32_t initDelSkylineIterator(STableBlockScanInfo* pBlockScanInfo, STsdbReader*
ASCENDING_TRAVERSE(pReader->order) ? 0 : taosArrayGetSize(pBlockScanInfo->delSkyline) - 1;
pBlockScanInfo->iiter.index = pBlockScanInfo->iter.index;
pBlockScanInfo->fileDelIndex = pBlockScanInfo->iter.index;
+ pBlockScanInfo->lastBlockDelIndex = pBlockScanInfo->iter.index;
return code;
_err:
@@ -1744,12 +2305,9 @@ _err:
return code;
}
-static TSDBKEY getCurrentKeyInBuf(SDataBlockIter* pBlockIter, STsdbReader* pReader) {
+static TSDBKEY getCurrentKeyInBuf(STableBlockScanInfo* pScanInfo, STsdbReader* pReader) {
TSDBKEY key = {.ts = TSKEY_INITIAL_VAL};
- SFileDataBlockInfo* pFBlock = getCurrentBlockInfo(pBlockIter);
- STableBlockScanInfo* pScanInfo = taosHashGet(pReader->status.pTableMap, &pFBlock->uid, sizeof(pFBlock->uid));
-
initMemDataIterator(pScanInfo, pReader);
TSDBROW* pRow = getValidRow(&pScanInfo->iter, pScanInfo->delSkyline, pReader);
if (pRow != NULL) {
@@ -1767,11 +2325,15 @@ static TSDBKEY getCurrentKeyInBuf(SDataBlockIter* pBlockIter, STsdbReader* pRead
return key;
}
-static int32_t moveToNextFile(STsdbReader* pReader, int32_t* numOfBlocks) {
+static int32_t moveToNextFile(STsdbReader* pReader, SBlockNumber* pBlockNum) {
SReaderStatus* pStatus = &pReader->status;
+ pBlockNum->numOfBlocks = 0;
+ pBlockNum->numOfLastBlocks = 0;
size_t numOfTables = taosHashGetSize(pReader->status.pTableMap);
SArray* pIndexList = taosArrayInit(numOfTables, sizeof(SBlockIdx));
+ SArray* pLastBlocks = pStatus->fileIter.pLastBlockReader->pBlockL;
+ taosArrayClear(pLastBlocks);
while (1) {
bool hasNext = filesetIteratorNext(&pStatus->fileIter, pReader);
@@ -1786,18 +2348,34 @@ static int32_t moveToNextFile(STsdbReader* pReader, int32_t* numOfBlocks) {
return code;
}
- if (taosArrayGetSize(pIndexList) > 0) {
- uint32_t numOfValidTable = 0;
- code = doLoadFileBlock(pReader, pIndexList, &numOfValidTable, numOfBlocks);
+ code = tsdbReadBlockL(pReader->pFileReader, pLastBlocks);
+ if (code != TSDB_CODE_SUCCESS) {
+ taosArrayDestroy(pIndexList);
+ return code;
+ }
+
+ if (taosArrayGetSize(pIndexList) > 0 || taosArrayGetSize(pLastBlocks) > 0) {
+ SArray* pQLastBlock = taosArrayInit(4, sizeof(SBlockL));
+
+ code = doLoadFileBlock(pReader, pIndexList, pLastBlocks, pBlockNum, pQLastBlock);
if (code != TSDB_CODE_SUCCESS) {
taosArrayDestroy(pIndexList);
+ taosArrayDestroy(pQLastBlock);
return code;
}
- if (numOfValidTable > 0) {
+ if (pBlockNum->numOfBlocks + pBlockNum->numOfLastBlocks > 0) {
+ ASSERT(taosArrayGetSize(pQLastBlock) == pBlockNum->numOfLastBlocks);
+ taosArrayClear(pLastBlocks);
+ taosArrayAddAll(pLastBlocks, pQLastBlock);
+
+ taosArrayDestroy(pQLastBlock);
break;
}
+
+ taosArrayDestroy(pQLastBlock);
}
+
// no blocks in current file, try next files
}
@@ -1805,28 +2383,172 @@ static int32_t moveToNextFile(STsdbReader* pReader, int32_t* numOfBlocks) {
return TSDB_CODE_SUCCESS;
}
+// todo add elapsed time results
+static int32_t doLoadRelatedLastBlock(SLastBlockReader* pLastBlockReader, STableBlockScanInfo *pBlockScanInfo, STsdbReader* pReader) {
+ SArray* pBlocks = pLastBlockReader->pBlockL;
+ SBlockL* pBlock = NULL;
+
+ uint64_t uid = pBlockScanInfo->uid;
+ int32_t totalLastBlocks = (int32_t)taosArrayGetSize(pBlocks);
+
+ initMemDataIterator(pBlockScanInfo, pReader);
+
+ // find the correct SBlockL. todo binary search
+ int32_t index = -1;
+ for (int32_t i = 0; i < totalLastBlocks; ++i) {
+ SBlockL* p = taosArrayGet(pBlocks, i);
+ if (p->minUid <= uid && p->maxUid >= uid) {
+ index = i;
+ pBlock = p;
+ break;
+ }
+ }
+
+ if (index == -1) {
+ pLastBlockReader->currentBlockIndex = index;
+ tBlockDataReset(&pLastBlockReader->lastBlockData);
+ return TSDB_CODE_SUCCESS;
+ }
+
+ // the required last datablock has already loaded
+ if (index == pLastBlockReader->currentBlockIndex) {
+ return TSDB_CODE_SUCCESS;
+ }
+
+ int32_t code = tBlockDataInit(&pLastBlockReader->lastBlockData, pReader->suid, pReader->suid ? 0 : uid, pReader->pSchema);
+ if (code != TSDB_CODE_SUCCESS) {
+ tsdbError("%p init block data failed, code:%s %s", pReader, tstrerror(code), pReader->idStr);
+ return code;
+ }
+
+ code = tsdbReadLastBlock(pReader->pFileReader, pBlock, &pLastBlockReader->lastBlockData);
+ if (code != TSDB_CODE_SUCCESS) {
+ tsdbError("%p error occurs in loading last block into buffer, last block index:%d, total:%d code:%s %s", pReader,
+ pLastBlockReader->currentBlockIndex, totalLastBlocks, tstrerror(code), pReader->idStr);
+ } else {
+ tsdbDebug("%p load last block completed, uid:%" PRIu64
+ " last block index:%d, total:%d rows:%d, minVer:%d, maxVer:%d, brange:%" PRId64 " - %" PRId64 " %s",
+ pReader, uid, pLastBlockReader->currentBlockIndex, totalLastBlocks, pBlock->nRow, pBlock->minVer,
+ pBlock->maxVer, pBlock->minKey, pBlock->maxKey, pReader->idStr);
+ }
+
+ pLastBlockReader->currentBlockIndex = index;
+ return TSDB_CODE_SUCCESS;
+}
+
+static int32_t doLoadLastBlockSequentially(STsdbReader* pReader) {
+ SReaderStatus* pStatus = &pReader->status;
+ SLastBlockReader* pLastBlockReader = pStatus->fileIter.pLastBlockReader;
+
+ while(1) {
+ if (pStatus->pTableIter == NULL) {
+ pStatus->pTableIter = taosHashIterate(pStatus->pTableMap, NULL);
+ if (pStatus->pTableIter == NULL) {
+ return TSDB_CODE_SUCCESS;
+ }
+ }
+
+ // load the last data block of current table
+ // todo opt perf by avoiding load last block repeatly
+ STableBlockScanInfo* pScanInfo = pStatus->pTableIter;
+ int32_t code = doLoadRelatedLastBlock(pLastBlockReader, pScanInfo, pReader);
+ if (code != TSDB_CODE_SUCCESS) {
+ return code;
+ }
+
+ if (pLastBlockReader->currentBlockIndex != -1) {
+ initLastBlockReader(pLastBlockReader, pScanInfo->uid, &pScanInfo->indexInBlockL);
+ int32_t index = pScanInfo->indexInBlockL;
+ if (index == DEFAULT_ROW_INDEX_VAL || index == pLastBlockReader->lastBlockData.nRow) {
+ bool hasData = nextRowInLastBlock(pLastBlockReader, pScanInfo);
+ if (!hasData) { // current table does not have rows in last block, try next table
+ pStatus->pTableIter = taosHashIterate(pStatus->pTableMap, pStatus->pTableIter);
+ if (pStatus->pTableIter == NULL) {
+ return TSDB_CODE_SUCCESS;
+ }
+ continue;
+ }
+ }
+ } else { // no data in last block, try next table
+ pStatus->pTableIter = taosHashIterate(pStatus->pTableMap, pStatus->pTableIter);
+ if (pStatus->pTableIter == NULL) {
+ return TSDB_CODE_SUCCESS;
+ }
+ continue;
+ }
+
+ code = doBuildDataBlock(pReader);
+ if (code != TSDB_CODE_SUCCESS) {
+ return code;
+ }
+
+ if (pReader->pResBlock->info.rows > 0) {
+ return TSDB_CODE_SUCCESS;
+ }
+
+ // current table is exhausted, let's try next table
+ pStatus->pTableIter = taosHashIterate(pStatus->pTableMap, pStatus->pTableIter);
+ if (pStatus->pTableIter == NULL) {
+ return TSDB_CODE_SUCCESS;
+ }
+ }
+}
+
static int32_t doBuildDataBlock(STsdbReader* pReader) {
int32_t code = TSDB_CODE_SUCCESS;
SReaderStatus* pStatus = &pReader->status;
SDataBlockIter* pBlockIter = &pStatus->blockIter;
- SFileDataBlockInfo* pFBlock = getCurrentBlockInfo(pBlockIter);
- STableBlockScanInfo* pScanInfo = taosHashGet(pStatus->pTableMap, &pFBlock->uid, sizeof(pFBlock->uid));
+ TSDBKEY key = {0};
+ SBlock* pBlock = NULL;
+ STableBlockScanInfo* pScanInfo = NULL;
+ SFileDataBlockInfo* pBlockInfo = getCurrentBlockInfo(pBlockIter);
+ SLastBlockReader* pLastBlockReader = pReader->status.fileIter.pLastBlockReader;
- SBlock* pBlock = getCurrentBlock(pBlockIter);
+ if (pBlockInfo != NULL) {
+ pScanInfo = taosHashGet(pReader->status.pTableMap, &pBlockInfo->uid, sizeof(pBlockInfo->uid));
+ } else {
+ pScanInfo = pReader->status.pTableIter;
+ }
- TSDBKEY key = getCurrentKeyInBuf(pBlockIter, pReader);
- if (fileBlockShouldLoad(pReader, pFBlock, pBlock, pScanInfo, key)) {
+ if (pBlockInfo != NULL) {
+ pBlock = getCurrentBlock(pBlockIter);
+ }
+
+ {
+ key = getCurrentKeyInBuf(pScanInfo, pReader);
+
+ // load the last data block of current table
+ code = doLoadRelatedLastBlock(pLastBlockReader, pScanInfo, pReader);
+ if (code != TSDB_CODE_SUCCESS) {
+ return code;
+ }
+
+ // note: the lastblock may be null here
+ initLastBlockReader(pLastBlockReader, pScanInfo->uid, &pScanInfo->indexInBlockL);
+ if (pScanInfo->indexInBlockL == DEFAULT_ROW_INDEX_VAL || pScanInfo->indexInBlockL == pLastBlockReader->lastBlockData.nRow) {
+ bool hasData = nextRowInLastBlock(pLastBlockReader, pScanInfo);
+ }
+ }
+
+ if (pBlockInfo == NULL) { // build data block from last data file
+ ASSERT(pBlockIter->numOfBlocks == 0);
+ code = buildComposedDataBlock(pReader);
+ } else if (fileBlockShouldLoad(pReader, pBlockInfo, pBlock, pScanInfo, key, pLastBlockReader)) {
tBlockDataReset(&pStatus->fileBlockData);
- tBlockDataClearData(&pStatus->fileBlockData);
- code = doLoadFileBlockData(pReader, pBlockIter, pScanInfo, &pStatus->fileBlockData);
+ code = tBlockDataInit(&pStatus->fileBlockData, pReader->suid, pScanInfo->uid, pReader->pSchema);
+ if (code != TSDB_CODE_SUCCESS) {
+ return code;
+ }
+
+ code = doLoadFileBlockData(pReader, pBlockIter, &pStatus->fileBlockData);
if (code != TSDB_CODE_SUCCESS) {
return code;
}
// build composed data block
- code = buildComposedDataBlock(pReader, pScanInfo);
+ code = buildComposedDataBlock(pReader);
} else if (bufferDataInFileBlockGap(pReader->order, key, pBlock)) {
// data in memory that are earlier than current file block
// todo rows in buffer should be less than the file block in asc, greater than file block in desc
@@ -1838,7 +2560,7 @@ static int32_t doBuildDataBlock(STsdbReader* pReader) {
pInfo->uid = pScanInfo->uid;
pInfo->window = (STimeWindow){.skey = pBlock->minKey.ts, .ekey = pBlock->maxKey.ts};
setComposedBlockFlag(pReader, false);
- setBlockAllDumped(&pStatus->fBlockDumpInfo, pBlock, pReader->order);
+ setBlockAllDumped(&pStatus->fBlockDumpInfo, pBlock->maxKey.ts, pReader->order);
}
return code;
@@ -1890,20 +2612,29 @@ static void initBlockDumpInfo(STsdbReader* pReader, SDataBlockIter* pBlockIter)
}
static int32_t initForFirstBlockInFile(STsdbReader* pReader, SDataBlockIter* pBlockIter) {
- int32_t numOfBlocks = 0;
- int32_t code = moveToNextFile(pReader, &numOfBlocks);
+ SBlockNumber num = {0};
+
+ int32_t code = moveToNextFile(pReader, &num);
if (code != TSDB_CODE_SUCCESS) {
return code;
}
// all data files are consumed, try data in buffer
- if (numOfBlocks == 0) {
+ if (num.numOfBlocks + num.numOfLastBlocks == 0) {
pReader->status.loadFromFile = false;
return code;
}
// initialize the block iterator for a new fileset
- code = initBlockIterator(pReader, pBlockIter, numOfBlocks);
+ if (num.numOfBlocks > 0) {
+ code = initBlockIterator(pReader, pBlockIter, num.numOfBlocks);
+ } else {
+ tBlockDataReset(&pReader->status.fileBlockData);
+ resetDataBlockIterator(pBlockIter, pReader->order, pReader->status.pTableMap);
+ }
+
+ SLastBlockReader* pLReader = pReader->status.fileIter.pLastBlockReader;
+ pLReader->currentBlockIndex = -1;
// set the correct start position according to the query time window
initBlockDumpInfo(pReader, pBlockIter);
@@ -1921,14 +2652,47 @@ static int32_t buildBlockFromFiles(STsdbReader* pReader) {
SDataBlockIter* pBlockIter = &pReader->status.blockIter;
- while (1) {
- SFileDataBlockInfo* pFBlock = getCurrentBlockInfo(&pReader->status.blockIter);
- STableBlockScanInfo* pScanInfo = taosHashGet(pReader->status.pTableMap, &pFBlock->uid, sizeof(pFBlock->uid));
+ if (pBlockIter->numOfBlocks == 0) {
+ _begin:
+ code = doLoadLastBlockSequentially(pReader);
+ if (code != TSDB_CODE_SUCCESS) {
+ return code;
+ }
+ if (pReader->pResBlock->info.rows > 0) {
+ return TSDB_CODE_SUCCESS;
+ }
+
+ // all data blocks are checked in this last block file, now let's try the next file
+ if (pReader->status.pTableIter == NULL) {
+ code = initForFirstBlockInFile(pReader, pBlockIter);
+
+ // error happens or all the data files are completely checked
+ if ((code != TSDB_CODE_SUCCESS) || (pReader->status.loadFromFile == false)) {
+ return code;
+ }
+
+ // this file does not have data files, let's start check the last block file if exists
+ if (pBlockIter->numOfBlocks == 0) {
+ goto _begin;
+ }
+ }
+
+ code = doBuildDataBlock(pReader);
+ if (code != TSDB_CODE_SUCCESS) {
+ return code;
+ }
+
+ if (pReader->pResBlock->info.rows > 0) {
+ return TSDB_CODE_SUCCESS;
+ }
+ }
+
+ while (1) {
SFileBlockDumpInfo* pDumpInfo = &pReader->status.fBlockDumpInfo;
if (fileBlockPartiallyRead(pDumpInfo, asc)) { // file data block is partially loaded
- code = buildComposedDataBlock(pReader, pScanInfo);
+ code = buildComposedDataBlock(pReader);
} else {
// current block are exhausted, try the next file block
if (pDumpInfo->allDumped) {
@@ -1936,17 +2700,26 @@ static int32_t buildBlockFromFiles(STsdbReader* pReader) {
bool hasNext = blockIteratorNext(&pReader->status.blockIter);
if (hasNext) { // check for the next block in the block accessed order list
initBlockDumpInfo(pReader, pBlockIter);
- } else { // data blocks in current file are exhausted, let's try the next file now
+ } else if (taosArrayGetSize(pReader->status.fileIter.pLastBlockReader->pBlockL) > 0) { // data blocks in current file are exhausted, let's try the next file now
+ // todo dump all data in last block if exists.
+ tBlockDataReset(&pReader->status.fileBlockData);
+ resetDataBlockIterator(pBlockIter, pReader->order, pReader->status.pTableMap);
+ goto _begin;
+ } else {
code = initForFirstBlockInFile(pReader, pBlockIter);
// error happens or all the data files are completely checked
if ((code != TSDB_CODE_SUCCESS) || (pReader->status.loadFromFile == false)) {
return code;
}
+
+ // this file does not have blocks, let's start check the last block file
+ if (pBlockIter->numOfBlocks == 0) {
+ goto _begin;
+ }
}
}
- // current block is not loaded yet, or data in buffer may overlap with the file block.
code = doBuildDataBlock(pReader);
}
@@ -2014,39 +2787,6 @@ SVersionRange getQueryVerRange(SVnode* pVnode, SQueryTableDataCond* pCond, int8_
return (SVersionRange){.minVer = startVer, .maxVer = endVer};
}
-// // todo not unref yet, since it is not support multi-group interpolation query
-// static UNUSED_FUNC void changeQueryHandleForInterpQuery(STsdbReader* pHandle) {
-// // filter the queried time stamp in the first place
-// STsdbReader* pTsdbReadHandle = (STsdbReader*)pHandle;
-
-// // starts from the buffer in case of descending timestamp order check data blocks
-// size_t numOfTables = taosArrayGetSize(pTsdbReadHandle->pTableCheckInfo);
-
-// int32_t i = 0;
-// while (i < numOfTables) {
-// STableBlockScanInfo* pCheckInfo = taosArrayGet(pTsdbReadHandle->pTableCheckInfo, i);
-
-// // the first qualified table for interpolation query
-// // if ((pTsdbReadHandle->window.skey <= pCheckInfo->pTableObj->lastKey) &&
-// // (pCheckInfo->pTableObj->lastKey != TSKEY_INITIAL_VAL)) {
-// // break;
-// // }
-
-// i++;
-// }
-
-// // there are no data in all the tables
-// if (i == numOfTables) {
-// return;
-// }
-
-// STableBlockScanInfo info = *(STableBlockScanInfo*)taosArrayGet(pTsdbReadHandle->pTableCheckInfo, i);
-// taosArrayClear(pTsdbReadHandle->pTableCheckInfo);
-
-// info.lastKey = pTsdbReadHandle->window.skey;
-// taosArrayPush(pTsdbReadHandle->pTableCheckInfo, &info);
-// }
-
bool hasBeenDropped(const SArray* pDelList, int32_t* index, TSDBKEY* pKey, int32_t order) {
ASSERT(pKey != NULL);
if (pDelList == NULL) {
@@ -2265,8 +3005,7 @@ static int32_t checkForNeighborFileBlock(STsdbReader* pReader, STableBlockScanIn
// 3. load the neighbor block, and set it to be the currently accessed file data block
tBlockDataReset(&pStatus->fileBlockData);
- tBlockDataClearData(&pStatus->fileBlockData);
- int32_t code = doLoadFileBlockData(pReader, pBlockIter, pScanInfo, &pStatus->fileBlockData);
+ int32_t code = doLoadFileBlockData(pReader, pBlockIter, &pStatus->fileBlockData);
if (code != TSDB_CODE_SUCCESS) {
return code;
}
@@ -2315,6 +3054,21 @@ int32_t doMergeRowsInFileBlocks(SBlockData* pBlockData, STableBlockScanInfo* pSc
return TSDB_CODE_SUCCESS;
}
+// todo check if the rows are dropped or not
+int32_t doMergeRowsInLastBlock(SLastBlockReader* pLastBlockReader, STableBlockScanInfo* pScanInfo, int64_t ts, SRowMerger* pMerger) {
+ while(nextRowInLastBlock(pLastBlockReader, pScanInfo)) {
+ int64_t next1 = getCurrentKeyInLastBlock(pLastBlockReader);
+ if (next1 == ts) {
+ TSDBROW fRow1 = tsdbRowFromBlockData(&pLastBlockReader->lastBlockData, *pLastBlockReader->rowIndex);
+ tRowMerge(pMerger, &fRow1);
+ } else {
+ break;
+ }
+ }
+
+ return TSDB_CODE_SUCCESS;
+}
+
void doMergeMultiRows(TSDBROW* pRow, uint64_t uid, SIterInfo* pIter, SArray* pDelList, STSRow** pTSRow,
STsdbReader* pReader, bool* freeTSRow) {
TSDBROW* pNextRow = NULL;
@@ -2487,7 +3241,7 @@ int32_t doAppendRowFromTSRow(SSDataBlock* pBlock, STsdbReader* pReader, STSRow*
return TSDB_CODE_SUCCESS;
}
-int32_t doAppendRowFromBlock(SSDataBlock* pResBlock, STsdbReader* pReader, SBlockData* pBlockData, int32_t rowIndex) {
+int32_t doAppendRowFromFileBlock(SSDataBlock* pResBlock, STsdbReader* pReader, SBlockData* pBlockData, int32_t rowIndex) {
int32_t i = 0, j = 0;
int32_t outputRowIndex = pResBlock->info.rows;
@@ -2564,7 +3318,7 @@ int32_t tsdbSetTableId(STsdbReader* pReader, int64_t uid) {
ASSERT(pReader != NULL);
taosHashClear(pReader->status.pTableMap);
- STableBlockScanInfo info = {.lastKey = 0, .uid = uid};
+ STableBlockScanInfo info = {.lastKey = 0, .uid = uid, .indexInBlockL = DEFAULT_ROW_INDEX_VAL};
taosHashPut(pReader->status.pTableMap, &info.uid, sizeof(uint64_t), &info, sizeof(info));
return TDB_CODE_SUCCESS;
}
@@ -2585,32 +3339,6 @@ void* tsdbGetIvtIdx(SMeta* pMeta) {
uint64_t getReaderMaxVersion(STsdbReader* pReader) { return pReader->verRange.maxVer; }
-/**
- * @brief Get all suids since suid
- *
- * @param pMeta
- * @param suid return all suids in one vnode if suid is 0
- * @param list
- * @return int32_t
- */
-int32_t tsdbGetStbIdList(SMeta* pMeta, int64_t suid, SArray* list) {
- SMStbCursor* pCur = metaOpenStbCursor(pMeta, suid);
- if (!pCur) {
- return TSDB_CODE_FAILED;
- }
-
- while (1) {
- tb_uid_t id = metaStbCursorNext(pCur);
- if (id == 0) {
- break;
- }
-
- taosArrayPush(list, &id);
- }
-
- metaCloseStbCursor(pCur);
- return TSDB_CODE_SUCCESS;
-}
// ====================================== EXPOSED APIs ======================================
int32_t tsdbReaderOpen(SVnode* pVnode, SQueryTableDataCond* pCond, SArray* pTableList, STsdbReader** ppReader,
@@ -2641,6 +3369,7 @@ int32_t tsdbReaderOpen(SVnode* pVnode, SQueryTableDataCond* pCond, SArray* pTabl
pCond->order = TSDB_ORDER_ASC;
}
+ // here we only need one more row, so the capacity is set to be ONE.
code = tsdbReaderCreate(pVnode, pCond, &pReader->innerReader[0], 1, idstr);
if (code != TSDB_CODE_SUCCESS) {
goto _err;
@@ -2684,7 +3413,7 @@ int32_t tsdbReaderOpen(SVnode* pVnode, SQueryTableDataCond* pCond, SArray* pTabl
if (pReader->type == TIMEWINDOW_RANGE_CONTAINED) {
SDataBlockIter* pBlockIter = &pReader->status.blockIter;
- initFilesetIterator(&pReader->status.fileIter, pReader->pReadSnap->fs.aDFileSet, pReader->order, pReader->idStr);
+ initFilesetIterator(&pReader->status.fileIter, pReader->pReadSnap->fs.aDFileSet, pReader);
resetDataBlockIterator(&pReader->status.blockIter, pReader->order, pReader->status.pTableMap);
// no data in files, let's try buffer in memory
@@ -2705,8 +3434,7 @@ int32_t tsdbReaderOpen(SVnode* pVnode, SQueryTableDataCond* pCond, SArray* pTabl
goto _err;
}
- initFilesetIterator(&pPrevReader->status.fileIter, pPrevReader->pReadSnap->fs.aDFileSet, pPrevReader->order,
- pPrevReader->idStr);
+ initFilesetIterator(&pPrevReader->status.fileIter, pPrevReader->pReadSnap->fs.aDFileSet, pPrevReader);
resetDataBlockIterator(&pPrevReader->status.blockIter, pPrevReader->order, pReader->status.pTableMap);
// no data in files, let's try buffer in memory
@@ -2746,7 +3474,7 @@ void tsdbReaderClose(STsdbReader* pReader) {
}
}
taosMemoryFree(pSupInfo->buildBuf);
- tBlockDataClear(&pReader->status.fileBlockData, true);
+ tBlockDataDestroy(&pReader->status.fileBlockData, true);
cleanupDataBlockIterator(&pReader->status.blockIter);
@@ -2758,6 +3486,13 @@ void tsdbReaderClose(STsdbReader* pReader) {
tsdbDataFReaderClose(&pReader->pFileReader);
}
+ SFilesetIter* pFilesetIter = &pReader->status.fileIter;
+ if (pFilesetIter->pLastBlockReader != NULL) {
+ tBlockDataDestroy(&pFilesetIter->pLastBlockReader->lastBlockData, true);
+ taosArrayDestroy(pFilesetIter->pLastBlockReader->pBlockL);
+ taosMemoryFree(pFilesetIter->pLastBlockReader);
+ }
+
SIOCostSummary* pCost = &pReader->cost;
tsdbDebug("%p :io-cost summary: head-file:%" PRIu64 ", head-file time:%.2f ms, SMA:%" PRId64
@@ -2883,7 +3618,7 @@ int32_t tsdbRetrieveDatablockSMA(STsdbReader* pReader, SColumnDataAgg*** pBlockS
SBlockLoadSuppInfo* pSup = &pReader->suppInfo;
if (tBlockHasSma(pBlock)) {
- code = tsdbReadBlockSma(pReader->pFileReader, pBlock, pSup->pColAgg, NULL);
+ code = tsdbReadBlockSma(pReader->pFileReader, pBlock, pSup->pColAgg);
if (code != TSDB_CODE_SUCCESS) {
tsdbDebug("vgId:%d, failed to load block SMA for uid %" PRIu64 ", code:%s, %s", 0, pFBlock->uid, tstrerror(code),
pReader->idStr);
@@ -2949,11 +3684,15 @@ static SArray* doRetrieveDataBlock(STsdbReader* pReader) {
STableBlockScanInfo* pBlockScanInfo = taosHashGet(pStatus->pTableMap, &pFBlock->uid, sizeof(pFBlock->uid));
tBlockDataReset(&pStatus->fileBlockData);
- tBlockDataClearData(&pStatus->fileBlockData);
- int32_t code = doLoadFileBlockData(pReader, &pStatus->blockIter, pBlockScanInfo, &pStatus->fileBlockData);
+ int32_t code = tBlockDataInit(&pStatus->fileBlockData, pReader->suid, pBlockScanInfo->uid, pReader->pSchema);
if (code != TSDB_CODE_SUCCESS) {
- tBlockDataClear(&pStatus->fileBlockData, 1);
+ terrno = code;
+ return NULL;
+ }
+ code = doLoadFileBlockData(pReader, &pStatus->blockIter, &pStatus->fileBlockData);
+ if (code != TSDB_CODE_SUCCESS) {
+ tBlockDataDestroy(&pStatus->fileBlockData, 1);
terrno = code;
return NULL;
}
@@ -2995,7 +3734,7 @@ int32_t tsdbReaderReset(STsdbReader* pReader, SQueryTableDataCond* pCond) {
int32_t numOfTables = taosHashGetSize(pReader->status.pTableMap);
tsdbDataFReaderClose(&pReader->pFileReader);
- initFilesetIterator(&pReader->status.fileIter, pReader->pReadSnap->fs.aDFileSet, pReader->order, pReader->idStr);
+ initFilesetIterator(&pReader->status.fileIter, pReader->pReadSnap->fs.aDFileSet, pReader);
resetDataBlockIterator(&pReader->status.blockIter, pReader->order, pReader->status.pTableMap);
resetDataBlockScanInfo(pReader->status.pTableMap);
@@ -3104,7 +3843,7 @@ int64_t tsdbGetNumOfRowsInMemTable(STsdbReader* pReader) {
STbData* d = NULL;
if (pReader->pTsdb->mem != NULL) {
- tsdbGetTbDataFromMemTable(pReader->pReadSnap->pMem, pReader->suid, pBlockScanInfo->uid, &d);
+ d = tsdbGetTbDataFromMemTable(pReader->pReadSnap->pMem, pReader->suid, pBlockScanInfo->uid);
if (d != NULL) {
rows += tsdbGetNRowsInTbData(d);
}
@@ -3112,7 +3851,7 @@ int64_t tsdbGetNumOfRowsInMemTable(STsdbReader* pReader) {
STbData* di = NULL;
if (pReader->pTsdb->imem != NULL) {
- tsdbGetTbDataFromMemTable(pReader->pReadSnap->pIMem, pReader->suid, pBlockScanInfo->uid, &di);
+ di = tsdbGetTbDataFromMemTable(pReader->pReadSnap->pIMem, pReader->suid, pBlockScanInfo->uid);
if (di != NULL) {
rows += tsdbGetNRowsInTbData(di);
}
diff --git a/source/dnode/vnode/src/tsdb/tsdbReaderWriter.c b/source/dnode/vnode/src/tsdb/tsdbReaderWriter.c
index ea9c3e5313..c8f3862071 100644
--- a/source/dnode/vnode/src/tsdb/tsdbReaderWriter.c
+++ b/source/dnode/vnode/src/tsdb/tsdbReaderWriter.c
@@ -15,8 +15,6 @@
#include "tsdb.h"
-#define TSDB_FILE_DLMT ((uint32_t)0xF00AFA0F)
-
// SDelFWriter ====================================================
int32_t tsdbDelFWriterOpen(SDelFWriter **ppWriter, SDelFile *pFile, STsdb *pTsdb) {
int32_t code = 0;
@@ -63,6 +61,7 @@ _err:
int32_t tsdbDelFWriterClose(SDelFWriter **ppWriter, int8_t sync) {
int32_t code = 0;
SDelFWriter *pWriter = *ppWriter;
+ STsdb *pTsdb = pWriter->pTsdb;
// sync
if (sync && taosFsyncFile(pWriter->pWriteH) < 0) {
@@ -76,47 +75,47 @@ int32_t tsdbDelFWriterClose(SDelFWriter **ppWriter, int8_t sync) {
goto _err;
}
+ for (int32_t iBuf = 0; iBuf < sizeof(pWriter->aBuf) / sizeof(uint8_t *); iBuf++) {
+ tFree(pWriter->aBuf[iBuf]);
+ }
+ taosMemoryFree(pWriter);
+
*ppWriter = NULL;
return code;
_err:
- tsdbError("vgId:%d, failed to close del file writer since %s", TD_VID(pWriter->pTsdb->pVnode), tstrerror(code));
+ tsdbError("vgId:%d, failed to close del file writer since %s", TD_VID(pTsdb->pVnode), tstrerror(code));
return code;
}
-int32_t tsdbWriteDelData(SDelFWriter *pWriter, SArray *aDelData, uint8_t **ppBuf, SDelIdx *pDelIdx) {
- int32_t code = 0;
- uint8_t *pBuf = NULL;
- int64_t size;
- int64_t n;
- SBlockDataHdr hdr = {.delimiter = TSDB_FILE_DLMT, .suid = pDelIdx->suid, .uid = pDelIdx->uid};
-
- if (!ppBuf) ppBuf = &pBuf;
+int32_t tsdbWriteDelData(SDelFWriter *pWriter, SArray *aDelData, SDelIdx *pDelIdx) {
+ int32_t code = 0;
+ int64_t size;
+ int64_t n;
// prepare
- size = sizeof(hdr);
+ size = sizeof(uint32_t);
for (int32_t iDelData = 0; iDelData < taosArrayGetSize(aDelData); iDelData++) {
size += tPutDelData(NULL, taosArrayGet(aDelData, iDelData));
}
size += sizeof(TSCKSUM);
// alloc
- code = tRealloc(ppBuf, size);
+ code = tRealloc(&pWriter->aBuf[0], size);
if (code) goto _err;
// build
n = 0;
- *(SBlockDataHdr *)(*ppBuf) = hdr;
- n += sizeof(hdr);
+ n += tPutU32(pWriter->aBuf[0] + n, TSDB_FILE_DLMT);
for (int32_t iDelData = 0; iDelData < taosArrayGetSize(aDelData); iDelData++) {
- n += tPutDelData(*ppBuf + n, taosArrayGet(aDelData, iDelData));
+ n += tPutDelData(pWriter->aBuf[0] + n, taosArrayGet(aDelData, iDelData));
}
- taosCalcChecksumAppend(0, *ppBuf, size);
+ taosCalcChecksumAppend(0, pWriter->aBuf[0], size);
ASSERT(n + sizeof(TSCKSUM) == size);
// write
- n = taosWriteFile(pWriter->pWriteH, *ppBuf, size);
+ n = taosWriteFile(pWriter->pWriteH, pWriter->aBuf[0], size);
if (n < 0) {
code = TAOS_SYSTEM_ERROR(errno);
goto _err;
@@ -129,48 +128,42 @@ int32_t tsdbWriteDelData(SDelFWriter *pWriter, SArray *aDelData, uint8_t **ppBuf
pDelIdx->size = size;
pWriter->fDel.size += size;
- tFree(pBuf);
return code;
_err:
tsdbError("vgId:%d, failed to write del data since %s", TD_VID(pWriter->pTsdb->pVnode), tstrerror(code));
- tFree(pBuf);
return code;
}
-int32_t tsdbWriteDelIdx(SDelFWriter *pWriter, SArray *aDelIdx, uint8_t **ppBuf) {
+int32_t tsdbWriteDelIdx(SDelFWriter *pWriter, SArray *aDelIdx) {
int32_t code = 0;
int64_t size;
int64_t n;
- uint8_t *pBuf = NULL;
SDelIdx *pDelIdx;
- if (!ppBuf) ppBuf = &pBuf;
-
// prepare
- size = 0;
- size += tPutU32(NULL, TSDB_FILE_DLMT);
+ size = sizeof(uint32_t);
for (int32_t iDelIdx = 0; iDelIdx < taosArrayGetSize(aDelIdx); iDelIdx++) {
size += tPutDelIdx(NULL, taosArrayGet(aDelIdx, iDelIdx));
}
size += sizeof(TSCKSUM);
// alloc
- code = tRealloc(ppBuf, size);
+ code = tRealloc(&pWriter->aBuf[0], size);
if (code) goto _err;
// build
n = 0;
- n += tPutU32(*ppBuf + n, TSDB_FILE_DLMT);
+ n += tPutU32(pWriter->aBuf[0] + n, TSDB_FILE_DLMT);
for (int32_t iDelIdx = 0; iDelIdx < taosArrayGetSize(aDelIdx); iDelIdx++) {
- n += tPutDelIdx(*ppBuf + n, taosArrayGet(aDelIdx, iDelIdx));
+ n += tPutDelIdx(pWriter->aBuf[0] + n, taosArrayGet(aDelIdx, iDelIdx));
}
- taosCalcChecksumAppend(0, *ppBuf, size);
+ taosCalcChecksumAppend(0, pWriter->aBuf[0], size);
ASSERT(n + sizeof(TSCKSUM) == size);
// write
- n = taosWriteFile(pWriter->pWriteH, *ppBuf, size);
+ n = taosWriteFile(pWriter->pWriteH, pWriter->aBuf[0], size);
if (n < 0) {
code = TAOS_SYSTEM_ERROR(errno);
goto _err;
@@ -180,12 +173,10 @@ int32_t tsdbWriteDelIdx(SDelFWriter *pWriter, SArray *aDelIdx, uint8_t **ppBuf)
pWriter->fDel.offset = pWriter->fDel.size;
pWriter->fDel.size += size;
- tFree(pBuf);
return code;
_err:
tsdbError("vgId:%d, write del idx failed since %s", TD_VID(pWriter->pTsdb->pVnode), tstrerror(code));
- tFree(pBuf);
return code;
}
@@ -225,9 +216,11 @@ struct SDelFReader {
STsdb *pTsdb;
SDelFile fDel;
TdFilePtr pReadH;
+
+ uint8_t *aBuf[1];
};
-int32_t tsdbDelFReaderOpen(SDelFReader **ppReader, SDelFile *pFile, STsdb *pTsdb, uint8_t **ppBuf) {
+int32_t tsdbDelFReaderOpen(SDelFReader **ppReader, SDelFile *pFile, STsdb *pTsdb) {
int32_t code = 0;
char fname[TSDB_FILENAME_LEN];
SDelFReader *pDelFReader;
@@ -252,32 +245,6 @@ int32_t tsdbDelFReaderOpen(SDelFReader **ppReader, SDelFile *pFile, STsdb *pTsdb
goto _err;
}
-#if 0
- // load and check hdr if buffer is given
- if (ppBuf) {
- code = tRealloc(ppBuf, TSDB_FHDR_SIZE);
- if (code) {
- goto _err;
- }
-
- n = taosReadFile(pDelFReader->pReadH, *ppBuf, TSDB_FHDR_SIZE);
- if (n < 0) {
- code = TAOS_SYSTEM_ERROR(errno);
- goto _err;
- } else if (n < TSDB_FHDR_SIZE) {
- code = TSDB_CODE_FILE_CORRUPTED;
- goto _err;
- }
-
- if (!taosCheckChecksumWhole(*ppBuf, TSDB_FHDR_SIZE)) {
- code = TSDB_CODE_FILE_CORRUPTED;
- goto _err;
- }
-
- // TODO: check the content
- }
-#endif
-
_exit:
*ppReader = pDelFReader;
return code;
@@ -297,6 +264,9 @@ int32_t tsdbDelFReaderClose(SDelFReader **ppReader) {
code = TAOS_SYSTEM_ERROR(errno);
goto _exit;
}
+ for (int32_t iBuf = 0; iBuf < sizeof(pReader->aBuf) / sizeof(uint8_t *); iBuf++) {
+ tFree(pReader->aBuf[iBuf]);
+ }
taosMemoryFree(pReader);
}
*ppReader = NULL;
@@ -305,16 +275,13 @@ _exit:
return code;
}
-int32_t tsdbReadDelData(SDelFReader *pReader, SDelIdx *pDelIdx, SArray *aDelData, uint8_t **ppBuf) {
- int32_t code = 0;
- int64_t offset = pDelIdx->offset;
- int64_t size = pDelIdx->size;
- int64_t n;
- uint8_t *pBuf = NULL;
- SBlockDataHdr *pHdr;
- SDelData *pDelData = &(SDelData){0};
+int32_t tsdbReadDelData(SDelFReader *pReader, SDelIdx *pDelIdx, SArray *aDelData) {
+ int32_t code = 0;
+ int64_t offset = pDelIdx->offset;
+ int64_t size = pDelIdx->size;
+ int64_t n;
- if (!ppBuf) ppBuf = &pBuf;
+ taosArrayClear(aDelData);
// seek
if (taosLSeekFile(pReader->pReadH, offset, SEEK_SET) < 0) {
@@ -323,11 +290,11 @@ int32_t tsdbReadDelData(SDelFReader *pReader, SDelIdx *pDelIdx, SArray *aDelData
}
// alloc
- code = tRealloc(ppBuf, size);
+ code = tRealloc(&pReader->aBuf[0], size);
if (code) goto _err;
// read
- n = taosReadFile(pReader->pReadH, *ppBuf, size);
+ n = taosReadFile(pReader->pReadH, pReader->aBuf[0], size);
if (n < 0) {
code = TAOS_SYSTEM_ERROR(errno);
goto _err;
@@ -337,23 +304,21 @@ int32_t tsdbReadDelData(SDelFReader *pReader, SDelIdx *pDelIdx, SArray *aDelData
}
// check
- if (!taosCheckChecksumWhole(*ppBuf, size)) {
+ if (!taosCheckChecksumWhole(pReader->aBuf[0], size)) {
code = TSDB_CODE_FILE_CORRUPTED;
goto _err;
}
// // decode
n = 0;
- pHdr = (SBlockDataHdr *)(*ppBuf + n);
- ASSERT(pHdr->delimiter == TSDB_FILE_DLMT);
- ASSERT(pHdr->suid == pDelIdx->suid);
- ASSERT(pHdr->uid == pDelIdx->uid);
- n += sizeof(*pHdr);
- taosArrayClear(aDelData);
- while (n < size - sizeof(TSCKSUM)) {
- n += tGetDelData(*ppBuf + n, pDelData);
- if (taosArrayPush(aDelData, pDelData) == NULL) {
+ uint32_t delimiter;
+ n += tGetU32(pReader->aBuf[0] + n, &delimiter);
+ while (n < size - sizeof(TSCKSUM)) {
+ SDelData delData;
+ n += tGetDelData(pReader->aBuf[0] + n, &delData);
+
+ if (taosArrayPush(aDelData, &delData) == NULL) {
code = TSDB_CODE_OUT_OF_MEMORY;
goto _err;
}
@@ -361,25 +326,20 @@ int32_t tsdbReadDelData(SDelFReader *pReader, SDelIdx *pDelIdx, SArray *aDelData
ASSERT(n == size - sizeof(TSCKSUM));
- tFree(pBuf);
return code;
_err:
tsdbError("vgId:%d, read del data failed since %s", TD_VID(pReader->pTsdb->pVnode), tstrerror(code));
- tFree(pBuf);
return code;
}
-int32_t tsdbReadDelIdx(SDelFReader *pReader, SArray *aDelIdx, uint8_t **ppBuf) {
- int32_t code = 0;
- int32_t n;
- int64_t offset = pReader->fDel.offset;
- int64_t size = pReader->fDel.size - offset;
- uint32_t delimiter;
- uint8_t *pBuf = NULL;
- SDelIdx *pDelIdx = &(SDelIdx){0};
+int32_t tsdbReadDelIdx(SDelFReader *pReader, SArray *aDelIdx) {
+ int32_t code = 0;
+ int32_t n;
+ int64_t offset = pReader->fDel.offset;
+ int64_t size = pReader->fDel.size - offset;
- if (!ppBuf) ppBuf = &pBuf;
+ taosArrayClear(aDelIdx);
// seek
if (taosLSeekFile(pReader->pReadH, offset, SEEK_SET) < 0) {
@@ -388,11 +348,11 @@ int32_t tsdbReadDelIdx(SDelFReader *pReader, SArray *aDelIdx, uint8_t **ppBuf) {
}
// alloc
- code = tRealloc(ppBuf, size);
+ code = tRealloc(&pReader->aBuf[0], size);
if (code) goto _err;
// read
- n = taosReadFile(pReader->pReadH, *ppBuf, size);
+ n = taosReadFile(pReader->pReadH, pReader->aBuf[0], size);
if (n < 0) {
code = TAOS_SYSTEM_ERROR(errno);
goto _err;
@@ -402,21 +362,23 @@ int32_t tsdbReadDelIdx(SDelFReader *pReader, SArray *aDelIdx, uint8_t **ppBuf) {
}
// check
- if (!taosCheckChecksumWhole(*ppBuf, size)) {
+ if (!taosCheckChecksumWhole(pReader->aBuf[0], size)) {
code = TSDB_CODE_FILE_CORRUPTED;
goto _err;
}
// decode
n = 0;
- n += tGetU32(*ppBuf + n, &delimiter);
+ uint32_t delimiter;
+ n += tGetU32(pReader->aBuf[0] + n, &delimiter);
ASSERT(delimiter == TSDB_FILE_DLMT);
- taosArrayClear(aDelIdx);
while (n < size - sizeof(TSCKSUM)) {
- n += tGetDelIdx(*ppBuf + n, pDelIdx);
+ SDelIdx delIdx;
- if (taosArrayPush(aDelIdx, pDelIdx) == NULL) {
+ n += tGetDelIdx(pReader->aBuf[0] + n, &delIdx);
+
+ if (taosArrayPush(aDelIdx, &delIdx) == NULL) {
code = TSDB_CODE_OUT_OF_MEMORY;
goto _err;
}
@@ -424,12 +386,10 @@ int32_t tsdbReadDelIdx(SDelFReader *pReader, SArray *aDelIdx, uint8_t **ppBuf) {
ASSERT(n == size - sizeof(TSCKSUM));
- tFree(pBuf);
return code;
_err:
tsdbError("vgId:%d, read del idx failed since %s", TD_VID(pReader->pTsdb->pVnode), tstrerror(code));
- tFree(pBuf);
return code;
}
@@ -441,6 +401,8 @@ struct SDataFReader {
TdFilePtr pDataFD;
TdFilePtr pLastFD;
TdFilePtr pSmaFD;
+
+ uint8_t *aBuf[3];
};
int32_t tsdbDataFReaderOpen(SDataFReader **ppReader, STsdb *pTsdb, SDFileSet *pSet) {
@@ -523,6 +485,10 @@ int32_t tsdbDataFReaderClose(SDataFReader **ppReader) {
goto _err;
}
+ for (int32_t iBuf = 0; iBuf < sizeof((*ppReader)->aBuf) / sizeof(uint8_t *); iBuf++) {
+ tFree((*ppReader)->aBuf[iBuf]);
+ }
+
taosMemoryFree(*ppReader);
_exit:
@@ -534,19 +500,20 @@ _err:
return code;
}
-int32_t tsdbReadBlockIdx(SDataFReader *pReader, SArray *aBlockIdx, uint8_t **ppBuf) {
- int32_t code = 0;
- int64_t offset = pReader->pSet->pHeadF->offset;
- int64_t size = pReader->pSet->pHeadF->size - offset;
- uint8_t *pBuf = NULL;
- int64_t n;
- uint32_t delimiter;
- SBlockIdx blockIdx;
+int32_t tsdbReadBlockIdx(SDataFReader *pReader, SArray *aBlockIdx) {
+ int32_t code = 0;
+ int64_t offset = pReader->pSet->pHeadF->offset;
+ int64_t size = pReader->pSet->pHeadF->size - offset;
+ int64_t n;
+ uint32_t delimiter;
- if (!ppBuf) ppBuf = &pBuf;
+ taosArrayClear(aBlockIdx);
+ if (size == 0) {
+ goto _exit;
+ }
// alloc
- code = tRealloc(ppBuf, size);
+ code = tRealloc(&pReader->aBuf[0], size);
if (code) goto _err;
// seek
@@ -556,7 +523,7 @@ int32_t tsdbReadBlockIdx(SDataFReader *pReader, SArray *aBlockIdx, uint8_t **ppB
}
// read
- n = taosReadFile(pReader->pHeadFD, *ppBuf, size);
+ n = taosReadFile(pReader->pHeadFD, pReader->aBuf[0], size);
if (n < 0) {
code = TAOS_SYSTEM_ERROR(errno);
goto _err;
@@ -566,19 +533,19 @@ int32_t tsdbReadBlockIdx(SDataFReader *pReader, SArray *aBlockIdx, uint8_t **ppB
}
// check
- if (!taosCheckChecksumWhole(*ppBuf, size)) {
+ if (!taosCheckChecksumWhole(pReader->aBuf[0], size)) {
code = TSDB_CODE_FILE_CORRUPTED;
goto _err;
}
// decode
n = 0;
- n = tGetU32(*ppBuf + n, &delimiter);
+ n = tGetU32(pReader->aBuf[0] + n, &delimiter);
ASSERT(delimiter == TSDB_FILE_DLMT);
- taosArrayClear(aBlockIdx);
while (n < size - sizeof(TSCKSUM)) {
- n += tGetBlockIdx(*ppBuf + n, &blockIdx);
+ SBlockIdx blockIdx;
+ n += tGetBlockIdx(pReader->aBuf[0] + n, &blockIdx);
if (taosArrayPush(aBlockIdx, &blockIdx) == NULL) {
code = TSDB_CODE_OUT_OF_MEMORY;
@@ -588,28 +555,86 @@ int32_t tsdbReadBlockIdx(SDataFReader *pReader, SArray *aBlockIdx, uint8_t **ppB
ASSERT(n + sizeof(TSCKSUM) == size);
- tFree(pBuf);
+_exit:
return code;
_err:
tsdbError("vgId:%d, read block idx failed since %s", TD_VID(pReader->pTsdb->pVnode), tstrerror(code));
- tFree(pBuf);
return code;
}
-int32_t tsdbReadBlock(SDataFReader *pReader, SBlockIdx *pBlockIdx, SMapData *mBlock, uint8_t **ppBuf) {
- int32_t code = 0;
- int64_t offset = pBlockIdx->offset;
- int64_t size = pBlockIdx->size;
- uint8_t *pBuf = NULL;
- int64_t n;
- int64_t tn;
- SBlockDataHdr hdr;
+int32_t tsdbReadBlockL(SDataFReader *pReader, SArray *aBlockL) {
+ int32_t code = 0;
+ int64_t offset = pReader->pSet->pLastF->offset;
+ int64_t size = pReader->pSet->pLastF->size - offset;
+ int64_t n;
+ uint32_t delimiter;
- if (!ppBuf) ppBuf = &pBuf;
+ taosArrayClear(aBlockL);
+ if (size == 0) {
+ goto _exit;
+ }
// alloc
- code = tRealloc(ppBuf, size);
+ code = tRealloc(&pReader->aBuf[0], size);
+ if (code) goto _err;
+
+ // seek
+ if (taosLSeekFile(pReader->pLastFD, offset, SEEK_SET) < 0) {
+ code = TAOS_SYSTEM_ERROR(errno);
+ goto _err;
+ }
+
+ // read
+ n = taosReadFile(pReader->pLastFD, pReader->aBuf[0], size);
+ if (n < 0) {
+ code = TAOS_SYSTEM_ERROR(errno);
+ goto _err;
+ } else if (n < size) {
+ code = TSDB_CODE_FILE_CORRUPTED;
+ goto _err;
+ }
+
+ // check
+ if (!taosCheckChecksumWhole(pReader->aBuf[0], size)) {
+ code = TSDB_CODE_FILE_CORRUPTED;
+ goto _err;
+ }
+
+ // decode
+ n = 0;
+ n = tGetU32(pReader->aBuf[0] + n, &delimiter);
+ ASSERT(delimiter == TSDB_FILE_DLMT);
+
+ while (n < size - sizeof(TSCKSUM)) {
+ SBlockL blockl;
+ n += tGetBlockL(pReader->aBuf[0] + n, &blockl);
+
+ if (taosArrayPush(aBlockL, &blockl) == NULL) {
+ code = TSDB_CODE_OUT_OF_MEMORY;
+ goto _err;
+ }
+ }
+
+ ASSERT(n + sizeof(TSCKSUM) == size);
+
+_exit:
+ return code;
+
+_err:
+ tsdbError("vgId:%d read blockl failed since %s", TD_VID(pReader->pTsdb->pVnode), tstrerror(code));
+ return code;
+}
+
+int32_t tsdbReadBlock(SDataFReader *pReader, SBlockIdx *pBlockIdx, SMapData *mBlock) {
+ int32_t code = 0;
+ int64_t offset = pBlockIdx->offset;
+ int64_t size = pBlockIdx->size;
+ int64_t n;
+ int64_t tn;
+
+ // alloc
+ code = tRealloc(&pReader->aBuf[0], size);
if (code) goto _err;
// seek
@@ -619,7 +644,7 @@ int32_t tsdbReadBlock(SDataFReader *pReader, SBlockIdx *pBlockIdx, SMapData *mBl
}
// read
- n = taosReadFile(pReader->pHeadFD, *ppBuf, size);
+ n = taosReadFile(pReader->pHeadFD, pReader->aBuf[0], size);
if (n < 0) {
code = TAOS_SYSTEM_ERROR(errno);
goto _err;
@@ -629,19 +654,19 @@ int32_t tsdbReadBlock(SDataFReader *pReader, SBlockIdx *pBlockIdx, SMapData *mBl
}
// check
- if (!taosCheckChecksumWhole(*ppBuf, size)) {
+ if (!taosCheckChecksumWhole(pReader->aBuf[0], size)) {
code = TSDB_CODE_FILE_CORRUPTED;
goto _err;
}
// decode
- hdr = *(SBlockDataHdr *)(*ppBuf);
- ASSERT(hdr.delimiter == TSDB_FILE_DLMT);
- ASSERT(hdr.suid == pBlockIdx->suid);
- ASSERT(hdr.uid == pBlockIdx->uid);
+ n = 0;
- n = sizeof(hdr);
- tn = tGetMapData(*ppBuf + n, mBlock);
+ uint32_t delimiter;
+ n += tGetU32(pReader->aBuf[0] + n, &delimiter);
+ ASSERT(delimiter == TSDB_FILE_DLMT);
+
+ tn = tGetMapData(pReader->aBuf[0] + n, mBlock);
if (tn < 0) {
code = TSDB_CODE_OUT_OF_MEMORY;
goto _err;
@@ -649,535 +674,38 @@ int32_t tsdbReadBlock(SDataFReader *pReader, SBlockIdx *pBlockIdx, SMapData *mBl
n += tn;
ASSERT(n + sizeof(TSCKSUM) == size);
- tFree(pBuf);
return code;
_err:
tsdbError("vgId:%d, read block failed since %s", TD_VID(pReader->pTsdb->pVnode), tstrerror(code));
- tFree(pBuf);
return code;
}
-static int32_t tsdbReadBlockDataKey(SBlockData *pBlockData, SSubBlock *pSubBlock, uint8_t *pBuf, uint8_t **ppBuf) {
- int32_t code = 0;
- int64_t size = pSubBlock->szVersion + pSubBlock->szTSKEY + sizeof(TSCKSUM);
- int64_t n;
+int32_t tsdbReadBlockSma(SDataFReader *pReader, SBlock *pBlock, SArray *aColumnDataAgg) {
+ int32_t code = 0;
+ SSmaInfo *pSmaInfo = &pBlock->smaInfo;
- if (!taosCheckChecksumWhole(pBuf, size)) {
- code = TSDB_CODE_FILE_CORRUPTED;
- goto _err;
- }
+ ASSERT(pSmaInfo->size > 0);
- code = tRealloc((uint8_t **)&pBlockData->aVersion, sizeof(int64_t) * pSubBlock->nRow);
- if (code) goto _err;
- code = tRealloc((uint8_t **)&pBlockData->aTSKEY, sizeof(TSKEY) * pSubBlock->nRow);
- if (code) goto _err;
+ taosArrayClear(aColumnDataAgg);
- if (pSubBlock->cmprAlg == NO_COMPRESSION) {
- ASSERT(pSubBlock->szVersion == sizeof(int64_t) * pSubBlock->nRow);
- ASSERT(pSubBlock->szTSKEY == sizeof(TSKEY) * pSubBlock->nRow);
-
- // VERSION
- memcpy(pBlockData->aVersion, pBuf, pSubBlock->szVersion);
-
- // TSKEY
- memcpy(pBlockData->aTSKEY, pBuf + pSubBlock->szVersion, pSubBlock->szTSKEY);
- } else {
- size = sizeof(int64_t) * pSubBlock->nRow + COMP_OVERFLOW_BYTES;
- if (pSubBlock->cmprAlg == TWO_STAGE_COMP) {
- code = tRealloc(ppBuf, size);
- if (code) goto _err;
- }
-
- // VERSION
- n = tsDecompressBigint(pBuf, pSubBlock->szVersion, pSubBlock->nRow, (char *)pBlockData->aVersion,
- sizeof(int64_t) * pSubBlock->nRow, pSubBlock->cmprAlg, *ppBuf, size);
- if (n < 0) {
- code = TSDB_CODE_COMPRESS_ERROR;
- goto _err;
- }
-
- // TSKEY
- n = tsDecompressTimestamp(pBuf + pSubBlock->szVersion, pSubBlock->szTSKEY, pSubBlock->nRow,
- (char *)pBlockData->aTSKEY, sizeof(TSKEY) * pSubBlock->nRow, pSubBlock->cmprAlg, *ppBuf,
- size);
- if (n < 0) {
- code = TSDB_CODE_COMPRESS_ERROR;
- goto _err;
- }
- }
-
- return code;
-
-_err:
- return code;
-}
-
-static int32_t tsdbReadColDataImpl(SSubBlock *pSubBlock, SBlockCol *pBlockCol, SColData *pColData, uint8_t *pBuf,
- uint8_t **ppBuf) {
- int32_t code = 0;
- int64_t size;
- int64_t n;
-
- if (!taosCheckChecksumWhole(pBuf, pBlockCol->szBitmap + pBlockCol->szOffset + pBlockCol->szValue + sizeof(TSCKSUM))) {
- code = TSDB_CODE_FILE_CORRUPTED;
- goto _err;
- }
-
- pColData->nVal = pSubBlock->nRow;
- pColData->flag = pBlockCol->flag;
-
- // BITMAP
- if (pBlockCol->flag != HAS_VALUE) {
- ASSERT(pBlockCol->szBitmap);
-
- size = BIT2_SIZE(pColData->nVal);
- code = tRealloc(&pColData->pBitMap, size);
- if (code) goto _err;
-
- code = tRealloc(ppBuf, size + COMP_OVERFLOW_BYTES);
- if (code) goto _err;
-
- n = tsDecompressTinyint(pBuf, pBlockCol->szBitmap, size, pColData->pBitMap, size, TWO_STAGE_COMP, *ppBuf,
- size + COMP_OVERFLOW_BYTES);
- if (n <= 0) {
- code = TSDB_CODE_COMPRESS_ERROR;
- goto _err;
- }
-
- ASSERT(n == size);
- } else {
- ASSERT(pBlockCol->szBitmap == 0);
- }
- pBuf = pBuf + pBlockCol->szBitmap;
-
- // OFFSET
- if (IS_VAR_DATA_TYPE(pColData->type)) {
- ASSERT(pBlockCol->szOffset);
-
- size = sizeof(int32_t) * pColData->nVal;
- code = tRealloc((uint8_t **)&pColData->aOffset, size);
- if (code) goto _err;
-
- code = tRealloc(ppBuf, size + COMP_OVERFLOW_BYTES);
- if (code) goto _err;
-
- n = tsDecompressInt(pBuf, pBlockCol->szOffset, pColData->nVal, (char *)pColData->aOffset, size, TWO_STAGE_COMP,
- *ppBuf, size + COMP_OVERFLOW_BYTES);
- if (n <= 0) {
- code = TSDB_CODE_COMPRESS_ERROR;
- goto _err;
- }
-
- ASSERT(n == size);
- } else {
- ASSERT(pBlockCol->szOffset == 0);
- }
- pBuf = pBuf + pBlockCol->szOffset;
-
- // VALUE
- pColData->nData = pBlockCol->szOrigin;
-
- code = tRealloc(&pColData->pData, pColData->nData);
- if (code) goto _err;
-
- if (pSubBlock->cmprAlg == NO_COMPRESSION) {
- memcpy(pColData->pData, pBuf, pColData->nData);
- } else {
- if (pSubBlock->cmprAlg == TWO_STAGE_COMP) {
- code = tRealloc(ppBuf, pColData->nData + COMP_OVERFLOW_BYTES);
- if (code) goto _err;
- }
-
- n = tDataTypes[pBlockCol->type].decompFunc(pBuf, pBlockCol->szValue, pSubBlock->nRow, pColData->pData,
- pColData->nData, pSubBlock->cmprAlg, *ppBuf,
- pColData->nData + COMP_OVERFLOW_BYTES);
- if (n < 0) {
- code = TSDB_CODE_COMPRESS_ERROR;
- goto _err;
- }
-
- ASSERT(n == pColData->nData);
- }
-
- return code;
-
-_err:
- return code;
-}
-
-static int32_t tsdbReadBlockCol(SSubBlock *pSubBlock, uint8_t *p, SArray *aBlockCol) {
- int32_t code = 0;
- int32_t n = 0;
- SBlockCol blockCol;
- SBlockCol *pBlockCol = &blockCol;
-
- if (!taosCheckChecksumWhole(p, pSubBlock->szBlockCol + sizeof(TSCKSUM))) {
- code = TSDB_CODE_FILE_CORRUPTED;
- goto _err;
- }
-
- n += sizeof(SBlockDataHdr);
- while (n < pSubBlock->szBlockCol) {
- n += tGetBlockCol(p + n, pBlockCol);
-
- if (taosArrayPush(aBlockCol, pBlockCol) == NULL) {
- code = TSDB_CODE_OUT_OF_MEMORY;
- goto _err;
- }
- }
-
- ASSERT(n == pSubBlock->szBlockCol);
-
- return code;
-
-_err:
- return code;
-}
-
-static int32_t tsdbReadSubColData(SDataFReader *pReader, SBlockIdx *pBlockIdx, SBlock *pBlock, int32_t iSubBlock,
- int16_t *aColId, int32_t nCol, SBlockData *pBlockData, uint8_t **ppBuf1,
- uint8_t **ppBuf2) {
- TdFilePtr pFD = pBlock->last ? pReader->pLastFD : pReader->pDataFD;
- SSubBlock *pSubBlock = &pBlock->aSubBlock[iSubBlock];
- SArray *aBlockCol = NULL;
- int32_t code = 0;
- int64_t offset;
- int64_t size;
- int64_t n;
-
- tBlockDataReset(pBlockData);
- pBlockData->nRow = pSubBlock->nRow;
-
- // TSDBKEY and SBlockCol
- if (nCol == 1) {
- offset = pSubBlock->offset + pSubBlock->szBlockCol + sizeof(TSCKSUM);
- size = pSubBlock->szVersion + pSubBlock->szTSKEY + sizeof(TSCKSUM);
- } else {
- offset = pSubBlock->offset;
- size = pSubBlock->szBlockCol + sizeof(TSCKSUM) + pSubBlock->szVersion + pSubBlock->szTSKEY + sizeof(TSCKSUM);
- }
-
- code = tRealloc(ppBuf1, size);
- if (code) goto _err;
-
- n = taosLSeekFile(pFD, offset, SEEK_SET);
- if (n < 0) {
- code = TAOS_SYSTEM_ERROR(errno);
- goto _err;
- }
-
- n = taosReadFile(pFD, *ppBuf1, size);
- if (n < 0) {
- code = TAOS_SYSTEM_ERROR(errno);
- goto _err;
- } else if (n < size) {
- code = TSDB_CODE_FILE_CORRUPTED;
- goto _err;
- }
-
- if (nCol == 1) {
- code = tsdbReadBlockDataKey(pBlockData, pSubBlock, *ppBuf1, ppBuf2);
- if (code) goto _err;
-
- goto _exit;
- } else {
- aBlockCol = taosArrayInit(0, sizeof(SBlockCol));
- if (aBlockCol == NULL) {
- code = TSDB_CODE_OUT_OF_MEMORY;
- goto _err;
- }
-
- code = tsdbReadBlockCol(pSubBlock, *ppBuf1, aBlockCol);
- if (code) goto _err;
-
- code = tsdbReadBlockDataKey(pBlockData, pSubBlock, *ppBuf1 + pSubBlock->szBlockCol + sizeof(TSCKSUM), ppBuf2);
- if (code) goto _err;
- }
-
- for (int32_t iCol = 1; iCol < nCol; iCol++) {
- void *p = taosArraySearch(aBlockCol, &(SBlockCol){.cid = aColId[iCol]}, tBlockColCmprFn, TD_EQ);
-
- if (p) {
- SBlockCol *pBlockCol = (SBlockCol *)p;
- SColData *pColData;
-
- ASSERT(pBlockCol->flag && pBlockCol->flag != HAS_NONE);
-
- code = tBlockDataAddColData(pBlockData, taosArrayGetSize(pBlockData->aIdx), &pColData);
- if (code) goto _err;
-
- tColDataInit(pColData, pBlockCol->cid, pBlockCol->type, pBlockCol->smaOn);
- if (pBlockCol->flag == HAS_NULL) {
- for (int32_t iRow = 0; iRow < pSubBlock->nRow; iRow++) {
- code = tColDataAppendValue(pColData, &COL_VAL_NULL(pBlockCol->cid, pBlockCol->type));
- if (code) goto _err;
- }
- } else {
- offset = pSubBlock->offset + pSubBlock->szBlockCol + sizeof(TSCKSUM) + pSubBlock->szVersion +
- pSubBlock->szTSKEY + sizeof(TSCKSUM) + pBlockCol->offset;
- size = pBlockCol->szBitmap + pBlockCol->szOffset + pBlockCol->szValue + sizeof(TSCKSUM);
-
- code = tRealloc(ppBuf1, size);
- if (code) goto _err;
-
- // seek
- n = taosLSeekFile(pFD, offset, SEEK_SET);
- if (n < 0) {
- code = TAOS_SYSTEM_ERROR(errno);
- goto _err;
- }
-
- // read
- n = taosReadFile(pFD, *ppBuf1, size);
- if (n < 0) {
- code = TAOS_SYSTEM_ERROR(errno);
- goto _err;
- } else if (n < size) {
- code = TSDB_CODE_FILE_CORRUPTED;
- goto _err;
- }
-
- code = tsdbReadColDataImpl(pSubBlock, pBlockCol, pColData, *ppBuf1, ppBuf2);
- if (code) goto _err;
- }
- }
- }
-
-_exit:
- taosArrayDestroy(aBlockCol);
- return code;
-
-_err:
- taosArrayDestroy(aBlockCol);
- return code;
-}
-
-int32_t tsdbReadColData(SDataFReader *pReader, SBlockIdx *pBlockIdx, SBlock *pBlock, int16_t *aColId, int32_t nCol,
- SBlockData *pBlockData, uint8_t **ppBuf1, uint8_t **ppBuf2) {
- int32_t code = 0;
- uint8_t *pBuf1 = NULL;
- uint8_t *pBuf2 = NULL;
-
- ASSERT(aColId[0] == PRIMARYKEY_TIMESTAMP_COL_ID);
-
- if (!ppBuf1) ppBuf1 = &pBuf1;
- if (!ppBuf2) ppBuf2 = &pBuf2;
-
- code = tsdbReadSubColData(pReader, pBlockIdx, pBlock, 0, aColId, nCol, pBlockData, ppBuf1, ppBuf2);
- if (code) goto _err;
-
- if (pBlock->nSubBlock > 1) {
- SBlockData *pBlockData1 = &(SBlockData){0};
- SBlockData *pBlockData2 = &(SBlockData){0};
-
- tBlockDataInit(pBlockData1);
- tBlockDataInit(pBlockData2);
- for (int32_t iSubBlock = 1; iSubBlock < pBlock->nSubBlock; iSubBlock++) {
- code = tsdbReadSubColData(pReader, pBlockIdx, pBlock, iSubBlock, aColId, nCol, pBlockData1, ppBuf1, ppBuf2);
- if (code) goto _err;
-
- code = tBlockDataCopy(pBlockData, pBlockData2);
- if (code) {
- tBlockDataClear(pBlockData1, 1);
- tBlockDataClear(pBlockData2, 1);
- goto _err;
- }
-
- code = tBlockDataMerge(pBlockData1, pBlockData2, pBlockData);
- if (code) {
- tBlockDataClear(pBlockData1, 1);
- tBlockDataClear(pBlockData2, 1);
- goto _err;
- }
- }
-
- tBlockDataClear(pBlockData1, 1);
- tBlockDataClear(pBlockData2, 1);
- }
-
- tFree(pBuf1);
- tFree(pBuf2);
- return code;
-
-_err:
- tsdbError("vgId:%d, tsdb read col data failed since %s", TD_VID(pReader->pTsdb->pVnode), tstrerror(code));
- tFree(pBuf1);
- tFree(pBuf2);
- return code;
-}
-
-static int32_t tsdbReadSubBlockData(SDataFReader *pReader, SBlockIdx *pBlockIdx, SBlock *pBlock, int32_t iSubBlock,
- SBlockData *pBlockData, uint8_t **ppBuf1, uint8_t **ppBuf2) {
- int32_t code = 0;
- uint8_t *p;
- int64_t size;
- int64_t n;
- TdFilePtr pFD = pBlock->last ? pReader->pLastFD : pReader->pDataFD;
- SSubBlock *pSubBlock = &pBlock->aSubBlock[iSubBlock];
- SArray *aBlockCol = NULL;
-
- tBlockDataReset(pBlockData);
-
- // realloc
- code = tRealloc(ppBuf1, pSubBlock->szBlock);
+ // alloc
+ int32_t size = pSmaInfo->size + sizeof(TSCKSUM);
+ code = tRealloc(&pReader->aBuf[0], size);
if (code) goto _err;
// seek
- n = taosLSeekFile(pFD, pSubBlock->offset, SEEK_SET);
+ int64_t n = taosLSeekFile(pReader->pSmaFD, pSmaInfo->offset, SEEK_SET);
if (n < 0) {
code = TAOS_SYSTEM_ERROR(errno);
goto _err;
- }
-
- // read
- n = taosReadFile(pFD, *ppBuf1, pSubBlock->szBlock);
- if (n < 0) {
- code = TAOS_SYSTEM_ERROR(errno);
- goto _err;
- } else if (n < pSubBlock->szBlock) {
+ } else if (n < pSmaInfo->offset) {
code = TSDB_CODE_FILE_CORRUPTED;
goto _err;
}
- pBlockData->nRow = pSubBlock->nRow;
-
- // TSDBKEY
- p = *ppBuf1 + pSubBlock->szBlockCol + sizeof(TSCKSUM);
- code = tsdbReadBlockDataKey(pBlockData, pSubBlock, p, ppBuf2);
- if (code) goto _err;
-
- // COLUMNS
- aBlockCol = taosArrayInit(0, sizeof(SBlockCol));
- if (aBlockCol == NULL) {
- code = TSDB_CODE_OUT_OF_MEMORY;
- goto _err;
- }
-
- code = tsdbReadBlockCol(pSubBlock, *ppBuf1, aBlockCol);
- if (code) goto _err;
-
- for (int32_t iBlockCol = 0; iBlockCol < taosArrayGetSize(aBlockCol); iBlockCol++) {
- SColData *pColData;
- SBlockCol *pBlockCol = (SBlockCol *)taosArrayGet(aBlockCol, iBlockCol);
-
- ASSERT(pBlockCol->flag && pBlockCol->flag != HAS_NONE);
-
- code = tBlockDataAddColData(pBlockData, iBlockCol, &pColData);
- if (code) goto _err;
-
- tColDataInit(pColData, pBlockCol->cid, pBlockCol->type, pBlockCol->smaOn);
- if (pBlockCol->flag == HAS_NULL) {
- for (int32_t iRow = 0; iRow < pSubBlock->nRow; iRow++) {
- code = tColDataAppendValue(pColData, &COL_VAL_NULL(pBlockCol->cid, pBlockCol->type));
- if (code) goto _err;
- }
- } else {
- p = *ppBuf1 + pSubBlock->szBlockCol + sizeof(TSCKSUM) + pSubBlock->szVersion + pSubBlock->szTSKEY +
- sizeof(TSCKSUM) + pBlockCol->offset;
- code = tsdbReadColDataImpl(pSubBlock, pBlockCol, pColData, p, ppBuf2);
- if (code) goto _err;
- }
- }
-
- taosArrayDestroy(aBlockCol);
- return code;
-
-_err:
- tsdbError("vgId:%d, tsdb read sub block data failed since %s", TD_VID(pReader->pTsdb->pVnode), tstrerror(code));
- taosArrayDestroy(aBlockCol);
- return code;
-}
-
-int32_t tsdbReadBlockData(SDataFReader *pReader, SBlockIdx *pBlockIdx, SBlock *pBlock, SBlockData *pBlockData,
- uint8_t **ppBuf1, uint8_t **ppBuf2) {
- int32_t code = 0;
- TdFilePtr pFD = pBlock->last ? pReader->pLastFD : pReader->pDataFD;
- uint8_t *pBuf1 = NULL;
- uint8_t *pBuf2 = NULL;
- int32_t iSubBlock;
-
- if (!ppBuf1) ppBuf1 = &pBuf1;
- if (!ppBuf2) ppBuf2 = &pBuf2;
-
- // read the first sub-block
- iSubBlock = 0;
- code = tsdbReadSubBlockData(pReader, pBlockIdx, pBlock, iSubBlock, pBlockData, ppBuf1, ppBuf2);
- if (code) goto _err;
-
- // read remain block data and do merg
- if (pBlock->nSubBlock > 1) {
- SBlockData *pBlockData1 = &(SBlockData){0};
- SBlockData *pBlockData2 = &(SBlockData){0};
-
- tBlockDataInit(pBlockData1);
- tBlockDataInit(pBlockData2);
- for (iSubBlock = 1; iSubBlock < pBlock->nSubBlock; iSubBlock++) {
- code = tsdbReadSubBlockData(pReader, pBlockIdx, pBlock, iSubBlock, pBlockData1, ppBuf1, ppBuf2);
- if (code) {
- tBlockDataClear(pBlockData1, 1);
- tBlockDataClear(pBlockData2, 1);
- goto _err;
- }
-
- code = tBlockDataCopy(pBlockData, pBlockData2);
- if (code) {
- tBlockDataClear(pBlockData1, 1);
- tBlockDataClear(pBlockData2, 1);
- goto _err;
- }
-
- // merge two block data
- code = tBlockDataMerge(pBlockData1, pBlockData2, pBlockData);
- if (code) {
- tBlockDataClear(pBlockData1, 1);
- tBlockDataClear(pBlockData2, 1);
- goto _err;
- }
- }
-
- tBlockDataClear(pBlockData1, 1);
- tBlockDataClear(pBlockData2, 1);
- }
-
- ASSERT(pBlock->nRow == pBlockData->nRow);
- ASSERT(tsdbKeyCmprFn(&pBlock->minKey, &TSDBROW_KEY(&tBlockDataFirstRow(pBlockData))) == 0);
- ASSERT(tsdbKeyCmprFn(&pBlock->maxKey, &TSDBROW_KEY(&tBlockDataLastRow(pBlockData))) == 0);
-
- if (pBuf1) tFree(pBuf1);
- if (pBuf2) tFree(pBuf2);
- return code;
-
-_err:
- tsdbError("vgId:%d, tsdb read block data failed since %s", TD_VID(pReader->pTsdb->pVnode), tstrerror(code));
- if (pBuf1) tFree(pBuf1);
- if (pBuf2) tFree(pBuf2);
- return code;
-}
-
-int32_t tsdbReadBlockSma(SDataFReader *pReader, SBlock *pBlock, SArray *aColumnDataAgg, uint8_t **ppBuf) {
- int32_t code = 0;
- TdFilePtr pFD = pReader->pSmaFD;
- int64_t offset = pBlock->aSubBlock[0].sOffset;
- int64_t size = pBlock->aSubBlock[0].nSma * sizeof(SColumnDataAgg) + sizeof(TSCKSUM);
- uint8_t *pBuf = NULL;
- int64_t n;
-
- ASSERT(tBlockHasSma(pBlock));
-
- if (!ppBuf) ppBuf = &pBuf;
- code = tRealloc(ppBuf, size);
- if (code) goto _err;
-
- // lseek
- n = taosLSeekFile(pFD, offset, SEEK_SET);
- if (n < 0) {
- code = TAOS_SYSTEM_ERROR(errno);
- goto _err;
- }
-
// read
- n = taosReadFile(pFD, *ppBuf, size);
+ n = taosReadFile(pReader->pSmaFD, pReader->aBuf[0], size);
if (n < 0) {
code = TAOS_SYSTEM_ERROR(errno);
goto _err;
@@ -1187,26 +715,202 @@ int32_t tsdbReadBlockSma(SDataFReader *pReader, SBlock *pBlock, SArray *aColumnD
}
// check
- if (!taosCheckChecksumWhole(*ppBuf, size)) {
+ if (!taosCheckChecksumWhole(pReader->aBuf[0], size)) {
code = TSDB_CODE_FILE_CORRUPTED;
goto _err;
}
// decode
- taosArrayClear(aColumnDataAgg);
- for (int32_t iSma = 0; iSma < pBlock->aSubBlock[0].nSma; iSma++) {
- if (taosArrayPush(aColumnDataAgg, &((SColumnDataAgg *)(*ppBuf))[iSma]) == NULL) {
+ n = 0;
+ while (n < pSmaInfo->size) {
+ SColumnDataAgg sma;
+
+ n += tGetColumnDataAgg(pReader->aBuf[0] + n, &sma);
+ if (taosArrayPush(aColumnDataAgg, &sma) == NULL) {
code = TSDB_CODE_OUT_OF_MEMORY;
goto _err;
}
}
- tFree(pBuf);
return code;
_err:
- tsdbError("vgId:%d, read block sma failed since %s", TD_VID(pReader->pTsdb->pVnode), tstrerror(code));
- tFree(pBuf);
+ tsdbError("vgId:%d tsdb read block sma failed since %s", TD_VID(pReader->pTsdb->pVnode), tstrerror(code));
+ return code;
+}
+
+static int32_t tsdbReadBlockDataImpl(SDataFReader *pReader, SBlockInfo *pBlkInfo, int8_t fromLast,
+ SBlockData *pBlockData) {
+ int32_t code = 0;
+
+ tBlockDataClear(pBlockData);
+
+ TdFilePtr pFD = fromLast ? pReader->pLastFD : pReader->pDataFD;
+
+ // uid + version + tskey
+ code = tsdbReadAndCheck(pFD, pBlkInfo->offset, &pReader->aBuf[0], pBlkInfo->szKey, 1);
+ if (code) goto _err;
+ SDiskDataHdr hdr;
+ uint8_t *p = pReader->aBuf[0] + tGetDiskDataHdr(pReader->aBuf[0], &hdr);
+
+ ASSERT(hdr.delimiter == TSDB_FILE_DLMT);
+ ASSERT(pBlockData->suid == hdr.suid);
+ ASSERT(pBlockData->uid == hdr.uid);
+
+ pBlockData->nRow = hdr.nRow;
+
+ // uid
+ if (hdr.uid == 0) {
+ ASSERT(hdr.szUid);
+ code = tsdbDecmprData(p, hdr.szUid, TSDB_DATA_TYPE_BIGINT, hdr.cmprAlg, (uint8_t **)&pBlockData->aUid,
+ sizeof(int64_t) * hdr.nRow, &pReader->aBuf[1]);
+ if (code) goto _err;
+ } else {
+ ASSERT(!hdr.szUid);
+ }
+ p += hdr.szUid;
+
+ // version
+ code = tsdbDecmprData(p, hdr.szVer, TSDB_DATA_TYPE_BIGINT, hdr.cmprAlg, (uint8_t **)&pBlockData->aVersion,
+ sizeof(int64_t) * hdr.nRow, &pReader->aBuf[1]);
+ if (code) goto _err;
+ p += hdr.szVer;
+
+ // TSKEY
+ code = tsdbDecmprData(p, hdr.szKey, TSDB_DATA_TYPE_TIMESTAMP, hdr.cmprAlg, (uint8_t **)&pBlockData->aTSKEY,
+ sizeof(TSKEY) * hdr.nRow, &pReader->aBuf[1]);
+ if (code) goto _err;
+ p += hdr.szKey;
+
+ ASSERT(p - pReader->aBuf[0] == pBlkInfo->szKey - sizeof(TSCKSUM));
+
+ // read and decode columns
+ if (taosArrayGetSize(pBlockData->aIdx) == 0) goto _exit;
+
+ if (hdr.szBlkCol > 0) {
+ int64_t offset = pBlkInfo->offset + pBlkInfo->szKey;
+ code = tsdbReadAndCheck(pFD, offset, &pReader->aBuf[0], hdr.szBlkCol + sizeof(TSCKSUM), 1);
+ if (code) goto _err;
+ }
+
+ SBlockCol blockCol = {.cid = 0};
+ SBlockCol *pBlockCol = &blockCol;
+ int32_t n = 0;
+
+ for (int32_t iColData = 0; iColData < taosArrayGetSize(pBlockData->aIdx); iColData++) {
+ SColData *pColData = tBlockDataGetColDataByIdx(pBlockData, iColData);
+
+ while (pBlockCol && pBlockCol->cid < pColData->cid) {
+ if (n < hdr.szBlkCol) {
+ n += tGetBlockCol(pReader->aBuf[0] + n, pBlockCol);
+ } else {
+ ASSERT(n == hdr.szBlkCol);
+ pBlockCol = NULL;
+ }
+ }
+
+ if (pBlockCol == NULL || pBlockCol->cid > pColData->cid) {
+ // add a lot of NONE
+ for (int32_t iRow = 0; iRow < hdr.nRow; iRow++) {
+ code = tColDataAppendValue(pColData, &COL_VAL_NONE(pColData->cid, pColData->type));
+ if (code) goto _err;
+ }
+ } else {
+ ASSERT(pBlockCol->type == pColData->type);
+ ASSERT(pBlockCol->flag && pBlockCol->flag != HAS_NONE);
+
+ if (pBlockCol->flag == HAS_NULL) {
+ // add a lot of NULL
+ for (int32_t iRow = 0; iRow < hdr.nRow; iRow++) {
+ code = tColDataAppendValue(pColData, &COL_VAL_NULL(pBlockCol->cid, pBlockCol->type));
+ if (code) goto _err;
+ }
+ } else {
+ // decode from binary
+ int64_t offset = pBlkInfo->offset + pBlkInfo->szKey + hdr.szBlkCol + sizeof(TSCKSUM) + pBlockCol->offset;
+ int32_t size = pBlockCol->szBitmap + pBlockCol->szOffset + pBlockCol->szValue + sizeof(TSCKSUM);
+
+ code = tsdbReadAndCheck(pFD, offset, &pReader->aBuf[1], size, 0);
+ if (code) goto _err;
+
+ code = tsdbDecmprColData(pReader->aBuf[1], pBlockCol, hdr.cmprAlg, hdr.nRow, pColData, &pReader->aBuf[2]);
+ if (code) goto _err;
+ }
+ }
+ }
+
+_exit:
+ return code;
+
+_err:
+ tsdbError("vgId:%d tsdb read block data impl failed since %s", TD_VID(pReader->pTsdb->pVnode), tstrerror(code));
+ return code;
+}
+
+int32_t tsdbReadDataBlock(SDataFReader *pReader, SBlock *pBlock, SBlockData *pBlockData) {
+ int32_t code = 0;
+
+ code = tsdbReadBlockDataImpl(pReader, &pBlock->aSubBlock[0], 0, pBlockData);
+ if (code) goto _err;
+
+ if (pBlock->nSubBlock > 1) {
+ SBlockData bData1;
+ SBlockData bData2;
+
+ // create
+ code = tBlockDataCreate(&bData1);
+ if (code) goto _err;
+ code = tBlockDataCreate(&bData2);
+ if (code) goto _err;
+
+ // init
+ tBlockDataInitEx(&bData1, pBlockData);
+ tBlockDataInitEx(&bData2, pBlockData);
+
+ for (int32_t iSubBlock = 1; iSubBlock < pBlock->nSubBlock; iSubBlock++) {
+ code = tsdbReadBlockDataImpl(pReader, &pBlock->aSubBlock[iSubBlock], 0, &bData1);
+ if (code) {
+ tBlockDataDestroy(&bData1, 1);
+ tBlockDataDestroy(&bData2, 1);
+ goto _err;
+ }
+
+ code = tBlockDataCopy(pBlockData, &bData2);
+ if (code) {
+ tBlockDataDestroy(&bData1, 1);
+ tBlockDataDestroy(&bData2, 1);
+ goto _err;
+ }
+
+ code = tBlockDataMerge(&bData1, &bData2, pBlockData);
+ if (code) {
+ tBlockDataDestroy(&bData1, 1);
+ tBlockDataDestroy(&bData2, 1);
+ goto _err;
+ }
+ }
+
+ tBlockDataDestroy(&bData1, 1);
+ tBlockDataDestroy(&bData2, 1);
+ }
+
+ return code;
+
+_err:
+ tsdbError("vgId:%d tsdb read data block failed since %s", TD_VID(pReader->pTsdb->pVnode), tstrerror(code));
+ return code;
+}
+
+int32_t tsdbReadLastBlock(SDataFReader *pReader, SBlockL *pBlockL, SBlockData *pBlockData) {
+ int32_t code = 0;
+
+ code = tsdbReadBlockDataImpl(pReader, &pBlockL->bInfo, 1, pBlockData);
+ if (code) goto _err;
+
+ return code;
+
+_err:
+ tsdbError("vgId:%d tsdb read last block failed since %s", TD_VID(pReader->pTsdb->pVnode), tstrerror(code));
return code;
}
@@ -1225,6 +929,7 @@ int32_t tsdbDataFWriterOpen(SDataFWriter **ppWriter, STsdb *pTsdb, SDFileSet *pS
code = TSDB_CODE_OUT_OF_MEMORY;
goto _err;
}
+ if (code) goto _err;
pWriter->pTsdb = pTsdb;
pWriter->wSet = (SDFileSet){.diskId = pSet->diskId,
.fid = pSet->fid,
@@ -1357,10 +1062,11 @@ _err:
int32_t tsdbDataFWriterClose(SDataFWriter **ppWriter, int8_t sync) {
int32_t code = 0;
- STsdb *pTsdb = (*ppWriter)->pTsdb;
+ STsdb *pTsdb = NULL;
if (*ppWriter == NULL) goto _exit;
+ pTsdb = (*ppWriter)->pTsdb;
if (sync) {
if (taosFsyncFile((*ppWriter)->pHeadFD) < 0) {
code = TAOS_SYSTEM_ERROR(errno);
@@ -1403,6 +1109,9 @@ int32_t tsdbDataFWriterClose(SDataFWriter **ppWriter, int8_t sync) {
goto _err;
}
+ for (int32_t iBuf = 0; iBuf < sizeof((*ppWriter)->aBuf) / sizeof(uint8_t *); iBuf++) {
+ tFree((*ppWriter)->aBuf[iBuf]);
+ }
taosMemoryFree(*ppWriter);
_exit:
*ppWriter = NULL;
@@ -1493,38 +1202,41 @@ _err:
return code;
}
-int32_t tsdbWriteBlockIdx(SDataFWriter *pWriter, SArray *aBlockIdx, uint8_t **ppBuf) {
+int32_t tsdbWriteBlockIdx(SDataFWriter *pWriter, SArray *aBlockIdx) {
int32_t code = 0;
SHeadFile *pHeadFile = &pWriter->fHead;
- uint8_t *pBuf = NULL;
- int64_t size;
+ int64_t size = 0;
int64_t n;
- if (!ppBuf) ppBuf = &pBuf;
+ // check
+ if (taosArrayGetSize(aBlockIdx) == 0) {
+ pHeadFile->offset = pHeadFile->size;
+ goto _exit;
+ }
// prepare
- size = tPutU32(NULL, TSDB_FILE_DLMT);
+ size = sizeof(uint32_t);
for (int32_t iBlockIdx = 0; iBlockIdx < taosArrayGetSize(aBlockIdx); iBlockIdx++) {
size += tPutBlockIdx(NULL, taosArrayGet(aBlockIdx, iBlockIdx));
}
size += sizeof(TSCKSUM);
// alloc
- code = tRealloc(ppBuf, size);
+ code = tRealloc(&pWriter->aBuf[0], size);
if (code) goto _err;
// build
n = 0;
- n = tPutU32(*ppBuf + n, TSDB_FILE_DLMT);
+ n = tPutU32(pWriter->aBuf[0] + n, TSDB_FILE_DLMT);
for (int32_t iBlockIdx = 0; iBlockIdx < taosArrayGetSize(aBlockIdx); iBlockIdx++) {
- n += tPutBlockIdx(*ppBuf + n, taosArrayGet(aBlockIdx, iBlockIdx));
+ n += tPutBlockIdx(pWriter->aBuf[0] + n, taosArrayGet(aBlockIdx, iBlockIdx));
}
- taosCalcChecksumAppend(0, *ppBuf, size);
+ taosCalcChecksumAppend(0, pWriter->aBuf[0], size);
ASSERT(n + sizeof(TSCKSUM) == size);
// write
- n = taosWriteFile(pWriter->pHeadFD, *ppBuf, size);
+ n = taosWriteFile(pWriter->pHeadFD, pWriter->aBuf[0], size);
if (n < 0) {
code = TAOS_SYSTEM_ERROR(errno);
goto _err;
@@ -1534,44 +1246,39 @@ int32_t tsdbWriteBlockIdx(SDataFWriter *pWriter, SArray *aBlockIdx, uint8_t **pp
pHeadFile->offset = pHeadFile->size;
pHeadFile->size += size;
- tFree(pBuf);
+_exit:
+ tsdbTrace("vgId:%d write block idx, offset:%" PRId64 " size:%" PRId64 " nBlockIdx:%d", TD_VID(pWriter->pTsdb->pVnode),
+ pHeadFile->offset, size, taosArrayGetSize(aBlockIdx));
return code;
_err:
tsdbError("vgId:%d, write block idx failed since %s", TD_VID(pWriter->pTsdb->pVnode), tstrerror(code));
- tFree(pBuf);
return code;
}
-int32_t tsdbWriteBlock(SDataFWriter *pWriter, SMapData *mBlock, uint8_t **ppBuf, SBlockIdx *pBlockIdx) {
- int32_t code = 0;
- SHeadFile *pHeadFile = &pWriter->fHead;
- SBlockDataHdr hdr = {.delimiter = TSDB_FILE_DLMT, .suid = pBlockIdx->suid, .uid = pBlockIdx->uid};
- uint8_t *pBuf = NULL;
- int64_t size;
- int64_t n;
+int32_t tsdbWriteBlock(SDataFWriter *pWriter, SMapData *mBlock, SBlockIdx *pBlockIdx) {
+ int32_t code = 0;
+ SHeadFile *pHeadFile = &pWriter->fHead;
+ int64_t size;
+ int64_t n;
ASSERT(mBlock->nItem > 0);
- // prepare
- size = sizeof(SBlockDataHdr) + tPutMapData(NULL, mBlock) + sizeof(TSCKSUM);
-
// alloc
- if (!ppBuf) ppBuf = &pBuf;
- code = tRealloc(ppBuf, size);
+ size = sizeof(uint32_t) + tPutMapData(NULL, mBlock) + sizeof(TSCKSUM);
+ code = tRealloc(&pWriter->aBuf[0], size);
if (code) goto _err;
// build
n = 0;
- *(SBlockDataHdr *)(*ppBuf) = hdr;
- n += sizeof(hdr);
- n += tPutMapData(*ppBuf + n, mBlock);
- taosCalcChecksumAppend(0, *ppBuf, size);
+ n += tPutU32(pWriter->aBuf[0] + n, TSDB_FILE_DLMT);
+ n += tPutMapData(pWriter->aBuf[0] + n, mBlock);
+ taosCalcChecksumAppend(0, pWriter->aBuf[0], size);
ASSERT(n + sizeof(TSCKSUM) == size);
// write
- n = taosWriteFile(pWriter->pHeadFD, *ppBuf, size);
+ n = taosWriteFile(pWriter->pHeadFD, pWriter->aBuf[0], size);
if (n < 0) {
code = TAOS_SYSTEM_ERROR(errno);
goto _err;
@@ -1582,17 +1289,71 @@ int32_t tsdbWriteBlock(SDataFWriter *pWriter, SMapData *mBlock, uint8_t **ppBuf,
pBlockIdx->size = size;
pHeadFile->size += size;
- tFree(pBuf);
- tsdbTrace("vgId:%d, write block, offset:%" PRId64 " size:%" PRId64, TD_VID(pWriter->pTsdb->pVnode), pBlockIdx->offset,
- pBlockIdx->size);
+ tsdbTrace("vgId:%d, write block, file ID:%d commit ID:%d suid:%" PRId64 " uid:%" PRId64 " offset:%" PRId64
+ " size:%" PRId64 " nItem:%d",
+ TD_VID(pWriter->pTsdb->pVnode), pWriter->wSet.fid, pHeadFile->commitID, pBlockIdx->suid, pBlockIdx->uid,
+ pBlockIdx->offset, pBlockIdx->size, mBlock->nItem);
return code;
_err:
- tFree(pBuf);
tsdbError("vgId:%d, write block failed since %s", TD_VID(pWriter->pTsdb->pVnode), tstrerror(code));
return code;
}
+int32_t tsdbWriteBlockL(SDataFWriter *pWriter, SArray *aBlockL) {
+ int32_t code = 0;
+ SLastFile *pLastFile = &pWriter->fLast;
+ int64_t size;
+ int64_t n;
+
+ // check
+ if (taosArrayGetSize(aBlockL) == 0) {
+ pLastFile->offset = pLastFile->size;
+ goto _exit;
+ }
+
+ // size
+ size = sizeof(uint32_t); // TSDB_FILE_DLMT
+ for (int32_t iBlockL = 0; iBlockL < taosArrayGetSize(aBlockL); iBlockL++) {
+ size += tPutBlockL(NULL, taosArrayGet(aBlockL, iBlockL));
+ }
+ size += sizeof(TSCKSUM);
+
+ // alloc
+ code = tRealloc(&pWriter->aBuf[0], size);
+ if (code) goto _err;
+
+ // encode
+ n = 0;
+ n += tPutU32(pWriter->aBuf[0] + n, TSDB_FILE_DLMT);
+ for (int32_t iBlockL = 0; iBlockL < taosArrayGetSize(aBlockL); iBlockL++) {
+ n += tPutBlockL(pWriter->aBuf[0] + n, taosArrayGet(aBlockL, iBlockL));
+ }
+ taosCalcChecksumAppend(0, pWriter->aBuf[0], size);
+
+ ASSERT(n + sizeof(TSCKSUM) == size);
+
+ // write
+ n = taosWriteFile(pWriter->pLastFD, pWriter->aBuf[0], size);
+ if (n < 0) {
+ code = TAOS_SYSTEM_ERROR(errno);
+ goto _err;
+ }
+
+ // update
+ pLastFile->offset = pLastFile->size;
+ pLastFile->size += size;
+
+_exit:
+ tsdbTrace("vgId:%d tsdb write blockl, loffset:%" PRId64 " size:%" PRId64, TD_VID(pWriter->pTsdb->pVnode),
+ pLastFile->offset, size);
+ return code;
+
+_err:
+ tsdbError("vgId:%d tsdb write blockl failed since %s", TD_VID(pWriter->pTsdb->pVnode), tstrerror(code));
+ return code;
+}
+
static void tsdbUpdateBlockInfo(SBlockData *pBlockData, SBlock *pBlock) {
for (int32_t iRow = 0; iRow < pBlockData->nRow; iRow++) {
TSDBKEY key = {.ts = pBlockData->aTSKEY[iRow], .version = pBlockData->aVersion[iRow]};
@@ -1611,357 +1372,127 @@ static void tsdbUpdateBlockInfo(SBlockData *pBlockData, SBlock *pBlock) {
pBlock->maxKey = key;
}
- pBlock->minVersion = TMIN(pBlock->minVersion, key.version);
- pBlock->maxVersion = TMAX(pBlock->maxVersion, key.version);
+ pBlock->minVer = TMIN(pBlock->minVer, key.version);
+ pBlock->maxVer = TMAX(pBlock->maxVer, key.version);
}
pBlock->nRow += pBlockData->nRow;
}
-static int32_t tsdbWriteBlockDataKey(SSubBlock *pSubBlock, SBlockData *pBlockData, uint8_t **ppBuf1, int64_t *nDataP,
- uint8_t **ppBuf2) {
+static int32_t tsdbWriteBlockSma(SDataFWriter *pWriter, SBlockData *pBlockData, SSmaInfo *pSmaInfo) {
int32_t code = 0;
- int64_t size;
- int64_t tsize;
- if (pSubBlock->cmprAlg == NO_COMPRESSION) {
- pSubBlock->szVersion = sizeof(int64_t) * pSubBlock->nRow;
- pSubBlock->szTSKEY = sizeof(TSKEY) * pSubBlock->nRow;
+ pSmaInfo->offset = 0;
+ pSmaInfo->size = 0;
- code = tRealloc(ppBuf1, *nDataP + pSubBlock->szVersion + pSubBlock->szTSKEY + sizeof(TSCKSUM));
- if (code) goto _err;
-
- // VERSION
- memcpy(*ppBuf1 + *nDataP, pBlockData->aVersion, pSubBlock->szVersion);
-
- // TSKEY
- memcpy(*ppBuf1 + *nDataP + pSubBlock->szVersion, pBlockData->aTSKEY, pSubBlock->szTSKEY);
- } else {
- size = (sizeof(int64_t) + sizeof(TSKEY)) * pSubBlock->nRow + COMP_OVERFLOW_BYTES * 2;
-
- code = tRealloc(ppBuf1, *nDataP + size + sizeof(TSCKSUM));
- if (code) goto _err;
-
- tsize = sizeof(int64_t) * pSubBlock->nRow + COMP_OVERFLOW_BYTES;
- if (pSubBlock->cmprAlg == TWO_STAGE_COMP) {
- code = tRealloc(ppBuf2, tsize);
- if (code) goto _err;
- }
-
- // VERSION
- pSubBlock->szVersion =
- tsCompressBigint((char *)pBlockData->aVersion, sizeof(int64_t) * pBlockData->nRow, pBlockData->nRow,
- *ppBuf1 + *nDataP, size, pSubBlock->cmprAlg, *ppBuf2, tsize);
- if (pSubBlock->szVersion <= 0) {
- code = TSDB_CODE_COMPRESS_ERROR;
- goto _err;
- }
-
- // TSKEY
- pSubBlock->szTSKEY = tsCompressTimestamp((char *)pBlockData->aTSKEY, sizeof(TSKEY) * pBlockData->nRow,
- pBlockData->nRow, *ppBuf1 + *nDataP + pSubBlock->szVersion,
- size - pSubBlock->szVersion, pSubBlock->cmprAlg, *ppBuf2, tsize);
- if (pSubBlock->szTSKEY <= 0) {
- code = TSDB_CODE_COMPRESS_ERROR;
- goto _err;
- }
-
- ASSERT(pSubBlock->szVersion + pSubBlock->szTSKEY <= size);
- }
-
- // checksum
- size = pSubBlock->szVersion + pSubBlock->szTSKEY + sizeof(TSCKSUM);
- taosCalcChecksumAppend(0, *ppBuf1 + *nDataP, size);
-
- *nDataP += size;
- return code;
-
-_err:
- return code;
-}
-
-static int32_t tsdbWriteColData(SColData *pColData, SBlockCol *pBlockCol, SSubBlock *pSubBlock, uint8_t **ppBuf1,
- int64_t *nDataP, uint8_t **ppBuf2) {
- int32_t code = 0;
- int64_t size;
- int64_t n = 0;
-
- // BITMAP
- if (pColData->flag != HAS_VALUE) {
- size = BIT2_SIZE(pColData->nVal) + COMP_OVERFLOW_BYTES;
-
- code = tRealloc(ppBuf1, *nDataP + n + size);
- if (code) goto _err;
-
- code = tRealloc(ppBuf2, size);
- if (code) goto _err;
-
- pBlockCol->szBitmap =
- tsCompressTinyint((char *)pColData->pBitMap, BIT2_SIZE(pColData->nVal), BIT2_SIZE(pColData->nVal),
- *ppBuf1 + *nDataP + n, size, TWO_STAGE_COMP, *ppBuf2, size);
- if (pBlockCol->szBitmap <= 0) {
- code = TSDB_CODE_COMPRESS_ERROR;
- goto _err;
- }
- } else {
- pBlockCol->szBitmap = 0;
- }
- n += pBlockCol->szBitmap;
-
- // OFFSET
- if (IS_VAR_DATA_TYPE(pColData->type)) {
- size = sizeof(int32_t) * pColData->nVal + COMP_OVERFLOW_BYTES;
-
- code = tRealloc(ppBuf1, *nDataP + n + size);
- if (code) goto _err;
-
- code = tRealloc(ppBuf2, size);
- if (code) goto _err;
-
- pBlockCol->szOffset = tsCompressInt((char *)pColData->aOffset, sizeof(int32_t) * pColData->nVal, pColData->nVal,
- *ppBuf1 + *nDataP + n, size, TWO_STAGE_COMP, *ppBuf2, size);
- if (pBlockCol->szOffset <= 0) {
- code = TSDB_CODE_COMPRESS_ERROR;
- goto _err;
- }
- } else {
- pBlockCol->szOffset = 0;
- }
- n += pBlockCol->szOffset;
-
- // VALUE
- if (pSubBlock->cmprAlg == NO_COMPRESSION) {
- pBlockCol->szValue = pColData->nData;
-
- code = tRealloc(ppBuf1, *nDataP + n + pBlockCol->szValue + sizeof(TSCKSUM));
- if (code) goto _err;
-
- memcpy(*ppBuf1 + *nDataP + n, pColData->pData, pBlockCol->szValue);
- } else {
- size = pColData->nData + COMP_OVERFLOW_BYTES;
-
- code = tRealloc(ppBuf1, *nDataP + n + size + sizeof(TSCKSUM));
- if (code) goto _err;
-
- if (pSubBlock->cmprAlg == TWO_STAGE_COMP) {
- code = tRealloc(ppBuf2, size);
- if (code) goto _err;
- }
-
- pBlockCol->szValue =
- tDataTypes[pColData->type].compFunc((char *)pColData->pData, pColData->nData, pColData->nVal,
- *ppBuf1 + *nDataP + n, size, pSubBlock->cmprAlg, *ppBuf2, size);
- if (pBlockCol->szValue <= 0) {
- code = TSDB_CODE_COMPRESS_ERROR;
- goto _err;
- }
- }
- n += pBlockCol->szValue;
- pBlockCol->szOrigin = pColData->nData;
-
- // checksum
- n += sizeof(TSCKSUM);
- taosCalcChecksumAppend(0, *ppBuf1 + *nDataP, n);
-
- *nDataP += n;
-
- return code;
-
-_err:
- return code;
-}
-
-static int32_t tsdbWriteBlockDataImpl(TdFilePtr pFD, SSubBlock *pSubBlock, SBlockDataHdr hdr, SArray *aBlockCol,
- uint8_t *pData, int64_t nData, uint8_t **ppBuf) {
- int32_t code = 0;
- int32_t nBlockCol = taosArrayGetSize(aBlockCol);
- int64_t size;
- int64_t n;
-
- // HDR + SArray
- pSubBlock->szBlockCol = sizeof(hdr);
- for (int32_t iBlockCol = 0; iBlockCol < nBlockCol; iBlockCol++) {
- pSubBlock->szBlockCol += tPutBlockCol(NULL, taosArrayGet(aBlockCol, iBlockCol));
- }
-
- code = tRealloc(ppBuf, pSubBlock->szBlockCol + sizeof(TSCKSUM));
- if (code) goto _err;
-
- n = 0;
- memcpy(*ppBuf, &hdr, sizeof(hdr));
- n += sizeof(hdr);
- for (int32_t iBlockCol = 0; iBlockCol < nBlockCol; iBlockCol++) {
- n += tPutBlockCol(*ppBuf + n, taosArrayGet(aBlockCol, iBlockCol));
- }
- taosCalcChecksumAppend(0, *ppBuf, pSubBlock->szBlockCol + sizeof(TSCKSUM));
-
- ASSERT(n == pSubBlock->szBlockCol);
-
- n = taosWriteFile(pFD, *ppBuf, pSubBlock->szBlockCol + sizeof(TSCKSUM));
- if (n < 0) {
- code = TAOS_SYSTEM_ERROR(errno);
- goto _err;
- }
-
- // SBlockData
- n = taosWriteFile(pFD, pData, nData);
- if (n < 0) {
- code = TAOS_SYSTEM_ERROR(errno);
- goto _err;
- }
-
- return code;
-
-_err:
- return code;
-}
-
-static int32_t tsdbWriteBlockSma(TdFilePtr pFD, SBlockData *pBlockData, SSubBlock *pSubBlock, uint8_t **ppBuf) {
- int32_t code = 0;
- int64_t n;
- SColData *pColData;
-
- // prepare
- pSubBlock->nSma = 0;
+ // encode
for (int32_t iColData = 0; iColData < taosArrayGetSize(pBlockData->aIdx); iColData++) {
- pColData = tBlockDataGetColDataByIdx(pBlockData, iColData);
+ SColData *pColData = tBlockDataGetColDataByIdx(pBlockData, iColData);
- if (IS_VAR_DATA_TYPE(pColData->type) || (!pColData->smaOn)) continue;
+ if ((!pColData->smaOn) || IS_VAR_DATA_TYPE(pColData->type)) continue;
- pSubBlock->nSma++;
- }
- if (pSubBlock->nSma == 0) goto _exit;
+ SColumnDataAgg sma;
+ tsdbCalcColDataSMA(pColData, &sma);
- // calc
- code = tRealloc(ppBuf, sizeof(SColumnDataAgg) * pSubBlock->nSma + sizeof(TSCKSUM));
- if (code) goto _err;
- n = 0;
- for (int32_t iColData = 0; iColData < taosArrayGetSize(pBlockData->aIdx); iColData++) {
- pColData = tBlockDataGetColDataByIdx(pBlockData, iColData);
-
- if (IS_VAR_DATA_TYPE(pColData->type) || (!pColData->smaOn)) continue;
-
- tsdbCalcColDataSMA(pColData, &((SColumnDataAgg *)(*ppBuf))[n]);
- n++;
- }
- taosCalcChecksumAppend(0, *ppBuf, sizeof(SColumnDataAgg) * pSubBlock->nSma + sizeof(TSCKSUM));
-
- // write
- n = taosWriteFile(pFD, *ppBuf, sizeof(SColumnDataAgg) * pSubBlock->nSma + sizeof(TSCKSUM));
- if (n < 0) {
- code = TAOS_SYSTEM_ERROR(errno);
- goto _err;
- }
-
-_exit:
- return code;
-
-_err:
- return code;
-}
-
-int32_t tsdbWriteBlockData(SDataFWriter *pWriter, SBlockData *pBlockData, uint8_t **ppBuf1, uint8_t **ppBuf2,
- SBlockIdx *pBlockIdx, SBlock *pBlock, int8_t cmprAlg) {
- int32_t code = 0;
- SSubBlock *pSubBlock = &pBlock->aSubBlock[pBlock->nSubBlock++];
- SBlockCol blockCol;
- SBlockCol *pBlockCol = &blockCol;
- int64_t n;
- TdFilePtr pFileFD = pBlock->last ? pWriter->pLastFD : pWriter->pDataFD;
- SBlockDataHdr hdr = {.delimiter = TSDB_FILE_DLMT, .suid = pBlockIdx->suid, .uid = pBlockIdx->uid};
- uint8_t *p;
- int64_t nData;
- uint8_t *pBuf1 = NULL;
- uint8_t *pBuf2 = NULL;
- SArray *aBlockCol = NULL;
-
- if (!ppBuf1) ppBuf1 = &pBuf1;
- if (!ppBuf2) ppBuf2 = &pBuf2;
-
- tsdbUpdateBlockInfo(pBlockData, pBlock);
-
- pSubBlock->nRow = pBlockData->nRow;
- pSubBlock->cmprAlg = cmprAlg;
- if (pBlock->last) {
- pSubBlock->offset = pWriter->fLast.size;
- } else {
- pSubBlock->offset = pWriter->fData.size;
- }
-
- // ======================= BLOCK DATA =======================
- // TSDBKEY
- nData = 0;
- code = tsdbWriteBlockDataKey(pSubBlock, pBlockData, ppBuf1, &nData, ppBuf2);
- if (code) goto _err;
-
- // COLUMNS
- aBlockCol = taosArrayInit(taosArrayGetSize(pBlockData->aIdx), sizeof(SBlockCol));
- if (aBlockCol == NULL) {
- code = TSDB_CODE_OUT_OF_MEMORY;
- goto _err;
- }
- int32_t offset = 0;
- for (int32_t iCol = 0; iCol < taosArrayGetSize(pBlockData->aIdx); iCol++) {
- SColData *pColData = tBlockDataGetColDataByIdx(pBlockData, iCol);
-
- ASSERT(pColData->flag);
-
- if (pColData->flag == HAS_NONE) continue;
-
- pBlockCol->cid = pColData->cid;
- pBlockCol->type = pColData->type;
- pBlockCol->smaOn = pColData->smaOn;
- pBlockCol->flag = pColData->flag;
-
- if (pColData->flag != HAS_NULL) {
- code = tsdbWriteColData(pColData, pBlockCol, pSubBlock, ppBuf1, &nData, ppBuf2);
- if (code) goto _err;
-
- pBlockCol->offset = offset;
- offset = offset + pBlockCol->szBitmap + pBlockCol->szOffset + pBlockCol->szValue + sizeof(TSCKSUM);
- }
-
- if (taosArrayPush(aBlockCol, pBlockCol) == NULL) {
- code = TSDB_CODE_OUT_OF_MEMORY;
- goto _err;
- }
+ code = tRealloc(&pWriter->aBuf[0], pSmaInfo->size + tPutColumnDataAgg(NULL, &sma));
+ if (code) goto _err;
+ pSmaInfo->size += tPutColumnDataAgg(pWriter->aBuf[0] + pSmaInfo->size, &sma);
}
// write
- code = tsdbWriteBlockDataImpl(pFileFD, pSubBlock, hdr, aBlockCol, *ppBuf1, nData, ppBuf2);
- if (code) goto _err;
+ if (pSmaInfo->size) {
+ int32_t size = pSmaInfo->size + sizeof(TSCKSUM);
- pSubBlock->szBlock = pSubBlock->szBlockCol + sizeof(TSCKSUM) + nData;
- if (pBlock->last) {
- pWriter->fLast.size += pSubBlock->szBlock;
- } else {
- pWriter->fData.size += pSubBlock->szBlock;
+ code = tRealloc(&pWriter->aBuf[0], size);
+ if (code) goto _err;
+
+ taosCalcChecksumAppend(0, pWriter->aBuf[0], size);
+
+ int64_t n = taosWriteFile(pWriter->pSmaFD, pWriter->aBuf[0], size);
+ if (n < 0) {
+ code = TAOS_SYSTEM_ERROR(errno);
+ goto _err;
+ }
+
+ pSmaInfo->offset = pWriter->fSma.size;
+ pWriter->fSma.size += size;
}
- // ======================= BLOCK SMA =======================
- pSubBlock->sOffset = 0;
- pSubBlock->nSma = 0;
-
- if (pBlock->nSubBlock > 1 || pBlock->last || pBlock->hasDup) goto _exit;
-
- code = tsdbWriteBlockSma(pWriter->pSmaFD, pBlockData, pSubBlock, ppBuf1);
- if (code) goto _err;
-
- if (pSubBlock->nSma > 0) {
- pSubBlock->sOffset = pWriter->fSma.size;
- pWriter->fSma.size += (sizeof(SColumnDataAgg) * pSubBlock->nSma + sizeof(TSCKSUM));
- }
-
-_exit:
- tFree(pBuf1);
- tFree(pBuf2);
- taosArrayDestroy(aBlockCol);
return code;
_err:
- tsdbError("vgId:%d, write block data failed since %s", TD_VID(pWriter->pTsdb->pVnode), tstrerror(code));
- tFree(pBuf1);
- tFree(pBuf2);
- taosArrayDestroy(aBlockCol);
+ tsdbError("vgId:%d tsdb write block sma failed since %s", TD_VID(pWriter->pTsdb->pVnode), tstrerror(code));
+ return code;
+}
+
+int32_t tsdbWriteBlockData(SDataFWriter *pWriter, SBlockData *pBlockData, SBlockInfo *pBlkInfo, SSmaInfo *pSmaInfo,
+ int8_t cmprAlg, int8_t toLast) {
+ int32_t code = 0;
+
+ ASSERT(pBlockData->nRow > 0);
+
+ pBlkInfo->offset = toLast ? pWriter->fLast.size : pWriter->fData.size;
+ pBlkInfo->szBlock = 0;
+ pBlkInfo->szKey = 0;
+
+ int32_t aBufN[4] = {0};
+ code = tCmprBlockData(pBlockData, cmprAlg, NULL, NULL, pWriter->aBuf, aBufN);
+ if (code) goto _err;
+
+ // write =================
+ TdFilePtr pFD = toLast ? pWriter->pLastFD : pWriter->pDataFD;
+
+ pBlkInfo->szKey = aBufN[3] + aBufN[2];
+ pBlkInfo->szBlock = aBufN[0] + aBufN[1] + aBufN[2] + aBufN[3];
+
+ int64_t n = taosWriteFile(pFD, pWriter->aBuf[3], aBufN[3]);
+ if (n < 0) {
+ code = TAOS_SYSTEM_ERROR(errno);
+ goto _err;
+ }
+
+ n = taosWriteFile(pFD, pWriter->aBuf[2], aBufN[2]);
+ if (n < 0) {
+ code = TAOS_SYSTEM_ERROR(errno);
+ goto _err;
+ }
+
+ if (aBufN[1]) {
+ n = taosWriteFile(pFD, pWriter->aBuf[1], aBufN[1]);
+ if (n < 0) {
+ code = TAOS_SYSTEM_ERROR(errno);
+ goto _err;
+ }
+ }
+
+ if (aBufN[0]) {
+ n = taosWriteFile(pFD, pWriter->aBuf[0], aBufN[0]);
+ if (n < 0) {
+ code = TAOS_SYSTEM_ERROR(errno);
+ goto _err;
+ }
+ }
+
+ // update info
+ if (toLast) {
+ pWriter->fLast.size += pBlkInfo->szBlock;
+ } else {
+ pWriter->fData.size += pBlkInfo->szBlock;
+ }
+
+ // ================= SMA ====================
+ if (pSmaInfo) {
+ code = tsdbWriteBlockSma(pWriter, pBlockData, pSmaInfo);
+ if (code) goto _err;
+ }
+
+_exit:
+ tsdbTrace("vgId:%d tsdb write block data, suid:%" PRId64 " uid:%" PRId64 " nRow:%d, offset:%" PRId64 " size:%d",
+ TD_VID(pWriter->pTsdb->pVnode), pBlockData->suid, pBlockData->uid, pBlockData->nRow, pBlkInfo->offset,
+ pBlkInfo->szBlock);
+ return code;
+
+_err:
+ tsdbError("vgId:%d tsdb write block data failed since %s", TD_VID(pWriter->pTsdb->pVnode), tstrerror(code));
return code;
}
@@ -2075,4 +1606,4 @@ int32_t tsdbDFileSetCopy(STsdb *pTsdb, SDFileSet *pSetFrom, SDFileSet *pSetTo) {
_err:
tsdbError("vgId:%d, tsdb DFileSet copy failed since %s", TD_VID(pTsdb->pVnode), tstrerror(code));
return code;
-}
\ No newline at end of file
+}
diff --git a/source/dnode/vnode/src/tsdb/tsdbSnapshot.c b/source/dnode/vnode/src/tsdb/tsdbSnapshot.c
index c40fb98d62..ab2b2b617a 100644
--- a/source/dnode/vnode/src/tsdb/tsdbSnapshot.c
+++ b/source/dnode/vnode/src/tsdb/tsdbSnapshot.c
@@ -27,12 +27,16 @@ struct STsdbSnapReader {
int32_t fid;
SDataFReader* pDataFReader;
SArray* aBlockIdx; // SArray
- int32_t iBlockIdx;
+ SArray* aBlockL; // SArray
SBlockIdx* pBlockIdx;
- SMapData mBlock; // SMapData
- int32_t iBlock;
- SBlockData oBlockData;
- SBlockData nBlockData;
+ SBlockL* pBlockL;
+
+ int32_t iBlockIdx;
+ int32_t iBlockL;
+ SMapData mBlock; // SMapData
+ int32_t iBlock;
+ SBlockData oBlockData;
+ SBlockData nBlockData;
// for del file
int8_t delDone;
SDelFReader* pDelFReader;
@@ -47,114 +51,116 @@ static int32_t tsdbSnapReadData(STsdbSnapReader* pReader, uint8_t** ppData) {
while (true) {
if (pReader->pDataFReader == NULL) {
- SDFileSet* pSet =
- taosArraySearch(pReader->fs.aDFileSet, &(SDFileSet){.fid = pReader->fid}, tDFileSetCmprFn, TD_GT);
-
+ // next
+ SDFileSet dFileSet = {.fid = pReader->fid};
+ SDFileSet* pSet = taosArraySearch(pReader->fs.aDFileSet, &dFileSet, tDFileSetCmprFn, TD_GT);
if (pSet == NULL) goto _exit;
-
pReader->fid = pSet->fid;
- code = tsdbDataFReaderOpen(&pReader->pDataFReader, pReader->pTsdb, pSet);
+
+ // load
+ code = tsdbDataFReaderOpen(&pReader->pDataFReader, pTsdb, pSet);
if (code) goto _err;
- // SBlockIdx
- code = tsdbReadBlockIdx(pReader->pDataFReader, pReader->aBlockIdx, NULL);
+ code = tsdbReadBlockIdx(pReader->pDataFReader, pReader->aBlockIdx);
if (code) goto _err;
+ code = tsdbReadBlockL(pReader->pDataFReader, pReader->aBlockL);
+ if (code) goto _err;
+
+ // init
pReader->iBlockIdx = 0;
- pReader->pBlockIdx = NULL;
+ if (pReader->iBlockIdx < taosArrayGetSize(pReader->aBlockIdx)) {
+ pReader->pBlockIdx = (SBlockIdx*)taosArrayGet(pReader->aBlockIdx, pReader->iBlockIdx);
+
+ code = tsdbReadBlock(pReader->pDataFReader, pReader->pBlockIdx, &pReader->mBlock);
+ if (code) goto _err;
+
+ pReader->iBlock = 0;
+ } else {
+ pReader->pBlockIdx = NULL;
+ }
+
+ pReader->iBlockL = 0;
+ while (true) {
+ if (pReader->iBlockL >= taosArrayGetSize(pReader->aBlockL)) {
+ pReader->pBlockL = NULL;
+ break;
+ }
+
+ pReader->pBlockL = (SBlockL*)taosArrayGet(pReader->aBlockL, pReader->iBlockL);
+ if (pReader->pBlockL->minVer <= pReader->ever && pReader->pBlockL->maxVer >= pReader->sver) {
+ // TODO
+ break;
+ }
+
+ pReader->iBlockL++;
+ }
tsdbInfo("vgId:%d, vnode snapshot tsdb open data file to read for %s, fid:%d", TD_VID(pTsdb->pVnode), pTsdb->path,
pReader->fid);
}
while (true) {
- if (pReader->pBlockIdx == NULL) {
- if (pReader->iBlockIdx >= taosArrayGetSize(pReader->aBlockIdx)) {
- tsdbDataFReaderClose(&pReader->pDataFReader);
- break;
+ if (pReader->pBlockIdx && pReader->pBlockL) {
+ TABLEID id = {.suid = pReader->pBlockL->suid, .uid = pReader->pBlockL->minUid};
+
+ ASSERT(0);
+
+ // if (tTABLEIDCmprFn(pReader->pBlockIdx, &minId) < 0) {
+ // // TODO
+ // } else if (tTABLEIDCmprFn(pReader->pBlockIdx, &maxId) < 0) {
+ // // TODO
+ // } else {
+ // // TODO
+ // }
+ } else if (pReader->pBlockIdx) {
+ while (pReader->iBlock < pReader->mBlock.nItem) {
+ SBlock block;
+ tMapDataGetItemByIdx(&pReader->mBlock, pReader->iBlock, &block, tGetBlock);
+
+ if (block.minVer <= pReader->ever && block.maxVer >= pReader->sver) {
+ // load data (todo)
+ }
+
+ // next
+ pReader->iBlock++;
+ if (*ppData) break;
}
- pReader->pBlockIdx = (SBlockIdx*)taosArrayGet(pReader->aBlockIdx, pReader->iBlockIdx);
- pReader->iBlockIdx++;
-
- code = tsdbReadBlock(pReader->pDataFReader, pReader->pBlockIdx, &pReader->mBlock, NULL);
- if (code) goto _err;
-
- pReader->iBlock = 0;
- }
-
- SBlock block;
- SBlock* pBlock = █
- while (true) {
if (pReader->iBlock >= pReader->mBlock.nItem) {
- pReader->pBlockIdx = NULL;
- break;
+ pReader->iBlockIdx++;
+ if (pReader->iBlockIdx < taosArrayGetSize(pReader->aBlockIdx)) {
+ pReader->pBlockIdx = (SBlockIdx*)taosArrayGet(pReader->aBlockIdx, pReader->iBlockIdx);
+
+ code = tsdbReadBlock(pReader->pDataFReader, pReader->pBlockIdx, &pReader->mBlock);
+ if (code) goto _err;
+
+ pReader->iBlock = 0;
+ } else {
+ pReader->pBlockIdx = NULL;
+ }
}
- tMapDataGetItemByIdx(&pReader->mBlock, pReader->iBlock, pBlock, tGetBlock);
- pReader->iBlock++;
+ if (*ppData) goto _exit;
+ } else if (pReader->pBlockL) {
+ while (pReader->pBlockL) {
+ if (pReader->pBlockL->minVer <= pReader->ever && pReader->pBlockL->maxVer >= pReader->sver) {
+ // load data (todo)
+ }
- if (pBlock->minVersion > pReader->ever || pBlock->maxVersion < pReader->sver) continue;
+ // next
+ pReader->iBlockL++;
+ if (pReader->iBlockL < taosArrayGetSize(pReader->aBlockL)) {
+ pReader->pBlockL = (SBlockL*)taosArrayGetSize(pReader->aBlockL);
+ } else {
+ pReader->pBlockL = NULL;
+ }
- code = tsdbReadBlockData(pReader->pDataFReader, pReader->pBlockIdx, pBlock, &pReader->oBlockData, NULL, NULL);
- if (code) goto _err;
-
- // filter
- tBlockDataReset(&pReader->nBlockData);
- for (int32_t iColData = 0; iColData < taosArrayGetSize(pReader->oBlockData.aIdx); iColData++) {
- SColData* pColDataO = tBlockDataGetColDataByIdx(&pReader->oBlockData, iColData);
- SColData* pColDataN = NULL;
-
- code = tBlockDataAddColData(&pReader->nBlockData, taosArrayGetSize(pReader->nBlockData.aIdx), &pColDataN);
- if (code) goto _err;
-
- tColDataInit(pColDataN, pColDataO->cid, pColDataO->type, pColDataO->smaOn);
+ if (*ppData) goto _exit;
}
-
- for (int32_t iRow = 0; iRow < pReader->oBlockData.nRow; iRow++) {
- TSDBROW row = tsdbRowFromBlockData(&pReader->oBlockData, iRow);
- int64_t version = TSDBROW_VERSION(&row);
-
- tsdbTrace("vgId:%d, vnode snapshot tsdb read for %s, %" PRId64 "(%" PRId64 " , %" PRId64 ")",
- TD_VID(pReader->pTsdb->pVnode), pReader->pTsdb->path, version, pReader->sver, pReader->ever);
-
- if (version < pReader->sver || version > pReader->ever) continue;
-
- code = tBlockDataAppendRow(&pReader->nBlockData, &row, NULL);
- if (code) goto _err;
- }
-
- if (pReader->nBlockData.nRow <= 0) {
- continue;
- }
-
- // org data
- // compress data (todo)
- int32_t size = sizeof(TABLEID) + tPutBlockData(NULL, &pReader->nBlockData);
-
- *ppData = taosMemoryMalloc(sizeof(SSnapDataHdr) + size);
- if (*ppData == NULL) {
- code = TSDB_CODE_OUT_OF_MEMORY;
- goto _err;
- }
-
- SSnapDataHdr* pHdr = (SSnapDataHdr*)(*ppData);
- pHdr->type = pReader->type;
- pHdr->size = size;
-
- TABLEID* pId = (TABLEID*)(&pHdr[1]);
- pId->suid = pReader->pBlockIdx->suid;
- pId->uid = pReader->pBlockIdx->uid;
-
- tPutBlockData((uint8_t*)(&pId[1]), &pReader->nBlockData);
-
- tsdbInfo("vgId:%d, vnode snapshot read data for %s, fid:%d suid:%" PRId64 " uid:%" PRId64
- " iBlock:%d minVersion:%d maxVersion:%d nRow:%d out of %d size:%d",
- TD_VID(pTsdb->pVnode), pTsdb->path, pReader->fid, pReader->pBlockIdx->suid, pReader->pBlockIdx->uid,
- pReader->iBlock - 1, pBlock->minVersion, pBlock->maxVersion, pReader->nBlockData.nRow, pBlock->nRow,
- size);
-
- goto _exit;
+ } else {
+ tsdbDataFReaderClose(&pReader->pDataFReader);
+ break;
}
}
}
@@ -179,11 +185,11 @@ static int32_t tsdbSnapReadDel(STsdbSnapReader* pReader, uint8_t** ppData) {
}
// open
- code = tsdbDelFReaderOpen(&pReader->pDelFReader, pDelFile, pTsdb, NULL);
+ code = tsdbDelFReaderOpen(&pReader->pDelFReader, pDelFile, pTsdb);
if (code) goto _err;
// read index
- code = tsdbReadDelIdx(pReader->pDelFReader, pReader->aDelIdx, NULL);
+ code = tsdbReadDelIdx(pReader->pDelFReader, pReader->aDelIdx);
if (code) goto _err;
pReader->iDelIdx = 0;
@@ -199,7 +205,7 @@ static int32_t tsdbSnapReadDel(STsdbSnapReader* pReader, uint8_t** ppData) {
pReader->iDelIdx++;
- code = tsdbReadDelData(pReader->pDelFReader, pDelIdx, pReader->aDelData, NULL);
+ code = tsdbReadDelData(pReader->pDelFReader, pDelIdx, pReader->aDelData);
if (code) goto _err;
int32_t size = 0;
@@ -292,10 +298,15 @@ int32_t tsdbSnapReaderOpen(STsdb* pTsdb, int64_t sver, int64_t ever, int8_t type
code = TSDB_CODE_OUT_OF_MEMORY;
goto _err;
}
+ pReader->aBlockL = taosArrayInit(0, sizeof(SBlockL));
+ if (pReader->aBlockL == NULL) {
+ code = TSDB_CODE_OUT_OF_MEMORY;
+ goto _err;
+ }
pReader->mBlock = tMapDataInit();
- code = tBlockDataInit(&pReader->oBlockData);
+ code = tBlockDataCreate(&pReader->oBlockData);
if (code) goto _err;
- code = tBlockDataInit(&pReader->nBlockData);
+ code = tBlockDataCreate(&pReader->nBlockData);
if (code) goto _err;
pReader->aDelIdx = taosArrayInit(0, sizeof(SDelIdx));
@@ -327,10 +338,11 @@ int32_t tsdbSnapReaderClose(STsdbSnapReader** ppReader) {
if (pReader->pDataFReader) {
tsdbDataFReaderClose(&pReader->pDataFReader);
}
+ taosArrayDestroy(pReader->aBlockL);
taosArrayDestroy(pReader->aBlockIdx);
tMapDataClear(&pReader->mBlock);
- tBlockDataClear(&pReader->oBlockData, 1);
- tBlockDataClear(&pReader->nBlockData, 1);
+ tBlockDataDestroy(&pReader->oBlockData, 1);
+ tBlockDataDestroy(&pReader->nBlockData, 1);
if (pReader->pDelFReader) {
tsdbDelFReaderClose(&pReader->pDelFReader);
@@ -405,6 +417,7 @@ struct STsdbSnapWriter {
int8_t cmprAlg;
int64_t commitID;
+ uint8_t* aBuf[5];
// for data file
SBlockData bData;
@@ -418,6 +431,9 @@ struct STsdbSnapWriter {
SBlockData* pBlockData;
int32_t iRow;
SBlockData bDataR;
+ SArray* aBlockL; // SArray
+ int32_t iBlockL;
+ SBlockData lDataR;
SDataFWriter* pDataFWriter;
SBlockIdx* pBlockIdxW; // NULL when no committing table
@@ -427,6 +443,7 @@ struct STsdbSnapWriter {
SMapData mBlockW; // SMapData
SArray* aBlockIdxW; // SArray
+ SArray* aBlockLW; // SArray
// for del file
SDelFReader* pDelFReader;
@@ -437,25 +454,6 @@ struct STsdbSnapWriter {
SArray* aDelIdxW;
};
-static int32_t tsdbSnapWriteAppendData(STsdbSnapWriter* pWriter, uint8_t* pData, uint32_t nData) {
- int32_t code = 0;
- int32_t iRow = 0; // todo
- int32_t nRow = 0; // todo
- SBlockData* pBlockData = NULL; // todo
-
- while (iRow < nRow) {
- code = tBlockDataAppendRow(&pWriter->bDataW, &tsdbRowFromBlockData(pBlockData, iRow), NULL);
- if (code) goto _err;
- }
-
- return code;
-
-_err:
- tsdbError("vgId:%d, tsdb snapshot write append data for %s failed since %s", TD_VID(pWriter->pTsdb->pVnode),
- pWriter->pTsdb->path, tstrerror(code));
- return code;
-}
-
static int32_t tsdbSnapWriteTableDataEnd(STsdbSnapWriter* pWriter) {
int32_t code = 0;
@@ -467,20 +465,21 @@ static int32_t tsdbSnapWriteTableDataEnd(STsdbSnapWriter* pWriter) {
if (pWriter->pBlockData) {
ASSERT(pWriter->iRow < pWriter->pBlockData->nRow);
while (pWriter->iRow < pWriter->pBlockData->nRow) {
- code = tBlockDataAppendRow(&pWriter->bDataW, &tsdbRowFromBlockData(pWriter->pBlockData, pWriter->iRow), NULL);
+ code = tBlockDataAppendRow(&pWriter->bDataW, &tsdbRowFromBlockData(pWriter->pBlockData, pWriter->iRow), NULL,
+ 0); // todo
if (code) goto _err;
if (pWriter->bDataW.nRow >= pWriter->maxRow * 4 / 5) {
- pWriter->blockW.last = 0;
- code = tsdbWriteBlockData(pWriter->pDataFWriter, &pWriter->bDataW, NULL, NULL, pWriter->pBlockIdxW,
- &pWriter->blockW, pWriter->cmprAlg);
+ // pWriter->blockW.last = 0;
+ // code = tsdbWriteBlockData(pWriter->pDataFWriter, &pWriter->bDataW, NULL, NULL, pWriter->pBlockIdxW,
+ // &pWriter->blockW, pWriter->cmprAlg);
if (code) goto _err;
code = tMapDataPutItem(&pWriter->mBlockW, &pWriter->blockW, tPutBlock);
if (code) goto _err;
tBlockReset(&pWriter->blockW);
- tBlockDataClearData(&pWriter->bDataW);
+ tBlockDataClear(&pWriter->bDataW);
}
pWriter->iRow++;
@@ -489,16 +488,16 @@ static int32_t tsdbSnapWriteTableDataEnd(STsdbSnapWriter* pWriter) {
// write remain data if has
if (pWriter->bDataW.nRow > 0) {
- pWriter->blockW.last = 0;
+ // pWriter->blockW.last = 0;
if (pWriter->bDataW.nRow < pWriter->minRow) {
if (pWriter->iBlock > pWriter->mBlock.nItem) {
- pWriter->blockW.last = 1;
+ // pWriter->blockW.last = 1;
}
}
- code = tsdbWriteBlockData(pWriter->pDataFWriter, &pWriter->bDataW, NULL, NULL, pWriter->pBlockIdxW,
- &pWriter->blockW, pWriter->cmprAlg);
- if (code) goto _err;
+ // code = tsdbWriteBlockData(pWriter->pDataFWriter, &pWriter->bDataW, NULL, NULL, pWriter->pBlockIdxW,
+ // &pWriter->blockW, pWriter->cmprAlg);
+ // if (code) goto _err;
code = tMapDataPutItem(&pWriter->mBlockW, &pWriter->blockW, tPutBlock);
if (code) goto _err;
@@ -510,16 +509,16 @@ static int32_t tsdbSnapWriteTableDataEnd(STsdbSnapWriter* pWriter) {
SBlock block;
tMapDataGetItemByIdx(&pWriter->mBlock, pWriter->iBlock, &block, tGetBlock);
- if (block.last) {
- code = tsdbReadBlockData(pWriter->pDataFReader, pWriter->pBlockIdx, &block, &pWriter->bDataR, NULL, NULL);
- if (code) goto _err;
+ // if (block.last) {
+ // code = tsdbReadBlockData(pWriter->pDataFReader, pWriter->pBlockIdx, &block, &pWriter->bDataR, NULL, NULL);
+ // if (code) goto _err;
- tBlockReset(&block);
- block.last = 1;
- code = tsdbWriteBlockData(pWriter->pDataFWriter, &pWriter->bDataR, NULL, NULL, pWriter->pBlockIdxW, &block,
- pWriter->cmprAlg);
- if (code) goto _err;
- }
+ // tBlockReset(&block);
+ // block.last = 1;
+ // code = tsdbWriteBlockData(pWriter->pDataFWriter, &pWriter->bDataR, NULL, NULL, pWriter->pBlockIdxW, &block,
+ // pWriter->cmprAlg);
+ // if (code) goto _err;
+ // }
code = tMapDataPutItem(&pWriter->mBlockW, &block, tPutBlock);
if (code) goto _err;
@@ -528,8 +527,8 @@ static int32_t tsdbSnapWriteTableDataEnd(STsdbSnapWriter* pWriter) {
}
// SBlock
- code = tsdbWriteBlock(pWriter->pDataFWriter, &pWriter->mBlockW, NULL, pWriter->pBlockIdxW);
- if (code) goto _err;
+ // code = tsdbWriteBlock(pWriter->pDataFWriter, &pWriter->mBlockW, NULL, pWriter->pBlockIdxW);
+ // if (code) goto _err;
// SBlockIdx
if (taosArrayPush(pWriter->aBlockIdxW, pWriter->pBlockIdxW) == NULL) {
@@ -550,7 +549,7 @@ _err:
static int32_t tsdbSnapMoveWriteTableData(STsdbSnapWriter* pWriter, SBlockIdx* pBlockIdx) {
int32_t code = 0;
- code = tsdbReadBlock(pWriter->pDataFReader, pBlockIdx, &pWriter->mBlock, NULL);
+ code = tsdbReadBlock(pWriter->pDataFReader, pBlockIdx, &pWriter->mBlock);
if (code) goto _err;
// SBlockData
@@ -559,16 +558,17 @@ static int32_t tsdbSnapMoveWriteTableData(STsdbSnapWriter* pWriter, SBlockIdx* p
for (int32_t iBlock = 0; iBlock < pWriter->mBlock.nItem; iBlock++) {
tMapDataGetItemByIdx(&pWriter->mBlock, iBlock, &block, tGetBlock);
- if (block.last) {
- code = tsdbReadBlockData(pWriter->pDataFReader, pBlockIdx, &block, &pWriter->bDataR, NULL, NULL);
- if (code) goto _err;
+ // if (block.last) {
+ // code = tsdbReadBlockData(pWriter->pDataFReader, pBlockIdx, &block, &pWriter->bDataR, NULL, NULL);
+ // if (code) goto _err;
- tBlockReset(&block);
- block.last = 1;
- code =
- tsdbWriteBlockData(pWriter->pDataFWriter, &pWriter->bDataR, NULL, NULL, pBlockIdx, &block, pWriter->cmprAlg);
- if (code) goto _err;
- }
+ // tBlockReset(&block);
+ // block.last = 1;
+ // code =
+ // tsdbWriteBlockData(pWriter->pDataFWriter, &pWriter->bDataR, NULL, NULL, pBlockIdx, &block,
+ // pWriter->cmprAlg);
+ // if (code) goto _err;
+ // }
code = tMapDataPutItem(&pWriter->mBlockW, &block, tPutBlock);
if (code) goto _err;
@@ -576,7 +576,7 @@ static int32_t tsdbSnapMoveWriteTableData(STsdbSnapWriter* pWriter, SBlockIdx* p
// SBlock
SBlockIdx blockIdx = {.suid = pBlockIdx->suid, .uid = pBlockIdx->uid};
- code = tsdbWriteBlock(pWriter->pDataFWriter, &pWriter->mBlockW, NULL, &blockIdx);
+ code = tsdbWriteBlock(pWriter->pDataFWriter, &pWriter->mBlockW, &blockIdx);
if (code) goto _err;
// SBlockIdx
@@ -601,9 +601,9 @@ static int32_t tsdbSnapWriteTableDataImpl(STsdbSnapWriter* pWriter) {
TSDBROW row;
TSDBROW* pRow = &row;
- // correct schema
- code = tBlockDataCorrectSchema(&pWriter->bDataW, pBlockData);
- if (code) goto _err;
+ // // correct schema
+ // code = tBlockDataCorrectSchema(&pWriter->bDataW, pBlockData);
+ // if (code) goto _err;
// loop to merge
*pRow = tsdbRowFromBlockData(pBlockData, iRow);
@@ -618,8 +618,8 @@ static int32_t tsdbSnapWriteTableDataImpl(STsdbSnapWriter* pWriter) {
ASSERT(c);
if (c < 0) {
- code = tBlockDataAppendRow(&pWriter->bDataW, pRow, NULL);
- if (code) goto _err;
+ // code = tBlockDataAppendRow(&pWriter->bDataW, pRow, NULL);
+ // if (code) goto _err;
iRow++;
if (iRow < pWriter->pBlockData->nRow) {
@@ -628,8 +628,8 @@ static int32_t tsdbSnapWriteTableDataImpl(STsdbSnapWriter* pWriter) {
pRow = NULL;
}
} else if (c > 0) {
- code = tBlockDataAppendRow(&pWriter->bDataW, &tsdbRowFromBlockData(pWriter->pBlockData, pWriter->iRow), NULL);
- if (code) goto _err;
+ // code = tBlockDataAppendRow(&pWriter->bDataW, &tsdbRowFromBlockData(pWriter->pBlockData, pWriter->iRow),
+ // NULL); if (code) goto _err;
pWriter->iRow++;
if (pWriter->iRow >= pWriter->pBlockData->nRow) {
@@ -647,16 +647,15 @@ static int32_t tsdbSnapWriteTableDataImpl(STsdbSnapWriter* pWriter) {
tMapDataGetItemByIdx(&pWriter->mBlock, pWriter->iBlock, &block, tGetBlock);
- if (block.last) {
- pWriter->pBlockData = &pWriter->bDataR;
+ // if (block.last) {
+ // pWriter->pBlockData = &pWriter->bDataR;
- code = tsdbReadBlockData(pWriter->pDataFReader, pWriter->pBlockIdx, &block, pWriter->pBlockData, NULL, NULL);
- if (code) goto _err;
- pWriter->iRow = 0;
+ // code = tsdbReadBlockData(pWriter->pDataFReader, pWriter->pBlockIdx, &block, pWriter->pBlockData, NULL,
+ // NULL); if (code) goto _err; pWriter->iRow = 0;
- pWriter->iBlock++;
- break;
- }
+ // pWriter->iBlock++;
+ // break;
+ // }
c = tsdbKeyCmprFn(&block.maxKey, &key);
@@ -664,16 +663,16 @@ static int32_t tsdbSnapWriteTableDataImpl(STsdbSnapWriter* pWriter) {
if (c < 0) {
if (pWriter->bDataW.nRow) {
- pWriter->blockW.last = 0;
- code = tsdbWriteBlockData(pWriter->pDataFWriter, &pWriter->bDataW, NULL, NULL, pWriter->pBlockIdxW,
- &pWriter->blockW, pWriter->cmprAlg);
- if (code) goto _err;
+ // pWriter->blockW.last = 0;
+ // code = tsdbWriteBlockData(pWriter->pDataFWriter, &pWriter->bDataW, NULL, NULL, pWriter->pBlockIdxW,
+ // &pWriter->blockW, pWriter->cmprAlg);
+ // if (code) goto _err;
code = tMapDataPutItem(&pWriter->mBlockW, &pWriter->blockW, tPutBlock);
if (code) goto _err;
tBlockReset(&pWriter->blockW);
- tBlockDataClearData(&pWriter->bDataW);
+ tBlockDataClear(&pWriter->bDataW);
}
code = tMapDataPutItem(&pWriter->mBlockW, &block, tPutBlock);
@@ -687,9 +686,10 @@ static int32_t tsdbSnapWriteTableDataImpl(STsdbSnapWriter* pWriter) {
if (c > 0) {
pWriter->pBlockData = &pWriter->bDataR;
- code =
- tsdbReadBlockData(pWriter->pDataFReader, pWriter->pBlockIdx, &block, pWriter->pBlockData, NULL, NULL);
- if (code) goto _err;
+ // code =
+ // tsdbReadBlockData(pWriter->pDataFReader, pWriter->pBlockIdx, &block, pWriter->pBlockData, NULL,
+ // NULL);
+ // if (code) goto _err;
pWriter->iRow = 0;
pWriter->iBlock++;
@@ -700,8 +700,8 @@ static int32_t tsdbSnapWriteTableDataImpl(STsdbSnapWriter* pWriter) {
if (pWriter->pBlockData) continue;
- code = tBlockDataAppendRow(&pWriter->bDataW, pRow, NULL);
- if (code) goto _err;
+ // code = tBlockDataAppendRow(&pWriter->bDataW, pRow, NULL);
+ // if (code) goto _err;
iRow++;
if (iRow < pBlockData->nRow) {
@@ -715,15 +715,15 @@ static int32_t tsdbSnapWriteTableDataImpl(STsdbSnapWriter* pWriter) {
if (pWriter->bDataW.nRow < pWriter->maxRow * 4 / 5) continue;
_write_block:
- code = tsdbWriteBlockData(pWriter->pDataFWriter, &pWriter->bDataW, NULL, NULL, pWriter->pBlockIdxW,
- &pWriter->blockW, pWriter->cmprAlg);
- if (code) goto _err;
+ // code = tsdbWriteBlockData(pWriter->pDataFWriter, &pWriter->bDataW, NULL, NULL, pWriter->pBlockIdxW,
+ // &pWriter->blockW, pWriter->cmprAlg);
+ // if (code) goto _err;
code = tMapDataPutItem(&pWriter->mBlockW, &pWriter->blockW, tPutBlock);
if (code) goto _err;
tBlockReset(&pWriter->blockW);
- tBlockDataClearData(&pWriter->bDataW);
+ tBlockDataClear(&pWriter->bDataW);
}
return code;
@@ -789,7 +789,7 @@ static int32_t tsdbSnapWriteTableData(STsdbSnapWriter* pWriter, TABLEID id) {
}
if (pWriter->pBlockIdx) {
- code = tsdbReadBlock(pWriter->pDataFReader, pWriter->pBlockIdx, &pWriter->mBlock, NULL);
+ code = tsdbReadBlock(pWriter->pDataFReader, pWriter->pBlockIdx, &pWriter->mBlock);
if (code) goto _err;
} else {
tMapDataReset(&pWriter->mBlock);
@@ -831,9 +831,11 @@ static int32_t tsdbSnapWriteDataEnd(STsdbSnapWriter* pWriter) {
if (pWriter->pDataFWriter == NULL) goto _exit;
+ // finish current table
code = tsdbSnapWriteTableDataEnd(pWriter);
if (code) goto _err;
+ // move remain table
while (pWriter->iBlockIdx < taosArrayGetSize(pWriter->aBlockIdx)) {
code = tsdbSnapMoveWriteTableData(pWriter, (SBlockIdx*)taosArrayGet(pWriter->aBlockIdx, pWriter->iBlockIdx));
if (code) goto _err;
@@ -841,8 +843,16 @@ static int32_t tsdbSnapWriteDataEnd(STsdbSnapWriter* pWriter) {
pWriter->iBlockIdx++;
}
- code = tsdbWriteBlockIdx(pWriter->pDataFWriter, pWriter->aBlockIdxW, NULL);
- if (code) goto _err;
+ // write remain stuff
+ if (taosArrayGetSize(pWriter->aBlockLW) > 0) {
+ code = tsdbWriteBlockL(pWriter->pDataFWriter, pWriter->aBlockIdxW);
+ if (code) goto _err;
+ }
+
+ if (taosArrayGetSize(pWriter->aBlockIdx) > 0) {
+ code = tsdbWriteBlockIdx(pWriter->pDataFWriter, pWriter->aBlockIdxW);
+ if (code) goto _err;
+ }
code = tsdbFSUpsertFSet(&pWriter->fs, &pWriter->pDataFWriter->wSet);
if (code) goto _err;
@@ -866,19 +876,22 @@ _err:
}
static int32_t tsdbSnapWriteData(STsdbSnapWriter* pWriter, uint8_t* pData, uint32_t nData) {
- int32_t code = 0;
- STsdb* pTsdb = pWriter->pTsdb;
- TABLEID id = *(TABLEID*)(pData + sizeof(SSnapDataHdr));
- int64_t n;
+ int32_t code = 0;
+ STsdb* pTsdb = pWriter->pTsdb;
+ SSnapDataHdr* pHdr = (SSnapDataHdr*)pData;
+ TABLEID id = *(TABLEID*)(pData + sizeof(SSnapDataHdr));
+ int64_t n;
// decode
SBlockData* pBlockData = &pWriter->bData;
- n = tGetBlockData(pData + sizeof(SSnapDataHdr) + sizeof(TABLEID), pBlockData);
- ASSERT(n + sizeof(SSnapDataHdr) + sizeof(TABLEID) == nData);
+ code = tDecmprBlockData(pData + sizeof(SSnapDataHdr) + sizeof(TABLEID), pHdr->size - sizeof(TABLEID), pBlockData,
+ pWriter->aBuf);
+ if (code) goto _err;
// open file
- TSDBKEY keyFirst = tBlockDataFirstKey(pBlockData);
- TSDBKEY keyLast = tBlockDataLastKey(pBlockData);
+ TSDBKEY keyFirst = {.version = pBlockData->aVersion[0], .ts = pBlockData->aTSKEY[0]};
+ TSDBKEY keyLast = {.version = pBlockData->aVersion[pBlockData->nRow - 1],
+ .ts = pBlockData->aTSKEY[pBlockData->nRow - 1]};
int32_t fid = tsdbKeyFid(keyFirst.ts, pWriter->minutes, pWriter->precision);
ASSERT(fid == tsdbKeyFid(keyLast.ts, pWriter->minutes, pWriter->precision));
@@ -895,11 +908,15 @@ static int32_t tsdbSnapWriteData(STsdbSnapWriter* pWriter, uint8_t* pData, uint3
code = tsdbDataFReaderOpen(&pWriter->pDataFReader, pTsdb, pSet);
if (code) goto _err;
- code = tsdbReadBlockIdx(pWriter->pDataFReader, pWriter->aBlockIdx, NULL);
+ code = tsdbReadBlockIdx(pWriter->pDataFReader, pWriter->aBlockIdx);
+ if (code) goto _err;
+
+ code = tsdbReadBlockL(pWriter->pDataFReader, pWriter->aBlockL);
if (code) goto _err;
} else {
ASSERT(pWriter->pDataFReader == NULL);
taosArrayClear(pWriter->aBlockIdx);
+ taosArrayClear(pWriter->aBlockL);
}
pWriter->iBlockIdx = 0;
pWriter->pBlockIdx = NULL;
@@ -907,7 +924,9 @@ static int32_t tsdbSnapWriteData(STsdbSnapWriter* pWriter, uint8_t* pData, uint3
pWriter->iBlock = 0;
pWriter->pBlockData = NULL;
pWriter->iRow = 0;
+ pWriter->iBlockL = 0;
tBlockDataReset(&pWriter->bDataR);
+ tBlockDataReset(&pWriter->lDataR);
// write
SHeadFile fHead;
@@ -928,7 +947,7 @@ static int32_t tsdbSnapWriteData(STsdbSnapWriter* pWriter, uint8_t* pData, uint3
wSet.fid = fid;
fHead = (SHeadFile){.commitID = pWriter->commitID, .offset = 0, .size = 0};
fData = (SDataFile){.commitID = pWriter->commitID, .size = 0};
- fLast = (SLastFile){.commitID = pWriter->commitID, .size = 0};
+ fLast = (SLastFile){.commitID = pWriter->commitID, .size = 0, .offset = 0};
fSma = (SSmaFile){.commitID = pWriter->commitID, .size = 0};
}
@@ -936,6 +955,7 @@ static int32_t tsdbSnapWriteData(STsdbSnapWriter* pWriter, uint8_t* pData, uint3
if (code) goto _err;
taosArrayClear(pWriter->aBlockIdxW);
+ taosArrayClear(pWriter->aBlockLW);
tMapDataReset(&pWriter->mBlockW);
pWriter->pBlockIdxW = NULL;
tBlockDataReset(&pWriter->bDataW);
@@ -963,10 +983,10 @@ static int32_t tsdbSnapWriteDel(STsdbSnapWriter* pWriter, uint8_t* pData, uint32
// reader
if (pDelFile) {
- code = tsdbDelFReaderOpen(&pWriter->pDelFReader, pDelFile, pTsdb, NULL);
+ code = tsdbDelFReaderOpen(&pWriter->pDelFReader, pDelFile, pTsdb);
if (code) goto _err;
- code = tsdbReadDelIdx(pWriter->pDelFReader, pWriter->aDelIdxR, NULL);
+ code = tsdbReadDelIdx(pWriter->pDelFReader, pWriter->aDelIdxR);
if (code) goto _err;
}
@@ -980,52 +1000,16 @@ static int32_t tsdbSnapWriteDel(STsdbSnapWriter* pWriter, uint8_t* pData, uint32
TABLEID id = *(TABLEID*)(pData + sizeof(SSnapDataHdr));
while (true) {
- SDelIdx* pDelIdx = NULL;
- int64_t n = sizeof(SSnapDataHdr) + sizeof(TABLEID);
- SDelData delData;
- SDelIdx delIdx;
- int8_t toBreak = 0;
+ if (pWriter->iDelIdx >= taosArrayGetSize(pWriter->aDelIdxR)) break;
+ if (tTABLEIDCmprFn(taosArrayGet(pWriter->aDelIdxR, pWriter->iDelIdx), &id) >= 0) break;
- if (pWriter->iDelIdx < taosArrayGetSize(pWriter->aDelIdxR)) {
- pDelIdx = (SDelIdx*)taosArrayGet(pWriter->aDelIdxR, pWriter->iDelIdx);
- }
+ SDelIdx* pDelIdx = (SDelIdx*)taosArrayGet(pWriter->aDelIdxR, pWriter->iDelIdx);
- if (pDelIdx) {
- int32_t c = tTABLEIDCmprFn(&id, pDelIdx);
- if (c < 0) {
- goto _new_del;
- } else {
- code = tsdbReadDelData(pWriter->pDelFReader, pDelIdx, pWriter->aDelData, NULL);
- if (code) goto _err;
+ code = tsdbReadDelData(pWriter->pDelFReader, pDelIdx, pWriter->aDelData);
+ if (code) goto _err;
- pWriter->iDelIdx++;
- if (c == 0) {
- toBreak = 1;
- delIdx = (SDelIdx){.suid = id.suid, .uid = id.uid};
- goto _merge_del;
- } else {
- delIdx = (SDelIdx){.suid = pDelIdx->suid, .uid = pDelIdx->uid};
- goto _write_del;
- }
- }
- }
-
- _new_del:
- toBreak = 1;
- delIdx = (SDelIdx){.suid = id.suid, .uid = id.uid};
- taosArrayClear(pWriter->aDelData);
-
- _merge_del:
- while (n < nData) {
- n += tGetDelData(pData + n, &delData);
- if (taosArrayPush(pWriter->aDelData, &delData) == NULL) {
- code = TSDB_CODE_OUT_OF_MEMORY;
- goto _err;
- }
- }
-
- _write_del:
- code = tsdbWriteDelData(pWriter->pDelFWriter, pWriter->aDelData, NULL, &delIdx);
+ SDelIdx delIdx = *pDelIdx;
+ code = tsdbWriteDelData(pWriter->pDelFWriter, pWriter->aDelData, &delIdx);
if (code) goto _err;
if (taosArrayPush(pWriter->aDelIdxW, &delIdx) == NULL) {
@@ -1033,7 +1017,40 @@ static int32_t tsdbSnapWriteDel(STsdbSnapWriter* pWriter, uint8_t* pData, uint32
goto _err;
}
- if (toBreak) break;
+ pWriter->iDelIdx++;
+ }
+
+ if (pWriter->iDelIdx < taosArrayGetSize(pWriter->aDelIdxR) &&
+ tTABLEIDCmprFn(taosArrayGet(pWriter->aDelIdxR, pWriter->iDelIdx), &id) == 0) {
+ SDelIdx* pDelIdx = (SDelIdx*)taosArrayGet(pWriter->aDelIdxR, pWriter->iDelIdx);
+
+ code = tsdbReadDelData(pWriter->pDelFReader, pDelIdx, pWriter->aDelData);
+ if (code) goto _err;
+
+ pWriter->iDelIdx++;
+ } else {
+ taosArrayClear(pWriter->aDelData);
+ }
+
+ int64_t n = sizeof(SSnapDataHdr) + sizeof(TABLEID);
+ while (n < nData) {
+ SDelData delData;
+
+ n += tGetDelData(pData + n, &delData);
+
+ if (taosArrayPush(pWriter->aDelData, &delData) == NULL) {
+ code = TSDB_CODE_OUT_OF_MEMORY;
+ goto _err;
+ }
+ }
+
+ SDelIdx delIdx = {.suid = id.suid, .uid = id.uid};
+ code = tsdbWriteDelData(pWriter->pDelFWriter, pWriter->aDelData, &delIdx);
+ if (code) goto _err;
+
+ if (taosArrayPush(pWriter->aDelIdxW, &delIdx) == NULL) {
+ code = TSDB_CODE_OUT_OF_MEMORY;
+ goto _err;
}
_exit:
@@ -1054,11 +1071,11 @@ static int32_t tsdbSnapWriteDelEnd(STsdbSnapWriter* pWriter) {
for (; pWriter->iDelIdx < taosArrayGetSize(pWriter->aDelIdxR); pWriter->iDelIdx++) {
SDelIdx* pDelIdx = (SDelIdx*)taosArrayGet(pWriter->aDelIdxR, pWriter->iDelIdx);
- code = tsdbReadDelData(pWriter->pDelFReader, pDelIdx, pWriter->aDelData, NULL);
+ code = tsdbReadDelData(pWriter->pDelFReader, pDelIdx, pWriter->aDelData);
if (code) goto _err;
- SDelIdx delIdx = (SDelIdx){.suid = pDelIdx->suid, .uid = pDelIdx->uid};
- code = tsdbWriteDelData(pWriter->pDelFWriter, pWriter->aDelData, NULL, &delIdx);
+ SDelIdx delIdx = *pDelIdx;
+ code = tsdbWriteDelData(pWriter->pDelFWriter, pWriter->aDelData, &delIdx);
if (code) goto _err;
if (taosArrayPush(pWriter->aDelIdxR, &delIdx) == NULL) {
@@ -1117,7 +1134,7 @@ int32_t tsdbSnapWriterOpen(STsdb* pTsdb, int64_t sver, int64_t ever, STsdbSnapWr
pWriter->commitID = pTsdb->pVnode->state.commitID;
// for data file
- code = tBlockDataInit(&pWriter->bData);
+ code = tBlockDataCreate(&pWriter->bData);
if (code) goto _err;
pWriter->aBlockIdx = taosArrayInit(0, sizeof(SBlockIdx));
@@ -1125,17 +1142,29 @@ int32_t tsdbSnapWriterOpen(STsdb* pTsdb, int64_t sver, int64_t ever, STsdbSnapWr
code = TSDB_CODE_OUT_OF_MEMORY;
goto _err;
}
- code = tBlockDataInit(&pWriter->bDataR);
+ code = tBlockDataCreate(&pWriter->bDataR);
if (code) goto _err;
+ pWriter->aBlockL = taosArrayInit(0, sizeof(SBlockL));
+ if (pWriter->aBlockL == NULL) {
+ code = TSDB_CODE_OUT_OF_MEMORY;
+ goto _err;
+ }
+
pWriter->aBlockIdxW = taosArrayInit(0, sizeof(SBlockIdx));
if (pWriter->aBlockIdxW == NULL) {
code = TSDB_CODE_OUT_OF_MEMORY;
goto _err;
}
- code = tBlockDataInit(&pWriter->bDataW);
+ code = tBlockDataCreate(&pWriter->bDataW);
if (code) goto _err;
+ pWriter->aBlockLW = taosArrayInit(0, sizeof(SBlockL));
+ if (pWriter->aBlockLW == NULL) {
+ code = TSDB_CODE_OUT_OF_MEMORY;
+ goto _err;
+ }
+
// for del file
pWriter->aDelIdxR = taosArrayInit(0, sizeof(SDelIdx));
if (pWriter->aDelIdxR == NULL) {
@@ -1186,6 +1215,10 @@ int32_t tsdbSnapWriterClose(STsdbSnapWriter** ppWriter, int8_t rollback) {
if (code) goto _err;
}
+ for (int32_t iBuf = 0; iBuf < sizeof(pWriter->aBuf) / sizeof(uint8_t*); iBuf++) {
+ tFree(pWriter->aBuf[iBuf]);
+ }
+
tsdbInfo("vgId:%d, vnode snapshot tsdb writer close for %s", TD_VID(pWriter->pTsdb->pVnode), pWriter->pTsdb->path);
taosMemoryFree(pWriter);
*ppWriter = NULL;
@@ -1224,6 +1257,7 @@ int32_t tsdbSnapWrite(STsdbSnapWriter* pWriter, uint8_t* pData, uint32_t nData)
_exit:
tsdbDebug("vgId:%d, tsdb snapshot write for %s succeed", TD_VID(pWriter->pTsdb->pVnode), pWriter->pTsdb->path);
+
return code;
_err:
diff --git a/source/dnode/vnode/src/tsdb/tsdbUtil.c b/source/dnode/vnode/src/tsdb/tsdbUtil.c
index 76af751196..6db9d5e6f4 100644
--- a/source/dnode/vnode/src/tsdb/tsdbUtil.c
+++ b/source/dnode/vnode/src/tsdb/tsdbUtil.c
@@ -152,25 +152,6 @@ int32_t tTABLEIDCmprFn(const void *p1, const void *p2) {
return 0;
}
-// TSDBKEY ======================================================
-static FORCE_INLINE int32_t tPutTSDBKEY(uint8_t *p, TSDBKEY *pKey) {
- int32_t n = 0;
-
- n += tPutI64v(p ? p + n : p, pKey->version);
- n += tPutI64(p ? p + n : p, pKey->ts);
-
- return n;
-}
-
-static FORCE_INLINE int32_t tGetTSDBKEY(uint8_t *p, TSDBKEY *pKey) {
- int32_t n = 0;
-
- n += tGetI64v(p + n, &pKey->version);
- n += tGetI64(p + n, &pKey->ts);
-
- return n;
-}
-
// SBlockIdx ======================================================
int32_t tPutBlockIdx(uint8_t *p, void *ph) {
int32_t n = 0;
@@ -215,34 +196,51 @@ int32_t tCmprBlockIdx(void const *lhs, void const *rhs) {
return 0;
}
+int32_t tCmprBlockL(void const *lhs, void const *rhs) {
+ SBlockIdx *lBlockIdx = (SBlockIdx *)lhs;
+ SBlockL *rBlockL = (SBlockL *)rhs;
+
+ if (lBlockIdx->suid < rBlockL->suid) {
+ return -1;
+ } else if (lBlockIdx->suid > rBlockL->suid) {
+ return 1;
+ }
+
+ if (lBlockIdx->uid < rBlockL->minUid) {
+ return -1;
+ } else if (lBlockIdx->uid > rBlockL->maxUid) {
+ return 1;
+ }
+
+ return 0;
+}
+
// SBlock ======================================================
void tBlockReset(SBlock *pBlock) {
- *pBlock =
- (SBlock){.minKey = TSDBKEY_MAX, .maxKey = TSDBKEY_MIN, .minVersion = VERSION_MAX, .maxVersion = VERSION_MIN};
+ *pBlock = (SBlock){.minKey = TSDBKEY_MAX, .maxKey = TSDBKEY_MIN, .minVer = VERSION_MAX, .maxVer = VERSION_MIN};
}
int32_t tPutBlock(uint8_t *p, void *ph) {
int32_t n = 0;
SBlock *pBlock = (SBlock *)ph;
- n += tPutTSDBKEY(p ? p + n : p, &pBlock->minKey);
- n += tPutTSDBKEY(p ? p + n : p, &pBlock->maxKey);
- n += tPutI64v(p ? p + n : p, pBlock->minVersion);
- n += tPutI64v(p ? p + n : p, pBlock->maxVersion);
+ n += tPutI64v(p ? p + n : p, pBlock->minKey.version);
+ n += tPutI64v(p ? p + n : p, pBlock->minKey.ts);
+ n += tPutI64v(p ? p + n : p, pBlock->maxKey.version);
+ n += tPutI64v(p ? p + n : p, pBlock->maxKey.ts);
+ n += tPutI64v(p ? p + n : p, pBlock->minVer);
+ n += tPutI64v(p ? p + n : p, pBlock->maxVer);
n += tPutI32v(p ? p + n : p, pBlock->nRow);
- n += tPutI8(p ? p + n : p, pBlock->last);
n += tPutI8(p ? p + n : p, pBlock->hasDup);
n += tPutI8(p ? p + n : p, pBlock->nSubBlock);
for (int8_t iSubBlock = 0; iSubBlock < pBlock->nSubBlock; iSubBlock++) {
- n += tPutI32v(p ? p + n : p, pBlock->aSubBlock[iSubBlock].nRow);
- n += tPutI8(p ? p + n : p, pBlock->aSubBlock[iSubBlock].cmprAlg);
n += tPutI64v(p ? p + n : p, pBlock->aSubBlock[iSubBlock].offset);
- n += tPutI32v(p ? p + n : p, pBlock->aSubBlock[iSubBlock].szBlockCol);
- n += tPutI32v(p ? p + n : p, pBlock->aSubBlock[iSubBlock].szVersion);
- n += tPutI32v(p ? p + n : p, pBlock->aSubBlock[iSubBlock].szTSKEY);
n += tPutI32v(p ? p + n : p, pBlock->aSubBlock[iSubBlock].szBlock);
- n += tPutI64v(p ? p + n : p, pBlock->aSubBlock[iSubBlock].sOffset);
- n += tPutI32v(p ? p + n : p, pBlock->aSubBlock[iSubBlock].nSma);
+ n += tPutI32v(p ? p + n : p, pBlock->aSubBlock[iSubBlock].szKey);
+ }
+ if (pBlock->nSubBlock == 1 && !pBlock->hasDup) {
+ n += tPutI64v(p ? p + n : p, pBlock->smaInfo.offset);
+ n += tPutI32v(p ? p + n : p, pBlock->smaInfo.size);
}
return n;
@@ -252,24 +250,26 @@ int32_t tGetBlock(uint8_t *p, void *ph) {
int32_t n = 0;
SBlock *pBlock = (SBlock *)ph;
- n += tGetTSDBKEY(p + n, &pBlock->minKey);
- n += tGetTSDBKEY(p + n, &pBlock->maxKey);
- n += tGetI64v(p + n, &pBlock->minVersion);
- n += tGetI64v(p + n, &pBlock->maxVersion);
+ n += tGetI64v(p + n, &pBlock->minKey.version);
+ n += tGetI64v(p + n, &pBlock->minKey.ts);
+ n += tGetI64v(p + n, &pBlock->maxKey.version);
+ n += tGetI64v(p + n, &pBlock->maxKey.ts);
+ n += tGetI64v(p + n, &pBlock->minVer);
+ n += tGetI64v(p + n, &pBlock->maxVer);
n += tGetI32v(p + n, &pBlock->nRow);
- n += tGetI8(p + n, &pBlock->last);
n += tGetI8(p + n, &pBlock->hasDup);
n += tGetI8(p + n, &pBlock->nSubBlock);
for (int8_t iSubBlock = 0; iSubBlock < pBlock->nSubBlock; iSubBlock++) {
- n += tGetI32v(p + n, &pBlock->aSubBlock[iSubBlock].nRow);
- n += tGetI8(p + n, &pBlock->aSubBlock[iSubBlock].cmprAlg);
n += tGetI64v(p + n, &pBlock->aSubBlock[iSubBlock].offset);
- n += tGetI32v(p + n, &pBlock->aSubBlock[iSubBlock].szBlockCol);
- n += tGetI32v(p + n, &pBlock->aSubBlock[iSubBlock].szVersion);
- n += tGetI32v(p + n, &pBlock->aSubBlock[iSubBlock].szTSKEY);
n += tGetI32v(p + n, &pBlock->aSubBlock[iSubBlock].szBlock);
- n += tGetI64v(p + n, &pBlock->aSubBlock[iSubBlock].sOffset);
- n += tGetI32v(p + n, &pBlock->aSubBlock[iSubBlock].nSma);
+ n += tGetI32v(p + n, &pBlock->aSubBlock[iSubBlock].szKey);
+ }
+ if (pBlock->nSubBlock == 1 && !pBlock->hasDup) {
+ n += tGetI64v(p + n, &pBlock->smaInfo.offset);
+ n += tGetI32v(p + n, &pBlock->smaInfo.size);
+ } else {
+ pBlock->smaInfo.offset = 0;
+ pBlock->smaInfo.size = 0;
}
return n;
@@ -290,10 +290,48 @@ int32_t tBlockCmprFn(const void *p1, const void *p2) {
bool tBlockHasSma(SBlock *pBlock) {
if (pBlock->nSubBlock > 1) return false;
- if (pBlock->last) return false;
if (pBlock->hasDup) return false;
- return pBlock->aSubBlock[0].nSma > 0;
+ return pBlock->smaInfo.size > 0;
+}
+
+// SBlockL ======================================================
+int32_t tPutBlockL(uint8_t *p, void *ph) {
+ int32_t n = 0;
+ SBlockL *pBlockL = (SBlockL *)ph;
+
+ n += tPutI64(p ? p + n : p, pBlockL->suid);
+ n += tPutI64(p ? p + n : p, pBlockL->minUid);
+ n += tPutI64(p ? p + n : p, pBlockL->maxUid);
+ n += tPutI64v(p ? p + n : p, pBlockL->minKey);
+ n += tPutI64v(p ? p + n : p, pBlockL->maxKey);
+ n += tPutI64v(p ? p + n : p, pBlockL->minVer);
+ n += tPutI64v(p ? p + n : p, pBlockL->maxVer);
+ n += tPutI32v(p ? p + n : p, pBlockL->nRow);
+ n += tPutI64v(p ? p + n : p, pBlockL->bInfo.offset);
+ n += tPutI32v(p ? p + n : p, pBlockL->bInfo.szBlock);
+ n += tPutI32v(p ? p + n : p, pBlockL->bInfo.szKey);
+
+ return n;
+}
+
+int32_t tGetBlockL(uint8_t *p, void *ph) {
+ int32_t n = 0;
+ SBlockL *pBlockL = (SBlockL *)ph;
+
+ n += tGetI64(p + n, &pBlockL->suid);
+ n += tGetI64(p + n, &pBlockL->minUid);
+ n += tGetI64(p + n, &pBlockL->maxUid);
+ n += tGetI64v(p + n, &pBlockL->minKey);
+ n += tGetI64v(p + n, &pBlockL->maxKey);
+ n += tGetI64v(p + n, &pBlockL->minVer);
+ n += tGetI64v(p + n, &pBlockL->maxVer);
+ n += tGetI32v(p + n, &pBlockL->nRow);
+ n += tGetI64v(p + n, &pBlockL->bInfo.offset);
+ n += tGetI32v(p + n, &pBlockL->bInfo.szBlock);
+ n += tGetI32v(p + n, &pBlockL->bInfo.szKey);
+
+ return n;
}
// SBlockCol ======================================================
@@ -307,15 +345,25 @@ int32_t tPutBlockCol(uint8_t *p, void *ph) {
n += tPutI8(p ? p + n : p, pBlockCol->type);
n += tPutI8(p ? p + n : p, pBlockCol->smaOn);
n += tPutI8(p ? p + n : p, pBlockCol->flag);
+ n += tPutI32v(p ? p + n : p, pBlockCol->szOrigin);
if (pBlockCol->flag != HAS_NULL) {
+ if (pBlockCol->flag != HAS_VALUE) {
+ n += tPutI32v(p ? p + n : p, pBlockCol->szBitmap);
+ }
+
+ if (IS_VAR_DATA_TYPE(pBlockCol->type)) {
+ n += tPutI32v(p ? p + n : p, pBlockCol->szOffset);
+ }
+
+ if (pBlockCol->flag != (HAS_NULL | HAS_NONE)) {
+ n += tPutI32v(p ? p + n : p, pBlockCol->szValue);
+ }
+
n += tPutI32v(p ? p + n : p, pBlockCol->offset);
- n += tPutI32v(p ? p + n : p, pBlockCol->szBitmap);
- n += tPutI32v(p ? p + n : p, pBlockCol->szOffset);
- n += tPutI32v(p ? p + n : p, pBlockCol->szValue);
- n += tPutI32v(p ? p + n : p, pBlockCol->szOrigin);
}
+_exit:
return n;
}
@@ -327,15 +375,29 @@ int32_t tGetBlockCol(uint8_t *p, void *ph) {
n += tGetI8(p + n, &pBlockCol->type);
n += tGetI8(p + n, &pBlockCol->smaOn);
n += tGetI8(p + n, &pBlockCol->flag);
+ n += tGetI32v(p + n, &pBlockCol->szOrigin);
ASSERT(pBlockCol->flag && (pBlockCol->flag != HAS_NONE));
+ pBlockCol->szBitmap = 0;
+ pBlockCol->szOffset = 0;
+ pBlockCol->szValue = 0;
+ pBlockCol->offset = 0;
+
if (pBlockCol->flag != HAS_NULL) {
+ if (pBlockCol->flag != HAS_VALUE) {
+ n += tGetI32v(p + n, &pBlockCol->szBitmap);
+ }
+
+ if (IS_VAR_DATA_TYPE(pBlockCol->type)) {
+ n += tGetI32v(p + n, &pBlockCol->szOffset);
+ }
+
+ if (pBlockCol->flag != (HAS_NULL | HAS_NONE)) {
+ n += tGetI32v(p + n, &pBlockCol->szValue);
+ }
+
n += tGetI32v(p + n, &pBlockCol->offset);
- n += tGetI32v(p + n, &pBlockCol->szBitmap);
- n += tGetI32v(p + n, &pBlockCol->szOffset);
- n += tGetI32v(p + n, &pBlockCol->szValue);
- n += tGetI32v(p + n, &pBlockCol->szOrigin);
}
return n;
@@ -866,6 +928,9 @@ int32_t tColDataAppendValue(SColData *pColData, SColVal *pColVal) {
size = BIT2_SIZE(pColData->nVal + 1);
code = tRealloc(&pColData->pBitMap, size);
if (code) goto _exit;
+ if ((pColData->nVal & 3) == 0) {
+ pColData->pBitMap[pColData->nVal >> 2] = 0;
+ }
// put value
if (pColVal->isNone) {
@@ -910,13 +975,14 @@ int32_t tColDataCopy(SColData *pColDataSrc, SColData *pColDataDest) {
int32_t size;
ASSERT(pColDataSrc->nVal > 0);
+ ASSERT(pColDataDest->cid = pColDataSrc->cid);
+ ASSERT(pColDataDest->type = pColDataSrc->type);
- pColDataDest->cid = pColDataSrc->cid;
- pColDataDest->type = pColDataSrc->type;
pColDataDest->smaOn = pColDataSrc->smaOn;
pColDataDest->nVal = pColDataSrc->nVal;
pColDataDest->flag = pColDataSrc->flag;
+ // bitmap
if (pColDataSrc->flag != HAS_NONE && pColDataSrc->flag != HAS_NULL && pColDataSrc->flag != HAS_VALUE) {
size = BIT2_SIZE(pColDataSrc->nVal);
code = tRealloc(&pColDataDest->pBitMap, size);
@@ -924,6 +990,7 @@ int32_t tColDataCopy(SColData *pColDataSrc, SColData *pColDataDest) {
memcpy(pColDataDest->pBitMap, pColDataSrc->pBitMap, size);
}
+ // offset
if (IS_VAR_DATA_TYPE(pColDataDest->type)) {
size = sizeof(int32_t) * pColDataSrc->nVal;
@@ -933,9 +1000,10 @@ int32_t tColDataCopy(SColData *pColDataSrc, SColData *pColDataDest) {
memcpy(pColDataDest->aOffset, pColDataSrc->aOffset, size);
}
+ // value
+ pColDataDest->nData = pColDataSrc->nData;
code = tRealloc(&pColDataDest->pData, pColDataSrc->nData);
if (code) goto _exit;
- pColDataDest->nData = pColDataSrc->nData;
memcpy(pColDataDest->pData, pColDataSrc->pData, pColDataDest->nData);
_exit:
@@ -1068,10 +1136,13 @@ static FORCE_INLINE int32_t tColDataCmprFn(const void *p1, const void *p2) {
}
// SBlockData ======================================================
-int32_t tBlockDataInit(SBlockData *pBlockData) {
+int32_t tBlockDataCreate(SBlockData *pBlockData) {
int32_t code = 0;
+ pBlockData->suid = 0;
+ pBlockData->uid = 0;
pBlockData->nRow = 0;
+ pBlockData->aUid = NULL;
pBlockData->aVersion = NULL;
pBlockData->aTSKEY = NULL;
pBlockData->aIdx = taosArrayInit(0, sizeof(int32_t));
@@ -1090,42 +1161,77 @@ _exit:
return code;
}
-void tBlockDataReset(SBlockData *pBlockData) {
- pBlockData->nRow = 0;
- taosArrayClear(pBlockData->aIdx);
-}
-
-void tBlockDataClear(SBlockData *pBlockData, int8_t deepClear) {
+void tBlockDataDestroy(SBlockData *pBlockData, int8_t deepClear) {
+ tFree((uint8_t *)pBlockData->aUid);
tFree((uint8_t *)pBlockData->aVersion);
tFree((uint8_t *)pBlockData->aTSKEY);
taosArrayDestroy(pBlockData->aIdx);
taosArrayDestroyEx(pBlockData->aColData, deepClear ? tColDataClear : NULL);
- pBlockData->aColData = NULL;
- pBlockData->aIdx = NULL;
- pBlockData->aTSKEY = NULL;
+ pBlockData->aUid = NULL;
pBlockData->aVersion = NULL;
+ pBlockData->aTSKEY = NULL;
+ pBlockData->aIdx = NULL;
+ pBlockData->aColData = NULL;
}
-int32_t tBlockDataSetSchema(SBlockData *pBlockData, STSchema *pTSchema) {
- int32_t code = 0;
- SColData *pColData;
- STColumn *pTColumn;
+int32_t tBlockDataInit(SBlockData *pBlockData, int64_t suid, int64_t uid, STSchema *pTSchema) {
+ int32_t code = 0;
- tBlockDataReset(pBlockData);
+ ASSERT(suid || uid);
+
+ pBlockData->suid = suid;
+ pBlockData->uid = uid;
+ pBlockData->nRow = 0;
+
+ taosArrayClear(pBlockData->aIdx);
for (int32_t iColumn = 1; iColumn < pTSchema->numOfCols; iColumn++) {
- pTColumn = &pTSchema->columns[iColumn];
+ STColumn *pTColumn = &pTSchema->columns[iColumn];
+ SColData *pColData;
code = tBlockDataAddColData(pBlockData, iColumn - 1, &pColData);
if (code) goto _exit;
- tColDataInit(pColData, pTColumn->colId, pTColumn->type, (pTColumn->flags & COL_SMA_ON) != 0);
+ tColDataInit(pColData, pTColumn->colId, pTColumn->type, (pTColumn->flags & COL_SMA_ON) ? 1 : 0);
}
_exit:
return code;
}
-void tBlockDataClearData(SBlockData *pBlockData) {
+int32_t tBlockDataInitEx(SBlockData *pBlockData, SBlockData *pBlockDataFrom) {
+ int32_t code = 0;
+
+ ASSERT(pBlockDataFrom->suid || pBlockDataFrom->uid);
+
+ pBlockData->suid = pBlockDataFrom->suid;
+ pBlockData->uid = pBlockDataFrom->uid;
+ pBlockData->nRow = 0;
+
+ taosArrayClear(pBlockData->aIdx);
+ for (int32_t iColData = 0; iColData < taosArrayGetSize(pBlockDataFrom->aIdx); iColData++) {
+ SColData *pColDataFrom = tBlockDataGetColDataByIdx(pBlockDataFrom, iColData);
+
+ SColData *pColData;
+ code = tBlockDataAddColData(pBlockData, iColData, &pColData);
+ if (code) goto _exit;
+
+ tColDataInit(pColData, pColDataFrom->cid, pColDataFrom->type, pColDataFrom->smaOn);
+ }
+
+_exit:
+ return code;
+}
+
+void tBlockDataReset(SBlockData *pBlockData) {
+ pBlockData->suid = 0;
+ pBlockData->uid = 0;
+ pBlockData->nRow = 0;
+ taosArrayClear(pBlockData->aIdx);
+}
+
+void tBlockDataClear(SBlockData *pBlockData) {
+ ASSERT(pBlockData->suid || pBlockData->uid);
+
pBlockData->nRow = 0;
for (int32_t iColData = 0; iColData < taosArrayGetSize(pBlockData->aIdx); iColData++) {
SColData *pColData = tBlockDataGetColDataByIdx(pBlockData, iColData);
@@ -1159,52 +1265,47 @@ _err:
return code;
}
-int32_t tBlockDataAppendRow(SBlockData *pBlockData, TSDBROW *pRow, STSchema *pTSchema) {
+int32_t tBlockDataAppendRow(SBlockData *pBlockData, TSDBROW *pRow, STSchema *pTSchema, int64_t uid) {
int32_t code = 0;
- // TSDBKEY
+ ASSERT(pBlockData->suid || pBlockData->uid);
+
+ // uid
+ if (pBlockData->uid == 0) {
+ ASSERT(uid);
+ code = tRealloc((uint8_t **)&pBlockData->aUid, sizeof(int64_t) * (pBlockData->nRow + 1));
+ if (code) goto _err;
+ pBlockData->aUid[pBlockData->nRow] = uid;
+ }
+ // version
code = tRealloc((uint8_t **)&pBlockData->aVersion, sizeof(int64_t) * (pBlockData->nRow + 1));
if (code) goto _err;
+ pBlockData->aVersion[pBlockData->nRow] = TSDBROW_VERSION(pRow);
+ // timestamp
code = tRealloc((uint8_t **)&pBlockData->aTSKEY, sizeof(TSKEY) * (pBlockData->nRow + 1));
if (code) goto _err;
- pBlockData->aVersion[pBlockData->nRow] = TSDBROW_VERSION(pRow);
pBlockData->aTSKEY[pBlockData->nRow] = TSDBROW_TS(pRow);
// OTHER
- int32_t iColData = 0;
- int32_t nColData = taosArrayGetSize(pBlockData->aIdx);
- SRowIter iter = {0};
- SRowIter *pIter = &iter;
- SColData *pColData;
- SColVal *pColVal;
+ SRowIter rIter = {0};
+ SColVal *pColVal;
- if (nColData == 0) goto _exit;
+ tRowIterInit(&rIter, pRow, pTSchema);
+ pColVal = tRowIterNext(&rIter);
+ for (int32_t iColData = 0; iColData < taosArrayGetSize(pBlockData->aIdx); iColData++) {
+ SColData *pColData = tBlockDataGetColDataByIdx(pBlockData, iColData);
- tRowIterInit(pIter, pRow, pTSchema);
- pColData = tBlockDataGetColDataByIdx(pBlockData, iColData);
- pColVal = tRowIterNext(pIter);
+ while (pColVal && pColVal->cid < pColData->cid) {
+ pColVal = tRowIterNext(&rIter);
+ }
- while (pColData) {
- if (pColVal) {
- if (pColData->cid == pColVal->cid) {
- code = tColDataAppendValue(pColData, pColVal);
- if (code) goto _err;
-
- pColVal = tRowIterNext(pIter);
- pColData = ((++iColData) < nColData) ? tBlockDataGetColDataByIdx(pBlockData, iColData) : NULL;
- } else if (pColData->cid < pColVal->cid) {
- code = tColDataAppendValue(pColData, &COL_VAL_NONE(pColData->cid, pColData->type));
- if (code) goto _err;
-
- pColData = ((++iColData) < nColData) ? tBlockDataGetColDataByIdx(pBlockData, iColData) : NULL;
- } else {
- pColVal = tRowIterNext(pIter);
- }
- } else {
+ if (pColVal == NULL || pColVal->cid > pColData->cid) {
code = tColDataAppendValue(pColData, &COL_VAL_NONE(pColData->cid, pColData->type));
if (code) goto _err;
-
- pColData = ((++iColData) < nColData) ? tBlockDataGetColDataByIdx(pBlockData, iColData) : NULL;
+ } else {
+ code = tColDataAppendValue(pColData, pColVal);
+ if (code) goto _err;
+ pColVal = tRowIterNext(&rIter);
}
}
@@ -1259,128 +1360,111 @@ _exit:
int32_t tBlockDataMerge(SBlockData *pBlockData1, SBlockData *pBlockData2, SBlockData *pBlockData) {
int32_t code = 0;
- // set target
- int32_t iColData1 = 0;
- int32_t nColData1 = taosArrayGetSize(pBlockData1->aIdx);
- int32_t iColData2 = 0;
- int32_t nColData2 = taosArrayGetSize(pBlockData2->aIdx);
- SColData *pColData1;
- SColData *pColData2;
- SColData *pColData;
+ ASSERT(pBlockData->suid == pBlockData1->suid);
+ ASSERT(pBlockData->uid == pBlockData1->uid);
+ ASSERT(pBlockData1->nRow > 0);
+ ASSERT(pBlockData2->nRow > 0);
- tBlockDataReset(pBlockData);
- while (iColData1 < nColData1 && iColData2 < nColData2) {
- pColData1 = tBlockDataGetColDataByIdx(pBlockData1, iColData1);
- pColData2 = tBlockDataGetColDataByIdx(pBlockData2, iColData2);
+ tBlockDataClear(pBlockData);
- if (pColData1->cid == pColData2->cid) {
- code = tBlockDataAddColData(pBlockData, taosArrayGetSize(pBlockData->aIdx), &pColData);
- if (code) goto _exit;
- tColDataInit(pColData, pColData2->cid, pColData2->type, pColData2->smaOn);
+ TSDBROW row1 = tsdbRowFromBlockData(pBlockData1, 0);
+ TSDBROW row2 = tsdbRowFromBlockData(pBlockData2, 0);
+ TSDBROW *pRow1 = &row1;
+ TSDBROW *pRow2 = &row2;
- iColData1++;
- iColData2++;
- } else if (pColData1->cid < pColData2->cid) {
- code = tBlockDataAddColData(pBlockData, taosArrayGetSize(pBlockData->aIdx), &pColData);
- if (code) goto _exit;
- tColDataInit(pColData, pColData1->cid, pColData1->type, pColData1->smaOn);
+ while (pRow1 && pRow2) {
+ int32_t c = tsdbRowCmprFn(pRow1, pRow2);
- iColData1++;
- } else {
- code = tBlockDataAddColData(pBlockData, taosArrayGetSize(pBlockData->aIdx), &pColData);
- if (code) goto _exit;
- tColDataInit(pColData, pColData2->cid, pColData2->type, pColData2->smaOn);
-
- iColData2++;
- }
- }
-
- while (iColData1 < nColData1) {
- code = tBlockDataAddColData(pBlockData, taosArrayGetSize(pBlockData->aIdx), &pColData);
- if (code) goto _exit;
- tColDataInit(pColData, pColData1->cid, pColData1->type, pColData1->smaOn);
-
- iColData1++;
- }
-
- while (iColData2 < nColData2) {
- code = tBlockDataAddColData(pBlockData, taosArrayGetSize(pBlockData->aIdx), &pColData);
- if (code) goto _exit;
- tColDataInit(pColData, pColData2->cid, pColData2->type, pColData2->smaOn);
-
- iColData2++;
- }
-
- // loop to merge
- int32_t iRow1 = 0;
- int32_t nRow1 = pBlockData1->nRow;
- int32_t iRow2 = 0;
- int32_t nRow2 = pBlockData2->nRow;
- TSDBROW row1;
- TSDBROW row2;
- int32_t c;
-
- while (iRow1 < nRow1 && iRow2 < nRow2) {
- row1 = tsdbRowFromBlockData(pBlockData1, iRow1);
- row2 = tsdbRowFromBlockData(pBlockData2, iRow2);
-
- c = tsdbKeyCmprFn(&TSDBROW_KEY(&row1), &TSDBROW_KEY(&row2));
if (c < 0) {
- code = tBlockDataAppendRow(pBlockData, &row1, NULL);
+ code = tBlockDataAppendRow(pBlockData, pRow1, NULL,
+ pBlockData1->uid ? pBlockData1->uid : pBlockData1->aUid[pRow1->iRow]);
if (code) goto _exit;
- iRow1++;
+
+ pRow1->iRow++;
+ if (pRow1->iRow < pBlockData1->nRow) {
+ *pRow1 = tsdbRowFromBlockData(pBlockData1, pRow1->iRow);
+ } else {
+ pRow1 = NULL;
+ }
} else if (c > 0) {
- code = tBlockDataAppendRow(pBlockData, &row2, NULL);
+ code = tBlockDataAppendRow(pBlockData, pRow2, NULL,
+ pBlockData2->uid ? pBlockData2->uid : pBlockData2->aUid[pRow2->iRow]);
if (code) goto _exit;
- iRow2++;
+
+ pRow2->iRow++;
+ if (pRow2->iRow < pBlockData2->nRow) {
+ *pRow2 = tsdbRowFromBlockData(pBlockData2, pRow2->iRow);
+ } else {
+ pRow2 = NULL;
+ }
} else {
ASSERT(0);
}
}
- while (iRow1 < nRow1) {
- row1 = tsdbRowFromBlockData(pBlockData1, iRow1);
- code = tBlockDataAppendRow(pBlockData, &row1, NULL);
+ while (pRow1) {
+ code = tBlockDataAppendRow(pBlockData, pRow1, NULL,
+ pBlockData1->uid ? pBlockData1->uid : pBlockData1->aUid[pRow1->iRow]);
if (code) goto _exit;
- iRow1++;
+
+ pRow1->iRow++;
+ if (pRow1->iRow < pBlockData1->nRow) {
+ *pRow1 = tsdbRowFromBlockData(pBlockData1, pRow1->iRow);
+ } else {
+ pRow1 = NULL;
+ }
}
- while (iRow2 < nRow2) {
- row2 = tsdbRowFromBlockData(pBlockData2, iRow2);
- code = tBlockDataAppendRow(pBlockData, &row2, NULL);
+ while (pRow2) {
+ code = tBlockDataAppendRow(pBlockData, pRow2, NULL,
+ pBlockData2->uid ? pBlockData2->uid : pBlockData2->aUid[pRow2->iRow]);
if (code) goto _exit;
- iRow2++;
+
+ pRow2->iRow++;
+ if (pRow2->iRow < pBlockData2->nRow) {
+ *pRow2 = tsdbRowFromBlockData(pBlockData2, pRow2->iRow);
+ } else {
+ pRow2 = NULL;
+ }
}
_exit:
return code;
}
-int32_t tBlockDataCopy(SBlockData *pBlockDataSrc, SBlockData *pBlockDataDest) {
- int32_t code = 0;
- SColData *pColDataSrc;
- SColData *pColDataDest;
+int32_t tBlockDataCopy(SBlockData *pSrc, SBlockData *pDest) {
+ int32_t code = 0;
- ASSERT(pBlockDataSrc->nRow > 0);
+ tBlockDataClear(pDest);
- tBlockDataReset(pBlockDataDest);
+ ASSERT(pDest->suid == pSrc->suid);
+ ASSERT(pDest->uid == pSrc->uid);
+ ASSERT(taosArrayGetSize(pSrc->aIdx) == taosArrayGetSize(pDest->aIdx));
- pBlockDataDest->nRow = pBlockDataSrc->nRow;
- // TSDBKEY
- code = tRealloc((uint8_t **)&pBlockDataDest->aVersion, sizeof(int64_t) * pBlockDataSrc->nRow);
- if (code) goto _exit;
- code = tRealloc((uint8_t **)&pBlockDataDest->aTSKEY, sizeof(TSKEY) * pBlockDataSrc->nRow);
- if (code) goto _exit;
- memcpy(pBlockDataDest->aVersion, pBlockDataSrc->aVersion, sizeof(int64_t) * pBlockDataSrc->nRow);
- memcpy(pBlockDataDest->aTSKEY, pBlockDataSrc->aTSKEY, sizeof(TSKEY) * pBlockDataSrc->nRow);
+ pDest->nRow = pSrc->nRow;
- // other
- for (size_t iColData = 0; iColData < taosArrayGetSize(pBlockDataSrc->aIdx); iColData++) {
- pColDataSrc = tBlockDataGetColDataByIdx(pBlockDataSrc, iColData);
- code = tBlockDataAddColData(pBlockDataDest, iColData, &pColDataDest);
+ if (pSrc->uid == 0) {
+ code = tRealloc((uint8_t **)&pDest->aUid, sizeof(int64_t) * pDest->nRow);
if (code) goto _exit;
+ memcpy(pDest->aUid, pSrc->aUid, sizeof(int64_t) * pDest->nRow);
+ }
- code = tColDataCopy(pColDataSrc, pColDataDest);
+ code = tRealloc((uint8_t **)&pDest->aVersion, sizeof(int64_t) * pDest->nRow);
+ if (code) goto _exit;
+ memcpy(pDest->aVersion, pSrc->aVersion, sizeof(int64_t) * pDest->nRow);
+
+ code = tRealloc((uint8_t **)&pDest->aTSKEY, sizeof(TSKEY) * pDest->nRow);
+ if (code) goto _exit;
+ memcpy(pDest->aTSKEY, pSrc->aTSKEY, sizeof(TSKEY) * pDest->nRow);
+
+ for (int32_t iColData = 0; iColData < taosArrayGetSize(pSrc->aIdx); iColData++) {
+ SColData *pColSrc = tBlockDataGetColDataByIdx(pSrc, iColData);
+ SColData *pColDest = tBlockDataGetColDataByIdx(pDest, iColData);
+
+ ASSERT(pColSrc->cid == pColDest->cid);
+ ASSERT(pColSrc->type == pColDest->type);
+
+ code = tColDataCopy(pColSrc, pColDest);
if (code) goto _exit;
}
@@ -1416,53 +1500,241 @@ void tBlockDataGetColData(SBlockData *pBlockData, int16_t cid, SColData **ppColD
*ppColData = NULL;
}
-int32_t tPutBlockData(uint8_t *p, SBlockData *pBlockData) {
- int32_t n = 0;
+int32_t tCmprBlockData(SBlockData *pBlockData, int8_t cmprAlg, uint8_t **ppOut, int32_t *szOut, uint8_t *aBuf[],
+ int32_t aBufN[]) {
+ int32_t code = 0;
- n += tPutI32v(p ? p + n : p, pBlockData->nRow);
- if (p) {
- memcpy(p + n, pBlockData->aVersion, sizeof(int64_t) * pBlockData->nRow);
- }
- n = n + sizeof(int64_t) * pBlockData->nRow;
- if (p) {
- memcpy(p + n, pBlockData->aTSKEY, sizeof(TSKEY) * pBlockData->nRow);
- }
- n = n + sizeof(TSKEY) * pBlockData->nRow;
+ SDiskDataHdr hdr = {.delimiter = TSDB_FILE_DLMT,
+ .fmtVer = 0,
+ .suid = pBlockData->suid,
+ .uid = pBlockData->uid,
+ .nRow = pBlockData->nRow,
+ .cmprAlg = cmprAlg};
- int32_t nCol = taosArrayGetSize(pBlockData->aIdx);
- n += tPutI32v(p ? p + n : p, nCol);
- for (int32_t iCol = 0; iCol < nCol; iCol++) {
- SColData *pColData = tBlockDataGetColDataByIdx(pBlockData, iCol);
- n += tPutColData(p ? p + n : p, pColData);
+ // encode =================
+ // columns AND SBlockCol
+ aBufN[0] = 0;
+ for (int32_t iColData = 0; iColData < taosArrayGetSize(pBlockData->aIdx); iColData++) {
+ SColData *pColData = tBlockDataGetColDataByIdx(pBlockData, iColData);
+
+ ASSERT(pColData->flag);
+
+ if (pColData->flag == HAS_NONE) continue;
+
+ SBlockCol blockCol = {.cid = pColData->cid,
+ .type = pColData->type,
+ .smaOn = pColData->smaOn,
+ .flag = pColData->flag,
+ .szOrigin = pColData->nData};
+
+ if (pColData->flag != HAS_NULL) {
+ code = tsdbCmprColData(pColData, cmprAlg, &blockCol, &aBuf[0], aBufN[0], &aBuf[2]);
+ if (code) goto _exit;
+
+ blockCol.offset = aBufN[0];
+ aBufN[0] = aBufN[0] + blockCol.szBitmap + blockCol.szOffset + blockCol.szValue + sizeof(TSCKSUM);
+ }
+
+ code = tRealloc(&aBuf[1], hdr.szBlkCol + tPutBlockCol(NULL, &blockCol));
+ if (code) goto _exit;
+ hdr.szBlkCol += tPutBlockCol(aBuf[1] + hdr.szBlkCol, &blockCol);
}
+ aBufN[1] = 0;
+ if (hdr.szBlkCol > 0) {
+ aBufN[1] = hdr.szBlkCol + sizeof(TSCKSUM);
+
+ code = tRealloc(&aBuf[1], aBufN[1]);
+ if (code) goto _exit;
+
+ taosCalcChecksumAppend(0, aBuf[1], aBufN[1]);
+ }
+
+ // uid + version + tskey
+ aBufN[2] = 0;
+ if (pBlockData->uid == 0) {
+ code = tsdbCmprData((uint8_t *)pBlockData->aUid, sizeof(int64_t) * pBlockData->nRow, TSDB_DATA_TYPE_BIGINT, cmprAlg,
+ &aBuf[2], aBufN[2], &hdr.szUid, &aBuf[3]);
+ if (code) goto _exit;
+ }
+ aBufN[2] += hdr.szUid;
+
+ code = tsdbCmprData((uint8_t *)pBlockData->aVersion, sizeof(int64_t) * pBlockData->nRow, TSDB_DATA_TYPE_BIGINT,
+ cmprAlg, &aBuf[2], aBufN[2], &hdr.szVer, &aBuf[3]);
+ if (code) goto _exit;
+ aBufN[2] += hdr.szVer;
+
+ code = tsdbCmprData((uint8_t *)pBlockData->aTSKEY, sizeof(TSKEY) * pBlockData->nRow, TSDB_DATA_TYPE_TIMESTAMP,
+ cmprAlg, &aBuf[2], aBufN[2], &hdr.szKey, &aBuf[3]);
+ if (code) goto _exit;
+ aBufN[2] += hdr.szKey;
+
+ aBufN[2] += sizeof(TSCKSUM);
+ code = tRealloc(&aBuf[2], aBufN[2]);
+ if (code) goto _exit;
+
+ // hdr
+ aBufN[3] = tPutDiskDataHdr(NULL, &hdr);
+ code = tRealloc(&aBuf[3], aBufN[3]);
+ if (code) goto _exit;
+ tPutDiskDataHdr(aBuf[3], &hdr);
+ taosCalcChecksumAppend(taosCalcChecksum(0, aBuf[3], aBufN[3]), aBuf[2], aBufN[2]);
+
+ // aggragate
+ if (ppOut) {
+ *szOut = aBufN[0] + aBufN[1] + aBufN[2] + aBufN[3];
+ code = tRealloc(ppOut, *szOut);
+ if (code) goto _exit;
+
+ memcpy(*ppOut, aBuf[3], aBufN[3]);
+ memcpy(*ppOut + aBufN[3], aBuf[2], aBufN[2]);
+ if (aBufN[1]) {
+ memcpy(*ppOut + aBufN[3] + aBufN[2], aBuf[1], aBufN[1]);
+ }
+ if (aBufN[0]) {
+ memcpy(*ppOut + aBufN[3] + aBufN[2] + aBufN[1], aBuf[0], aBufN[0]);
+ }
+ }
+
+_exit:
+ return code;
+}
+
+int32_t tDecmprBlockData(uint8_t *pIn, int32_t szIn, SBlockData *pBlockData, uint8_t *aBuf[]) {
+ int32_t code = 0;
+
+ tBlockDataClear(pBlockData);
+
+ int32_t n = 0;
+ SDiskDataHdr hdr = {0};
+
+ // SDiskDataHdr
+ n += tGetDiskDataHdr(pIn + n, &hdr);
+ if (!taosCheckChecksumWhole(pIn, n + hdr.szUid + hdr.szVer + hdr.szKey + sizeof(TSCKSUM))) {
+ code = TSDB_CODE_FILE_CORRUPTED;
+ goto _exit;
+ }
+ ASSERT(hdr.delimiter == TSDB_FILE_DLMT);
+
+ pBlockData->suid = hdr.suid;
+ pBlockData->uid = hdr.uid;
+ pBlockData->nRow = hdr.nRow;
+
+ // uid
+ if (hdr.uid == 0) {
+ ASSERT(hdr.szUid);
+ code = tsdbDecmprData(pIn + n, hdr.szUid, TSDB_DATA_TYPE_BIGINT, hdr.cmprAlg, (uint8_t **)&pBlockData->aUid,
+ sizeof(int64_t) * hdr.nRow, &aBuf[0]);
+ if (code) goto _exit;
+ } else {
+ ASSERT(!hdr.szUid);
+ }
+ n += hdr.szUid;
+
+ // version
+ code = tsdbDecmprData(pIn + n, hdr.szVer, TSDB_DATA_TYPE_BIGINT, hdr.cmprAlg, (uint8_t **)&pBlockData->aVersion,
+ sizeof(int64_t) * hdr.nRow, &aBuf[0]);
+ if (code) goto _exit;
+ n += hdr.szVer;
+
+ // TSKEY
+ code = tsdbDecmprData(pIn + n, hdr.szKey, TSDB_DATA_TYPE_TIMESTAMP, hdr.cmprAlg, (uint8_t **)&pBlockData->aTSKEY,
+ sizeof(TSKEY) * hdr.nRow, &aBuf[0]);
+ if (code) goto _exit;
+ n = n + hdr.szKey + sizeof(TSCKSUM);
+
+ // loop to decode each column data
+ if (hdr.szBlkCol == 0) goto _exit;
+
+ int32_t nt = 0;
+ while (nt < hdr.szBlkCol) {
+ SBlockCol blockCol = {0};
+ nt += tGetBlockCol(pIn + n + nt, &blockCol);
+ ASSERT(nt <= hdr.szBlkCol);
+
+ SColData *pColData;
+ code = tBlockDataAddColData(pBlockData, taosArrayGetSize(pBlockData->aIdx), &pColData);
+ if (code) goto _exit;
+
+ tColDataInit(pColData, blockCol.cid, blockCol.type, blockCol.smaOn);
+ if (blockCol.flag == HAS_NULL) {
+ for (int32_t iRow = 0; iRow < hdr.nRow; iRow++) {
+ code = tColDataAppendValue(pColData, &COL_VAL_NULL(blockCol.cid, blockCol.type));
+ if (code) goto _exit;
+ }
+ } else {
+ code = tsdbDecmprColData(pIn + n + hdr.szBlkCol + sizeof(TSCKSUM) + blockCol.offset, &blockCol, hdr.cmprAlg,
+ hdr.nRow, pColData, &aBuf[0]);
+ if (code) goto _exit;
+ }
+ }
+
+_exit:
+ return code;
+}
+
+// SDiskDataHdr ==============================
+int32_t tPutDiskDataHdr(uint8_t *p, void *ph) {
+ int32_t n = 0;
+ SDiskDataHdr *pHdr = (SDiskDataHdr *)ph;
+
+ n += tPutU32(p ? p + n : p, pHdr->delimiter);
+ n += tPutU32v(p ? p + n : p, pHdr->fmtVer);
+ n += tPutI64(p ? p + n : p, pHdr->suid);
+ n += tPutI64(p ? p + n : p, pHdr->uid);
+ n += tPutI32v(p ? p + n : p, pHdr->szUid);
+ n += tPutI32v(p ? p + n : p, pHdr->szVer);
+ n += tPutI32v(p ? p + n : p, pHdr->szKey);
+ n += tPutI32v(p ? p + n : p, pHdr->szBlkCol);
+ n += tPutI32v(p ? p + n : p, pHdr->nRow);
+ n += tPutI8(p ? p + n : p, pHdr->cmprAlg);
+
return n;
}
-int32_t tGetBlockData(uint8_t *p, SBlockData *pBlockData) {
- int32_t n = 0;
+int32_t tGetDiskDataHdr(uint8_t *p, void *ph) {
+ int32_t n = 0;
+ SDiskDataHdr *pHdr = (SDiskDataHdr *)ph;
- tBlockDataReset(pBlockData);
-
- n += tGetI32v(p + n, &pBlockData->nRow);
- pBlockData->aVersion = (int64_t *)(p + n);
- n = n + sizeof(int64_t) * pBlockData->nRow;
- pBlockData->aTSKEY = (TSKEY *)(p + n);
- n = n + sizeof(TSKEY) * pBlockData->nRow;
-
- int32_t nCol;
- n += tGetI32v(p + n, &nCol);
- for (int32_t iCol = 0; iCol < nCol; iCol++) {
- SColData *pColData;
-
- if (tBlockDataAddColData(pBlockData, iCol, &pColData)) return -1;
- n += tGetColData(p + n, pColData);
- }
+ n += tGetU32(p + n, &pHdr->delimiter);
+ n += tGetU32v(p + n, &pHdr->fmtVer);
+ n += tGetI64(p + n, &pHdr->suid);
+ n += tGetI64(p + n, &pHdr->uid);
+ n += tGetI32v(p + n, &pHdr->szUid);
+ n += tGetI32v(p + n, &pHdr->szVer);
+ n += tGetI32v(p + n, &pHdr->szKey);
+ n += tGetI32v(p + n, &pHdr->szBlkCol);
+ n += tGetI32v(p + n, &pHdr->nRow);
+ n += tGetI8(p + n, &pHdr->cmprAlg);
return n;
}
// ALGORITHM ==============================
+int32_t tPutColumnDataAgg(uint8_t *p, SColumnDataAgg *pColAgg) {
+ int32_t n = 0;
+
+ n += tPutI16v(p ? p + n : p, pColAgg->colId);
+ n += tPutI16v(p ? p + n : p, pColAgg->numOfNull);
+ n += tPutI64(p ? p + n : p, pColAgg->sum);
+ n += tPutI64(p ? p + n : p, pColAgg->max);
+ n += tPutI64(p ? p + n : p, pColAgg->min);
+
+ return n;
+}
+
+int32_t tGetColumnDataAgg(uint8_t *p, SColumnDataAgg *pColAgg) {
+ int32_t n = 0;
+
+ n += tGetI16v(p + n, &pColAgg->colId);
+ n += tGetI16v(p + n, &pColAgg->numOfNull);
+ n += tGetI64(p + n, &pColAgg->sum);
+ n += tGetI64(p + n, &pColAgg->max);
+ n += tGetI64(p + n, &pColAgg->min);
+
+ return n;
+}
+
void tsdbCalcColDataSMA(SColData *pColData, SColumnDataAgg *pColAgg) {
SColVal colVal;
SColVal *pColVal = &colVal;
@@ -1532,25 +1804,25 @@ void tsdbCalcColDataSMA(SColData *pColData, SColumnDataAgg *pColAgg) {
break;
}
case TSDB_DATA_TYPE_FLOAT: {
- *(double*)(&pColAgg->sum) += colVal.value.f;
- if (!minAssigned || *(double*)(&pColAgg->min) > colVal.value.f) {
- *(double*)(&pColAgg->min) = colVal.value.f;
+ *(double *)(&pColAgg->sum) += colVal.value.f;
+ if (!minAssigned || *(double *)(&pColAgg->min) > colVal.value.f) {
+ *(double *)(&pColAgg->min) = colVal.value.f;
minAssigned = true;
}
- if (!maxAssigned || *(double*)(&pColAgg->max) < colVal.value.f) {
- *(double*)(&pColAgg->max) = colVal.value.f;
+ if (!maxAssigned || *(double *)(&pColAgg->max) < colVal.value.f) {
+ *(double *)(&pColAgg->max) = colVal.value.f;
maxAssigned = true;
}
break;
}
case TSDB_DATA_TYPE_DOUBLE: {
- *(double*)(&pColAgg->sum) += colVal.value.d;
- if (!minAssigned || *(double*)(&pColAgg->min) > colVal.value.d) {
- *(double*)(&pColAgg->min) = colVal.value.d;
+ *(double *)(&pColAgg->sum) += colVal.value.d;
+ if (!minAssigned || *(double *)(&pColAgg->min) > colVal.value.d) {
+ *(double *)(&pColAgg->min) = colVal.value.d;
minAssigned = true;
}
- if (!maxAssigned || *(double*)(&pColAgg->max) < colVal.value.d) {
- *(double*)(&pColAgg->max) = colVal.value.d;
+ if (!maxAssigned || *(double *)(&pColAgg->max) < colVal.value.d) {
+ *(double *)(&pColAgg->max) = colVal.value.d;
maxAssigned = true;
}
break;
@@ -1634,3 +1906,268 @@ void tsdbCalcColDataSMA(SColData *pColData, SColumnDataAgg *pColAgg) {
}
}
}
+
+int32_t tsdbCmprData(uint8_t *pIn, int32_t szIn, int8_t type, int8_t cmprAlg, uint8_t **ppOut, int32_t nOut,
+ int32_t *szOut, uint8_t **ppBuf) {
+ int32_t code = 0;
+
+ ASSERT(szIn > 0 && ppOut);
+
+ if (cmprAlg == NO_COMPRESSION) {
+ code = tRealloc(ppOut, nOut + szIn);
+ if (code) goto _exit;
+
+ memcpy(*ppOut + nOut, pIn, szIn);
+ *szOut = szIn;
+ } else {
+ int32_t size = szIn + COMP_OVERFLOW_BYTES;
+
+ code = tRealloc(ppOut, nOut + size);
+ if (code) goto _exit;
+
+ if (cmprAlg == TWO_STAGE_COMP) {
+ ASSERT(ppBuf);
+ code = tRealloc(ppBuf, size);
+ if (code) goto _exit;
+ }
+
+ *szOut =
+ tDataTypes[type].compFunc(pIn, szIn, szIn / tDataTypes[type].bytes, *ppOut + nOut, size, cmprAlg, *ppBuf, size);
+ if (*szOut <= 0) {
+ code = TSDB_CODE_COMPRESS_ERROR;
+ goto _exit;
+ }
+ }
+
+_exit:
+ return code;
+}
+
+int32_t tsdbDecmprData(uint8_t *pIn, int32_t szIn, int8_t type, int8_t cmprAlg, uint8_t **ppOut, int32_t szOut,
+ uint8_t **ppBuf) {
+ int32_t code = 0;
+
+ code = tRealloc(ppOut, szOut);
+ if (code) goto _exit;
+
+ if (cmprAlg == NO_COMPRESSION) {
+ ASSERT(szIn == szOut);
+ memcpy(*ppOut, pIn, szOut);
+ } else {
+ if (cmprAlg == TWO_STAGE_COMP) {
+ code = tRealloc(ppBuf, szOut + COMP_OVERFLOW_BYTES);
+ if (code) goto _exit;
+ }
+
+ int32_t size = tDataTypes[type].decompFunc(pIn, szIn, szOut / tDataTypes[type].bytes, *ppOut, szOut, cmprAlg,
+ *ppBuf, szOut + COMP_OVERFLOW_BYTES);
+ if (size <= 0) {
+ code = TSDB_CODE_COMPRESS_ERROR;
+ goto _exit;
+ }
+
+ ASSERT(size == szOut);
+ }
+
+_exit:
+ return code;
+}
+
+int32_t tsdbCmprColData(SColData *pColData, int8_t cmprAlg, SBlockCol *pBlockCol, uint8_t **ppOut, int32_t nOut,
+ uint8_t **ppBuf) {
+ int32_t code = 0;
+
+ ASSERT(pColData->flag && (pColData->flag != HAS_NONE) && (pColData->flag != HAS_NULL));
+
+ pBlockCol->szBitmap = 0;
+ pBlockCol->szOffset = 0;
+ pBlockCol->szValue = 0;
+
+ int32_t size = 0;
+ // bitmap
+ if (pColData->flag != HAS_VALUE) {
+ uint8_t *pBitMap = pColData->pBitMap;
+ int32_t szBitMap = BIT2_SIZE(pColData->nVal);
+
+ // BIT2 to BIT1
+ if (pColData->flag != (HAS_VALUE | HAS_NULL | HAS_NONE)) {
+ szBitMap = BIT1_SIZE(pColData->nVal);
+ pBitMap = taosMemoryCalloc(1, szBitMap);
+ if (pBitMap == NULL) {
+ code = TSDB_CODE_OUT_OF_MEMORY;
+ goto _exit;
+ }
+
+ for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
+ uint8_t v = GET_BIT2(pColData->pBitMap, iVal);
+ switch (pColData->flag) {
+ case (HAS_NULL | HAS_NONE):
+ SET_BIT1(pBitMap, iVal, v);
+ break;
+ case (HAS_VALUE | HAS_NONE):
+ if (v) {
+ SET_BIT1(pBitMap, iVal, 1);
+ } else {
+ SET_BIT1(pBitMap, iVal, 0);
+ }
+ break;
+ case (HAS_VALUE | HAS_NULL):
+ SET_BIT1(pBitMap, iVal, v - 1);
+ break;
+ default:
+ ASSERT(0);
+ }
+ }
+ }
+
+ code = tsdbCmprData(pBitMap, szBitMap, TSDB_DATA_TYPE_TINYINT, cmprAlg, ppOut, nOut + size, &pBlockCol->szBitmap,
+ ppBuf);
+ if (code) goto _exit;
+
+ if (pColData->flag != (HAS_VALUE | HAS_NULL | HAS_NONE)) {
+ taosMemoryFree(pBitMap);
+ }
+ }
+ size += pBlockCol->szBitmap;
+
+ // offset
+ if (IS_VAR_DATA_TYPE(pColData->type)) {
+ code = tsdbCmprData((uint8_t *)pColData->aOffset, sizeof(int32_t) * pColData->nVal, TSDB_DATA_TYPE_INT, cmprAlg,
+ ppOut, nOut + size, &pBlockCol->szOffset, ppBuf);
+ if (code) goto _exit;
+ }
+ size += pBlockCol->szOffset;
+
+ // value
+ if (pColData->flag != (HAS_NULL | HAS_NONE)) {
+ code = tsdbCmprData((uint8_t *)pColData->pData, pColData->nData, pColData->type, cmprAlg, ppOut, nOut + size,
+ &pBlockCol->szValue, ppBuf);
+ if (code) goto _exit;
+ }
+ size += pBlockCol->szValue;
+
+ // checksum
+ size += sizeof(TSCKSUM);
+ code = tRealloc(ppOut, nOut + size);
+ if (code) goto _exit;
+ taosCalcChecksumAppend(0, *ppOut + nOut, size);
+
+_exit:
+ return code;
+}
+
+int32_t tsdbDecmprColData(uint8_t *pIn, SBlockCol *pBlockCol, int8_t cmprAlg, int32_t nVal, SColData *pColData,
+ uint8_t **ppBuf) {
+ int32_t code = 0;
+
+ int32_t size = pBlockCol->szBitmap + pBlockCol->szOffset + pBlockCol->szValue + sizeof(TSCKSUM);
+ if (!taosCheckChecksumWhole(pIn, size)) {
+ code = TSDB_CODE_FILE_CORRUPTED;
+ goto _exit;
+ }
+
+ ASSERT(pColData->cid == pBlockCol->cid);
+ ASSERT(pColData->type == pBlockCol->type);
+ pColData->smaOn = pBlockCol->smaOn;
+ pColData->flag = pBlockCol->flag;
+ pColData->nVal = nVal;
+ pColData->nData = pBlockCol->szOrigin;
+
+ uint8_t *p = pIn;
+ // bitmap
+ if (pBlockCol->szBitmap) {
+ if (pBlockCol->flag != (HAS_VALUE | HAS_NULL | HAS_NONE)) {
+ uint8_t *pBitMap = NULL;
+ code = tsdbDecmprData(p, pBlockCol->szBitmap, TSDB_DATA_TYPE_TINYINT, cmprAlg, &pBitMap,
+ BIT1_SIZE(pColData->nVal), ppBuf);
+ if (code) goto _exit;
+
+ code = tRealloc(&pColData->pBitMap, BIT2_SIZE(pColData->nVal));
+ if (code) {
+ tFree(pBitMap);
+ goto _exit;
+ }
+
+ // BIT1 to BIT2
+ for (int32_t iVal = 0; iVal < nVal; iVal++) {
+ uint8_t v = GET_BIT1(pBitMap, iVal);
+ switch (pBlockCol->flag) {
+ case (HAS_NULL | HAS_NONE):
+ SET_BIT2(pColData->pBitMap, iVal, v);
+ break;
+ case (HAS_VALUE | HAS_NONE):
+ if (v) {
+ SET_BIT2(pColData->pBitMap, iVal, 2);
+ } else {
+ SET_BIT2(pColData->pBitMap, iVal, 0);
+ }
+ break;
+ case (HAS_VALUE | HAS_NULL):
+ SET_BIT2(pColData->pBitMap, iVal, v + 1);
+ break;
+ default:
+ ASSERT(0);
+ }
+ }
+
+ tFree(pBitMap);
+ } else {
+ code = tsdbDecmprData(p, pBlockCol->szBitmap, TSDB_DATA_TYPE_TINYINT, cmprAlg, &pColData->pBitMap,
+ BIT2_SIZE(pColData->nVal), ppBuf);
+ if (code) goto _exit;
+ }
+ }
+ p += pBlockCol->szBitmap;
+
+ // offset
+ if (pBlockCol->szOffset) {
+ code = tsdbDecmprData(p, pBlockCol->szOffset, TSDB_DATA_TYPE_INT, cmprAlg, (uint8_t **)&pColData->aOffset,
+ sizeof(int32_t) * pColData->nVal, ppBuf);
+ if (code) goto _exit;
+ }
+ p += pBlockCol->szOffset;
+
+ // value
+ if (pBlockCol->szValue) {
+ code = tsdbDecmprData(p, pBlockCol->szValue, pColData->type, cmprAlg, &pColData->pData, pColData->nData, ppBuf);
+ if (code) goto _exit;
+ }
+ p += pBlockCol->szValue;
+
+_exit:
+ return code;
+}
+
+int32_t tsdbReadAndCheck(TdFilePtr pFD, int64_t offset, uint8_t **ppOut, int32_t size, int8_t toCheck) {
+ int32_t code = 0;
+
+ // alloc
+ code = tRealloc(ppOut, size);
+ if (code) goto _exit;
+
+ // seek
+ int64_t n = taosLSeekFile(pFD, offset, SEEK_SET);
+ if (n < 0) {
+ code = TAOS_SYSTEM_ERROR(errno);
+ goto _exit;
+ }
+
+ // read
+ n = taosReadFile(pFD, *ppOut, size);
+ if (n < 0) {
+ code = TAOS_SYSTEM_ERROR(errno);
+ goto _exit;
+ } else if (n < size) {
+ code = TSDB_CODE_FILE_CORRUPTED;
+ goto _exit;
+ }
+
+ // check
+ if (toCheck && !taosCheckChecksumWhole(*ppOut, size)) {
+ code = TSDB_CODE_FILE_CORRUPTED;
+ goto _exit;
+ }
+
+_exit:
+ return code;
+}
diff --git a/source/dnode/vnode/src/vnd/vnodeBufPool.c b/source/dnode/vnode/src/vnd/vnodeBufPool.c
index 0623b3bd10..5a22114ab4 100644
--- a/source/dnode/vnode/src/vnd/vnodeBufPool.c
+++ b/source/dnode/vnode/src/vnd/vnodeBufPool.c
@@ -78,7 +78,7 @@ void vnodeBufPoolReset(SVBufPool *pPool) {
void *vnodeBufPoolMalloc(SVBufPool *pPool, int size) {
SVBufPoolNode *pNode;
void *p;
-
+ taosThreadSpinLock(&pPool->lock);
if (pPool->node.size >= pPool->ptr - pPool->node.data + size) {
// allocate from the anchor node
p = pPool->ptr;
@@ -89,6 +89,7 @@ void *vnodeBufPoolMalloc(SVBufPool *pPool, int size) {
pNode = taosMemoryMalloc(sizeof(*pNode) + size);
if (pNode == NULL) {
terrno = TSDB_CODE_OUT_OF_MEMORY;
+ taosThreadSpinUnlock(&pPool->lock);
return NULL;
}
@@ -101,7 +102,7 @@ void *vnodeBufPoolMalloc(SVBufPool *pPool, int size) {
pPool->size = pPool->size + sizeof(*pNode) + size;
}
-
+ taosThreadSpinUnlock(&pPool->lock);
return p;
}
@@ -129,6 +130,12 @@ static int vnodeBufPoolCreate(SVnode *pVnode, int64_t size, SVBufPool **ppPool)
return -1;
}
+ if (taosThreadSpinInit(&pPool->lock, 0) != 0) {
+ taosMemoryFree(pPool);
+ terrno = TAOS_SYSTEM_ERROR(errno);
+ return -1;
+ }
+
pPool->next = NULL;
pPool->pVnode = pVnode;
pPool->nRef = 0;
@@ -145,6 +152,7 @@ static int vnodeBufPoolCreate(SVnode *pVnode, int64_t size, SVBufPool **ppPool)
static int vnodeBufPoolDestroy(SVBufPool *pPool) {
vnodeBufPoolReset(pPool);
+ taosThreadSpinDestroy(&pPool->lock);
taosMemoryFree(pPool);
return 0;
}
diff --git a/source/dnode/vnode/src/vnd/vnodeCommit.c b/source/dnode/vnode/src/vnd/vnodeCommit.c
index c8dc07af0a..8c73499229 100644
--- a/source/dnode/vnode/src/vnd/vnodeCommit.c
+++ b/source/dnode/vnode/src/vnd/vnodeCommit.c
@@ -220,9 +220,6 @@ int vnodeCommit(SVnode *pVnode) {
vInfo("vgId:%d, start to commit, commit ID:%" PRId64 " version:%" PRId64, TD_VID(pVnode), pVnode->state.commitID,
pVnode->state.applied);
- vnodeBufPoolUnRef(pVnode->inUse);
- pVnode->inUse = NULL;
-
pVnode->state.commitTerm = pVnode->state.applyTerm;
// save info
@@ -239,7 +236,13 @@ int vnodeCommit(SVnode *pVnode) {
// preCommit
// smaSyncPreCommit(pVnode->pSma);
- smaAsyncPreCommit(pVnode->pSma);
+ if(smaAsyncPreCommit(pVnode->pSma) < 0){
+ ASSERT(0);
+ return -1;
+ }
+
+ vnodeBufPoolUnRef(pVnode->inUse);
+ pVnode->inUse = NULL;
// commit each sub-system
if (metaCommit(pVnode->pMeta) < 0) {
@@ -248,7 +251,10 @@ int vnodeCommit(SVnode *pVnode) {
}
if (VND_IS_RSMA(pVnode)) {
- smaAsyncCommit(pVnode->pSma);
+ if (smaAsyncCommit(pVnode->pSma) < 0) {
+ ASSERT(0);
+ return -1;
+ }
if (tsdbCommit(VND_RSMA0(pVnode)) < 0) {
ASSERT(0);
@@ -285,7 +291,10 @@ int vnodeCommit(SVnode *pVnode) {
// postCommit
// smaSyncPostCommit(pVnode->pSma);
- smaAsyncPostCommit(pVnode->pSma);
+ if (smaAsyncPostCommit(pVnode->pSma) < 0) {
+ ASSERT(0);
+ return -1;
+ }
// apply the commit (TODO)
walEndSnapshot(pVnode->pWal);
diff --git a/source/dnode/vnode/src/vnd/vnodeOpen.c b/source/dnode/vnode/src/vnd/vnodeOpen.c
index a4fd984fb7..dcfbd33b90 100644
--- a/source/dnode/vnode/src/vnd/vnodeOpen.c
+++ b/source/dnode/vnode/src/vnd/vnodeOpen.c
@@ -87,6 +87,7 @@ SVnode *vnodeOpen(const char *path, STfs *pTfs, SMsgCb msgCb) {
pVnode->msgCb = msgCb;
taosThreadMutexInit(&pVnode->lock, NULL);
pVnode->blocked = false;
+ pVnode->inClose = false;
tsem_init(&pVnode->syncSem, 0, 0);
tsem_init(&(pVnode->canCommit), 0, 1);
@@ -181,6 +182,8 @@ _err:
void vnodePreClose(SVnode *pVnode) {
if (pVnode) {
syncLeaderTransfer(pVnode->sync);
+ pVnode->inClose = true;
+ smaPreClose(pVnode->pSma);
}
}
diff --git a/source/dnode/vnode/src/vnd/vnodeQuery.c b/source/dnode/vnode/src/vnd/vnodeQuery.c
index d55f1796ad..8d799e919d 100644
--- a/source/dnode/vnode/src/vnd/vnodeQuery.c
+++ b/source/dnode/vnode/src/vnd/vnodeQuery.c
@@ -424,6 +424,25 @@ int32_t vnodeGetCtbIdList(SVnode *pVnode, int64_t suid, SArray *list) {
return TSDB_CODE_SUCCESS;
}
+int32_t vnodeGetStbIdList(SVnode* pVnode, int64_t suid, SArray* list) {
+ SMStbCursor* pCur = metaOpenStbCursor(pVnode->pMeta, suid);
+ if (!pCur) {
+ return TSDB_CODE_FAILED;
+ }
+
+ while (1) {
+ tb_uid_t id = metaStbCursorNext(pCur);
+ if (id == 0) {
+ break;
+ }
+
+ taosArrayPush(list, &id);
+ }
+
+ metaCloseStbCursor(pCur);
+ return TSDB_CODE_SUCCESS;
+}
+
int32_t vnodeGetCtbNum(SVnode *pVnode, int64_t suid, int64_t *num) {
SMCtbCursor *pCur = metaOpenCtbCursor(pVnode->pMeta, suid);
if (!pCur) {
diff --git a/source/dnode/vnode/src/vnd/vnodeSvr.c b/source/dnode/vnode/src/vnd/vnodeSvr.c
index 54a5aacbd2..7a8d168f4f 100644
--- a/source/dnode/vnode/src/vnd/vnodeSvr.c
+++ b/source/dnode/vnode/src/vnd/vnodeSvr.c
@@ -301,8 +301,8 @@ int32_t vnodeProcessQueryMsg(SVnode *pVnode, SRpcMsg *pMsg) {
return qWorkerProcessQueryMsg(&handle, pVnode->pQuery, pMsg, 0);
case TDMT_SCH_QUERY_CONTINUE:
return qWorkerProcessCQueryMsg(&handle, pVnode->pQuery, pMsg, 0);
- case TDMT_VND_FETCH_RSMA:
- return smaProcessFetch(pVnode->pSma, pMsg);
+ case TDMT_VND_EXEC_RSMA:
+ return smaProcessExec(pVnode->pSma, pMsg);
default:
vError("unknown msg type:%d in query queue", pMsg->msgType);
return TSDB_CODE_VND_APP_ERROR;
@@ -530,7 +530,9 @@ static int32_t vnodeProcessCreateTbReq(SVnode *pVnode, int64_t version, void *pR
}
tqUpdateTbUidList(pVnode->pTq, tbUids, true);
- tdUpdateTbUidList(pVnode->pSma, pStore);
+ if (tdUpdateTbUidList(pVnode->pSma, pStore) < 0) {
+ goto _exit;
+ }
tdUidStoreFree(pStore);
// prepare rsp
diff --git a/source/libs/executor/inc/executorimpl.h b/source/libs/executor/inc/executorimpl.h
index 311d82c8a2..5e339eb113 100644
--- a/source/libs/executor/inc/executorimpl.h
+++ b/source/libs/executor/inc/executorimpl.h
@@ -205,7 +205,7 @@ typedef struct SExprSupp {
} SExprSupp;
typedef struct SOperatorInfo {
- uint8_t operatorType;
+ uint16_t operatorType;
bool blocking; // block operator or not
uint8_t status; // denote if current operator is completed
char* name; // name, for debug purpose
@@ -434,7 +434,7 @@ typedef struct SStreamAggSupporter {
typedef struct SessionWindowSupporter {
SStreamAggSupporter* pStreamAggSup;
int64_t gap;
- uint8_t parentType;
+ uint16_t parentType;
SAggSupporter* pIntervalAggSup;
} SessionWindowSupporter;
@@ -924,9 +924,6 @@ SOperatorInfo* createMergeAlignedIntervalOperatorInfo(SOperatorInfo* downstream,
SOperatorInfo* createStreamFinalIntervalOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode,
SExecTaskInfo* pTaskInfo, int32_t numOfChild);
-SOperatorInfo* createStreamIntervalOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols,
- SSDataBlock* pResBlock, SInterval* pInterval, int32_t primaryTsSlotId,
- STimeWindowAggSupp *pTwAggSupp, SExecTaskInfo* pTaskInfo);
SOperatorInfo* createSessionAggOperatorInfo(SOperatorInfo* downstream, SSessionWinodwPhysiNode* pSessionNode,
SExecTaskInfo* pTaskInfo);
SOperatorInfo* createGroupOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols,
diff --git a/source/libs/executor/inc/tsimplehash.h b/source/libs/executor/inc/tsimplehash.h
index a56f8e8c04..4c5a80e2f1 100644
--- a/source/libs/executor/inc/tsimplehash.h
+++ b/source/libs/executor/inc/tsimplehash.h
@@ -17,7 +17,6 @@
#define TDENGINE_TSIMPLEHASH_H
#include "tarray.h"
-#include "tlockfree.h"
#ifdef __cplusplus
extern "C" {
@@ -27,6 +26,10 @@ typedef uint32_t (*_hash_fn_t)(const char *, uint32_t);
typedef int32_t (*_equal_fn_t)(const void *, const void *, size_t len);
typedef void (*_hash_free_fn_t)(void *);
+/**
+ * @brief single thread hash
+ *
+ */
typedef struct SSHashObj SSHashObj;
/**
@@ -36,7 +39,7 @@ typedef struct SSHashObj SSHashObj;
* @param fn hash function to generate the hash value
* @return
*/
-SSHashObj *tSimpleHashInit(size_t capacity, _hash_fn_t fn, size_t keyLen, size_t dataLen);
+SSHashObj *tSimpleHashInit(size_t capacity, _hash_fn_t fn);
/**
* return the size of hash table
@@ -48,22 +51,26 @@ int32_t tSimpleHashGetSize(const SSHashObj *pHashObj);
int32_t tSimpleHashPrint(const SSHashObj *pHashObj);
/**
- * put element into hash table, if the element with the same key exists, update it
- * @param pHashObj
- * @param key
- * @param data
- * @return
+ * @brief put element into hash table, if the element with the same key exists, update it
+ *
+ * @param pHashObj
+ * @param key
+ * @param keyLen
+ * @param data
+ * @param dataLen
+ * @return int32_t
*/
-int32_t tSimpleHashPut(SSHashObj *pHashObj, const void *key, const void *data);
+int32_t tSimpleHashPut(SSHashObj *pHashObj, const void *key, size_t keyLen, const void *data, size_t dataLen);
/**
* return the payload data with the specified key
*
* @param pHashObj
* @param key
+ * @param keyLen
* @return
*/
-void *tSimpleHashGet(SSHashObj *pHashObj, const void *key);
+void *tSimpleHashGet(SSHashObj *pHashObj, const void *key, size_t keyLen);
/**
* remove item with the specified key
@@ -71,7 +78,7 @@ void *tSimpleHashGet(SSHashObj *pHashObj, const void *key);
* @param key
* @param keyLen
*/
-int32_t tSimpleHashRemove(SSHashObj *pHashObj, const void *key);
+int32_t tSimpleHashRemove(SSHashObj *pHashObj, const void *key, size_t keyLen);
/**
* Clear the hash table.
@@ -98,7 +105,7 @@ size_t tSimpleHashGetMemSize(const SSHashObj *pHashObj);
* @param keyLen
* @return
*/
-void *tSimpleHashGetKey(const SSHashObj* pHashObj, void *data, size_t* keyLen);
+void *tSimpleHashGetKey(void *data, size_t* keyLen);
/**
* Create the hash table iterator
@@ -109,7 +116,18 @@ void *tSimpleHashGetKey(const SSHashObj* pHashObj, void *data, size_t* keyLen);
*/
void *tSimpleHashIterate(const SSHashObj *pHashObj, void *data, int32_t *iter);
+/**
+ * Create the hash table iterator
+ *
+ * @param pHashObj
+ * @param data
+ * @param key
+ * @param iter
+ * @return void*
+ */
+void *tSimpleHashIterateKV(const SSHashObj *pHashObj, void *data, void **key, int32_t *iter);
+
#ifdef __cplusplus
}
#endif
-#endif // TDENGINE_TSIMPLEHASH_H
+#endif // TDENGINE_TSIMPLEHASH_H
\ No newline at end of file
diff --git a/source/libs/executor/src/executil.c b/source/libs/executor/src/executil.c
index 1dabea0d6b..bf969bf2e4 100644
--- a/source/libs/executor/src/executil.c
+++ b/source/libs/executor/src/executil.c
@@ -429,7 +429,9 @@ static SColumnInfoData* getColInfoResult(void* metaHandle, uint64_t suid, SArray
for (int32_t i = 0; i < rows; i++) {
int64_t* uid = taosArrayGet(uidList, i);
void* tag = taosHashGet(tags, uid, sizeof(int64_t));
- ASSERT(tag);
+ if (suid != 0) {
+ ASSERT(tag);
+ }
for(int32_t j = 0; j < taosArrayGetSize(pResBlock->pDataBlock); j++){
SColumnInfoData* pColInfo = (SColumnInfoData*)taosArrayGet(pResBlock->pDataBlock, j);
@@ -533,7 +535,9 @@ int32_t getTableList(void* metaHandle, void* pVnode, SScanPhysiNode* pScanNode,
vnodeGetCtbIdList(pVnode, pScanNode->suid, res);
}
} else { // Create one table group.
- taosArrayPush(res, &tableUid);
+ if(metaIsTableExist(metaHandle, tableUid)){
+ taosArrayPush(res, &tableUid);
+ }
}
if (pTagCond) {
@@ -599,7 +603,10 @@ size_t getTableTagsBufLen(const SNodeList* pGroups) {
int32_t getGroupIdFromTagsVal(void* pMeta, uint64_t uid, SNodeList* pGroupNode, char* keyBuf, uint64_t* pGroupId) {
SMetaReader mr = {0};
metaReaderInit(&mr, pMeta, 0);
- metaGetTableEntryByUid(&mr, uid);
+ if(metaGetTableEntryByUid(&mr, uid) != 0){ // table not exist
+ metaReaderClear(&mr);
+ return TSDB_CODE_PAR_TABLE_NOT_EXIST;
+ }
SNodeList* groupNew = nodesCloneList(pGroupNode);
diff --git a/source/libs/executor/src/executor.c b/source/libs/executor/src/executor.c
index 7115ad85a5..d8f63cb008 100644
--- a/source/libs/executor/src/executor.c
+++ b/source/libs/executor/src/executor.c
@@ -55,7 +55,7 @@ static int32_t doSetStreamBlock(SOperatorInfo* pOperator, void* input, size_t nu
taosArrayClear(pInfo->pBlockLists);
if (type == STREAM_INPUT__MERGED_SUBMIT) {
- ASSERT(numOfBlocks > 1);
+ // ASSERT(numOfBlocks > 1);
for (int32_t i = 0; i < numOfBlocks; i++) {
SSubmitReq* pReq = *(void**)POINTER_SHIFT(input, i * sizeof(void*));
taosArrayPush(pInfo->pBlockLists, &pReq);
@@ -348,7 +348,7 @@ int32_t qCreateExecTask(SReadHandle* readHandle, int32_t vgId, uint64_t taskId,
taosThreadOnce(&initPoolOnce, initRefPool);
atexit(cleanupRefPool);
- qDebug("start to create subplan task, TID:0x%"PRIx64 " QID:0x%"PRIx64, taskId, pSubplan->id.queryId);
+ qDebug("start to create subplan task, TID:0x%" PRIx64 " QID:0x%" PRIx64, taskId, pSubplan->id.queryId);
int32_t code = createExecTaskInfoImpl(pSubplan, pTask, readHandle, taskId, sql, model);
if (code != TSDB_CODE_SUCCESS) {
@@ -374,7 +374,7 @@ int32_t qCreateExecTask(SReadHandle* readHandle, int32_t vgId, uint64_t taskId,
}
}
- qDebug("subplan task create completed, TID:0x%"PRIx64 " QID:0x%"PRIx64, taskId, pSubplan->id.queryId);
+ qDebug("subplan task create completed, TID:0x%" PRIx64 " QID:0x%" PRIx64, taskId, pSubplan->id.queryId);
_error:
// if failed to add ref for all tables in this query, abort current query
@@ -427,7 +427,7 @@ int waitMoment(SQInfo* pQInfo) {
#endif
static void freeBlock(void* param) {
- SSDataBlock* pBlock = *(SSDataBlock**) param;
+ SSDataBlock* pBlock = *(SSDataBlock**)param;
blockDataDestroy(pBlock);
}
@@ -467,12 +467,12 @@ int32_t qExecTaskOpt(qTaskInfo_t tinfo, SArray* pResList, uint64_t* useconds) {
qDebug("%s execTask is launched", GET_TASKID(pTaskInfo));
- int32_t current = 0;
+ int32_t current = 0;
SSDataBlock* pRes = NULL;
int64_t st = taosGetTimestampUs();
- while((pRes = pTaskInfo->pRoot->fpSet.getNextFn(pTaskInfo->pRoot)) != NULL) {
+ while ((pRes = pTaskInfo->pRoot->fpSet.getNextFn(pTaskInfo->pRoot)) != NULL) {
SSDataBlock* p = createOneDataBlock(pRes, true);
current += p->info.rows;
ASSERT(p->info.rows > 0);
@@ -494,7 +494,7 @@ int32_t qExecTaskOpt(qTaskInfo_t tinfo, SArray* pResList, uint64_t* useconds) {
uint64_t total = pTaskInfo->pRoot->resultInfo.totalRows;
qDebug("%s task suspended, %d rows in %d blocks returned, total:%" PRId64 " rows, in sinkNode:%d, elapsed:%.2f ms",
- GET_TASKID(pTaskInfo), current, (int32_t) taosArrayGetSize(pResList), total, 0, el / 1000.0);
+ GET_TASKID(pTaskInfo), current, (int32_t)taosArrayGetSize(pResList), total, 0, el / 1000.0);
atomic_store_64(&pTaskInfo->owner, 0);
return pTaskInfo->code;
@@ -632,7 +632,7 @@ int32_t qExtractStreamScanner(qTaskInfo_t tinfo, void** scanner) {
SOperatorInfo* pOperator = pTaskInfo->pRoot;
while (1) {
- uint8_t type = pOperator->operatorType;
+ uint16_t type = pOperator->operatorType;
if (type == QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN) {
*scanner = pOperator->info;
return 0;
@@ -691,7 +691,7 @@ int32_t qStreamPrepareScan(qTaskInfo_t tinfo, const STqOffsetVal* pOffset) {
pTaskInfo->streamInfo.prepareStatus = *pOffset;
if (!tOffsetEqual(pOffset, &pTaskInfo->streamInfo.lastStatus)) {
while (1) {
- uint8_t type = pOperator->operatorType;
+ uint16_t type = pOperator->operatorType;
pOperator->status = OP_OPENED;
// TODO add more check
if (type != QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN) {
diff --git a/source/libs/executor/src/executorimpl.c b/source/libs/executor/src/executorimpl.c
index d15dc99122..f7fb6cd405 100644
--- a/source/libs/executor/src/executorimpl.c
+++ b/source/libs/executor/src/executorimpl.c
@@ -76,6 +76,12 @@ static UNUSED_FUNC void* u_realloc(void* p, size_t __size) {
#define realloc u_realloc
#endif
+#define T_LONG_JMP(_obj, _c) \
+ do { \
+ assert((_c) != -1); \
+ longjmp((_obj), (_c)); \
+ } while (0);
+
#define CLEAR_QUERY_STATUS(q, st) ((q)->status &= (~(st)))
#define QUERY_IS_INTERVAL_QUERY(_q) ((_q)->interval.interval > 0)
@@ -3131,6 +3137,7 @@ int32_t aggDecodeResultRow(SOperatorInfo* pOperator, char* result) {
initResultRow(resultRow);
pInfo->resultRowInfo.cur = (SResultRowPosition){.pageId = resultRow->pageId, .offset = resultRow->offset};
+ // releaseBufPage(pSup->pResultBuf, getBufPage(pSup->pResultBuf, pageId));
}
if (offset != length) {
@@ -3217,8 +3224,8 @@ int32_t handleLimitOffset(SOperatorInfo* pOperator, SLimitInfo* pLimitInfo, SSDa
}
static void doApplyScalarCalculation(SOperatorInfo* pOperator, SSDataBlock* pBlock, int32_t order, int32_t scanFlag);
-static void doHandleRemainBlockForNewGroupImpl(SOperatorInfo *pOperator, SFillOperatorInfo* pInfo, SResultInfo* pResultInfo,
- SExecTaskInfo* pTaskInfo) {
+static void doHandleRemainBlockForNewGroupImpl(SOperatorInfo* pOperator, SFillOperatorInfo* pInfo,
+ SResultInfo* pResultInfo, SExecTaskInfo* pTaskInfo) {
pInfo->totalInputRows = pInfo->existNewGroupBlock->info.rows;
SSDataBlock* pResBlock = pInfo->pFinalRes;
@@ -3242,8 +3249,8 @@ static void doHandleRemainBlockForNewGroupImpl(SOperatorInfo *pOperator, SFillOp
pInfo->existNewGroupBlock = NULL;
}
-static void doHandleRemainBlockFromNewGroup(SOperatorInfo* pOperator, SFillOperatorInfo* pInfo, SResultInfo* pResultInfo,
- SExecTaskInfo* pTaskInfo) {
+static void doHandleRemainBlockFromNewGroup(SOperatorInfo* pOperator, SFillOperatorInfo* pInfo,
+ SResultInfo* pResultInfo, SExecTaskInfo* pTaskInfo) {
if (taosFillHasMoreResults(pInfo->pFillInfo)) {
int32_t numOfResultRows = pResultInfo->capacity - pInfo->pFinalRes->info.rows;
taosFillResultDataBlock(pInfo->pFillInfo, pInfo->pFinalRes, numOfResultRows);
@@ -3259,8 +3266,8 @@ static void doHandleRemainBlockFromNewGroup(SOperatorInfo* pOperator, SFillOpera
static void doApplyScalarCalculation(SOperatorInfo* pOperator, SSDataBlock* pBlock, int32_t order, int32_t scanFlag) {
SFillOperatorInfo* pInfo = pOperator->info;
- SExprSupp* pSup = &pOperator->exprSupp;
- SSDataBlock* pResBlock = pInfo->pFinalRes;
+ SExprSupp* pSup = &pOperator->exprSupp;
+ SSDataBlock* pResBlock = pInfo->pFinalRes;
setInputDataBlock(pOperator, pSup->pCtx, pBlock, order, scanFlag, false);
projectApplyFunctions(pSup->pExprInfo, pInfo->pRes, pBlock, pSup->pCtx, pSup->numOfExprs, NULL);
@@ -3270,13 +3277,13 @@ static void doApplyScalarCalculation(SOperatorInfo* pOperator, SSDataBlock* pBlo
SColumnInfoData* pSrc = taosArrayGet(pBlock->pDataBlock, pInfo->primarySrcSlotId);
colDataAssign(pDst, pSrc, pInfo->pRes->info.rows, &pResBlock->info);
- for(int32_t i = 0; i < pInfo->numOfNotFillExpr; ++i) {
+ for (int32_t i = 0; i < pInfo->numOfNotFillExpr; ++i) {
SFillColInfo* pCol = &pInfo->pFillInfo->pFillCol[i + pInfo->numOfExpr];
ASSERT(pCol->notFillCol);
SExprInfo* pExpr = pCol->pExpr;
- int32_t srcSlotId = pExpr->base.pParam[0].pCol->slotId;
- int32_t dstSlotId = pExpr->base.resSchema.slotId;
+ int32_t srcSlotId = pExpr->base.pParam[0].pCol->slotId;
+ int32_t dstSlotId = pExpr->base.resSchema.slotId;
SColumnInfoData* pDst1 = taosArrayGet(pInfo->pRes->pDataBlock, dstSlotId);
SColumnInfoData* pSrc1 = taosArrayGet(pBlock->pDataBlock, srcSlotId);
@@ -3664,7 +3671,7 @@ void destroyExchangeOperatorInfo(void* param, int32_t numOfOutput) {
taosRemoveRef(exchangeObjRefPool, pExInfo->self);
}
-void freeSourceDataInfo(void *p) {
+void freeSourceDataInfo(void* p) {
SSourceDataInfo* pInfo = (SSourceDataInfo*)p;
taosMemoryFreeClear(pInfo->pRsp);
}
@@ -3694,8 +3701,8 @@ static int32_t initFillInfo(SFillOperatorInfo* pInfo, SExprInfo* pExpr, int32_t
STimeWindow w = getAlignQueryTimeWindow(pInterval, pInterval->precision, win.skey);
w = getFirstQualifiedTimeWindow(win.skey, &w, pInterval, TSDB_ORDER_ASC);
- pInfo->pFillInfo =
- taosCreateFillInfo(w.skey, numOfCols, numOfNotFillCols, capacity, pInterval, fillType, pColInfo, pInfo->primaryTsCol, order, id);
+ pInfo->pFillInfo = taosCreateFillInfo(w.skey, numOfCols, numOfNotFillCols, capacity, pInterval, fillType, pColInfo,
+ pInfo->primaryTsCol, order, id);
pInfo->win = win;
pInfo->p = taosMemoryCalloc(numOfCols, POINTER_BYTES);
@@ -3721,10 +3728,10 @@ SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SFillPhysiNode*
SExprInfo* pExprInfo = createExprInfo(pPhyFillNode->pFillExprs, NULL, &pInfo->numOfExpr);
pInfo->pNotFillExprInfo = createExprInfo(pPhyFillNode->pNotFillExprs, NULL, &pInfo->numOfNotFillExpr);
- SInterval* pInterval =
+ SInterval* pInterval =
QUERY_NODE_PHYSICAL_PLAN_MERGE_ALIGNED_INTERVAL == downstream->operatorType
- ? &((SMergeAlignedIntervalAggOperatorInfo*)downstream->info)->intervalAggOperatorInfo->interval
- : &((SIntervalAggOperatorInfo*)downstream->info)->interval;
+ ? &((SMergeAlignedIntervalAggOperatorInfo*)downstream->info)->intervalAggOperatorInfo->interval
+ : &((SIntervalAggOperatorInfo*)downstream->info)->interval;
int32_t order = (pPhyFillNode->inputTsOrder == ORDER_ASC) ? TSDB_ORDER_ASC : TSDB_ORDER_DESC;
int32_t type = convertFillType(pPhyFillNode->mode);
@@ -3741,9 +3748,9 @@ SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SFillPhysiNode*
SArray* pColMatchColInfo = extractColMatchInfo(pPhyFillNode->pFillExprs, pPhyFillNode->node.pOutputDataBlockDesc,
&numOfOutputCols, COL_MATCH_FROM_SLOT_ID);
- int32_t code =
- initFillInfo(pInfo, pExprInfo, pInfo->numOfExpr, pInfo->pNotFillExprInfo, pInfo->numOfNotFillExpr, (SNodeListNode*)pPhyFillNode->pValues,
- pPhyFillNode->timeRange, pResultInfo->capacity, pTaskInfo->id.str, pInterval, type, order);
+ int32_t code = initFillInfo(pInfo, pExprInfo, pInfo->numOfExpr, pInfo->pNotFillExprInfo, pInfo->numOfNotFillExpr,
+ (SNodeListNode*)pPhyFillNode->pValues, pPhyFillNode->timeRange, pResultInfo->capacity,
+ pTaskInfo->id.str, pInterval, type, order);
if (code != TSDB_CODE_SUCCESS) {
goto _error;
}
diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c
index aca0078592..7b13aa8ad8 100644
--- a/source/libs/executor/src/scanoperator.c
+++ b/source/libs/executor/src/scanoperator.c
@@ -139,7 +139,7 @@ static bool overlapWithTimeWindow(SInterval* pInterval, SDataBlockInfo* pBlockIn
}
assert(w.ekey > pBlockInfo->window.ekey);
- if (w.skey <= pBlockInfo->window.ekey && w.skey > pBlockInfo->window.skey) {
+ if (TMAX(w.skey, pBlockInfo->window.skey) <= pBlockInfo->window.ekey) {
return true;
}
}
@@ -147,7 +147,7 @@ static bool overlapWithTimeWindow(SInterval* pInterval, SDataBlockInfo* pBlockIn
w = getAlignQueryTimeWindow(pInterval, pInterval->precision, pBlockInfo->window.ekey);
assert(w.skey <= pBlockInfo->window.ekey);
- if (w.skey > pBlockInfo->window.skey) {
+ if (TMAX(w.skey, pBlockInfo->window.skey) <= TMIN(w.ekey, pBlockInfo->window.ekey)) {
return true;
}
@@ -158,7 +158,7 @@ static bool overlapWithTimeWindow(SInterval* pInterval, SDataBlockInfo* pBlockIn
}
assert(w.skey < pBlockInfo->window.skey);
- if (w.ekey < pBlockInfo->window.ekey && w.ekey >= pBlockInfo->window.skey) {
+ if (pBlockInfo->window.skey <= TMIN(w.ekey, pBlockInfo->window.ekey)) {
return true;
}
}
@@ -1649,6 +1649,8 @@ SOperatorInfo* createStreamScanOperatorInfo(SReadHandle* pHandle, STableScanPhys
}
taosArrayDestroy(tableIdList);
memcpy(&pTaskInfo->streamInfo.tableCond, &pTSInfo->cond, sizeof(SQueryTableDataCond));
+ } else {
+ taosArrayDestroy(pColIds);
}
// create the pseduo columns info
@@ -2038,10 +2040,34 @@ static SSDataBlock* sysTableScanUserTags(SOperatorInfo* pOperator) {
metaReaderClear(&smr);
if (numOfRows >= pOperator->resultInfo.capacity) {
- break;
+ p->info.rows = numOfRows;
+ pInfo->pRes->info.rows = numOfRows;
+
+ relocateColumnData(pInfo->pRes, pInfo->scanCols, p->pDataBlock, false);
+ doFilterResult(pInfo);
+
+ blockDataCleanup(p);
+ numOfRows = 0;
+
+ if (pInfo->pRes->info.rows > 0) {
+ break;
+ }
}
}
+ if (numOfRows > 0) {
+ p->info.rows = numOfRows;
+ pInfo->pRes->info.rows = numOfRows;
+
+ relocateColumnData(pInfo->pRes, pInfo->scanCols, p->pDataBlock, false);
+ doFilterResult(pInfo);
+
+ blockDataCleanup(p);
+ numOfRows = 0;
+ }
+
+ blockDataDestroy(p);
+
// todo temporarily free the cursor here, the true reason why the free is not valid needs to be found
if (ret != 0) {
metaCloseTbCursor(pInfo->pCur);
@@ -2049,14 +2075,6 @@ static SSDataBlock* sysTableScanUserTags(SOperatorInfo* pOperator) {
doSetOperatorCompleted(pOperator);
}
- p->info.rows = numOfRows;
- pInfo->pRes->info.rows = numOfRows;
-
- relocateColumnData(pInfo->pRes, pInfo->scanCols, p->pDataBlock, false);
- doFilterResult(pInfo);
-
- blockDataDestroy(p);
-
pInfo->loadInfo.totalRows += pInfo->pRes->info.rows;
return (pInfo->pRes->info.rows == 0) ? NULL : pInfo->pRes;
}
@@ -2213,10 +2231,34 @@ static SSDataBlock* sysTableScanUserTables(SOperatorInfo* pOperator) {
colDataAppend(pColInfoData, numOfRows, n, false);
if (++numOfRows >= pOperator->resultInfo.capacity) {
- break;
+ p->info.rows = numOfRows;
+ pInfo->pRes->info.rows = numOfRows;
+
+ relocateColumnData(pInfo->pRes, pInfo->scanCols, p->pDataBlock, false);
+ doFilterResult(pInfo);
+
+ blockDataCleanup(p);
+ numOfRows = 0;
+
+ if (pInfo->pRes->info.rows > 0) {
+ break;
+ }
}
}
+ if (numOfRows > 0) {
+ p->info.rows = numOfRows;
+ pInfo->pRes->info.rows = numOfRows;
+
+ relocateColumnData(pInfo->pRes, pInfo->scanCols, p->pDataBlock, false);
+ doFilterResult(pInfo);
+
+ blockDataCleanup(p);
+ numOfRows = 0;
+ }
+
+ blockDataDestroy(p);
+
// todo temporarily free the cursor here, the true reason why the free is not valid needs to be found
if (ret != 0) {
metaCloseTbCursor(pInfo->pCur);
@@ -2224,14 +2266,6 @@ static SSDataBlock* sysTableScanUserTables(SOperatorInfo* pOperator) {
doSetOperatorCompleted(pOperator);
}
- p->info.rows = numOfRows;
- pInfo->pRes->info.rows = numOfRows;
-
- relocateColumnData(pInfo->pRes, pInfo->scanCols, p->pDataBlock, false);
- doFilterResult(pInfo);
-
- blockDataDestroy(p);
-
pInfo->loadInfo.totalRows += pInfo->pRes->info.rows;
return (pInfo->pRes->info.rows == 0) ? NULL : pInfo->pRes;
}
diff --git a/source/libs/executor/src/timewindowoperator.c b/source/libs/executor/src/timewindowoperator.c
index 6418f5305c..9b9a38c7ea 100644
--- a/source/libs/executor/src/timewindowoperator.c
+++ b/source/libs/executor/src/timewindowoperator.c
@@ -871,7 +871,6 @@ static int32_t saveWinResult(int64_t ts, int32_t pageId, int32_t offset, uint64_
static int32_t saveWinResultRow(SResultRow* result, uint64_t groupId, SHashObj* pUpdatedMap) {
return saveWinResult(result->win.skey, result->pageId, result->offset, groupId, pUpdatedMap);
- ;
}
static int32_t saveResultRow(SResultRow* result, uint64_t groupId, SArray* pUpdated) {
@@ -910,11 +909,11 @@ int32_t compareWinRes(void* pKey, void* data, int32_t index) {
}
static void removeDeleteResults(SHashObj* pUpdatedMap, SArray* pDelWins) {
- if (!pUpdatedMap || taosHashGetSize(pUpdatedMap) == 0) {
+ int32_t delSize = taosArrayGetSize(pDelWins);
+ if (taosHashGetSize(pUpdatedMap) == 0 || delSize == 0) {
return;
}
- int32_t delSize = taosArrayGetSize(pDelWins);
- void* pIte = NULL;
+ void* pIte = NULL;
while ((pIte = taosHashIterate(pUpdatedMap, pIte)) != NULL) {
SResKeyPos* pResKey = (SResKeyPos*)pIte;
int32_t index = binarySearchCom(pDelWins, delSize, pResKey, TSDB_ORDER_DESC, compareWinRes);
@@ -1595,7 +1594,7 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) {
SOperatorInfo* downstream = pOperator->pDownstream[0];
SArray* pUpdated = taosArrayInit(4, POINTER_BYTES); // SResKeyPos
- _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_TIMESTAMP);
+ _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
SHashObj* pUpdatedMap = taosHashInit(1024, hashFn, false, HASH_NO_LOCK);
while (1) {
SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream);
@@ -1706,14 +1705,19 @@ void destroyStreamFinalIntervalOperatorInfo(void* param, int32_t numOfOutput) {
blockDataDestroy(pInfo->pPullDataRes);
taosArrayDestroy(pInfo->pRecycledPages);
blockDataDestroy(pInfo->pUpdateRes);
+ taosArrayDestroy(pInfo->pDelWins);
+ blockDataDestroy(pInfo->pDelRes);
if (pInfo->pChildren) {
int32_t size = taosArrayGetSize(pInfo->pChildren);
for (int32_t i = 0; i < size; i++) {
SOperatorInfo* pChildOp = taosArrayGetP(pInfo->pChildren, i);
destroyStreamFinalIntervalOperatorInfo(pChildOp->info, numOfOutput);
+ taosMemoryFree(pChildOp->pDownstream);
+ cleanupExprSupp(&pChildOp->exprSupp);
taosMemoryFreeClear(pChildOp);
}
+ taosArrayDestroy(pInfo->pChildren);
}
nodesDestroyNode((SNode*)pInfo->pPhyNode);
colDataDestroy(&pInfo->twAggSup.timeWindowData);
@@ -1780,7 +1784,7 @@ void increaseTs(SqlFunctionCtx* pCtx) {
}
}
-void initIntervalDownStream(SOperatorInfo* downstream, uint8_t type, SAggSupporter* pSup) {
+void initIntervalDownStream(SOperatorInfo* downstream, uint16_t type, SAggSupporter* pSup) {
if (downstream->operatorType != QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN) {
// Todo(liuyao) support partition by column
return;
@@ -1881,62 +1885,6 @@ _error:
return NULL;
}
-SOperatorInfo* createStreamIntervalOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols,
- SSDataBlock* pResBlock, SInterval* pInterval, int32_t primaryTsSlotId,
- STimeWindowAggSupp* pTwAggSupp, SExecTaskInfo* pTaskInfo) {
- SIntervalAggOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SIntervalAggOperatorInfo));
- SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
- if (pInfo == NULL || pOperator == NULL) {
- goto _error;
- }
-
- pOperator->pTaskInfo = pTaskInfo;
- pInfo->inputOrder = TSDB_ORDER_ASC;
- pInfo->interval = *pInterval;
- pInfo->execModel = OPTR_EXEC_MODEL_STREAM;
- pInfo->win = pTaskInfo->window;
- pInfo->twAggSup = *pTwAggSupp;
- pInfo->primaryTsIndex = primaryTsSlotId;
-
- int32_t numOfRows = 4096;
- size_t keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES;
-
- initResultSizeInfo(&pOperator->resultInfo, numOfRows);
- int32_t code = initAggInfo(&pOperator->exprSupp, &pInfo->aggSup, pExprInfo, numOfCols, keyBufSize, pTaskInfo->id.str);
- initBasicInfo(&pInfo->binfo, pResBlock);
- initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pInfo->win);
-
- if (code != TSDB_CODE_SUCCESS) {
- goto _error;
- }
-
- initResultRowInfo(&pInfo->binfo.resultRowInfo);
-
- pOperator->name = "StreamTimeIntervalAggOperator";
- pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_HASH_INTERVAL;
- pOperator->blocking = true;
- pOperator->status = OP_NOT_OPENED;
- pOperator->exprSupp.pExprInfo = pExprInfo;
- pOperator->exprSupp.numOfExprs = numOfCols;
- pOperator->info = pInfo;
-
- pOperator->fpSet = createOperatorFpSet(doOpenIntervalAgg, doStreamIntervalAgg, doStreamIntervalAgg, NULL,
- destroyIntervalOperatorInfo, aggEncodeResultRow, aggDecodeResultRow, NULL);
-
- code = appendDownstream(pOperator, &downstream, 1);
- if (code != TSDB_CODE_SUCCESS) {
- goto _error;
- }
-
- return pOperator;
-
-_error:
- destroyIntervalOperatorInfo(pInfo, numOfCols);
- taosMemoryFreeClear(pOperator);
- pTaskInfo->code = code;
- return NULL;
-}
-
// todo handle multiple timeline cases. assume no timeline interweaving
static void doSessionWindowAggImpl(SOperatorInfo* pOperator, SSessionAggOperatorInfo* pInfo, SSDataBlock* pBlock) {
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
@@ -2154,7 +2102,7 @@ static void doKeepLinearInfo(STimeSliceOperatorInfo* pSliceInfo, const SSDataBlo
static void genInterpolationResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp* pExprSup, SSDataBlock* pResBlock) {
int32_t rows = pResBlock->info.rows;
-
+ blockDataEnsureCapacity(pResBlock, rows + 1);
// todo set the correct primary timestamp column
// output the result
@@ -2408,11 +2356,11 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) {
break;
}
}
+ }
- if (pSliceInfo->current > pSliceInfo->win.ekey) {
- doSetOperatorCompleted(pOperator);
- break;
- }
+ if (pSliceInfo->current > pSliceInfo->win.ekey) {
+ doSetOperatorCompleted(pOperator);
+ break;
}
if (ts == pSliceInfo->current) {
@@ -2644,7 +2592,6 @@ void destroyTimeSliceOperatorInfo(void* param, int32_t numOfOutput) {
taosMemoryFreeClear(param);
}
-
SOperatorInfo* createTimeSliceOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo) {
STimeSliceOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(STimeSliceOperatorInfo));
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
@@ -3105,11 +3052,12 @@ void processPullOver(SSDataBlock* pBlock, SHashObj* pMap) {
static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) {
SStreamFinalIntervalOperatorInfo* pInfo = pOperator->info;
- SOperatorInfo* downstream = pOperator->pDownstream[0];
- SArray* pUpdated = taosArrayInit(4, POINTER_BYTES);
- _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_TIMESTAMP);
- SHashObj* pUpdatedMap = taosHashInit(1024, hashFn, false, HASH_NO_LOCK);
- TSKEY maxTs = INT64_MIN;
+
+ SOperatorInfo* downstream = pOperator->pDownstream[0];
+ SArray* pUpdated = taosArrayInit(4, POINTER_BYTES);
+ _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
+ SHashObj* pUpdatedMap = taosHashInit(1024, hashFn, false, HASH_NO_LOCK);
+ TSKEY maxTs = INT64_MIN;
SExprSupp* pSup = &pOperator->exprSupp;
@@ -3542,7 +3490,7 @@ void initDummyFunction(SqlFunctionCtx* pDummy, SqlFunctionCtx* pCtx, int32_t num
}
void initDownStream(SOperatorInfo* downstream, SStreamAggSupporter* pAggSup, int64_t gap, int64_t waterMark,
- uint8_t type) {
+ uint16_t type) {
ASSERT(downstream->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN);
SStreamScanInfo* pScanInfo = downstream->info;
pScanInfo->sessionSup = (SessionWindowSupporter){.pStreamAggSup = pAggSup, .gap = gap, .parentType = type};
diff --git a/source/libs/executor/src/tsimplehash.c b/source/libs/executor/src/tsimplehash.c
index 7989ad2b5a..6b2edf0d5e 100644
--- a/source/libs/executor/src/tsimplehash.c
+++ b/source/libs/executor/src/tsimplehash.c
@@ -14,8 +14,8 @@
*/
#include "tsimplehash.h"
-#include "os.h"
#include "taoserror.h"
+#include "tlog.h"
#define SHASH_DEFAULT_LOAD_FACTOR 0.75
#define HASH_MAX_CAPACITY (1024 * 1024 * 16)
@@ -31,19 +31,21 @@
taosMemoryFreeClear(_n); \
} while (0);
+#pragma pack(push, 4)
typedef struct SHNode {
struct SHNode *next;
+ uint32_t keyLen : 20;
+ uint32_t dataLen : 12;
char data[];
} SHNode;
+#pragma pack(pop)
struct SSHashObj {
SHNode **hashList;
size_t capacity; // number of slots
- int64_t size; // number of elements in hash table
- _hash_fn_t hashFp; // hash function
- _equal_fn_t equalFp; // equal function
- int32_t keyLen;
- int32_t dataLen;
+ int64_t size; // number of elements in hash table
+ _hash_fn_t hashFp; // hash function
+ _equal_fn_t equalFp; // equal function
};
static FORCE_INLINE int32_t taosHashCapacity(int32_t length) {
@@ -54,7 +56,7 @@ static FORCE_INLINE int32_t taosHashCapacity(int32_t length) {
return i;
}
-SSHashObj *tSimpleHashInit(size_t capacity, _hash_fn_t fn, size_t keyLen, size_t dataLen) {
+SSHashObj *tSimpleHashInit(size_t capacity, _hash_fn_t fn) {
ASSERT(fn != NULL);
if (capacity == 0) {
@@ -74,8 +76,6 @@ SSHashObj *tSimpleHashInit(size_t capacity, _hash_fn_t fn, size_t keyLen, size_t
pHashObj->hashFp = fn;
ASSERT((pHashObj->capacity & (pHashObj->capacity - 1)) == 0);
- pHashObj->keyLen = keyLen;
- pHashObj->dataLen = dataLen;
pHashObj->hashList = (SHNode **)taosMemoryCalloc(pHashObj->capacity, sizeof(void *));
if (!pHashObj->hashList) {
@@ -93,40 +93,41 @@ int32_t tSimpleHashGetSize(const SSHashObj *pHashObj) {
return (int32_t)atomic_load_64((int64_t *)&pHashObj->size);
}
-static SHNode *doCreateHashNode(const void *key, size_t keyLen, const void *pData, size_t dsize, uint32_t hashVal) {
- SHNode *pNewNode = taosMemoryMalloc(sizeof(SHNode) + keyLen + dsize);
+static SHNode *doCreateHashNode(const void *key, size_t keyLen, const void *data, size_t dataLen, uint32_t hashVal) {
+ SHNode *pNewNode = taosMemoryMalloc(sizeof(SHNode) + keyLen + dataLen);
if (!pNewNode) {
terrno = TSDB_CODE_OUT_OF_MEMORY;
return NULL;
}
-
+ pNewNode->keyLen = keyLen;
+ pNewNode->dataLen = dataLen;
pNewNode->next = NULL;
- memcpy(GET_SHASH_NODE_DATA(pNewNode), pData, dsize);
- memcpy(GET_SHASH_NODE_KEY(pNewNode, dsize), key, keyLen);
+ memcpy(GET_SHASH_NODE_DATA(pNewNode), data, dataLen);
+ memcpy(GET_SHASH_NODE_KEY(pNewNode, dataLen), key, keyLen);
return pNewNode;
}
-static void taosHashTableResize(SSHashObj *pHashObj) {
+static void tSimpleHashTableResize(SSHashObj *pHashObj) {
if (!SHASH_NEED_RESIZE(pHashObj)) {
return;
}
int32_t newCapacity = (int32_t)(pHashObj->capacity << 1u);
if (newCapacity > HASH_MAX_CAPACITY) {
- // uDebug("current capacity:%zu, maximum capacity:%d, no resize applied due to limitation is reached",
- // pHashObj->capacity, HASH_MAX_CAPACITY);
+ uDebug("current capacity:%zu, maximum capacity:%" PRIu64 ", no resize applied due to limitation is reached",
+ pHashObj->capacity, HASH_MAX_CAPACITY);
return;
}
int64_t st = taosGetTimestampUs();
void *pNewEntryList = taosMemoryRealloc(pHashObj->hashList, sizeof(void *) * newCapacity);
if (!pNewEntryList) {
- // qWarn("hash resize failed due to out of memory, capacity remain:%zu", pHashObj->capacity);
+ uWarn("hash resize failed due to out of memory, capacity remain:%zu", pHashObj->capacity);
return;
}
size_t inc = newCapacity - pHashObj->capacity;
- memset((char *)pNewEntryList + pHashObj->capacity * sizeof(void *), 0, inc);
+ memset((char *)pNewEntryList + pHashObj->capacity * sizeof(void *), 0, inc * sizeof(void *));
pHashObj->hashList = pNewEntryList;
pHashObj->capacity = newCapacity;
@@ -141,8 +142,8 @@ static void taosHashTableResize(SSHashObj *pHashObj) {
SHNode *pPrev = NULL;
while (pNode != NULL) {
- void *key = GET_SHASH_NODE_KEY(pNode, pHashObj->dataLen);
- uint32_t hashVal = (*pHashObj->hashFp)(key, (uint32_t)pHashObj->keyLen);
+ void *key = GET_SHASH_NODE_KEY(pNode, pNode->dataLen);
+ uint32_t hashVal = (*pHashObj->hashFp)(key, (uint32_t)pNode->keyLen);
int32_t newIdx = HASH_INDEX(hashVal, pHashObj->capacity);
pNext = pNode->next;
@@ -170,23 +171,23 @@ static void taosHashTableResize(SSHashObj *pHashObj) {
// ((double)pHashObj->size) / pHashObj->capacity, (et - st) / 1000.0);
}
-int32_t tSimpleHashPut(SSHashObj *pHashObj, const void *key, const void *data) {
+int32_t tSimpleHashPut(SSHashObj *pHashObj, const void *key, size_t keyLen, const void *data, size_t dataLen) {
if (!pHashObj || !key) {
return -1;
}
- uint32_t hashVal = (*pHashObj->hashFp)(key, (uint32_t)pHashObj->keyLen);
+ uint32_t hashVal = (*pHashObj->hashFp)(key, (uint32_t)keyLen);
// need the resize process, write lock applied
if (SHASH_NEED_RESIZE(pHashObj)) {
- taosHashTableResize(pHashObj);
+ tSimpleHashTableResize(pHashObj);
}
int32_t slot = HASH_INDEX(hashVal, pHashObj->capacity);
SHNode *pNode = pHashObj->hashList[slot];
if (!pNode) {
- SHNode *pNewNode = doCreateHashNode(key, pHashObj->keyLen, data, pHashObj->dataLen, hashVal);
+ SHNode *pNewNode = doCreateHashNode(key, keyLen, data, dataLen, hashVal);
if (!pNewNode) {
return -1;
}
@@ -197,14 +198,14 @@ int32_t tSimpleHashPut(SSHashObj *pHashObj, const void *key, const void *data) {
}
while (pNode) {
- if ((*(pHashObj->equalFp))(GET_SHASH_NODE_KEY(pNode, pHashObj->dataLen), key, pHashObj->keyLen) == 0) {
+ if ((*(pHashObj->equalFp))(GET_SHASH_NODE_KEY(pNode, pNode->dataLen), key, keyLen) == 0) {
break;
}
pNode = pNode->next;
}
if (!pNode) {
- SHNode *pNewNode = doCreateHashNode(key, pHashObj->keyLen, data, pHashObj->dataLen, hashVal);
+ SHNode *pNewNode = doCreateHashNode(key, keyLen, data, dataLen, hashVal);
if (!pNewNode) {
return -1;
}
@@ -212,16 +213,16 @@ int32_t tSimpleHashPut(SSHashObj *pHashObj, const void *key, const void *data) {
pHashObj->hashList[slot] = pNewNode;
atomic_add_fetch_64(&pHashObj->size, 1);
} else { // update data
- memcpy(GET_SHASH_NODE_DATA(pNode), data, pHashObj->dataLen);
+ memcpy(GET_SHASH_NODE_DATA(pNode), data, dataLen);
}
return 0;
}
-static FORCE_INLINE SHNode *doSearchInEntryList(SSHashObj *pHashObj, const void *key, int32_t index) {
+static FORCE_INLINE SHNode *doSearchInEntryList(SSHashObj *pHashObj, const void *key, size_t keyLen, int32_t index) {
SHNode *pNode = pHashObj->hashList[index];
while (pNode) {
- if ((*(pHashObj->equalFp))(GET_SHASH_NODE_KEY(pNode, pHashObj->dataLen), key, pHashObj->keyLen) == 0) {
+ if ((*(pHashObj->equalFp))(GET_SHASH_NODE_KEY(pNode, pNode->dataLen), key, keyLen) == 0) {
break;
}
@@ -233,12 +234,12 @@ static FORCE_INLINE SHNode *doSearchInEntryList(SSHashObj *pHashObj, const void
static FORCE_INLINE bool taosHashTableEmpty(const SSHashObj *pHashObj) { return tSimpleHashGetSize(pHashObj) == 0; }
-void *tSimpleHashGet(SSHashObj *pHashObj, const void *key) {
+void *tSimpleHashGet(SSHashObj *pHashObj, const void *key, size_t keyLen) {
if (!pHashObj || taosHashTableEmpty(pHashObj) || !key) {
return NULL;
}
- uint32_t hashVal = (*pHashObj->hashFp)(key, (uint32_t)pHashObj->keyLen);
+ uint32_t hashVal = (*pHashObj->hashFp)(key, (uint32_t)keyLen);
int32_t slot = HASH_INDEX(hashVal, pHashObj->capacity);
SHNode *pNode = pHashObj->hashList[slot];
@@ -247,7 +248,7 @@ void *tSimpleHashGet(SSHashObj *pHashObj, const void *key) {
}
char *data = NULL;
- pNode = doSearchInEntryList(pHashObj, key, slot);
+ pNode = doSearchInEntryList(pHashObj, key, keyLen, slot);
if (pNode != NULL) {
data = GET_SHASH_NODE_DATA(pNode);
}
@@ -255,19 +256,19 @@ void *tSimpleHashGet(SSHashObj *pHashObj, const void *key) {
return data;
}
-int32_t tSimpleHashRemove(SSHashObj *pHashObj, const void *key) {
+int32_t tSimpleHashRemove(SSHashObj *pHashObj, const void *key, size_t keyLen) {
if (!pHashObj || !key) {
return TSDB_CODE_FAILED;
}
- uint32_t hashVal = (*pHashObj->hashFp)(key, (uint32_t)pHashObj->keyLen);
+ uint32_t hashVal = (*pHashObj->hashFp)(key, (uint32_t)keyLen);
int32_t slot = HASH_INDEX(hashVal, pHashObj->capacity);
SHNode *pNode = pHashObj->hashList[slot];
SHNode *pPrev = NULL;
while (pNode) {
- if ((*(pHashObj->equalFp))(GET_SHASH_NODE_KEY(pNode, pHashObj->dataLen), key, pHashObj->keyLen) == 0) {
+ if ((*(pHashObj->equalFp))(GET_SHASH_NODE_KEY(pNode, pNode->dataLen), key, keyLen) == 0) {
if (!pPrev) {
pHashObj->hashList[slot] = pNode->next;
} else {
@@ -312,6 +313,7 @@ void tSimpleHashCleanup(SSHashObj *pHashObj) {
tSimpleHashClear(pHashObj);
taosMemoryFreeClear(pHashObj->hashList);
+ taosMemoryFree(pHashObj);
}
size_t tSimpleHashGetMemSize(const SSHashObj *pHashObj) {
@@ -322,23 +324,13 @@ size_t tSimpleHashGetMemSize(const SSHashObj *pHashObj) {
return (pHashObj->capacity * sizeof(void *)) + sizeof(SHNode) * tSimpleHashGetSize(pHashObj) + sizeof(SSHashObj);
}
-void *tSimpleHashGetKey(const SSHashObj *pHashObj, void *data, size_t *keyLen) {
-#if 0
- int32_t offset = offsetof(SHNode, data);
- SHNode *node = ((SHNode *)(char *)data - offset);
+void *tSimpleHashGetKey(void *data, size_t *keyLen) {
+ SHNode *node = (SHNode *)((char *)data - offsetof(SHNode, data));
if (keyLen) {
- *keyLen = pHashObj->keyLen;
+ *keyLen = node->keyLen;
}
- return POINTER_SHIFT(data, pHashObj->dataLen);
-
- return GET_SHASH_NODE_KEY(node, pHashObj->dataLen);
-#endif
- if (keyLen) {
- *keyLen = pHashObj->keyLen;
- }
-
- return POINTER_SHIFT(data, pHashObj->dataLen);
+ return POINTER_SHIFT(data, node->dataLen);
}
void *tSimpleHashIterate(const SSHashObj *pHashObj, void *data, int32_t *iter) {
@@ -376,5 +368,52 @@ void *tSimpleHashIterate(const SSHashObj *pHashObj, void *data, int32_t *iter) {
return GET_SHASH_NODE_DATA(pNode);
}
+ return NULL;
+}
+
+void *tSimpleHashIterateKV(const SSHashObj *pHashObj, void *data, void **key, int32_t *iter) {
+ if (!pHashObj) {
+ return NULL;
+ }
+
+ SHNode *pNode = NULL;
+
+ if (!data) {
+ for (int32_t i = 0; i < pHashObj->capacity; ++i) {
+ pNode = pHashObj->hashList[i];
+ if (!pNode) {
+ continue;
+ }
+ *iter = i;
+ if (key) {
+ *key = GET_SHASH_NODE_KEY(pNode, pNode->dataLen);
+ }
+ return GET_SHASH_NODE_DATA(pNode);
+ }
+ return NULL;
+ }
+
+ pNode = (SHNode *)((char *)data - offsetof(SHNode, data));
+
+ if (pNode->next) {
+ if (key) {
+ *key = GET_SHASH_NODE_KEY(pNode->next, pNode->next->dataLen);
+ }
+ return GET_SHASH_NODE_DATA(pNode->next);
+ }
+
+ ++(*iter);
+ for (int32_t i = *iter; i < pHashObj->capacity; ++i) {
+ pNode = pHashObj->hashList[i];
+ if (!pNode) {
+ continue;
+ }
+ *iter = i;
+ if (key) {
+ *key = GET_SHASH_NODE_KEY(pNode, pNode->dataLen);
+ }
+ return GET_SHASH_NODE_DATA(pNode);
+ }
+
return NULL;
}
\ No newline at end of file
diff --git a/source/libs/executor/test/tSimpleHashTests.cpp b/source/libs/executor/test/tSimpleHashTests.cpp
index a17a7146ea..acb6d434b4 100644
--- a/source/libs/executor/test/tSimpleHashTests.cpp
+++ b/source/libs/executor/test/tSimpleHashTests.cpp
@@ -32,31 +32,33 @@
TEST(testCase, tSimpleHashTest) {
SSHashObj *pHashObj =
- tSimpleHashInit(8, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), sizeof(int64_t), sizeof(int64_t));
+ tSimpleHashInit(8, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT));
assert(pHashObj != nullptr);
ASSERT_EQ(0, tSimpleHashGetSize(pHashObj));
+ size_t keyLen = sizeof(int64_t);
+ size_t dataLen = sizeof(int64_t);
+
int64_t originKeySum = 0;
for (int64_t i = 1; i <= 100; ++i) {
originKeySum += i;
- tSimpleHashPut(pHashObj, (const void *)&i, (const void *)&i);
+ tSimpleHashPut(pHashObj, (const void *)&i, keyLen, (const void *)&i, dataLen);
ASSERT_EQ(i, tSimpleHashGetSize(pHashObj));
}
for (int64_t i = 1; i <= 100; ++i) {
- void *data = tSimpleHashGet(pHashObj, (const void *)&i);
+ void *data = tSimpleHashGet(pHashObj, (const void *)&i, keyLen);
ASSERT_EQ(i, *(int64_t *)data);
}
-
void *data = NULL;
int32_t iter = 0;
int64_t keySum = 0;
int64_t dataSum = 0;
while ((data = tSimpleHashIterate(pHashObj, data, &iter))) {
- void *key = tSimpleHashGetKey(pHashObj, data, NULL);
+ void *key = tSimpleHashGetKey(data, NULL);
keySum += *(int64_t *)key;
dataSum += *(int64_t *)data;
}
@@ -65,7 +67,7 @@ TEST(testCase, tSimpleHashTest) {
ASSERT_EQ(keySum, originKeySum);
for (int64_t i = 1; i <= 100; ++i) {
- tSimpleHashRemove(pHashObj, (const void *)&i);
+ tSimpleHashRemove(pHashObj, (const void *)&i, keyLen);
ASSERT_EQ(100 - i, tSimpleHashGetSize(pHashObj));
}
diff --git a/source/libs/function/src/builtins.c b/source/libs/function/src/builtins.c
index c19b459cdb..ed82e4cb50 100644
--- a/source/libs/function/src/builtins.c
+++ b/source/libs/function/src/builtins.c
@@ -1503,11 +1503,17 @@ static int32_t translateInterp(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
}
+ uint8_t nodeType = nodeType(nodesListGetNode(pFunc->pParameterList, 0));
+ uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
+ if (!IS_NUMERIC_TYPE(paraType) || QUERY_NODE_VALUE == nodeType) {
+ return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
+ }
+
if (3 <= numOfParams) {
int64_t timeVal[2] = {0};
for (int32_t i = 1; i < 3; ++i) {
- uint8_t nodeType = nodeType(nodesListGetNode(pFunc->pParameterList, i));
- uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, i))->resType.type;
+ nodeType = nodeType(nodesListGetNode(pFunc->pParameterList, i));
+ paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, i))->resType.type;
if (!IS_VAR_DATA_TYPE(paraType) || QUERY_NODE_VALUE != nodeType) {
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
}
@@ -1525,8 +1531,8 @@ static int32_t translateInterp(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
}
if (4 == numOfParams) {
- uint8_t nodeType = nodeType(nodesListGetNode(pFunc->pParameterList, 3));
- uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 3))->resType.type;
+ nodeType = nodeType(nodesListGetNode(pFunc->pParameterList, 3));
+ paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 3))->resType.type;
if (!IS_INTEGER_TYPE(paraType) || QUERY_NODE_VALUE != nodeType) {
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
}
diff --git a/source/libs/function/src/builtinsimpl.c b/source/libs/function/src/builtinsimpl.c
index 5aeaecd598..5051dcd65c 100644
--- a/source/libs/function/src/builtinsimpl.c
+++ b/source/libs/function/src/builtinsimpl.c
@@ -3970,16 +3970,16 @@ int32_t elapsedFunction(SqlFunctionCtx* pCtx) {
TSKEY* ptsList = (int64_t*)colDataGetData(pCol, 0);
if (pCtx->order == TSDB_ORDER_DESC) {
if (pCtx->start.key == INT64_MIN) {
- pInfo->max =
- (pInfo->max < ptsList[start + pInput->numOfRows - 1]) ? ptsList[start + pInput->numOfRows - 1] : pInfo->max;
+ pInfo->max = (pInfo->max < ptsList[start]) ? ptsList[start] : pInfo->max;
} else {
pInfo->max = pCtx->start.key + 1;
}
- if (pCtx->end.key != INT64_MIN) {
- pInfo->min = pCtx->end.key;
+ if (pCtx->end.key == INT64_MIN) {
+ pInfo->min = (pInfo->min > ptsList[start + pInput->numOfRows - 1]) ?
+ ptsList[start + pInput->numOfRows - 1] : pInfo->min;
} else {
- pInfo->min = ptsList[start];
+ pInfo->min = pCtx->end.key;
}
} else {
if (pCtx->start.key == INT64_MIN) {
@@ -3988,10 +3988,11 @@ int32_t elapsedFunction(SqlFunctionCtx* pCtx) {
pInfo->min = pCtx->start.key;
}
- if (pCtx->end.key != INT64_MIN) {
- pInfo->max = pCtx->end.key + 1;
+ if (pCtx->end.key == INT64_MIN) {
+ pInfo->max = (pInfo->max < ptsList[start + pInput->numOfRows - 1]) ?
+ ptsList[start + pInput->numOfRows - 1] : pInfo->max;
} else {
- pInfo->max = ptsList[start + pInput->numOfRows - 1];
+ pInfo->max = pCtx->end.key + 1;
}
}
}
@@ -5573,6 +5574,7 @@ int32_t twaFunction(SqlFunctionCtx* pCtx) {
if (pCtx->end.key != INT64_MIN) {
pInfo->dOutput += twa_get_area(pInfo->p, pCtx->end);
pInfo->p = pCtx->end;
+ numOfElems += 1;
}
pInfo->win.ekey = pInfo->p.key;
diff --git a/source/libs/nodes/src/nodesCodeFuncs.c b/source/libs/nodes/src/nodesCodeFuncs.c
index a6546f3299..0f32001c47 100644
--- a/source/libs/nodes/src/nodesCodeFuncs.c
+++ b/source/libs/nodes/src/nodesCodeFuncs.c
@@ -4673,7 +4673,6 @@ static int32_t jsonToNode(const SJson* pJson, void* pObj) {
int32_t code;
tjsonGetNumberValue(pJson, jkNodeType, pNode->type, code);
- ;
if (TSDB_CODE_SUCCESS == code) {
code = tjsonToObject(pJson, nodesNodeName(pNode->type), jsonToSpecificNode, pNode);
if (TSDB_CODE_SUCCESS != code) {
diff --git a/source/libs/nodes/src/nodesToSQLFuncs.c b/source/libs/nodes/src/nodesToSQLFuncs.c
index 3b129740e8..e521c57c3d 100644
--- a/source/libs/nodes/src/nodesToSQLFuncs.c
+++ b/source/libs/nodes/src/nodesToSQLFuncs.c
@@ -21,36 +21,89 @@
#include "taoserror.h"
#include "thash.h"
-char *gOperatorStr[] = {NULL,
- "+",
- "-",
- "*",
- "/",
- "%",
- "-",
- "&",
- "|",
- ">",
- ">=",
- "<",
- "<=",
- "=",
- "<>",
- "IN",
- "NOT IN",
- "LIKE",
- "NOT LIKE",
- "MATCH",
- "NMATCH",
- "IS NULL",
- "IS NOT NULL",
- "IS TRUE",
- "IS FALSE",
- "IS UNKNOWN",
- "IS NOT TRUE",
- "IS NOT FALSE",
- "IS NOT UNKNOWN"};
-char *gLogicConditionStr[] = {"AND", "OR", "NOT"};
+const char *operatorTypeStr(EOperatorType type) {
+ switch (type) {
+ case OP_TYPE_ADD:
+ return "+";
+ case OP_TYPE_SUB:
+ return "-";
+ case OP_TYPE_MULTI:
+ return "*";
+ case OP_TYPE_DIV:
+ return "/";
+ case OP_TYPE_REM:
+ return "%";
+ case OP_TYPE_MINUS:
+ return "-";
+ case OP_TYPE_BIT_AND:
+ return "&";
+ case OP_TYPE_BIT_OR:
+ return "|";
+ case OP_TYPE_GREATER_THAN:
+ return ">";
+ case OP_TYPE_GREATER_EQUAL:
+ return ">=";
+ case OP_TYPE_LOWER_THAN:
+ return "<";
+ case OP_TYPE_LOWER_EQUAL:
+ return "<=";
+ case OP_TYPE_EQUAL:
+ return "=";
+ case OP_TYPE_NOT_EQUAL:
+ return "<>";
+ case OP_TYPE_IN:
+ return "IN";
+ case OP_TYPE_NOT_IN:
+ return "NOT IN";
+ case OP_TYPE_LIKE:
+ return "LIKE";
+ case OP_TYPE_NOT_LIKE:
+ return "NOT LIKE";
+ case OP_TYPE_MATCH:
+ return "MATCH";
+ case OP_TYPE_NMATCH:
+ return "NMATCH";
+ case OP_TYPE_IS_NULL:
+ return "IS NULL";
+ case OP_TYPE_IS_NOT_NULL:
+ return "IS NOT NULL";
+ case OP_TYPE_IS_TRUE:
+ return "IS TRUE";
+ case OP_TYPE_IS_FALSE:
+ return "IS FALSE";
+ case OP_TYPE_IS_UNKNOWN:
+ return "IS UNKNOWN";
+ case OP_TYPE_IS_NOT_TRUE:
+ return "IS NOT TRUE";
+ case OP_TYPE_IS_NOT_FALSE:
+ return "IS NOT FALSE";
+ case OP_TYPE_IS_NOT_UNKNOWN:
+ return "IS NOT UNKNOWN";
+ case OP_TYPE_JSON_GET_VALUE:
+ return "=>";
+ case OP_TYPE_JSON_CONTAINS:
+ return "CONTAINS";
+ case OP_TYPE_ASSIGN:
+ return "=";
+ default:
+ break;
+ }
+ return "UNKNOWN";
+}
+
+const char *logicConditionTypeStr(ELogicConditionType type) {
+ switch (type) {
+ case LOGIC_COND_TYPE_AND:
+ return "AND";
+ case LOGIC_COND_TYPE_OR:
+ return "OR";
+ case LOGIC_COND_TYPE_NOT:
+ return "NOT";
+ default:
+ break;
+ }
+ return "UNKNOWN";
+}
int32_t nodesNodeToSQL(SNode *pNode, char *buf, int32_t bufSize, int32_t *len) {
switch (pNode->type) {
@@ -94,12 +147,7 @@ int32_t nodesNodeToSQL(SNode *pNode, char *buf, int32_t bufSize, int32_t *len) {
NODES_ERR_RET(nodesNodeToSQL(pOpNode->pLeft, buf, bufSize, len));
}
- if (pOpNode->opType >= (sizeof(gOperatorStr) / sizeof(gOperatorStr[0]))) {
- nodesError("unknown operation type:%d", pOpNode->opType);
- NODES_ERR_RET(TSDB_CODE_QRY_APP_ERROR);
- }
-
- *len += snprintf(buf + *len, bufSize - *len, " %s ", gOperatorStr[pOpNode->opType]);
+ *len += snprintf(buf + *len, bufSize - *len, " %s ", operatorTypeStr(pOpNode->opType));
if (pOpNode->pRight) {
NODES_ERR_RET(nodesNodeToSQL(pOpNode->pRight, buf, bufSize, len));
@@ -118,7 +166,7 @@ int32_t nodesNodeToSQL(SNode *pNode, char *buf, int32_t bufSize, int32_t *len) {
FOREACH(node, pLogicNode->pParameterList) {
if (!first) {
- *len += snprintf(buf + *len, bufSize - *len, " %s ", gLogicConditionStr[pLogicNode->condType]);
+ *len += snprintf(buf + *len, bufSize - *len, " %s ", logicConditionTypeStr(pLogicNode->condType));
}
NODES_ERR_RET(nodesNodeToSQL(node, buf, bufSize, len));
first = false;
diff --git a/source/libs/parser/src/parInsert.c b/source/libs/parser/src/parInsert.c
index 31ae35e717..0922cdb6b9 100644
--- a/source/libs/parser/src/parInsert.c
+++ b/source/libs/parser/src/parInsert.c
@@ -143,9 +143,9 @@ static int32_t createSName(SName* pName, SToken* pTableName, int32_t acctId, con
}
char name[TSDB_DB_FNAME_LEN] = {0};
strncpy(name, pTableName->z, dbLen);
- dbLen = strdequote(name);
+ int32_t actualDbLen = strdequote(name);
- code = tNameSetDbName(pName, acctId, name, dbLen);
+ code = tNameSetDbName(pName, acctId, name, actualDbLen);
if (code != TSDB_CODE_SUCCESS) {
return buildInvalidOperationMsg(pMsgBuf, msg1);
}
diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c
index 1c7446ad6f..3c0d9a5f63 100644
--- a/source/libs/parser/src/parTranslater.c
+++ b/source/libs/parser/src/parTranslater.c
@@ -2822,6 +2822,29 @@ static int32_t createDefaultFillNode(STranslateContext* pCxt, SNode** pOutput) {
return TSDB_CODE_SUCCESS;
}
+static int32_t checkEvery(STranslateContext* pCxt, SValueNode* pInterval) {
+ int32_t len = strlen(pInterval->literal);
+
+ char *unit = &pInterval->literal[len - 1];
+ if (*unit == 'n' || *unit == 'y') {
+ return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_WRONG_VALUE_TYPE,
+ "Unsupported time unit in EVERY clause");
+ }
+
+ return TSDB_CODE_SUCCESS;
+}
+
+static int32_t translateInterpEvery(STranslateContext* pCxt, SNode** pEvery) {
+ int32_t code = TSDB_CODE_SUCCESS;
+
+ code = checkEvery(pCxt, (SValueNode *)(*pEvery));
+ if (TSDB_CODE_SUCCESS == code) {
+ code = translateExpr(pCxt, pEvery);
+ }
+
+ return code;
+}
+
static int32_t translateInterpFill(STranslateContext* pCxt, SSelectStmt* pSelect) {
int32_t code = TSDB_CODE_SUCCESS;
@@ -2856,7 +2879,7 @@ static int32_t translateInterp(STranslateContext* pCxt, SSelectStmt* pSelect) {
int32_t code = translateExpr(pCxt, &pSelect->pRange);
if (TSDB_CODE_SUCCESS == code) {
- code = translateExpr(pCxt, &pSelect->pEvery);
+ code = translateInterpEvery(pCxt, &pSelect->pEvery);
}
if (TSDB_CODE_SUCCESS == code) {
code = translateInterpFill(pCxt, pSelect);
diff --git a/source/libs/scalar/inc/filterInt.h b/source/libs/scalar/inc/filterInt.h
index 54e873065b..23693c785a 100644
--- a/source/libs/scalar/inc/filterInt.h
+++ b/source/libs/scalar/inc/filterInt.h
@@ -350,7 +350,6 @@ struct SFilterInfo {
extern bool filterDoCompare(__compar_fn_t func, uint8_t optr, void *left, void *right);
extern __compar_fn_t filterGetCompFunc(int32_t type, int32_t optr);
-extern OptrStr gOptrStr[];
#ifdef __cplusplus
}
diff --git a/source/libs/scalar/src/filter.c b/source/libs/scalar/src/filter.c
index 1664a4d612..4377dbf14e 100644
--- a/source/libs/scalar/src/filter.c
+++ b/source/libs/scalar/src/filter.c
@@ -24,46 +24,6 @@
#include "ttime.h"
#include "functionMgt.h"
-OptrStr gOptrStr[] = {
- {0, "invalid"},
- {OP_TYPE_ADD, "+"},
- {OP_TYPE_SUB, "-"},
- {OP_TYPE_MULTI, "*"},
- {OP_TYPE_DIV, "/"},
- {OP_TYPE_REM, "%"},
- {OP_TYPE_MINUS, "minus"},
- {OP_TYPE_ASSIGN, "assign"},
- // bit operator
- {OP_TYPE_BIT_AND, "&"},
- {OP_TYPE_BIT_OR, "|"},
-
- // comparison operator
- {OP_TYPE_GREATER_THAN, ">"},
- {OP_TYPE_GREATER_EQUAL, ">="},
- {OP_TYPE_LOWER_THAN, "<"},
- {OP_TYPE_LOWER_EQUAL, "<="},
- {OP_TYPE_EQUAL, "=="},
- {OP_TYPE_NOT_EQUAL, "!="},
- {OP_TYPE_IN, "in"},
- {OP_TYPE_NOT_IN, "not in"},
- {OP_TYPE_LIKE, "like"},
- {OP_TYPE_NOT_LIKE, "not like"},
- {OP_TYPE_MATCH, "match"},
- {OP_TYPE_NMATCH, "nmatch"},
- {OP_TYPE_IS_NULL, "is null"},
- {OP_TYPE_IS_NOT_NULL, "not null"},
- {OP_TYPE_IS_TRUE, "is true"},
- {OP_TYPE_IS_FALSE, "is false"},
- {OP_TYPE_IS_UNKNOWN, "is unknown"},
- {OP_TYPE_IS_NOT_TRUE, "not true"},
- {OP_TYPE_IS_NOT_FALSE, "not false"},
- {OP_TYPE_IS_NOT_UNKNOWN, "not unknown"},
-
- // json operator
- {OP_TYPE_JSON_GET_VALUE, "->"},
- {OP_TYPE_JSON_CONTAINS, "json contains"}
-};
-
bool filterRangeCompGi (const void *minv, const void *maxv, const void *minr, const void *maxr, __compar_fn_t cfunc) {
int32_t result = cfunc(maxv, minr);
return result >= 0;
@@ -986,7 +946,7 @@ int32_t filterAddUnit(SFilterInfo *info, uint8_t optr, SFilterFieldId *left, SFi
} else {
int32_t paramNum = scalarGetOperatorParamNum(optr);
if (1 != paramNum) {
- fltError("invalid right field in unit, operator:%s, rightType:%d", gOptrStr[optr].str, u->right.type);
+ fltError("invalid right field in unit, operator:%s, rightType:%d", operatorTypeStr(optr), u->right.type);
return TSDB_CODE_QRY_APP_ERROR;
}
}
@@ -1517,7 +1477,7 @@ void filterDumpInfoToString(SFilterInfo *info, const char *msg, int32_t options)
SFilterField *left = FILTER_UNIT_LEFT_FIELD(info, unit);
SColumnNode *refNode = (SColumnNode *)left->desc;
if (unit->compare.optr >= 0 && unit->compare.optr <= OP_TYPE_JSON_CONTAINS){
- len = sprintf(str, "UNIT[%d] => [%d][%d] %s [", i, refNode->dataBlockId, refNode->slotId, gOptrStr[unit->compare.optr].str);
+ len = sprintf(str, "UNIT[%d] => [%d][%d] %s [", i, refNode->dataBlockId, refNode->slotId, operatorTypeStr(unit->compare.optr));
}
if (unit->right.type == FLD_TYPE_VALUE && FILTER_UNIT_OPTR(unit) != OP_TYPE_IN) {
@@ -1536,7 +1496,7 @@ void filterDumpInfoToString(SFilterInfo *info, const char *msg, int32_t options)
if (unit->compare.optr2) {
strcat(str, " && ");
if (unit->compare.optr2 >= 0 && unit->compare.optr2 <= OP_TYPE_JSON_CONTAINS){
- sprintf(str + strlen(str), "[%d][%d] %s [", refNode->dataBlockId, refNode->slotId, gOptrStr[unit->compare.optr2].str);
+ sprintf(str + strlen(str), "[%d][%d] %s [", refNode->dataBlockId, refNode->slotId, operatorTypeStr(unit->compare.optr2));
}
if (unit->right2.type == FLD_TYPE_VALUE && FILTER_UNIT_OPTR(unit) != OP_TYPE_IN) {
diff --git a/source/libs/scalar/test/scalar/scalarTests.cpp b/source/libs/scalar/test/scalar/scalarTests.cpp
index 9b40f0a465..7229fdec38 100644
--- a/source/libs/scalar/test/scalar/scalarTests.cpp
+++ b/source/libs/scalar/test/scalar/scalarTests.cpp
@@ -1089,16 +1089,16 @@ void makeCalculate(void *json, void *key, int32_t rightType, void *rightData, do
}else if(opType == OP_TYPE_ADD || opType == OP_TYPE_SUB || opType == OP_TYPE_MULTI || opType == OP_TYPE_DIV ||
opType == OP_TYPE_REM || opType == OP_TYPE_MINUS){
- printf("op:%s,1result:%f,except:%f\n", gOptrStr[opType].str, *((double *)colDataGetData(column, 0)), exceptValue);
+ printf("op:%s,1result:%f,except:%f\n", operatorTypeStr(opType), *((double *)colDataGetData(column, 0)), exceptValue);
ASSERT_TRUE(fabs(*((double *)colDataGetData(column, 0)) - exceptValue) < 0.0001);
}else if(opType == OP_TYPE_BIT_AND || opType == OP_TYPE_BIT_OR){
- printf("op:%s,2result:%" PRId64 ",except:%f\n", gOptrStr[opType].str, *((int64_t *)colDataGetData(column, 0)), exceptValue);
+ printf("op:%s,2result:%" PRId64 ",except:%f\n", operatorTypeStr(opType), *((int64_t *)colDataGetData(column, 0)), exceptValue);
ASSERT_EQ(*((int64_t *)colDataGetData(column, 0)), exceptValue);
}else if(opType == OP_TYPE_GREATER_THAN || opType == OP_TYPE_GREATER_EQUAL || opType == OP_TYPE_LOWER_THAN ||
opType == OP_TYPE_LOWER_EQUAL || opType == OP_TYPE_EQUAL || opType == OP_TYPE_NOT_EQUAL ||
opType == OP_TYPE_IS_NULL || opType == OP_TYPE_IS_NOT_NULL || opType == OP_TYPE_IS_TRUE ||
opType == OP_TYPE_LIKE || opType == OP_TYPE_NOT_LIKE || opType == OP_TYPE_MATCH || opType == OP_TYPE_NMATCH){
- printf("op:%s,3result:%d,except:%f\n", gOptrStr[opType].str, *((bool *)colDataGetData(column, 0)), exceptValue);
+ printf("op:%s,3result:%d,except:%f\n", operatorTypeStr(opType), *((bool *)colDataGetData(column, 0)), exceptValue);
ASSERT_EQ(*((bool *)colDataGetData(column, 0)), exceptValue);
}
diff --git a/source/libs/scheduler/src/schRemote.c b/source/libs/scheduler/src/schRemote.c
index 8c9003a9b2..ecd9daf1bc 100644
--- a/source/libs/scheduler/src/schRemote.c
+++ b/source/libs/scheduler/src/schRemote.c
@@ -20,7 +20,7 @@
#include "tmsg.h"
#include "tref.h"
#include "trpc.h"
-
+// clang-format off
int32_t schValidateRspMsgType(SSchJob *pJob, SSchTask *pTask, int32_t msgType) {
int32_t lastMsgType = pTask->lastMsgType;
int32_t taskStatus = SCH_GET_TASK_STATUS(pTask);
@@ -402,7 +402,7 @@ int32_t schHandleDropCallback(void *param, SDataBuf *pMsg, int32_t code) {
qDebug("QID:0x%" PRIx64 ",TID:0x%" PRIx64 " drop task rsp received, code:0x%x", pParam->queryId, pParam->taskId,
code);
if (pMsg) {
- taosMemoryFree(pMsg->pData);
+ taosMemoryFree(pMsg->pData);
}
return TSDB_CODE_SUCCESS;
}
@@ -415,7 +415,7 @@ int32_t schHandleLinkBrokenCallback(void *param, SDataBuf *pMsg, int32_t code) {
if (head->isHbParam) {
taosMemoryFree(pMsg->pData);
-
+
SSchHbCallbackParam *hbParam = (SSchHbCallbackParam *)param;
SSchTrans trans = {.pTrans = hbParam->pTrans, .pHandle = NULL};
SCH_ERR_RET(schUpdateHbConnection(&hbParam->nodeEpId, &trans));
@@ -1104,7 +1104,7 @@ int32_t schBuildAndSendMsg(SSchJob *pJob, SSchTask *pTask, SQueryNodeAddr *addr,
#if 1
SSchTrans trans = {.pTrans = pJob->conn.pTrans, .pHandle = SCH_GET_TASK_HANDLE(pTask)};
- schAsyncSendMsg(pJob, pTask, &trans, addr, msgType, msg, msgSize, persistHandle, (rpcCtx.args ? &rpcCtx : NULL));
+ code = schAsyncSendMsg(pJob, pTask, &trans, addr, msgType, msg, msgSize, persistHandle, (rpcCtx.args ? &rpcCtx : NULL));
msg = NULL;
SCH_ERR_JRET(code);
@@ -1114,7 +1114,7 @@ int32_t schBuildAndSendMsg(SSchJob *pJob, SSchTask *pTask, SQueryNodeAddr *addr,
#else
if (TDMT_VND_SUBMIT != msgType) {
SSchTrans trans = {.pTrans = pJob->conn.pTrans, .pHandle = SCH_GET_TASK_HANDLE(pTask)};
- schAsyncSendMsg(pJob, pTask, &trans, addr, msgType, msg, msgSize, persistHandle, (rpcCtx.args ? &rpcCtx : NULL));
+ code = schAsyncSendMsg(pJob, pTask, &trans, addr, msgType, msg, msgSize, persistHandle, (rpcCtx.args ? &rpcCtx : NULL));
msg = NULL;
SCH_ERR_JRET(code);
@@ -1136,3 +1136,4 @@ _return:
taosMemoryFreeClear(msg);
SCH_RET(code);
}
+// clang-format on
diff --git a/source/libs/stream/inc/streamInc.h b/source/libs/stream/inc/streamInc.h
index 3776cb261f..6e30eeaa86 100644
--- a/source/libs/stream/inc/streamInc.h
+++ b/source/libs/stream/inc/streamInc.h
@@ -32,7 +32,6 @@ typedef struct {
static SStreamGlobalEnv streamEnv;
-int32_t streamExec(SStreamTask* pTask);
int32_t streamPipelineExec(SStreamTask* pTask, int32_t batchNum, bool dispatch);
int32_t streamDispatch(SStreamTask* pTask);
diff --git a/source/libs/stream/src/stream.c b/source/libs/stream/src/stream.c
index 6da7d4fd59..d6e87c2736 100644
--- a/source/libs/stream/src/stream.c
+++ b/source/libs/stream/src/stream.c
@@ -185,7 +185,9 @@ int32_t streamProcessDispatchReq(SStreamTask* pTask, SStreamDispatchReq* pReq, S
tFreeStreamDispatchReq(pReq);
if (exec) {
- streamTryExec(pTask);
+ if (streamTryExec(pTask) < 0) {
+ return -1;
+ }
if (pTask->outputType == TASK_OUTPUT__FIXED_DISPATCH || pTask->outputType == TASK_OUTPUT__SHUFFLE_DISPATCH) {
streamDispatch(pTask);
@@ -221,7 +223,9 @@ int32_t streamProcessDispatchRsp(SStreamTask* pTask, SStreamDispatchRsp* pRsp) {
}
int32_t streamProcessRunReq(SStreamTask* pTask) {
- streamTryExec(pTask);
+ if (streamTryExec(pTask) < 0) {
+ return -1;
+ }
if (pTask->outputType == TASK_OUTPUT__FIXED_DISPATCH || pTask->outputType == TASK_OUTPUT__SHUFFLE_DISPATCH) {
streamDispatch(pTask);
diff --git a/source/libs/stream/src/streamMeta.c b/source/libs/stream/src/streamMeta.c
index 64a9537e6c..5ff700546c 100644
--- a/source/libs/stream/src/streamMeta.c
+++ b/source/libs/stream/src/streamMeta.c
@@ -15,6 +15,7 @@
#include "executor.h"
#include "tstream.h"
+#include "ttimer.h"
SStreamMeta* streamMetaOpen(const char* path, void* ahandle, FTaskExpand expandFunc) {
SStreamMeta* pMeta = taosMemoryCalloc(1, sizeof(SStreamMeta));
@@ -99,16 +100,19 @@ int32_t streamMetaAddSerializedTask(SStreamMeta* pMeta, int64_t startVer, char*
goto FAIL;
}
- taosHashPut(pMeta->pTasks, &pTask->taskId, sizeof(int32_t), &pTask, sizeof(void*));
+ if (taosHashPut(pMeta->pTasks, &pTask->taskId, sizeof(int32_t), &pTask, sizeof(void*)) < 0) {
+ goto FAIL;
+ }
if (tdbTbUpsert(pMeta->pTaskDb, &pTask->taskId, sizeof(int32_t), msg, msgLen, &pMeta->txn) < 0) {
+ taosHashRemove(pMeta->pTasks, &pTask->taskId, sizeof(int32_t));
ASSERT(0);
- return -1;
+ goto FAIL;
}
return 0;
FAIL:
- if (pTask) taosMemoryFree(pTask);
+ if (pTask) tFreeSStreamTask(pTask);
return -1;
}
@@ -158,11 +162,28 @@ int32_t streamMetaRemoveTask(SStreamMeta* pMeta, int32_t taskId) {
SStreamTask* pTask = *ppTask;
taosHashRemove(pMeta->pTasks, &taskId, sizeof(int32_t));
atomic_store_8(&pTask->taskStatus, TASK_STATUS__DROPPING);
+
+ if (tdbTbDelete(pMeta->pTaskDb, &taskId, sizeof(int32_t), &pMeta->txn) < 0) {
+ /*return -1;*/
+ }
+
+ if (pTask->triggerParam != 0) {
+ taosTmrStop(pTask->timer);
+ }
+
+ while (1) {
+ int8_t schedStatus =
+ atomic_val_compare_exchange_8(&pTask->schedStatus, TASK_SCHED_STATUS__INACTIVE, TASK_SCHED_STATUS__DROPPING);
+ if (schedStatus == TASK_SCHED_STATUS__INACTIVE) {
+ tFreeSStreamTask(pTask);
+ break;
+ } else if (schedStatus == TASK_SCHED_STATUS__DROPPING) {
+ break;
+ }
+ taosMsleep(10);
+ }
}
- if (tdbTbDelete(pMeta->pTaskDb, &taskId, sizeof(int32_t), &pMeta->txn) < 0) {
- /*return -1;*/
- }
return 0;
}
diff --git a/source/libs/stream/src/streamQueue.c b/source/libs/stream/src/streamQueue.c
index 6819e5329f..ac10c82587 100644
--- a/source/libs/stream/src/streamQueue.c
+++ b/source/libs/stream/src/streamQueue.c
@@ -13,7 +13,7 @@
* along with this program. If not, see .
*/
-#include "tstream.h"
+#include "streamInc.h"
SStreamQueue* streamQueueOpen() {
SStreamQueue* pQueue = taosMemoryCalloc(1, sizeof(SStreamQueue));
@@ -36,9 +36,12 @@ void streamQueueClose(SStreamQueue* queue) {
while (1) {
void* qItem = streamQueueNextItem(queue);
if (qItem) {
- taosFreeQitem(qItem);
+ streamFreeQitem(qItem);
} else {
- return;
+ break;
}
}
+ taosFreeQall(queue->qall);
+ taosCloseQueue(queue->queue);
+ taosMemoryFree(queue);
}
diff --git a/source/libs/stream/src/streamTask.c b/source/libs/stream/src/streamTask.c
index 638d39e5cc..4009a47c65 100644
--- a/source/libs/stream/src/streamTask.c
+++ b/source/libs/stream/src/streamTask.c
@@ -152,9 +152,18 @@ int32_t tDecodeSStreamTask(SDecoder* pDecoder, SStreamTask* pTask) {
}
void tFreeSStreamTask(SStreamTask* pTask) {
- streamQueueClose(pTask->inputQueue);
- streamQueueClose(pTask->outputQueue);
+ qDebug("free stream task %d", pTask->taskId);
+ if (pTask->inputQueue) streamQueueClose(pTask->inputQueue);
+ if (pTask->outputQueue) streamQueueClose(pTask->outputQueue);
if (pTask->exec.qmsg) taosMemoryFree(pTask->exec.qmsg);
if (pTask->exec.executor) qDestroyTask(pTask->exec.executor);
+ taosArrayDestroyP(pTask->childEpInfo, taosMemoryFree);
+ if (pTask->outputType == TASK_OUTPUT__TABLE) {
+ tDeleteSSchemaWrapper(pTask->tbSink.pSchemaWrapper);
+ taosMemoryFree(pTask->tbSink.pTSchema);
+ }
+ if (pTask->outputType == TASK_OUTPUT__SHUFFLE_DISPATCH) {
+ taosArrayDestroy(pTask->shuffleDispatcher.dbInfo.pVgroupInfos);
+ }
taosMemoryFree(pTask);
}
diff --git a/source/libs/sync/inc/syncInt.h b/source/libs/sync/inc/syncInt.h
index de43c81654..0afc373f2d 100644
--- a/source/libs/sync/inc/syncInt.h
+++ b/source/libs/sync/inc/syncInt.h
@@ -237,7 +237,7 @@ void syncNodeVoteForSelf(SSyncNode* pSyncNode);
bool syncNodeHasSnapshot(SSyncNode* pSyncNode);
void syncNodeMaybeUpdateCommitBySnapshot(SSyncNode* pSyncNode);
-SyncIndex syncNodeGetLastIndex(SSyncNode* pSyncNode);
+SyncIndex syncNodeGetLastIndex(const SSyncNode* pSyncNode);
SyncTerm syncNodeGetLastTerm(SSyncNode* pSyncNode);
int32_t syncNodeGetLastIndexTerm(SSyncNode* pSyncNode, SyncIndex* pLastIndex, SyncTerm* pLastTerm);
diff --git a/source/libs/sync/src/syncCommit.c b/source/libs/sync/src/syncCommit.c
index 3829ea0730..1e68fe346c 100644
--- a/source/libs/sync/src/syncCommit.c
+++ b/source/libs/sync/src/syncCommit.c
@@ -146,23 +146,47 @@ int32_t syncNodeDynamicQuorum(const SSyncNode* pSyncNode) {
int64_t timeNow = taosGetTimestampMs();
for (int i = 0; i < pSyncNode->peersNum; ++i) {
- int64_t peerStartTime = syncIndexMgrGetStartTime(pSyncNode->pNextIndex, &(pSyncNode->peersId)[i]);
- int64_t peerRecvTime = syncIndexMgrGetRecvTime(pSyncNode->pNextIndex, &(pSyncNode->peersId)[i]);
+ int64_t peerStartTime = syncIndexMgrGetStartTime(pSyncNode->pNextIndex, &(pSyncNode->peersId)[i]);
+ int64_t peerRecvTime = syncIndexMgrGetRecvTime(pSyncNode->pNextIndex, &(pSyncNode->peersId)[i]);
+ SyncIndex peerMatchIndex = syncIndexMgrGetIndex(pSyncNode->pMatchIndex, &(pSyncNode->peersId)[i]);
- int64_t recvTimeDiff = syncNodeAbs64(peerRecvTime, timeNow);
- int64_t startTimeDiff = syncNodeAbs64(peerStartTime, pSyncNode->startTime);
+ int64_t recvTimeDiff = TABS(peerRecvTime - timeNow);
+ int64_t startTimeDiff = TABS(peerStartTime - pSyncNode->startTime);
+ int64_t logDiff = TABS(peerMatchIndex - syncNodeGetLastIndex(pSyncNode));
+
+ /*
+ int64_t recvTimeDiff = syncNodeAbs64(peerRecvTime, timeNow);
+ int64_t startTimeDiff = syncNodeAbs64(peerStartTime, pSyncNode->startTime);
+ int64_t logDiff = syncNodeAbs64(peerMatchIndex, syncNodeGetLastIndex(pSyncNode));
+ */
int32_t addQuorum = 0;
if (recvTimeDiff < SYNC_MAX_RECV_TIME_RANGE_MS) {
- addQuorum = 1;
+ if (startTimeDiff < SYNC_MAX_START_TIME_RANGE_MS) {
+ addQuorum = 1;
+ } else {
+ if (logDiff < SYNC_ADD_QUORUM_COUNT) {
+ addQuorum = 1;
+ } else {
+ addQuorum = 0;
+ }
+ }
} else {
addQuorum = 0;
}
- if (startTimeDiff > SYNC_MAX_START_TIME_RANGE_MS) {
- addQuorum = 0;
- }
+ /*
+ if (recvTimeDiff < SYNC_MAX_RECV_TIME_RANGE_MS) {
+ addQuorum = 1;
+ } else {
+ addQuorum = 0;
+ }
+
+ if (startTimeDiff > SYNC_MAX_START_TIME_RANGE_MS) {
+ addQuorum = 0;
+ }
+ */
quorum += addQuorum;
}
diff --git a/source/libs/sync/src/syncMain.c b/source/libs/sync/src/syncMain.c
index a00b59d292..3fe600ecbb 100644
--- a/source/libs/sync/src/syncMain.c
+++ b/source/libs/sync/src/syncMain.c
@@ -2284,7 +2284,7 @@ bool syncNodeHasSnapshot(SSyncNode* pSyncNode) {
// return max(logLastIndex, snapshotLastIndex)
// if no snapshot and log, return -1
-SyncIndex syncNodeGetLastIndex(SSyncNode* pSyncNode) {
+SyncIndex syncNodeGetLastIndex(const SSyncNode* pSyncNode) {
SSnapshot snapshot = {.data = NULL, .lastApplyIndex = -1, .lastApplyTerm = 0, .lastConfigIndex = -1};
if (pSyncNode->pFsm->FpGetSnapshotInfo != NULL) {
pSyncNode->pFsm->FpGetSnapshotInfo(pSyncNode->pFsm, &snapshot);
@@ -2773,11 +2773,27 @@ int32_t syncDoLeaderTransfer(SSyncNode* ths, SRpcMsg* pRpcMsg, SSyncRaftEntry* p
return 0;
}
- if (ths->vgId > 1) {
- syncNodeEventLog(ths, "I am vnode, can not do leader transfer");
+ if (pEntry->term < ths->pRaftStore->currentTerm) {
+ char logBuf[128];
+ snprintf(logBuf, sizeof(logBuf), "little term:%lu, can not do leader transfer", pEntry->term);
+ syncNodeEventLog(ths, logBuf);
return 0;
}
+ if (pEntry->index < syncNodeGetLastIndex(ths)) {
+ char logBuf[128];
+ snprintf(logBuf, sizeof(logBuf), "little index:%ld, can not do leader transfer", pEntry->index);
+ syncNodeEventLog(ths, logBuf);
+ return 0;
+ }
+
+ /*
+ if (ths->vgId > 1) {
+ syncNodeEventLog(ths, "I am vnode, can not do leader transfer");
+ return 0;
+ }
+ */
+
do {
char logBuf[128];
snprintf(logBuf, sizeof(logBuf), "do leader transfer, index:%ld", pEntry->index);
diff --git a/source/libs/tdb/src/db/tdbPCache.c b/source/libs/tdb/src/db/tdbPCache.c
index 22229ea0e8..ab9b21dc3f 100644
--- a/source/libs/tdb/src/db/tdbPCache.c
+++ b/source/libs/tdb/src/db/tdbPCache.c
@@ -199,10 +199,20 @@ static SPage *tdbPCacheFetchImpl(SPCache *pCache, const SPgid *pPgid, TXN *pTxn)
if (pPageH) {
// copy the page content
memcpy(&(pPage->pgid), pPgid, sizeof(*pPgid));
+
+ for (int nLoops = 0;;) {
+ if (pPageH->pPager) break;
+ if (++nLoops > 1000) {
+ sched_yield();
+ nLoops = 0;
+ }
+ }
+
pPage->pLruNext = NULL;
pPage->pPager = pPageH->pPager;
memcpy(pPage->pData, pPageH->pData, pPage->pageSize);
+ tdbDebug("pcache/pPageH: %p %d %p %p", pPageH, pPageH->pPageHdr - pPageH->pData, pPageH->xCellSize, pPage);
tdbPageInit(pPage, pPageH->pPageHdr - pPageH->pData, pPageH->xCellSize);
pPage->kLen = pPageH->kLen;
pPage->vLen = pPageH->vLen;
diff --git a/source/libs/transport/inc/transComm.h b/source/libs/transport/inc/transComm.h
index 6b52c74271..c6f3066be7 100644
--- a/source/libs/transport/inc/transComm.h
+++ b/source/libs/transport/inc/transComm.h
@@ -98,6 +98,17 @@ typedef void* queue[2];
#define TRANS_RETRY_INTERVAL 15 // retry interval (ms)
#define TRANS_CONN_TIMEOUT 3 // connect timeout (s)
#define TRANS_READ_TIMEOUT 3000 // read timeout (ms)
+#define TRANS_PACKET_LIMIT 1024 * 1024 * 512
+
+#define TRANS_MAGIC_NUM 0x5f375a86
+
+#define TRANS_NOVALID_PACKET(src) ((src) != TRANS_MAGIC_NUM ? 1 : 0)
+
+#define TRANS_PACKET_LIMIT 1024 * 1024 * 512
+
+#define TRANS_MAGIC_NUM 0x5f375a86
+
+#define TRANS_NOVALID_PACKET(src) ((src) != TRANS_MAGIC_NUM ? 1 : 0)
typedef SRpcMsg STransMsg;
typedef SRpcCtx STransCtx;
@@ -151,6 +162,7 @@ typedef struct {
char hasEpSet : 2; // contain epset or not, 0(default): no epset, 1: contain epset
char user[TSDB_UNI_LEN];
+ uint32_t magicNum;
STraceId traceId;
uint64_t ahandle; // ahandle assigned by client
uint32_t code; // del later
@@ -203,6 +215,7 @@ typedef struct SConnBuffer {
int cap;
int left;
int total;
+ int invalid;
} SConnBuffer;
typedef void (*AsyncCB)(uv_async_t* handle);
diff --git a/source/libs/transport/src/thttp.c b/source/libs/transport/src/thttp.c
index 62277a7569..7cfb188ac9 100644
--- a/source/libs/transport/src/thttp.c
+++ b/source/libs/transport/src/thttp.c
@@ -14,15 +14,25 @@
*/
#define _DEFAULT_SOURCE
-#ifdef USE_UV
-#include
-#endif
// clang-format off
+#include
#include "zlib.h"
#include "thttp.h"
#include "taoserror.h"
#include "tlog.h"
+
+#define HTTP_RECV_BUF_SIZE 1024
+typedef struct SHttpClient {
+ uv_connect_t conn;
+ uv_tcp_t tcp;
+ uv_write_t req;
+ uv_buf_t* wbuf;
+ char *rbuf;
+ char* addr;
+ uint16_t port;
+} SHttpClient;
+
static int32_t taosBuildHttpHeader(const char* server, int32_t contLen, char* pHead, int32_t headLen,
EHttpCompFlag flag) {
if (flag == HTTP_FLAT) {
@@ -45,7 +55,7 @@ static int32_t taosBuildHttpHeader(const char* server, int32_t contLen, char* pH
}
}
-int32_t taosCompressHttpRport(char* pSrc, int32_t srcLen) {
+static int32_t taosCompressHttpRport(char* pSrc, int32_t srcLen) {
int32_t code = -1;
int32_t destLen = srcLen;
void* pDest = taosMemoryMalloc(destLen);
@@ -114,84 +124,69 @@ _OVER:
return code;
}
-#ifdef USE_UV
-static void clientConnCb(uv_connect_t* req, int32_t status) {
- if (status < 0) {
+static void destroyHttpClient(SHttpClient* cli) {
+ taosMemoryFree(cli->wbuf);
+ taosMemoryFree(cli->rbuf);
+ taosMemoryFree(cli->addr);
+ taosMemoryFree(cli);
+
+}
+static void clientCloseCb(uv_handle_t* handle) {
+ SHttpClient* cli = handle->data;
+ destroyHttpClient(cli);
+}
+static void clientAllocBuffCb(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) {
+ SHttpClient* cli = handle->data;
+ buf->base = cli->rbuf;
+ buf->len = HTTP_RECV_BUF_SIZE;
+}
+static void clientRecvCb(uv_stream_t* handle, ssize_t nread, const uv_buf_t *buf) {
+ SHttpClient* cli = handle->data;
+ if (nread < 0) {
+ uError("http-report read error:%s", uv_err_name(nread));
+ } else {
+ uInfo("http-report succ to read %d bytes, just ignore it", nread);
+ }
+ uv_close((uv_handle_t*)&cli->tcp, clientCloseCb);
+}
+static void clientSentCb(uv_write_t* req, int32_t status) {
+ SHttpClient* cli = req->data;
+ if (status != 0) {
terrno = TAOS_SYSTEM_ERROR(status);
- uError("connection error %s", uv_strerror(status));
- uv_close((uv_handle_t*)req->handle, NULL);
+ uError("http-report failed to send data %s", uv_strerror(status));
+ } else {
+ uInfo("http-report succ to send data");
+ }
+ uv_read_start((uv_stream_t *)&cli->tcp, clientAllocBuffCb, clientRecvCb);
+}
+static void clientConnCb(uv_connect_t* req, int32_t status) {
+ SHttpClient* cli = req->data;
+ if (status != 0) {
+ terrno = TAOS_SYSTEM_ERROR(status);
+ uError("http-report failed to conn to server, reason:%s, dst:%s:%d", uv_strerror(status), cli->addr, cli->port);
+ uv_close((uv_handle_t*)&cli->tcp, clientCloseCb);
return;
}
- uv_buf_t* wb = req->data;
- assert(wb != NULL);
- uv_write_t write_req;
- uv_write(&write_req, req->handle, wb, 2, NULL);
- uv_close((uv_handle_t*)req->handle, NULL);
+ uv_write(&cli->req, (uv_stream_t*)&cli->tcp, cli->wbuf, 2, clientSentCb);
}
-int32_t taosSendHttpReport(const char* server, uint16_t port, char* pCont, int32_t contLen, EHttpCompFlag flag) {
- uint32_t ipv4 = taosGetIpv4FromFqdn(server);
- if (ipv4 == 0xffffffff) {
- terrno = TAOS_SYSTEM_ERROR(errno);
- uError("failed to get http server:%s ip since %s", server, terrstr());
- return -1;
- }
-
- char ipv4Buf[128] = {0};
- tinet_ntoa(ipv4Buf, ipv4);
-
- struct sockaddr_in dest = {0};
- uv_ip4_addr(ipv4Buf, port, &dest);
-
- uv_tcp_t socket_tcp = {0};
- uv_loop_t* loop = uv_default_loop();
- uv_tcp_init(loop, &socket_tcp);
- uv_connect_t* connect = (uv_connect_t*)taosMemoryMalloc(sizeof(uv_connect_t));
-
- if (flag == HTTP_GZIP) {
- int32_t dstLen = taosCompressHttpRport(pCont, contLen);
- if (dstLen > 0) {
- contLen = dstLen;
- } else {
- flag = HTTP_FLAT;
- }
- }
-
- char header[1024] = {0};
- int32_t headLen = taosBuildHttpHeader(server, contLen, header, sizeof(header), flag);
-
- uv_buf_t wb[2];
- wb[0] = uv_buf_init((char*)header, headLen);
- wb[1] = uv_buf_init((char*)pCont, contLen);
-
- connect->data = wb;
- terrno = 0;
- uv_tcp_connect(connect, &socket_tcp, (const struct sockaddr*)&dest, clientConnCb);
- uv_run(loop, UV_RUN_DEFAULT);
- uv_loop_close(loop);
- taosMemoryFree(connect);
- return terrno;
-}
-
-#else
-int32_t taosSendHttpReport(const char* server, uint16_t port, char* pCont, int32_t contLen, EHttpCompFlag flag) {
- int32_t code = -1;
- TdSocketPtr pSocket = NULL;
-
+static int32_t taosBuildDstAddr(const char* server, uint16_t port, struct sockaddr_in* dest) {
uint32_t ip = taosGetIpv4FromFqdn(server);
if (ip == 0xffffffff) {
terrno = TAOS_SYSTEM_ERROR(errno);
- uError("failed to get http server:%s ip since %s", server, terrstr());
- goto SEND_OVER;
+ uError("http-report failed to get http server:%s ip since %s", server, terrstr());
+ return -1;
}
-
- pSocket = taosOpenTcpClientSocket(ip, port, 0);
- if (pSocket == NULL) {
- terrno = TAOS_SYSTEM_ERROR(errno);
- uError("failed to create http socket to %s:%u since %s", server, port, terrstr());
- goto SEND_OVER;
+ char buf[128] = {0};
+ tinet_ntoa(buf, ip);
+ uv_ip4_addr(buf, port, dest);
+ return 0;
+}
+int32_t taosSendHttpReport(const char* server, uint16_t port, char* pCont, int32_t contLen, EHttpCompFlag flag) {
+ struct sockaddr_in dest = {0};
+ if (taosBuildDstAddr(server, port, &dest) < 0) {
+ return -1;
}
-
if (flag == HTTP_GZIP) {
int32_t dstLen = taosCompressHttpRport(pCont, contLen);
if (dstLen > 0) {
@@ -200,37 +195,38 @@ int32_t taosSendHttpReport(const char* server, uint16_t port, char* pCont, int32
flag = HTTP_FLAT;
}
}
+ terrno = 0;
- char header[1024] = {0};
+ char header[2048] = {0};
int32_t headLen = taosBuildHttpHeader(server, contLen, header, sizeof(header), flag);
- if (taosWriteMsg(pSocket, header, headLen) < 0) {
- terrno = TAOS_SYSTEM_ERROR(errno);
- uError("failed to send http header to %s:%u since %s", server, port, terrstr());
- goto SEND_OVER;
+
+ uv_buf_t* wb = taosMemoryCalloc(2, sizeof(uv_buf_t));
+ wb[0] = uv_buf_init((char*)header, headLen); // stack var
+ wb[1] = uv_buf_init((char*)pCont, contLen); // heap var
+
+ SHttpClient* cli = taosMemoryCalloc(1, sizeof(SHttpClient));
+ cli->conn.data = cli;
+ cli->tcp.data = cli;
+ cli->req.data = cli;
+ cli->wbuf = wb;
+ cli->rbuf = taosMemoryCalloc(1, HTTP_RECV_BUF_SIZE);
+ cli->addr = tstrdup(server);
+ cli->port = port;
+
+ uv_loop_t* loop = uv_default_loop();
+ uv_tcp_init(loop, &cli->tcp);
+ // set up timeout to avoid stuck;
+ int32_t fd = taosCreateSocketWithTimeout(5);
+ uv_tcp_open((uv_tcp_t*)&cli->tcp, fd);
+
+ int32_t ret = uv_tcp_connect(&cli->conn, &cli->tcp, (const struct sockaddr*)&dest, clientConnCb);
+ if (ret != 0) {
+ uError("http-report failed to connect to server, reason:%s, dst:%s:%d", uv_strerror(ret), cli->addr, cli->port);
+ destroyHttpClient(cli);
}
- if (taosWriteMsg(pSocket, (void*)pCont, contLen) < 0) {
- terrno = TAOS_SYSTEM_ERROR(errno);
- uError("failed to send http content to %s:%u since %s", server, port, terrstr());
- goto SEND_OVER;
- }
-
- // read something to avoid nginx error 499
- if (taosWriteMsg(pSocket, header, 10) < 0) {
- terrno = TAOS_SYSTEM_ERROR(errno);
- uError("failed to receive response from %s:%u since %s", server, port, terrstr());
- goto SEND_OVER;
- }
-
- code = 0;
-
-SEND_OVER:
- if (pSocket != NULL) {
- taosCloseSocket(&pSocket);
- }
-
- return code;
+ uv_run(loop, UV_RUN_DEFAULT);
+ uv_loop_close(loop);
+ return terrno;
}
-
// clang-format on
-#endif
diff --git a/source/libs/transport/src/transCli.c b/source/libs/transport/src/transCli.c
index add007e14d..7052b0b915 100644
--- a/source/libs/transport/src/transCli.c
+++ b/source/libs/transport/src/transCli.c
@@ -318,10 +318,17 @@ void cliHandleResp(SCliConn* conn) {
}
STransMsgHead* pHead = NULL;
- transDumpFromBuffer(&conn->readBuf, (char**)&pHead);
+ if (transDumpFromBuffer(&conn->readBuf, (char**)&pHead) <= 0) {
+ tDebug("%s conn %p recv invalid packet ", CONN_GET_INST_LABEL(conn), conn);
+ return;
+ }
pHead->code = htonl(pHead->code);
pHead->msgLen = htonl(pHead->msgLen);
+ if (cliRecvReleaseReq(conn, pHead)) {
+ return;
+ }
+
STransMsg transMsg = {0};
transMsg.contLen = transContLenFromMsg(pHead->msgLen);
transMsg.pCont = transContFromHead((char*)pHead);
@@ -333,10 +340,6 @@ void cliHandleResp(SCliConn* conn) {
SCliMsg* pMsg = NULL;
STransConnCtx* pCtx = NULL;
- if (cliRecvReleaseReq(conn, pHead)) {
- return;
- }
-
if (CONN_NO_PERSIST_BY_APP(conn)) {
pMsg = transQueuePop(&conn->cliMsgs);
@@ -598,7 +601,12 @@ static void cliRecvCb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) {
pBuf->len += nread;
while (transReadComplete(pBuf)) {
tTrace("%s conn %p read complete", CONN_GET_INST_LABEL(conn), conn);
- cliHandleResp(conn);
+ if (pBuf->invalid) {
+ cliHandleExcept(conn);
+ break;
+ } else {
+ cliHandleResp(conn);
+ }
}
return;
}
@@ -759,6 +767,7 @@ void cliSend(SCliConn* pConn) {
pHead->release = REQUEST_RELEASE_HANDLE(pCliMsg) ? 1 : 0;
memcpy(pHead->user, pTransInst->user, strlen(pTransInst->user));
pHead->traceId = pMsg->info.traceId;
+ pHead->magicNum = htonl(TRANS_MAGIC_NUM);
uv_buf_t wb = uv_buf_init((char*)pHead, msgLen);
@@ -1423,7 +1432,7 @@ int transSendRequest(void* shandle, const SEpSet* pEpSet, STransMsg* pReq, STran
if (pThrd == NULL && valid == false) {
transFreeMsg(pReq->pCont);
transReleaseExHandle(transGetInstMgt(), (int64_t)shandle);
- return -1;
+ return TSDB_CODE_RPC_BROKEN_LINK;
}
TRACE_SET_MSGID(&pReq->info.traceId, tGenIdPI64());
@@ -1468,7 +1477,7 @@ int transSendRecv(void* shandle, const SEpSet* pEpSet, STransMsg* pReq, STransMs
if (pThrd == NULL && valid == false) {
transFreeMsg(pReq->pCont);
transReleaseExHandle(transGetInstMgt(), (int64_t)shandle);
- return -1;
+ return TSDB_CODE_RPC_BROKEN_LINK;
}
tsem_t* sem = taosMemoryCalloc(1, sizeof(tsem_t));
diff --git a/source/libs/transport/src/transComm.c b/source/libs/transport/src/transComm.c
index 4272ec0b1c..a4d679b281 100644
--- a/source/libs/transport/src/transComm.c
+++ b/source/libs/transport/src/transComm.c
@@ -91,6 +91,7 @@ int transInitBuffer(SConnBuffer* buf) {
buf->left = -1;
buf->len = 0;
buf->total = 0;
+ buf->invalid = 0;
return 0;
}
int transDestroyBuffer(SConnBuffer* p) {
@@ -108,19 +109,25 @@ int transClearBuffer(SConnBuffer* buf) {
p->left = -1;
p->len = 0;
p->total = 0;
+ p->invalid = 0;
return 0;
}
int transDumpFromBuffer(SConnBuffer* connBuf, char** buf) {
+ static const int HEADSIZE = sizeof(STransMsgHead);
+
SConnBuffer* p = connBuf;
if (p->left != 0) {
return -1;
}
int total = connBuf->total;
- *buf = taosMemoryCalloc(1, total);
- memcpy(*buf, p->buf, total);
-
- transResetBuffer(connBuf);
+ if (total >= HEADSIZE && !p->invalid) {
+ *buf = taosMemoryCalloc(1, total);
+ memcpy(*buf, p->buf, total);
+ transResetBuffer(connBuf);
+ } else {
+ total = -1;
+ }
return total;
}
@@ -173,6 +180,7 @@ bool transReadComplete(SConnBuffer* connBuf) {
memcpy((char*)&head, connBuf->buf, sizeof(head));
int32_t msgLen = (int32_t)htonl(head.msgLen);
p->total = msgLen;
+ p->invalid = TRANS_NOVALID_PACKET(htonl(head.magicNum));
}
if (p->total >= p->len) {
p->left = p->total - p->len;
@@ -180,7 +188,7 @@ bool transReadComplete(SConnBuffer* connBuf) {
p->left = 0;
}
}
- return p->left == 0 ? true : false;
+ return (p->left == 0 || p->invalid) ? true : false;
}
int transSetConnOption(uv_tcp_t* stream) {
diff --git a/source/libs/transport/src/transSvr.c b/source/libs/transport/src/transSvr.c
index 3512b27bf8..447db76136 100644
--- a/source/libs/transport/src/transSvr.c
+++ b/source/libs/transport/src/transSvr.c
@@ -183,17 +183,25 @@ static void uvHandleActivityTimeout(uv_timer_t* handle) {
tDebug("%p timeout since no activity", conn);
}
-static void uvHandleReq(SSvrConn* pConn) {
- STransMsgHead* msg = NULL;
- int msgLen = 0;
+static bool uvHandleReq(SSvrConn* pConn) {
+ STrans* pTransInst = pConn->pTransInst;
- msgLen = transDumpFromBuffer(&pConn->readBuf, (char**)&msg);
+ STransMsgHead* msg = NULL;
+ int msgLen = transDumpFromBuffer(&pConn->readBuf, (char**)&msg);
+ if (msgLen <= 0) {
+ tError("%s conn %p read invalid packet", transLabel(pTransInst), pConn);
+ return false;
+ }
STransMsgHead* pHead = (STransMsgHead*)msg;
pHead->code = htonl(pHead->code);
pHead->msgLen = htonl(pHead->msgLen);
memcpy(pConn->user, pHead->user, strlen(pHead->user));
+ if (uvRecvReleaseReq(pConn, pHead)) {
+ return true;
+ }
+
// TODO(dengyihao): time-consuming task throwed into BG Thread
// uv_work_t* wreq = taosMemoryMalloc(sizeof(uv_work_t));
// wreq->data = pConn;
@@ -201,10 +209,6 @@ static void uvHandleReq(SSvrConn* pConn) {
// transRefSrvHandle(pConn);
// uv_queue_work(((SWorkThrd*)pConn->hostThrd)->loop, wreq, uvWorkDoTask, uvWorkAfterTask);
- if (uvRecvReleaseReq(pConn, pHead)) {
- return;
- }
-
STransMsg transMsg;
memset(&transMsg, 0, sizeof(transMsg));
transMsg.contLen = transContLenFromMsg(pHead->msgLen);
@@ -220,7 +224,6 @@ static void uvHandleReq(SSvrConn* pConn) {
tDebug("conn %p acquired by server app", pConn);
}
}
- STrans* pTransInst = pConn->pTransInst;
STraceId* trace = &pHead->traceId;
if (pConn->status == ConnNormal && pHead->noResp == 0) {
transRefSrvHandle(pConn);
@@ -258,21 +261,32 @@ static void uvHandleReq(SSvrConn* pConn) {
transReleaseExHandle(transGetRefMgt(), pConn->refId);
(*pTransInst->cfp)(pTransInst->parent, &transMsg, NULL);
+ return true;
}
void uvOnRecvCb(uv_stream_t* cli, ssize_t nread, const uv_buf_t* buf) {
- // opt
- SSvrConn* conn = cli->data;
+ SSvrConn* conn = cli->data;
+ STrans* pTransInst = conn->pTransInst;
+
SConnBuffer* pBuf = &conn->readBuf;
- STrans* pTransInst = conn->pTransInst;
if (nread > 0) {
pBuf->len += nread;
tTrace("%s conn %p total read:%d, current read:%d", transLabel(pTransInst), conn, pBuf->len, (int)nread);
- while (transReadComplete(pBuf)) {
- tTrace("%s conn %p alread read complete packet", transLabel(pTransInst), conn);
- uvHandleReq(conn);
+ if (pBuf->len <= TRANS_PACKET_LIMIT) {
+ while (transReadComplete(pBuf)) {
+ tTrace("%s conn %p alread read complete packet", transLabel(pTransInst), conn);
+ if (true == pBuf->invalid || false == uvHandleReq(conn)) {
+ tError("%s conn %p read invalid packet", transLabel(pTransInst), conn);
+ destroyConn(conn, true);
+ return;
+ }
+ }
+ return;
+ } else {
+ tError("%s conn %p read invalid packet, exceed limit", transLabel(pTransInst), conn);
+ destroyConn(conn, true);
+ return;
}
- return;
}
if (nread == 0) {
return;
@@ -364,6 +378,7 @@ static void uvPrepareSendData(SSvrMsg* smsg, uv_buf_t* wb) {
pHead->ahandle = (uint64_t)pMsg->info.ahandle;
pHead->traceId = pMsg->info.traceId;
pHead->hasEpSet = pMsg->info.hasEpSet;
+ pHead->magicNum = htonl(TRANS_MAGIC_NUM);
if (pConn->status == ConnNormal) {
pHead->msgType = (0 == pMsg->msgType ? pConn->inType + 1 : pMsg->msgType);
@@ -859,6 +874,7 @@ static int reallocConnRef(SSvrConn* conn) {
}
static void uvDestroyConn(uv_handle_t* handle) {
SSvrConn* conn = handle->data;
+
if (conn == NULL) {
return;
}
@@ -874,9 +890,8 @@ static void uvDestroyConn(uv_handle_t* handle) {
SSvrMsg* msg = transQueueGet(&conn->srvMsgs, i);
destroySmsg(msg);
}
-
- transReqQueueClear(&conn->wreqQueue);
transQueueDestroy(&conn->srvMsgs);
+ transReqQueueClear(&conn->wreqQueue);
QUEUE_REMOVE(&conn->queue);
taosMemoryFree(conn->pTcp);
diff --git a/source/util/src/tconfig.c b/source/util/src/tconfig.c
index fdb397561d..2a28ec66d2 100644
--- a/source/util/src/tconfig.c
+++ b/source/util/src/tconfig.c
@@ -33,6 +33,8 @@ int32_t cfgLoadFromEnvCmd(SConfig *pConfig, const char **envCmd);
int32_t cfgLoadFromApollUrl(SConfig *pConfig, const char *url);
int32_t cfgSetItem(SConfig *pConfig, const char *name, const char *value, ECfgSrcType stype);
+extern char **environ;
+
SConfig *cfgInit() {
SConfig *pCfg = taosMemoryCalloc(1, sizeof(SConfig));
if (pCfg == NULL) {
@@ -627,24 +629,17 @@ void cfgDumpCfg(SConfig *pCfg, bool tsc, bool dump) {
}
int32_t cfgLoadFromEnvVar(SConfig *pConfig) {
- char *line = NULL, *name, *value, *value2, *value3;
+ char line[1024], *name, *value, *value2, *value3;
int32_t olen, vlen, vlen2, vlen3;
int32_t code = 0;
- ssize_t _bytes = 0;
- TdCmdPtr pCmd = taosOpenCmd("set");
- if (pCmd == NULL) {
- terrno = TAOS_SYSTEM_ERROR(errno);
- return -1;
- }
- while (!taosEOFCmd(pCmd)) {
+ char **pEnv = environ;
+ line[1023] = 0;
+ while(*pEnv != NULL) {
name = value = value2 = value3 = NULL;
olen = vlen = vlen2 = vlen3 = 0;
- _bytes = taosGetLineCmd(pCmd, &line);
- if (_bytes < 0) {
- break;
- }
- if(line[_bytes - 1] == '\n') line[_bytes - 1] = 0;
+ strncpy(line, *pEnv, sizeof(line)-1);
+ pEnv++;
taosEnvToCfg(line, line);
paGetToken(line, &name, &olen);
@@ -671,9 +666,6 @@ int32_t cfgLoadFromEnvVar(SConfig *pConfig) {
}
}
- taosCloseCmd(&pCmd);
- if (line != NULL) taosMemoryFreeClear(line);
-
uInfo("load from env variables cfg success");
return 0;
}
@@ -1040,34 +1032,25 @@ int32_t cfgGetApollUrl(const char **envCmd, const char *envFile, char* apolloUrl
index++;
}
- char *line = NULL;
- ssize_t _bytes = 0;
- TdCmdPtr pCmd = taosOpenCmd("set");
- if (pCmd != NULL) {
- while (!taosEOFCmd(pCmd)) {
- _bytes = taosGetLineCmd(pCmd, &line);
- if (_bytes < 0) {
- break;
- }
- if(line[_bytes - 1] == '\n') line[_bytes - 1] = 0;
- if (strncmp(line, "TAOS_APOLLO_URL", 14) == 0) {
- char *p = strchr(line, '=');
- if (p != NULL) {
+ char line[1024];
+ char **pEnv = environ;
+ line[1023] = 0;
+ while(*pEnv != NULL) {
+ strncpy(line, *pEnv, sizeof(line)-1);
+ pEnv++;
+ if (strncmp(line, "TAOS_APOLLO_URL", 14) == 0) {
+ char *p = strchr(line, '=');
+ if (p != NULL) {
+ p++;
+ if (*p == '\'') {
p++;
- if (*p == '\'') {
- p++;
- p[strlen(p)-1] = '\0';
- }
- memcpy(apolloUrl, p, TMIN(strlen(p)+1,PATH_MAX));
- uInfo("get apollo url from env variables success, apolloUrl=%s",apolloUrl);
- taosCloseCmd(&pCmd);
- if (line != NULL) taosMemoryFreeClear(line);
- return 0;
+ p[strlen(p)-1] = '\0';
}
+ memcpy(apolloUrl, p, TMIN(strlen(p)+1,PATH_MAX));
+ uInfo("get apollo url from env variables success, apolloUrl=%s",apolloUrl);
+ return 0;
}
}
- taosCloseCmd(&pCmd);
- if (line != NULL) taosMemoryFreeClear(line);
}
const char *filepath = ".env";
@@ -1083,10 +1066,11 @@ int32_t cfgGetApollUrl(const char **envCmd, const char *envFile, char* apolloUrl
return 0;
}
}
+ int64_t _bytes;
TdFilePtr pFile = taosOpenFile(filepath, TD_FILE_READ | TD_FILE_STREAM);
if (pFile != NULL) {
while (!taosEOFFile(pFile)) {
- _bytes = taosGetLineFile(pFile, &line);
+ _bytes = taosGetsFile(pFile, sizeof(line) - 1, line);
if (_bytes <= 0) {
break;
}
@@ -1101,14 +1085,12 @@ int32_t cfgGetApollUrl(const char **envCmd, const char *envFile, char* apolloUrl
}
memcpy(apolloUrl, p, TMIN(strlen(p)+1,PATH_MAX));
taosCloseFile(&pFile);
- if (line != NULL) taosMemoryFreeClear(line);
uInfo("get apollo url from env file success");
return 0;
}
}
}
taosCloseFile(&pFile);
- if (line != NULL) taosMemoryFreeClear(line);
}
uInfo("fail get apollo url from cmd env file");
diff --git a/source/util/src/terror.c b/source/util/src/terror.c
index 7b06967940..662a3f0c88 100644
--- a/source/util/src/terror.c
+++ b/source/util/src/terror.c
@@ -293,6 +293,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_MND_CGROUP_USED, "Consumer group being
TAOS_DEFINE_ERROR(TSDB_CODE_MND_STREAM_ALREADY_EXIST, "Stream already exists")
TAOS_DEFINE_ERROR(TSDB_CODE_MND_STREAM_NOT_EXIST, "Stream not exist")
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_STREAM_OPTION, "Invalid stream option")
+TAOS_DEFINE_ERROR(TSDB_CODE_MND_STREAM_MUST_BE_DELETED, "Stream must be dropped first")
// mnode-sma
TAOS_DEFINE_ERROR(TSDB_CODE_MND_SMA_ALREADY_EXIST, "SMA already exists")
@@ -616,6 +617,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_RSMA_FILE_CORRUPTED, "Rsma file corrupted
TAOS_DEFINE_ERROR(TSDB_CODE_RSMA_REMOVE_EXISTS, "Rsma remove exists")
TAOS_DEFINE_ERROR(TSDB_CODE_RSMA_FETCH_MSG_MSSED_UP, "Rsma fetch msg is messed up")
TAOS_DEFINE_ERROR(TSDB_CODE_RSMA_EMPTY_INFO, "Rsma info is empty")
+TAOS_DEFINE_ERROR(TSDB_CODE_RSMA_INVALID_SCHEMA, "Rsma invalid schema")
//index
TAOS_DEFINE_ERROR(TSDB_CODE_INDEX_REBUILDING, "Index is rebuilding")
diff --git a/source/util/src/tqueue.c b/source/util/src/tqueue.c
index 50beba8a9b..eb70002680 100644
--- a/source/util/src/tqueue.c
+++ b/source/util/src/tqueue.c
@@ -298,7 +298,8 @@ int32_t taosGetQitem(STaosQall *qall, void **ppItem) {
return num;
}
-void taosResetQitems(STaosQall *qall) { qall->current = qall->start; }
+void taosResetQitems(STaosQall *qall) { qall->current = qall->start; }
+int32_t taosQallItemSize(STaosQall *qall) { return qall->numOfItems; }
STaosQset *taosOpenQset() {
STaosQset *qset = taosMemoryCalloc(sizeof(STaosQset), 1);
diff --git a/source/util/src/trbtree.c b/source/util/src/trbtree.c
new file mode 100644
index 0000000000..0970485dad
--- /dev/null
+++ b/source/util/src/trbtree.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc.
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#include "os.h"
+
+typedef int32_t (*tRBTreeCmprFn)(void *, void *);
+
+typedef struct SRBTree SRBTree;
+typedef struct SRBTreeNode SRBTreeNode;
+typedef struct SRBTreeIter SRBTreeIter;
+
+struct SRBTreeNode {
+ enum { RED, BLACK } color;
+ SRBTreeNode *parent;
+ SRBTreeNode *left;
+ SRBTreeNode *right;
+ uint8_t payload[];
+};
+
+struct SRBTree {
+ tRBTreeCmprFn cmprFn;
+ SRBTreeNode *root;
+};
+
+struct SRBTreeIter {
+ SRBTree *pTree;
+};
+
+#define RBTREE_NODE_COLOR(N) ((N) ? (N)->color : BLACK)
+
+// APIs ================================================
+static void tRBTreeRotateLeft(SRBTree *pTree, SRBTreeNode *pNode) {
+ SRBTreeNode *right = pNode->right;
+
+ pNode->right = right->left;
+ if (pNode->right) {
+ pNode->right->parent = pNode;
+ }
+
+ right->parent = pNode->parent;
+ if (pNode->parent == NULL) {
+ pTree->root = right;
+ } else if (pNode == pNode->parent->left) {
+ pNode->parent->left = right;
+ } else {
+ pNode->parent->right = right;
+ }
+
+ right->left = pNode;
+ pNode->parent = right;
+}
+
+static void tRBTreeRotateRight(SRBTree *pTree, SRBTreeNode *pNode) {
+ SRBTreeNode *left = pNode->left;
+
+ pNode->left = left->right;
+ if (pNode->left) {
+ pNode->left->parent = pNode;
+ }
+
+ left->parent = pNode->parent;
+ if (pNode->parent == NULL) {
+ pTree->root = left;
+ } else if (pNode == pNode->parent->left) {
+ pNode->parent->left = left;
+ } else {
+ pNode->parent->right = left;
+ }
+
+ left->right = pNode;
+ pNode->parent = left;
+}
+
+#define tRBTreeCreate(compare) \
+ (SRBTree) { .cmprFn = (compare), .root = NULL }
+
+SRBTreeNode *tRBTreePut(SRBTree *pTree, SRBTreeNode *pNew) {
+ pNew->left = NULL;
+ pNew->right = NULL;
+ pNew->color = RED;
+
+ // insert
+ if (pTree->root == NULL) {
+ pNew->parent = NULL;
+ pTree->root = pNew;
+ } else {
+ SRBTreeNode *pNode = pTree->root;
+ while (true) {
+ ASSERT(pNode);
+
+ int32_t c = pTree->cmprFn(pNew->payload, pNode->payload);
+ if (c < 0) {
+ if (pNode->left) {
+ pNode = pNode->left;
+ } else {
+ pNew->parent = pNode;
+ pNode->left = pNew;
+ break;
+ }
+ } else if (c > 0) {
+ if (pNode->right) {
+ pNode = pNode->right;
+ } else {
+ pNew->parent = pNode;
+ pNode->right = pNew;
+ break;
+ }
+ } else {
+ return NULL;
+ }
+ }
+ }
+
+ // fix
+ SRBTreeNode *pNode = pNew;
+ while (pNode->parent && pNode->parent->color == RED) {
+ SRBTreeNode *p = pNode->parent;
+ SRBTreeNode *g = p->parent;
+
+ if (p == g->left) {
+ SRBTreeNode *u = g->right;
+
+ if (RBTREE_NODE_COLOR(u) == RED) {
+ p->color = BLACK;
+ u->color = BLACK;
+ g->color = RED;
+ pNode = g;
+ } else {
+ if (pNode == p->right) {
+ pNode = p;
+ tRBTreeRotateLeft(pTree, pNode);
+ }
+ pNode->parent->color = BLACK;
+ pNode->parent->parent->color = RED;
+ tRBTreeRotateRight(pTree, pNode->parent->parent);
+ }
+ } else {
+ SRBTreeNode *u = g->left;
+
+ if (RBTREE_NODE_COLOR(u) == RED) {
+ p->color = BLACK;
+ u->color = BLACK;
+ g->color = RED;
+ } else {
+ if (pNode == p->left) {
+ pNode = p;
+ tRBTreeRotateRight(pTree, pNode);
+ }
+ pNode->parent->color = BLACK;
+ pNode->parent->parent->color = RED;
+ tRBTreeRotateLeft(pTree, pNode->parent->parent);
+ }
+ }
+ }
+
+ pTree->root->color = BLACK;
+ return pNew;
+}
+
+SRBTreeNode *tRBTreeDrop(SRBTree *pTree, void *pKey) {
+ SRBTreeNode *pNode = pTree->root;
+
+ while (pNode) {
+ int32_t c = pTree->cmprFn(pKey, pNode->payload);
+
+ if (c < 0) {
+ pNode = pNode->left;
+ } else if (c > 0) {
+ pNode = pNode->right;
+ } else {
+ break;
+ }
+ }
+
+ if (pNode) {
+ // TODO
+ }
+
+ return pNode;
+}
+
+SRBTreeNode *tRBTreeGet(SRBTree *pTree, void *pKey) {
+ SRBTreeNode *pNode = pTree->root;
+
+ while (pNode) {
+ int32_t c = pTree->cmprFn(pKey, pNode->payload);
+
+ if (c < 0) {
+ pNode = pNode->left;
+ } else if (c > 0) {
+ pNode = pNode->right;
+ } else {
+ break;
+ }
+ }
+
+ return pNode;
+}
diff --git a/tests/script/tsim/alter/cached_schema_after_alter.sim b/tests/script/tsim/alter/cached_schema_after_alter.sim
index bd2b1d272c..30b879b612 100644
--- a/tests/script/tsim/alter/cached_schema_after_alter.sim
+++ b/tests/script/tsim/alter/cached_schema_after_alter.sim
@@ -14,7 +14,7 @@ print ========== cached_schema_after_alter.sim
sql drop database $db -x step1
step1:
-sql create database $db
+sql create database $db
print ====== create tables
sql use $db
@@ -32,10 +32,10 @@ if $rows != 1 then
endi
if $data01 != 1 then
return -1
-endi
+endi
if $data02 != 1 then
return -1
-endi
+endi
sql select * from $tb2
if $rows != 1 then
@@ -43,10 +43,10 @@ if $rows != 1 then
endi
if $data01 != 1 then
return -1
-endi
+endi
if $data02 != 1 then
return -1
-endi
+endi
print ================== restart server to commit data into disk
system sh/exec.sh -n dnode1 -s stop -x SIGINT
@@ -61,10 +61,10 @@ if $rows != 1 then
endi
if $data01 != 1 then
return -1
-endi
+endi
if $data02 != 1 then
return -1
-endi
+endi
sql select * from $tb2
print select * from $tb2 ==> $data00 $data01 $data02
@@ -73,10 +73,10 @@ if $rows != 1 then
endi
if $data01 != 1 then
return -1
-endi
+endi
if $data02 != 1 then
return -1
-endi
+endi
$ts = $ts0 + $delta
sql insert into $tb2 values ( $ts , 2, 2)
@@ -86,16 +86,16 @@ if $rows != 2 then
endi
if $data01 != 1 then
return -1
-endi
+endi
if $data02 != 1 then
return -1
-endi
+endi
if $data11 != 2 then
return -1
-endi
+endi
if $data12 != 2 then
return -1
-endi
+endi
sql select * from $tb2 order by ts asc
if $rows != 2 then
@@ -103,15 +103,15 @@ if $rows != 2 then
endi
if $data01 != 1 then
return -1
-endi
+endi
if $data02 != 1 then
return -1
-endi
+endi
if $data11 != 2 then
return -1
-endi
+endi
if $data12 != 2 then
return -1
-endi
+endi
-system sh/exec.sh -n dnode1 -s stop -x SIGINT
\ No newline at end of file
+system sh/exec.sh -n dnode1 -s stop -x SIGINT
diff --git a/tests/script/tsim/alter/dnode.sim b/tests/script/tsim/alter/dnode.sim
index d773c1f8a9..be3c385d45 100644
--- a/tests/script/tsim/alter/dnode.sim
+++ b/tests/script/tsim/alter/dnode.sim
@@ -3,7 +3,7 @@ system sh/deploy.sh -n dnode1 -i 1
system sh/exec.sh -n dnode1 -s start
sql connect
-print ======== step1
+print ======== step1
sql alter dnode 1 'resetlog'
sql alter dnode 1 'monitor' '1'
sql alter dnode 1 'monitor' '0'
@@ -65,4 +65,4 @@ sql alter dnode 1 balance "vnode:2-dnode:1" -x step4
step4:
print ======= over
-system sh/exec.sh -n dnode1 -s stop -x SIGINT
\ No newline at end of file
+system sh/exec.sh -n dnode1 -s stop -x SIGINT
diff --git a/tests/script/tsim/alter/table.sim b/tests/script/tsim/alter/table.sim
index 48ab7ddab0..dccfc7f5d6 100644
--- a/tests/script/tsim/alter/table.sim
+++ b/tests/script/tsim/alter/table.sim
@@ -3,7 +3,7 @@ system sh/deploy.sh -n dnode1 -i 1
system sh/exec.sh -n dnode1 -s start
sql connect
-print ======== step1
+print ======== step1
sql create database d1
sql use d1
sql create table tb (ts timestamp, a int)
diff --git a/tests/script/tsim/bnode/basic1.sim b/tests/script/tsim/bnode/basic1.sim
index 003d0ceb3d..0a20001636 100644
--- a/tests/script/tsim/bnode/basic1.sim
+++ b/tests/script/tsim/bnode/basic1.sim
@@ -7,24 +7,24 @@ sql connect
print =============== select * from information_schema.ins_dnodes
sql select * from information_schema.ins_dnodes;
-if $rows != 1 then
+if $rows != 1 then
return -1
endi
-if $data00 != 1 then
+if $data00 != 1 then
return -1
endi
sql select * from information_schema.ins_mnodes;
-if $rows != 1 then
+if $rows != 1 then
return -1
endi
-if $data00 != 1 then
+if $data00 != 1 then
return -1
endi
-if $data02 != leader then
+if $data02 != leader then
return -1
endi
@@ -33,62 +33,62 @@ sql create dnode $hostname port 7200
sleep 2000
sql select * from information_schema.ins_dnodes;
-if $rows != 2 then
+if $rows != 2 then
return -1
endi
-if $data00 != 1 then
+if $data00 != 1 then
return -1
endi
-if $data10 != 2 then
+if $data10 != 2 then
return -1
endi
print $data02
-if $data02 != 0 then
+if $data02 != 0 then
return -1
endi
-if $data12 != 0 then
+if $data12 != 0 then
return -1
endi
-if $data04 != ready then
+if $data04 != ready then
return -1
endi
-if $data14 != ready then
+if $data14 != ready then
return -1
endi
sql select * from information_schema.ins_mnodes;
-if $rows != 1 then
+if $rows != 1 then
return -1
endi
-if $data00 != 1 then
+if $data00 != 1 then
return -1
endi
-if $data02 != leader then
+if $data02 != leader then
return -1
endi
#print =============== create drop bnode 1
#sql create bnode on dnode 1
#sql show bnodes
-#if $rows != 1 then
+#if $rows != 1 then
# return -1
#endi
-#if $data00 != 1 then
+#if $data00 != 1 then
# return -1
#endi
#sql_error create bnode on dnode 1
#
#sql drop bnode on dnode 1
#sql show bnodes
-#if $rows != 0 then
+#if $rows != 0 then
# return -1
#endi
#sql_error drop bnode on dnode 1
@@ -96,17 +96,17 @@ endi
#print =============== create drop bnode 2
#sql create bnode on dnode 2
#sql show bnodes
-#if $rows != 1 then
+#if $rows != 1 then
# return -1
#endi
-#if $data00 != 2 then
+#if $data00 != 2 then
# return -1
#endi
#sql_error create bnode on dnode 2
#
#sql drop bnode on dnode 2
#sql show bnodes
-#if $rows != 0 then
+#if $rows != 0 then
# return -1
#endi
#sql_error drop bnode on dnode 2
@@ -115,7 +115,7 @@ endi
#sql create bnode on dnode 1
#sql create bnode on dnode 2
#sql show bnodes
-#if $rows != 2 then
+#if $rows != 2 then
# return -1
#endi
@@ -127,7 +127,7 @@ endi
#
#sleep 2000
#sql show bnodes
-#if $rows != 2 then
+#if $rows != 2 then
# return -1
#endi
diff --git a/tests/script/tsim/compress/commitlog.sim b/tests/script/tsim/compress/commitlog.sim
index bc9c231a9e..38899b95ba 100644
--- a/tests/script/tsim/compress/commitlog.sim
+++ b/tests/script/tsim/compress/commitlog.sim
@@ -25,7 +25,7 @@ while $count < $N
endw
sql select * from $tb
-if $rows != $N then
+if $rows != $N then
return -1
endi
@@ -46,7 +46,7 @@ while $count < $N
endw
sql select * from $tb
-if $rows != $N then
+if $rows != $N then
return -1
endi
@@ -67,7 +67,7 @@ while $count < $N
endw
sql select * from $tb
-if $rows != $N then
+if $rows != $N then
return -1
endi
@@ -83,7 +83,7 @@ $tb = $tbPrefix . $i
sql use $db
sql select * from $tb
print select * from $tb ==> $rows points
-if $rows != $N then
+if $rows != $N then
return -1
endi
@@ -93,18 +93,18 @@ $tb = $tbPrefix . $i
sql use $db
sql select * from $tb
print select * from $tb ==> $rows points
-if $rows != $N then
+if $rows != $N then
return -1
endi
-
+
$i = 2
$db = $dbPrefix . $i
$tb = $tbPrefix . $i
sql use $db
sql select * from $tb
print select * from $tb ==> $rows points
-if $rows != $N then
+if $rows != $N then
return -1
-endi
-
-system sh/exec.sh -n dnode1 -s stop -x SIGINT
\ No newline at end of file
+endi
+
+system sh/exec.sh -n dnode1 -s stop -x SIGINT
diff --git a/tests/script/tsim/compress/compress.sim b/tests/script/tsim/compress/compress.sim
index 766f97450c..4752f1ba50 100644
--- a/tests/script/tsim/compress/compress.sim
+++ b/tests/script/tsim/compress/compress.sim
@@ -25,7 +25,7 @@ while $count < $N
endw
sql select * from $tb
-if $rows != $N then
+if $rows != $N then
return -1
endi
@@ -47,7 +47,7 @@ while $count < $N
endw
sql select * from $tb
-if $rows != $N then
+if $rows != $N then
return -1
endi
@@ -69,7 +69,7 @@ while $count < $N
endw
sql select * from $tb
-if $rows != $N then
+if $rows != $N then
return -1
endi
@@ -85,7 +85,7 @@ $tb = $tbPrefix . $i
sql use $db
sql select * from $tb
print select * from $tb ==> $rows points
-if $rows != $N then
+if $rows != $N then
return -1
endi
@@ -95,18 +95,18 @@ $tb = $tbPrefix . $i
sql use $db
sql select * from $tb
print select * from $tb ==> $rows points
-if $rows != $N then
+if $rows != $N then
return -1
endi
-
+
$i = 2
$db = $dbPrefix . $i
$tb = $tbPrefix . $i
sql use $db
sql select * from $tb
print select * from $tb ==> $rows points
-if $rows != $N then
+if $rows != $N then
return -1
-endi
-
-system sh/exec.sh -n dnode1 -s stop -x SIGINT
\ No newline at end of file
+endi
+
+system sh/exec.sh -n dnode1 -s stop -x SIGINT
diff --git a/tests/script/tsim/compress/compress2.sim b/tests/script/tsim/compress/compress2.sim
index 87e50cce5b..c55b74f246 100644
--- a/tests/script/tsim/compress/compress2.sim
+++ b/tests/script/tsim/compress/compress2.sim
@@ -26,7 +26,7 @@ while $count < $N
endw
sql select * from $tb
-if $rows != $N then
+if $rows != $N then
return -1
endi
@@ -48,7 +48,7 @@ while $count < $N
endw
sql select * from $tb
-if $rows != $N then
+if $rows != $N then
return -1
endi
@@ -70,7 +70,7 @@ while $count < $N
endw
sql select * from $tb
-if $rows != $N then
+if $rows != $N then
return -1
endi
@@ -86,7 +86,7 @@ $tb = $tbPrefix . $i
sql use $db
sql select * from $tb
print select * from $tb ==> $rows points
-if $rows != $N then
+if $rows != $N then
return -1
endi
@@ -96,18 +96,18 @@ $tb = $tbPrefix . $i
sql use $db
sql select * from $tb
print select * from $tb ==> $rows points
-if $rows != $N then
+if $rows != $N then
return -1
endi
-
+
$i = 2
$db = $dbPrefix . $i
$tb = $tbPrefix . $i
sql use $db
sql select * from $tb
print select * from $tb ==> $rows points
-if $rows != $N then
+if $rows != $N then
return -1
-endi
-
-system sh/exec.sh -n dnode1 -s stop -x SIGINT
\ No newline at end of file
+endi
+
+system sh/exec.sh -n dnode1 -s stop -x SIGINT
diff --git a/tests/script/tsim/compress/uncompress.sim b/tests/script/tsim/compress/uncompress.sim
index ccd5db4b0c..f48fc6da23 100644
--- a/tests/script/tsim/compress/uncompress.sim
+++ b/tests/script/tsim/compress/uncompress.sim
@@ -26,7 +26,7 @@ while $count < $N
endw
sql select * from $tb
-if $rows != $N then
+if $rows != $N then
return -1
endi
@@ -48,7 +48,7 @@ while $count < $N
endw
sql select * from $tb
-if $rows != $N then
+if $rows != $N then
return -1
endi
@@ -70,7 +70,7 @@ while $count < $N
endw
sql select * from $tb
-if $rows != $N then
+if $rows != $N then
return -1
endi
@@ -85,7 +85,7 @@ $tb = $tbPrefix . $i
sql use $db
sql select * from $tb
print select * from $tb ==> $rows points
-if $rows != $N then
+if $rows != $N then
return -1
endi
@@ -95,18 +95,18 @@ $tb = $tbPrefix . $i
sql use $db
sql select * from $tb
print select * from $tb ==> $rows points
-if $rows != $N then
+if $rows != $N then
return -1
endi
-
+
$i = 2
$db = $dbPrefix . $i
$tb = $tbPrefix . $i
sql use $db
sql select * from $tb
print select * from $tb ==> $rows points
-if $rows != $N then
+if $rows != $N then
return -1
-endi
-
-system sh/exec.sh -n dnode1 -s stop -x SIGINT
\ No newline at end of file
+endi
+
+system sh/exec.sh -n dnode1 -s stop -x SIGINT
diff --git a/tests/script/tsim/db/alter_option.sim b/tests/script/tsim/db/alter_option.sim
index d81671eebd..3d260235f2 100644
--- a/tests/script/tsim/db/alter_option.sim
+++ b/tests/script/tsim/db/alter_option.sim
@@ -186,13 +186,13 @@ sql_error alter database db replica 0
#sql alter database db replica 1
#sql select * from information_schema.ins_databases
#print replica: $data4_db
-#if $data4_db != 1 then
+#if $data4_db != 1 then
# return -1
#endi
#sql alter database db replica 3
#sql select * from information_schema.ins_databases
#print replica: $data4_db
-#if $data4_db != 3 then
+#if $data4_db != 3 then
# return -1
#endi
@@ -200,13 +200,13 @@ sql_error alter database db replica 0
#sql alter database db quorum 2
#sql select * from information_schema.ins_databases
#print quorum $data5_db
-#if $data5_db != 2 then
+#if $data5_db != 2 then
# return -1
#endi
#sql alter database db quorum 1
#sql select * from information_schema.ins_databases
#print quorum $data5_db
-#if $data5_db != 1 then
+#if $data5_db != 1 then
# return -1
#endi
@@ -233,7 +233,7 @@ endi
#sql alter database db keep 1000,2000
#sql select * from information_schema.ins_databases
#print keep $data7_db
-#if $data7_db != 500,500,500 then
+#if $data7_db != 500,500,500 then
# return -1
#endi
@@ -263,13 +263,13 @@ sql_error alter database db keep -1
#sql alter database db blocks 3
#sql select * from information_schema.ins_databases
#print blocks $data9_db
-#if $data9_db != 3 then
+#if $data9_db != 3 then
# return -1
#endi
#sql alter database db blocks 11
#sql select * from information_schema.ins_databases
#print blocks $data9_db
-#if $data9_db != 11 then
+#if $data9_db != 11 then
# return -1
#endi
@@ -300,13 +300,13 @@ print ============== step wal_level
sql alter database db wal_level 1
sql select * from information_schema.ins_databases
print wal_level $data20_db
-if $data20_db != 1 then
+if $data20_db != 1 then
return -1
endi
sql alter database db wal_level 2
sql select * from information_schema.ins_databases
print wal_level $data20_db
-if $data20_db != 2 then
+if $data20_db != 2 then
return -1
endi
@@ -319,19 +319,19 @@ print ============== modify wal_fsync_period
sql alter database db wal_fsync_period 2000
sql select * from information_schema.ins_databases
print wal_fsync_period $data21_db
-if $data21_db != 2000 then
+if $data21_db != 2000 then
return -1
endi
sql alter database db wal_fsync_period 500
sql select * from information_schema.ins_databases
print wal_fsync_period $data21_db
-if $data21_db != 500 then
+if $data21_db != 500 then
return -1
endi
sql alter database db wal_fsync_period 0
sql select * from information_schema.ins_databases
print wal_fsync_period $data21_db
-if $data21_db != 0 then
+if $data21_db != 0 then
return -1
endi
sql_error alter database db wal_fsync_period 180001
@@ -351,31 +351,31 @@ print ============== modify cachelast [0, 1, 2, 3]
sql alter database db cachemodel 'last_value'
sql select * from information_schema.ins_databases
print cachelast $data18_db
-if $data18_db != last_value then
+if $data18_db != last_value then
return -1
endi
sql alter database db cachemodel 'last_row'
sql select * from information_schema.ins_databases
print cachelast $data18_db
-if $data18_db != last_row then
+if $data18_db != last_row then
return -1
endi
sql alter database db cachemodel 'none'
sql select * from information_schema.ins_databases
print cachelast $data18_db
-if $data18_db != none then
+if $data18_db != none then
return -1
endi
sql alter database db cachemodel 'last_value'
sql select * from information_schema.ins_databases
print cachelast $data18_db
-if $data18_db != last_value then
+if $data18_db != last_value then
return -1
endi
sql alter database db cachemodel 'both'
sql select * from information_schema.ins_databases
print cachelast $data18_db
-if $data18_db != both then
+if $data18_db != both then
return -1
endi
diff --git a/tests/script/tsim/db/alter_replica_13.sim b/tests/script/tsim/db/alter_replica_13.sim
index d232c9bcd3..1d06d3abb9 100644
--- a/tests/script/tsim/db/alter_replica_13.sim
+++ b/tests/script/tsim/db/alter_replica_13.sim
@@ -36,10 +36,10 @@ endi
print =============== step2: create database
sql create database db vgroups 1
sql select * from information_schema.ins_databases
-if $rows != 3 then
+if $rows != 3 then
return -1
endi
-if $data(db)[4] != 1 then
+if $data(db)[4] != 1 then
return -1
endi
@@ -82,7 +82,7 @@ step3:
return -1
endi
sql select * from information_schema.ins_dnodes
-print ===> rows: $rows
+print ===> rows: $rows
print ===> $data00 $data01 $data02 $data03 $data04 $data05
print ===> $data10 $data11 $data12 $data13 $data14 $data15
print ===> $data20 $data21 $data22 $data23 $data24 $data25
@@ -115,7 +115,7 @@ step4:
return -1
endi
sql show db.vgroups
-print ===> rows: $rows
+print ===> rows: $rows
print ===> $data00 $data01 $data02 $data03 $data04 $data05
if $data[0][4] != leader then
goto step4
@@ -137,4 +137,4 @@ endi
system sh/exec.sh -n dnode1 -s stop -x SIGINT
system sh/exec.sh -n dnode2 -s stop -x SIGINT
system sh/exec.sh -n dnode3 -s stop -x SIGINT
-system sh/exec.sh -n dnode4 -s stop -x SIGINT
\ No newline at end of file
+system sh/exec.sh -n dnode4 -s stop -x SIGINT
diff --git a/tests/script/tsim/db/alter_replica_31.sim b/tests/script/tsim/db/alter_replica_31.sim
index 17ab040520..4ab6783d07 100644
--- a/tests/script/tsim/db/alter_replica_31.sim
+++ b/tests/script/tsim/db/alter_replica_31.sim
@@ -23,7 +23,7 @@ step1:
return -1
endi
sql select * from information_schema.ins_dnodes
-print ===> rows: $rows
+print ===> rows: $rows
print ===> $data00 $data01 $data02 $data03 $data04 $data05
print ===> $data10 $data11 $data12 $data13 $data14 $data15
print ===> $data20 $data21 $data22 $data23 $data24 $data25
@@ -47,10 +47,10 @@ endi
print =============== step2: create database
sql create database db vgroups 1 replica 3
sql select * from information_schema.ins_databases
-if $rows != 3 then
+if $rows != 3 then
return -1
endi
-if $data(db)[4] != 3 then
+if $data(db)[4] != 3 then
return -1
endi
@@ -139,7 +139,7 @@ step3:
return -1
endi
sql show db.vgroups
-print ===> rows: $rows
+print ===> rows: $rows
if $rows != 1 then
goto step3
endi
@@ -165,4 +165,4 @@ endi
system sh/exec.sh -n dnode1 -s stop -x SIGINT
system sh/exec.sh -n dnode2 -s stop -x SIGINT
system sh/exec.sh -n dnode3 -s stop -x SIGINT
-system sh/exec.sh -n dnode4 -s stop -x SIGINT
\ No newline at end of file
+system sh/exec.sh -n dnode4 -s stop -x SIGINT
diff --git a/tests/script/tsim/db/back_insert.sim b/tests/script/tsim/db/back_insert.sim
index e2bdb3a64b..b3f8207293 100644
--- a/tests/script/tsim/db/back_insert.sim
+++ b/tests/script/tsim/db/back_insert.sim
@@ -2,8 +2,8 @@ sql connect
$x = 1
begin:
sql reset query cache
- sleep 100
- sql insert into db.tb values(now, $x ) -x begin
- #print ===> insert successed $x
- $x = $x + 1
-goto begin
\ No newline at end of file
+ sleep 100
+ sql insert into db.tb values(now, $x ) -x begin
+ #print ===> insert successed $x
+ $x = $x + 1
+goto begin
diff --git a/tests/script/tsim/db/basic1.sim b/tests/script/tsim/db/basic1.sim
index 679440590f..69eeb9347b 100644
--- a/tests/script/tsim/db/basic1.sim
+++ b/tests/script/tsim/db/basic1.sim
@@ -25,15 +25,15 @@ endi
print =============== show vgroups1
sql use d1
sql show vgroups
-if $rows != 2 then
+if $rows != 2 then
return -1
endi
-if $data00 != 2 then
+if $data00 != 2 then
return -1
endi
-if $data10 != 3 then
+if $data10 != 3 then
return -1
endi
@@ -59,11 +59,11 @@ if $rows != 2 then
return -1
endi
-if $data00 != 4 then
+if $data00 != 4 then
return -1
endi
-if $data10 != 5 then
+if $data10 != 5 then
return -1
endi
@@ -73,15 +73,15 @@ if $rows != 3 then
return -1
endi
-if $data00 != 6 then
+if $data00 != 6 then
return -1
endi
-if $data10 != 7 then
+if $data10 != 7 then
return -1
endi
-if $data20 != 8 then
+if $data20 != 8 then
return -1
endi
@@ -91,19 +91,19 @@ if $rows != 4 then
return -1
endi
-if $data00 != 9 then
+if $data00 != 9 then
return -1
endi
-if $data10 != 10 then
+if $data10 != 10 then
return -1
endi
-if $data20 != 11 then
+if $data20 != 11 then
return -1
endi
-if $data30 != 12 then
+if $data30 != 12 then
return -1
endi
diff --git a/tests/script/tsim/db/basic2.sim b/tests/script/tsim/db/basic2.sim
index 2ba7d806af..b7ac0b5edd 100644
--- a/tests/script/tsim/db/basic2.sim
+++ b/tests/script/tsim/db/basic2.sim
@@ -27,7 +27,7 @@ sql create table t3 (ts timestamp, i int);
sql create table t4 (ts timestamp, i int);
sql select * from information_schema.ins_databases
-print rows: $rows
+print rows: $rows
print $data00 $data01 $data02 $data03
print $data10 $data11 $data12 $data13
if $rows != 3 then
@@ -47,7 +47,7 @@ endi
#endi
sql show tables
-if $rows != 4 then
+if $rows != 4 then
return -1
endi
@@ -64,8 +64,8 @@ if $rows != 4 then
endi
sql show tables
-if $rows != 3 then
+if $rows != 3 then
return -1
endi
-system sh/exec.sh -n dnode1 -s stop -x SIGINT
\ No newline at end of file
+system sh/exec.sh -n dnode1 -s stop -x SIGINT
diff --git a/tests/script/tsim/db/basic3.sim b/tests/script/tsim/db/basic3.sim
index 30faec0494..db355213db 100644
--- a/tests/script/tsim/db/basic3.sim
+++ b/tests/script/tsim/db/basic3.sim
@@ -23,12 +23,12 @@ if $data22 != 2 then
return -1
endi
-#if $data03 != 4 then
+#if $data03 != 4 then
# return -1
#endi
sql show d1.tables
-if $rows != 4 then
+if $rows != 4 then
return -1
endi
@@ -44,8 +44,8 @@ if $rows != 4 then
endi
sql show d2.tables
-if $rows != 3 then
+if $rows != 3 then
return -1
endi
-system sh/exec.sh -n dnode1 -s stop -x SIGINT
\ No newline at end of file
+system sh/exec.sh -n dnode1 -s stop -x SIGINT
diff --git a/tests/script/tsim/db/basic4.sim b/tests/script/tsim/db/basic4.sim
index f407c6352d..7a5e0ec764 100644
--- a/tests/script/tsim/db/basic4.sim
+++ b/tests/script/tsim/db/basic4.sim
@@ -11,109 +11,109 @@ sql create table d1.t3 (ts timestamp, i int);
sql create table d1.t4 (ts timestamp, i int);
sql select * from information_schema.ins_databases
-if $rows != 3 then
+if $rows != 3 then
return -1
endi
-if $data20 != d1 then
+if $data20 != d1 then
return -1
endi
-if $data22 != 1 then
+if $data22 != 1 then
return -1
endi
-if $data24 != 1 then
+if $data24 != 1 then
return -1
endi
sql show d1.tables
-if $rows != 4 then
+if $rows != 4 then
return -1
endi
sql show d1.vgroups
-if $rows != 1 then
+if $rows != 1 then
return -1
endi
-if $data00 != 2 then
+if $data00 != 2 then
return -1
endi
-if $data01 != d1 then
+if $data01 != d1 then
return -1
endi
-print =============== drop table
+print =============== drop table
sql drop table d1.t1
sql select * from information_schema.ins_databases
-if $rows != 3 then
+if $rows != 3 then
return -1
endi
-if $data20 != d1 then
+if $data20 != d1 then
return -1
endi
-if $data22 != 1 then
+if $data22 != 1 then
return -1
endi
-if $data24 != 1 then
+if $data24 != 1 then
return -1
endi
sql show d1.tables
-if $rows != 3 then
+if $rows != 3 then
return -1
endi
sql show d1.vgroups
-if $rows != 1 then
+if $rows != 1 then
return -1
endi
-if $data00 != 2 then
+if $data00 != 2 then
return -1
endi
-if $data01 != d1 then
+if $data01 != d1 then
return -1
endi
-print =============== drop all table
+print =============== drop all table
sql drop table d1.t2
sql drop table d1.t3
sql drop table d1.t4
sql select * from information_schema.ins_databases
-if $rows != 3 then
+if $rows != 3 then
return -1
endi
-if $data20 != d1 then
+if $data20 != d1 then
return -1
endi
-if $data22 != 1 then
+if $data22 != 1 then
return -1
endi
-if $data24 != 1 then
+if $data24 != 1 then
return -1
endi
sql show d1.tables
-if $rows != 0 then
+if $rows != 0 then
return -1
endi
sql show d1.vgroups
-if $rows != 1 then
+if $rows != 1 then
return -1
endi
-if $data00 != 2 then
+if $data00 != 2 then
return -1
endi
-if $data01 != d1 then
+if $data01 != d1 then
return -1
endi
-system sh/exec.sh -n dnode1 -s stop -x SIGINT
\ No newline at end of file
+system sh/exec.sh -n dnode1 -s stop -x SIGINT
diff --git a/tests/script/tsim/db/basic5.sim b/tests/script/tsim/db/basic5.sim
index 9b809c35f0..933fb8cf4b 100644
--- a/tests/script/tsim/db/basic5.sim
+++ b/tests/script/tsim/db/basic5.sim
@@ -13,13 +13,13 @@ sql create table tb1 using st1 tags(1);
sql insert into tb1 values (now, 1);
sql show stables
-if $rows != 1 then
+if $rows != 1 then
print $rows
return -1
endi
sql show tables
-if $rows != 1 then
+if $rows != 1 then
return -1
endi
@@ -35,12 +35,12 @@ sql use db1;
sql create stable st1 (ts timestamp, f1 int) tags(t1 int)
sql show stables
-if $rows != 1 then
+if $rows != 1 then
return -1
endi
sql show tables
-if $rows != 0 then
+if $rows != 0 then
return -1
endi
diff --git a/tests/script/tsim/db/basic6.sim b/tests/script/tsim/db/basic6.sim
index 2377a65ac0..5043574787 100644
--- a/tests/script/tsim/db/basic6.sim
+++ b/tests/script/tsim/db/basic6.sim
@@ -14,7 +14,7 @@ $st = $stPrefix . $i
$tb = $tbPrefix . $i
print =============== step1
-# quorum presicion
+# quorum presicion
sql create database $db vgroups 8 replica 1 duration 2 keep 10 minrows 80 maxrows 10000 wal_level 2 wal_fsync_period 1000 comp 0 cachemodel 'last_value' precision 'us'
sql select * from information_schema.ins_databases
print $data00 $data01 $data02 $data03 $data04 $data05 $data06 $data07 $data08 $data09
@@ -46,7 +46,7 @@ endi
#if $data29 != 12 then
# return -1
#endi
-
+
print =============== step2
sql_error create database $db
sql create database if not exists $db
@@ -60,7 +60,7 @@ sql drop database $db
sql select * from information_schema.ins_databases
if $rows != 2 then
return -1
-endi
+endi
print =============== step4
sql_error drop database $db
@@ -102,22 +102,22 @@ while $i < 5
sql create table $tb using $st tags(1)
sql show stables
- if $rows != 1 then
+ if $rows != 1 then
return -1
endi
print $data00 $data01 $data02 $data03
- if $data00 != $st then
+ if $data00 != $st then
return -1
endi
sql show tables
- if $rows != 1 then
+ if $rows != 1 then
return -1
endi
print $data00 $data01 $data02 $data03
- if $data00 != $tb then
+ if $data00 != $tb then
return -1
endi
@@ -127,8 +127,8 @@ endw
print =============== step7
$i = 0
while $i < 5
- $db = $dbPrefix . $i
- sql drop database $db
+ $db = $dbPrefix . $i
+ sql drop database $db
$i = $i + 1
endw
@@ -143,20 +143,20 @@ sql create table $st (ts timestamp, i int) tags (j int)
sql create table $tb using $st tags(1)
sql show stables
-if $rows != 1 then
+if $rows != 1 then
return -1
endi
-if $data00 != $st then
+if $data00 != $st then
return -1
endi
sql show tables
-if $rows != 1 then
+if $rows != 1 then
return -1
endi
-if $data00 != $tb then
+if $data00 != $tb then
return -1
endi
@@ -168,12 +168,12 @@ sql create database $db
sql use $db
sql show stables
-if $rows != 0 then
+if $rows != 0 then
return -1
endi
sql show tables
-if $rows != 0 then
+if $rows != 0 then
return -1
endi
@@ -182,20 +182,20 @@ sql create table $st (ts timestamp, i int) tags (j int)
sql create table $tb using $st tags(1)
sql show stables
-if $rows != 1 then
+if $rows != 1 then
return -1
endi
-if $data00 != $st then
+if $data00 != $st then
return -1
endi
sql show tables
-if $rows != 1 then
+if $rows != 1 then
return -1
endi
-if $data00 != $tb then
+if $data00 != $tb then
return -1
endi
@@ -207,12 +207,12 @@ sql create database $db
sql use $db
sql show stables
-if $rows != 0 then
+if $rows != 0 then
return -1
endi
sql show tables
-if $rows != 0 then
+if $rows != 0 then
return -1
endi
@@ -221,20 +221,20 @@ sql create table $st (ts timestamp, i int) tags (j int)
sql create table $tb using $st tags(1)
sql show stables
-if $rows != 1 then
+if $rows != 1 then
return -1
endi
-if $data00 != $st then
+if $data00 != $st then
return -1
endi
sql show tables
-if $rows != 1 then
+if $rows != 1 then
return -1
endi
-if $data00 != $tb then
+if $data00 != $tb then
return -1
endi
@@ -245,12 +245,12 @@ sql insert into $tb values (now+4a, 3)
sql insert into $tb values (now+5a, 4)
sql select * from $tb
-if $rows != 5 then
+if $rows != 5 then
return -1
endi
sql select * from $st
-if $rows != 5 then
+if $rows != 5 then
return -1
endi
@@ -262,12 +262,12 @@ sql create database $db
sql use $db
sql show stables
-if $rows != 0 then
+if $rows != 0 then
return -1
endi
sql show tables
-if $rows != 0 then
+if $rows != 0 then
return -1
endi
@@ -276,20 +276,20 @@ sql create table $st (ts timestamp, i int) tags (j int)
sql create table $tb using $st tags(1)
sql show stables
-if $rows != 1 then
+if $rows != 1 then
return -1
endi
-if $data00 != $st then
+if $data00 != $st then
return -1
endi
sql show tables
-if $rows != 1 then
+if $rows != 1 then
return -1
endi
-if $data00 != $tb then
+if $data00 != $tb then
return -1
endi
@@ -300,12 +300,12 @@ sql insert into $tb values (now+4a, 3)
sql insert into $tb values (now+5a, 4)
sql select * from $tb
-if $rows != 5 then
+if $rows != 5 then
return -1
endi
sql select * from $st
-if $rows != 5 then
+if $rows != 5 then
return -1
endi
diff --git a/tests/script/tsim/db/commit.sim b/tests/script/tsim/db/commit.sim
index 731f2aa256..2233245034 100644
--- a/tests/script/tsim/db/commit.sim
+++ b/tests/script/tsim/db/commit.sim
@@ -39,9 +39,9 @@ sql create table tb (ts timestamp, i int)
$x = 1
while $x < 41
$time = $x . m
- sql insert into tb values (now + $time , $x )
+ sql insert into tb values (now + $time , $x )
$x = $x + 1
-endw
+endw
sql select * from tb order by ts desc
print ===> rows $rows
@@ -71,7 +71,7 @@ if $data01 != 40 then
return -1
endi
-$oldnum = $rows
+$oldnum = $rows
$num = $rows + 2
print ======== step3 import old data
@@ -120,4 +120,4 @@ if $data01 != 40 then
endi
system sh/exec.sh -n dnode1 -s stop -x SIGINT
-system sh/exec.sh -n dnode2 -s stop -x SIGINT
\ No newline at end of file
+system sh/exec.sh -n dnode2 -s stop -x SIGINT
diff --git a/tests/script/tsim/db/delete_reuse1.sim b/tests/script/tsim/db/delete_reuse1.sim
index 680fe6b2ed..9dcb3c6ac1 100644
--- a/tests/script/tsim/db/delete_reuse1.sim
+++ b/tests/script/tsim/db/delete_reuse1.sim
@@ -3,7 +3,7 @@ system sh/deploy.sh -n dnode1 -i 1
system sh/exec.sh -n dnode1 -s start
sql connect
-print ======== step1
+print ======== step1
sql create database d1 replica 1 vgroups 1
sql create database d2 replica 1 vgroups 1
sql create database d3 replica 1 vgroups 1
@@ -47,7 +47,7 @@ step2:
print ========= step3
sql reset query cache
-sleep 50
+sleep 50
sql create database d1 replica 1
sql create table d1.t1 (ts timestamp, i int)
@@ -65,20 +65,20 @@ while $x < 20
sql insert into d1.t1 values(now, -1) -x step4
return -1
step4:
-
+
sql create database d1 replica 1
sql reset query cache
- sleep 50
+ sleep 50
sql create table d1.t1 (ts timestamp, i int)
sql insert into d1.t1 values(now, $x )
sql select * from d1.t1
if $rows != 1 then
return -1
endi
-
- $x = $x + 1
-
- print ===> loop times: $x
-endw
-system sh/exec.sh -n dnode1 -s stop -x SIGINT
\ No newline at end of file
+ $x = $x + 1
+
+ print ===> loop times: $x
+endw
+
+system sh/exec.sh -n dnode1 -s stop -x SIGINT
diff --git a/tests/script/tsim/db/delete_reuse2.sim b/tests/script/tsim/db/delete_reuse2.sim
index d181b6b780..4480b60b1b 100644
--- a/tests/script/tsim/db/delete_reuse2.sim
+++ b/tests/script/tsim/db/delete_reuse2.sim
@@ -3,7 +3,7 @@ system sh/deploy.sh -n dnode1 -i 1
system sh/exec.sh -n dnode1 -s start
sql connect
-print ======== step1
+print ======== step1
sql create database d1 replica 1
sql create database d2 replica 1
sql create database d3 replica 1
@@ -48,7 +48,7 @@ step2:
print ========= step3
sql create database db1 replica 1
sql reset query cache
-sleep 50
+sleep 50
sql create table db1.tb1 (ts timestamp, i int)
sql insert into db1.tb1 values(now, 2)
@@ -61,7 +61,7 @@ print ========= step4
$x = 1
while $x < 20
- $db = db . $x
+ $db = db . $x
$tb = tb . $x
sql use $db
sql drop database $db
@@ -69,14 +69,14 @@ while $x < 20
sql insert into $tb values(now, -1) -x step4
return -1
step4:
-
- $x = $x + 1
- $db = db . $x
+
+ $x = $x + 1
+ $db = db . $x
$tb = tb . $x
-
+
sql reset query cache
- sleep 50
-
+ sleep 50
+
sql create database $db replica 1
sql use $db
sql create table $tb (ts timestamp, i int)
@@ -85,8 +85,8 @@ while $x < 20
if $rows != 1 then
return -1
endi
-
- print ===> loop times: $x
-endw
-system sh/exec.sh -n dnode1 -s stop -x SIGINT
\ No newline at end of file
+ print ===> loop times: $x
+endw
+
+system sh/exec.sh -n dnode1 -s stop -x SIGINT
diff --git a/tests/script/tsim/db/delete_reusevnode.sim b/tests/script/tsim/db/delete_reusevnode.sim
index d194f82d08..7af5c9d39d 100644
--- a/tests/script/tsim/db/delete_reusevnode.sim
+++ b/tests/script/tsim/db/delete_reusevnode.sim
@@ -3,7 +3,7 @@ system sh/deploy.sh -n dnode1 -i 1
system sh/exec.sh -n dnode1 -s start
sql connect
-print ======== step1
+print ======== step1
$tbPrefix = t
$i = 0
@@ -21,13 +21,13 @@ while $i < 30
print times $i
$i = $i + 1
-endw
+endw
print ======== step2
sql select * from information_schema.ins_databases
-if $rows != 2 then
+if $rows != 2 then
return -1
-endi
+endi
system sh/stop_dnodes.sh
@@ -94,4 +94,4 @@ if $rows != 2 then
return -1
endi
-system sh/exec.sh -n dnode1 -s stop -x SIGINT
\ No newline at end of file
+system sh/exec.sh -n dnode1 -s stop -x SIGINT
diff --git a/tests/script/tsim/db/delete_reusevnode2.sim b/tests/script/tsim/db/delete_reusevnode2.sim
index 754a6d695b..91473e5ee1 100644
--- a/tests/script/tsim/db/delete_reusevnode2.sim
+++ b/tests/script/tsim/db/delete_reusevnode2.sim
@@ -62,4 +62,4 @@ if $rows != 2 then
return -1
endi
-system sh/exec.sh -n dnode1 -s stop -x SIGINT
\ No newline at end of file
+system sh/exec.sh -n dnode1 -s stop -x SIGINT
diff --git a/tests/script/tsim/db/delete_writing1.sim b/tests/script/tsim/db/delete_writing1.sim
index 279f8dece8..6fec09989d 100644
--- a/tests/script/tsim/db/delete_writing1.sim
+++ b/tests/script/tsim/db/delete_writing1.sim
@@ -3,7 +3,7 @@ system sh/deploy.sh -n dnode1 -i 1
system sh/exec.sh -n dnode1 -s start
sql connect
-sql create database db
+sql create database db
sql create table db.tb (ts timestamp, i int)
sql insert into db.tb values(now, 1)
@@ -11,18 +11,18 @@ print ======== start back
run_back tsim/db/back_insert.sim
sleep 1000
-print ======== step1
-$x = 1
+print ======== step1
+$x = 1
while $x < 10
print drop database times $x
sql drop database if exists db
- sql create database db
+ sql create database db
sql create table db.tb (ts timestamp, i int)
sleep 1000
-
+
$x = $x + 1
endw
-system sh/exec.sh -n dnode1 -s stop -x SIGINT
\ No newline at end of file
+system sh/exec.sh -n dnode1 -s stop -x SIGINT
diff --git a/tests/script/tsim/db/delete_writing2.sim b/tests/script/tsim/db/delete_writing2.sim
index 8eab126ae8..ad156f30eb 100644
--- a/tests/script/tsim/db/delete_writing2.sim
+++ b/tests/script/tsim/db/delete_writing2.sim
@@ -3,7 +3,7 @@ system sh/deploy.sh -n dnode1 -i 1
system sh/exec.sh -n dnode1 -s start
sql connect
-sql create database db
+sql create database db
sql create table db.tb (ts timestamp, i int)
sql insert into db.tb values(now, 1)
@@ -11,11 +11,11 @@ sql create database db2
sql create table db2.tb2 (ts timestamp, i int)
sql insert into db2.tb2 values(now, 1)
-sql create database db3
+sql create database db3
sql create table db3.tb3 (ts timestamp, i int)
sql insert into db3.tb3 values(now, 1)
-sql create database db4
+sql create database db4
sql create table db4.tb4 (ts timestamp, i int)
sql insert into db4.tb4 values(now, 1)
@@ -23,19 +23,19 @@ print ======== start back
run_back tsim/db/back_insert.sim
sleep 1000
-print ======== step1
-$x = 1
+print ======== step1
+$x = 1
while $x < 10
print drop database times $x
sql drop database if exists db
- sql create database db
+ sql create database db
sql create table db.tb (ts timestamp, i int)
sleep 1000
-
+
$x = $x + 1
endw
-system sh/exec.sh -n dnode1 -s stop -x SIGINT
\ No newline at end of file
+system sh/exec.sh -n dnode1 -s stop -x SIGINT
diff --git a/tests/script/tsim/db/dropdnodes.sim b/tests/script/tsim/db/dropdnodes.sim
index 8a46d5f9ce..20b4a136df 100644
--- a/tests/script/tsim/db/dropdnodes.sim
+++ b/tests/script/tsim/db/dropdnodes.sim
@@ -12,7 +12,7 @@ system sh/exec.sh -n dnode1 -s start
system sh/exec.sh -n dnode2 -s start
sleep 2000
-sql connect
+sql connect
sql create dnode $hostname2
sleep 2000
@@ -61,13 +61,13 @@ sql show tables
print $rows
if $rows != 16 then
return -1
-endi
+endi
sql select * from mt
print $rows
if $rows != 16 then
return -1
-endi
+endi
print ========== step3
@@ -82,26 +82,26 @@ sql show tables
print $rows
if $rows != 8 then
return -1
-endi
+endi
sql select * from mt
print $rows
if $rows != 8 then
return -1
-endi
+endi
sql select * from db.t5
if $rows != 1 then
return -1
-endi
+endi
sql select * from db.t13
if $rows != 1 then
return -1
-endi
+endi
sql_error select * from db.t1
sql_error select * from db.t9
system sh/exec.sh -n dnode1 -s stop -x SIGINT
-system sh/exec.sh -n dnode2 -s stop -x SIGINT
\ No newline at end of file
+system sh/exec.sh -n dnode2 -s stop -x SIGINT
diff --git a/tests/script/tsim/db/keep.sim b/tests/script/tsim/db/keep.sim
index e146a666d0..f0653c4801 100644
--- a/tests/script/tsim/db/keep.sim
+++ b/tests/script/tsim/db/keep.sim
@@ -14,7 +14,7 @@ while $x < 41
sql insert into tb values (now - $time , $x ) -x step2
step2:
$x = $x + 1
-endw
+endw
sql select * from tb
print ===> rows $rows last $data01
@@ -42,10 +42,10 @@ sql alter database keepdb keep 60
sql flush database keepdb
sql select * from information_schema.ins_databases
print $data00 $data01 $data02 $data03 $data04 $data05 $data06 $data07
-if $data22 != 2 then
+if $data22 != 2 then
return -1
endi
-if $data27 != 86400m,86400m,86400m then
+if $data27 != 86400m,86400m,86400m then
return -1
endi
@@ -56,7 +56,7 @@ while $x < 81
sql insert into tb values (now - $time , $x ) -x step4
step4:
$x = $x + 1
-endw
+endw
sql select * from tb
print ===> rows $rows last $data01
@@ -83,10 +83,10 @@ endi
print ======== step6 alter db
sql alter database keepdb keep 30
sql select * from information_schema.ins_databases
-if $data22 != 2 then
+if $data22 != 2 then
return -1
endi
-if $data27 != 43200m,43200m,43200m then
+if $data27 != 43200m,43200m,43200m then
return -1
endi
@@ -110,7 +110,7 @@ while $x < 121
sql insert into tb values (now - $time , $x ) -x step8
step8:
$x = $x + 1
-endw
+endw
sql select * from tb
print ===> rows $rows last $data01
@@ -137,4 +137,4 @@ error3:
print ======= test success
system sh/exec.sh -n dnode1 -s stop -x SIGINT
-system sh/exec.sh -n dnode2 -s stop -x SIGINT
\ No newline at end of file
+system sh/exec.sh -n dnode2 -s stop -x SIGINT
diff --git a/tests/script/tsim/db/len.sim b/tests/script/tsim/db/len.sim
index ae475ddf47..047dafd5f8 100644
--- a/tests/script/tsim/db/len.sim
+++ b/tests/script/tsim/db/len.sim
@@ -11,33 +11,33 @@ sql create database -x step1
step1:
sql select * from information_schema.ins_databases
-if $rows != 2 then
+if $rows != 2 then
return -1
endi
print =============== step2
sql create database a
sql select * from information_schema.ins_databases
-if $rows != 3 then
+if $rows != 3 then
return -1
endi
sql drop database a
sql select * from information_schema.ins_databases
-if $rows != 2 then
+if $rows != 2 then
return -1
endi
print =============== step3
sql create database a12345678
sql select * from information_schema.ins_databases
-if $rows != 3 then
+if $rows != 3 then
return -1
endi
sql drop database a12345678
sql select * from information_schema.ins_databases
-if $rows != 2 then
+if $rows != 2 then
return -1
endi
@@ -46,15 +46,15 @@ sql create database a012345678901201234567890120123456789012a0123456789012012345
return -1
step4:
sql select * from information_schema.ins_databases
-if $rows != 2 then
+if $rows != 2 then
return -1
endi
print =============== step5
-sql create database a;1
+sql create database a;1
sql drop database a
sql select * from information_schema.ins_databases
-if $rows != 2 then
+if $rows != 2 then
return -1
endi
@@ -64,7 +64,7 @@ sql create database a'1 -x step6
step6:
sql select * from information_schema.ins_databases
-if $rows != 2 then
+if $rows != 2 then
return -1
endi
@@ -73,7 +73,7 @@ sql create database (a) -x step7
return -1
step7:
sql select * from information_schema.ins_databases
-if $rows != 2 then
+if $rows != 2 then
return -1
endi
@@ -82,8 +82,8 @@ sql create database a.1 -x step8
return -1
step8:
sql select * from information_schema.ins_databases
-if $rows != 2 then
+if $rows != 2 then
return -1
endi
-system sh/exec.sh -n dnode1 -s stop -x SIGINT
\ No newline at end of file
+system sh/exec.sh -n dnode1 -s stop -x SIGINT
diff --git a/tests/script/tsim/db/repeat.sim b/tests/script/tsim/db/repeat.sim
index 98d66244f5..b0627659d0 100644
--- a/tests/script/tsim/db/repeat.sim
+++ b/tests/script/tsim/db/repeat.sim
@@ -56,4 +56,4 @@ sql drop database d10
sql drop database d11
sql drop database d12
-system sh/exec.sh -n dnode1 -s stop -x SIGINT
\ No newline at end of file
+system sh/exec.sh -n dnode1 -s stop -x SIGINT
diff --git a/tests/script/tsim/db/show_create_db.sim b/tests/script/tsim/db/show_create_db.sim
index 45007d01d6..3a51fedbff 100644
--- a/tests/script/tsim/db/show_create_db.sim
+++ b/tests/script/tsim/db/show_create_db.sim
@@ -7,7 +7,7 @@ print =============== step2
sql create database db
sql show create database db
-if $rows != 1 then
+if $rows != 1 then
return -1
endi
@@ -15,13 +15,13 @@ print =============== step3
sql use db
sql show create database db
-if $rows != 1 then
+if $rows != 1 then
return -1
endi
-if $data00 != db then
+if $data00 != db then
return -1
-endi
+endi
sql drop database db
diff --git a/tests/script/tsim/db/show_create_table.sim b/tests/script/tsim/db/show_create_table.sim
index 44fa09577e..0aeee42d21 100644
--- a/tests/script/tsim/db/show_create_table.sim
+++ b/tests/script/tsim/db/show_create_table.sim
@@ -11,14 +11,14 @@ sql create table t0 using meters tags(1,'ch')
sql create table normalTbl(ts timestamp, zone binary(8))
sql use db
-sql show create table meters
-if $rows != 1 then
+sql show create table meters
+if $rows != 1 then
return -1
endi
print ===============check sub table
sql show create table t0
-if $rows != 1 then
+if $rows != 1 then
return -1
endi
if $data00 == 't0' then
@@ -27,8 +27,8 @@ endi
print ===============check normal table
-sql show create table normalTbl
-if $rows != 1 then
+sql show create table normalTbl
+if $rows != 1 then
return -1
endi
@@ -37,8 +37,8 @@ if $data00 == 'normalTbl' then
endi
print ===============check super table
-sql show create table meters
-if $rows != 1 then
+sql show create table meters
+if $rows != 1 then
return -1
endi
@@ -49,7 +49,7 @@ endi
print ===============check sub table with prefix
sql show create table db.t0
-if $rows != 1 then
+if $rows != 1 then
return -1
endi
@@ -58,8 +58,8 @@ if $data00 == 't0' then
endi
print ===============check normal table with prefix
-sql show create table db.normalTbl
-if $rows != 1 then
+sql show create table db.normalTbl
+if $rows != 1 then
return -1
endi
@@ -69,8 +69,8 @@ endi
print ===============check super table with prefix
-sql show create table db.meters
-if $rows != 1 then
+sql show create table db.meters
+if $rows != 1 then
return -1
endi
diff --git a/tests/script/tsim/db/tables.sim b/tests/script/tsim/db/tables.sim
index cdee504753..273a1fd45d 100644
--- a/tests/script/tsim/db/tables.sim
+++ b/tests/script/tsim/db/tables.sim
@@ -8,7 +8,7 @@ sql create database db
sql select * from information_schema.ins_databases
print $rows $data07
-if $rows != 3 then
+if $rows != 3 then
return -1
endi
@@ -125,4 +125,4 @@ if $data01 != 4 then
return -1
endi
-system sh/exec.sh -n dnode1 -s stop -x SIGINT
\ No newline at end of file
+system sh/exec.sh -n dnode1 -s stop -x SIGINT
diff --git a/tests/script/tsim/parser/fill_stb.sim b/tests/script/tsim/parser/fill_stb.sim
index 51ae6f4b41..656b1ac94e 100644
--- a/tests/script/tsim/parser/fill_stb.sim
+++ b/tests/script/tsim/parser/fill_stb.sim
@@ -136,7 +136,8 @@ if $data74 != -4.00000 then
endi
## fill(value) + group by
-sql select max(c1), max(c2), max(c3), max(c4), max(c5) from $stb where ts >= $ts0 and ts <= $tsu interval(5m) fill(value, -1, -2, -3, -4, -5, -6, -7, -8) group by t1
+print select _wstart, max(c1), max(c2), max(c3), max(c4), max(c5) from $stb where ts >= $ts0 and ts <= $tsu partition by t1 interval(5m) fill(value, -1, -2, -3, -4, -5, -6, -7, -8)
+sql select _wstart, max(c1), max(c2), max(c3), max(c4), max(c5) from $stb where ts >= $ts0 and ts <= $tsu partition by t1 interval(5m) fill(value, -1, -2, -3, -4, -5, -6, -7, -8)
$val = $rowNum * 2
print $rowNum, $val
@@ -148,18 +149,13 @@ if $rows != 190 then
print expect 190, actual:$rows
return -1
endi
-if $data06 != 0 then
- return -1
-endi
if $data11 != -1 then
return -1
endi
-#if $data16 != 0 then
-# return -1
-#endi
# number of fill values is smaller than number of selected columns
-sql select max(c1), max(c2), max(c3) from $stb where ts >= $ts0 and ts <= $tsu interval(5m) fill(value, 6, 6)
+print select _wstart, max(c1), max(c2), max(c3) from $stb where ts >= $ts0 and ts <= $tsu interval(5m) fill(value, 6, 6)
+sql select _wstart, max(c1), max(c2), max(c3) from $stb where ts >= $ts0 and ts <= $tsu interval(5m) fill(value, 6, 6)
if $data11 != 6 then
return -1
endi
@@ -174,11 +170,11 @@ endi
sql_error select max(c1), max(c2), max(c3), max(c4), max(c5) from $stb where ts >= $ts0 and ts <= $tsu interval(5m) fill (6, 6, 6, 6, 6)
# fill_char_values_to_arithmetic_fields
-sql_error select sum(c1), avg(c2), max(c3), min(c4), avg(c4), count(c6), last(c7), last(c8) from $stb where ts >= $ts0 and ts <= $tsu interval(5m) fill(value, 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c')
+sql select sum(c1), avg(c2), max(c3), min(c4), avg(c4), count(c6), last(c7), last(c8) from $stb where ts >= $ts0 and ts <= $tsu interval(5m) fill(value, 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c')
# fill_multiple_columns
sql_error select sum(c1), avg(c2), min(c3), max(c4), count(c6), first(c7), last(c8) from $stb where ts >= $ts0 and ts <= $tsu interval(5m) fill(value, 99, 99, 99, 99, 99, abc, abc)
-sql select sum(c1), avg(c2), min(c3), max(c4) from $stb where ts >= $ts0 and ts <= $tsu interval(5m) fill(value, 99, 99, 99, 99)
+sql select _wstart, sum(c1), avg(c2), min(c3), max(c4) from $stb where ts >= $ts0 and ts <= $tsu interval(5m) fill(value, 99, 99, 99, 99)
$val = $rowNum * 2
$val = $val - 1
if $rows != $val then
@@ -196,11 +192,14 @@ sql select * from $stb
if $data09 != nchar0 then
return -1
endi
-sql select max(c4) from $stb where t1 > 4 and ts >= $ts0 and ts <= $tsu interval(5m) fill(value, -1) group by t1
-if $rows != 0 then
- return -1
-endi
-sql select min(c1), max(c4) from $stb where t1 > 4 and ts >= $ts0 and ts <= $tsu interval(5m) fill(value, -1)
+
+print select max(c4) from $stb where t1 > 4 and ts >= $ts0 and ts <= $tsu partition by t1 interval(5m) fill(value, -1)
+sql select max(c4) from $stb where t1 > 4 and ts >= $ts0 and ts <= $tsu partition by t1 interval(5m) fill(value, -1)
+#if $rows != 0 then
+# return -1
+#endi
+
+sql select _wstart, min(c1), max(c4) from $stb where t1 > 4 and ts >= $ts0 and ts <= $tsu interval(5m) fill(value, -1)
$val = $rowNum * 2
$val = $val - 1
if $rows != $val then
@@ -223,11 +222,12 @@ if $data12 != -1.000000000 then
endi
# fill_into_nonarithmetic_fieds
-sql select first(c7), first(c8), first(c9) from $stb where ts >= $ts0 and ts <= $tsu interval(5m) fill(value, 20000000, 20000000, 20000000)
+print select _wstart, first(c7), first(c8), first(c9) from $stb where ts >= $ts0 and ts <= $tsu interval(5m) fill(value, 20000000, 20000000, 20000000)
+sql select _wstart, first(c7), first(c8), first(c9) from $stb where ts >= $ts0 and ts <= $tsu interval(5m) fill(value, 20000000, 20000000, 20000000)
#if $data11 != 20000000 then
-if $data11 != 1 then
- return -1
-endi
+#if $data11 != 1 then
+# return -1
+#endi
sql select first(c7), first(c8), first(c9) from $stb where ts >= $ts0 and ts <= $tsu interval(5m) fill(value, 1, 1, 1)
sql select first(c7), first(c8), first(c9) from $stb where ts >= $ts0 and ts <= $tsu interval(5m) fill(value, 1.1, 1.1, 1.1)
@@ -235,16 +235,15 @@ sql select first(c7), first(c8), first(c9) from $stb where ts >= $ts0 and ts <=
sql select first(c8), first(c9) from $stb where ts >= $ts0 and ts <= $tsu interval(5m) fill(value, '1e', '1e1')
# fill quoted values into bool column will throw error unless the value is 'true' or 'false' Note:2018-10-24
# fill values into binary or nchar columns will be set to NULL automatically Note:2018-10-24
-sql_error select first(c7), first(c8), first(c9) from $stb where ts >= $ts0 and ts <= $tsu interval(5m) fill(value, '1e', '1e1','1e1')
+sql select first(c7), first(c8), first(c9) from $stb where ts >= $ts0 and ts <= $tsu interval(5m) fill(value, '1e', '1e1','1e1')
sql select first(c7), first(c8), first(c9) from $stb where ts >= $ts0 and ts <= $tsu interval(5m) fill(value, true, true, true)
sql select first(c7), first(c8), first(c9) from $stb where ts >= $ts0 and ts <= $tsu interval(5m) fill(value, 'true', 'true','true')
-
# fill nonarithmetic values into arithmetic fields
sql_error select count(*) from $stb where ts >= $ts0 and ts <= $tsu interval(5m) fill(value, abc);
-sql_error select count(*) from $stb where ts >= $ts0 and ts <= $tsu interval(5m) fill(value, 'true');
+sql select count(*) from $stb where ts >= $ts0 and ts <= $tsu interval(5m) fill(value, 'true');
-sql select count(*) from $stb where ts >= $ts0 and ts <= $tsu interval(5m) fill(value, '2e1');
+sql select _wstart, count(*) from $stb where ts >= $ts0 and ts <= $tsu interval(5m) fill(value, '2e1');
$val = $rowNum * 2
$val = $val - 1
if $rows != $val then
@@ -253,11 +252,11 @@ endi
if $data01 != $rowNum then
return -1
endi
-if $data11 != 20 then
- return -1
-endi
+#if $data11 != 20 then
+# return -1
+#endi
-sql select count(*) from $stb where ts >= $ts0 and ts <= $tsu interval(5m) fill(value, 2e1);
+sql select _wstart, count(*) from $stb where ts >= $ts0 and ts <= $tsu interval(5m) fill(value, 2e1);
if $rows != $val then
return -1
endi
@@ -268,43 +267,44 @@ if $data11 != 20 then
return -1
endi
-sql select count(*) from $stb where ts >= $ts0 and ts <= $tsu interval(5m) fill(value, '20');
+sql select _wstart, count(*) from $stb where ts >= $ts0 and ts <= $tsu interval(5m) fill(value, '20');
if $rows != $val then
return -1
endi
if $data01 != $rowNum then
return -1
endi
-if $data11 != 20 then
- return -1
-endi
+#if $data11 != 20 then
+# return -1
+#endi
## linear fill
-sql select max(c1), min(c2), avg(c3), sum(c4), first(c7), last(c8), first(c9) from $stb where ts >= $ts0 and ts <= $tsu interval(5m) fill(linear) group by t1
+sql select _wstart, max(c1), min(c2), avg(c3), sum(c4), first(c7), last(c8), first(c9) from $stb where ts >= $ts0 and ts <= $tsu partition by t1 interval(5m) fill(linear)
$val = $rowNum * 2
$val = $val - 1
$val = $val * $tbNum
if $rows != $val then
return -1
endi
-if $data08 != 0 then
- return -1
-endi
-if $data15 != NULL then
- return -1
-endi
-if $data16 != NULL then
- return -1
-endi
-if $data17 != NULL then
- return -1
-endi
-if $data18 != 0 then
- return -1
-endi
+#if $data08 != 0 then
+# return -1
+#endi
+#if $data15 != NULL then
+# return -1
+#endi
+#if $data16 != NULL then
+# return -1
+#endi
+#if $data17 != NULL then
+# return -1
+#endi
+#if $data18 != 0 then
+# return -1
+#endi
## [TBASE-365]
-sql select max(c1), min(c2), avg(c3), sum(c4), first(c7), last(c8), first(c9) from $stb where ts >= $ts0 and ts <= $tsu and t1 > 4 interval(5m) fill(linear) group by t1
+sql select _wstart, max(c1), min(c2), avg(c3), sum(c4), first(c7), last(c8), first(c9) from $stb where ts >= $ts0 and ts <= $tsu and t1 > 4 partition by t1 interval(5m) fill(linear)
+print select _wstart, max(c1), min(c2), avg(c3), sum(c4), first(c7), last(c8), first(c9) from $stb where ts >= $ts0 and ts <= $tsu and t1 > 4 partition by t1 interval(5m) fill(linear)
if $rows != 95 then
return -1
endi
@@ -332,14 +332,8 @@ endi
if $data17 != NULL then
return -1
endi
-if $data08 != 5 then
- return -1
-endi
-if $data18 != 5 then
- return -1
-endi
-sql select max(c1), min(c2), sum(c3), avg(c4), first(c7), last(c8), first(c9) from $stb where ts >= $ts0 and ts <= $tsu interval(5m) fill(linear)
+sql select _wstart, max(c1), min(c2), sum(c3), avg(c4), first(c7), last(c8), first(c9) from $stb where ts >= $ts0 and ts <= $tsu interval(5m) fill(linear)
$val = $rowNum * 2
$val = $val - 1
if $rows != $val then
@@ -359,7 +353,8 @@ endi
## previous fill
print fill(prev)
-sql select max(c1), min(c2), avg(c3), sum(c4), count(c5), first(c7), last(c8), first(c9) from $stb where ts >= $ts0 and ts <= $tsu and t1 > 4 interval(5m) fill(prev) group by t1 limit 5
+print select _wstart, max(c1), min(c2), avg(c3), sum(c4), count(c5), first(c7), last(c8), first(c9) from $stb where ts >= $ts0 and ts <= $tsu and t1 > 4 partition by t1 interval(5m) fill(prev) limit 5
+sql select _wstart, max(c1), min(c2), avg(c3), sum(c4), count(c5), first(c7), last(c8), first(c9) from $stb where ts >= $ts0 and ts <= $tsu and t1 > 4 partition by t1 interval(5m) fill(prev) limit 5
if $rows != 25 then
return -1
endi
@@ -372,69 +367,43 @@ endi
if $data04 != NULL then
return -1
endi
-if $data09 != 5 then
- return -1
-endi
if $data12 != NULL then
return -1
endi
-if $data19 != 5 then
- return -1
-endi
if $data18 != nchar0 then
return -1
endi
-if $data59 != 6 then
- return -1
-endi
-if $data69 != 6 then
- return -1
-endi
## NULL fill
print fill(NULL)
-sql select max(c1), min(c2), avg(c3), sum(c4), count(c5), first(c7), last(c8), first(c9) from $stb where ts >= $ts0 and ts <= $tsu and t1 > 4 interval(5m) fill(value, NULL) group by t1 limit 5
+print select _wstart, max(c1), min(c2), avg(c3), sum(c4), count(c5), first(c7), last(c8), first(c9) from $stb where ts >= $ts0 and ts <= $tsu and t1 > 4 partition by t1 interval(5m) fill(value, NULL) limit 5
+sql select _wstart, max(c1), min(c2), avg(c3), sum(c4), count(c5), first(c7), last(c8), first(c9) from $stb where ts >= $ts0 and ts <= $tsu and t1 > 4 partition by t1 interval(5m) fill(value, NULL) limit 5
if $rows != 25 then
return -1
endi
if $data01 != 0 then
return -1
endi
-if $data02 != NULL then
- return -1
-endi
-if $data04 != NULL then
+if $data02 != 0 then
return -1
endi
if $data06 != 1 then
return -1
endi
-if $data09 != 5 then
+if $data11 != 0 then
return -1
endi
-if $data11 != NULL then
- return -1
-endi
-if $data12 != NULL then
- return -1
-endi
-if $data19 != 5 then
+if $data12 != 0 then
return -1
endi
if $data18 != NULL then
return -1
endi
-if $data59 != 6 then
- return -1
-endi
-if $data69 != 6 then
- return -1
-endi
print =============== clear
sql drop database $db
sql select * from information_schema.ins_databases
-if $rows != 0 then
+if $rows != 2 then
return -1
endi
diff --git a/tests/script/tsim/parser/function.sim b/tests/script/tsim/parser/function.sim
index 0219a84c64..0002a5d095 100644
--- a/tests/script/tsim/parser/function.sim
+++ b/tests/script/tsim/parser/function.sim
@@ -70,6 +70,7 @@ if $data00 != @15-08-18 00:00:00.000@ then
return -1
endi
if $data01 != 2.068333156 then
+ print expect 2.068333156, actual: $data01
return -1
endi
if $data02 != 2.063999891 then
@@ -128,6 +129,7 @@ if $data03 != 2 then
return -1
endi
if $data11 != 2.077099980 then
+ print expect 2.077099980, actual: $data11
return -1
endi
if $data12 != 2.077000022 then
diff --git a/tests/script/tsim/sma/rsmaPersistenceRecovery.sim b/tests/script/tsim/sma/rsmaPersistenceRecovery.sim
index f53cd45d48..faff48b61c 100644
--- a/tests/script/tsim/sma/rsmaPersistenceRecovery.sim
+++ b/tests/script/tsim/sma/rsmaPersistenceRecovery.sim
@@ -35,6 +35,7 @@ sleep 7000
print =============== select * from retention level 2 from memory
sql select * from ct1;
print $data00 $data01 $data02
+print $data10 $data11 $data12
if $rows > 2 then
print retention level 2 file rows $rows > 2
return -1
@@ -51,6 +52,7 @@ endi
print =============== select * from retention level 1 from memory
sql select * from ct1 where ts > now-8d;
print $data00 $data01 $data02
+print $data10 $data11 $data12
if $rows > 2 then
print retention level 1 file rows $rows > 2
return -1
@@ -89,6 +91,7 @@ system sh/exec.sh -n dnode1 -s start
print =============== select * from retention level 2 from file
sql select * from ct1;
print $data00 $data01 $data02
+print $data10 $data11 $data12
if $rows > 2 then
print retention level 2 file rows $rows > 2
return -1
@@ -104,6 +107,7 @@ endi
print =============== select * from retention level 1 from file
sql select * from ct1 where ts > now-8d;
print $data00 $data01 $data02
+print $data10 $data11 $data12
if $rows > 2 then
print retention level 1 file rows $rows > 2
return -1
@@ -141,6 +145,7 @@ sleep 7000
print =============== select * from retention level 2 from file and memory after rsma qtaskinfo recovery
sql select * from ct1;
print $data00 $data01 $data02
+print $data10 $data11 $data12
if $rows > 2 then
print retention level 2 file/mem rows $rows > 2
return -1
@@ -163,6 +168,7 @@ endi
print =============== select * from retention level 1 from file and memory after rsma qtaskinfo recovery
sql select * from ct1 where ts > now-8d;
print $data00 $data01 $data02
+print $data10 $data11 $data12
if $rows > 2 then
print retention level 1 file/mem rows $rows > 2
return -1
diff --git a/tests/script/tsim/stream/basic0.sim b/tests/script/tsim/stream/basic0.sim
index 9a5fb8012f..6d05f69dcf 100644
--- a/tests/script/tsim/stream/basic0.sim
+++ b/tests/script/tsim/stream/basic0.sim
@@ -1,7 +1,7 @@
system sh/stop_dnodes.sh
system sh/deploy.sh -n dnode1 -i 1
-system sh/exec.sh -n dnode1 -s start
-sleep 50
+system sh/cfg.sh -n dnode1 -c debugflag -v 131
+system sh/exec.sh -n dnode1 -s start -v
sql connect
print =============== create database
@@ -137,4 +137,17 @@ if $data13 != 789 then
return -1
endi
+_OVER:
system sh/exec.sh -n dnode1 -s stop -x SIGINT
+print =============== check
+$null=
+
+system_content sh/checkValgrind.sh -n dnode1
+print cmd return result ----> [ $system_content ]
+if $system_content > 0 then
+ return -1
+endi
+
+if $system_content == $null then
+ return -1
+endi
diff --git a/tests/system-test/1-insert/time_range_wise.py b/tests/system-test/1-insert/time_range_wise.py
index 8f61da221d..c31d8d2547 100644
--- a/tests/system-test/1-insert/time_range_wise.py
+++ b/tests/system-test/1-insert/time_range_wise.py
@@ -293,7 +293,7 @@ class TDTestCase:
dbname = tdSql.getData(0,0)
tdSql.query("select * from information_schema.ins_databases")
for index , value in enumerate(tdSql.cursor.description):
- if value[0] == "retention":
+ if value[0] == "retentions":
r_index = index
break
for row in tdSql.queryResult:
diff --git a/tests/system-test/2-query/interp.py b/tests/system-test/2-query/interp.py
index 9348a8ca8f..934ba9e161 100644
--- a/tests/system-test/2-query/interp.py
+++ b/tests/system-test/2-query/interp.py
@@ -551,6 +551,29 @@ class TDTestCase:
tdSql.checkData(0, 0, 15)
tdSql.checkData(1, 0, 15)
+ tdLog.printNoPrefix("==========step9:test error cases")
+
+ tdSql.error(f"select interp(c0) from {dbname}.{tbname}")
+ tdSql.error(f"select interp(c0) from {dbname}.{tbname} range('2020-02-10 00:00:05', '2020-02-15 00:00:05')")
+ tdSql.error(f"select interp(c0) from {dbname}.{tbname} range('2020-02-10 00:00:05', '2020-02-15 00:00:05') every(1d)")
+ tdSql.error(f"select interp(c0) from {dbname}.{tbname} range('2020-02-10 00:00:05', '2020-02-15 00:00:05') fill(null)")
+ tdSql.error(f"select interp(c0) from {dbname}.{tbname} every(1s) fill(null)")
+ tdSql.error(f"select interp(c0) from {dbname}.{tbname} where ts >= '2020-02-10 00:00:05' and ts <= '2020-02-15 00:00:05' every(1s) fill(null)")
+
+ # input can only be numerical types
+ tdSql.error(f"select interp(ts) from {dbname}.{tbname} range('2020-02-10 00:00:05', '2020-02-15 00:00:05') every(1d) fill(null)")
+ tdSql.error(f"select interp(c6) from {dbname}.{tbname} range('2020-02-10 00:00:05', '2020-02-15 00:00:05') every(1d) fill(null)")
+ tdSql.error(f"select interp(c7) from {dbname}.{tbname} range('2020-02-10 00:00:05', '2020-02-15 00:00:05') every(1d) fill(null)")
+ tdSql.error(f"select interp(c8) from {dbname}.{tbname} range('2020-02-10 00:00:05', '2020-02-15 00:00:05') every(1d) fill(null)")
+
+ # input can only be columns
+ tdSql.error(f"select interp(1) from {dbname}.{tbname} range('2020-02-10 00:00:05', '2020-02-15 00:00:05') every(1d) fill(null)")
+ tdSql.error(f"select interp(1.5) from {dbname}.{tbname} range('2020-02-10 00:00:05', '2020-02-15 00:00:05') every(1d) fill(null)")
+ tdSql.error(f"select interp(true) from {dbname}.{tbname} range('2020-02-10 00:00:05', '2020-02-15 00:00:05') every(1d) fill(null)")
+ tdSql.error(f"select interp(false) from {dbname}.{tbname} range('2020-02-10 00:00:05', '2020-02-15 00:00:05') every(1d) fill(null)")
+ tdSql.error(f"select interp('abcd') from {dbname}.{tbname} range('2020-02-10 00:00:05', '2020-02-15 00:00:05') every(1d) fill(null)")
+ tdSql.error(f"select interp('中文字符') from {dbname}.{tbname} range('2020-02-10 00:00:05', '2020-02-15 00:00:05') every(1d) fill(null)")
+
def stop(self):
tdSql.close()
tdLog.success(f"{__file__} successfully executed")
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
index 25d6e33175..5eec174618 100644
--- a/tools/CMakeLists.txt
+++ b/tools/CMakeLists.txt
@@ -128,6 +128,7 @@ ELSE ()
COMMAND cmake -E copy ./taosadapter.service ${CMAKE_BINARY_DIR}/test/cfg/
COMMAND cmake -E copy taosadapter-debug ${CMAKE_BINARY_DIR}/build/bin
)
+ unset(_upx_prefix)
ELSEIF (TD_DARWIN)
include(ExternalProject)
ExternalProject_Add(taosadapter
@@ -149,8 +150,42 @@ ELSE ()
COMMAND cmake -E copy ./taosadapter.service ${CMAKE_BINARY_DIR}/test/cfg/
COMMAND cmake -E copy taosadapter-debug ${CMAKE_BINARY_DIR}/build/bin
)
+# unset(_upx_prefix)
+ ELSEIF (TD_WINDOWS)
+ include(ExternalProject)
+ set(_upx_prefix "${CMAKE_BINARY_DIR}/.taos/externals/upx")
+ ExternalProject_Add(upx
+ PREFIX "${_upx_prefix}"
+ URL https://github.com/upx/upx/releases/download/v3.96/upx-3.96-win32.zip
+ CONFIGURE_COMMAND cmake -E true
+ BUILD_COMMAND cmake -E true
+ INSTALL_COMMAND cmake -E true
+ )
+
+ ExternalProject_Add(taosadapter
+ PREFIX "taosadapter"
+ SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/taosadapter
+ BUILD_ALWAYS off
+ DEPENDS taos
+ BUILD_IN_SOURCE 1
+ CONFIGURE_COMMAND cmake -E echo "taosadapter no need cmake to config"
+ PATCH_COMMAND
+ COMMAND git clean -f -d
+ BUILD_COMMAND
+ COMMAND set CGO_CFLAGS=-I${CMAKE_CURRENT_SOURCE_DIR}/../include/client
+ COMMAND set CGO_LDFLAGS=-L${CMAKE_BINARY_DIR}/build/lib
+ COMMAND go build -a -o taosadapter.exe -ldflags "-s -w -X github.com/taosdata/taosadapter/version.Version=${taos_version} -X github.com/taosdata/taosadapter/version.CommitID=${taosadapter_commit_sha1}"
+ COMMAND go build -a -o taosadapter-debug.exe -ldflags "-X github.com/taosdata/taosadapter/version.Version=${taos_version} -X github.com/taosdata/taosadapter/version.CommitID=${taosadapter_commit_sha1}"
+ INSTALL_COMMAND
+ COMMAND ${_upx_prefix}/src/upx/upx taosadapter.exe
+ COMMAND cmake -E copy taosadapter.exe ${CMAKE_BINARY_DIR}/build/bin
+ COMMAND cmake -E make_directory ${CMAKE_BINARY_DIR}/test/cfg/
+ COMMAND cmake -E copy ./example/config/taosadapter.toml ${CMAKE_BINARY_DIR}/test/cfg/
+ COMMAND cmake -E copy ./taosadapter.service ${CMAKE_BINARY_DIR}/test/cfg/
+ COMMAND cmake -E copy taosadapter-debug.exe ${CMAKE_BINARY_DIR}/build/bin
+ )
unset(_upx_prefix)
ELSE ()
- MESSAGE("${Yellow} Windows system still use original embedded httpd ${ColourReset}")
+ MESSAGE("${Yellow} taosAdapter Not supported yet ${ColourReset}")
ENDIF ()
ENDIF ()