Merge branch 'develop' into 2.0
# Conflicts: # src/system/CMakeLists.txt # src/system/detail/CMakeLists.txt # src/system/lite/CMakeLists.txt # src/util/inc/textbuffer.h # src/vnode/detail/inc/vnodeTagMgmt.h # src/vnode/detail/src/vnodeQueryImpl.c # src/vnode/detail/src/vnodeSupertableQuery.c
This commit is contained in:
commit
7540c92f01
|
@ -36,7 +36,7 @@ ENDIF ()
|
||||||
IF (NOT DEFINED TD_CLUSTER)
|
IF (NOT DEFINED TD_CLUSTER)
|
||||||
MESSAGE(STATUS "Build the Lite Version")
|
MESSAGE(STATUS "Build the Lite Version")
|
||||||
SET(TD_CLUSTER FALSE)
|
SET(TD_CLUSTER FALSE)
|
||||||
SET(TD_LITE TRUE)
|
SET(TD_EDGE TRUE)
|
||||||
|
|
||||||
SET(TD_COMMUNITY_DIR ${PROJECT_SOURCE_DIR})
|
SET(TD_COMMUNITY_DIR ${PROJECT_SOURCE_DIR})
|
||||||
MESSAGE(STATUS "Community directory: " ${TD_COMMUNITY_DIR})
|
MESSAGE(STATUS "Community directory: " ${TD_COMMUNITY_DIR})
|
||||||
|
@ -53,12 +53,18 @@ IF (NOT DEFINED TD_CLUSTER)
|
||||||
SET(TD_MIPS_32 FALSE)
|
SET(TD_MIPS_32 FALSE)
|
||||||
SET(TD_DARWIN_64 FALSE)
|
SET(TD_DARWIN_64 FALSE)
|
||||||
SET(TD_WINDOWS_64 FALSE)
|
SET(TD_WINDOWS_64 FALSE)
|
||||||
|
SET(TD_PAGMODE_LITE FALSE)
|
||||||
|
|
||||||
|
IF (${PAGMODE} MATCHES "lite")
|
||||||
|
SET(TD_PAGMODE_LITE TRUE)
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
# if generate ARM version:
|
# if generate ARM version:
|
||||||
# cmake -DCPUTYPE=aarch32 .. or cmake -DCPUTYPE=aarch64
|
# cmake -DCPUTYPE=aarch32 .. or cmake -DCPUTYPE=aarch64
|
||||||
IF (${CPUTYPE} MATCHES "aarch32")
|
IF (${CPUTYPE} MATCHES "aarch32")
|
||||||
SET(TD_ARM TRUE)
|
SET(TD_ARM TRUE)
|
||||||
SET(TD_ARM_32 TRUE)
|
SET(TD_ARM_32 TRUE)
|
||||||
|
SET(TD_PAGMODE_LITE TRUE)
|
||||||
ADD_DEFINITIONS(-D_TD_ARM_)
|
ADD_DEFINITIONS(-D_TD_ARM_)
|
||||||
ADD_DEFINITIONS(-D_TD_ARM_32_)
|
ADD_DEFINITIONS(-D_TD_ARM_32_)
|
||||||
ELSEIF (${CPUTYPE} MATCHES "aarch64")
|
ELSEIF (${CPUTYPE} MATCHES "aarch64")
|
||||||
|
|
|
@ -130,3 +130,8 @@ The TDengine community has also kindly built some of their own connectors! Follo
|
||||||
# Contribute to TDengine
|
# Contribute to TDengine
|
||||||
|
|
||||||
Please follow the [contribution guidelines](CONTRIBUTING.md) to contribute to the project.
|
Please follow the [contribution guidelines](CONTRIBUTING.md) to contribute to the project.
|
||||||
|
|
||||||
|
# Join TDengine WeChat Group
|
||||||
|
|
||||||
|
Add WeChat “tdengine” to join the group,you can communicate with other users.
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ tags (location binary(20), type int)</code></pre>
|
||||||
<p>查看数据库内全部STable,及其相关信息,包括STable的名称、创建时间、列数量、标签(TAG)数量、通过该STable建表的数量。 </p></li>
|
<p>查看数据库内全部STable,及其相关信息,包括STable的名称、创建时间、列数量、标签(TAG)数量、通过该STable建表的数量。 </p></li>
|
||||||
<li><p>删除超级表</p>
|
<li><p>删除超级表</p>
|
||||||
<pre><code class="mysql language-mysql">DROP TABLE <stable_name></code></pre>
|
<pre><code class="mysql language-mysql">DROP TABLE <stable_name></code></pre>
|
||||||
<p>Note: 删除STable不会级联删除通过STable创建的表;相反删除STable时要求通过该STable创建的表都已经被删除。</p></li>
|
<p>Note: 删除STable时,所有通过该STable创建的表都将被删除。</p></li>
|
||||||
<li><p>查看属于某STable并满足查询条件的表</p>
|
<li><p>查看属于某STable并满足查询条件的表</p>
|
||||||
<pre><code class="mysql language-mysql">SELECT TBNAME,[TAG_NAME,…] FROM <stable_name> WHERE <tag_name> <[=|=<|>=|<>] values..> ([AND|OR] …)</code></pre>
|
<pre><code class="mysql language-mysql">SELECT TBNAME,[TAG_NAME,…] FROM <stable_name> WHERE <tag_name> <[=|=<|>=|<>] values..> ([AND|OR] …)</code></pre>
|
||||||
<p>查看属于某STable并满足查询条件的表。说明:TBNAME为关键词,显示通过STable建立的子表表名,查询过程中可以使用针对标签的条件。</p>
|
<p>查看属于某STable并满足查询条件的表。说明:TBNAME为关键词,显示通过STable建立的子表表名,查询过程中可以使用针对标签的条件。</p>
|
||||||
|
|
|
@ -73,7 +73,7 @@ INTERVAL(10M)</code></pre>
|
||||||
<p>It lists the STable's schema and tags</p>
|
<p>It lists the STable's schema and tags</p>
|
||||||
<a class='anchor' id='Drop-a-STable'></a><h3>Drop a STable</h3>
|
<a class='anchor' id='Drop-a-STable'></a><h3>Drop a STable</h3>
|
||||||
<pre><code class="mysql language-mysql">DROP TABLE <stable_name></code></pre>
|
<pre><code class="mysql language-mysql">DROP TABLE <stable_name></code></pre>
|
||||||
<p>To delete a STable, all the tables created via this STable shall be deleted first, otherwise, it will fail.</p>
|
<p>To delete a STable, all the tables created via this STable will be deleted.</p>
|
||||||
<a class='anchor' id='List-the-Associated-Tables-of-a-STable'></a><h3>List the Associated Tables of a STable</h3>
|
<a class='anchor' id='List-the-Associated-Tables-of-a-STable'></a><h3>List the Associated Tables of a STable</h3>
|
||||||
<pre><code class="mysql language-mysql">SELECT TBNAME,[TAG_NAME, ...] FROM <stable_name> WHERE <tag_name> <[=|=<|>=|<>] values..> ([AND|OR] ...)</code></pre>
|
<pre><code class="mysql language-mysql">SELECT TBNAME,[TAG_NAME, ...] FROM <stable_name> WHERE <tag_name> <[=|=<|>=|<>] values..> ([AND|OR] ...)</code></pre>
|
||||||
<p>It will list all the tables which satisfy the tag filter conditions. The tables are all created from this specific STable. TBNAME is a new keyword introduced, it is the table name associated with the STable. </p>
|
<p>It will list all the tables which satisfy the tag filter conditions. The tables are all created from this specific STable. TBNAME is a new keyword introduced, it is the table name associated with the STable. </p>
|
||||||
|
|
|
@ -72,10 +72,10 @@ sed -i "2c$debver" ${pkg_dir}/DEBIAN/control
|
||||||
|
|
||||||
if [ "$verMode" == "cluster" ]; then
|
if [ "$verMode" == "cluster" ]; then
|
||||||
debname="TDengine-server-"${tdengine_ver}-${osType}-${cpuType}
|
debname="TDengine-server-"${tdengine_ver}-${osType}-${cpuType}
|
||||||
elif [ "$verMode" == "lite" ]; then
|
elif [ "$verMode" == "edge" ]; then
|
||||||
debname="TDengine-server"-${tdengine_ver}-${osType}-${cpuType}
|
debname="TDengine-server"-${tdengine_ver}-${osType}-${cpuType}
|
||||||
else
|
else
|
||||||
echo "unknow verMode, nor cluster or lite"
|
echo "unknow verMode, nor cluster or edge"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
@ -5,15 +5,20 @@
|
||||||
set -e
|
set -e
|
||||||
#set -x
|
#set -x
|
||||||
|
|
||||||
# releash.sh -v [cluster | lite] -c [aarch32 | aarch64 | x64 | x86 | mips64 ...] -o [Linux | Kylin | Alpine | Raspberrypi | Darwin | Windows | ...] -V [stable | beta]
|
# releash.sh -v [cluster | edge]
|
||||||
|
# -c [aarch32 | aarch64 | x64 | x86 | mips64 ...]
|
||||||
|
# -o [Linux | Kylin | Alpine | Raspberrypi | Darwin | Windows | ...]
|
||||||
|
# -V [stable | beta]
|
||||||
|
# -l [full | lite]
|
||||||
|
|
||||||
# set parameters by default value
|
# set parameters by default value
|
||||||
verMode=lite # [cluster, lite]
|
verMode=edge # [cluster, edge]
|
||||||
verType=stable # [stable, beta]
|
verType=stable # [stable, beta]
|
||||||
cpuType=x64 # [aarch32 | aarch64 | x64 | x86 | mips64 ...]
|
cpuType=x64 # [aarch32 | aarch64 | x64 | x86 | mips64 ...]
|
||||||
osType=Linux # [Linux | Kylin | Alpine | Raspberrypi | Darwin | Windows | ...]
|
osType=Linux # [Linux | Kylin | Alpine | Raspberrypi | Darwin | Windows | ...]
|
||||||
|
pagMode=full # [full | lite]
|
||||||
|
|
||||||
while getopts "hv:V:c:o:" arg
|
while getopts "hv:V:c:o:l:" arg
|
||||||
do
|
do
|
||||||
case $arg in
|
case $arg in
|
||||||
v)
|
v)
|
||||||
|
@ -28,12 +33,16 @@ do
|
||||||
#echo "cpuType=$OPTARG"
|
#echo "cpuType=$OPTARG"
|
||||||
cpuType=$(echo $OPTARG)
|
cpuType=$(echo $OPTARG)
|
||||||
;;
|
;;
|
||||||
|
l)
|
||||||
|
#echo "pagMode=$OPTARG"
|
||||||
|
pagMode=$(echo $OPTARG)
|
||||||
|
;;
|
||||||
o)
|
o)
|
||||||
#echo "osType=$OPTARG"
|
#echo "osType=$OPTARG"
|
||||||
osType=$(echo $OPTARG)
|
osType=$(echo $OPTARG)
|
||||||
;;
|
;;
|
||||||
h)
|
h)
|
||||||
echo "Usage: `basename $0` -v [cluster | lite] -c [aarch32 | aarch64 | x64 | x86 | mips64 ...] -o [Linux | Kylin | Alpine | Raspberrypi | Darwin | Windows | ...] -V [stable | beta]"
|
echo "Usage: `basename $0` -v [cluster | edge] -c [aarch32 | aarch64 | x64 | x86 | mips64 ...] -o [Linux | Kylin | Alpine | Raspberrypi | Darwin | Windows | ...] -V [stable | beta] -l [full | lite]"
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
?) #unknow option
|
?) #unknow option
|
||||||
|
@ -43,7 +52,7 @@ do
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
echo "verMode=${verMode} verType=${verType} cpuType=${cpuType} osType=${osType}"
|
echo "verMode=${verMode} verType=${verType} cpuType=${cpuType} osType=${osType} pagMode=${pagMode}"
|
||||||
|
|
||||||
curr_dir=$(pwd)
|
curr_dir=$(pwd)
|
||||||
|
|
||||||
|
@ -193,7 +202,7 @@ cd ${compile_dir}
|
||||||
# check support cpu type
|
# check support cpu type
|
||||||
if [[ "$cpuType" == "x64" ]] || [[ "$cpuType" == "aarch64" ]] || [[ "$cpuType" == "aarch32" ]] || [[ "$cpuType" == "mips64" ]] ; then
|
if [[ "$cpuType" == "x64" ]] || [[ "$cpuType" == "aarch64" ]] || [[ "$cpuType" == "aarch32" ]] || [[ "$cpuType" == "mips64" ]] ; then
|
||||||
if [ "$verMode" != "cluster" ]; then
|
if [ "$verMode" != "cluster" ]; then
|
||||||
cmake ../ -DCPUTYPE=${cpuType}
|
cmake ../ -DCPUTYPE=${cpuType} -DPAGMODE=${pagMode}
|
||||||
else
|
else
|
||||||
cmake ../../ -DCPUTYPE=${cpuType}
|
cmake ../../ -DCPUTYPE=${cpuType}
|
||||||
fi
|
fi
|
||||||
|
@ -235,8 +244,8 @@ if [ "$osType" != "Darwin" ]; then
|
||||||
echo "====do tar.gz package for all systems===="
|
echo "====do tar.gz package for all systems===="
|
||||||
cd ${script_dir}/tools
|
cd ${script_dir}/tools
|
||||||
|
|
||||||
${csudo} ./makepkg.sh ${compile_dir} ${version} "${build_time}" ${cpuType} ${osType} ${verMode} ${verType}
|
${csudo} ./makepkg.sh ${compile_dir} ${version} "${build_time}" ${cpuType} ${osType} ${verMode} ${verType} ${pagMode}
|
||||||
${csudo} ./makeclient.sh ${compile_dir} ${version} "${build_time}" ${cpuType} ${osType} ${verMode} ${verType}
|
${csudo} ./makeclient.sh ${compile_dir} ${version} "${build_time}" ${cpuType} ${osType} ${verMode} ${verType} ${pagMode}
|
||||||
else
|
else
|
||||||
cd ${script_dir}/tools
|
cd ${script_dir}/tools
|
||||||
./makeclient.sh ${compile_dir} ${version} "${build_time}" ${cpuType} ${osType} ${verMode} ${verType}
|
./makeclient.sh ${compile_dir} ${version} "${build_time}" ${cpuType} ${osType} ${verMode} ${verType}
|
||||||
|
|
|
@ -65,10 +65,10 @@ cp_rpm_package ${pkg_dir}/RPMS
|
||||||
|
|
||||||
if [ "$verMode" == "cluster" ]; then
|
if [ "$verMode" == "cluster" ]; then
|
||||||
rpmname="TDengine-server-"${tdengine_ver}-${osType}-${cpuType}
|
rpmname="TDengine-server-"${tdengine_ver}-${osType}-${cpuType}
|
||||||
elif [ "$verMode" == "lite" ]; then
|
elif [ "$verMode" == "edge" ]; then
|
||||||
rpmname="TDengine-server"-${tdengine_ver}-${osType}-${cpuType}
|
rpmname="TDengine-server"-${tdengine_ver}-${osType}-${cpuType}
|
||||||
else
|
else
|
||||||
echo "unknow verMode, nor cluster or lite"
|
echo "unknow verMode, nor cluster or edge"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,8 @@
|
||||||
set -e
|
set -e
|
||||||
#set -x
|
#set -x
|
||||||
|
|
||||||
verMode=lite
|
verMode=edge
|
||||||
|
pagMode=full
|
||||||
|
|
||||||
# -----------------------Variables definition---------------------
|
# -----------------------Variables definition---------------------
|
||||||
script_dir=$(dirname $(readlink -f "$0"))
|
script_dir=$(dirname $(readlink -f "$0"))
|
||||||
|
@ -479,7 +480,9 @@ function update_TDengine() {
|
||||||
install_log
|
install_log
|
||||||
install_header
|
install_header
|
||||||
install_lib
|
install_lib
|
||||||
|
if [ "$pagMode" != "lite" ]; then
|
||||||
install_connector
|
install_connector
|
||||||
|
fi
|
||||||
install_examples
|
install_examples
|
||||||
if [ -z $1 ]; then
|
if [ -z $1 ]; then
|
||||||
install_bin
|
install_bin
|
||||||
|
@ -554,7 +557,9 @@ function install_TDengine() {
|
||||||
install_log
|
install_log
|
||||||
install_header
|
install_header
|
||||||
install_lib
|
install_lib
|
||||||
|
if [ "$pagMode" != "lite" ]; then
|
||||||
install_connector
|
install_connector
|
||||||
|
fi
|
||||||
install_examples
|
install_examples
|
||||||
|
|
||||||
if [ -z $1 ]; then # install service and client
|
if [ -z $1 ]; then # install service and client
|
||||||
|
|
|
@ -9,6 +9,7 @@ set -e
|
||||||
# -----------------------Variables definition---------------------
|
# -----------------------Variables definition---------------------
|
||||||
|
|
||||||
osType=Linux
|
osType=Linux
|
||||||
|
pagMode=full
|
||||||
|
|
||||||
if [ "$osType" != "Darwin" ]; then
|
if [ "$osType" != "Darwin" ]; then
|
||||||
script_dir=$(dirname $(readlink -f "$0"))
|
script_dir=$(dirname $(readlink -f "$0"))
|
||||||
|
@ -180,7 +181,9 @@ function update_TDengine() {
|
||||||
install_log
|
install_log
|
||||||
install_header
|
install_header
|
||||||
install_lib
|
install_lib
|
||||||
|
if [ "$pagMode" != "lite" ]; then
|
||||||
install_connector
|
install_connector
|
||||||
|
fi
|
||||||
install_examples
|
install_examples
|
||||||
install_bin
|
install_bin
|
||||||
install_config
|
install_config
|
||||||
|
@ -205,7 +208,9 @@ function install_TDengine() {
|
||||||
install_log
|
install_log
|
||||||
install_header
|
install_header
|
||||||
install_lib
|
install_lib
|
||||||
|
if [ "$pagMode" != "lite" ]; then
|
||||||
install_connector
|
install_connector
|
||||||
|
fi
|
||||||
install_examples
|
install_examples
|
||||||
install_bin
|
install_bin
|
||||||
install_config
|
install_config
|
||||||
|
|
|
@ -12,6 +12,7 @@ cpuType=$4
|
||||||
osType=$5
|
osType=$5
|
||||||
verMode=$6
|
verMode=$6
|
||||||
verType=$7
|
verType=$7
|
||||||
|
pagMode=$8
|
||||||
|
|
||||||
if [ "$osType" != "Darwin" ]; then
|
if [ "$osType" != "Darwin" ]; then
|
||||||
script_dir="$(dirname $(readlink -f $0))"
|
script_dir="$(dirname $(readlink -f $0))"
|
||||||
|
@ -39,7 +40,13 @@ fi
|
||||||
# Directories and files.
|
# Directories and files.
|
||||||
|
|
||||||
if [ "$osType" != "Darwin" ]; then
|
if [ "$osType" != "Darwin" ]; then
|
||||||
|
if [ "$pagMode" == "lite" ]; then
|
||||||
|
strip ${build_dir}/bin/taosd
|
||||||
|
strip ${build_dir}/bin/taos
|
||||||
|
bin_files="${build_dir}/bin/taos ${script_dir}/remove_client.sh"
|
||||||
|
else
|
||||||
bin_files="${build_dir}/bin/taos ${build_dir}/bin/taosdump ${script_dir}/remove_client.sh"
|
bin_files="${build_dir}/bin/taos ${build_dir}/bin/taosdump ${script_dir}/remove_client.sh"
|
||||||
|
fi
|
||||||
lib_files="${build_dir}/lib/libtaos.so.${version}"
|
lib_files="${build_dir}/lib/libtaos.so.${version}"
|
||||||
else
|
else
|
||||||
bin_files="${build_dir}/bin/taos ${script_dir}/remove_client.sh"
|
bin_files="${build_dir}/bin/taos ${script_dir}/remove_client.sh"
|
||||||
|
@ -74,18 +81,23 @@ if [ "$osType" == "Darwin" ]; then
|
||||||
sed 's/osType=Linux/osType=Darwin/g' ${install_dir}/install_client.sh >> install_client_temp.sh
|
sed 's/osType=Linux/osType=Darwin/g' ${install_dir}/install_client.sh >> install_client_temp.sh
|
||||||
mv install_client_temp.sh ${install_dir}/install_client.sh
|
mv install_client_temp.sh ${install_dir}/install_client.sh
|
||||||
fi
|
fi
|
||||||
|
if [ "$pagMode" == "lite" ]; then
|
||||||
|
sed 's/pagMode=full/pagMode=lite/g' ${install_dir}/install_client.sh >> install_client_temp.sh
|
||||||
|
mv install_client_temp.sh ${install_dir}/install_client.sh
|
||||||
|
fi
|
||||||
chmod a+x ${install_dir}/install_client.sh
|
chmod a+x ${install_dir}/install_client.sh
|
||||||
|
|
||||||
# Copy example code
|
# Copy example code
|
||||||
mkdir -p ${install_dir}/examples
|
mkdir -p ${install_dir}/examples
|
||||||
examples_dir="${top_dir}/tests/examples"
|
examples_dir="${top_dir}/tests/examples"
|
||||||
cp -r ${examples_dir}/c ${install_dir}/examples
|
cp -r ${examples_dir}/c ${install_dir}/examples
|
||||||
cp -r ${examples_dir}/JDBC ${install_dir}/examples
|
if [[ "$pagMode" != "lite" ]] && [[ "$cpuType" != "aarch32" ]]; then
|
||||||
cp -r ${examples_dir}/matlab ${install_dir}/examples
|
cp -r ${examples_dir}/JDBC ${install_dir}/examples
|
||||||
cp -r ${examples_dir}/python ${install_dir}/examples
|
cp -r ${examples_dir}/matlab ${install_dir}/examples
|
||||||
cp -r ${examples_dir}/R ${install_dir}/examples
|
cp -r ${examples_dir}/python ${install_dir}/examples
|
||||||
cp -r ${examples_dir}/go ${install_dir}/examples
|
cp -r ${examples_dir}/R ${install_dir}/examples
|
||||||
|
cp -r ${examples_dir}/go ${install_dir}/examples
|
||||||
|
fi
|
||||||
# Copy driver
|
# Copy driver
|
||||||
mkdir -p ${install_dir}/driver
|
mkdir -p ${install_dir}/driver
|
||||||
cp ${lib_files} ${install_dir}/driver
|
cp ${lib_files} ${install_dir}/driver
|
||||||
|
@ -94,13 +106,14 @@ cp ${lib_files} ${install_dir}/driver
|
||||||
connector_dir="${code_dir}/connector"
|
connector_dir="${code_dir}/connector"
|
||||||
mkdir -p ${install_dir}/connector
|
mkdir -p ${install_dir}/connector
|
||||||
|
|
||||||
if [ "$osType" != "Darwin" ]; then
|
if [[ "$pagMode" != "lite" ]] && [[ "$cpuType" != "aarch32" ]]; then
|
||||||
|
if [ "$osType" != "Darwin" ]; then
|
||||||
cp ${build_dir}/lib/*.jar ${install_dir}/connector
|
cp ${build_dir}/lib/*.jar ${install_dir}/connector
|
||||||
|
fi
|
||||||
|
cp -r ${connector_dir}/grafana ${install_dir}/connector/
|
||||||
|
cp -r ${connector_dir}/python ${install_dir}/connector/
|
||||||
|
cp -r ${connector_dir}/go ${install_dir}/connector
|
||||||
fi
|
fi
|
||||||
cp -r ${connector_dir}/grafana ${install_dir}/connector/
|
|
||||||
cp -r ${connector_dir}/python ${install_dir}/connector/
|
|
||||||
cp -r ${connector_dir}/go ${install_dir}/connector
|
|
||||||
|
|
||||||
# Copy release note
|
# Copy release note
|
||||||
# cp ${script_dir}/release_note ${install_dir}
|
# cp ${script_dir}/release_note ${install_dir}
|
||||||
|
|
||||||
|
@ -110,13 +123,17 @@ cd ${release_dir}
|
||||||
|
|
||||||
if [ "$verMode" == "cluster" ]; then
|
if [ "$verMode" == "cluster" ]; then
|
||||||
pkg_name=${install_dir}-${version}-${osType}-${cpuType}
|
pkg_name=${install_dir}-${version}-${osType}-${cpuType}
|
||||||
elif [ "$verMode" == "lite" ]; then
|
elif [ "$verMode" == "edge" ]; then
|
||||||
pkg_name=${install_dir}-${version}-${osType}-${cpuType}
|
pkg_name=${install_dir}-${version}-${osType}-${cpuType}
|
||||||
else
|
else
|
||||||
echo "unknow verMode, nor cluster or lite"
|
echo "unknow verMode, nor cluster or edge"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "$pagMode" == "lite" ]; then
|
||||||
|
pkg_name=${pkg_name}-Lite
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "$verType" == "beta" ]; then
|
if [ "$verType" == "beta" ]; then
|
||||||
pkg_name=${pkg_name}-${verType}
|
pkg_name=${pkg_name}-${verType}
|
||||||
elif [ "$verType" == "stable" ]; then
|
elif [ "$verType" == "stable" ]; then
|
||||||
|
|
|
@ -13,6 +13,7 @@ cpuType=$4
|
||||||
osType=$5
|
osType=$5
|
||||||
verMode=$6
|
verMode=$6
|
||||||
verType=$7
|
verType=$7
|
||||||
|
pagMode=$8
|
||||||
|
|
||||||
script_dir="$(dirname $(readlink -f $0))"
|
script_dir="$(dirname $(readlink -f $0))"
|
||||||
top_dir="$(readlink -f ${script_dir}/../..)"
|
top_dir="$(readlink -f ${script_dir}/../..)"
|
||||||
|
@ -30,7 +31,14 @@ else
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Directories and files.
|
# Directories and files.
|
||||||
bin_files="${build_dir}/bin/taosd ${build_dir}/bin/taos ${build_dir}/bin/taosdemo ${build_dir}/bin/taosdump ${script_dir}/remove.sh"
|
if [ "$pagMode" == "lite" ]; then
|
||||||
|
strip ${build_dir}/bin/taosd
|
||||||
|
strip ${build_dir}/bin/taos
|
||||||
|
bin_files="${build_dir}/bin/taosd ${build_dir}/bin/taos ${script_dir}/remove.sh"
|
||||||
|
else
|
||||||
|
bin_files="${build_dir}/bin/taosd ${build_dir}/bin/taos ${build_dir}/bin/taosdemo ${build_dir}/bin/taosdump ${script_dir}/remove.sh"
|
||||||
|
fi
|
||||||
|
|
||||||
lib_files="${build_dir}/lib/libtaos.so.${version}"
|
lib_files="${build_dir}/lib/libtaos.so.${version}"
|
||||||
header_files="${code_dir}/inc/taos.h ${code_dir}/inc/taoserror.h"
|
header_files="${code_dir}/inc/taos.h ${code_dir}/inc/taoserror.h"
|
||||||
cfg_dir="${top_dir}/packaging/cfg"
|
cfg_dir="${top_dir}/packaging/cfg"
|
||||||
|
@ -56,6 +64,9 @@ mkdir -p ${install_dir}/init.d && cp ${init_file_deb} ${install_dir}/init.d/taos
|
||||||
mkdir -p ${install_dir}/init.d && cp ${init_file_rpm} ${install_dir}/init.d/taosd.rpm
|
mkdir -p ${install_dir}/init.d && cp ${init_file_rpm} ${install_dir}/init.d/taosd.rpm
|
||||||
|
|
||||||
if [ "$verMode" == "cluster" ]; then
|
if [ "$verMode" == "cluster" ]; then
|
||||||
|
sed 's/verMode=edge/verMode=cluster/g' ${install_dir}/bin/remove.sh >> remove_temp.sh
|
||||||
|
mv remove_temp.sh ${install_dir}/bin/remove.sh
|
||||||
|
|
||||||
mkdir -p ${install_dir}/nginxd && cp -r ${nginx_dir}/* ${install_dir}/nginxd
|
mkdir -p ${install_dir}/nginxd && cp -r ${nginx_dir}/* ${install_dir}/nginxd
|
||||||
cp ${nginx_dir}/png/taos.png ${install_dir}/nginxd/admin/images/taos.png
|
cp ${nginx_dir}/png/taos.png ${install_dir}/nginxd/admin/images/taos.png
|
||||||
rm -rf ${install_dir}/nginxd/png
|
rm -rf ${install_dir}/nginxd/png
|
||||||
|
@ -70,11 +81,20 @@ fi
|
||||||
|
|
||||||
cd ${install_dir}
|
cd ${install_dir}
|
||||||
tar -zcv -f taos.tar.gz * --remove-files || :
|
tar -zcv -f taos.tar.gz * --remove-files || :
|
||||||
|
exitcode=$?
|
||||||
|
if [ "$exitcode" != "0" ]; then
|
||||||
|
echo "tar taos.tar.gz error !!!"
|
||||||
|
exit $exitcode
|
||||||
|
fi
|
||||||
|
|
||||||
cd ${curr_dir}
|
cd ${curr_dir}
|
||||||
cp ${install_files} ${install_dir}
|
cp ${install_files} ${install_dir}
|
||||||
if [ "$verMode" == "cluster" ]; then
|
if [ "$verMode" == "cluster" ]; then
|
||||||
sed 's/verMode=lite/verMode=cluster/g' ${install_dir}/install.sh >> install_temp.sh
|
sed 's/verMode=edge/verMode=cluster/g' ${install_dir}/install.sh >> install_temp.sh
|
||||||
|
mv install_temp.sh ${install_dir}/install.sh
|
||||||
|
fi
|
||||||
|
if [ "$pagMode" == "lite" ]; then
|
||||||
|
sed 's/pagMode=full/pagMode=lite/g' ${install_dir}/install.sh >> install_temp.sh
|
||||||
mv install_temp.sh ${install_dir}/install.sh
|
mv install_temp.sh ${install_dir}/install.sh
|
||||||
fi
|
fi
|
||||||
chmod a+x ${install_dir}/install.sh
|
chmod a+x ${install_dir}/install.sh
|
||||||
|
@ -82,13 +102,14 @@ chmod a+x ${install_dir}/install.sh
|
||||||
# Copy example code
|
# Copy example code
|
||||||
mkdir -p ${install_dir}/examples
|
mkdir -p ${install_dir}/examples
|
||||||
examples_dir="${top_dir}/tests/examples"
|
examples_dir="${top_dir}/tests/examples"
|
||||||
cp -r ${examples_dir}/c ${install_dir}/examples
|
cp -r ${examples_dir}/c ${install_dir}/examples
|
||||||
cp -r ${examples_dir}/JDBC ${install_dir}/examples
|
if [[ "$pagMode" != "lite" ]] && [[ "$cpuType" != "aarch32" ]]; then
|
||||||
cp -r ${examples_dir}/matlab ${install_dir}/examples
|
cp -r ${examples_dir}/JDBC ${install_dir}/examples
|
||||||
cp -r ${examples_dir}/python ${install_dir}/examples
|
cp -r ${examples_dir}/matlab ${install_dir}/examples
|
||||||
cp -r ${examples_dir}/R ${install_dir}/examples
|
cp -r ${examples_dir}/python ${install_dir}/examples
|
||||||
cp -r ${examples_dir}/go ${install_dir}/examples
|
cp -r ${examples_dir}/R ${install_dir}/examples
|
||||||
|
cp -r ${examples_dir}/go ${install_dir}/examples
|
||||||
|
fi
|
||||||
# Copy driver
|
# Copy driver
|
||||||
mkdir -p ${install_dir}/driver
|
mkdir -p ${install_dir}/driver
|
||||||
cp ${lib_files} ${install_dir}/driver
|
cp ${lib_files} ${install_dir}/driver
|
||||||
|
@ -96,11 +117,12 @@ cp ${lib_files} ${install_dir}/driver
|
||||||
# Copy connector
|
# Copy connector
|
||||||
connector_dir="${code_dir}/connector"
|
connector_dir="${code_dir}/connector"
|
||||||
mkdir -p ${install_dir}/connector
|
mkdir -p ${install_dir}/connector
|
||||||
cp ${build_dir}/lib/*.jar ${install_dir}/connector
|
if [[ "$pagMode" != "lite" ]] && [[ "$cpuType" != "aarch32" ]]; then
|
||||||
cp -r ${connector_dir}/grafana ${install_dir}/connector/
|
cp ${build_dir}/lib/*.jar ${install_dir}/connector
|
||||||
cp -r ${connector_dir}/python ${install_dir}/connector/
|
cp -r ${connector_dir}/grafana ${install_dir}/connector/
|
||||||
cp -r ${connector_dir}/go ${install_dir}/connector
|
cp -r ${connector_dir}/python ${install_dir}/connector/
|
||||||
|
cp -r ${connector_dir}/go ${install_dir}/connector
|
||||||
|
fi
|
||||||
# Copy release note
|
# Copy release note
|
||||||
# cp ${script_dir}/release_note ${install_dir}
|
# cp ${script_dir}/release_note ${install_dir}
|
||||||
|
|
||||||
|
@ -110,13 +132,17 @@ cd ${release_dir}
|
||||||
|
|
||||||
if [ "$verMode" == "cluster" ]; then
|
if [ "$verMode" == "cluster" ]; then
|
||||||
pkg_name=${install_dir}-${version}-${osType}-${cpuType}
|
pkg_name=${install_dir}-${version}-${osType}-${cpuType}
|
||||||
elif [ "$verMode" == "lite" ]; then
|
elif [ "$verMode" == "edge" ]; then
|
||||||
pkg_name=${install_dir}-${version}-${osType}-${cpuType}
|
pkg_name=${install_dir}-${version}-${osType}-${cpuType}
|
||||||
else
|
else
|
||||||
echo "unknow verMode, nor cluster or lite"
|
echo "unknow verMode, nor cluster or edge"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "$pagMode" == "lite" ]; then
|
||||||
|
pkg_name=${pkg_name}-Lite
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "$verType" == "beta" ]; then
|
if [ "$verType" == "beta" ]; then
|
||||||
pkg_name=${pkg_name}-${verType}
|
pkg_name=${pkg_name}-${verType}
|
||||||
elif [ "$verType" == "stable" ]; then
|
elif [ "$verType" == "stable" ]; then
|
||||||
|
@ -127,5 +153,10 @@ else
|
||||||
fi
|
fi
|
||||||
|
|
||||||
tar -zcv -f "$(basename ${pkg_name}).tar.gz" $(basename ${install_dir}) --remove-files || :
|
tar -zcv -f "$(basename ${pkg_name}).tar.gz" $(basename ${install_dir}) --remove-files || :
|
||||||
|
exitcode=$?
|
||||||
|
if [ "$exitcode" != "0" ]; then
|
||||||
|
echo "tar ${pkg_name}.tar.gz error !!!"
|
||||||
|
exit $exitcode
|
||||||
|
fi
|
||||||
|
|
||||||
cd ${curr_dir}
|
cd ${curr_dir}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
set -e
|
set -e
|
||||||
#set -x
|
#set -x
|
||||||
|
|
||||||
verMode=lite
|
verMode=edge
|
||||||
|
|
||||||
RED='\033[0;31m'
|
RED='\033[0;31m'
|
||||||
GREEN='\033[1;32m'
|
GREEN='\033[1;32m'
|
||||||
|
|
|
@ -68,7 +68,7 @@ typedef struct SLocalReducer {
|
||||||
bool hasPrevRow; // cannot be released
|
bool hasPrevRow; // cannot be released
|
||||||
bool hasUnprocessedRow;
|
bool hasUnprocessedRow;
|
||||||
tOrderDescriptor * pDesc;
|
tOrderDescriptor * pDesc;
|
||||||
tColModel * resColModel;
|
SColumnModel * resColModel;
|
||||||
tExtMemBuffer ** pExtMemBuffer; // disk-based buffer
|
tExtMemBuffer ** pExtMemBuffer; // disk-based buffer
|
||||||
SInterpolationInfo interpolationInfo; // interpolation support structure
|
SInterpolationInfo interpolationInfo; // interpolation support structure
|
||||||
char * pFinalRes; // result data after interpo
|
char * pFinalRes; // result data after interpo
|
||||||
|
@ -92,7 +92,7 @@ typedef struct SSubqueryState {
|
||||||
typedef struct SRetrieveSupport {
|
typedef struct SRetrieveSupport {
|
||||||
tExtMemBuffer ** pExtMemBuffer; // for build loser tree
|
tExtMemBuffer ** pExtMemBuffer; // for build loser tree
|
||||||
tOrderDescriptor *pOrderDescriptor;
|
tOrderDescriptor *pOrderDescriptor;
|
||||||
tColModel * pFinalColModel; // colModel for final result
|
SColumnModel * pFinalColModel; // colModel for final result
|
||||||
SSubqueryState * pState;
|
SSubqueryState * pState;
|
||||||
int32_t subqueryIndex; // index of current vnode in vnode list
|
int32_t subqueryIndex; // index of current vnode in vnode list
|
||||||
SSqlObj * pParentSqlObj;
|
SSqlObj * pParentSqlObj;
|
||||||
|
@ -102,9 +102,9 @@ typedef struct SRetrieveSupport {
|
||||||
} SRetrieveSupport;
|
} SRetrieveSupport;
|
||||||
|
|
||||||
int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOrderDescriptor **pDesc,
|
int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOrderDescriptor **pDesc,
|
||||||
tColModel **pFinalModel, uint32_t nBufferSize);
|
SColumnModel **pFinalModel, uint32_t nBufferSize);
|
||||||
|
|
||||||
void tscLocalReducerEnvDestroy(tExtMemBuffer **pMemBuffer, tOrderDescriptor *pDesc, tColModel *pFinalModel,
|
void tscLocalReducerEnvDestroy(tExtMemBuffer **pMemBuffer, tOrderDescriptor *pDesc, SColumnModel *pFinalModel,
|
||||||
int32_t numOfVnodes);
|
int32_t numOfVnodes);
|
||||||
|
|
||||||
int32_t saveToBuffer(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tFilePage *pPage, void *data,
|
int32_t saveToBuffer(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tFilePage *pPage, void *data,
|
||||||
|
@ -116,7 +116,7 @@ int32_t tscFlushTmpBuffer(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tF
|
||||||
* create local reducer to launch the second-stage reduce process at client site
|
* create local reducer to launch the second-stage reduce process at client site
|
||||||
*/
|
*/
|
||||||
void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrderDescriptor *pDesc,
|
void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrderDescriptor *pDesc,
|
||||||
tColModel *finalModel, SSqlCmd *pSqlCmd, SSqlRes *pRes);
|
SColumnModel *finalModel, SSqlCmd *pSqlCmd, SSqlRes *pRes);
|
||||||
|
|
||||||
void tscDestroyLocalReducer(SSqlObj *pSql);
|
void tscDestroyLocalReducer(SSqlObj *pSql);
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "ttime.h"
|
#include "ttime.h"
|
||||||
#include "ttypes.h"
|
#include "ttypes.h"
|
||||||
#include "tutil.h"
|
#include "tutil.h"
|
||||||
|
#include "tpercentile.h"
|
||||||
|
|
||||||
#define GET_INPUT_CHAR(x) (((char *)((x)->aInputElemBuf)) + ((x)->startOffset) * ((x)->inputBytes))
|
#define GET_INPUT_CHAR(x) (((char *)((x)->aInputElemBuf)) + ((x)->startOffset) * ((x)->inputBytes))
|
||||||
#define GET_INPUT_CHAR_INDEX(x, y) (GET_INPUT_CHAR(x) + (y) * (x)->inputBytes)
|
#define GET_INPUT_CHAR_INDEX(x, y) (GET_INPUT_CHAR(x) + (y) * (x)->inputBytes)
|
||||||
|
@ -220,7 +221,7 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
|
||||||
} else if (functionId == TSDB_FUNC_TWA) {
|
} else if (functionId == TSDB_FUNC_TWA) {
|
||||||
*type = TSDB_DATA_TYPE_DOUBLE;
|
*type = TSDB_DATA_TYPE_DOUBLE;
|
||||||
*bytes = sizeof(STwaInfo);
|
*bytes = sizeof(STwaInfo);
|
||||||
*intermediateResBytes = sizeof(STwaInfo);
|
*intermediateResBytes = *bytes;
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -271,7 +272,6 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
|
||||||
} else if (functionId == TSDB_FUNC_PERCT) {
|
} else if (functionId == TSDB_FUNC_PERCT) {
|
||||||
*type = (int16_t)TSDB_DATA_TYPE_DOUBLE;
|
*type = (int16_t)TSDB_DATA_TYPE_DOUBLE;
|
||||||
*bytes = (int16_t)sizeof(double);
|
*bytes = (int16_t)sizeof(double);
|
||||||
//*intermediateResBytes = POINTER_BYTES;
|
|
||||||
*intermediateResBytes = (int16_t)sizeof(double);
|
*intermediateResBytes = (int16_t)sizeof(double);
|
||||||
} else if (functionId == TSDB_FUNC_LEASTSQR) {
|
} else if (functionId == TSDB_FUNC_LEASTSQR) {
|
||||||
*type = TSDB_DATA_TYPE_BINARY;
|
*type = TSDB_DATA_TYPE_BINARY;
|
||||||
|
@ -1878,6 +1878,7 @@ static void do_top_function_add(STopBotInfo *pInfo, int32_t maxLen, void *pData,
|
||||||
tVariantCreateFromBinary(&val, pData, tDataTypeDesc[type].nSize, type);
|
tVariantCreateFromBinary(&val, pData, tDataTypeDesc[type].nSize, type);
|
||||||
|
|
||||||
tValuePair **pList = pInfo->res;
|
tValuePair **pList = pInfo->res;
|
||||||
|
assert(pList != NULL);
|
||||||
|
|
||||||
if (pInfo->num < maxLen) {
|
if (pInfo->num < maxLen) {
|
||||||
if (pInfo->num == 0 ||
|
if (pInfo->num == 0 ||
|
||||||
|
@ -2416,7 +2417,7 @@ static bool percentile_function_setup(SQLFunctionCtx *pCtx) {
|
||||||
SResultInfo *pResInfo = GET_RES_INFO(pCtx);
|
SResultInfo *pResInfo = GET_RES_INFO(pCtx);
|
||||||
SSchema field[1] = {{pCtx->inputType, "dummyCol", 0, pCtx->inputBytes}};
|
SSchema field[1] = {{pCtx->inputType, "dummyCol", 0, pCtx->inputBytes}};
|
||||||
|
|
||||||
tColModel *pModel = tColModelCreate(field, 1, 1000);
|
SColumnModel *pModel = createColumnModel(field, 1, 1000);
|
||||||
int32_t orderIdx = 0;
|
int32_t orderIdx = 0;
|
||||||
|
|
||||||
// tOrderDesc object
|
// tOrderDesc object
|
||||||
|
|
|
@ -321,7 +321,7 @@ int32_t tsParseOneColumnData(SSchema *pSchema, SSQLToken *pToken, char *payload,
|
||||||
if (pToken->type == TK_NULL) {
|
if (pToken->type == TK_NULL) {
|
||||||
*(uint32_t *)payload = TSDB_DATA_NCHAR_NULL;
|
*(uint32_t *)payload = TSDB_DATA_NCHAR_NULL;
|
||||||
} else {
|
} else {
|
||||||
// if the converted output len is over than pSchema->bytes, return error: 'Argument list too long'
|
// if the converted output len is over than pColumnModel->bytes, return error: 'Argument list too long'
|
||||||
if (!taosMbsToUcs4(pToken->z, pToken->n, payload, pSchema->bytes)) {
|
if (!taosMbsToUcs4(pToken->z, pToken->n, payload, pSchema->bytes)) {
|
||||||
char buf[512] = {0};
|
char buf[512] = {0};
|
||||||
snprintf(buf, 512, "%s", strerror(errno));
|
snprintf(buf, 512, "%s", strerror(errno));
|
||||||
|
|
|
@ -72,7 +72,7 @@ static void setColumnOffsetValueInResultset(SQueryInfo* pQueryInfo);
|
||||||
static int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, tVariantList* pList, SSqlCmd* pCmd);
|
static int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, tVariantList* pList, SSqlCmd* pCmd);
|
||||||
|
|
||||||
static int32_t parseIntervalClause(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql);
|
static int32_t parseIntervalClause(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql);
|
||||||
static int32_t setSlidingClause(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql);
|
static int32_t parseSlidingClause(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql);
|
||||||
|
|
||||||
static int32_t addProjectionExprAndResultField(SQueryInfo* pQueryInfo, tSQLExprItem* pItem);
|
static int32_t addProjectionExprAndResultField(SQueryInfo* pQueryInfo, tSQLExprItem* pItem);
|
||||||
|
|
||||||
|
@ -657,14 +657,14 @@ int32_t parseIntervalClause(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setSlidingClause(pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
|
if (parseSlidingClause(pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
|
||||||
return TSDB_CODE_INVALID_SQL;
|
return TSDB_CODE_INVALID_SQL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t setSlidingClause(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
|
int32_t parseSlidingClause(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
|
||||||
const char* msg0 = "sliding value too small";
|
const char* msg0 = "sliding value too small";
|
||||||
const char* msg1 = "sliding value no larger than the interval value";
|
const char* msg1 = "sliding value no larger than the interval value";
|
||||||
|
|
||||||
|
@ -685,7 +685,7 @@ int32_t setSlidingClause(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
|
||||||
return invalidSqlErrMsg(pQueryInfo->msg, msg1);
|
return invalidSqlErrMsg(pQueryInfo->msg, msg1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pSliding->n = pQueryInfo->nAggTimeInterval;
|
pQueryInfo->nSlidingTime = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
@ -5453,8 +5453,6 @@ int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) {
|
||||||
const char* msg0 = "invalid table name";
|
const char* msg0 = "invalid table name";
|
||||||
const char* msg1 = "table name too long";
|
const char* msg1 = "table name too long";
|
||||||
const char* msg2 = "point interpolation query needs timestamp";
|
const char* msg2 = "point interpolation query needs timestamp";
|
||||||
const char* msg3 = "sliding value too small";
|
|
||||||
const char* msg4 = "sliding value no larger than the interval value";
|
|
||||||
const char* msg5 = "fill only available for interval query";
|
const char* msg5 = "fill only available for interval query";
|
||||||
const char* msg6 = "start(end) time of query range required or time range too large";
|
const char* msg6 = "start(end) time of query range required or time range too large";
|
||||||
const char* msg7 = "illegal number of tables in from clause";
|
const char* msg7 = "illegal number of tables in from clause";
|
||||||
|
@ -5588,30 +5586,6 @@ int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) {
|
||||||
return invalidSqlErrMsg(pQueryInfo->msg, msg2);
|
return invalidSqlErrMsg(pQueryInfo->msg, msg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// // set sliding value, the query time range needs to be decide in the first place
|
|
||||||
// SSQLToken* pSliding = &pQuerySql->sliding;
|
|
||||||
// if (pSliding->n != 0) {
|
|
||||||
// if (!tscEmbedded && pCmd->inStream == 0 && hasDefaultQueryTimeRange(pQueryInfo)) { // sliding only allowed in stream
|
|
||||||
// const char* msg = "time range expected for sliding window query";
|
|
||||||
// return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// getTimestampInUsFromStr(pSliding->z, pSliding->n, &pQueryInfo->nSlidingTime);
|
|
||||||
// if (pMeterMetaInfo->pMeterMeta->precision == TSDB_TIME_PRECISION_MILLI) {
|
|
||||||
// pQueryInfo->nSlidingTime /= 1000;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (pQueryInfo->nSlidingTime < tsMinSlidingTime) {
|
|
||||||
// return invalidSqlErrMsg(pQueryInfo->msg, msg3);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (pQueryInfo->nSlidingTime > pQueryInfo->nAggTimeInterval) {
|
|
||||||
// return invalidSqlErrMsg(pQueryInfo->msg, msg4);
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// pQueryInfo->nSlidingTime = -1;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// in case of join query, time range is required.
|
// in case of join query, time range is required.
|
||||||
if (QUERY_IS_JOIN_QUERY(pQueryInfo->type)) {
|
if (QUERY_IS_JOIN_QUERY(pQueryInfo->type)) {
|
||||||
int64_t timeRange = labs(pQueryInfo->stime - pQueryInfo->etime);
|
int64_t timeRange = labs(pQueryInfo->stime - pQueryInfo->etime);
|
||||||
|
|
|
@ -62,16 +62,19 @@ static void tscInitSqlContext(SSqlCmd *pCmd, SSqlRes *pRes, SLocalReducer *pRedu
|
||||||
for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) {
|
for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) {
|
||||||
SQLFunctionCtx *pCtx = &pReducer->pCtx[i];
|
SQLFunctionCtx *pCtx = &pReducer->pCtx[i];
|
||||||
|
|
||||||
pCtx->aOutputBuf = pReducer->pResultBuf->data + tscFieldInfoGetOffset(pQueryInfo, i) * pReducer->resColModel->maxCapacity;
|
pCtx->aOutputBuf = pReducer->pResultBuf->data + tscFieldInfoGetOffset(pQueryInfo, i) * pReducer->resColModel->capacity;
|
||||||
pCtx->order = pQueryInfo->order.order;
|
pCtx->order = pQueryInfo->order.order;
|
||||||
pCtx->functionId = pQueryInfo->exprsInfo.pExprs[i].functionId;
|
pCtx->functionId = pQueryInfo->exprsInfo.pExprs[i].functionId;
|
||||||
|
|
||||||
// input buffer hold only one point data
|
// input buffer hold only one point data
|
||||||
pCtx->aInputElemBuf = pReducer->pTempBuffer->data + pDesc->pSchema->colOffset[i];
|
int16_t offset = getColumnModelOffset(pDesc->pColumnModel, i);
|
||||||
|
SSchema* pSchema = getColumnModelSchema(pDesc->pColumnModel, i);
|
||||||
|
|
||||||
|
pCtx->aInputElemBuf = pReducer->pTempBuffer->data + offset;
|
||||||
|
|
||||||
// input data format comes from pModel
|
// input data format comes from pModel
|
||||||
pCtx->inputType = pDesc->pSchema->pFields[i].type;
|
pCtx->inputType = pSchema->type;
|
||||||
pCtx->inputBytes = pDesc->pSchema->pFields[i].bytes;
|
pCtx->inputBytes = pSchema->bytes;
|
||||||
|
|
||||||
TAOS_FIELD *pField = tscFieldInfoGetField(pQueryInfo, i);
|
TAOS_FIELD *pField = tscFieldInfoGetField(pQueryInfo, i);
|
||||||
// output data format yet comes from pCmd.
|
// output data format yet comes from pCmd.
|
||||||
|
@ -132,11 +135,11 @@ static void tscInitSqlContext(SSqlCmd *pCmd, SSqlRes *pRes, SLocalReducer *pRedu
|
||||||
* todo release allocated memory process with async process
|
* todo release allocated memory process with async process
|
||||||
*/
|
*/
|
||||||
void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrderDescriptor *pDesc,
|
void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrderDescriptor *pDesc,
|
||||||
tColModel *finalmodel, SSqlCmd *pCmd, SSqlRes *pRes) {
|
SColumnModel *finalmodel, SSqlCmd *pCmd, SSqlRes *pRes) {
|
||||||
// offset of cmd in SSqlObj structure
|
// offset of cmd in SSqlObj structure
|
||||||
char *pSqlObjAddr = (char *)pCmd - offsetof(SSqlObj, cmd);
|
char *pSqlObjAddr = (char *)pCmd - offsetof(SSqlObj, cmd);
|
||||||
|
|
||||||
if (pMemBuffer == NULL || pDesc->pSchema == NULL) {
|
if (pMemBuffer == NULL || pDesc->pColumnModel == NULL) {
|
||||||
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, numOfBuffer);
|
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, numOfBuffer);
|
||||||
|
|
||||||
tscError("%p no local buffer or intermediate result format model", pSqlObjAddr);
|
tscError("%p no local buffer or intermediate result format model", pSqlObjAddr);
|
||||||
|
@ -162,9 +165,9 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pDesc->pSchema->maxCapacity >= pMemBuffer[0]->nPageSize) {
|
if (pDesc->pColumnModel->capacity >= pMemBuffer[0]->pageSize) {
|
||||||
tscError("%p Invalid value of buffer capacity %d and page size %d ", pSqlObjAddr, pDesc->pSchema->maxCapacity,
|
tscError("%p Invalid value of buffer capacity %d and page size %d ", pSqlObjAddr, pDesc->pColumnModel->capacity,
|
||||||
pMemBuffer[0]->nPageSize);
|
pMemBuffer[0]->pageSize);
|
||||||
|
|
||||||
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, numOfBuffer);
|
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, numOfBuffer);
|
||||||
pRes->code = TSDB_CODE_APP_ERROR;
|
pRes->code = TSDB_CODE_APP_ERROR;
|
||||||
|
@ -196,7 +199,7 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
|
||||||
int32_t numOfFlushoutInFile = pMemBuffer[i]->fileMeta.flushoutData.nLength;
|
int32_t numOfFlushoutInFile = pMemBuffer[i]->fileMeta.flushoutData.nLength;
|
||||||
|
|
||||||
for (int32_t j = 0; j < numOfFlushoutInFile; ++j) {
|
for (int32_t j = 0; j < numOfFlushoutInFile; ++j) {
|
||||||
SLocalDataSource *pDS = (SLocalDataSource *)malloc(sizeof(SLocalDataSource) + pMemBuffer[0]->nPageSize);
|
SLocalDataSource *pDS = (SLocalDataSource *)malloc(sizeof(SLocalDataSource) + pMemBuffer[0]->pageSize);
|
||||||
if (pDS == NULL) {
|
if (pDS == NULL) {
|
||||||
tscError("%p failed to create merge structure", pSqlObjAddr);
|
tscError("%p failed to create merge structure", pSqlObjAddr);
|
||||||
pRes->code = TSDB_CODE_CLI_OUT_OF_MEMORY;
|
pRes->code = TSDB_CODE_CLI_OUT_OF_MEMORY;
|
||||||
|
@ -219,7 +222,7 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
|
||||||
|
|
||||||
tscGetSrcColumnInfo(colInfo, pQueryInfo);
|
tscGetSrcColumnInfo(colInfo, pQueryInfo);
|
||||||
|
|
||||||
tColModelDisplayEx(pDesc->pSchema, pDS->filePage.data, pDS->filePage.numOfElems, pMemBuffer[0]->numOfElemsPerPage,
|
tColModelDisplayEx(pDesc->pColumnModel, pDS->filePage.data, pDS->filePage.numOfElems, pMemBuffer[0]->numOfElemsPerPage,
|
||||||
colInfo);
|
colInfo);
|
||||||
#endif
|
#endif
|
||||||
if (pDS->filePage.numOfElems == 0) { // no data in this flush
|
if (pDS->filePage.numOfElems == 0) { // no data in this flush
|
||||||
|
@ -259,7 +262,7 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
|
||||||
tscRestoreSQLFunctionForMetricQuery(pQueryInfo);
|
tscRestoreSQLFunctionForMetricQuery(pQueryInfo);
|
||||||
tscFieldInfoCalOffset(pQueryInfo);
|
tscFieldInfoCalOffset(pQueryInfo);
|
||||||
|
|
||||||
if (pReducer->rowSize > pMemBuffer[0]->nPageSize) {
|
if (pReducer->rowSize > pMemBuffer[0]->pageSize) {
|
||||||
assert(false); // todo fixed row size is larger than the minimum page size;
|
assert(false); // todo fixed row size is larger than the minimum page size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,15 +277,15 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
|
||||||
pReducer->discardData = (tFilePage *)calloc(1, pReducer->rowSize + sizeof(tFilePage));
|
pReducer->discardData = (tFilePage *)calloc(1, pReducer->rowSize + sizeof(tFilePage));
|
||||||
pReducer->discard = false;
|
pReducer->discard = false;
|
||||||
|
|
||||||
pReducer->nResultBufSize = pMemBuffer[0]->nPageSize * 16;
|
pReducer->nResultBufSize = pMemBuffer[0]->pageSize * 16;
|
||||||
pReducer->pResultBuf = (tFilePage *)calloc(1, pReducer->nResultBufSize + sizeof(tFilePage));
|
pReducer->pResultBuf = (tFilePage *)calloc(1, pReducer->nResultBufSize + sizeof(tFilePage));
|
||||||
|
|
||||||
int32_t finalRowLength = tscGetResRowLength(pQueryInfo);
|
int32_t finalRowLength = tscGetResRowLength(pQueryInfo);
|
||||||
pReducer->resColModel = finalmodel;
|
pReducer->resColModel = finalmodel;
|
||||||
pReducer->resColModel->maxCapacity = pReducer->nResultBufSize / finalRowLength;
|
pReducer->resColModel->capacity = pReducer->nResultBufSize / finalRowLength;
|
||||||
assert(finalRowLength <= pReducer->rowSize);
|
assert(finalRowLength <= pReducer->rowSize);
|
||||||
|
|
||||||
pReducer->pFinalRes = calloc(1, pReducer->rowSize * pReducer->resColModel->maxCapacity);
|
pReducer->pFinalRes = calloc(1, pReducer->rowSize * pReducer->resColModel->capacity);
|
||||||
pReducer->pBufForInterpo = calloc(1, pReducer->nResultBufSize);
|
pReducer->pBufForInterpo = calloc(1, pReducer->nResultBufSize);
|
||||||
|
|
||||||
if (pReducer->pTempBuffer == NULL|| pReducer->discardData == NULL || pReducer->pResultBuf == NULL ||
|
if (pReducer->pTempBuffer == NULL|| pReducer->discardData == NULL || pReducer->pResultBuf == NULL ||
|
||||||
|
@ -304,8 +307,8 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
|
||||||
tscCreateResPointerInfo(pRes, pQueryInfo);
|
tscCreateResPointerInfo(pRes, pQueryInfo);
|
||||||
tscInitSqlContext(pCmd, pRes, pReducer, pDesc);
|
tscInitSqlContext(pCmd, pRes, pReducer, pDesc);
|
||||||
|
|
||||||
// we change the maxCapacity of schema to denote that there is only one row in temp buffer
|
// we change the capacity of schema to denote that there is only one row in temp buffer
|
||||||
pReducer->pDesc->pSchema->maxCapacity = 1;
|
pReducer->pDesc->pColumnModel->capacity = 1;
|
||||||
|
|
||||||
//restore the limitation value at the last stage
|
//restore the limitation value at the last stage
|
||||||
if (tscOrderedProjectionQueryOnSTable(pQueryInfo, 0)) {
|
if (tscOrderedProjectionQueryOnSTable(pQueryInfo, 0)) {
|
||||||
|
@ -333,7 +336,8 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
|
||||||
if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) {
|
if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) {
|
||||||
pInterpoInfo->pTags[0] = (char *)pInterpoInfo->pTags + POINTER_BYTES * pQueryInfo->groupbyExpr.numOfGroupCols;
|
pInterpoInfo->pTags[0] = (char *)pInterpoInfo->pTags + POINTER_BYTES * pQueryInfo->groupbyExpr.numOfGroupCols;
|
||||||
for (int32_t i = 1; i < pQueryInfo->groupbyExpr.numOfGroupCols; ++i) {
|
for (int32_t i = 1; i < pQueryInfo->groupbyExpr.numOfGroupCols; ++i) {
|
||||||
pInterpoInfo->pTags[i] = pReducer->resColModel->pFields[startIndex + i - 1].bytes + pInterpoInfo->pTags[i - 1];
|
SSchema* pSchema = getColumnModelSchema(pReducer->resColModel, startIndex + i - 1);
|
||||||
|
pInterpoInfo->pTags[i] = pSchema->bytes + pInterpoInfo->pTags[i - 1];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
assert(pInterpoInfo->pTags == NULL);
|
assert(pInterpoInfo->pTags == NULL);
|
||||||
|
@ -346,16 +350,16 @@ static int32_t tscFlushTmpBufferImpl(tExtMemBuffer *pMemoryBuf, tOrderDescriptor
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(pPage->numOfElems <= pDesc->pSchema->maxCapacity);
|
assert(pPage->numOfElems <= pDesc->pColumnModel->capacity);
|
||||||
|
|
||||||
// sort before flush to disk, the data must be consecutively put on tFilePage.
|
// sort before flush to disk, the data must be consecutively put on tFilePage.
|
||||||
if (pDesc->orderIdx.numOfOrderedCols > 0) {
|
if (pDesc->orderIdx.numOfCols > 0) {
|
||||||
tColDataQSort(pDesc, pPage->numOfElems, 0, pPage->numOfElems - 1, pPage->data, orderType);
|
tColDataQSort(pDesc, pPage->numOfElems, 0, pPage->numOfElems - 1, pPage->data, orderType);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _DEBUG_VIEW
|
#ifdef _DEBUG_VIEW
|
||||||
printf("%" PRIu64 " rows data flushed to disk after been sorted:\n", pPage->numOfElems);
|
printf("%" PRIu64 " rows data flushed to disk after been sorted:\n", pPage->numOfElems);
|
||||||
tColModelDisplay(pDesc->pSchema, pPage->data, pPage->numOfElems, pPage->numOfElems);
|
tColModelDisplay(pDesc->pColumnModel, pPage->data, pPage->numOfElems, pPage->numOfElems);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// write to cache after being sorted
|
// write to cache after being sorted
|
||||||
|
@ -383,18 +387,19 @@ int32_t tscFlushTmpBuffer(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tF
|
||||||
|
|
||||||
int32_t saveToBuffer(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tFilePage *pPage, void *data,
|
int32_t saveToBuffer(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tFilePage *pPage, void *data,
|
||||||
int32_t numOfRows, int32_t orderType) {
|
int32_t numOfRows, int32_t orderType) {
|
||||||
if (pPage->numOfElems + numOfRows <= pDesc->pSchema->maxCapacity) {
|
SColumnModel *pModel = pDesc->pColumnModel;
|
||||||
tColModelAppend(pDesc->pSchema, pPage, data, 0, numOfRows, numOfRows);
|
|
||||||
|
if (pPage->numOfElems + numOfRows <= pModel->capacity) {
|
||||||
|
tColModelAppend(pModel, pPage, data, 0, numOfRows, numOfRows);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
tColModel *pModel = pDesc->pSchema;
|
// current buffer is overflow, flush data to extensive buffer
|
||||||
|
int32_t numOfRemainEntries = pModel->capacity - pPage->numOfElems;
|
||||||
int32_t numOfRemainEntries = pDesc->pSchema->maxCapacity - pPage->numOfElems;
|
|
||||||
tColModelAppend(pModel, pPage, data, 0, numOfRemainEntries, numOfRows);
|
tColModelAppend(pModel, pPage, data, 0, numOfRemainEntries, numOfRows);
|
||||||
|
|
||||||
/* current buffer is full, need to flushed to disk */
|
// current buffer is full, need to flushed to disk
|
||||||
assert(pPage->numOfElems == pDesc->pSchema->maxCapacity);
|
assert(pPage->numOfElems == pModel->capacity);
|
||||||
int32_t ret = tscFlushTmpBuffer(pMemoryBuf, pDesc, pPage, orderType);
|
int32_t ret = tscFlushTmpBuffer(pMemoryBuf, pDesc, pPage, orderType);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -404,15 +409,15 @@ int32_t saveToBuffer(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tFilePa
|
||||||
|
|
||||||
while (remain > 0) {
|
while (remain > 0) {
|
||||||
int32_t numOfWriteElems = 0;
|
int32_t numOfWriteElems = 0;
|
||||||
if (remain > pModel->maxCapacity) {
|
if (remain > pModel->capacity) {
|
||||||
numOfWriteElems = pModel->maxCapacity;
|
numOfWriteElems = pModel->capacity;
|
||||||
} else {
|
} else {
|
||||||
numOfWriteElems = remain;
|
numOfWriteElems = remain;
|
||||||
}
|
}
|
||||||
|
|
||||||
tColModelAppend(pModel, pPage, data, numOfRows - remain, numOfWriteElems, numOfRows);
|
tColModelAppend(pModel, pPage, data, numOfRows - remain, numOfWriteElems, numOfRows);
|
||||||
|
|
||||||
if (pPage->numOfElems == pModel->maxCapacity) {
|
if (pPage->numOfElems == pModel->capacity) {
|
||||||
int32_t ret = tscFlushTmpBuffer(pMemoryBuf, pDesc, pPage, orderType);
|
int32_t ret = tscFlushTmpBuffer(pMemoryBuf, pDesc, pPage, orderType);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -508,7 +513,7 @@ void tscDestroyLocalReducer(SSqlObj *pSql) {
|
||||||
tscTrace("%p free local reducer finished", pSql);
|
tscTrace("%p free local reducer finished", pSql);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t createOrderDescriptor(tOrderDescriptor **pOrderDesc, SSqlCmd *pCmd, tColModel *pModel) {
|
static int32_t createOrderDescriptor(tOrderDescriptor **pOrderDesc, SSqlCmd *pCmd, SColumnModel *pModel) {
|
||||||
int32_t numOfGroupByCols = 0;
|
int32_t numOfGroupByCols = 0;
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||||
|
|
||||||
|
@ -567,7 +572,7 @@ bool isSameGroup(SSqlCmd *pCmd, SLocalReducer *pReducer, char *pPrev, tFilePage
|
||||||
}
|
}
|
||||||
|
|
||||||
tOrderDescriptor *pOrderDesc = pReducer->pDesc;
|
tOrderDescriptor *pOrderDesc = pReducer->pDesc;
|
||||||
int32_t numOfCols = pOrderDesc->orderIdx.numOfOrderedCols;
|
int32_t numOfCols = pOrderDesc->orderIdx.numOfCols;
|
||||||
|
|
||||||
// no group by columns, all data belongs to one group
|
// no group by columns, all data belongs to one group
|
||||||
if (numOfCols <= 0) {
|
if (numOfCols <= 0) {
|
||||||
|
@ -577,25 +582,25 @@ bool isSameGroup(SSqlCmd *pCmd, SLocalReducer *pReducer, char *pPrev, tFilePage
|
||||||
if (pOrderDesc->orderIdx.pData[numOfCols - 1] == PRIMARYKEY_TIMESTAMP_COL_INDEX) { //<= 0
|
if (pOrderDesc->orderIdx.pData[numOfCols - 1] == PRIMARYKEY_TIMESTAMP_COL_INDEX) { //<= 0
|
||||||
// super table interval query
|
// super table interval query
|
||||||
assert(pQueryInfo->nAggTimeInterval > 0);
|
assert(pQueryInfo->nAggTimeInterval > 0);
|
||||||
pOrderDesc->orderIdx.numOfOrderedCols -= 1;
|
pOrderDesc->orderIdx.numOfCols -= 1;
|
||||||
} else { // simple group by query
|
} else { // simple group by query
|
||||||
assert(pQueryInfo->nAggTimeInterval == 0);
|
assert(pQueryInfo->nAggTimeInterval == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// only one row exists
|
// only one row exists
|
||||||
int32_t ret = compare_a(pOrderDesc, 1, 0, pPrev, 1, 0, tmpBuffer->data);
|
int32_t ret = compare_a(pOrderDesc, 1, 0, pPrev, 1, 0, tmpBuffer->data);
|
||||||
pOrderDesc->orderIdx.numOfOrderedCols = numOfCols;
|
pOrderDesc->orderIdx.numOfCols = numOfCols;
|
||||||
|
|
||||||
return (ret == 0);
|
return (ret == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOrderDescriptor **pOrderDesc,
|
int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOrderDescriptor **pOrderDesc,
|
||||||
tColModel **pFinalModel, uint32_t nBufferSizes) {
|
SColumnModel **pFinalModel, uint32_t nBufferSizes) {
|
||||||
SSqlCmd *pCmd = &pSql->cmd;
|
SSqlCmd *pCmd = &pSql->cmd;
|
||||||
SSqlRes *pRes = &pSql->res;
|
SSqlRes *pRes = &pSql->res;
|
||||||
|
|
||||||
SSchema * pSchema = NULL;
|
SSchema * pSchema = NULL;
|
||||||
tColModel *pModel = NULL;
|
SColumnModel *pModel = NULL;
|
||||||
*pFinalModel = NULL;
|
*pFinalModel = NULL;
|
||||||
|
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||||
|
@ -630,14 +635,10 @@ int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOr
|
||||||
capacity = nBufferSizes / rlen;
|
capacity = nBufferSizes / rlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
pModel = tColModelCreate(pSchema, pQueryInfo->fieldsInfo.numOfOutputCols, capacity);
|
pModel = createColumnModel(pSchema, pQueryInfo->fieldsInfo.numOfOutputCols, capacity);
|
||||||
|
|
||||||
for (int32_t i = 0; i < pMeterMetaInfo->pMetricMeta->numOfVnodes; ++i) {
|
for (int32_t i = 0; i < pMeterMetaInfo->pMetricMeta->numOfVnodes; ++i) {
|
||||||
char tmpPath[512] = {0};
|
(*pMemBuffer)[i] = createExtMemBuffer(nBufferSizes, rlen, pModel);
|
||||||
getTmpfilePath("tv_bf_db", tmpPath);
|
|
||||||
tscTrace("%p create [%d](%d) tmp file for subquery:%s", pSql, pMeterMetaInfo->pMetricMeta->numOfVnodes, i, tmpPath);
|
|
||||||
|
|
||||||
tExtMemBufferCreate(&(*pMemBuffer)[i], nBufferSizes, rlen, tmpPath, pModel);
|
|
||||||
(*pMemBuffer)[i]->flushModel = MULTIPLE_APPEND_MODEL;
|
(*pMemBuffer)[i]->flushModel = MULTIPLE_APPEND_MODEL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -655,7 +656,7 @@ int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOr
|
||||||
strcpy(pSchema[i].name, pField->name);
|
strcpy(pSchema[i].name, pField->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
*pFinalModel = tColModelCreate(pSchema, pQueryInfo->fieldsInfo.numOfOutputCols, capacity);
|
*pFinalModel = createColumnModel(pSchema, pQueryInfo->fieldsInfo.numOfOutputCols, capacity);
|
||||||
tfree(pSchema);
|
tfree(pSchema);
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
@ -667,12 +668,12 @@ int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOr
|
||||||
* @param pFinalModel
|
* @param pFinalModel
|
||||||
* @param numOfVnodes
|
* @param numOfVnodes
|
||||||
*/
|
*/
|
||||||
void tscLocalReducerEnvDestroy(tExtMemBuffer **pMemBuffer, tOrderDescriptor *pDesc, tColModel *pFinalModel,
|
void tscLocalReducerEnvDestroy(tExtMemBuffer **pMemBuffer, tOrderDescriptor *pDesc, SColumnModel *pFinalModel,
|
||||||
int32_t numOfVnodes) {
|
int32_t numOfVnodes) {
|
||||||
tColModelDestroy(pFinalModel);
|
destroyColumnModel(pFinalModel);
|
||||||
tOrderDescDestroy(pDesc);
|
tOrderDescDestroy(pDesc);
|
||||||
for (int32_t i = 0; i < numOfVnodes; ++i) {
|
for (int32_t i = 0; i < numOfVnodes; ++i) {
|
||||||
tExtMemBufferDestroy(&pMemBuffer[i]);
|
pMemBuffer[i] = destoryExtMemBuffer(pMemBuffer[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
tfree(pMemBuffer);
|
tfree(pMemBuffer);
|
||||||
|
@ -697,8 +698,8 @@ int32_t loadNewDataFromDiskFor(SLocalReducer *pLocalReducer, SLocalDataSource *p
|
||||||
|
|
||||||
#if defined(_DEBUG_VIEW)
|
#if defined(_DEBUG_VIEW)
|
||||||
printf("new page load to buffer\n");
|
printf("new page load to buffer\n");
|
||||||
tColModelDisplay(pOneInterDataSrc->pMemBuffer->pColModel, pOneInterDataSrc->filePage.data,
|
tColModelDisplay(pOneInterDataSrc->pMemBuffer->pColumnModel, pOneInterDataSrc->filePage.data,
|
||||||
pOneInterDataSrc->filePage.numOfElems, pOneInterDataSrc->pMemBuffer->pColModel->maxCapacity);
|
pOneInterDataSrc->filePage.numOfElems, pOneInterDataSrc->pMemBuffer->pColumnModel->capacity);
|
||||||
#endif
|
#endif
|
||||||
*needAdjustLoserTree = true;
|
*needAdjustLoserTree = true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -759,7 +760,7 @@ void savePrevRecordAndSetupInterpoInfo(SLocalReducer *pLocalReducer, SQueryInfo*
|
||||||
pLocalReducer->discard = true;
|
pLocalReducer->discard = true;
|
||||||
pLocalReducer->discardData->numOfElems = 0;
|
pLocalReducer->discardData->numOfElems = 0;
|
||||||
|
|
||||||
tColModel *pModel = pLocalReducer->pDesc->pSchema;
|
SColumnModel *pModel = pLocalReducer->pDesc->pColumnModel;
|
||||||
tColModelAppend(pModel, pLocalReducer->discardData, pLocalReducer->prevRowOfInput, 0, 1, 1);
|
tColModelAppend(pModel, pLocalReducer->discardData, pLocalReducer->prevRowOfInput, 0, 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -782,11 +783,12 @@ static void reversedCopyResultToDstBuf(SQueryInfo* pQueryInfo, SSqlRes *pRes, tF
|
||||||
}
|
}
|
||||||
|
|
||||||
static void reversedCopyFromInterpolationToDstBuf(SQueryInfo* pQueryInfo, SSqlRes *pRes, tFilePage **pResPages, SLocalReducer *pLocalReducer) {
|
static void reversedCopyFromInterpolationToDstBuf(SQueryInfo* pQueryInfo, SSqlRes *pRes, tFilePage **pResPages, SLocalReducer *pLocalReducer) {
|
||||||
|
assert(0);
|
||||||
for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
|
for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
|
||||||
TAOS_FIELD *pField = tscFieldInfoGetField(pQueryInfo, i);
|
TAOS_FIELD *pField = tscFieldInfoGetField(pQueryInfo, i);
|
||||||
|
|
||||||
int32_t offset = tscFieldInfoGetOffset(pQueryInfo, i);
|
int32_t offset = tscFieldInfoGetOffset(pQueryInfo, i);
|
||||||
assert(offset == pLocalReducer->resColModel->colOffset[i]);
|
assert(offset == getColumnModelOffset(pLocalReducer->resColModel, i));
|
||||||
|
|
||||||
char *src = pResPages[i]->data + (pRes->numOfRows - 1) * pField->bytes;
|
char *src = pResPages[i]->data + (pRes->numOfRows - 1) * pField->bytes;
|
||||||
char *dst = pRes->data + pRes->numOfRows * offset;
|
char *dst = pRes->data + pRes->numOfRows * offset;
|
||||||
|
@ -880,7 +882,7 @@ static void doInterpolateResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, boo
|
||||||
tFilePage **pResPages = malloc(POINTER_BYTES * pQueryInfo->fieldsInfo.numOfOutputCols);
|
tFilePage **pResPages = malloc(POINTER_BYTES * pQueryInfo->fieldsInfo.numOfOutputCols);
|
||||||
for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) {
|
for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) {
|
||||||
TAOS_FIELD *pField = tscFieldInfoGetField(pQueryInfo, i);
|
TAOS_FIELD *pField = tscFieldInfoGetField(pQueryInfo, i);
|
||||||
pResPages[i] = calloc(1, sizeof(tFilePage) + pField->bytes * pLocalReducer->resColModel->maxCapacity);
|
pResPages[i] = calloc(1, sizeof(tFilePage) + pField->bytes * pLocalReducer->resColModel->capacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
char ** srcData = (char **)malloc((POINTER_BYTES + sizeof(int32_t)) * pQueryInfo->fieldsInfo.numOfOutputCols);
|
char ** srcData = (char **)malloc((POINTER_BYTES + sizeof(int32_t)) * pQueryInfo->fieldsInfo.numOfOutputCols);
|
||||||
|
@ -899,11 +901,11 @@ static void doInterpolateResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, boo
|
||||||
TSKEY etime = taosGetRevisedEndKey(actualETime, pQueryInfo->order.order, pQueryInfo->nAggTimeInterval, pQueryInfo->intervalTimeUnit,
|
TSKEY etime = taosGetRevisedEndKey(actualETime, pQueryInfo->order.order, pQueryInfo->nAggTimeInterval, pQueryInfo->intervalTimeUnit,
|
||||||
precision);
|
precision);
|
||||||
int32_t nrows = taosGetNumOfResultWithInterpo(pInterpoInfo, pPrimaryKeys, remains, pQueryInfo->nAggTimeInterval, etime,
|
int32_t nrows = taosGetNumOfResultWithInterpo(pInterpoInfo, pPrimaryKeys, remains, pQueryInfo->nAggTimeInterval, etime,
|
||||||
pLocalReducer->resColModel->maxCapacity);
|
pLocalReducer->resColModel->capacity);
|
||||||
|
|
||||||
int32_t newRows = taosDoInterpoResult(pInterpoInfo, pQueryInfo->interpoType, pResPages, remains, nrows,
|
int32_t newRows = taosDoInterpoResult(pInterpoInfo, pQueryInfo->interpoType, pResPages, remains, nrows,
|
||||||
pQueryInfo->nAggTimeInterval, pPrimaryKeys, pLocalReducer->resColModel, srcData,
|
pQueryInfo->nAggTimeInterval, pPrimaryKeys, pLocalReducer->resColModel, srcData,
|
||||||
pQueryInfo->defaultVal, functions, pLocalReducer->resColModel->maxCapacity);
|
pQueryInfo->defaultVal, functions, pLocalReducer->resColModel->capacity);
|
||||||
assert(newRows <= nrows);
|
assert(newRows <= nrows);
|
||||||
|
|
||||||
if (pQueryInfo->limit.offset < newRows) {
|
if (pQueryInfo->limit.offset < newRows) {
|
||||||
|
@ -960,11 +962,10 @@ static void doInterpolateResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, boo
|
||||||
if (pQueryInfo->order.order == TSQL_SO_ASC) {
|
if (pQueryInfo->order.order == TSQL_SO_ASC) {
|
||||||
for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) {
|
for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) {
|
||||||
TAOS_FIELD *pField = tscFieldInfoGetField(pQueryInfo, i);
|
TAOS_FIELD *pField = tscFieldInfoGetField(pQueryInfo, i);
|
||||||
|
int16_t offset = getColumnModelOffset(pLocalReducer->resColModel, i);
|
||||||
memcpy(pRes->data + pLocalReducer->resColModel->colOffset[i] * pRes->numOfRows, pResPages[i]->data,
|
memcpy(pRes->data + offset * pRes->numOfRows, pResPages[i]->data, pField->bytes * pRes->numOfRows);
|
||||||
pField->bytes * pRes->numOfRows);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {//todo bug??
|
||||||
reversedCopyFromInterpolationToDstBuf(pQueryInfo, pRes, pResPages, pLocalReducer);
|
reversedCopyFromInterpolationToDstBuf(pQueryInfo, pRes, pResPages, pLocalReducer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -979,13 +980,15 @@ static void doInterpolateResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, boo
|
||||||
}
|
}
|
||||||
|
|
||||||
static void savePreviousRow(SLocalReducer *pLocalReducer, tFilePage *tmpBuffer) {
|
static void savePreviousRow(SLocalReducer *pLocalReducer, tFilePage *tmpBuffer) {
|
||||||
tColModel *pColModel = pLocalReducer->pDesc->pSchema;
|
SColumnModel *pColumnModel = pLocalReducer->pDesc->pColumnModel;
|
||||||
assert(pColModel->maxCapacity == 1 && tmpBuffer->numOfElems == 1);
|
assert(pColumnModel->capacity == 1 && tmpBuffer->numOfElems == 1);
|
||||||
|
|
||||||
// copy to previous temp buffer
|
// copy to previous temp buffer
|
||||||
for (int32_t i = 0; i < pLocalReducer->pDesc->pSchema->numOfCols; ++i) {
|
for (int32_t i = 0; i < pColumnModel->numOfCols; ++i) {
|
||||||
memcpy(pLocalReducer->prevRowOfInput + pColModel->colOffset[i], tmpBuffer->data + pColModel->colOffset[i],
|
SSchema* pSchema = getColumnModelSchema(pColumnModel, i);
|
||||||
pColModel->pFields[i].bytes);
|
int16_t offset = getColumnModelOffset(pColumnModel, i);
|
||||||
|
|
||||||
|
memcpy(pLocalReducer->prevRowOfInput + offset, tmpBuffer->data + offset, pSchema->bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpBuffer->numOfElems = 0;
|
tmpBuffer->numOfElems = 0;
|
||||||
|
@ -1127,7 +1130,7 @@ bool needToMerge(SQueryInfo* pQueryInfo, SLocalReducer *pLocalReducer, tFilePage
|
||||||
ret = 1; // disable merge procedure
|
ret = 1; // disable merge procedure
|
||||||
} else {
|
} else {
|
||||||
tOrderDescriptor *pDesc = pLocalReducer->pDesc;
|
tOrderDescriptor *pDesc = pLocalReducer->pDesc;
|
||||||
if (pDesc->orderIdx.numOfOrderedCols > 0) {
|
if (pDesc->orderIdx.numOfCols > 0) {
|
||||||
if (pDesc->tsOrder == TSQL_SO_ASC) { // asc
|
if (pDesc->tsOrder == TSQL_SO_ASC) { // asc
|
||||||
// todo refactor comparator
|
// todo refactor comparator
|
||||||
ret = compare_a(pLocalReducer->pDesc, 1, 0, pLocalReducer->prevRowOfInput, 1, 0, tmpBuffer->data);
|
ret = compare_a(pLocalReducer->pDesc, 1, 0, pLocalReducer->prevRowOfInput, 1, 0, tmpBuffer->data);
|
||||||
|
@ -1177,7 +1180,7 @@ bool doGenerateFinalResults(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool no
|
||||||
|
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||||
tFilePage *pResBuf = pLocalReducer->pResultBuf;
|
tFilePage *pResBuf = pLocalReducer->pResultBuf;
|
||||||
tColModel *pModel = pLocalReducer->resColModel;
|
SColumnModel *pModel = pLocalReducer->resColModel;
|
||||||
|
|
||||||
pRes->code = TSDB_CODE_SUCCESS;
|
pRes->code = TSDB_CODE_SUCCESS;
|
||||||
|
|
||||||
|
@ -1192,7 +1195,7 @@ bool doGenerateFinalResults(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool no
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
tColModelCompact(pModel, pResBuf, pModel->maxCapacity);
|
tColModelCompact(pModel, pResBuf, pModel->capacity);
|
||||||
memcpy(pLocalReducer->pBufForInterpo, pResBuf->data, pLocalReducer->nResultBufSize);
|
memcpy(pLocalReducer->pBufForInterpo, pResBuf->data, pLocalReducer->nResultBufSize);
|
||||||
|
|
||||||
#ifdef _DEBUG_VIEW
|
#ifdef _DEBUG_VIEW
|
||||||
|
@ -1204,9 +1207,11 @@ bool doGenerateFinalResults(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool no
|
||||||
int32_t startIndex = pQueryInfo->fieldsInfo.numOfOutputCols - pQueryInfo->groupbyExpr.numOfGroupCols;
|
int32_t startIndex = pQueryInfo->fieldsInfo.numOfOutputCols - pQueryInfo->groupbyExpr.numOfGroupCols;
|
||||||
|
|
||||||
for (int32_t i = 0; i < pQueryInfo->groupbyExpr.numOfGroupCols; ++i) {
|
for (int32_t i = 0; i < pQueryInfo->groupbyExpr.numOfGroupCols; ++i) {
|
||||||
|
int16_t offset = getColumnModelOffset(pModel, startIndex + i);
|
||||||
|
SSchema* pSchema = getColumnModelSchema(pModel, startIndex + i);
|
||||||
|
|
||||||
memcpy(pInterpoInfo->pTags[i],
|
memcpy(pInterpoInfo->pTags[i],
|
||||||
pLocalReducer->pBufForInterpo + pModel->colOffset[startIndex + i] * pResBuf->numOfElems,
|
pLocalReducer->pBufForInterpo + offset * pResBuf->numOfElems, pSchema->bytes);
|
||||||
pModel->pFields[startIndex + i].bytes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
taosInterpoSetStartInfo(&pLocalReducer->interpolationInfo, pResBuf->numOfElems, pQueryInfo->interpoType);
|
taosInterpoSetStartInfo(&pLocalReducer->interpolationInfo, pResBuf->numOfElems, pQueryInfo->interpoType);
|
||||||
|
@ -1218,7 +1223,7 @@ bool doGenerateFinalResults(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool no
|
||||||
void resetOutputBuf(SQueryInfo* pQueryInfo, SLocalReducer *pLocalReducer) { // reset output buffer to the beginning
|
void resetOutputBuf(SQueryInfo* pQueryInfo, SLocalReducer *pLocalReducer) { // reset output buffer to the beginning
|
||||||
for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) {
|
for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) {
|
||||||
pLocalReducer->pCtx[i].aOutputBuf =
|
pLocalReducer->pCtx[i].aOutputBuf =
|
||||||
pLocalReducer->pResultBuf->data + tscFieldInfoGetOffset(pQueryInfo, i) * pLocalReducer->resColModel->maxCapacity;
|
pLocalReducer->pResultBuf->data + tscFieldInfoGetOffset(pQueryInfo, i) * pLocalReducer->resColModel->capacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(pLocalReducer->pResultBuf, 0, pLocalReducer->nResultBufSize + sizeof(tFilePage));
|
memset(pLocalReducer->pResultBuf, 0, pLocalReducer->nResultBufSize + sizeof(tFilePage));
|
||||||
|
@ -1270,7 +1275,7 @@ static bool doInterpolationForCurrentGroup(SSqlObj *pSql) {
|
||||||
int32_t remain = taosNumOfRemainPoints(pInterpoInfo);
|
int32_t remain = taosNumOfRemainPoints(pInterpoInfo);
|
||||||
TSKEY ekey = taosGetRevisedEndKey(etime, pQueryInfo->order.order, pQueryInfo->nAggTimeInterval, pQueryInfo->intervalTimeUnit, p);
|
TSKEY ekey = taosGetRevisedEndKey(etime, pQueryInfo->order.order, pQueryInfo->nAggTimeInterval, pQueryInfo->intervalTimeUnit, p);
|
||||||
int32_t rows = taosGetNumOfResultWithInterpo(pInterpoInfo, (TSKEY *)pLocalReducer->pBufForInterpo, remain,
|
int32_t rows = taosGetNumOfResultWithInterpo(pInterpoInfo, (TSKEY *)pLocalReducer->pBufForInterpo, remain,
|
||||||
pQueryInfo->nAggTimeInterval, ekey, pLocalReducer->resColModel->maxCapacity);
|
pQueryInfo->nAggTimeInterval, ekey, pLocalReducer->resColModel->capacity);
|
||||||
if (rows > 0) { // do interpo
|
if (rows > 0) { // do interpo
|
||||||
doInterpolateResult(pSql, pLocalReducer, false);
|
doInterpolateResult(pSql, pLocalReducer, false);
|
||||||
}
|
}
|
||||||
|
@ -1302,7 +1307,7 @@ static bool doHandleLastRemainData(SSqlObj *pSql) {
|
||||||
|
|
||||||
etime = taosGetRevisedEndKey(etime, pQueryInfo->order.order, pQueryInfo->nAggTimeInterval, pQueryInfo->intervalTimeUnit, precision);
|
etime = taosGetRevisedEndKey(etime, pQueryInfo->order.order, pQueryInfo->nAggTimeInterval, pQueryInfo->intervalTimeUnit, precision);
|
||||||
int32_t rows = taosGetNumOfResultWithInterpo(pInterpoInfo, NULL, 0, pQueryInfo->nAggTimeInterval, etime,
|
int32_t rows = taosGetNumOfResultWithInterpo(pInterpoInfo, NULL, 0, pQueryInfo->nAggTimeInterval, etime,
|
||||||
pLocalReducer->resColModel->maxCapacity);
|
pLocalReducer->resColModel->capacity);
|
||||||
if (rows > 0) { // do interpo
|
if (rows > 0) { // do interpo
|
||||||
doInterpolateResult(pSql, pLocalReducer, true);
|
doInterpolateResult(pSql, pLocalReducer, true);
|
||||||
}
|
}
|
||||||
|
@ -1391,7 +1396,7 @@ int32_t tscDoLocalreduce(SSqlObj *pSql) {
|
||||||
|
|
||||||
// clear buffer
|
// clear buffer
|
||||||
handleUnprocessedRow(pCmd, pLocalReducer, tmpBuffer);
|
handleUnprocessedRow(pCmd, pLocalReducer, tmpBuffer);
|
||||||
tColModel *pModel = pLocalReducer->pDesc->pSchema;
|
SColumnModel *pModel = pLocalReducer->pDesc->pColumnModel;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (isAllSourcesCompleted(pLocalReducer)) {
|
if (isAllSourcesCompleted(pLocalReducer)) {
|
||||||
|
@ -1408,14 +1413,14 @@ int32_t tscDoLocalreduce(SSqlObj *pSql) {
|
||||||
SLocalDataSource *pOneDataSrc = pLocalReducer->pLocalDataSrc[pTree->pNode[0].index];
|
SLocalDataSource *pOneDataSrc = pLocalReducer->pLocalDataSrc[pTree->pNode[0].index];
|
||||||
|
|
||||||
tColModelAppend(pModel, tmpBuffer, pOneDataSrc->filePage.data, pOneDataSrc->rowIdx, 1,
|
tColModelAppend(pModel, tmpBuffer, pOneDataSrc->filePage.data, pOneDataSrc->rowIdx, 1,
|
||||||
pOneDataSrc->pMemBuffer->pColModel->maxCapacity);
|
pOneDataSrc->pMemBuffer->pColumnModel->capacity);
|
||||||
|
|
||||||
#if defined(_DEBUG_VIEW)
|
#if defined(_DEBUG_VIEW)
|
||||||
printf("chosen row:\t");
|
printf("chosen row:\t");
|
||||||
SSrcColumnInfo colInfo[256] = {0};
|
SSrcColumnInfo colInfo[256] = {0};
|
||||||
tscGetSrcColumnInfo(colInfo, pQueryInfo);
|
tscGetSrcColumnInfo(colInfo, pQueryInfo);
|
||||||
|
|
||||||
tColModelDisplayEx(pModel, tmpBuffer->data, tmpBuffer->numOfElems, pModel->maxCapacity, colInfo);
|
tColModelDisplayEx(pModel, tmpBuffer->data, tmpBuffer->numOfElems, pModel->capacity, colInfo);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (pLocalReducer->discard) {
|
if (pLocalReducer->discard) {
|
||||||
|
@ -1470,7 +1475,7 @@ int32_t tscDoLocalreduce(SSqlObj *pSql) {
|
||||||
* continue to process results instead of return results.
|
* continue to process results instead of return results.
|
||||||
*/
|
*/
|
||||||
if ((!sameGroup && pResBuf->numOfElems > 0) ||
|
if ((!sameGroup && pResBuf->numOfElems > 0) ||
|
||||||
(pResBuf->numOfElems == pLocalReducer->resColModel->maxCapacity)) {
|
(pResBuf->numOfElems == pLocalReducer->resColModel->capacity)) {
|
||||||
// does not belong to the same group
|
// does not belong to the same group
|
||||||
bool notSkipped = doGenerateFinalResults(pSql, pLocalReducer, !sameGroup);
|
bool notSkipped = doGenerateFinalResults(pSql, pLocalReducer, !sameGroup);
|
||||||
|
|
||||||
|
|
|
@ -901,7 +901,7 @@ int tscLaunchSTableSubqueries(SSqlObj *pSql) {
|
||||||
|
|
||||||
tExtMemBuffer ** pMemoryBuf = NULL;
|
tExtMemBuffer ** pMemoryBuf = NULL;
|
||||||
tOrderDescriptor *pDesc = NULL;
|
tOrderDescriptor *pDesc = NULL;
|
||||||
tColModel * pModel = NULL;
|
SColumnModel * pModel = NULL;
|
||||||
|
|
||||||
pRes->qhandle = 1; // hack the qhandle check
|
pRes->qhandle = 1; // hack the qhandle check
|
||||||
|
|
||||||
|
@ -1181,7 +1181,7 @@ void tscRetrieveFromVnodeCallBack(void *param, TAOS_RES *tres, int numOfRows) {
|
||||||
tscTrace("%p sub:%p retrieve numOfRows:%d totalNumOfRows:%d from ip:%u,vid:%d,orderOfSub:%d", pPObj, pSql,
|
tscTrace("%p sub:%p retrieve numOfRows:%d totalNumOfRows:%d from ip:%u,vid:%d,orderOfSub:%d", pPObj, pSql,
|
||||||
pRes->numOfRows, pState->numOfRetrievedRows, pSvd->ip, pSvd->vnode, idx);
|
pRes->numOfRows, pState->numOfRetrievedRows, pSvd->ip, pSvd->vnode, idx);
|
||||||
|
|
||||||
if (num > tsMaxNumOfOrderedResults) {
|
if (num > tsMaxNumOfOrderedResults && tscIsProjectionQueryOnSTable(pQueryInfo, 0)) {
|
||||||
tscError("%p sub:%p num of OrderedRes is too many, max allowed:%" PRId64 " , current:%" PRId64,
|
tscError("%p sub:%p num of OrderedRes is too many, max allowed:%" PRId64 " , current:%" PRId64,
|
||||||
pPObj, pSql, tsMaxNumOfOrderedResults, num);
|
pPObj, pSql, tsMaxNumOfOrderedResults, num);
|
||||||
tscAbortFurtherRetryRetrieval(trsupport, tres, TSDB_CODE_SORTED_RES_TOO_MANY);
|
tscAbortFurtherRetryRetrieval(trsupport, tres, TSDB_CODE_SORTED_RES_TOO_MANY);
|
||||||
|
@ -1194,7 +1194,7 @@ void tscRetrieveFromVnodeCallBack(void *param, TAOS_RES *tres, int numOfRows) {
|
||||||
SSrcColumnInfo colInfo[256] = {0};
|
SSrcColumnInfo colInfo[256] = {0};
|
||||||
|
|
||||||
tscGetSrcColumnInfo(colInfo, pQueryInfo);
|
tscGetSrcColumnInfo(colInfo, pQueryInfo);
|
||||||
tColModelDisplayEx(pDesc->pSchema, pRes->data, pRes->numOfRows, pRes->numOfRows, colInfo);
|
tColModelDisplayEx(pDesc->pColumnModel, pRes->data, pRes->numOfRows, pRes->numOfRows, colInfo);
|
||||||
#endif
|
#endif
|
||||||
if (tsTotalTmpDirGB != 0 && tsAvailTmpDirGB < tsMinimalTmpDirGB) {
|
if (tsTotalTmpDirGB != 0 && tsAvailTmpDirGB < tsMinimalTmpDirGB) {
|
||||||
tscError("%p sub:%p client disk space remain %.3f GB, need at least %.3f GB, stop query", pPObj, pSql,
|
tscError("%p sub:%p client disk space remain %.3f GB, need at least %.3f GB, stop query", pPObj, pSql,
|
||||||
|
@ -1202,6 +1202,7 @@ void tscRetrieveFromVnodeCallBack(void *param, TAOS_RES *tres, int numOfRows) {
|
||||||
tscAbortFurtherRetryRetrieval(trsupport, tres, TSDB_CODE_CLI_NO_DISKSPACE);
|
tscAbortFurtherRetryRetrieval(trsupport, tres, TSDB_CODE_CLI_NO_DISKSPACE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t ret = saveToBuffer(trsupport->pExtMemBuffer[idx], pDesc, trsupport->localBuffer, pRes->data,
|
int32_t ret = saveToBuffer(trsupport->pExtMemBuffer[idx], pDesc, trsupport->localBuffer, pRes->data,
|
||||||
pRes->numOfRows, pQueryInfo->groupbyExpr.orderType);
|
pRes->numOfRows, pQueryInfo->groupbyExpr.orderType);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
@ -1214,17 +1215,17 @@ void tscRetrieveFromVnodeCallBack(void *param, TAOS_RES *tres, int numOfRows) {
|
||||||
|
|
||||||
} else { // all data has been retrieved to client
|
} else { // all data has been retrieved to client
|
||||||
/* data in from current vnode is stored in cache and disk */
|
/* data in from current vnode is stored in cache and disk */
|
||||||
uint32_t numOfRowsFromVnode = trsupport->pExtMemBuffer[idx]->numOfAllElems + trsupport->localBuffer->numOfElems;
|
uint32_t numOfRowsFromVnode = trsupport->pExtMemBuffer[idx]->numOfTotalElems + trsupport->localBuffer->numOfElems;
|
||||||
tscTrace("%p sub:%p all data retrieved from ip:%u,vid:%d, numOfRows:%d, orderOfSub:%d", pPObj, pSql, pSvd->ip,
|
tscTrace("%p sub:%p all data retrieved from ip:%u,vid:%d, numOfRows:%d, orderOfSub:%d", pPObj, pSql, pSvd->ip,
|
||||||
pSvd->vnode, numOfRowsFromVnode, idx);
|
pSvd->vnode, numOfRowsFromVnode, idx);
|
||||||
|
|
||||||
tColModelCompact(pDesc->pSchema, trsupport->localBuffer, pDesc->pSchema->maxCapacity);
|
tColModelCompact(pDesc->pColumnModel, trsupport->localBuffer, pDesc->pColumnModel->capacity);
|
||||||
|
|
||||||
#ifdef _DEBUG_VIEW
|
#ifdef _DEBUG_VIEW
|
||||||
printf("%" PRIu64 " rows data flushed to disk:\n", trsupport->localBuffer->numOfElems);
|
printf("%" PRIu64 " rows data flushed to disk:\n", trsupport->localBuffer->numOfElems);
|
||||||
SSrcColumnInfo colInfo[256] = {0};
|
SSrcColumnInfo colInfo[256] = {0};
|
||||||
tscGetSrcColumnInfo(colInfo, pQueryInfo);
|
tscGetSrcColumnInfo(colInfo, pQueryInfo);
|
||||||
tColModelDisplayEx(pDesc->pSchema, trsupport->localBuffer->data, trsupport->localBuffer->numOfElems,
|
tColModelDisplayEx(pDesc->pColumnModel, trsupport->localBuffer->data, trsupport->localBuffer->numOfElems,
|
||||||
trsupport->localBuffer->numOfElems, colInfo);
|
trsupport->localBuffer->numOfElems, colInfo);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1256,7 +1257,7 @@ void tscRetrieveFromVnodeCallBack(void *param, TAOS_RES *tres, int numOfRows) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// all sub-queries are returned, start to local merge process
|
// all sub-queries are returned, start to local merge process
|
||||||
pDesc->pSchema->maxCapacity = trsupport->pExtMemBuffer[idx]->numOfElemsPerPage;
|
pDesc->pColumnModel->capacity = trsupport->pExtMemBuffer[idx]->numOfElemsPerPage;
|
||||||
|
|
||||||
tscTrace("%p retrieve from %d vnodes completed.final NumOfRows:%d,start to build loser tree", pPObj,
|
tscTrace("%p retrieve from %d vnodes completed.final NumOfRows:%d,start to build loser tree", pPObj,
|
||||||
pState->numOfTotal, pState->numOfRetrievedRows);
|
pState->numOfTotal, pState->numOfRetrievedRows);
|
||||||
|
@ -1516,7 +1517,7 @@ void tscUpdateVnodeInQueryMsg(SSqlObj *pSql, char *buf) {
|
||||||
char * pStart = buf + tsRpcHeadSize;
|
char * pStart = buf + tsRpcHeadSize;
|
||||||
SQueryMeterMsg *pQueryMsg = (SQueryMeterMsg *)pStart;
|
SQueryMeterMsg *pQueryMsg = (SQueryMeterMsg *)pStart;
|
||||||
|
|
||||||
if (UTIL_METER_IS_NOMRAL_METER(pMeterMetaInfo)) { // pSchema == NULL, query on meter
|
if (UTIL_METER_IS_NOMRAL_METER(pMeterMetaInfo)) { // pColumnModel == NULL, query on meter
|
||||||
SMeterMeta *pMeterMeta = pMeterMetaInfo->pMeterMeta;
|
SMeterMeta *pMeterMeta = pMeterMetaInfo->pMeterMeta;
|
||||||
pQueryMsg->vnode = htons(pMeterMeta->vpeerDesc[pSql->index].vnode);
|
pQueryMsg->vnode = htons(pMeterMeta->vpeerDesc[pSql->index].vnode);
|
||||||
} else { // query on metric
|
} else { // query on metric
|
||||||
|
|
|
@ -396,7 +396,9 @@ static void tscSetSlidingWindowInfo(SSqlObj *pSql, SSqlStream *pStream) {
|
||||||
int64_t minSlidingTime =
|
int64_t minSlidingTime =
|
||||||
(pStream->precision == TSDB_TIME_PRECISION_MICRO) ? tsMinSlidingTime * 1000L : tsMinSlidingTime;
|
(pStream->precision == TSDB_TIME_PRECISION_MICRO) ? tsMinSlidingTime * 1000L : tsMinSlidingTime;
|
||||||
|
|
||||||
if (pQueryInfo->nSlidingTime < minSlidingTime) {
|
if (pQueryInfo->nSlidingTime == -1) {
|
||||||
|
pQueryInfo->nSlidingTime = pQueryInfo->nAggTimeInterval;
|
||||||
|
} else if (pQueryInfo->nSlidingTime < minSlidingTime) {
|
||||||
tscWarn("%p stream:%p, original sliding value:%" PRId64 " too small, reset to:%" PRId64 "", pSql, pStream,
|
tscWarn("%p stream:%p, original sliding value:%" PRId64 " too small, reset to:%" PRId64 "", pSql, pStream,
|
||||||
pQueryInfo->nSlidingTime, minSlidingTime);
|
pQueryInfo->nSlidingTime, minSlidingTime);
|
||||||
|
|
||||||
|
|
|
@ -676,7 +676,7 @@ int32_t tscGetDataBlockFromList(void* pHashList, SDataBlockList* pDataBlockList,
|
||||||
STableDataBlocks** dataBlocks) {
|
STableDataBlocks** dataBlocks) {
|
||||||
*dataBlocks = NULL;
|
*dataBlocks = NULL;
|
||||||
|
|
||||||
STableDataBlocks** t1 = (STableDataBlocks**)taosGetDataFromHash(pHashList, (const char*)&id, sizeof(id));
|
STableDataBlocks** t1 = (STableDataBlocks**)taosGetDataFromHashTable(pHashList, (const char*)&id, sizeof(id));
|
||||||
if (t1 != NULL) {
|
if (t1 != NULL) {
|
||||||
*dataBlocks = *t1;
|
*dataBlocks = *t1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -442,7 +442,6 @@ void vnodeExecuteRetrieveReq(SSchedMsg *pSched) {
|
||||||
|
|
||||||
if (code == TSDB_CODE_SUCCESS) {
|
if (code == TSDB_CODE_SUCCESS) {
|
||||||
size = vnodeGetResultSize((void *)(pRetrieve->qhandle), &numOfRows);
|
size = vnodeGetResultSize((void *)(pRetrieve->qhandle), &numOfRows);
|
||||||
}
|
|
||||||
|
|
||||||
// buffer size for progress information, including meter count,
|
// buffer size for progress information, including meter count,
|
||||||
// and for each meter, including 'uid' and 'TSKEY'.
|
// and for each meter, including 'uid' and 'TSKEY'.
|
||||||
|
@ -457,6 +456,7 @@ void vnodeExecuteRetrieveReq(SSchedMsg *pSched) {
|
||||||
taosSendSimpleRsp(pObj->thandle, TSDB_MSG_TYPE_RETRIEVE_RSP, TSDB_CODE_SERV_OUT_OF_MEMORY);
|
taosSendSimpleRsp(pObj->thandle, TSDB_MSG_TYPE_RETRIEVE_RSP, TSDB_CODE_SERV_OUT_OF_MEMORY);
|
||||||
goto _exit;
|
goto _exit;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pMsg = pStart;
|
pMsg = pStart;
|
||||||
|
|
||||||
|
@ -485,27 +485,29 @@ void vnodeExecuteRetrieveReq(SSchedMsg *pSched) {
|
||||||
|
|
||||||
// write the progress information of each meter to response
|
// write the progress information of each meter to response
|
||||||
// this is required by subscriptions
|
// this is required by subscriptions
|
||||||
|
if (numOfRows > 0 && code == TSDB_CODE_SUCCESS) {
|
||||||
if (pQInfo->pMeterQuerySupporter != NULL && pQInfo->pMeterQuerySupporter->pMeterSidExtInfo != NULL) {
|
if (pQInfo->pMeterQuerySupporter != NULL && pQInfo->pMeterQuerySupporter->pMeterSidExtInfo != NULL) {
|
||||||
*((int32_t*)pMsg) = htonl(pQInfo->pMeterQuerySupporter->numOfMeters);
|
*((int32_t *)pMsg) = htonl(pQInfo->pMeterQuerySupporter->numOfMeters);
|
||||||
pMsg += sizeof(int32_t);
|
pMsg += sizeof(int32_t);
|
||||||
for (int32_t i = 0; i < pQInfo->pMeterQuerySupporter->numOfMeters; i++) {
|
for (int32_t i = 0; i < pQInfo->pMeterQuerySupporter->numOfMeters; i++) {
|
||||||
*((int64_t*)pMsg) = htobe64(pQInfo->pMeterQuerySupporter->pMeterSidExtInfo[i]->uid);
|
*((int64_t *)pMsg) = htobe64(pQInfo->pMeterQuerySupporter->pMeterSidExtInfo[i]->uid);
|
||||||
pMsg += sizeof(int64_t);
|
pMsg += sizeof(int64_t);
|
||||||
*((TSKEY*)pMsg) = htobe64(pQInfo->pMeterQuerySupporter->pMeterSidExtInfo[i]->key);
|
*((TSKEY *)pMsg) = htobe64(pQInfo->pMeterQuerySupporter->pMeterSidExtInfo[i]->key);
|
||||||
pMsg += sizeof(TSKEY);
|
pMsg += sizeof(TSKEY);
|
||||||
}
|
}
|
||||||
} else if (pQInfo->pObj != NULL) {
|
} else if (pQInfo->pObj != NULL) {
|
||||||
*((int32_t*)pMsg) = htonl(1);
|
*((int32_t *)pMsg) = htonl(1);
|
||||||
pMsg += sizeof(int32_t);
|
pMsg += sizeof(int32_t);
|
||||||
*((int64_t*)pMsg) = htobe64(pQInfo->pObj->uid);
|
*((int64_t *)pMsg) = htobe64(pQInfo->pObj->uid);
|
||||||
pMsg += sizeof(int64_t);
|
pMsg += sizeof(int64_t);
|
||||||
if (pQInfo->pointsRead > 0) {
|
if (pQInfo->pointsRead > 0) {
|
||||||
*((TSKEY*)pMsg) = htobe64(pQInfo->query.lastKey + 1);
|
*((TSKEY *)pMsg) = htobe64(pQInfo->query.lastKey + 1);
|
||||||
} else {
|
} else {
|
||||||
*((TSKEY*)pMsg) = htobe64(pQInfo->query.lastKey);
|
*((TSKEY *)pMsg) = htobe64(pQInfo->query.lastKey);
|
||||||
}
|
}
|
||||||
pMsg += sizeof(TSKEY);
|
pMsg += sizeof(TSKEY);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
msgLen = pMsg - pStart;
|
msgLen = pMsg - pStart;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TDENGINE_TPERCENTILE_H
|
||||||
|
#define TDENGINE_TPERCENTILE_H
|
||||||
|
|
||||||
|
#include "textbuffer.h"
|
||||||
|
|
||||||
|
typedef struct MinMaxEntry {
|
||||||
|
union {
|
||||||
|
double dMinVal;
|
||||||
|
int32_t iMinVal;
|
||||||
|
int64_t i64MinVal;
|
||||||
|
};
|
||||||
|
union {
|
||||||
|
double dMaxVal;
|
||||||
|
int32_t iMaxVal;
|
||||||
|
int64_t i64MaxVal;
|
||||||
|
};
|
||||||
|
} MinMaxEntry;
|
||||||
|
|
||||||
|
typedef struct tMemBucketSegment {
|
||||||
|
int32_t numOfSlots;
|
||||||
|
MinMaxEntry * pBoundingEntries;
|
||||||
|
tExtMemBuffer **pBuffer;
|
||||||
|
} tMemBucketSegment;
|
||||||
|
|
||||||
|
typedef struct tMemBucket {
|
||||||
|
int16_t numOfSegs;
|
||||||
|
int16_t nTotalSlots;
|
||||||
|
int16_t nSlotsOfSeg;
|
||||||
|
int16_t dataType;
|
||||||
|
|
||||||
|
int16_t nElemSize;
|
||||||
|
int32_t numOfElems;
|
||||||
|
|
||||||
|
int32_t nTotalBufferSize;
|
||||||
|
int32_t maxElemsCapacity;
|
||||||
|
|
||||||
|
int16_t pageSize;
|
||||||
|
int16_t numOfTotalPages;
|
||||||
|
int16_t numOfAvailPages; /* remain available buffer pages */
|
||||||
|
|
||||||
|
tMemBucketSegment *pSegs;
|
||||||
|
tOrderDescriptor * pOrderDesc;
|
||||||
|
|
||||||
|
MinMaxEntry nRange;
|
||||||
|
|
||||||
|
void (*HashFunc)(struct tMemBucket *pBucket, void *value, int16_t *segIdx, int16_t *slotIdx);
|
||||||
|
} tMemBucket;
|
||||||
|
|
||||||
|
tMemBucket *tMemBucketCreate(int32_t totalSlots, int32_t nBufferSize, int16_t nElemSize, int16_t dataType,
|
||||||
|
tOrderDescriptor *pDesc);
|
||||||
|
|
||||||
|
void tMemBucketDestroy(tMemBucket *pBucket);
|
||||||
|
|
||||||
|
void tMemBucketPut(tMemBucket *pBucket, void *data, int32_t numOfRows);
|
||||||
|
|
||||||
|
double getPercentile(tMemBucket *pMemBucket, double percent);
|
||||||
|
|
||||||
|
void tBucketIntHash(tMemBucket *pBucket, void *value, int16_t *segIdx, int16_t *slotIdx);
|
||||||
|
|
||||||
|
void tBucketDoubleHash(tMemBucket *pBucket, void *value, int16_t *segIdx, int16_t *slotIdx);
|
||||||
|
|
||||||
|
#endif // TDENGINE_TPERCENTILE_H
|
|
@ -0,0 +1,104 @@
|
||||||
|
#ifndef TDENGINE_VNODEQUERYUTIL_H
|
||||||
|
#define TDENGINE_VNODEQUERYUTIL_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "os.h"
|
||||||
|
#include "textbuffer.h"
|
||||||
|
|
||||||
|
typedef struct SIDList {
|
||||||
|
uint32_t alloc;
|
||||||
|
int32_t size;
|
||||||
|
int32_t* pData;
|
||||||
|
} SIDList;
|
||||||
|
|
||||||
|
typedef struct SQueryResultBuf {
|
||||||
|
int32_t numOfRowsPerPage;
|
||||||
|
int32_t numOfPages;
|
||||||
|
int64_t totalBufSize;
|
||||||
|
int32_t fd; // data file fd
|
||||||
|
int32_t allocateId; // allocated page id
|
||||||
|
int32_t incStep; // minimum allocated pages
|
||||||
|
char* pBuf; // mmap buffer pointer
|
||||||
|
char* path; // file path
|
||||||
|
|
||||||
|
uint32_t numOfAllocGroupIds; // number of allocated id list
|
||||||
|
void* idsTable; // id hash table
|
||||||
|
SIDList* list; // for each id, there is a page id list
|
||||||
|
} SQueryResultBuf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create disk-based result buffer
|
||||||
|
* @param pResultBuf
|
||||||
|
* @param size
|
||||||
|
* @param rowSize
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int32_t createResultBuf(SQueryResultBuf** pResultBuf, int32_t size, int32_t rowSize);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param pResultBuf
|
||||||
|
* @param groupId
|
||||||
|
* @param pageId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
tFilePage* getNewDataBuf(SQueryResultBuf* pResultBuf, int32_t groupId, int32_t* pageId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param pResultBuf
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int32_t getNumOfRowsPerPage(SQueryResultBuf* pResultBuf);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param pResultBuf
|
||||||
|
* @param groupId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
SIDList getDataBufPagesIdList(SQueryResultBuf* pResultBuf, int32_t groupId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the specified buffer page by id
|
||||||
|
* @param pResultBuf
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
tFilePage* getResultBufferPageById(SQueryResultBuf* pResultBuf, int32_t id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the total buffer size in the format of disk file
|
||||||
|
* @param pResultBuf
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int32_t getResBufSize(SQueryResultBuf* pResultBuf);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the number of groups in the result buffer
|
||||||
|
* @param pResultBuf
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int32_t getNumOfResultBufGroupId(SQueryResultBuf* pResultBuf);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* destroy result buffer
|
||||||
|
* @param pResultBuf
|
||||||
|
*/
|
||||||
|
void destroyResultBuf(SQueryResultBuf* pResultBuf);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param pList
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int32_t getLastPageId(SIDList *pList);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // TDENGINE_VNODEQUERYUTIL_H
|
|
@ -11,7 +11,13 @@ IF ((TD_LINUX_64) OR (TD_LINUX_32 AND TD_ARM))
|
||||||
LIST(REMOVE_ITEM SRC ./src/shellWindows.c)
|
LIST(REMOVE_ITEM SRC ./src/shellWindows.c)
|
||||||
LIST(REMOVE_ITEM SRC ./src/shellDarwin.c)
|
LIST(REMOVE_ITEM SRC ./src/shellDarwin.c)
|
||||||
ADD_EXECUTABLE(shell ${SRC})
|
ADD_EXECUTABLE(shell ${SRC})
|
||||||
|
|
||||||
|
IF (TD_PAGMODE_LITE)
|
||||||
|
TARGET_LINK_LIBRARIES(shell taos)
|
||||||
|
ELSE ()
|
||||||
TARGET_LINK_LIBRARIES(shell taos_static)
|
TARGET_LINK_LIBRARIES(shell taos_static)
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
SET_TARGET_PROPERTIES(shell PROPERTIES OUTPUT_NAME taos)
|
SET_TARGET_PROPERTIES(shell PROPERTIES OUTPUT_NAME taos)
|
||||||
ELSEIF (TD_WINDOWS_64)
|
ELSEIF (TD_WINDOWS_64)
|
||||||
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/pthread)
|
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/pthread)
|
||||||
|
|
|
@ -9,5 +9,11 @@ INCLUDE_DIRECTORIES(inc)
|
||||||
IF ((TD_LINUX_64) OR (TD_LINUX_32 AND TD_ARM))
|
IF ((TD_LINUX_64) OR (TD_LINUX_32 AND TD_ARM))
|
||||||
AUX_SOURCE_DIRECTORY(. SRC)
|
AUX_SOURCE_DIRECTORY(. SRC)
|
||||||
ADD_EXECUTABLE(taosdemo ${SRC})
|
ADD_EXECUTABLE(taosdemo ${SRC})
|
||||||
|
|
||||||
|
IF (TD_PAGMODE_LITE)
|
||||||
|
TARGET_LINK_LIBRARIES(taosdemo taos)
|
||||||
|
ELSE ()
|
||||||
TARGET_LINK_LIBRARIES(taosdemo taos_static)
|
TARGET_LINK_LIBRARIES(taosdemo taos_static)
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
|
@ -9,5 +9,12 @@ INCLUDE_DIRECTORIES(inc)
|
||||||
IF ((TD_LINUX_64) OR (TD_LINUX_32 AND TD_ARM))
|
IF ((TD_LINUX_64) OR (TD_LINUX_32 AND TD_ARM))
|
||||||
AUX_SOURCE_DIRECTORY(. SRC)
|
AUX_SOURCE_DIRECTORY(. SRC)
|
||||||
ADD_EXECUTABLE(taosdump ${SRC})
|
ADD_EXECUTABLE(taosdump ${SRC})
|
||||||
|
|
||||||
|
IF (TD_PAGMODE_LITE)
|
||||||
|
TARGET_LINK_LIBRARIES(taosdump taos)
|
||||||
|
ELSE ()
|
||||||
TARGET_LINK_LIBRARIES(taosdump taos_static)
|
TARGET_LINK_LIBRARIES(taosdump taos_static)
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
|
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
|
@ -211,7 +211,7 @@ char *mgmtBuildCreateMeterIe(STabObj *pTable, char *pMsg, int vnode) {
|
||||||
|
|
||||||
for (int i = 0; i < pTable->numOfColumns; ++i) {
|
for (int i = 0; i < pTable->numOfColumns; ++i) {
|
||||||
pCreateMeter->schema[i].type = pSchema[i].type;
|
pCreateMeter->schema[i].type = pSchema[i].type;
|
||||||
/* strcpy(pCreateMeter->schema[i].name, pSchema[i].name); */
|
/* strcpy(pCreateMeter->schema[i].name, pColumnModel[i].name); */
|
||||||
pCreateMeter->schema[i].bytes = htons(pSchema[i].bytes);
|
pCreateMeter->schema[i].bytes = htons(pSchema[i].bytes);
|
||||||
pCreateMeter->schema[i].colId = htons(pSchema[i].colId);
|
pCreateMeter->schema[i].colId = htons(pSchema[i].colId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||||
|
PROJECT(TDengine)
|
||||||
|
|
||||||
|
ADD_SUBDIRECTORY(detail)
|
||||||
|
|
||||||
|
IF (TD_EDGE)
|
||||||
|
ADD_SUBDIRECTORY(lite)
|
||||||
|
ENDIF ()
|
|
@ -0,0 +1,46 @@
|
||||||
|
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||||
|
PROJECT(TDengine)
|
||||||
|
|
||||||
|
IF ((TD_LINUX_64) OR (TD_LINUX_32 AND TD_ARM))
|
||||||
|
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/inc)
|
||||||
|
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/client/inc)
|
||||||
|
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/modules/http/inc)
|
||||||
|
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/modules/monitor/inc)
|
||||||
|
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/inc)
|
||||||
|
INCLUDE_DIRECTORIES(${TD_ENTERPRISE_DIR}/src/util/cluster/inc)
|
||||||
|
INCLUDE_DIRECTORIES(${TD_OS_DIR}/inc)
|
||||||
|
INCLUDE_DIRECTORIES(inc)
|
||||||
|
AUX_SOURCE_DIRECTORY(./src SRC)
|
||||||
|
LIST(REMOVE_ITEM SRC ./src/vnodeFileUtil.c)
|
||||||
|
LIST(REMOVE_ITEM SRC ./src/taosGrant.c)
|
||||||
|
|
||||||
|
ADD_EXECUTABLE(taosd ${SRC})
|
||||||
|
|
||||||
|
IF (TD_PAGMODE_LITE)
|
||||||
|
TARGET_LINK_LIBRARIES(taosd taos trpc tutil sdb monitor pthread http)
|
||||||
|
ELSE ()
|
||||||
|
TARGET_LINK_LIBRARIES(taosd taos_static trpc tutil sdb monitor pthread http)
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
|
IF (TD_EDGE)
|
||||||
|
TARGET_LINK_LIBRARIES(taosd taosd_edge)
|
||||||
|
ELSE ()
|
||||||
|
TARGET_LINK_LIBRARIES(taosd taosd_cluster)
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
|
SET(PREPARE_ENV_CMD "prepare_env_cmd")
|
||||||
|
SET(PREPARE_ENV_TARGET "prepare_env_target")
|
||||||
|
ADD_CUSTOM_COMMAND(OUTPUT ${PREPARE_ENV_CMD}
|
||||||
|
POST_BUILD
|
||||||
|
COMMAND echo "make test directory"
|
||||||
|
DEPENDS taosd
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E make_directory ${TD_TESTS_OUTPUT_DIR}/cfg/
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E make_directory ${TD_TESTS_OUTPUT_DIR}/log/
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E make_directory ${TD_TESTS_OUTPUT_DIR}/data/
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E echo dataDir ${TD_TESTS_OUTPUT_DIR}/data > ${TD_TESTS_OUTPUT_DIR}/cfg/taos.cfg
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E echo logDir ${TD_TESTS_OUTPUT_DIR}/log >> ${TD_TESTS_OUTPUT_DIR}/cfg/taos.cfg
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E echo charset UTF-8 >> ${TD_TESTS_OUTPUT_DIR}/cfg/taos.cfg
|
||||||
|
COMMENT "prepare taosd environment")
|
||||||
|
ADD_CUSTOM_TARGET(${PREPARE_ENV_TARGET} ALL WORKING_DIRECTORY ${TD_EXECUTABLE_OUTPUT_PATH} DEPENDS ${PREPARE_ENV_CMD})
|
||||||
|
|
||||||
|
ENDIF ()
|
|
@ -0,0 +1,17 @@
|
||||||
|
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||||
|
PROJECT(TDengine)
|
||||||
|
|
||||||
|
IF ((TD_LINUX_64) OR (TD_LINUX_32 AND TD_ARM))
|
||||||
|
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/inc)
|
||||||
|
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/client/inc)
|
||||||
|
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/modules/http/inc)
|
||||||
|
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/modules/monitor/inc)
|
||||||
|
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/system/detail/inc)
|
||||||
|
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/inc)
|
||||||
|
INCLUDE_DIRECTORIES(${TD_ENTERPRISE_DIR}/src/util/cluster/inc)
|
||||||
|
INCLUDE_DIRECTORIES(${TD_OS_DIR}/inc)
|
||||||
|
INCLUDE_DIRECTORIES(inc)
|
||||||
|
|
||||||
|
AUX_SOURCE_DIRECTORY(./src SRC)
|
||||||
|
ADD_LIBRARY(taosd_edge ${SRC})
|
||||||
|
ENDIF ()
|
|
@ -43,10 +43,10 @@ typedef struct SHashEntry {
|
||||||
|
|
||||||
typedef struct HashObj {
|
typedef struct HashObj {
|
||||||
SHashEntry **hashList;
|
SHashEntry **hashList;
|
||||||
uint32_t capacity;
|
uint32_t capacity; // number of slots
|
||||||
int size;
|
int size; // number of elements in hash table
|
||||||
_hash_fn_t hashFp;
|
_hash_fn_t hashFp; // hash function
|
||||||
bool multithreadSafe; // enable lock
|
bool multithreadSafe; // enable lock or not
|
||||||
|
|
||||||
#if defined LINUX
|
#if defined LINUX
|
||||||
pthread_rwlock_t lock;
|
pthread_rwlock_t lock;
|
||||||
|
@ -57,11 +57,13 @@ typedef struct HashObj {
|
||||||
} HashObj;
|
} HashObj;
|
||||||
|
|
||||||
void *taosInitHashTable(uint32_t capacity, _hash_fn_t fn, bool multithreadSafe);
|
void *taosInitHashTable(uint32_t capacity, _hash_fn_t fn, bool multithreadSafe);
|
||||||
|
|
||||||
int32_t taosAddToHashTable(HashObj *pObj, const char *key, uint32_t keyLen, void *data, uint32_t size);
|
|
||||||
void taosDeleteFromHashTable(HashObj *pObj, const char *key, uint32_t keyLen);
|
void taosDeleteFromHashTable(HashObj *pObj, const char *key, uint32_t keyLen);
|
||||||
|
|
||||||
char *taosGetDataFromHash(HashObj *pObj, const char *key, uint32_t keyLen);
|
int32_t taosAddToHashTable(HashObj *pObj, const char *key, uint32_t keyLen, void *data, uint32_t size);
|
||||||
|
int32_t taosNumElemsInHashTable(HashObj *pObj);
|
||||||
|
|
||||||
|
char *taosGetDataFromHashTable(HashObj *pObj, const char *key, uint32_t keyLen);
|
||||||
|
|
||||||
|
|
||||||
void taosCleanUpHashTable(void *handle);
|
void taosCleanUpHashTable(void *handle);
|
||||||
|
|
||||||
|
|
|
@ -19,21 +19,15 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include "os.h"
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "tutil.h"
|
|
||||||
#include "taosmsg.h"
|
#include "taosmsg.h"
|
||||||
|
#include "tutil.h"
|
||||||
|
|
||||||
#define DEFAULT_PAGE_SIZE 16384 // 16k larger than the SHistoInfo
|
#define DEFAULT_PAGE_SIZE 16384 // 16k larger than the SHistoInfo
|
||||||
#define MIN_BUFFER_SIZE (1 << 19)
|
#define MIN_BUFFER_SIZE (1 << 19)
|
||||||
#define MAX_TMPFILE_PATH_LENGTH PATH_MAX
|
#define MAX_TMPFILE_PATH_LENGTH PATH_MAX
|
||||||
#define INITIAL_ALLOCATION_BUFFER_SIZE 64
|
#define INITIAL_ALLOCATION_BUFFER_SIZE 64
|
||||||
|
|
||||||
// forward declare
|
|
||||||
struct tTagSchema;
|
|
||||||
|
|
||||||
typedef enum EXT_BUFFER_FLUSH_MODEL {
|
typedef enum EXT_BUFFER_FLUSH_MODEL {
|
||||||
/*
|
/*
|
||||||
* all data that have been flushed to disk is belonged to the same group
|
* all data that have been flushed to disk is belonged to the same group
|
||||||
|
@ -61,12 +55,12 @@ typedef struct tFlushoutData {
|
||||||
tFlushoutInfo *pFlushoutInfo;
|
tFlushoutInfo *pFlushoutInfo;
|
||||||
} tFlushoutData;
|
} tFlushoutData;
|
||||||
|
|
||||||
typedef struct tFileMeta {
|
typedef struct SFileInfo {
|
||||||
uint32_t nFileSize; // in pages
|
uint32_t nFileSize; // in pages
|
||||||
uint32_t nPageSize;
|
uint32_t pageSize;
|
||||||
uint32_t numOfElemsInFile;
|
uint32_t numOfElemsInFile;
|
||||||
tFlushoutData flushoutData;
|
tFlushoutData flushoutData;
|
||||||
} tFileMeta;
|
} SFileInfo;
|
||||||
|
|
||||||
typedef struct tFilePage {
|
typedef struct tFilePage {
|
||||||
uint64_t numOfElems;
|
uint64_t numOfElems;
|
||||||
|
@ -78,51 +72,50 @@ typedef struct tFilePagesItem {
|
||||||
tFilePage item;
|
tFilePage item;
|
||||||
} tFilePagesItem;
|
} tFilePagesItem;
|
||||||
|
|
||||||
typedef struct tColModel {
|
typedef struct SSchemaEx {
|
||||||
int32_t maxCapacity;
|
struct SSchema field;
|
||||||
int32_t numOfCols;
|
int16_t offset;
|
||||||
int16_t * colOffset;
|
} SSchemaEx;
|
||||||
struct SSchema *pFields;
|
|
||||||
} tColModel;
|
|
||||||
|
|
||||||
typedef struct tOrderIdx {
|
typedef struct SColumnModel {
|
||||||
int32_t numOfOrderedCols;
|
int32_t capacity;
|
||||||
|
int32_t numOfCols;
|
||||||
|
int16_t rowSize;
|
||||||
|
SSchemaEx *pFields;
|
||||||
|
} SColumnModel;
|
||||||
|
|
||||||
|
typedef struct SColumnOrderInfo {
|
||||||
|
int32_t numOfCols;
|
||||||
int16_t pData[];
|
int16_t pData[];
|
||||||
} tOrderIdx;
|
} SColumnOrderInfo;
|
||||||
|
|
||||||
typedef struct tOrderDescriptor {
|
typedef struct tOrderDescriptor {
|
||||||
union {
|
SColumnModel * pColumnModel;
|
||||||
struct tTagSchema *pTagSchema;
|
|
||||||
tColModel * pSchema;
|
|
||||||
};
|
|
||||||
int32_t tsOrder; // timestamp order type if exists
|
int32_t tsOrder; // timestamp order type if exists
|
||||||
tOrderIdx orderIdx;
|
SColumnOrderInfo orderIdx;
|
||||||
} tOrderDescriptor;
|
} tOrderDescriptor;
|
||||||
|
|
||||||
typedef struct tExtMemBuffer {
|
typedef struct tExtMemBuffer {
|
||||||
int32_t nMaxSizeInPages;
|
int32_t inMemCapacity;
|
||||||
|
|
||||||
int32_t nElemSize;
|
int32_t nElemSize;
|
||||||
int32_t nPageSize;
|
int32_t pageSize;
|
||||||
|
int32_t numOfTotalElems;
|
||||||
int32_t numOfAllElems;
|
|
||||||
int32_t numOfElemsInBuffer;
|
int32_t numOfElemsInBuffer;
|
||||||
int32_t numOfElemsPerPage;
|
int32_t numOfElemsPerPage;
|
||||||
|
int16_t numOfInMemPages;
|
||||||
|
|
||||||
int16_t numOfPagesInMem;
|
|
||||||
tFilePagesItem *pHead;
|
tFilePagesItem *pHead;
|
||||||
tFilePagesItem *pTail;
|
tFilePagesItem *pTail;
|
||||||
|
|
||||||
tFileMeta fileMeta;
|
char * path;
|
||||||
|
FILE * file;
|
||||||
char dataFilePath[MAX_TMPFILE_PATH_LENGTH];
|
SFileInfo fileMeta;
|
||||||
FILE *dataFile;
|
|
||||||
|
|
||||||
tColModel *pColModel;
|
|
||||||
|
|
||||||
|
SColumnModel * pColumnModel;
|
||||||
EXT_BUFFER_FLUSH_MODEL flushModel;
|
EXT_BUFFER_FLUSH_MODEL flushModel;
|
||||||
} tExtMemBuffer;
|
} tExtMemBuffer;
|
||||||
|
|
||||||
|
<<<<<<< HEAD:src/util/inc/textbuffer.h
|
||||||
typedef struct tTagSchema {
|
typedef struct tTagSchema {
|
||||||
struct SSchema *pSchema;
|
struct SSchema *pSchema;
|
||||||
int32_t numOfCols;
|
int32_t numOfCols;
|
||||||
|
@ -139,20 +132,32 @@ typedef struct tSidSet {
|
||||||
tOrderIdx orderIdx;
|
tOrderIdx orderIdx;
|
||||||
} tSidSet;
|
} tSidSet;
|
||||||
|
|
||||||
|
=======
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param fileNamePattern
|
||||||
|
* @param dstPath
|
||||||
|
*/
|
||||||
|
>>>>>>> develop:src/inc/textbuffer.h
|
||||||
void getTmpfilePath(const char *fileNamePattern, char *dstPath);
|
void getTmpfilePath(const char *fileNamePattern, char *dstPath);
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* create ext-memory buffer
|
*
|
||||||
|
* @param inMemSize
|
||||||
|
* @param elemSize
|
||||||
|
* @param pModel
|
||||||
|
* @return
|
||||||
*/
|
*/
|
||||||
void tExtMemBufferCreate(tExtMemBuffer **pMemBuffer, int32_t numOfBufferSize, int32_t elemSize,
|
tExtMemBuffer *createExtMemBuffer(int32_t inMemSize, int32_t elemSize, SColumnModel *pModel);
|
||||||
const char *tmpDataFilePath, tColModel *pModel);
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* destroy ext-memory buffer
|
*
|
||||||
|
* @param pMemBuffer
|
||||||
|
* @return
|
||||||
*/
|
*/
|
||||||
void tExtMemBufferDestroy(tExtMemBuffer **pMemBuffer);
|
void *destoryExtMemBuffer(tExtMemBuffer *pMemBuffer);
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* @param pMemBuffer
|
* @param pMemBuffer
|
||||||
* @param data input data pointer
|
* @param data input data pointer
|
||||||
* @param numOfRows number of rows in data
|
* @param numOfRows number of rows in data
|
||||||
|
@ -161,12 +166,15 @@ void tExtMemBufferDestroy(tExtMemBuffer **pMemBuffer);
|
||||||
*/
|
*/
|
||||||
int16_t tExtMemBufferPut(tExtMemBuffer *pMemBuffer, void *data, int32_t numOfRows);
|
int16_t tExtMemBufferPut(tExtMemBuffer *pMemBuffer, void *data, int32_t numOfRows);
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* flush all data into disk and release all in-memory buffer
|
*
|
||||||
|
* @param pMemBuffer
|
||||||
|
* @return
|
||||||
*/
|
*/
|
||||||
bool tExtMemBufferFlush(tExtMemBuffer *pMemBuffer);
|
bool tExtMemBufferFlush(tExtMemBuffer *pMemBuffer);
|
||||||
|
|
||||||
/*
|
/**
|
||||||
|
*
|
||||||
* remove all data that has been put into buffer, including in buffer or
|
* remove all data that has been put into buffer, including in buffer or
|
||||||
* ext-buffer(disk)
|
* ext-buffer(disk)
|
||||||
*/
|
*/
|
||||||
|
@ -179,11 +187,44 @@ void tExtMemBufferClear(tExtMemBuffer *pMemBuffer);
|
||||||
*/
|
*/
|
||||||
bool tExtMemBufferLoadData(tExtMemBuffer *pMemBuffer, tFilePage *pFilePage, int32_t flushIdx, int32_t pageIdx);
|
bool tExtMemBufferLoadData(tExtMemBuffer *pMemBuffer, tFilePage *pFilePage, int32_t flushIdx, int32_t pageIdx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param pMemBuffer
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
bool tExtMemBufferIsAllDataInMem(tExtMemBuffer *pMemBuffer);
|
bool tExtMemBufferIsAllDataInMem(tExtMemBuffer *pMemBuffer);
|
||||||
|
|
||||||
tColModel *tColModelCreate(SSchema *field, int32_t numOfCols, int32_t maxCapacity);
|
/**
|
||||||
|
*
|
||||||
|
* @param fields
|
||||||
|
* @param numOfCols
|
||||||
|
* @param blockCapacity
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
SColumnModel *createColumnModel(SSchema *fields, int32_t numOfCols, int32_t blockCapacity);
|
||||||
|
|
||||||
void tColModelDestroy(tColModel *pModel);
|
/**
|
||||||
|
*
|
||||||
|
* @param pSrc
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
SColumnModel *cloneColumnModel(SColumnModel *pSrc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param pModel
|
||||||
|
*/
|
||||||
|
void destroyColumnModel(SColumnModel *pModel);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* compress data into consecutive block without hole in data
|
||||||
|
*/
|
||||||
|
void tColModelCompact(SColumnModel *pModel, tFilePage *inputBuffer, int32_t maxElemsCapacity);
|
||||||
|
|
||||||
|
void tColModelErase(SColumnModel *pModel, tFilePage *inputBuffer, int32_t maxCapacity, int32_t s, int32_t e);
|
||||||
|
SSchema *getColumnModelSchema(SColumnModel *pColumnModel, int32_t index);
|
||||||
|
|
||||||
|
int16_t getColumnModelOffset(SColumnModel *pColumnModel, int32_t index);
|
||||||
|
|
||||||
typedef struct SSrcColumnInfo {
|
typedef struct SSrcColumnInfo {
|
||||||
int32_t functionId;
|
int32_t functionId;
|
||||||
|
@ -193,68 +234,18 @@ typedef struct SSrcColumnInfo {
|
||||||
/*
|
/*
|
||||||
* display data in column format model for debug purpose only
|
* display data in column format model for debug purpose only
|
||||||
*/
|
*/
|
||||||
void tColModelDisplay(tColModel *pModel, void *pData, int32_t numOfRows, int32_t maxCount);
|
void tColModelDisplay(SColumnModel *pModel, void *pData, int32_t numOfRows, int32_t maxCount);
|
||||||
|
|
||||||
void tColModelDisplayEx(tColModel *pModel, void *pData, int32_t numOfRows, int32_t maxCount, SSrcColumnInfo *pInfo);
|
void tColModelDisplayEx(SColumnModel *pModel, void *pData, int32_t numOfRows, int32_t maxCount, SSrcColumnInfo *pInfo);
|
||||||
|
|
||||||
/*
|
tOrderDescriptor *tOrderDesCreate(const int32_t *orderColIdx, int32_t numOfOrderCols, SColumnModel *pModel,
|
||||||
* compress data into consecutive block without hole in data
|
int32_t tsOrderType);
|
||||||
*/
|
|
||||||
void tColModelCompact(tColModel *pModel, tFilePage *inputBuffer, int32_t maxElemsCapacity);
|
|
||||||
|
|
||||||
void tColModelErase(tColModel *pModel, tFilePage *inputBuffer, int32_t maxCapacity, int32_t s, int32_t e);
|
|
||||||
|
|
||||||
tOrderDescriptor *tOrderDesCreate(int32_t *orderColIdx, int32_t numOfOrderCols, tColModel *pModel, int32_t tsOrderType);
|
|
||||||
|
|
||||||
void tOrderDescDestroy(tOrderDescriptor *pDesc);
|
void tOrderDescDestroy(tOrderDescriptor *pDesc);
|
||||||
|
|
||||||
void tColModelAppend(tColModel *dstModel, tFilePage *dstPage, void *srcData, int32_t srcStartRows,
|
void tColModelAppend(SColumnModel *dstModel, tFilePage *dstPage, void *srcData, int32_t srcStartRows,
|
||||||
int32_t numOfRowsToWrite, int32_t srcCapacity);
|
int32_t numOfRowsToWrite, int32_t srcCapacity);
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
typedef struct MinMaxEntry {
|
|
||||||
union {
|
|
||||||
double dMinVal;
|
|
||||||
int32_t iMinVal;
|
|
||||||
int64_t i64MinVal;
|
|
||||||
};
|
|
||||||
union {
|
|
||||||
double dMaxVal;
|
|
||||||
int32_t iMaxVal;
|
|
||||||
int64_t i64MaxVal;
|
|
||||||
};
|
|
||||||
} MinMaxEntry;
|
|
||||||
|
|
||||||
typedef struct tMemBucketSegment {
|
|
||||||
int32_t numOfSlots;
|
|
||||||
MinMaxEntry * pBoundingEntries;
|
|
||||||
tExtMemBuffer **pBuffer;
|
|
||||||
} tMemBucketSegment;
|
|
||||||
|
|
||||||
typedef struct tMemBucket {
|
|
||||||
int16_t numOfSegs;
|
|
||||||
int16_t nTotalSlots;
|
|
||||||
int16_t nSlotsOfSeg;
|
|
||||||
int16_t dataType;
|
|
||||||
|
|
||||||
int16_t nElemSize;
|
|
||||||
int32_t numOfElems;
|
|
||||||
|
|
||||||
int32_t nTotalBufferSize;
|
|
||||||
int32_t maxElemsCapacity;
|
|
||||||
|
|
||||||
int16_t nPageSize;
|
|
||||||
int16_t numOfTotalPages;
|
|
||||||
int16_t numOfAvailPages; /* remain available buffer pages */
|
|
||||||
|
|
||||||
tMemBucketSegment *pSegs;
|
|
||||||
tOrderDescriptor * pOrderDesc;
|
|
||||||
|
|
||||||
MinMaxEntry nRange;
|
|
||||||
|
|
||||||
void (*HashFunc)(struct tMemBucket *pBucket, void *value, int16_t *segIdx, int16_t *slotIdx);
|
|
||||||
} tMemBucket;
|
|
||||||
|
|
||||||
typedef int (*__col_compar_fn_t)(tOrderDescriptor *, int32_t numOfRows, int32_t idx1, int32_t idx2, char *data);
|
typedef int (*__col_compar_fn_t)(tOrderDescriptor *, int32_t numOfRows, int32_t idx1, int32_t idx2, char *data);
|
||||||
|
|
||||||
void tColDataQSort(tOrderDescriptor *, int32_t numOfRows, int32_t start, int32_t end, char *data, int32_t orderType);
|
void tColDataQSort(tOrderDescriptor *, int32_t numOfRows, int32_t start, int32_t end, char *data, int32_t orderType);
|
||||||
|
@ -269,19 +260,6 @@ int32_t compare_a(tOrderDescriptor *, int32_t numOfRow1, int32_t s1, char *data1
|
||||||
int32_t compare_d(tOrderDescriptor *, int32_t numOfRow1, int32_t s1, char *data1, int32_t numOfRow2, int32_t s2,
|
int32_t compare_d(tOrderDescriptor *, int32_t numOfRow1, int32_t s1, char *data1, int32_t numOfRow2, int32_t s2,
|
||||||
char *data2);
|
char *data2);
|
||||||
|
|
||||||
tMemBucket* tMemBucketCreate(int32_t totalSlots, int32_t nBufferSize, int16_t nElemSize,
|
|
||||||
int16_t dataType, tOrderDescriptor *pDesc);
|
|
||||||
|
|
||||||
void tMemBucketDestroy(tMemBucket *pBucket);
|
|
||||||
|
|
||||||
void tMemBucketPut(tMemBucket *pBucket, void *data, int32_t numOfRows);
|
|
||||||
|
|
||||||
double getPercentile(tMemBucket *pMemBucket, double percent);
|
|
||||||
|
|
||||||
void tBucketIntHash(tMemBucket *pBucket, void *value, int16_t *segIdx, int16_t *slotIdx);
|
|
||||||
|
|
||||||
void tBucketDoubleHash(tMemBucket *pBucket, void *value, int16_t *segIdx, int16_t *slotIdx);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -20,8 +20,6 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "tskiplist.h"
|
|
||||||
|
|
||||||
#define USE_ARRAYLIST
|
#define USE_ARRAYLIST
|
||||||
|
|
||||||
#define MAX_HISTOGRAM_BIN 500
|
#define MAX_HISTOGRAM_BIN 500
|
||||||
|
|
|
@ -78,7 +78,7 @@ int32_t taosNumOfRemainPoints(SInterpolationInfo *pInterpoInfo);
|
||||||
*/
|
*/
|
||||||
int32_t taosDoInterpoResult(SInterpolationInfo *pInterpoInfo, int16_t interpoType, tFilePage **data,
|
int32_t taosDoInterpoResult(SInterpolationInfo *pInterpoInfo, int16_t interpoType, tFilePage **data,
|
||||||
int32_t numOfRawDataInRows, int32_t outputRows, int64_t nInterval,
|
int32_t numOfRawDataInRows, int32_t outputRows, int64_t nInterval,
|
||||||
const int64_t *pPrimaryKeyArray, tColModel *pModel, char **srcData, int64_t *defaultVal,
|
const int64_t *pPrimaryKeyArray, SColumnModel *pModel, char **srcData, int64_t *defaultVal,
|
||||||
const int32_t *functionIDs, int32_t bufSize);
|
const int32_t *functionIDs, int32_t bufSize);
|
||||||
|
|
||||||
int taosDoLinearInterpolation(int32_t type, SPoint *point1, SPoint *point2, SPoint *point);
|
int taosDoLinearInterpolation(int32_t type, SPoint *point1, SPoint *point2, SPoint *point);
|
||||||
|
|
|
@ -346,6 +346,14 @@ static void doAddToHashTable(HashObj *pObj, SHashNode *pNode) {
|
||||||
// pTrace("key:%s %p add to hash table", key, pNode);
|
// pTrace("key:%s %p add to hash table", key, pNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t taosNumElemsInHashTable(HashObj *pObj) {
|
||||||
|
if (pObj == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pObj->size;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* add data node into hash table
|
* add data node into hash table
|
||||||
* @param pObj hash object
|
* @param pObj hash object
|
||||||
|
@ -392,7 +400,7 @@ int32_t taosAddToHashTable(HashObj *pObj, const char *key, uint32_t keyLen, void
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *taosGetDataFromHash(HashObj *pObj, const char *key, uint32_t keyLen) {
|
char *taosGetDataFromHashTable(HashObj *pObj, const char *key, uint32_t keyLen) {
|
||||||
if (pObj->multithreadSafe) {
|
if (pObj->multithreadSafe) {
|
||||||
__rd_lock(&pObj->lock);
|
__rd_lock(&pObj->lock);
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -205,16 +205,18 @@ static char* getPos(char* data, int32_t bytes, int32_t order, int32_t capacity,
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setTagsValueInInterpolation(tFilePage** data, char** pTags, tColModel* pModel, int32_t order, int32_t start,
|
static void setTagsValueInInterpolation(tFilePage** data, char** pTags, SColumnModel* pModel, int32_t order, int32_t start,
|
||||||
int32_t capacity, int32_t num) {
|
int32_t capacity, int32_t num) {
|
||||||
for (int32_t j = 0, i = start; i < pModel->numOfCols; ++i, ++j) {
|
for (int32_t j = 0, i = start; i < pModel->numOfCols; ++i, ++j) {
|
||||||
char* val1 = getPos(data[i]->data, pModel->pFields[i].bytes, order, capacity, num);
|
SSchema* pSchema = getColumnModelSchema(pModel, i);
|
||||||
assignVal(val1, pTags[j], pModel->pFields[i].bytes, pModel->pFields[i].type);
|
|
||||||
|
char* val1 = getPos(data[i]->data, pSchema->bytes, order, capacity, num);
|
||||||
|
assignVal(val1, pTags[j], pSchema->bytes, pSchema->type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void doInterpoResultImpl(SInterpolationInfo* pInterpoInfo, int16_t interpoType, tFilePage** data,
|
static void doInterpoResultImpl(SInterpolationInfo* pInterpoInfo, int16_t interpoType, tFilePage** data,
|
||||||
tColModel* pModel, int32_t* num, char** srcData, int64_t nInterval, int64_t* defaultVal,
|
SColumnModel* pModel, int32_t* num, char** srcData, int64_t nInterval, int64_t* defaultVal,
|
||||||
int64_t currentTimestamp, int32_t capacity, int32_t numOfTags, char** pTags,
|
int64_t currentTimestamp, int32_t capacity, int32_t numOfTags, char** pTags,
|
||||||
bool outOfBound) {
|
bool outOfBound) {
|
||||||
char** prevValues = &pInterpoInfo->prevValues;
|
char** prevValues = &pInterpoInfo->prevValues;
|
||||||
|
@ -234,18 +236,23 @@ static void doInterpoResultImpl(SInterpolationInfo* pInterpoInfo, int16_t interp
|
||||||
char* pInterpolationData = INTERPOL_IS_ASC_INTERPOL(pInterpoInfo) ? *prevValues : *nextValues;
|
char* pInterpolationData = INTERPOL_IS_ASC_INTERPOL(pInterpoInfo) ? *prevValues : *nextValues;
|
||||||
if (pInterpolationData != NULL) {
|
if (pInterpolationData != NULL) {
|
||||||
for (int32_t i = 1; i < numOfValCols; ++i) {
|
for (int32_t i = 1; i < numOfValCols; ++i) {
|
||||||
char* val1 = getPos(data[i]->data, pModel->pFields[i].bytes, pInterpoInfo->order, capacity, *num);
|
SSchema* pSchema = getColumnModelSchema(pModel, i);
|
||||||
|
int16_t offset = getColumnModelOffset(pModel, i);
|
||||||
|
|
||||||
if (isNull(pInterpolationData + pModel->colOffset[i], pModel->pFields[i].type)) {
|
char* val1 = getPos(data[i]->data, pSchema->bytes, pInterpoInfo->order, capacity, *num);
|
||||||
setNull(val1, pModel->pFields[i].type, pModel->pFields[i].bytes);
|
|
||||||
|
if (isNull(pInterpolationData + offset, pSchema->type)) {
|
||||||
|
setNull(val1, pSchema->type, pSchema->bytes);
|
||||||
} else {
|
} else {
|
||||||
assignVal(val1, pInterpolationData + pModel->colOffset[i], pModel->pFields[i].bytes, pModel->pFields[i].type);
|
assignVal(val1, pInterpolationData + offset, pSchema->bytes, pSchema->type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { /* no prev value yet, set the value for null */
|
} else { /* no prev value yet, set the value for null */
|
||||||
for (int32_t i = 1; i < numOfValCols; ++i) {
|
for (int32_t i = 1; i < numOfValCols; ++i) {
|
||||||
char* val1 = getPos(data[i]->data, pModel->pFields[i].bytes, pInterpoInfo->order, capacity, *num);
|
SSchema* pSchema = getColumnModelSchema(pModel, i);
|
||||||
setNull(val1, pModel->pFields[i].type, pModel->pFields[i].bytes);
|
|
||||||
|
char* val1 = getPos(data[i]->data, pSchema->bytes, pInterpoInfo->order, capacity, *num);
|
||||||
|
setNull(val1, pSchema->type, pSchema->bytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,34 +261,41 @@ static void doInterpoResultImpl(SInterpolationInfo* pInterpoInfo, int16_t interp
|
||||||
// TODO : linear interpolation supports NULL value
|
// TODO : linear interpolation supports NULL value
|
||||||
if (*prevValues != NULL && !outOfBound) {
|
if (*prevValues != NULL && !outOfBound) {
|
||||||
for (int32_t i = 1; i < numOfValCols; ++i) {
|
for (int32_t i = 1; i < numOfValCols; ++i) {
|
||||||
int32_t type = pModel->pFields[i].type;
|
SSchema* pSchema = getColumnModelSchema(pModel, i);
|
||||||
char* val1 = getPos(data[i]->data, pModel->pFields[i].bytes, pInterpoInfo->order, capacity, *num);
|
int16_t offset = getColumnModelOffset(pModel, i);
|
||||||
|
|
||||||
|
int16_t type = pSchema->type;
|
||||||
|
char* val1 = getPos(data[i]->data, pSchema->bytes, pInterpoInfo->order, capacity, *num);
|
||||||
|
|
||||||
if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR || type == TSDB_DATA_TYPE_BOOL) {
|
if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR || type == TSDB_DATA_TYPE_BOOL) {
|
||||||
setNull(val1, pModel->pFields[i].type, pModel->pFields[i].bytes);
|
setNull(val1, type, pSchema->bytes);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
point1 = (SPoint){.key = *(TSKEY*)(*prevValues), .val = *prevValues + pModel->colOffset[i]};
|
point1 = (SPoint){.key = *(TSKEY*)(*prevValues), .val = *prevValues + offset};
|
||||||
point2 = (SPoint){.key = currentTimestamp, .val = srcData[i] + pInterpoInfo->rowIdx * pModel->pFields[i].bytes};
|
point2 = (SPoint){.key = currentTimestamp, .val = srcData[i] + pInterpoInfo->rowIdx * pSchema->bytes};
|
||||||
point = (SPoint){.key = pInterpoInfo->startTimestamp, .val = val1};
|
point = (SPoint){.key = pInterpoInfo->startTimestamp, .val = val1};
|
||||||
taosDoLinearInterpolation(pModel->pFields[i].type, &point1, &point2, &point);
|
taosDoLinearInterpolation(type, &point1, &point2, &point);
|
||||||
}
|
}
|
||||||
|
|
||||||
setTagsValueInInterpolation(data, pTags, pModel, pInterpoInfo->order, numOfValCols, capacity, *num);
|
setTagsValueInInterpolation(data, pTags, pModel, pInterpoInfo->order, numOfValCols, capacity, *num);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
for (int32_t i = 1; i < numOfValCols; ++i) {
|
for (int32_t i = 1; i < numOfValCols; ++i) {
|
||||||
char* val1 = getPos(data[i]->data, pModel->pFields[i].bytes, pInterpoInfo->order, capacity, *num);
|
SSchema* pSchema = getColumnModelSchema(pModel, i);
|
||||||
setNull(val1, pModel->pFields[i].type, pModel->pFields[i].bytes);
|
|
||||||
|
char* val1 = getPos(data[i]->data, pSchema->bytes, pInterpoInfo->order, capacity, *num);
|
||||||
|
setNull(val1, pSchema->type, pSchema->bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
setTagsValueInInterpolation(data, pTags, pModel, pInterpoInfo->order, numOfValCols, capacity, *num);
|
setTagsValueInInterpolation(data, pTags, pModel, pInterpoInfo->order, numOfValCols, capacity, *num);
|
||||||
}
|
}
|
||||||
} else { /* default value interpolation */
|
} else { /* default value interpolation */
|
||||||
for (int32_t i = 1; i < numOfValCols; ++i) {
|
for (int32_t i = 1; i < numOfValCols; ++i) {
|
||||||
char* val1 = getPos(data[i]->data, pModel->pFields[i].bytes, pInterpoInfo->order, capacity, *num);
|
SSchema* pSchema = getColumnModelSchema(pModel, i);
|
||||||
assignVal(val1, (char*)&defaultVal[i], pModel->pFields[i].bytes, pModel->pFields[i].type);
|
|
||||||
|
char* val1 = getPos(data[i]->data, pSchema->bytes, pInterpoInfo->order, capacity, *num);
|
||||||
|
assignVal(val1, (char*)&defaultVal[i], pSchema->bytes, pSchema->type);
|
||||||
}
|
}
|
||||||
|
|
||||||
setTagsValueInInterpolation(data, pTags, pModel, pInterpoInfo->order, numOfValCols, capacity, *num);
|
setTagsValueInInterpolation(data, pTags, pModel, pInterpoInfo->order, numOfValCols, capacity, *num);
|
||||||
|
@ -295,7 +309,7 @@ static void doInterpoResultImpl(SInterpolationInfo* pInterpoInfo, int16_t interp
|
||||||
|
|
||||||
int32_t taosDoInterpoResult(SInterpolationInfo* pInterpoInfo, int16_t interpoType, tFilePage** data,
|
int32_t taosDoInterpoResult(SInterpolationInfo* pInterpoInfo, int16_t interpoType, tFilePage** data,
|
||||||
int32_t numOfRawDataInRows, int32_t outputRows, int64_t nInterval,
|
int32_t numOfRawDataInRows, int32_t outputRows, int64_t nInterval,
|
||||||
const int64_t* pPrimaryKeyArray, tColModel* pModel, char** srcData, int64_t* defaultVal,
|
const int64_t* pPrimaryKeyArray, SColumnModel* pModel, char** srcData, int64_t* defaultVal,
|
||||||
const int32_t* functionIDs, int32_t bufSize) {
|
const int32_t* functionIDs, int32_t bufSize) {
|
||||||
int32_t num = 0;
|
int32_t num = 0;
|
||||||
pInterpoInfo->numOfCurrentInterpo = 0;
|
pInterpoInfo->numOfCurrentInterpo = 0;
|
||||||
|
@ -328,17 +342,21 @@ int32_t taosDoInterpoResult(SInterpolationInfo* pInterpoInfo, int16_t interpoTyp
|
||||||
(pInterpoInfo->startTimestamp > currentTimestamp && !INTERPOL_IS_ASC_INTERPOL(pInterpoInfo))) {
|
(pInterpoInfo->startTimestamp > currentTimestamp && !INTERPOL_IS_ASC_INTERPOL(pInterpoInfo))) {
|
||||||
/* set the next value for interpolation */
|
/* set the next value for interpolation */
|
||||||
if (*nextValues == NULL) {
|
if (*nextValues == NULL) {
|
||||||
*nextValues =
|
*nextValues = calloc(1, pModel->rowSize);
|
||||||
calloc(1, pModel->colOffset[pModel->numOfCols - 1] + pModel->pFields[pModel->numOfCols - 1].bytes);
|
|
||||||
for (int i = 1; i < pModel->numOfCols; i++) {
|
for (int i = 1; i < pModel->numOfCols; i++) {
|
||||||
setNull(*nextValues + pModel->colOffset[i], pModel->pFields[i].type, pModel->pFields[i].bytes);
|
int16_t offset = getColumnModelOffset(pModel, i);
|
||||||
|
SSchema* pSchema = getColumnModelSchema(pModel, i);
|
||||||
|
|
||||||
|
setNull(*nextValues + offset, pSchema->type, pSchema->bytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t offset = pInterpoInfo->rowIdx;
|
int32_t offset = pInterpoInfo->rowIdx;
|
||||||
for (int32_t tlen = 0, i = 0; i < pModel->numOfCols - numOfTags; ++i) {
|
for (int32_t tlen = 0, i = 0; i < pModel->numOfCols - numOfTags; ++i) {
|
||||||
memcpy(*nextValues + tlen, srcData[i] + offset * pModel->pFields[i].bytes, pModel->pFields[i].bytes);
|
SSchema* pSchema = getColumnModelSchema(pModel, i);
|
||||||
tlen += pModel->pFields[i].bytes;
|
|
||||||
|
memcpy(*nextValues + tlen, srcData[i] + offset * pSchema->bytes, pSchema->bytes);
|
||||||
|
tlen += pSchema->bytes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -358,37 +376,41 @@ int32_t taosDoInterpoResult(SInterpolationInfo* pInterpoInfo, int16_t interpoTyp
|
||||||
|
|
||||||
if (pInterpoInfo->startTimestamp == currentTimestamp) {
|
if (pInterpoInfo->startTimestamp == currentTimestamp) {
|
||||||
if (*prevValues == NULL) {
|
if (*prevValues == NULL) {
|
||||||
*prevValues =
|
*prevValues = calloc(1, pModel->rowSize);
|
||||||
calloc(1, pModel->colOffset[pModel->numOfCols - 1] + pModel->pFields[pModel->numOfCols - 1].bytes);
|
|
||||||
for (int i = 1; i < pModel->numOfCols; i++) {
|
for (int i = 1; i < pModel->numOfCols; i++) {
|
||||||
setNull(*prevValues + pModel->colOffset[i], pModel->pFields[i].type, pModel->pFields[i].bytes);
|
int16_t offset = getColumnModelOffset(pModel, i);
|
||||||
|
SSchema* pSchema = getColumnModelSchema(pModel, i);
|
||||||
|
|
||||||
|
setNull(*prevValues + offset, pSchema->type, pSchema->bytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// assign rows to dst buffer
|
// assign rows to dst buffer
|
||||||
int32_t i = 0;
|
int32_t i = 0;
|
||||||
for (int32_t tlen = 0; i < pModel->numOfCols - numOfTags; ++i) {
|
for (int32_t tlen = 0; i < pModel->numOfCols - numOfTags; ++i) {
|
||||||
char* val1 = getPos(data[i]->data, pModel->pFields[i].bytes, pInterpoInfo->order, bufSize, num);
|
int16_t offset = getColumnModelOffset(pModel, i);
|
||||||
|
SSchema* pSchema = getColumnModelSchema(pModel, i);
|
||||||
|
|
||||||
|
char* val1 = getPos(data[i]->data, pSchema->bytes, pInterpoInfo->order, bufSize, num);
|
||||||
|
|
||||||
if (i == 0 ||
|
if (i == 0 ||
|
||||||
(functionIDs[i] != TSDB_FUNC_COUNT &&
|
(functionIDs[i] != TSDB_FUNC_COUNT &&
|
||||||
!isNull(srcData[i] + pInterpoInfo->rowIdx * pModel->pFields[i].bytes, pModel->pFields[i].type)) ||
|
!isNull(srcData[i] + pInterpoInfo->rowIdx * pSchema->bytes, pSchema->type)) ||
|
||||||
(functionIDs[i] == TSDB_FUNC_COUNT &&
|
(functionIDs[i] == TSDB_FUNC_COUNT &&
|
||||||
*(int64_t*)(srcData[i] + pInterpoInfo->rowIdx * pModel->pFields[i].bytes) != 0)) {
|
*(int64_t*)(srcData[i] + pInterpoInfo->rowIdx * pSchema->bytes) != 0)) {
|
||||||
assignVal(val1, srcData[i] + pInterpoInfo->rowIdx * pModel->pFields[i].bytes, pModel->pFields[i].bytes,
|
|
||||||
pModel->pFields[i].type);
|
assignVal(val1, srcData[i] + pInterpoInfo->rowIdx * pSchema->bytes, pSchema->bytes, pSchema->type);
|
||||||
memcpy(*prevValues + tlen, srcData[i] + pInterpoInfo->rowIdx * pModel->pFields[i].bytes,
|
memcpy(*prevValues + tlen, srcData[i] + pInterpoInfo->rowIdx * pSchema->bytes, pSchema->bytes);
|
||||||
pModel->pFields[i].bytes);
|
|
||||||
} else { // i > 0 and isNULL, do interpolation
|
} else { // i > 0 and isNULL, do interpolation
|
||||||
if (interpoType == TSDB_INTERPO_PREV) {
|
if (interpoType == TSDB_INTERPO_PREV) {
|
||||||
assignVal(val1, *prevValues + pModel->colOffset[i], pModel->pFields[i].bytes, pModel->pFields[i].type);
|
assignVal(val1, *prevValues + offset, pSchema->bytes, pSchema->type);
|
||||||
} else if (interpoType == TSDB_INTERPO_LINEAR) {
|
} else if (interpoType == TSDB_INTERPO_LINEAR) {
|
||||||
// TODO:
|
// TODO:
|
||||||
} else {
|
} else {
|
||||||
assignVal(val1, (char*)&defaultVal[i], pModel->pFields[i].bytes, pModel->pFields[i].type);
|
assignVal(val1, (char*)&defaultVal[i], pSchema->bytes, pSchema->type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tlen += pModel->pFields[i].bytes;
|
tlen += pSchema->bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set the tag value for final result */
|
/* set the tag value for final result */
|
||||||
|
|
|
@ -0,0 +1,976 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "os.h"
|
||||||
|
|
||||||
|
#include "taosmsg.h"
|
||||||
|
#include "tsdb.h"
|
||||||
|
#include "tlog.h"
|
||||||
|
#include "ttypes.h"
|
||||||
|
#include "tpercentile.h"
|
||||||
|
|
||||||
|
tExtMemBuffer *releaseBucketsExceptFor(tMemBucket *pMemBucket, int16_t segIdx, int16_t slotIdx) {
|
||||||
|
tExtMemBuffer *pBuffer = NULL;
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < pMemBucket->numOfSegs; ++i) {
|
||||||
|
tMemBucketSegment *pSeg = &pMemBucket->pSegs[i];
|
||||||
|
|
||||||
|
for (int32_t j = 0; j < pSeg->numOfSlots; ++j) {
|
||||||
|
if (i == segIdx && j == slotIdx) {
|
||||||
|
pBuffer = pSeg->pBuffer[j];
|
||||||
|
} else {
|
||||||
|
if (pSeg->pBuffer && pSeg->pBuffer[j]) {
|
||||||
|
pSeg->pBuffer[j] = destoryExtMemBuffer(pSeg->pBuffer[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static tFilePage *loadIntoBucketFromDisk(tMemBucket *pMemBucket, int32_t segIdx, int32_t slotIdx,
|
||||||
|
tOrderDescriptor *pDesc) {
|
||||||
|
// release all data in other slots
|
||||||
|
tExtMemBuffer *pMemBuffer = pMemBucket->pSegs[segIdx].pBuffer[slotIdx];
|
||||||
|
tFilePage * buffer = (tFilePage *)calloc(1, pMemBuffer->nElemSize * pMemBuffer->numOfTotalElems + sizeof(tFilePage));
|
||||||
|
int32_t oldCapacity = pDesc->pColumnModel->capacity;
|
||||||
|
pDesc->pColumnModel->capacity = pMemBuffer->numOfTotalElems;
|
||||||
|
|
||||||
|
if (!tExtMemBufferIsAllDataInMem(pMemBuffer)) {
|
||||||
|
pMemBuffer = releaseBucketsExceptFor(pMemBucket, segIdx, slotIdx);
|
||||||
|
assert(pMemBuffer->numOfTotalElems > 0);
|
||||||
|
|
||||||
|
// load data in disk to memory
|
||||||
|
tFilePage *pPage = (tFilePage *)calloc(1, pMemBuffer->pageSize);
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < pMemBuffer->fileMeta.flushoutData.nLength; ++i) {
|
||||||
|
tFlushoutInfo *pFlushInfo = &pMemBuffer->fileMeta.flushoutData.pFlushoutInfo[i];
|
||||||
|
|
||||||
|
int32_t ret = fseek(pMemBuffer->file, pFlushInfo->startPageId * pMemBuffer->pageSize, SEEK_SET);
|
||||||
|
UNUSED(ret);
|
||||||
|
|
||||||
|
for (uint32_t j = 0; j < pFlushInfo->numOfPages; ++j) {
|
||||||
|
ret = fread(pPage, pMemBuffer->pageSize, 1, pMemBuffer->file);
|
||||||
|
UNUSED(ret);
|
||||||
|
assert(pPage->numOfElems > 0);
|
||||||
|
|
||||||
|
tColModelAppend(pDesc->pColumnModel, buffer, pPage->data, 0, pPage->numOfElems, pPage->numOfElems);
|
||||||
|
printf("id: %d count: %" PRIu64 "\n", j, buffer->numOfElems);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tfree(pPage);
|
||||||
|
|
||||||
|
assert(buffer->numOfElems == pMemBuffer->fileMeta.numOfElemsInFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
// load data in pMemBuffer to buffer
|
||||||
|
tFilePagesItem *pListItem = pMemBuffer->pHead;
|
||||||
|
while (pListItem != NULL) {
|
||||||
|
tColModelAppend(pDesc->pColumnModel, buffer, pListItem->item.data, 0, pListItem->item.numOfElems,
|
||||||
|
pListItem->item.numOfElems);
|
||||||
|
pListItem = pListItem->pNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
tColDataQSort(pDesc, buffer->numOfElems, 0, buffer->numOfElems - 1, buffer->data, TSQL_SO_ASC);
|
||||||
|
|
||||||
|
pDesc->pColumnModel->capacity = oldCapacity; // restore value
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
double findOnlyResult(tMemBucket *pMemBucket) {
|
||||||
|
assert(pMemBucket->numOfElems == 1);
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < pMemBucket->numOfSegs; ++i) {
|
||||||
|
tMemBucketSegment *pSeg = &pMemBucket->pSegs[i];
|
||||||
|
if (pSeg->pBuffer) {
|
||||||
|
for (int32_t j = 0; j < pSeg->numOfSlots; ++j) {
|
||||||
|
tExtMemBuffer *pBuffer = pSeg->pBuffer[j];
|
||||||
|
if (pBuffer) {
|
||||||
|
assert(pBuffer->numOfTotalElems == 1);
|
||||||
|
tFilePage *pPage = &pBuffer->pHead->item;
|
||||||
|
if (pBuffer->numOfElemsInBuffer == 1) {
|
||||||
|
switch (pMemBucket->dataType) {
|
||||||
|
case TSDB_DATA_TYPE_INT:
|
||||||
|
return *(int32_t *)pPage->data;
|
||||||
|
case TSDB_DATA_TYPE_SMALLINT:
|
||||||
|
return *(int16_t *)pPage->data;
|
||||||
|
case TSDB_DATA_TYPE_TINYINT:
|
||||||
|
return *(int8_t *)pPage->data;
|
||||||
|
case TSDB_DATA_TYPE_BIGINT:
|
||||||
|
return (double)(*(int64_t *)pPage->data);
|
||||||
|
case TSDB_DATA_TYPE_DOUBLE: {
|
||||||
|
double dv = GET_DOUBLE_VAL(pPage->data);
|
||||||
|
//return *(double *)pPage->data;
|
||||||
|
return dv;
|
||||||
|
}
|
||||||
|
case TSDB_DATA_TYPE_FLOAT: {
|
||||||
|
float fv = GET_FLOAT_VAL(pPage->data);
|
||||||
|
//return *(float *)pPage->data;
|
||||||
|
return fv;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tBucketBigIntHash(tMemBucket *pBucket, void *value, int16_t *segIdx, int16_t *slotIdx) {
|
||||||
|
int64_t v = *(int64_t *)value;
|
||||||
|
|
||||||
|
if (pBucket->nRange.i64MaxVal == INT64_MIN) {
|
||||||
|
if (v >= 0) {
|
||||||
|
*segIdx = ((v >> (64 - 9)) >> 6) + 8;
|
||||||
|
*slotIdx = (v >> (64 - 9)) & 0x3F;
|
||||||
|
} else { // v<0
|
||||||
|
*segIdx = ((-v) >> (64 - 9)) >> 6;
|
||||||
|
*slotIdx = ((-v) >> (64 - 9)) & 0x3F;
|
||||||
|
*segIdx = 7 - (*segIdx);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// todo hash for bigint and float and double
|
||||||
|
int64_t span = pBucket->nRange.i64MaxVal - pBucket->nRange.i64MinVal;
|
||||||
|
if (span < pBucket->nTotalSlots) {
|
||||||
|
int32_t delta = (int32_t)(v - pBucket->nRange.i64MinVal);
|
||||||
|
*segIdx = delta / pBucket->nSlotsOfSeg;
|
||||||
|
*slotIdx = delta % pBucket->nSlotsOfSeg;
|
||||||
|
} else {
|
||||||
|
double x = (double)span / pBucket->nTotalSlots;
|
||||||
|
double posx = (v - pBucket->nRange.i64MinVal) / x;
|
||||||
|
if (v == pBucket->nRange.i64MaxVal) {
|
||||||
|
posx -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*segIdx = ((int32_t)posx) / pBucket->nSlotsOfSeg;
|
||||||
|
*slotIdx = ((int32_t)posx) % pBucket->nSlotsOfSeg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo refactor to more generic
|
||||||
|
void tBucketIntHash(tMemBucket *pBucket, void *value, int16_t *segIdx, int16_t *slotIdx) {
|
||||||
|
int32_t v = *(int32_t *)value;
|
||||||
|
|
||||||
|
if (pBucket->nRange.iMaxVal == INT32_MIN) {
|
||||||
|
/*
|
||||||
|
* taking negative integer into consideration,
|
||||||
|
* there is only half of pBucket->segs available for non-negative integer
|
||||||
|
*/
|
||||||
|
// int32_t numOfSlots = pBucket->nTotalSlots>>1;
|
||||||
|
// int32_t bits = bitsOfNumber(numOfSlots)-1;
|
||||||
|
|
||||||
|
if (v >= 0) {
|
||||||
|
*segIdx = ((v >> (32 - 9)) >> 6) + 8;
|
||||||
|
*slotIdx = (v >> (32 - 9)) & 0x3F;
|
||||||
|
} else { // v<0
|
||||||
|
*segIdx = ((-v) >> (32 - 9)) >> 6;
|
||||||
|
*slotIdx = ((-v) >> (32 - 9)) & 0x3F;
|
||||||
|
*segIdx = 7 - (*segIdx);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// divide a range of [iMinVal, iMaxVal] into 1024 buckets
|
||||||
|
int32_t span = pBucket->nRange.iMaxVal - pBucket->nRange.iMinVal;
|
||||||
|
if (span < pBucket->nTotalSlots) {
|
||||||
|
int32_t delta = v - pBucket->nRange.iMinVal;
|
||||||
|
*segIdx = delta / pBucket->nSlotsOfSeg;
|
||||||
|
*slotIdx = delta % pBucket->nSlotsOfSeg;
|
||||||
|
} else {
|
||||||
|
double x = (double)span / pBucket->nTotalSlots;
|
||||||
|
double posx = (v - pBucket->nRange.iMinVal) / x;
|
||||||
|
if (v == pBucket->nRange.iMaxVal) {
|
||||||
|
posx -= 1;
|
||||||
|
}
|
||||||
|
*segIdx = ((int32_t)posx) / pBucket->nSlotsOfSeg;
|
||||||
|
*slotIdx = ((int32_t)posx) % pBucket->nSlotsOfSeg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void tBucketDoubleHash(tMemBucket *pBucket, void *value, int16_t *segIdx, int16_t *slotIdx) {
|
||||||
|
// double v = *(double *)value;
|
||||||
|
double v = GET_DOUBLE_VAL(value);
|
||||||
|
|
||||||
|
if (pBucket->nRange.dMinVal == DBL_MAX) {
|
||||||
|
/*
|
||||||
|
* taking negative integer into consideration,
|
||||||
|
* there is only half of pBucket->segs available for non-negative integer
|
||||||
|
*/
|
||||||
|
double x = DBL_MAX / (pBucket->nTotalSlots >> 1);
|
||||||
|
double posx = (v + DBL_MAX) / x;
|
||||||
|
*segIdx = ((int32_t)posx) / pBucket->nSlotsOfSeg;
|
||||||
|
*slotIdx = ((int32_t)posx) % pBucket->nSlotsOfSeg;
|
||||||
|
} else {
|
||||||
|
// divide a range of [dMinVal, dMaxVal] into 1024 buckets
|
||||||
|
double span = pBucket->nRange.dMaxVal - pBucket->nRange.dMinVal;
|
||||||
|
if (span < pBucket->nTotalSlots) {
|
||||||
|
int32_t delta = (int32_t)(v - pBucket->nRange.dMinVal);
|
||||||
|
*segIdx = delta / pBucket->nSlotsOfSeg;
|
||||||
|
*slotIdx = delta % pBucket->nSlotsOfSeg;
|
||||||
|
} else {
|
||||||
|
double x = span / pBucket->nTotalSlots;
|
||||||
|
double posx = (v - pBucket->nRange.dMinVal) / x;
|
||||||
|
if (v == pBucket->nRange.dMaxVal) {
|
||||||
|
posx -= 1;
|
||||||
|
}
|
||||||
|
*segIdx = ((int32_t)posx) / pBucket->nSlotsOfSeg;
|
||||||
|
*slotIdx = ((int32_t)posx) % pBucket->nSlotsOfSeg;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*segIdx < 0 || *segIdx > 16 || *slotIdx < 0 || *slotIdx > 64) {
|
||||||
|
pError("error in hash process. segment is: %d, slot id is: %d\n", *segIdx, *slotIdx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tMemBucket *tMemBucketCreate(int32_t totalSlots, int32_t nBufferSize, int16_t nElemSize, int16_t dataType,
|
||||||
|
tOrderDescriptor *pDesc) {
|
||||||
|
tMemBucket *pBucket = (tMemBucket *)malloc(sizeof(tMemBucket));
|
||||||
|
|
||||||
|
pBucket->nTotalSlots = totalSlots;
|
||||||
|
pBucket->nSlotsOfSeg = 1 << 6; // 64 Segments, 16 slots each seg.
|
||||||
|
pBucket->dataType = dataType;
|
||||||
|
pBucket->nElemSize = nElemSize;
|
||||||
|
pBucket->pageSize = DEFAULT_PAGE_SIZE;
|
||||||
|
|
||||||
|
pBucket->numOfElems = 0;
|
||||||
|
pBucket->numOfSegs = pBucket->nTotalSlots / pBucket->nSlotsOfSeg;
|
||||||
|
|
||||||
|
pBucket->nTotalBufferSize = nBufferSize;
|
||||||
|
|
||||||
|
pBucket->maxElemsCapacity = pBucket->nTotalBufferSize / pBucket->nElemSize;
|
||||||
|
|
||||||
|
pBucket->numOfTotalPages = pBucket->nTotalBufferSize / pBucket->pageSize;
|
||||||
|
pBucket->numOfAvailPages = pBucket->numOfTotalPages;
|
||||||
|
|
||||||
|
pBucket->pOrderDesc = pDesc;
|
||||||
|
|
||||||
|
switch (pBucket->dataType) {
|
||||||
|
case TSDB_DATA_TYPE_INT:
|
||||||
|
case TSDB_DATA_TYPE_SMALLINT:
|
||||||
|
case TSDB_DATA_TYPE_TINYINT: {
|
||||||
|
pBucket->nRange.iMinVal = INT32_MAX;
|
||||||
|
pBucket->nRange.iMaxVal = INT32_MIN;
|
||||||
|
pBucket->HashFunc = tBucketIntHash;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
case TSDB_DATA_TYPE_DOUBLE:
|
||||||
|
case TSDB_DATA_TYPE_FLOAT: {
|
||||||
|
pBucket->nRange.dMinVal = DBL_MAX;
|
||||||
|
pBucket->nRange.dMaxVal = -DBL_MAX;
|
||||||
|
pBucket->HashFunc = tBucketDoubleHash;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
case TSDB_DATA_TYPE_BIGINT: {
|
||||||
|
pBucket->nRange.i64MinVal = INT64_MAX;
|
||||||
|
pBucket->nRange.i64MaxVal = INT64_MIN;
|
||||||
|
pBucket->HashFunc = tBucketBigIntHash;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
default: {
|
||||||
|
pError("MemBucket:%p,not support data type %d,failed", *pBucket, pBucket->dataType);
|
||||||
|
tfree(pBucket);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t numOfCols = pDesc->pColumnModel->numOfCols;
|
||||||
|
if (numOfCols != 1) {
|
||||||
|
pError("MemBucket:%p,only consecutive data is allowed,invalid numOfCols:%d", pBucket, numOfCols);
|
||||||
|
tfree(pBucket);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SSchema* pSchema = getColumnModelSchema(pDesc->pColumnModel, 0);
|
||||||
|
if (pSchema->type != dataType) {
|
||||||
|
pError("MemBucket:%p,data type is not consistent,%d in schema, %d in param", pBucket, pSchema->type, dataType);
|
||||||
|
tfree(pBucket);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pBucket->numOfTotalPages < pBucket->nTotalSlots) {
|
||||||
|
pWarn("MemBucket:%p,total buffer pages %d are not enough for all slots", pBucket, pBucket->numOfTotalPages);
|
||||||
|
}
|
||||||
|
|
||||||
|
pBucket->pSegs = (tMemBucketSegment *)malloc(pBucket->numOfSegs * sizeof(tMemBucketSegment));
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < pBucket->numOfSegs; ++i) {
|
||||||
|
pBucket->pSegs[i].numOfSlots = pBucket->nSlotsOfSeg;
|
||||||
|
pBucket->pSegs[i].pBuffer = NULL;
|
||||||
|
pBucket->pSegs[i].pBoundingEntries = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pTrace("MemBucket:%p,created,buffer size:%d,elem size:%d", pBucket, pBucket->numOfTotalPages * DEFAULT_PAGE_SIZE,
|
||||||
|
pBucket->nElemSize);
|
||||||
|
|
||||||
|
return pBucket;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tMemBucketDestroy(tMemBucket *pBucket) {
|
||||||
|
if (pBucket == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pBucket->pSegs) {
|
||||||
|
for (int32_t i = 0; i < pBucket->numOfSegs; ++i) {
|
||||||
|
tMemBucketSegment *pSeg = &(pBucket->pSegs[i]);
|
||||||
|
tfree(pSeg->pBoundingEntries);
|
||||||
|
|
||||||
|
if (pSeg->pBuffer == NULL || pSeg->numOfSlots == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int32_t j = 0; j < pSeg->numOfSlots; ++j) {
|
||||||
|
if (pSeg->pBuffer[j] != NULL) {
|
||||||
|
pSeg->pBuffer[j] = destoryExtMemBuffer(pSeg->pBuffer[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tfree(pSeg->pBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tfree(pBucket->pSegs);
|
||||||
|
tfree(pBucket);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* find the slots which accounts for largest proportion of total in-memory buffer
|
||||||
|
*/
|
||||||
|
static void tBucketGetMaxMemSlot(tMemBucket *pBucket, int16_t *segIdx, int16_t *slotIdx) {
|
||||||
|
*segIdx = -1;
|
||||||
|
*slotIdx = -1;
|
||||||
|
|
||||||
|
int32_t val = 0;
|
||||||
|
for (int32_t k = 0; k < pBucket->numOfSegs; ++k) {
|
||||||
|
tMemBucketSegment *pSeg = &pBucket->pSegs[k];
|
||||||
|
for (int32_t i = 0; i < pSeg->numOfSlots; ++i) {
|
||||||
|
if (pSeg->pBuffer == NULL || pSeg->pBuffer[i] == NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (val < pSeg->pBuffer[i]->numOfInMemPages) {
|
||||||
|
val = pSeg->pBuffer[i]->numOfInMemPages;
|
||||||
|
*segIdx = k;
|
||||||
|
*slotIdx = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void resetBoundingBox(tMemBucketSegment *pSeg, int32_t type) {
|
||||||
|
switch (type) {
|
||||||
|
case TSDB_DATA_TYPE_BIGINT: {
|
||||||
|
for (int32_t i = 0; i < pSeg->numOfSlots; ++i) {
|
||||||
|
pSeg->pBoundingEntries[i].i64MaxVal = INT64_MIN;
|
||||||
|
pSeg->pBoundingEntries[i].i64MinVal = INT64_MAX;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
case TSDB_DATA_TYPE_INT:
|
||||||
|
case TSDB_DATA_TYPE_SMALLINT:
|
||||||
|
case TSDB_DATA_TYPE_TINYINT: {
|
||||||
|
for (int32_t i = 0; i < pSeg->numOfSlots; ++i) {
|
||||||
|
pSeg->pBoundingEntries[i].iMaxVal = INT32_MIN;
|
||||||
|
pSeg->pBoundingEntries[i].iMinVal = INT32_MAX;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
case TSDB_DATA_TYPE_DOUBLE:
|
||||||
|
case TSDB_DATA_TYPE_FLOAT: {
|
||||||
|
for (int32_t i = 0; i < pSeg->numOfSlots; ++i) {
|
||||||
|
pSeg->pBoundingEntries[i].dMaxVal = -DBL_MAX;
|
||||||
|
pSeg->pBoundingEntries[i].dMinVal = DBL_MAX;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void tMemBucketUpdateBoundingBox(MinMaxEntry *r, char *data, int32_t dataType) {
|
||||||
|
switch (dataType) {
|
||||||
|
case TSDB_DATA_TYPE_INT: {
|
||||||
|
int32_t val = *(int32_t *)data;
|
||||||
|
if (r->iMinVal > val) {
|
||||||
|
r->iMinVal = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r->iMaxVal < val) {
|
||||||
|
r->iMaxVal = val;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
case TSDB_DATA_TYPE_BIGINT: {
|
||||||
|
int64_t val = *(int64_t *)data;
|
||||||
|
if (r->i64MinVal > val) {
|
||||||
|
r->i64MinVal = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r->i64MaxVal < val) {
|
||||||
|
r->i64MaxVal = val;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
case TSDB_DATA_TYPE_SMALLINT: {
|
||||||
|
int32_t val = *(int16_t *)data;
|
||||||
|
if (r->iMinVal > val) {
|
||||||
|
r->iMinVal = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r->iMaxVal < val) {
|
||||||
|
r->iMaxVal = val;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
case TSDB_DATA_TYPE_TINYINT: {
|
||||||
|
int32_t val = *(int8_t *)data;
|
||||||
|
if (r->iMinVal > val) {
|
||||||
|
r->iMinVal = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r->iMaxVal < val) {
|
||||||
|
r->iMaxVal = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
case TSDB_DATA_TYPE_DOUBLE: {
|
||||||
|
// double val = *(double *)data;
|
||||||
|
double val = GET_DOUBLE_VAL(data);
|
||||||
|
if (r->dMinVal > val) {
|
||||||
|
r->dMinVal = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r->dMaxVal < val) {
|
||||||
|
r->dMaxVal = val;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
case TSDB_DATA_TYPE_FLOAT: {
|
||||||
|
// double val = *(float *)data;
|
||||||
|
double val = GET_FLOAT_VAL(data);
|
||||||
|
|
||||||
|
if (r->dMinVal > val) {
|
||||||
|
r->dMinVal = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r->dMaxVal < val) {
|
||||||
|
r->dMaxVal = val;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
default: { assert(false); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* in memory bucket, we only accept the simple data consecutive put in a row/column
|
||||||
|
* no column-model in this case.
|
||||||
|
*/
|
||||||
|
void tMemBucketPut(tMemBucket *pBucket, void *data, int32_t numOfRows) {
|
||||||
|
pBucket->numOfElems += numOfRows;
|
||||||
|
int16_t segIdx = 0, slotIdx = 0;
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < numOfRows; ++i) {
|
||||||
|
char *d = (char *)data + i * tDataTypeDesc[pBucket->dataType].nSize;
|
||||||
|
|
||||||
|
switch (pBucket->dataType) {
|
||||||
|
case TSDB_DATA_TYPE_SMALLINT: {
|
||||||
|
int32_t val = *(int16_t *)d;
|
||||||
|
(pBucket->HashFunc)(pBucket, &val, &segIdx, &slotIdx);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TSDB_DATA_TYPE_TINYINT: {
|
||||||
|
int32_t val = *(int8_t *)d;
|
||||||
|
(pBucket->HashFunc)(pBucket, &val, &segIdx, &slotIdx);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TSDB_DATA_TYPE_INT: {
|
||||||
|
int32_t val = *(int32_t *)d;
|
||||||
|
(pBucket->HashFunc)(pBucket, &val, &segIdx, &slotIdx);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TSDB_DATA_TYPE_BIGINT: {
|
||||||
|
int64_t val = *(int64_t *)d;
|
||||||
|
(pBucket->HashFunc)(pBucket, &val, &segIdx, &slotIdx);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TSDB_DATA_TYPE_DOUBLE: {
|
||||||
|
// double val = *(double *)d;
|
||||||
|
double val = GET_DOUBLE_VAL(d);
|
||||||
|
(pBucket->HashFunc)(pBucket, &val, &segIdx, &slotIdx);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TSDB_DATA_TYPE_FLOAT: {
|
||||||
|
// double val = *(float *)d;
|
||||||
|
double val = GET_FLOAT_VAL(d);
|
||||||
|
(pBucket->HashFunc)(pBucket, &val, &segIdx, &slotIdx);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tMemBucketSegment *pSeg = &pBucket->pSegs[segIdx];
|
||||||
|
if (pSeg->pBoundingEntries == NULL) {
|
||||||
|
pSeg->pBoundingEntries = (MinMaxEntry *)malloc(sizeof(MinMaxEntry) * pBucket->nSlotsOfSeg);
|
||||||
|
resetBoundingBox(pSeg, pBucket->dataType);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pSeg->pBuffer == NULL) {
|
||||||
|
pSeg->pBuffer = (tExtMemBuffer **)calloc(pBucket->nSlotsOfSeg, sizeof(void *));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pSeg->pBuffer[slotIdx] == NULL) {
|
||||||
|
pSeg->pBuffer[slotIdx] = createExtMemBuffer(pBucket->numOfTotalPages * pBucket->pageSize, pBucket->nElemSize,
|
||||||
|
pBucket->pOrderDesc->pColumnModel);
|
||||||
|
pSeg->pBuffer[slotIdx]->flushModel = SINGLE_APPEND_MODEL;
|
||||||
|
pBucket->pOrderDesc->pColumnModel->capacity = pSeg->pBuffer[slotIdx]->numOfElemsPerPage;
|
||||||
|
}
|
||||||
|
|
||||||
|
tMemBucketUpdateBoundingBox(&pSeg->pBoundingEntries[slotIdx], d, pBucket->dataType);
|
||||||
|
|
||||||
|
// ensure available memory pages to allocate
|
||||||
|
int16_t cseg = 0, cslot = 0;
|
||||||
|
if (pBucket->numOfAvailPages == 0) {
|
||||||
|
pTrace("MemBucket:%p,max avail size:%d, no avail memory pages,", pBucket, pBucket->numOfTotalPages);
|
||||||
|
|
||||||
|
tBucketGetMaxMemSlot(pBucket, &cseg, &cslot);
|
||||||
|
if (cseg == -1 || cslot == -1) {
|
||||||
|
pError("MemBucket:%p,failed to find appropriated avail buffer", pBucket);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cseg != segIdx || cslot != slotIdx) {
|
||||||
|
pBucket->numOfAvailPages += pBucket->pSegs[cseg].pBuffer[cslot]->numOfInMemPages;
|
||||||
|
|
||||||
|
int32_t avail = pBucket->pSegs[cseg].pBuffer[cslot]->numOfInMemPages;
|
||||||
|
UNUSED(avail);
|
||||||
|
tExtMemBufferFlush(pBucket->pSegs[cseg].pBuffer[cslot]);
|
||||||
|
|
||||||
|
pTrace("MemBucket:%p,seg:%d,slot:%d flushed to disk,new avail pages:%d", pBucket, cseg, cslot,
|
||||||
|
pBucket->numOfAvailPages);
|
||||||
|
} else {
|
||||||
|
pTrace("MemBucket:%p,failed to choose slot to flush to disk seg:%d,slot:%d", pBucket, cseg, cslot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int16_t consumedPgs = pSeg->pBuffer[slotIdx]->numOfInMemPages;
|
||||||
|
|
||||||
|
int16_t newPgs = tExtMemBufferPut(pSeg->pBuffer[slotIdx], d, 1);
|
||||||
|
/*
|
||||||
|
* trigger 1. page re-allocation, to reduce the available pages
|
||||||
|
* 2. page flushout, to increase the available pages
|
||||||
|
*/
|
||||||
|
pBucket->numOfAvailPages += (consumedPgs - newPgs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void releaseBucket(tMemBucket *pMemBucket, int32_t segIdx, int32_t slotIdx) {
|
||||||
|
if (segIdx < 0 || segIdx > pMemBucket->numOfSegs || slotIdx < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tMemBucketSegment *pSeg = &pMemBucket->pSegs[segIdx];
|
||||||
|
if (slotIdx < 0 || slotIdx >= pSeg->numOfSlots || pSeg->pBuffer[slotIdx] == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pSeg->pBuffer[slotIdx] = destoryExtMemBuffer(pSeg->pBuffer[slotIdx]);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
static void findMaxMinValue(tMemBucket *pMemBucket, double *maxVal, double *minVal) {
|
||||||
|
*minVal = DBL_MAX;
|
||||||
|
*maxVal = -DBL_MAX;
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < pMemBucket->numOfSegs; ++i) {
|
||||||
|
tMemBucketSegment *pSeg = &pMemBucket->pSegs[i];
|
||||||
|
if (pSeg->pBuffer == NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch (pMemBucket->dataType) {
|
||||||
|
case TSDB_DATA_TYPE_INT:
|
||||||
|
case TSDB_DATA_TYPE_SMALLINT:
|
||||||
|
case TSDB_DATA_TYPE_TINYINT: {
|
||||||
|
for (int32_t j = 0; j < pSeg->numOfSlots; ++j) {
|
||||||
|
double minv = pSeg->pBoundingEntries[j].iMinVal;
|
||||||
|
double maxv = pSeg->pBoundingEntries[j].iMaxVal;
|
||||||
|
|
||||||
|
if (*minVal > minv) {
|
||||||
|
*minVal = minv;
|
||||||
|
}
|
||||||
|
if (*maxVal < maxv) {
|
||||||
|
*maxVal = maxv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TSDB_DATA_TYPE_DOUBLE:
|
||||||
|
case TSDB_DATA_TYPE_FLOAT: {
|
||||||
|
for (int32_t j = 0; j < pSeg->numOfSlots; ++j) {
|
||||||
|
double minv = pSeg->pBoundingEntries[j].dMinVal;
|
||||||
|
double maxv = pSeg->pBoundingEntries[j].dMaxVal;
|
||||||
|
|
||||||
|
if (*minVal > minv) {
|
||||||
|
*minVal = minv;
|
||||||
|
}
|
||||||
|
if (*maxVal < maxv) {
|
||||||
|
*maxVal = maxv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TSDB_DATA_TYPE_BIGINT: {
|
||||||
|
for (int32_t j = 0; j < pSeg->numOfSlots; ++j) {
|
||||||
|
double minv = (double)pSeg->pBoundingEntries[j].i64MinVal;
|
||||||
|
double maxv = (double)pSeg->pBoundingEntries[j].i64MaxVal;
|
||||||
|
|
||||||
|
if (*minVal > minv) {
|
||||||
|
*minVal = minv;
|
||||||
|
}
|
||||||
|
if (*maxVal < maxv) {
|
||||||
|
*maxVal = maxv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static MinMaxEntry getMinMaxEntryOfNearestSlotInNextSegment(tMemBucket *pMemBucket, int32_t segIdx) {
|
||||||
|
int32_t i = segIdx + 1;
|
||||||
|
while (i < pMemBucket->numOfSegs && pMemBucket->pSegs[i].numOfSlots == 0) ++i;
|
||||||
|
|
||||||
|
tMemBucketSegment *pSeg = &pMemBucket->pSegs[i];
|
||||||
|
assert(pMemBucket->numOfSegs > i && pMemBucket->pSegs[i].pBuffer != NULL);
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (i < pMemBucket->nSlotsOfSeg && pSeg->pBuffer[i] == NULL) ++i;
|
||||||
|
|
||||||
|
assert(i < pMemBucket->nSlotsOfSeg);
|
||||||
|
return pSeg->pBoundingEntries[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* now, we need to find the minimum value of the next slot for
|
||||||
|
* interpolating the percentile value
|
||||||
|
* j is the last slot of current segment, we need to get the first
|
||||||
|
* slot of the next segment.
|
||||||
|
*/
|
||||||
|
static MinMaxEntry getMinMaxEntryOfNextSlotWithData(tMemBucket *pMemBucket, int32_t segIdx, int32_t slotIdx) {
|
||||||
|
tMemBucketSegment *pSeg = &pMemBucket->pSegs[segIdx];
|
||||||
|
|
||||||
|
MinMaxEntry next;
|
||||||
|
if (slotIdx == pSeg->numOfSlots - 1) { // find next segment with data
|
||||||
|
return getMinMaxEntryOfNearestSlotInNextSegment(pMemBucket, segIdx);
|
||||||
|
} else {
|
||||||
|
int32_t j = slotIdx + 1;
|
||||||
|
for (; j < pMemBucket->nSlotsOfSeg && pMemBucket->pSegs[segIdx].pBuffer[j] == 0; ++j) {
|
||||||
|
};
|
||||||
|
|
||||||
|
if (j == pMemBucket->nSlotsOfSeg) { // current slot has no available
|
||||||
|
// slot,try next segment
|
||||||
|
return getMinMaxEntryOfNearestSlotInNextSegment(pMemBucket, segIdx);
|
||||||
|
} else {
|
||||||
|
next = pSeg->pBoundingEntries[slotIdx + 1];
|
||||||
|
assert(pSeg->pBuffer[slotIdx + 1] != NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isIdenticalData(tMemBucket *pMemBucket, int32_t segIdx, int32_t slotIdx);
|
||||||
|
char *getFirstElemOfMemBuffer(tMemBucketSegment *pSeg, int32_t slotIdx, tFilePage *pPage);
|
||||||
|
|
||||||
|
double getPercentileImpl(tMemBucket *pMemBucket, int32_t count, double fraction) {
|
||||||
|
int32_t num = 0;
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < pMemBucket->numOfSegs; ++i) {
|
||||||
|
tMemBucketSegment *pSeg = &pMemBucket->pSegs[i];
|
||||||
|
for (int32_t j = 0; j < pSeg->numOfSlots; ++j) {
|
||||||
|
if (pSeg->pBuffer == NULL || pSeg->pBuffer[j] == NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// required value in current slot
|
||||||
|
if (num < (count + 1) && num + pSeg->pBuffer[j]->numOfTotalElems >= (count + 1)) {
|
||||||
|
if (pSeg->pBuffer[j]->numOfTotalElems + num == (count + 1)) {
|
||||||
|
/*
|
||||||
|
* now, we need to find the minimum value of the next slot for interpolating the percentile value
|
||||||
|
* j is the last slot of current segment, we need to get the first slot of the next segment.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
MinMaxEntry next = getMinMaxEntryOfNextSlotWithData(pMemBucket, i, j);
|
||||||
|
|
||||||
|
double maxOfThisSlot = 0;
|
||||||
|
double minOfNextSlot = 0;
|
||||||
|
switch (pMemBucket->dataType) {
|
||||||
|
case TSDB_DATA_TYPE_INT:
|
||||||
|
case TSDB_DATA_TYPE_SMALLINT:
|
||||||
|
case TSDB_DATA_TYPE_TINYINT: {
|
||||||
|
maxOfThisSlot = pSeg->pBoundingEntries[j].iMaxVal;
|
||||||
|
minOfNextSlot = next.iMinVal;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
case TSDB_DATA_TYPE_FLOAT:
|
||||||
|
case TSDB_DATA_TYPE_DOUBLE: {
|
||||||
|
maxOfThisSlot = pSeg->pBoundingEntries[j].dMaxVal;
|
||||||
|
minOfNextSlot = next.dMinVal;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
case TSDB_DATA_TYPE_BIGINT: {
|
||||||
|
maxOfThisSlot = (double)pSeg->pBoundingEntries[j].i64MaxVal;
|
||||||
|
minOfNextSlot = (double)next.i64MinVal;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
assert(minOfNextSlot > maxOfThisSlot);
|
||||||
|
|
||||||
|
double val = (1 - fraction) * maxOfThisSlot + fraction * minOfNextSlot;
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
if (pSeg->pBuffer[j]->numOfTotalElems <= pMemBucket->maxElemsCapacity) {
|
||||||
|
// data in buffer and file are merged together to be processed.
|
||||||
|
tFilePage *buffer = loadIntoBucketFromDisk(pMemBucket, i, j, pMemBucket->pOrderDesc);
|
||||||
|
int32_t currentIdx = count - num;
|
||||||
|
|
||||||
|
char * thisVal = buffer->data + pMemBucket->nElemSize * currentIdx;
|
||||||
|
char * nextVal = thisVal + pMemBucket->nElemSize;
|
||||||
|
double td, nd;
|
||||||
|
switch (pMemBucket->dataType) {
|
||||||
|
case TSDB_DATA_TYPE_SMALLINT: {
|
||||||
|
td = *(int16_t *)thisVal;
|
||||||
|
nd = *(int16_t *)nextVal;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TSDB_DATA_TYPE_TINYINT: {
|
||||||
|
td = *(int8_t *)thisVal;
|
||||||
|
nd = *(int8_t *)nextVal;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TSDB_DATA_TYPE_INT: {
|
||||||
|
td = *(int32_t *)thisVal;
|
||||||
|
nd = *(int32_t *)nextVal;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
case TSDB_DATA_TYPE_FLOAT: {
|
||||||
|
// td = *(float *)thisVal;
|
||||||
|
// nd = *(float *)nextVal;
|
||||||
|
td = GET_FLOAT_VAL(thisVal);
|
||||||
|
nd = GET_FLOAT_VAL(nextVal);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TSDB_DATA_TYPE_DOUBLE: {
|
||||||
|
// td = *(double *)thisVal;
|
||||||
|
td = GET_DOUBLE_VAL(thisVal);
|
||||||
|
// nd = *(double *)nextVal;
|
||||||
|
nd = GET_DOUBLE_VAL(nextVal);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TSDB_DATA_TYPE_BIGINT: {
|
||||||
|
td = (double)*(int64_t *)thisVal;
|
||||||
|
nd = (double)*(int64_t *)nextVal;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
double val = (1 - fraction) * td + fraction * nd;
|
||||||
|
tfree(buffer);
|
||||||
|
|
||||||
|
return val;
|
||||||
|
} else { // incur a second round bucket split
|
||||||
|
if (isIdenticalData(pMemBucket, i, j)) {
|
||||||
|
tExtMemBuffer *pMemBuffer = pSeg->pBuffer[j];
|
||||||
|
|
||||||
|
tFilePage *pPage = (tFilePage *)malloc(pMemBuffer->pageSize);
|
||||||
|
|
||||||
|
char *thisVal = getFirstElemOfMemBuffer(pSeg, j, pPage);
|
||||||
|
|
||||||
|
double finalResult = 0.0;
|
||||||
|
|
||||||
|
switch (pMemBucket->dataType) {
|
||||||
|
case TSDB_DATA_TYPE_SMALLINT: {
|
||||||
|
finalResult = *(int16_t *)thisVal;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TSDB_DATA_TYPE_TINYINT: {
|
||||||
|
finalResult = *(int8_t *)thisVal;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TSDB_DATA_TYPE_INT: {
|
||||||
|
finalResult = *(int32_t *)thisVal;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
case TSDB_DATA_TYPE_FLOAT: {
|
||||||
|
// finalResult = *(float *)thisVal;
|
||||||
|
finalResult = GET_FLOAT_VAL(thisVal);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TSDB_DATA_TYPE_DOUBLE: {
|
||||||
|
// finalResult = *(double *)thisVal;
|
||||||
|
finalResult = GET_DOUBLE_VAL(thisVal);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TSDB_DATA_TYPE_BIGINT: {
|
||||||
|
finalResult = (double)(*(int64_t *)thisVal);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(pPage);
|
||||||
|
return finalResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
pTrace("MemBucket:%p,start second round bucketing", pMemBucket);
|
||||||
|
|
||||||
|
if (pSeg->pBuffer[j]->numOfElemsInBuffer != 0) {
|
||||||
|
pTrace("MemBucket:%p,flush %d pages to disk, clear status", pMemBucket, pSeg->pBuffer[j]->numOfInMemPages);
|
||||||
|
|
||||||
|
pMemBucket->numOfAvailPages += pSeg->pBuffer[j]->numOfInMemPages;
|
||||||
|
tExtMemBufferFlush(pSeg->pBuffer[j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
tExtMemBuffer *pMemBuffer = pSeg->pBuffer[j];
|
||||||
|
pSeg->pBuffer[j] = NULL;
|
||||||
|
|
||||||
|
// release all
|
||||||
|
for (int32_t tt = 0; tt < pMemBucket->numOfSegs; ++tt) {
|
||||||
|
tMemBucketSegment *pSeg = &pMemBucket->pSegs[tt];
|
||||||
|
for (int32_t ttx = 0; ttx < pSeg->numOfSlots; ++ttx) {
|
||||||
|
if (pSeg->pBuffer && pSeg->pBuffer[ttx]) {
|
||||||
|
pSeg->pBuffer[ttx] = destoryExtMemBuffer(pSeg->pBuffer[ttx]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pMemBucket->nRange.i64MaxVal = pSeg->pBoundingEntries->i64MaxVal;
|
||||||
|
pMemBucket->nRange.i64MinVal = pSeg->pBoundingEntries->i64MinVal;
|
||||||
|
pMemBucket->numOfElems = 0;
|
||||||
|
|
||||||
|
for (int32_t tt = 0; tt < pMemBucket->numOfSegs; ++tt) {
|
||||||
|
tMemBucketSegment *pSeg = &pMemBucket->pSegs[tt];
|
||||||
|
for (int32_t ttx = 0; ttx < pSeg->numOfSlots; ++ttx) {
|
||||||
|
if (pSeg->pBoundingEntries) {
|
||||||
|
resetBoundingBox(pSeg, pMemBucket->dataType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tFilePage *pPage = (tFilePage *)malloc(pMemBuffer->pageSize);
|
||||||
|
|
||||||
|
tFlushoutInfo *pFlushInfo = &pMemBuffer->fileMeta.flushoutData.pFlushoutInfo[0];
|
||||||
|
assert(pFlushInfo->numOfPages == pMemBuffer->fileMeta.nFileSize);
|
||||||
|
|
||||||
|
int32_t ret = fseek(pMemBuffer->file, pFlushInfo->startPageId * pMemBuffer->pageSize, SEEK_SET);
|
||||||
|
UNUSED(ret);
|
||||||
|
|
||||||
|
for (uint32_t jx = 0; jx < pFlushInfo->numOfPages; ++jx) {
|
||||||
|
ret = fread(pPage, pMemBuffer->pageSize, 1, pMemBuffer->file);
|
||||||
|
UNUSED(ret);
|
||||||
|
tMemBucketPut(pMemBucket, pPage->data, pPage->numOfElems);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(pMemBuffer->file);
|
||||||
|
if (unlink(pMemBuffer->path) != 0) {
|
||||||
|
pError("MemBucket:%p, remove tmp file %s failed", pMemBucket, pMemBuffer->path);
|
||||||
|
}
|
||||||
|
tfree(pMemBuffer);
|
||||||
|
tfree(pPage);
|
||||||
|
|
||||||
|
return getPercentileImpl(pMemBucket, count - num, fraction);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
num += pSeg->pBuffer[j]->numOfTotalElems;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
double getPercentile(tMemBucket *pMemBucket, double percent) {
|
||||||
|
if (pMemBucket->numOfElems == 0) {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pMemBucket->numOfElems == 1) { // return the only element
|
||||||
|
return findOnlyResult(pMemBucket);
|
||||||
|
}
|
||||||
|
|
||||||
|
percent = fabs(percent);
|
||||||
|
|
||||||
|
// validate the parameters
|
||||||
|
if (fabs(percent - 100.0) < DBL_EPSILON || (percent < DBL_EPSILON)) {
|
||||||
|
double minx = 0, maxx = 0;
|
||||||
|
/*
|
||||||
|
* find the min/max value, no need to scan all data in bucket
|
||||||
|
*/
|
||||||
|
findMaxMinValue(pMemBucket, &maxx, &minx);
|
||||||
|
|
||||||
|
return fabs(percent - 100) < DBL_EPSILON ? maxx : minx;
|
||||||
|
}
|
||||||
|
|
||||||
|
double percentVal = (percent * (pMemBucket->numOfElems - 1)) / ((double)100.0);
|
||||||
|
int32_t orderIdx = (int32_t)percentVal;
|
||||||
|
|
||||||
|
// do put data by using buckets
|
||||||
|
return getPercentileImpl(pMemBucket, orderIdx, percentVal - orderIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* check if data in one slot are all identical
|
||||||
|
* only need to compare with the bounding box
|
||||||
|
*/
|
||||||
|
bool isIdenticalData(tMemBucket *pMemBucket, int32_t segIdx, int32_t slotIdx) {
|
||||||
|
tMemBucketSegment *pSeg = &pMemBucket->pSegs[segIdx];
|
||||||
|
|
||||||
|
if (pMemBucket->dataType == TSDB_DATA_TYPE_INT || pMemBucket->dataType == TSDB_DATA_TYPE_BIGINT ||
|
||||||
|
pMemBucket->dataType == TSDB_DATA_TYPE_SMALLINT || pMemBucket->dataType == TSDB_DATA_TYPE_TINYINT) {
|
||||||
|
return pSeg->pBoundingEntries[slotIdx].i64MinVal == pSeg->pBoundingEntries[slotIdx].i64MaxVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pMemBucket->dataType == TSDB_DATA_TYPE_FLOAT || pMemBucket->dataType == TSDB_DATA_TYPE_DOUBLE) {
|
||||||
|
return fabs(pSeg->pBoundingEntries[slotIdx].dMaxVal - pSeg->pBoundingEntries[slotIdx].dMinVal) < DBL_EPSILON;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* get the first element of one slot into memory.
|
||||||
|
* if no data of current slot in memory, load it from disk
|
||||||
|
*/
|
||||||
|
char *getFirstElemOfMemBuffer(tMemBucketSegment *pSeg, int32_t slotIdx, tFilePage *pPage) {
|
||||||
|
tExtMemBuffer *pMemBuffer = pSeg->pBuffer[slotIdx];
|
||||||
|
char * thisVal = NULL;
|
||||||
|
|
||||||
|
if (pSeg->pBuffer[slotIdx]->numOfElemsInBuffer != 0) {
|
||||||
|
thisVal = pSeg->pBuffer[slotIdx]->pHead->item.data;
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* no data in memory, load one page into memory
|
||||||
|
*/
|
||||||
|
tFlushoutInfo *pFlushInfo = &pMemBuffer->fileMeta.flushoutData.pFlushoutInfo[0];
|
||||||
|
assert(pFlushInfo->numOfPages == pMemBuffer->fileMeta.nFileSize);
|
||||||
|
|
||||||
|
fseek(pMemBuffer->file, pFlushInfo->startPageId * pMemBuffer->pageSize, SEEK_SET);
|
||||||
|
size_t ret = fread(pPage, pMemBuffer->pageSize, 1, pMemBuffer->file);
|
||||||
|
UNUSED(ret);
|
||||||
|
thisVal = pPage->data;
|
||||||
|
}
|
||||||
|
return thisVal;
|
||||||
|
}
|
|
@ -0,0 +1,225 @@
|
||||||
|
#include "hash.h"
|
||||||
|
#include "taoserror.h"
|
||||||
|
#include "textbuffer.h"
|
||||||
|
#include "tlog.h"
|
||||||
|
#include "tsqlfunction.h"
|
||||||
|
#include "tresultBuf.h"
|
||||||
|
|
||||||
|
#define DEFAULT_INTERN_BUF_SIZE 16384L
|
||||||
|
|
||||||
|
int32_t createResultBuf(SQueryResultBuf** pResultBuf, int32_t size, int32_t rowSize) {
|
||||||
|
SQueryResultBuf* pResBuf = calloc(1, sizeof(SQueryResultBuf));
|
||||||
|
pResBuf->numOfRowsPerPage = (DEFAULT_INTERN_BUF_SIZE - sizeof(tFilePage)) / rowSize;
|
||||||
|
pResBuf->numOfPages = size;
|
||||||
|
|
||||||
|
pResBuf->totalBufSize = pResBuf->numOfPages * DEFAULT_INTERN_BUF_SIZE;
|
||||||
|
pResBuf->incStep = 4;
|
||||||
|
|
||||||
|
// init id hash table
|
||||||
|
pResBuf->idsTable = taosInitHashTable(size, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false);
|
||||||
|
pResBuf->list = calloc(size, sizeof(SIDList));
|
||||||
|
pResBuf->numOfAllocGroupIds = size;
|
||||||
|
|
||||||
|
char path[4096] = {0};
|
||||||
|
getTmpfilePath("tsdb_q_buf", path);
|
||||||
|
pResBuf->path = strdup(path);
|
||||||
|
|
||||||
|
pResBuf->fd = open(pResBuf->path, O_CREAT | O_RDWR, 0666);
|
||||||
|
|
||||||
|
memset(path, 0, tListLen(path));
|
||||||
|
|
||||||
|
if (!FD_VALID(pResBuf->fd)) {
|
||||||
|
pError("failed to create tmp file: %s on disk. %s", pResBuf->path, strerror(errno));
|
||||||
|
return TSDB_CODE_CLI_NO_DISKSPACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t ret = ftruncate(pResBuf->fd, pResBuf->numOfPages * DEFAULT_INTERN_BUF_SIZE);
|
||||||
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
|
pError("failed to create tmp file: %s on disk. %s", pResBuf->path, strerror(errno));
|
||||||
|
return TSDB_CODE_CLI_NO_DISKSPACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
pResBuf->pBuf = mmap(NULL, pResBuf->totalBufSize, PROT_READ | PROT_WRITE, MAP_SHARED, pResBuf->fd, 0);
|
||||||
|
if (pResBuf->pBuf == MAP_FAILED) {
|
||||||
|
pError("QInfo:%p failed to map temp file: %s. %s", pResBuf->path, strerror(errno));
|
||||||
|
return TSDB_CODE_CLI_OUT_OF_MEMORY; // todo change error code
|
||||||
|
}
|
||||||
|
|
||||||
|
pTrace("create tmp file for output result, %s, " PRId64 "bytes", pResBuf->path, pResBuf->totalBufSize);
|
||||||
|
*pResultBuf = pResBuf;
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
tFilePage* getResultBufferPageById(SQueryResultBuf* pResultBuf, int32_t id) {
|
||||||
|
assert(id < pResultBuf->numOfPages && id >= 0);
|
||||||
|
|
||||||
|
return (tFilePage*)(pResultBuf->pBuf + DEFAULT_INTERN_BUF_SIZE * id);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t getNumOfResultBufGroupId(SQueryResultBuf* pResultBuf) { return taosNumElemsInHashTable(pResultBuf->idsTable); }
|
||||||
|
|
||||||
|
int32_t getResBufSize(SQueryResultBuf* pResultBuf) { return pResultBuf->totalBufSize; }
|
||||||
|
|
||||||
|
static int32_t extendDiskFileSize(SQueryResultBuf* pResultBuf, int32_t numOfPages) {
|
||||||
|
assert(pResultBuf->numOfPages * DEFAULT_INTERN_BUF_SIZE == pResultBuf->totalBufSize);
|
||||||
|
|
||||||
|
int32_t ret = munmap(pResultBuf->pBuf, pResultBuf->totalBufSize);
|
||||||
|
pResultBuf->numOfPages += numOfPages;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* disk-based output buffer is exhausted, try to extend the disk-based buffer, the available disk space may
|
||||||
|
* be insufficient
|
||||||
|
*/
|
||||||
|
ret = ftruncate(pResultBuf->fd, pResultBuf->numOfPages * DEFAULT_INTERN_BUF_SIZE);
|
||||||
|
if (ret != 0) {
|
||||||
|
// dError("QInfo:%p failed to create intermediate result output file:%s. %s", pQInfo, pSupporter->extBufFile,
|
||||||
|
// strerror(errno));
|
||||||
|
return -TSDB_CODE_SERV_NO_DISKSPACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
pResultBuf->totalBufSize = pResultBuf->numOfPages * DEFAULT_INTERN_BUF_SIZE;
|
||||||
|
pResultBuf->pBuf = mmap(NULL, pResultBuf->totalBufSize, PROT_READ | PROT_WRITE, MAP_SHARED, pResultBuf->fd, 0);
|
||||||
|
|
||||||
|
if (pResultBuf->pBuf == MAP_FAILED) {
|
||||||
|
// dError("QInfo:%p failed to map temp file: %s. %s", pQInfo, pSupporter->extBufFile, strerror(errno));
|
||||||
|
return -TSDB_CODE_SERV_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool noMoreAvailablePages(SQueryResultBuf* pResultBuf) {
|
||||||
|
return (pResultBuf->allocateId == pResultBuf->numOfPages - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t getGroupIndex(SQueryResultBuf* pResultBuf, int32_t groupId) {
|
||||||
|
assert(pResultBuf != NULL);
|
||||||
|
|
||||||
|
char* p = taosGetDataFromHashTable(pResultBuf->idsTable, (const char*)&groupId, sizeof(int32_t));
|
||||||
|
if (p == NULL) { // it is a new group id
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t slot = GET_INT32_VAL(p);
|
||||||
|
assert(slot >= 0 && slot < pResultBuf->numOfAllocGroupIds);
|
||||||
|
|
||||||
|
return slot;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t addNewGroupId(SQueryResultBuf* pResultBuf, int32_t groupId) {
|
||||||
|
int32_t num = getNumOfResultBufGroupId(pResultBuf); // the num is the newest allocated group id slot
|
||||||
|
|
||||||
|
if (pResultBuf->numOfAllocGroupIds <= num) {
|
||||||
|
size_t n = pResultBuf->numOfAllocGroupIds << 1u;
|
||||||
|
|
||||||
|
SIDList* p = (SIDList*)realloc(pResultBuf->list, sizeof(SIDList) * n);
|
||||||
|
assert(p != NULL);
|
||||||
|
|
||||||
|
memset(&p[pResultBuf->numOfAllocGroupIds], 0, sizeof(SIDList) * pResultBuf->numOfAllocGroupIds);
|
||||||
|
|
||||||
|
pResultBuf->list = p;
|
||||||
|
pResultBuf->numOfAllocGroupIds = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
taosAddToHashTable(pResultBuf->idsTable, (const char*)&groupId, sizeof(int32_t), &num, sizeof(int32_t));
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t doRegisterId(SIDList* pList, int32_t id) {
|
||||||
|
if (pList->size >= pList->alloc) {
|
||||||
|
int32_t s = 0;
|
||||||
|
if (pList->alloc == 0) {
|
||||||
|
s = 4;
|
||||||
|
assert(pList->pData == NULL);
|
||||||
|
} else {
|
||||||
|
s = pList->alloc << 1u;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t* c = realloc(pList->pData, s * sizeof(int32_t));
|
||||||
|
assert(c);
|
||||||
|
|
||||||
|
memset(&c[pList->alloc], 0, sizeof(int32_t) * pList->alloc);
|
||||||
|
|
||||||
|
pList->pData = c;
|
||||||
|
pList->alloc = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
pList->pData[pList->size++] = id;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void registerPageId(SQueryResultBuf* pResultBuf, int32_t groupId, int32_t pageId) {
|
||||||
|
int32_t slot = getGroupIndex(pResultBuf, groupId);
|
||||||
|
if (slot < 0) {
|
||||||
|
slot = addNewGroupId(pResultBuf, groupId);
|
||||||
|
}
|
||||||
|
|
||||||
|
SIDList* pList = &pResultBuf->list[slot];
|
||||||
|
doRegisterId(pList, pageId);
|
||||||
|
}
|
||||||
|
|
||||||
|
tFilePage* getNewDataBuf(SQueryResultBuf* pResultBuf, int32_t groupId, int32_t* pageId) {
|
||||||
|
if (noMoreAvailablePages(pResultBuf)) {
|
||||||
|
if (extendDiskFileSize(pResultBuf, pResultBuf->incStep) != TSDB_CODE_SUCCESS) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// register new id in this group
|
||||||
|
*pageId = (pResultBuf->allocateId++);
|
||||||
|
registerPageId(pResultBuf, groupId, *pageId);
|
||||||
|
|
||||||
|
tFilePage* page = getResultBufferPageById(pResultBuf, *pageId);
|
||||||
|
|
||||||
|
// clear memory for the new page
|
||||||
|
memset(page, 0, DEFAULT_INTERN_BUF_SIZE);
|
||||||
|
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t getNumOfRowsPerPage(SQueryResultBuf* pResultBuf) { return pResultBuf->numOfRowsPerPage; }
|
||||||
|
|
||||||
|
SIDList getDataBufPagesIdList(SQueryResultBuf* pResultBuf, int32_t groupId) {
|
||||||
|
SIDList list = {0};
|
||||||
|
int32_t slot = getGroupIndex(pResultBuf, groupId);
|
||||||
|
if (slot < 0) {
|
||||||
|
return list;
|
||||||
|
} else {
|
||||||
|
return pResultBuf->list[slot];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroyResultBuf(SQueryResultBuf* pResultBuf) {
|
||||||
|
if (pResultBuf == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FD_VALID(pResultBuf->fd)) {
|
||||||
|
close(pResultBuf->fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
pTrace("disk-based output buffer closed, %" PRId64 " bytes, file:%s", pResultBuf->totalBufSize, pResultBuf->path);
|
||||||
|
munmap(pResultBuf->pBuf, pResultBuf->totalBufSize);
|
||||||
|
unlink(pResultBuf->path);
|
||||||
|
|
||||||
|
tfree(pResultBuf->path);
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < pResultBuf->numOfAllocGroupIds; ++i) {
|
||||||
|
SIDList* pList = &pResultBuf->list[i];
|
||||||
|
tfree(pList->pData);
|
||||||
|
}
|
||||||
|
|
||||||
|
tfree(pResultBuf->list);
|
||||||
|
taosCleanUpHashTable(pResultBuf->idsTable);
|
||||||
|
|
||||||
|
tfree(pResultBuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t getLastPageId(SIDList *pList) {
|
||||||
|
if (pList == NULL && pList->size <= 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pList->pData[pList->size - 1];
|
||||||
|
}
|
||||||
|
|
|
@ -274,7 +274,7 @@ int tSQLKeywordCode(const char* z, int n) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SKeyword** pKey = (SKeyword**)taosGetDataFromHash(KeywordHashTable, key, n);
|
SKeyword** pKey = (SKeyword**)taosGetDataFromHashTable(KeywordHashTable, key, n);
|
||||||
if (pKey != NULL) {
|
if (pKey != NULL) {
|
||||||
return (*pKey)->type;
|
return (*pKey)->type;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -13,8 +13,8 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef TDENGINE_VNODEQUERYUTIL_H
|
#ifndef TDENGINE_VNODEQUERYIMPL_H
|
||||||
#define TDENGINE_VNODEQUERYUTIL_H
|
#define TDENGINE_VNODEQUERYIMPL_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -120,7 +120,7 @@ typedef enum {
|
||||||
typedef int (*__block_search_fn_t)(char* data, int num, int64_t key, int order);
|
typedef int (*__block_search_fn_t)(char* data, int num, int64_t key, int order);
|
||||||
|
|
||||||
static FORCE_INLINE SMeterObj* getMeterObj(void* hashHandle, int32_t sid) {
|
static FORCE_INLINE SMeterObj* getMeterObj(void* hashHandle, int32_t sid) {
|
||||||
return *(SMeterObj**)taosGetDataFromHash(hashHandle, (const char*) &sid, sizeof(sid));
|
return *(SMeterObj**)taosGetDataFromHashTable(hashHandle, (const char*) &sid, sizeof(sid));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isQueryKilled(SQuery* pQuery);
|
bool isQueryKilled(SQuery* pQuery);
|
||||||
|
@ -209,7 +209,7 @@ int32_t vnodeGetHeaderFile(SQueryRuntimeEnv *pRuntimeEnv, int32_t fileIndex);
|
||||||
* @param ekey
|
* @param ekey
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
SMeterQueryInfo* createMeterQueryInfo(SQuery* pQuery, TSKEY skey, TSKEY ekey);
|
SMeterQueryInfo* createMeterQueryInfo(SQuery* pQuery, int32_t sid, TSKEY skey, TSKEY ekey);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy meter query info
|
* Destroy meter query info
|
||||||
|
@ -224,7 +224,7 @@ void destroyMeterQueryInfo(SMeterQueryInfo *pMeterQueryInfo, int32_t numOfCols);
|
||||||
* @param skey
|
* @param skey
|
||||||
* @param ekey
|
* @param ekey
|
||||||
*/
|
*/
|
||||||
void changeMeterQueryInfoForSuppleQuery(SMeterQueryInfo *pMeterQueryInfo, TSKEY skey, TSKEY ekey);
|
void changeMeterQueryInfoForSuppleQuery(SQueryResultBuf* pResultBuf, SMeterQueryInfo *pMeterQueryInfo, TSKEY skey, TSKEY ekey);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* add the new allocated disk page to meter query info
|
* add the new allocated disk page to meter query info
|
||||||
|
@ -276,11 +276,11 @@ void displayInterResult(SData** pdata, SQuery* pQuery, int32_t numOfRows);
|
||||||
|
|
||||||
void vnodePrintQueryStatistics(SMeterQuerySupportObj* pSupporter);
|
void vnodePrintQueryStatistics(SMeterQuerySupportObj* pSupporter);
|
||||||
|
|
||||||
void clearGroupResultBuf(SOutputRes* pOneOutputRes, int32_t nOutputCols);
|
void clearGroupResultBuf(SQueryRuntimeEnv *pRuntimeEnv, SOutputRes *pOneOutputRes);
|
||||||
void copyGroupResultBuf(SOutputRes* dst, const SOutputRes* src, int32_t nOutputCols);
|
void copyGroupResultBuf(SQueryRuntimeEnv *pRuntimeEnv, SOutputRes* dst, const SOutputRes* src);
|
||||||
|
|
||||||
void resetSlidingWindowInfo(SSlidingWindowInfo* pSlidingWindowInfo, int32_t numOfCols);
|
void resetSlidingWindowInfo(SQueryRuntimeEnv *pRuntimeEnv, SSlidingWindowInfo* pSlidingWindowInfo);
|
||||||
void clearCompletedSlidingWindows(SSlidingWindowInfo* pSlidingWindowInfo, int32_t numOfCols);
|
void clearCompletedSlidingWindows(SQueryRuntimeEnv* pRuntimeEnv);
|
||||||
int32_t numOfClosedSlidingWindow(SSlidingWindowInfo* pSlidingWindowInfo);
|
int32_t numOfClosedSlidingWindow(SSlidingWindowInfo* pSlidingWindowInfo);
|
||||||
void closeSlidingWindow(SSlidingWindowInfo* pSlidingWindowInfo, int32_t slot);
|
void closeSlidingWindow(SSlidingWindowInfo* pSlidingWindowInfo, int32_t slot);
|
||||||
void closeAllSlidingWindow(SSlidingWindowInfo* pSlidingWindowInfo);
|
void closeAllSlidingWindow(SSlidingWindowInfo* pSlidingWindowInfo);
|
||||||
|
@ -289,4 +289,4 @@ void closeAllSlidingWindow(SSlidingWindowInfo* pSlidingWindowInfo);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // TDENGINE_VNODEQUERYUTIL_H
|
#endif // TDENGINE_VNODEQUERYIMPL_H
|
||||||
|
|
|
@ -21,6 +21,7 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
#include "tresultBuf.h"
|
||||||
|
|
||||||
#include "tinterpolation.h"
|
#include "tinterpolation.h"
|
||||||
#include "vnodeTagMgmt.h"
|
#include "vnodeTagMgmt.h"
|
||||||
|
@ -84,10 +85,15 @@ typedef struct SQueryCostSummary {
|
||||||
int64_t tmpBufferInDisk; // size of buffer for intermediate result
|
int64_t tmpBufferInDisk; // size of buffer for intermediate result
|
||||||
} SQueryCostSummary;
|
} SQueryCostSummary;
|
||||||
|
|
||||||
|
typedef struct SPosInfo {
|
||||||
|
int64_t pageId;
|
||||||
|
int32_t rowId;
|
||||||
|
} SPosInfo;
|
||||||
|
|
||||||
typedef struct SOutputRes {
|
typedef struct SOutputRes {
|
||||||
uint16_t numOfRows;
|
uint16_t numOfRows;
|
||||||
int32_t nAlloc;
|
int32_t nAlloc;
|
||||||
tFilePage** result;
|
SPosInfo pos;
|
||||||
SResultInfo* resultInfo;
|
SResultInfo* resultInfo;
|
||||||
} SOutputRes;
|
} SOutputRes;
|
||||||
|
|
||||||
|
@ -174,16 +180,17 @@ typedef struct SQueryRuntimeEnv {
|
||||||
* So we keep a copy of the support structure as well as the cache block data itself.
|
* So we keep a copy of the support structure as well as the cache block data itself.
|
||||||
*/
|
*/
|
||||||
SCacheBlock cacheBlock;
|
SCacheBlock cacheBlock;
|
||||||
|
|
||||||
|
SQueryResultBuf* pResultBuf;
|
||||||
|
bool stableQuery; // is super table query or not
|
||||||
} SQueryRuntimeEnv;
|
} SQueryRuntimeEnv;
|
||||||
|
|
||||||
/* intermediate result during multimeter query involves interval */
|
/* intermediate pos during multimeter query involves interval */
|
||||||
typedef struct SMeterQueryInfo {
|
typedef struct SMeterQueryInfo {
|
||||||
int64_t lastKey;
|
int64_t lastKey;
|
||||||
int64_t skey;
|
int64_t skey;
|
||||||
int64_t ekey;
|
int64_t ekey;
|
||||||
int32_t numOfRes;
|
int32_t numOfRes;
|
||||||
uint32_t numOfPages;
|
|
||||||
uint32_t numOfAlloc;
|
|
||||||
int32_t reverseIndex; // reversed output indicator, start from (numOfRes-1)
|
int32_t reverseIndex; // reversed output indicator, start from (numOfRes-1)
|
||||||
int16_t reverseFillRes; // denote if reverse fill the results in supplementary scan required or not
|
int16_t reverseFillRes; // denote if reverse fill the results in supplementary scan required or not
|
||||||
int16_t queryRangeSet; // denote if the query range is set, only available for interval query
|
int16_t queryRangeSet; // denote if the query range is set, only available for interval query
|
||||||
|
@ -191,7 +198,7 @@ typedef struct SMeterQueryInfo {
|
||||||
int64_t tag;
|
int64_t tag;
|
||||||
STSCursor cur;
|
STSCursor cur;
|
||||||
SResultInfo* resultInfo;
|
SResultInfo* resultInfo;
|
||||||
uint32_t* pageList;
|
int32_t sid; // for retrieve the page id list
|
||||||
} SMeterQueryInfo;
|
} SMeterQueryInfo;
|
||||||
|
|
||||||
typedef struct SMeterDataInfo {
|
typedef struct SMeterDataInfo {
|
||||||
|
@ -235,16 +242,8 @@ typedef struct SMeterQuerySupportObj {
|
||||||
*/
|
*/
|
||||||
int32_t meterIdx;
|
int32_t meterIdx;
|
||||||
|
|
||||||
int32_t meterOutputFd;
|
|
||||||
int32_t lastPageId;
|
|
||||||
int32_t numOfPages;
|
|
||||||
int32_t numOfGroupResultPages;
|
int32_t numOfGroupResultPages;
|
||||||
int32_t groupResultSize;
|
int32_t groupResultSize;
|
||||||
|
|
||||||
char* meterOutputMMapBuf;
|
|
||||||
int64_t bufSize;
|
|
||||||
char extBufFile[256]; // external file name
|
|
||||||
|
|
||||||
SMeterDataInfo* pMeterDataInfo;
|
SMeterDataInfo* pMeterDataInfo;
|
||||||
|
|
||||||
TSKEY* tsList;
|
TSKEY* tsList;
|
||||||
|
|
|
@ -32,14 +32,21 @@ extern "C" {
|
||||||
* Note:
|
* Note:
|
||||||
* 1. we implement a quick sort algorithm, may remove it later.
|
* 1. we implement a quick sort algorithm, may remove it later.
|
||||||
*/
|
*/
|
||||||
|
typedef struct tSidSet {
|
||||||
|
int32_t numOfSids;
|
||||||
|
int32_t numOfSubSet;
|
||||||
|
SMeterSidExtInfo **pSids;
|
||||||
|
int32_t * starterPos; // position of each subgroup, generated according to
|
||||||
|
|
||||||
|
SColumnModel *pColumnModel;
|
||||||
|
SColumnOrderInfo orderIdx;
|
||||||
|
} tSidSet;
|
||||||
|
|
||||||
typedef int32_t (*__ext_compar_fn_t)(const void *p1, const void *p2, void *param);
|
typedef int32_t (*__ext_compar_fn_t)(const void *p1, const void *p2, void *param);
|
||||||
|
|
||||||
tSidSet *tSidSetCreate(struct SMeterSidExtInfo **pMeterSidExtInfo, int32_t numOfMeters, SSchema *pSchema,
|
tSidSet *tSidSetCreate(struct SMeterSidExtInfo **pMeterSidExtInfo, int32_t numOfMeters, SSchema *pSchema,
|
||||||
int32_t numOfTags, SColIndexEx *colList, int32_t numOfOrderCols);
|
int32_t numOfTags, SColIndexEx *colList, int32_t numOfOrderCols);
|
||||||
|
|
||||||
tTagSchema *tCreateTagSchema(SSchema *pSchema, int32_t numOfTagCols);
|
|
||||||
|
|
||||||
int32_t *calculateSubGroup(void **pSids, int32_t numOfMeters, int32_t *numOfSubset, tOrderDescriptor *pOrderDesc,
|
int32_t *calculateSubGroup(void **pSids, int32_t numOfMeters, int32_t *numOfSubset, tOrderDescriptor *pOrderDesc,
|
||||||
__ext_compar_fn_t compareFn);
|
__ext_compar_fn_t compareFn);
|
||||||
|
|
||||||
|
|
|
@ -127,7 +127,7 @@ int vnodeCreateHeadDataFile(int vnode, int fileId, char *headName, char *dataNam
|
||||||
if (symlink(dDataName, dataName) != 0) return -1;
|
if (symlink(dDataName, dataName) != 0) return -1;
|
||||||
if (symlink(dLastName, lastName) != 0) return -1;
|
if (symlink(dLastName, lastName) != 0) return -1;
|
||||||
|
|
||||||
dPrint("vid:%d, fileId:%d, empty header file:%s dataFile:%s lastFile:%s on disk:%s is created ",
|
dPrint("vid:%d, fileId:%d, empty header file:%s file:%s lastFile:%s on disk:%s is created ",
|
||||||
vnode, fileId, headName, dataName, lastName, path);
|
vnode, fileId, headName, dataName, lastName, path);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -132,7 +132,7 @@ static void queryOnMultiDataCache(SQInfo *pQInfo, SMeterDataInfo *pMeterInfo) {
|
||||||
pRuntimeEnv->pMeterObj = pMeterObj;
|
pRuntimeEnv->pMeterObj = pMeterObj;
|
||||||
|
|
||||||
if (pMeterInfo[k].pMeterQInfo == NULL) {
|
if (pMeterInfo[k].pMeterQInfo == NULL) {
|
||||||
pMeterInfo[k].pMeterQInfo = createMeterQueryInfo(pQuery, pSupporter->rawSKey, pSupporter->rawEKey);
|
pMeterInfo[k].pMeterQInfo = createMeterQueryInfo(pQuery, pMeterObj->sid, pSupporter->rawSKey, pSupporter->rawEKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pMeterInfo[k].pMeterObj == NULL) { // no data in disk for this meter, set its pointer
|
if (pMeterInfo[k].pMeterObj == NULL) { // no data in disk for this meter, set its pointer
|
||||||
|
@ -683,7 +683,7 @@ static void vnodeSTableSeqProcessor(SQInfo *pQInfo) {
|
||||||
}
|
}
|
||||||
|
|
||||||
resetCtxOutputBuf(pRuntimeEnv);
|
resetCtxOutputBuf(pRuntimeEnv);
|
||||||
resetSlidingWindowInfo(&pRuntimeEnv->swindowResInfo, pQuery->numOfOutputCols);
|
resetSlidingWindowInfo(pRuntimeEnv, &pRuntimeEnv->swindowResInfo);
|
||||||
|
|
||||||
while (pSupporter->meterIdx < pSupporter->numOfMeters) {
|
while (pSupporter->meterIdx < pSupporter->numOfMeters) {
|
||||||
int32_t k = pSupporter->meterIdx;
|
int32_t k = pSupporter->meterIdx;
|
||||||
|
@ -858,7 +858,9 @@ static void doOrderedScan(SQInfo *pQInfo) {
|
||||||
static void setupMeterQueryInfoForSupplementQuery(SMeterQuerySupportObj *pSupporter) {
|
static void setupMeterQueryInfoForSupplementQuery(SMeterQuerySupportObj *pSupporter) {
|
||||||
for (int32_t i = 0; i < pSupporter->numOfMeters; ++i) {
|
for (int32_t i = 0; i < pSupporter->numOfMeters; ++i) {
|
||||||
SMeterQueryInfo *pMeterQueryInfo = pSupporter->pMeterDataInfo[i].pMeterQInfo;
|
SMeterQueryInfo *pMeterQueryInfo = pSupporter->pMeterDataInfo[i].pMeterQInfo;
|
||||||
changeMeterQueryInfoForSuppleQuery(pMeterQueryInfo, pSupporter->rawSKey, pSupporter->rawEKey);
|
SQueryResultBuf* pResultBuf = pSupporter->runtimeEnv.pResultBuf;
|
||||||
|
|
||||||
|
changeMeterQueryInfoForSuppleQuery(pResultBuf, pMeterQueryInfo, pSupporter->rawSKey, pSupporter->rawEKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1086,7 +1088,7 @@ static void vnodeSingleMeterIntervalMainLooper(SMeterQuerySupportObj *pSupporter
|
||||||
(pQuery->skey >= pQuery->ekey && !QUERY_IS_ASC_QUERY(pQuery)));
|
(pQuery->skey >= pQuery->ekey && !QUERY_IS_ASC_QUERY(pQuery)));
|
||||||
|
|
||||||
initCtxOutputBuf(pRuntimeEnv);
|
initCtxOutputBuf(pRuntimeEnv);
|
||||||
clearCompletedSlidingWindows(&pRuntimeEnv->swindowResInfo, pQuery->numOfOutputCols);
|
clearCompletedSlidingWindows(pRuntimeEnv);
|
||||||
|
|
||||||
vnodeScanAllData(pRuntimeEnv);
|
vnodeScanAllData(pRuntimeEnv);
|
||||||
if (isQueryKilled(pQuery)) {
|
if (isQueryKilled(pQuery)) {
|
||||||
|
|
|
@ -77,7 +77,7 @@ static int32_t tabObjResultComparator(const void* p1, const void* p2, void* para
|
||||||
STabObj* pNode1 = (STabObj*)p1;
|
STabObj* pNode1 = (STabObj*)p1;
|
||||||
STabObj* pNode2 = (STabObj*)p2;
|
STabObj* pNode2 = (STabObj*)p2;
|
||||||
|
|
||||||
for (int32_t i = 0; i < pOrderDesc->orderIdx.numOfOrderedCols; ++i) {
|
for (int32_t i = 0; i < pOrderDesc->orderIdx.numOfCols; ++i) {
|
||||||
int32_t colIdx = pOrderDesc->orderIdx.pData[i];
|
int32_t colIdx = pOrderDesc->orderIdx.pData[i];
|
||||||
|
|
||||||
char* f1 = NULL;
|
char* f1 = NULL;
|
||||||
|
@ -91,9 +91,11 @@ static int32_t tabObjResultComparator(const void* p1, const void* p2, void* para
|
||||||
schema.type = TSDB_DATA_TYPE_BINARY;
|
schema.type = TSDB_DATA_TYPE_BINARY;
|
||||||
schema.bytes = TSDB_TABLE_ID_LEN;
|
schema.bytes = TSDB_TABLE_ID_LEN;
|
||||||
} else {
|
} else {
|
||||||
f1 = mgmtTableGetTag(pNode1, colIdx, NULL);
|
f1 = mgmtMeterGetTag(pNode1, colIdx, NULL);
|
||||||
f2 = mgmtTableGetTag(pNode2, colIdx, &schema);
|
f2 = mgmtMeterGetTag(pNode2, colIdx, &schema);
|
||||||
assert(schema.type == pOrderDesc->pTagSchema->pSchema[colIdx].type);
|
|
||||||
|
SSchema* pSchema = getColumnModelSchema(pOrderDesc->pColumnModel, colIdx);
|
||||||
|
assert(schema.type == pSchema->type);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t ret = doCompare(f1, f2, schema.type, schema.bytes);
|
int32_t ret = doCompare(f1, f2, schema.type, schema.bytes);
|
||||||
|
@ -116,7 +118,7 @@ static int32_t tabObjResultComparator(const void* p1, const void* p2, void* para
|
||||||
* @param pOrderIndexInfo
|
* @param pOrderIndexInfo
|
||||||
* @param numOfTags
|
* @param numOfTags
|
||||||
*/
|
*/
|
||||||
static void mgmtUpdateOrderTagColIndex(SSuperTableMetaMsg* pSuperTableMetaMsg, int32_t tableIndex, tOrderIdx* pOrderIndexInfo,
|
static void mgmtUpdateOrderTagColIndex(SMetricMetaMsg* pMetricMetaMsg, int32_t tableIndex, SColumnOrderInfo* pOrderIndexInfo,
|
||||||
int32_t numOfTags) {
|
int32_t numOfTags) {
|
||||||
SMetricMetaElemMsg* pElem = (SMetricMetaElemMsg*)((char*)pSuperTableMetaMsg + pSuperTableMetaMsg->metaElem[tableIndex]);
|
SMetricMetaElemMsg* pElem = (SMetricMetaElemMsg*)((char*)pSuperTableMetaMsg + pSuperTableMetaMsg->metaElem[tableIndex]);
|
||||||
SColIndexEx* groupColumnList = (SColIndexEx*)((char*)pSuperTableMetaMsg + pElem->groupbyTagColumnList);
|
SColIndexEx* groupColumnList = (SColIndexEx*)((char*)pSuperTableMetaMsg + pElem->groupbyTagColumnList);
|
||||||
|
@ -130,7 +132,7 @@ static void mgmtUpdateOrderTagColIndex(SSuperTableMetaMsg* pSuperTableMetaMsg, i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pOrderIndexInfo->numOfOrderedCols = numOfGroupbyTags;
|
pOrderIndexInfo->numOfCols = numOfGroupbyTags;
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo merge sort function with losertree used
|
// todo merge sort function with losertree used
|
||||||
|
@ -150,14 +152,14 @@ void mgmtReorganizeMetersInMetricMeta(SSuperTableMetaMsg* pSuperTableMetaMsg, in
|
||||||
*/
|
*/
|
||||||
tOrderDescriptor* descriptor =
|
tOrderDescriptor* descriptor =
|
||||||
(tOrderDescriptor*)calloc(1, sizeof(tOrderDescriptor) + sizeof(int32_t) * pElem->numOfGroupCols);
|
(tOrderDescriptor*)calloc(1, sizeof(tOrderDescriptor) + sizeof(int32_t) * pElem->numOfGroupCols);
|
||||||
descriptor->pTagSchema = tCreateTagSchema(pTagSchema, pMetric->numOfTags);
|
descriptor->pColumnModel = createColumnModel(pTagSchema, pMetric->numOfTags, 1);
|
||||||
descriptor->orderIdx.numOfOrderedCols = pElem->numOfGroupCols;
|
descriptor->orderIdx.numOfCols = pElem->numOfGroupCols;
|
||||||
|
|
||||||
int32_t* startPos = NULL;
|
int32_t* startPos = NULL;
|
||||||
int32_t numOfSubset = 1;
|
int32_t numOfSubset = 1;
|
||||||
|
|
||||||
mgmtUpdateOrderTagColIndex(pSuperTableMetaMsg, tableIndex, &descriptor->orderIdx, pMetric->numOfTags);
|
mgmtUpdateOrderTagColIndex(pMetricMetaMsg, tableIndex, &descriptor->orderIdx, pMetric->numOfTags);
|
||||||
if (descriptor->orderIdx.numOfOrderedCols > 0) {
|
if (descriptor->orderIdx.numOfCols > 0) {
|
||||||
tQSortEx(pRes->pRes, POINTER_BYTES, 0, pRes->num - 1, descriptor, tabObjResultComparator);
|
tQSortEx(pRes->pRes, POINTER_BYTES, 0, pRes->num - 1, descriptor, tabObjResultComparator);
|
||||||
startPos = calculateSubGroup(pRes->pRes, pRes->num, &numOfSubset, descriptor, tabObjResultComparator);
|
startPos = calculateSubGroup(pRes->pRes, pRes->num, &numOfSubset, descriptor, tabObjResultComparator);
|
||||||
} else {
|
} else {
|
||||||
|
@ -173,7 +175,7 @@ void mgmtReorganizeMetersInMetricMeta(SSuperTableMetaMsg* pSuperTableMetaMsg, in
|
||||||
*/
|
*/
|
||||||
qsort(pRes->pRes, (size_t)pRes->num, POINTER_BYTES, tabObjVGIDComparator);
|
qsort(pRes->pRes, (size_t)pRes->num, POINTER_BYTES, tabObjVGIDComparator);
|
||||||
|
|
||||||
free(descriptor->pTagSchema);
|
free(descriptor->pColumnModel);
|
||||||
free(descriptor);
|
free(descriptor);
|
||||||
free(startPos);
|
free(startPos);
|
||||||
}
|
}
|
||||||
|
@ -298,15 +300,15 @@ static void orderResult(SSuperTableMetaMsg* pSuperTableMetaMsg, tQueryResultset*
|
||||||
STabObj* pMetric = mgmtGetTable(pElem->meterId);
|
STabObj* pMetric = mgmtGetTable(pElem->meterId);
|
||||||
SSchema* pTagSchema = (SSchema*)(pMetric->schema + pMetric->numOfColumns * sizeof(SSchema));
|
SSchema* pTagSchema = (SSchema*)(pMetric->schema + pMetric->numOfColumns * sizeof(SSchema));
|
||||||
|
|
||||||
descriptor->pTagSchema = tCreateTagSchema(pTagSchema, pMetric->numOfTags);
|
descriptor->pColumnModel = createColumnModel(pTagSchema, pMetric->numOfTags, 1);
|
||||||
|
|
||||||
descriptor->orderIdx.pData[0] = colIndex;
|
descriptor->orderIdx.pData[0] = colIndex;
|
||||||
descriptor->orderIdx.numOfOrderedCols = 1;
|
descriptor->orderIdx.numOfCols = 1;
|
||||||
|
|
||||||
// sort results list
|
// sort results list
|
||||||
tQSortEx(pRes->pRes, POINTER_BYTES, 0, pRes->num - 1, descriptor, tabObjResultComparator);
|
tQSortEx(pRes->pRes, POINTER_BYTES, 0, pRes->num - 1, descriptor, tabObjResultComparator);
|
||||||
|
|
||||||
free(descriptor->pTagSchema);
|
free(descriptor->pColumnModel);
|
||||||
free(descriptor);
|
free(descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,10 +24,10 @@
|
||||||
#include "tast.h"
|
#include "tast.h"
|
||||||
#include "vnodeTagMgmt.h"
|
#include "vnodeTagMgmt.h"
|
||||||
|
|
||||||
#define GET_TAG_VAL_POINTER(s, col, sc, t) ((t *)(&((s)->tags[(sc)->colOffset[(col)]])))
|
#define GET_TAG_VAL_POINTER(s, col, sc, t) ((t *)(&((s)->tags[getColumnModelOffset(sc, col)])))
|
||||||
#define GET_TAG_VAL(s, col, sc, t) (*GET_TAG_VAL_POINTER(s, col, sc, t))
|
#define GET_TAG_VAL(s, col, sc, t) (*GET_TAG_VAL_POINTER(s, col, sc, t))
|
||||||
|
|
||||||
static void tTagsPrints(SMeterSidExtInfo *pMeterInfo, tTagSchema *pSchema, tOrderIdx *pOrder);
|
static void tTagsPrints(SMeterSidExtInfo *pMeterInfo, SColumnModel *pSchema, SColumnOrderInfo *pOrder);
|
||||||
|
|
||||||
static void tSidSetDisplay(tSidSet *pSets);
|
static void tSidSetDisplay(tSidSet *pSets);
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ int32_t meterSidComparator(const void *p1, const void *p2, void *param) {
|
||||||
SMeterSidExtInfo *s1 = (SMeterSidExtInfo *)p1;
|
SMeterSidExtInfo *s1 = (SMeterSidExtInfo *)p1;
|
||||||
SMeterSidExtInfo *s2 = (SMeterSidExtInfo *)p2;
|
SMeterSidExtInfo *s2 = (SMeterSidExtInfo *)p2;
|
||||||
|
|
||||||
for (int32_t i = 0; i < pOrderDesc->orderIdx.numOfOrderedCols; ++i) {
|
for (int32_t i = 0; i < pOrderDesc->orderIdx.numOfCols; ++i) {
|
||||||
int32_t colIdx = pOrderDesc->orderIdx.pData[i];
|
int32_t colIdx = pOrderDesc->orderIdx.pData[i];
|
||||||
|
|
||||||
char * f1 = NULL;
|
char * f1 = NULL;
|
||||||
|
@ -79,9 +79,9 @@ int32_t meterSidComparator(const void *p1, const void *p2, void *param) {
|
||||||
type = TSDB_DATA_TYPE_BINARY;
|
type = TSDB_DATA_TYPE_BINARY;
|
||||||
bytes = TSDB_METER_NAME_LEN;
|
bytes = TSDB_METER_NAME_LEN;
|
||||||
} else {
|
} else {
|
||||||
f1 = GET_TAG_VAL_POINTER(s1, colIdx, pOrderDesc->pTagSchema, char);
|
f1 = GET_TAG_VAL_POINTER(s1, colIdx, pOrderDesc->pColumnModel, char);
|
||||||
f2 = GET_TAG_VAL_POINTER(s2, colIdx, pOrderDesc->pTagSchema, char);
|
f2 = GET_TAG_VAL_POINTER(s2, colIdx, pOrderDesc->pColumnModel, char);
|
||||||
SSchema *pSchema = &pOrderDesc->pTagSchema->pSchema[colIdx];
|
SSchema *pSchema = getColumnModelSchema(pOrderDesc->pColumnModel, colIdx);
|
||||||
type = pSchema->type;
|
type = pSchema->type;
|
||||||
bytes = pSchema->bytes;
|
bytes = pSchema->bytes;
|
||||||
}
|
}
|
||||||
|
@ -116,9 +116,9 @@ static void median(void **pMeterSids, size_t size, int32_t s1, int32_t s2, tOrde
|
||||||
compareFn(pMeterSids[s1], pMeterSids[s2], pOrderDesc) <= 0);
|
compareFn(pMeterSids[s1], pMeterSids[s2], pOrderDesc) <= 0);
|
||||||
|
|
||||||
#ifdef _DEBUG_VIEW
|
#ifdef _DEBUG_VIEW
|
||||||
tTagsPrints(pMeterSids[s1], pOrderDesc->pTagSchema, &pOrderDesc->orderIdx);
|
tTagsPrints(pMeterSids[s1], pOrderDesc->pColumnModel, &pOrderDesc->orderIdx);
|
||||||
tTagsPrints(pMeterSids[midIdx], pOrderDesc->pTagSchema, &pOrderDesc->orderIdx);
|
tTagsPrints(pMeterSids[midIdx], pOrderDesc->pColumnModel, &pOrderDesc->orderIdx);
|
||||||
tTagsPrints(pMeterSids[s2], pOrderDesc->pTagSchema, &pOrderDesc->orderIdx);
|
tTagsPrints(pMeterSids[s2], pOrderDesc->pColumnModel, &pOrderDesc->orderIdx);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,25 +241,6 @@ int32_t *calculateSubGroup(void **pSids, int32_t numOfMeters, int32_t *numOfSubs
|
||||||
return starterPos;
|
return starterPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
tTagSchema *tCreateTagSchema(SSchema *pSchema, int32_t numOfTagCols) {
|
|
||||||
if (numOfTagCols == 0 || pSchema == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
tTagSchema *pTagSchema =
|
|
||||||
(tTagSchema *)calloc(1, sizeof(tTagSchema) + numOfTagCols * sizeof(int32_t) + sizeof(SSchema) * numOfTagCols);
|
|
||||||
|
|
||||||
pTagSchema->colOffset[0] = 0;
|
|
||||||
pTagSchema->numOfCols = numOfTagCols;
|
|
||||||
for (int32_t i = 1; i < numOfTagCols; ++i) {
|
|
||||||
pTagSchema->colOffset[i] = (pTagSchema->colOffset[i - 1] + pSchema[i - 1].bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
pTagSchema->pSchema = (SSchema *)&(pTagSchema->colOffset[numOfTagCols]);
|
|
||||||
memcpy(pTagSchema->pSchema, pSchema, sizeof(SSchema) * numOfTagCols);
|
|
||||||
return pTagSchema;
|
|
||||||
}
|
|
||||||
|
|
||||||
tSidSet *tSidSetCreate(struct SMeterSidExtInfo **pMeterSidExtInfo, int32_t numOfMeters, SSchema *pSchema,
|
tSidSet *tSidSetCreate(struct SMeterSidExtInfo **pMeterSidExtInfo, int32_t numOfMeters, SSchema *pSchema,
|
||||||
int32_t numOfTags, SColIndexEx *colList, int32_t numOfCols) {
|
int32_t numOfTags, SColIndexEx *colList, int32_t numOfCols) {
|
||||||
tSidSet *pSidSet = (tSidSet *)calloc(1, sizeof(tSidSet) + numOfCols * sizeof(int16_t));
|
tSidSet *pSidSet = (tSidSet *)calloc(1, sizeof(tSidSet) + numOfCols * sizeof(int16_t));
|
||||||
|
@ -269,8 +250,8 @@ tSidSet *tSidSetCreate(struct SMeterSidExtInfo **pMeterSidExtInfo, int32_t numOf
|
||||||
|
|
||||||
pSidSet->numOfSids = numOfMeters;
|
pSidSet->numOfSids = numOfMeters;
|
||||||
pSidSet->pSids = pMeterSidExtInfo;
|
pSidSet->pSids = pMeterSidExtInfo;
|
||||||
pSidSet->pTagSchema = tCreateTagSchema(pSchema, numOfTags);
|
pSidSet->pColumnModel = createColumnModel(pSchema, numOfTags, 1);
|
||||||
pSidSet->orderIdx.numOfOrderedCols = numOfCols;
|
pSidSet->orderIdx.numOfCols = numOfCols;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* in case of "group by tbname,normal_col", the normal_col is ignored
|
* in case of "group by tbname,normal_col", the normal_col is ignored
|
||||||
|
@ -282,7 +263,7 @@ tSidSet *tSidSetCreate(struct SMeterSidExtInfo **pMeterSidExtInfo, int32_t numOf
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pSidSet->orderIdx.numOfOrderedCols = numOfTagCols;
|
pSidSet->orderIdx.numOfCols = numOfTagCols;
|
||||||
|
|
||||||
pSidSet->starterPos = NULL;
|
pSidSet->starterPos = NULL;
|
||||||
return pSidSet;
|
return pSidSet;
|
||||||
|
@ -291,19 +272,19 @@ tSidSet *tSidSetCreate(struct SMeterSidExtInfo **pMeterSidExtInfo, int32_t numOf
|
||||||
void tSidSetDestroy(tSidSet **pSets) {
|
void tSidSetDestroy(tSidSet **pSets) {
|
||||||
if ((*pSets) != NULL) {
|
if ((*pSets) != NULL) {
|
||||||
tfree((*pSets)->starterPos);
|
tfree((*pSets)->starterPos);
|
||||||
tfree((*pSets)->pTagSchema)(*pSets)->pSids = NULL;
|
tfree((*pSets)->pColumnModel)(*pSets)->pSids = NULL;
|
||||||
tfree(*pSets);
|
tfree(*pSets);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void tTagsPrints(SMeterSidExtInfo *pMeterInfo, tTagSchema *pSchema, tOrderIdx *pOrder) {
|
void tTagsPrints(SMeterSidExtInfo *pMeterInfo, SColumnModel *pSchema, SColumnOrderInfo *pOrder) {
|
||||||
if (pSchema == NULL) {
|
if (pSchema == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("sid: %-5d tags(", pMeterInfo->sid);
|
printf("sid: %-5d tags(", pMeterInfo->sid);
|
||||||
|
|
||||||
for (int32_t i = 0; i < pOrder->numOfOrderedCols; ++i) {
|
for (int32_t i = 0; i < pOrder->numOfCols; ++i) {
|
||||||
int32_t colIndex = pOrder->pData[i];
|
int32_t colIndex = pOrder->pData[i];
|
||||||
|
|
||||||
// it is the tbname column
|
// it is the tbname column
|
||||||
|
@ -312,7 +293,9 @@ void tTagsPrints(SMeterSidExtInfo *pMeterInfo, tTagSchema *pSchema, tOrderIdx *p
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (pSchema->pSchema[colIndex].type) {
|
SSchema* s = getColumnModelSchema(pSchema, colIndex);
|
||||||
|
|
||||||
|
switch (s->type) {
|
||||||
case TSDB_DATA_TYPE_INT:
|
case TSDB_DATA_TYPE_INT:
|
||||||
printf("%d, ", GET_TAG_VAL(pMeterInfo, colIndex, pSchema, int32_t));
|
printf("%d, ", GET_TAG_VAL(pMeterInfo, colIndex, pSchema, int32_t));
|
||||||
break;
|
break;
|
||||||
|
@ -336,9 +319,9 @@ void tTagsPrints(SMeterSidExtInfo *pMeterInfo, tTagSchema *pSchema, tOrderIdx *p
|
||||||
break;
|
break;
|
||||||
case TSDB_DATA_TYPE_NCHAR: {
|
case TSDB_DATA_TYPE_NCHAR: {
|
||||||
char *data = GET_TAG_VAL_POINTER(pMeterInfo, colIndex, pSchema, char);
|
char *data = GET_TAG_VAL_POINTER(pMeterInfo, colIndex, pSchema, char);
|
||||||
char buffer[512] = {0};
|
|
||||||
|
|
||||||
taosUcs4ToMbs(data, pSchema->pSchema[colIndex].bytes, buffer);
|
char buffer[512] = {0};
|
||||||
|
taosUcs4ToMbs(data, s->bytes, buffer);
|
||||||
printf("%s, ", buffer);
|
printf("%s, ", buffer);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -370,16 +353,16 @@ static void UNUSED_FUNC tSidSetDisplay(tSidSet *pSets) {
|
||||||
|
|
||||||
printf("the %d-th subgroup: \n", i + 1);
|
printf("the %d-th subgroup: \n", i + 1);
|
||||||
for (int32_t j = s; j < e; ++j) {
|
for (int32_t j = s; j < e; ++j) {
|
||||||
tTagsPrints(pSets->pSids[j], pSets->pTagSchema, &pSets->orderIdx);
|
tTagsPrints(pSets->pSids[j], pSets->pColumnModel, &pSets->orderIdx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void tSidSetSort(tSidSet *pSets) {
|
void tSidSetSort(tSidSet *pSets) {
|
||||||
pTrace("number of meters in sort: %d", pSets->numOfSids);
|
pTrace("number of meters in sort: %d", pSets->numOfSids);
|
||||||
tOrderIdx *pOrderIdx = &pSets->orderIdx;
|
SColumnOrderInfo *pOrderIdx = &pSets->orderIdx;
|
||||||
|
|
||||||
if (pOrderIdx->numOfOrderedCols == 0 || pSets->numOfSids <= 1 || pSets->pTagSchema == NULL) { // no group by tags clause
|
if (pOrderIdx->numOfCols == 0 || pSets->numOfSids <= 1 || pSets->pColumnModel == NULL) { // no group by tags clause
|
||||||
pSets->numOfSubSet = 1;
|
pSets->numOfSubSet = 1;
|
||||||
pSets->starterPos = (int32_t *)malloc(sizeof(int32_t) * (pSets->numOfSubSet + 1));
|
pSets->starterPos = (int32_t *)malloc(sizeof(int32_t) * (pSets->numOfSubSet + 1));
|
||||||
pSets->starterPos[0] = 0;
|
pSets->starterPos[0] = 0;
|
||||||
|
@ -390,11 +373,11 @@ void tSidSetSort(tSidSet *pSets) {
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
tOrderDescriptor *descriptor =
|
tOrderDescriptor *descriptor =
|
||||||
(tOrderDescriptor *)calloc(1, sizeof(tOrderDescriptor) + sizeof(int16_t) * pSets->orderIdx.numOfOrderedCols);
|
(tOrderDescriptor *)calloc(1, sizeof(tOrderDescriptor) + sizeof(int16_t) * pSets->orderIdx.numOfCols);
|
||||||
descriptor->pTagSchema = pSets->pTagSchema;
|
descriptor->pColumnModel = pSets->pColumnModel;
|
||||||
descriptor->orderIdx = pSets->orderIdx;
|
descriptor->orderIdx = pSets->orderIdx;
|
||||||
|
|
||||||
memcpy(descriptor->orderIdx.pData, pOrderIdx->pData, sizeof(int16_t) * pSets->orderIdx.numOfOrderedCols);
|
memcpy(descriptor->orderIdx.pData, pOrderIdx->pData, sizeof(int16_t) * pSets->orderIdx.numOfCols);
|
||||||
|
|
||||||
tQSortEx((void **)pSets->pSids, POINTER_BYTES, 0, pSets->numOfSids - 1, descriptor, meterSidComparator);
|
tQSortEx((void **)pSets->pSids, POINTER_BYTES, 0, pSets->numOfSids - 1, descriptor, meterSidComparator);
|
||||||
pSets->starterPos =
|
pSets->starterPos =
|
||||||
|
|
|
@ -247,7 +247,7 @@ SSqlFunctionExpr* vnodeCreateSqlFunctionExpr(SQueryMeterMsg* pQueryMsg, int32_t*
|
||||||
|
|
||||||
SColIndexEx* pColumnIndexExInfo = &pExprs[i].pBase.colInfo;
|
SColIndexEx* pColumnIndexExInfo = &pExprs[i].pBase.colInfo;
|
||||||
|
|
||||||
// tag column schema is kept in pQueryMsg->pTagSchema
|
// tag column schema is kept in pQueryMsg->pColumnModel
|
||||||
if (TSDB_COL_IS_TAG(pColumnIndexExInfo->flag)) {
|
if (TSDB_COL_IS_TAG(pColumnIndexExInfo->flag)) {
|
||||||
if (pColumnIndexExInfo->colIdx >= pQueryMsg->numOfTagsCols) {
|
if (pColumnIndexExInfo->colIdx >= pQueryMsg->numOfTagsCols) {
|
||||||
*code = TSDB_CODE_INVALID_QUERY_MSG;
|
*code = TSDB_CODE_INVALID_QUERY_MSG;
|
||||||
|
|
Loading…
Reference in New Issue