2020-03-19 16:03:55 +00:00
/*
* 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/>.
*/
2022-08-09 02:16:00 +00:00
# include "osDef.h"
2022-04-26 11:04:26 +00:00
# include "tsdb.h"
2022-08-20 03:14:00 +00:00
2022-08-26 07:27:19 +00:00
# define ASCENDING_TRAVERSE(o) (o == TSDB_ORDER_ASC)
2022-08-20 03:14:00 +00:00
# define ALL_ROWS_CHECKED_INDEX (INT16_MIN)
2022-08-26 07:27:19 +00:00
# define INITIAL_ROW_INDEX_VAL (-1)
2022-06-16 08:58:00 +00:00
2022-07-25 03:17:45 +00:00
typedef enum {
EXTERNAL_ROWS_PREV = 0x1 ,
EXTERNAL_ROWS_MAIN = 0x2 ,
EXTERNAL_ROWS_NEXT = 0x3 ,
} EContentData ;
2022-07-04 15:28:27 +00:00
typedef struct {
2022-07-06 10:29:11 +00:00
STbDataIter * iter ;
2022-07-04 15:28:27 +00:00
int32_t index ;
bool hasVal ;
} SIterInfo ;
2022-08-16 23:51:09 +00:00
typedef struct {
int32_t numOfBlocks ;
int32_t numOfLastBlocks ;
} SBlockNumber ;
2022-06-27 02:46:20 +00:00
typedef struct STableBlockScanInfo {
2022-07-06 10:29:11 +00:00
uint64_t uid ;
TSKEY lastKey ;
2022-08-17 16:08:09 +00:00
SMapData mapData ; // block info (compressed)
SArray * pBlockList ; // block data index list
SIterInfo iter ; // mem buffer skip list iterator
SIterInfo iiter ; // imem buffer skip list iterator
SArray * delSkyline ; // delete info for this table
2022-08-21 12:15:53 +00:00
int32_t fileDelIndex ; // file block delete index
int32_t lastBlockDelIndex ; // delete index for last block
2022-08-17 16:08:09 +00:00
bool iterInit ; // whether to initialize the in-memory skip list iterator or not
int16_t indexInBlockL ; // row position in last block
2022-06-27 02:46:20 +00:00
} STableBlockScanInfo ;
typedef struct SBlockOrderWrapper {
2022-07-06 10:29:11 +00:00
int64_t uid ;
2022-07-26 02:19:12 +00:00
int64_t offset ;
2022-06-27 02:46:20 +00:00
} SBlockOrderWrapper ;
2022-06-16 08:58:00 +00:00
typedef struct SBlockOrderSupporter {
2022-07-04 03:42:50 +00:00
SBlockOrderWrapper * * pDataBlockInfo ;
int32_t * indexPerTable ;
int32_t * numOfBlocksPerTable ;
int32_t numOfTables ;
2022-06-16 08:58:00 +00:00
} SBlockOrderSupporter ;
typedef struct SIOCostSummary {
2022-07-26 02:19:12 +00:00
int64_t numOfBlocks ;
double blockLoadTime ;
double buildmemBlock ;
2021-07-15 07:28:55 +00:00
int64_t headFileLoad ;
2022-07-26 02:19:12 +00:00
double headFileLoadTime ;
2022-08-22 03:57:10 +00:00
int64_t smaDataLoad ;
2022-07-26 02:19:12 +00:00
double smaLoadTime ;
2022-08-22 03:57:10 +00:00
int64_t lastBlockLoad ;
double lastBlockLoadTime ;
2022-06-16 08:58:00 +00:00
} SIOCostSummary ;
typedef struct SBlockLoadSuppInfo {
2022-07-07 07:56:43 +00:00
SArray * pColAgg ;
2022-07-07 07:32:56 +00:00
SColumnDataAgg tsColAgg ;
2022-05-02 10:16:43 +00:00
SColumnDataAgg * * plist ;
2022-07-04 03:42:50 +00:00
int16_t * colIds ; // column ids for loading file block data
char * * buildBuf ; // build string tmp buffer, todo remove it later after all string format being updated.
2022-06-16 08:58:00 +00:00
} SBlockLoadSuppInfo ;
2022-08-17 16:08:09 +00:00
typedef struct SVersionRange {
uint64_t minVer ;
uint64_t maxVer ;
} SVersionRange ;
typedef struct SLastBlockReader {
SArray * pBlockL ;
int32_t currentBlockIndex ;
SBlockData lastBlockData ;
STimeWindow window ;
SVersionRange verRange ;
2022-08-18 14:42:16 +00:00
int32_t order ;
2022-08-17 16:08:09 +00:00
uint64_t uid ;
2022-08-21 13:36:15 +00:00
int16_t * rowIndex ; // row index ptr, usually from the STableBlockScanInfo->indexInBlockL
2022-08-17 16:08:09 +00:00
} SLastBlockReader ;
2022-06-30 15:38:18 +00:00
typedef struct SFilesetIter {
2022-08-22 03:57:10 +00:00
int32_t numOfFiles ; // number of total files
int32_t index ; // current accessed index in the list
SArray * pFileList ; // data file list
int32_t order ;
2022-08-17 16:08:09 +00:00
SLastBlockReader * pLastBlockReader ; // last file block reader
2022-06-30 15:38:18 +00:00
} SFilesetIter ;
2022-06-27 02:46:20 +00:00
typedef struct SFileDataBlockInfo {
2022-07-25 03:17:45 +00:00
// index position in STableBlockScanInfo in order to check whether neighbor block overlaps with it
2022-07-06 10:29:11 +00:00
uint64_t uid ;
2022-07-29 10:15:44 +00:00
int32_t tbBlockIdx ;
2022-06-27 02:46:20 +00:00
} SFileDataBlockInfo ;
typedef struct SDataBlockIter {
2022-08-17 16:08:09 +00:00
int32_t numOfBlocks ;
2022-07-29 10:15:44 +00:00
int32_t index ;
2022-08-16 23:51:09 +00:00
SArray * blockList ; // SArray<SFileDataBlockInfo>
2022-07-29 10:15:44 +00:00
int32_t order ;
2022-08-16 23:51:09 +00:00
SBlock block ; // current SBlock data
2022-07-26 02:19:12 +00:00
SHashObj * pTableMap ;
2022-06-27 02:46:20 +00:00
} SDataBlockIter ;
typedef struct SFileBlockDumpInfo {
2022-07-06 10:29:11 +00:00
int32_t totalRows ;
int32_t rowIndex ;
int64_t lastKey ;
bool allDumped ;
2022-06-27 02:46:20 +00:00
} SFileBlockDumpInfo ;
2022-08-25 07:31:48 +00:00
typedef struct SUidOrderCheckInfo {
uint64_t * tableUidList ; // access table uid list in uid ascending order list
int32_t currentIndex ; // index in table uid list
} SUidOrderCheckInfo ;
2022-06-27 02:46:20 +00:00
typedef struct SReaderStatus {
2022-08-25 07:31:48 +00:00
bool loadFromFile ; // check file stage
2022-08-24 09:09:33 +00:00
bool composedDataBlock ; // the returned data block is a composed block or not
2022-08-25 07:31:48 +00:00
SHashObj * pTableMap ; // SHash<STableBlockScanInfo>
STableBlockScanInfo * pTableIter ; // table iterator used in building in-memory buffer data blocks.
SUidOrderCheckInfo uidCheckInfo ; // check all table in uid order
2022-07-04 03:42:50 +00:00
SFileBlockDumpInfo fBlockDumpInfo ;
2022-08-25 07:31:48 +00:00
SDFileSet * pCurrentFileset ; // current opened file set
2022-07-25 03:17:45 +00:00
SBlockData fileBlockData ;
SFilesetIter fileIter ;
SDataBlockIter blockIter ;
2022-06-27 02:46:20 +00:00
} SReaderStatus ;
2022-06-16 09:18:30 +00:00
struct STsdbReader {
2022-06-27 02:46:20 +00:00
STsdb * pTsdb ;
uint64_t suid ;
int16_t order ;
STimeWindow window ; // the primary query time window that applies to all queries
SSDataBlock * pResBlock ;
int32_t capacity ;
SReaderStatus status ;
2022-07-29 10:15:44 +00:00
char * idStr ; // query info handle, for debug purpose
int32_t type ; // query type: 1. retrieve all data blocks, 2. retrieve direct prev|next rows
2022-06-16 08:58:00 +00:00
SBlockLoadSuppInfo suppInfo ;
2022-07-21 11:42:42 +00:00
STsdbReadSnap * pReadSnap ;
2022-07-25 03:17:45 +00:00
SIOCostSummary cost ;
2022-08-11 10:19:44 +00:00
STSchema * pSchema ; // the newest version schema
STSchema * pMemSchema ; // the previous schema for in-memory data, to avoid load schema too many times
2022-07-25 03:17:45 +00:00
SDataFReader * pFileReader ;
SVersionRange verRange ;
2022-07-04 15:28:27 +00:00
2022-07-29 10:15:44 +00:00
int32_t step ;
STsdbReader * innerReader [ 2 ] ;
2022-06-16 09:18:30 +00:00
} ;
2022-06-16 08:58:00 +00:00
2022-06-27 02:46:20 +00:00
static SFileDataBlockInfo * getCurrentBlockInfo ( SDataBlockIter * pBlockIter ) ;
2022-07-04 03:42:50 +00:00
static int buildDataBlockFromBufImpl ( STableBlockScanInfo * pBlockScanInfo , int64_t endKey , int32_t capacity ,
STsdbReader * pReader ) ;
2022-08-24 09:09:33 +00:00
static TSDBROW * getValidMemRow ( SIterInfo * pIter , const SArray * pDelList , STsdbReader * pReader ) ;
2022-07-04 03:42:50 +00:00
static int32_t doMergeRowsInFileBlocks ( SBlockData * pBlockData , STableBlockScanInfo * pScanInfo , STsdbReader * pReader ,
SRowMerger * pMerger ) ;
2022-08-21 10:59:21 +00:00
static int32_t doMergeRowsInLastBlock ( SLastBlockReader * pLastBlockReader , STableBlockScanInfo * pScanInfo , int64_t ts , SRowMerger * pMerger ) ;
2022-07-30 04:46:40 +00:00
static int32_t doMergeRowsInBuf ( SIterInfo * pIter , uint64_t uid , int64_t ts , SArray * pDelList , SRowMerger * pMerger ,
2022-07-06 10:29:11 +00:00
STsdbReader * pReader ) ;
2022-08-09 02:16:00 +00:00
static int32_t doAppendRowFromTSRow ( SSDataBlock * pBlock , STsdbReader * pReader , STSRow * pTSRow , uint64_t uid ) ;
2022-08-17 16:08:09 +00:00
static int32_t doAppendRowFromFileBlock ( SSDataBlock * pResBlock , STsdbReader * pReader , SBlockData * pBlockData ,
2022-08-02 04:56:33 +00:00
int32_t rowIndex ) ;
2022-07-04 03:42:50 +00:00
static void setComposedBlockFlag ( STsdbReader * pReader , bool composed ) ;
2022-07-08 03:02:12 +00:00
static bool hasBeenDropped ( const SArray * pDelList , int32_t * index , TSDBKEY * pKey , int32_t order ) ;
2022-07-04 03:42:50 +00:00
2022-08-23 09:28:08 +00:00
static void doMergeMemTableMultiRows ( TSDBROW * pRow , uint64_t uid , SIterInfo * pIter , SArray * pDelList , STSRow * * pTSRow ,
2022-08-03 06:08:03 +00:00
STsdbReader * pReader , bool * freeTSRow ) ;
2022-07-04 03:42:50 +00:00
static void doMergeMemIMemRows ( TSDBROW * pRow , TSDBROW * piRow , STableBlockScanInfo * pBlockScanInfo , STsdbReader * pReader ,
STSRow * * pTSRow ) ;
2022-08-23 11:44:59 +00:00
static int32_t mergeRowsInFileBlocks ( SBlockData * pBlockData , STableBlockScanInfo * pBlockScanInfo , int64_t key , STsdbReader * pReader ) ;
2022-07-06 10:29:11 +00:00
static int32_t initDelSkylineIterator ( STableBlockScanInfo * pBlockScanInfo , STsdbReader * pReader , STbData * pMemTbData ,
STbData * piMemTbData ) ;
static STsdb * getTsdbByRetentions ( SVnode * pVnode , TSKEY winSKey , SRetention * retentions , const char * idstr ,
int8_t * pLevel ) ;
2022-07-05 11:30:37 +00:00
static SVersionRange getQueryVerRange ( SVnode * pVnode , SQueryTableDataCond * pCond , int8_t level ) ;
2022-08-17 16:08:09 +00:00
static int64_t getCurrentKeyInLastBlock ( SLastBlockReader * pLastBlockReader ) ;
2022-08-18 10:48:50 +00:00
static bool hasDataInLastBlock ( SLastBlockReader * pLastBlockReader ) ;
static int32_t doBuildDataBlock ( STsdbReader * pReader ) ;
2022-06-27 02:46:20 +00:00
2022-06-28 03:37:26 +00:00
static int32_t setColumnIdSlotList ( STsdbReader * pReader , SSDataBlock * pBlock ) {
SBlockLoadSuppInfo * pSupInfo = & pReader - > suppInfo ;
2022-06-30 06:50:59 +00:00
size_t numOfCols = blockDataGetNumOfCols ( pBlock ) ;
2022-06-28 03:37:26 +00:00
2022-06-30 06:50:59 +00:00
pSupInfo - > colIds = taosMemoryMalloc ( numOfCols * sizeof ( int16_t ) ) ;
2022-06-28 03:37:26 +00:00
pSupInfo - > buildBuf = taosMemoryCalloc ( numOfCols , POINTER_BYTES ) ;
2022-06-30 06:50:59 +00:00
if ( pSupInfo - > buildBuf = = NULL | | pSupInfo - > colIds = = NULL ) {
taosMemoryFree ( pSupInfo - > colIds ) ;
taosMemoryFree ( pSupInfo - > buildBuf ) ;
2022-06-27 02:46:20 +00:00
return TSDB_CODE_OUT_OF_MEMORY ;
}
2022-06-16 11:32:05 +00:00
2022-06-27 02:46:20 +00:00
for ( int32_t i = 0 ; i < numOfCols ; + + i ) {
SColumnInfoData * pCol = taosArrayGet ( pBlock - > pDataBlock , i ) ;
2022-06-30 06:50:59 +00:00
pSupInfo - > colIds [ i ] = pCol - > info . colId ;
2022-06-28 03:37:26 +00:00
if ( IS_VAR_DATA_TYPE ( pCol - > info . type ) ) {
pSupInfo - > buildBuf [ i ] = taosMemoryMalloc ( pCol - > info . bytes ) ;
}
2022-06-27 02:46:20 +00:00
}
2022-06-16 11:32:05 +00:00
2022-06-27 02:46:20 +00:00
return TSDB_CODE_SUCCESS ;
}
2022-06-16 08:58:00 +00:00
2022-06-28 02:32:42 +00:00
static SHashObj * createDataBlockScanInfo ( STsdbReader * pTsdbReader , const STableKeyInfo * idList , int32_t numOfTables ) {
2020-10-17 05:02:19 +00:00
// allocate buffer in order to load data blocks from file
2022-07-26 03:43:45 +00:00
// todo use simple hash instead, optimize the memory consumption
2022-07-04 03:42:50 +00:00
SHashObj * pTableMap =
taosHashInit ( numOfTables , taosGetDefaultHashFunction ( TSDB_DATA_TYPE_BIGINT ) , false , HASH_NO_LOCK ) ;
if ( pTableMap = = NULL ) {
2020-10-17 05:02:19 +00:00
return NULL ;
}
2022-07-04 03:42:50 +00:00
for ( int32_t j = 0 ; j < numOfTables ; + + j ) {
2022-08-26 07:27:19 +00:00
STableBlockScanInfo info = { . lastKey = 0 , . uid = idList [ j ] . uid , . indexInBlockL = INITIAL_ROW_INDEX_VAL } ;
2022-07-04 03:42:50 +00:00
if ( ASCENDING_TRAVERSE ( pTsdbReader - > order ) ) {
if ( info . lastKey = = INT64_MIN | | info . lastKey < pTsdbReader - > window . skey ) {
info . lastKey = pTsdbReader - > window . skey ;
2020-10-17 05:02:19 +00:00
}
2022-07-04 03:42:50 +00:00
ASSERT ( info . lastKey > = pTsdbReader - > window . skey & & info . lastKey < = pTsdbReader - > window . ekey ) ;
2022-05-26 08:05:27 +00:00
} else {
2022-07-04 03:42:50 +00:00
info . lastKey = pTsdbReader - > window . skey ;
2020-10-17 05:02:19 +00:00
}
2022-05-26 08:05:27 +00:00
2022-07-04 03:42:50 +00:00
taosHashPut ( pTableMap , & info . uid , sizeof ( uint64_t ) , & info , sizeof ( info ) ) ;
tsdbDebug ( " %p check table uid:% " PRId64 " from lastKey:% " PRId64 " %s " , pTsdbReader , info . uid , info . lastKey ,
pTsdbReader - > idStr ) ;
2020-10-17 05:02:19 +00:00
}
2022-07-29 10:15:44 +00:00
tsdbDebug ( " %p create %d tables scan-info, size:%.2f Kb, %s " , pTsdbReader , numOfTables ,
( sizeof ( STableBlockScanInfo ) * numOfTables ) / 1024.0 , pTsdbReader - > idStr ) ;
2022-07-25 03:17:45 +00:00
2022-07-04 03:42:50 +00:00
return pTableMap ;
2022-06-17 12:22:45 +00:00
}
2022-06-16 08:58:00 +00:00
2022-07-06 05:33:21 +00:00
static void resetDataBlockScanInfo ( SHashObj * pTableMap ) {
STableBlockScanInfo * p = NULL ;
2022-07-06 10:29:11 +00:00
while ( ( p = taosHashIterate ( pTableMap , p ) ) ! = NULL ) {
2022-07-06 05:33:21 +00:00
p - > iterInit = false ;
p - > iiter . hasVal = false ;
2022-07-06 10:29:11 +00:00
if ( p - > iter . iter ! = NULL ) {
2022-07-14 05:53:23 +00:00
p - > iter . iter = tsdbTbDataIterDestroy ( p - > iter . iter ) ;
2022-07-06 05:33:21 +00:00
}
2022-08-26 07:27:19 +00:00
p - > fileDelIndex = - 1 ;
p - > delSkyline = taosArrayDestroy ( p - > delSkyline ) ;
p - > lastBlockDelIndex = INITIAL_ROW_INDEX_VAL ;
2022-07-06 05:33:21 +00:00
}
}
2022-07-10 09:34:21 +00:00
static void destroyBlockScanInfo ( SHashObj * pTableMap ) {
STableBlockScanInfo * p = NULL ;
while ( ( p = taosHashIterate ( pTableMap , p ) ) ! = NULL ) {
p - > iterInit = false ;
p - > iiter . hasVal = false ;
if ( p - > iter . iter ! = NULL ) {
2022-07-14 05:53:23 +00:00
p - > iter . iter = tsdbTbDataIterDestroy ( p - > iter . iter ) ;
2022-07-10 09:34:21 +00:00
}
if ( p - > iiter . iter ! = NULL ) {
2022-07-14 05:53:23 +00:00
p - > iiter . iter = tsdbTbDataIterDestroy ( p - > iiter . iter ) ;
2022-07-10 09:34:21 +00:00
}
2022-07-14 05:53:23 +00:00
p - > delSkyline = taosArrayDestroy ( p - > delSkyline ) ;
p - > pBlockList = taosArrayDestroy ( p - > pBlockList ) ;
2022-07-26 03:43:45 +00:00
tMapDataClear ( & p - > mapData ) ;
2022-07-10 09:34:21 +00:00
}
taosHashCleanup ( pTableMap ) ;
}
2022-07-04 06:10:29 +00:00
static bool isEmptyQueryTimeWindow ( STimeWindow * pWindow ) {
2022-07-04 03:42:50 +00:00
ASSERT ( pWindow ! = NULL ) ;
return pWindow - > skey > pWindow - > ekey ;
2020-10-17 05:02:19 +00:00
}
2022-06-16 08:58:00 +00:00
2022-07-04 06:10:29 +00:00
// Update the query time window according to the data time to live(TTL) information, in order to avoid to return
// the expired data to client, even it is queried already.
static STimeWindow updateQueryTimeWindow ( STsdb * pTsdb , STimeWindow * pWindow ) {
2022-07-06 10:29:11 +00:00
STsdbKeepCfg * pCfg = & pTsdb - > keepCfg ;
2022-06-16 08:58:00 +00:00
2021-06-29 08:55:06 +00:00
int64_t now = taosGetTimestamp ( pCfg - > precision ) ;
2022-07-06 10:29:11 +00:00
int64_t earilyTs = now - ( tsTickPerMin [ pCfg - > precision ] * pCfg - > keep2 ) + 1 ; // needs to add one tick
2022-07-04 06:10:29 +00:00
2022-07-06 10:29:11 +00:00
STimeWindow win = * pWindow ;
2022-07-04 06:10:29 +00:00
if ( win . skey < earilyTs ) {
win . skey = earilyTs ;
}
return win ;
}
2022-06-16 08:58:00 +00:00
2022-06-29 12:25:03 +00:00
static void limitOutputBufferSize ( const SQueryTableDataCond * pCond , int32_t * capacity ) {
2022-06-27 02:46:20 +00:00
int32_t rowLen = 0 ;
for ( int32_t i = 0 ; i < pCond - > numOfCols ; + + i ) {
rowLen + = pCond - > colList [ i ] . bytes ;
}
// make sure the output SSDataBlock size be less than 2MB.
2022-06-29 12:25:03 +00:00
const int32_t TWOMB = 2 * 1024 * 1024 ;
if ( ( * capacity ) * rowLen > TWOMB ) {
( * capacity ) = TWOMB / rowLen ;
2022-06-27 02:46:20 +00:00
}
}
// init file iterator
2022-08-18 14:42:16 +00:00
static int32_t initFilesetIterator ( SFilesetIter * pIter , SArray * aDFileSet , STsdbReader * pReader /*int32_t order, const char* idstr*/ ) {
2022-07-21 11:42:42 +00:00
size_t numOfFileset = taosArrayGetSize ( aDFileSet ) ;
2022-06-30 15:38:18 +00:00
2022-08-18 14:42:16 +00:00
pIter - > index = ASCENDING_TRAVERSE ( pReader - > order ) ? - 1 : numOfFileset ;
pIter - > order = pReader - > order ;
2022-07-21 11:42:42 +00:00
pIter - > pFileList = aDFileSet ;
2022-06-30 15:38:18 +00:00
pIter - > numOfFiles = numOfFileset ;
2022-06-27 02:46:20 +00:00
2022-08-17 16:08:09 +00:00
if ( pIter - > pLastBlockReader = = NULL ) {
pIter - > pLastBlockReader = taosMemoryCalloc ( 1 , sizeof ( struct SLastBlockReader ) ) ;
if ( pIter - > pLastBlockReader = = NULL ) {
int32_t code = TSDB_CODE_OUT_OF_MEMORY ;
2022-08-18 14:42:16 +00:00
tsdbError ( " failed to prepare the last block iterator, code:%d %s " , tstrerror ( code ) , pReader - > idStr ) ;
2022-08-17 16:08:09 +00:00
return code ;
}
2022-08-18 14:42:16 +00:00
SLastBlockReader * pLReader = pIter - > pLastBlockReader ;
pLReader - > pBlockL = taosArrayInit ( 4 , sizeof ( SBlockL ) ) ;
pLReader - > order = pReader - > order ;
pLReader - > window = pReader - > window ;
pLReader - > verRange = pReader - > verRange ;
2022-08-21 14:02:01 +00:00
pLReader - > currentBlockIndex = - 1 ;
2022-08-20 11:05:55 +00:00
int32_t code = tBlockDataCreate ( & pLReader - > lastBlockData ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
return code ;
}
2022-08-16 23:51:09 +00:00
}
2022-08-18 14:42:16 +00:00
tsdbDebug ( " init fileset iterator, total files:%d %s " , pIter - > numOfFiles , pReader - > idStr ) ;
2022-06-27 02:46:20 +00:00
return TSDB_CODE_SUCCESS ;
}
2022-06-30 15:38:18 +00:00
static bool filesetIteratorNext ( SFilesetIter * pIter , STsdbReader * pReader ) {
2022-07-01 07:19:02 +00:00
bool asc = ASCENDING_TRAVERSE ( pIter - > order ) ;
int32_t step = asc ? 1 : - 1 ;
2022-06-30 15:38:18 +00:00
pIter - > index + = step ;
if ( ( asc & & pIter - > index > = pIter - > numOfFiles ) | | ( ( ! asc ) & & pIter - > index < 0 ) ) {
2022-06-27 02:46:20 +00:00
return false ;
}
// check file the time range of coverage
STimeWindow win = { 0 } ;
2022-06-16 12:53:25 +00:00
2022-07-04 03:42:50 +00:00
while ( 1 ) {
2022-07-13 15:15:58 +00:00
if ( pReader - > pFileReader ! = NULL ) {
tsdbDataFReaderClose ( & pReader - > pFileReader ) ;
}
2022-07-12 09:44:10 +00:00
2022-07-01 07:19:02 +00:00
pReader - > status . pCurrentFileset = ( SDFileSet * ) taosArrayGet ( pIter - > pFileList , pIter - > index ) ;
2022-06-27 02:46:20 +00:00
2022-07-01 07:19:02 +00:00
int32_t code = tsdbDataFReaderOpen ( & pReader - > pFileReader , pReader - > pTsdb , pReader - > status . pCurrentFileset ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
goto _err ;
}
2022-06-27 02:46:20 +00:00
2022-07-26 02:19:12 +00:00
pReader - > cost . headFileLoad + = 1 ;
2022-07-01 07:19:02 +00:00
int32_t fid = pReader - > status . pCurrentFileset - > fid ;
tsdbFidKeyRange ( fid , pReader - > pTsdb - > keepCfg . days , pReader - > pTsdb - > keepCfg . precision , & win . skey , & win . ekey ) ;
// current file are no longer overlapped with query time window, ignore remain files
if ( ( asc & & win . skey > pReader - > window . ekey ) | | ( ! asc & & win . ekey < pReader - > window . skey ) ) {
tsdbDebug ( " %p remain files are not qualified for qrange:% " PRId64 " -% " PRId64 " , ignore, %s " , pReader ,
pReader - > window . skey , pReader - > window . ekey , pReader - > idStr ) ;
return false ;
}
if ( ( asc & & ( win . ekey < pReader - > window . skey ) ) | | ( ( ! asc ) & & ( win . skey > pReader - > window . ekey ) ) ) {
pIter - > index + = step ;
2022-07-11 03:13:49 +00:00
if ( ( asc & & pIter - > index > = pIter - > numOfFiles ) | | ( ( ! asc ) & & pIter - > index < 0 ) ) {
return false ;
}
2022-07-01 07:19:02 +00:00
continue ;
}
2022-05-09 16:03:44 +00:00
2022-07-25 03:17:45 +00:00
tsdbDebug ( " %p file found fid:%d for qrange:% " PRId64 " -% " PRId64 " , %s " , pReader , fid , pReader - > window . skey ,
2022-07-04 03:42:50 +00:00
pReader - > window . ekey , pReader - > idStr ) ;
2022-07-01 07:19:02 +00:00
return true ;
}
2022-06-29 01:40:31 +00:00
2022-07-01 07:19:02 +00:00
_err :
2022-06-27 02:46:20 +00:00
return false ;
}
2022-08-26 07:27:19 +00:00
static void resetDataBlockIterator ( SDataBlockIter * pIter , int32_t order ) {
2022-07-04 03:42:50 +00:00
pIter - > order = order ;
pIter - > index = - 1 ;
2022-08-20 08:57:44 +00:00
pIter - > numOfBlocks = 0 ;
2022-07-10 09:34:21 +00:00
if ( pIter - > blockList = = NULL ) {
pIter - > blockList = taosArrayInit ( 4 , sizeof ( SFileDataBlockInfo ) ) ;
} else {
taosArrayClear ( pIter - > blockList ) ;
}
}
2022-07-12 09:28:14 +00:00
static void cleanupDataBlockIterator ( SDataBlockIter * pIter ) { taosArrayDestroy ( pIter - > blockList ) ; }
2022-06-29 12:25:03 +00:00
2022-06-27 02:46:20 +00:00
static void initReaderStatus ( SReaderStatus * pStatus ) {
2022-07-06 10:29:11 +00:00
pStatus - > pTableIter = NULL ;
pStatus - > loadFromFile = true ;
2022-06-27 02:46:20 +00:00
}
2022-07-01 07:19:02 +00:00
static SSDataBlock * createResBlock ( SQueryTableDataCond * pCond , int32_t capacity ) {
SSDataBlock * pResBlock = createDataBlock ( ) ;
if ( pResBlock = = NULL ) {
terrno = TSDB_CODE_OUT_OF_MEMORY ;
return NULL ;
}
for ( int32_t i = 0 ; i < pCond - > numOfCols ; + + i ) {
SColumnInfoData colInfo = { { 0 } , 0 } ;
colInfo . info = pCond - > colList [ i ] ;
blockDataAppendColInfo ( pResBlock , & colInfo ) ;
}
int32_t code = blockDataEnsureCapacity ( pResBlock , capacity ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
terrno = code ;
taosMemoryFree ( pResBlock ) ;
return NULL ;
}
return pResBlock ;
}
2022-07-29 10:15:44 +00:00
static int32_t tsdbReaderCreate ( SVnode * pVnode , SQueryTableDataCond * pCond , STsdbReader * * ppReader , int32_t capacity ,
const char * idstr ) {
2022-06-27 02:46:20 +00:00
int32_t code = 0 ;
2022-07-05 11:30:37 +00:00
int8_t level = 0 ;
2022-06-27 02:46:20 +00:00
STsdbReader * pReader = ( STsdbReader * ) taosMemoryCalloc ( 1 , sizeof ( * pReader ) ) ;
2022-06-16 12:53:25 +00:00
if ( pReader = = NULL ) {
code = TSDB_CODE_OUT_OF_MEMORY ;
2022-06-27 02:46:20 +00:00
goto _end ;
2022-06-16 12:53:25 +00:00
}
2022-08-03 06:58:54 +00:00
if ( VND_IS_TSMA ( pVnode ) ) {
tsdbDebug ( " vgId:%d, tsma is selected to query " , TD_VID ( pVnode ) ) ;
}
2022-06-27 02:46:20 +00:00
initReaderStatus ( & pReader - > status ) ;
2022-06-28 02:32:42 +00:00
2022-07-12 09:28:14 +00:00
pReader - > pTsdb = getTsdbByRetentions ( pVnode , pCond - > twindows . skey , pVnode - > config . tsdbCfg . retentions , idstr , & level ) ;
2022-07-06 10:29:11 +00:00
pReader - > suid = pCond - > suid ;
pReader - > order = pCond - > order ;
2022-08-20 15:26:58 +00:00
pReader - > capacity = 4096 ;
2022-07-06 10:29:11 +00:00
pReader - > idStr = ( idstr ! = NULL ) ? strdup ( idstr ) : NULL ;
pReader - > verRange = getQueryVerRange ( pVnode , pCond , level ) ;
2022-07-05 11:30:37 +00:00
pReader - > type = pCond - > type ;
2022-07-12 06:14:42 +00:00
pReader - > window = updateQueryTimeWindow ( pReader - > pTsdb , & pCond - > twindows ) ;
2022-06-30 15:38:18 +00:00
2022-07-04 03:42:50 +00:00
ASSERT ( pCond - > numOfCols > 0 ) ;
2022-06-17 12:22:45 +00:00
2022-07-01 07:19:02 +00:00
limitOutputBufferSize ( pCond , & pReader - > capacity ) ;
2022-06-28 02:32:42 +00:00
2022-07-01 07:19:02 +00:00
// allocate buffer in order to load data blocks from file
SBlockLoadSuppInfo * pSup = & pReader - > suppInfo ;
2022-07-07 07:56:43 +00:00
pSup - > pColAgg = taosArrayInit ( 4 , sizeof ( SColumnDataAgg ) ) ;
2022-07-01 07:19:02 +00:00
pSup - > plist = taosMemoryCalloc ( pCond - > numOfCols , POINTER_BYTES ) ;
2022-07-07 07:56:43 +00:00
if ( pSup - > pColAgg = = NULL | | pSup - > plist = = NULL ) {
2022-07-01 07:19:02 +00:00
code = TSDB_CODE_OUT_OF_MEMORY ;
goto _end ;
}
2022-06-27 02:46:20 +00:00
2022-07-07 07:32:56 +00:00
pSup - > tsColAgg . colId = PRIMARYKEY_TIMESTAMP_COL_ID ;
2022-08-08 03:22:24 +00:00
code = tBlockDataCreate ( & pReader - > status . fileBlockData ) ;
2022-07-26 12:40:39 +00:00
if ( code ! = TSDB_CODE_SUCCESS ) {
terrno = code ;
goto _end ;
}
2022-07-01 07:19:02 +00:00
pReader - > pResBlock = createResBlock ( pCond , pReader - > capacity ) ;
if ( pReader - > pResBlock = = NULL ) {
code = terrno ;
goto _end ;
2022-06-17 12:22:45 +00:00
}
2022-06-16 11:32:05 +00:00
2022-07-01 07:19:02 +00:00
setColumnIdSlotList ( pReader , pReader - > pResBlock ) ;
2022-06-16 12:53:25 +00:00
* ppReader = pReader ;
return code ;
2022-06-16 11:32:05 +00:00
2022-06-27 02:46:20 +00:00
_end :
tsdbReaderClose ( pReader ) ;
2022-06-16 12:53:25 +00:00
* ppReader = NULL ;
return code ;
}
2022-06-16 11:32:05 +00:00
2022-06-27 02:46:20 +00:00
static int32_t doLoadBlockIndex ( STsdbReader * pReader , SDataFReader * pFileReader , SArray * pIndexList ) {
2022-07-26 07:52:47 +00:00
SArray * aBlockIdx = taosArrayInit ( 8 , sizeof ( SBlockIdx ) ) ;
2022-06-16 11:32:05 +00:00
2022-07-25 03:17:45 +00:00
int64_t st = taosGetTimestampUs ( ) ;
2022-08-06 12:04:42 +00:00
int32_t code = tsdbReadBlockIdx ( pFileReader , aBlockIdx ) ;
2022-06-27 02:46:20 +00:00
if ( code ! = TSDB_CODE_SUCCESS ) {
2022-07-03 15:00:12 +00:00
goto _end ;
2022-06-27 02:46:20 +00:00
}
2022-06-16 11:32:05 +00:00
2022-07-25 03:17:45 +00:00
size_t num = taosArrayGetSize ( aBlockIdx ) ;
if ( num = = 0 ) {
2022-08-20 11:05:55 +00:00
taosArrayDestroy ( aBlockIdx ) ;
2022-06-27 02:46:20 +00:00
return TSDB_CODE_SUCCESS ;
}
2022-06-16 08:58:00 +00:00
2022-07-25 03:17:45 +00:00
int64_t et1 = taosGetTimestampUs ( ) ;
SBlockIdx * pBlockIdx = NULL ;
for ( int32_t i = 0 ; i < num ; + + i ) {
2022-07-04 03:42:50 +00:00
pBlockIdx = ( SBlockIdx * ) taosArrayGet ( aBlockIdx , i ) ;
2022-06-27 02:46:20 +00:00
2022-07-03 15:00:12 +00:00
// uid check
2022-06-30 06:02:47 +00:00
if ( pBlockIdx - > suid ! = pReader - > suid ) {
2022-06-27 02:46:20 +00:00
continue ;
}
// this block belongs to a table that is not queried.
2022-06-30 06:02:47 +00:00
void * p = taosHashGet ( pReader - > status . pTableMap , & pBlockIdx - > uid , sizeof ( uint64_t ) ) ;
2022-06-27 02:46:20 +00:00
if ( p = = NULL ) {
continue ;
}
STableBlockScanInfo * pScanInfo = p ;
if ( pScanInfo - > pBlockList = = NULL ) {
2022-07-26 02:19:12 +00:00
pScanInfo - > pBlockList = taosArrayInit ( 4 , sizeof ( int32_t ) ) ;
2022-06-27 02:46:20 +00:00
}
2022-06-30 06:02:47 +00:00
taosArrayPush ( pIndexList , pBlockIdx ) ;
2022-06-27 02:46:20 +00:00
}
2022-06-16 08:58:00 +00:00
2022-07-25 03:17:45 +00:00
int64_t et2 = taosGetTimestampUs ( ) ;
2022-07-26 02:19:12 +00:00
tsdbDebug ( " load block index for %d tables completed, elapsed time:%.2f ms, set blockIdx:%.2f ms, size:%.2f Kb %s " ,
2022-07-29 10:15:44 +00:00
( int32_t ) num , ( et1 - st ) / 1000.0 , ( et2 - et1 ) / 1000.0 , num * sizeof ( SBlockIdx ) / 1024.0 , pReader - > idStr ) ;
2022-07-26 02:19:12 +00:00
pReader - > cost . headFileLoadTime + = ( et1 - st ) / 1000.0 ;
2022-07-03 15:00:12 +00:00
_end :
2022-06-30 06:02:47 +00:00
taosArrayDestroy ( aBlockIdx ) ;
2022-06-27 02:46:20 +00:00
return code ;
}
2022-06-16 08:58:00 +00:00
2022-08-18 10:48:50 +00:00
static void cleanupTableScanInfo ( SHashObj * pTableMap ) {
2022-07-04 06:10:29 +00:00
STableBlockScanInfo * px = NULL ;
2022-07-06 10:29:11 +00:00
while ( 1 ) {
2022-08-18 10:48:50 +00:00
px = taosHashIterate ( pTableMap , px ) ;
2022-07-04 06:10:29 +00:00
if ( px = = NULL ) {
break ;
}
2022-08-18 10:48:50 +00:00
// reset the index in last block when handing a new file
2022-08-26 07:27:19 +00:00
px - > indexInBlockL = INITIAL_ROW_INDEX_VAL ;
2022-07-26 02:19:12 +00:00
tMapDataClear ( & px - > mapData ) ;
2022-07-04 06:10:29 +00:00
taosArrayClear ( px - > pBlockList ) ;
}
2022-08-18 10:48:50 +00:00
}
static int32_t doLoadFileBlock ( STsdbReader * pReader , SArray * pIndexList , SArray * pLastBlockIndex ,
SBlockNumber * pBlockNum , SArray * pQualifiedLastBlock ) {
int32_t numOfQTable = 0 ;
size_t sizeInDisk = 0 ;
size_t numOfTables = taosArrayGetSize ( pIndexList ) ;
int64_t st = taosGetTimestampUs ( ) ;
cleanupTableScanInfo ( pReader - > status . pTableMap ) ;
2022-07-04 06:10:29 +00:00
2022-07-06 10:29:11 +00:00
for ( int32_t i = 0 ; i < numOfTables ; + + i ) {
2022-06-27 02:46:20 +00:00
SBlockIdx * pBlockIdx = taosArrayGet ( pIndexList , i ) ;
2022-06-16 08:58:00 +00:00
2022-07-26 02:19:12 +00:00
STableBlockScanInfo * pScanInfo = taosHashGet ( pReader - > status . pTableMap , & pBlockIdx - > uid , sizeof ( int64_t ) ) ;
2022-06-16 08:58:00 +00:00
2022-07-26 02:19:12 +00:00
tMapDataReset ( & pScanInfo - > mapData ) ;
2022-08-06 12:04:42 +00:00
tsdbReadBlock ( pReader - > pFileReader , pBlockIdx , & pScanInfo - > mapData ) ;
2022-07-25 03:17:45 +00:00
2022-08-18 10:48:50 +00:00
sizeInDisk + = pScanInfo - > mapData . nData ;
2022-07-26 02:19:12 +00:00
for ( int32_t j = 0 ; j < pScanInfo - > mapData . nItem ; + + j ) {
2022-06-27 02:46:20 +00:00
SBlock block = { 0 } ;
2022-07-26 02:19:12 +00:00
tMapDataGetItemByIdx ( & pScanInfo - > mapData , j , & block , tGetBlock ) ;
2022-06-16 08:58:00 +00:00
2022-06-29 01:40:31 +00:00
// 1. time range check
2022-06-30 15:38:18 +00:00
if ( block . minKey . ts > pReader - > window . ekey | | block . maxKey . ts < pReader - > window . skey ) {
2022-06-27 02:46:20 +00:00
continue ;
}
2022-06-16 08:58:00 +00:00
2022-06-29 01:40:31 +00:00
// 2. version range check
2022-08-05 09:47:26 +00:00
if ( block . minVer > pReader - > verRange . maxVer | | block . maxVer < pReader - > verRange . minVer ) {
2022-06-30 06:50:59 +00:00
continue ;
}
2022-06-29 01:40:31 +00:00
2022-07-26 02:19:12 +00:00
void * p = taosArrayPush ( pScanInfo - > pBlockList , & j ) ;
2022-06-27 02:46:20 +00:00
if ( p = = NULL ) {
2022-07-26 02:19:12 +00:00
tMapDataClear ( & pScanInfo - > mapData ) ;
2022-06-27 02:46:20 +00:00
return TSDB_CODE_OUT_OF_MEMORY ;
}
2022-06-29 01:40:31 +00:00
2022-08-16 23:51:09 +00:00
pBlockNum - > numOfBlocks + = 1 ;
2022-06-27 02:46:20 +00:00
}
2022-06-16 08:58:00 +00:00
2022-06-27 02:46:20 +00:00
if ( pScanInfo - > pBlockList ! = NULL & & taosArrayGetSize ( pScanInfo - > pBlockList ) > 0 ) {
2022-08-16 23:51:09 +00:00
numOfQTable + = 1 ;
}
}
size_t numOfLast = taosArrayGetSize ( pLastBlockIndex ) ;
for ( int32_t i = 0 ; i < numOfLast ; + + i ) {
SBlockL * pLastBlock = taosArrayGet ( pLastBlockIndex , i ) ;
if ( pLastBlock - > suid ! = pReader - > suid ) {
continue ;
}
{
2022-08-20 03:14:00 +00:00
// 1. time range check
if ( pLastBlock - > minKey > pReader - > window . ekey | | pLastBlock - > maxKey < pReader - > window . skey ) {
continue ;
}
2022-08-16 23:51:09 +00:00
// 2. version range check
if ( pLastBlock - > minVer > pReader - > verRange . maxVer | | pLastBlock - > maxVer < pReader - > verRange . minVer ) {
continue ;
}
pBlockNum - > numOfLastBlocks + = 1 ;
2022-08-17 16:08:09 +00:00
taosArrayPush ( pQualifiedLastBlock , pLastBlock ) ;
2022-06-27 02:46:20 +00:00
}
}
2022-06-16 08:58:00 +00:00
2022-08-16 23:51:09 +00:00
int32_t total = pBlockNum - > numOfLastBlocks + pBlockNum - > numOfBlocks ;
2022-07-29 10:15:44 +00:00
double el = ( taosGetTimestampUs ( ) - st ) / 1000.0 ;
2022-08-25 08:22:22 +00:00
tsdbDebug (
" load block of %d tables completed, blocks:%d in %d tables, lastBlock:%d, block-info-size:%.2f Kb, elapsed "
" time:%.2f ms %s " ,
numOfTables , pBlockNum - > numOfBlocks , numOfQTable , pBlockNum - > numOfLastBlocks , sizeInDisk / 1000.0 , el ,
pReader - > idStr ) ;
2022-07-26 02:19:12 +00:00
2022-08-16 23:51:09 +00:00
pReader - > cost . numOfBlocks + = total ;
2022-07-26 02:19:12 +00:00
pReader - > cost . headFileLoadTime + = el ;
2022-07-25 03:17:45 +00:00
2022-06-27 02:46:20 +00:00
return TSDB_CODE_SUCCESS ;
}
2022-06-16 08:58:00 +00:00
2022-08-20 03:14:00 +00:00
static void setBlockAllDumped ( SFileBlockDumpInfo * pDumpInfo , int64_t maxKey , int32_t order ) {
2022-07-04 03:42:50 +00:00
int32_t step = ASCENDING_TRAVERSE ( order ) ? 1 : - 1 ;
2022-06-30 15:38:18 +00:00
pDumpInfo - > allDumped = true ;
2022-08-20 03:14:00 +00:00
pDumpInfo - > lastKey = maxKey + step ;
2022-06-29 12:25:03 +00:00
}
2022-07-04 03:42:50 +00:00
static void doCopyColVal ( SColumnInfoData * pColInfoData , int32_t rowIndex , int32_t colIndex , SColVal * pColVal ,
SBlockLoadSuppInfo * pSup ) {
2022-06-29 12:25:03 +00:00
if ( IS_VAR_DATA_TYPE ( pColVal - > type ) ) {
2022-07-02 12:39:23 +00:00
if ( pColVal - > isNull | | pColVal - > isNone ) {
2022-06-29 12:25:03 +00:00
colDataAppendNULL ( pColInfoData , rowIndex ) ;
} else {
varDataSetLen ( pSup - > buildBuf [ colIndex ] , pColVal - > value . nData ) ;
2022-08-09 08:54:05 +00:00
ASSERT ( pColVal - > value . nData < = pColInfoData - > info . bytes ) ;
2022-06-29 12:25:03 +00:00
memcpy ( varDataVal ( pSup - > buildBuf [ colIndex ] ) , pColVal - > value . pData , pColVal - > value . nData ) ;
colDataAppend ( pColInfoData , rowIndex , pSup - > buildBuf [ colIndex ] , false ) ;
}
} else {
2022-07-04 06:46:00 +00:00
colDataAppend ( pColInfoData , rowIndex , ( const char * ) & pColVal - > value , pColVal - > isNull | | pColVal - > isNone ) ;
2022-06-29 12:25:03 +00:00
}
2022-06-29 02:35:07 +00:00
}
2022-07-26 02:19:12 +00:00
static SFileDataBlockInfo * getCurrentBlockInfo ( SDataBlockIter * pBlockIter ) {
2022-08-17 16:08:09 +00:00
if ( taosArrayGetSize ( pBlockIter - > blockList ) = = 0 ) {
ASSERT ( pBlockIter - > numOfBlocks = = taosArrayGetSize ( pBlockIter - > blockList ) ) ;
2022-08-16 23:51:09 +00:00
return NULL ;
}
2022-08-17 16:08:09 +00:00
SFileDataBlockInfo * pBlockInfo = taosArrayGet ( pBlockIter - > blockList , pBlockIter - > index ) ;
return pBlockInfo ;
2022-07-26 02:19:12 +00:00
}
2022-07-29 10:15:44 +00:00
static SBlock * getCurrentBlock ( SDataBlockIter * pBlockIter ) { return & pBlockIter - > block ; }
2022-07-26 02:19:12 +00:00
2022-07-01 07:19:02 +00:00
static int32_t copyBlockDataToSDataBlock ( STsdbReader * pReader , STableBlockScanInfo * pBlockScanInfo ) {
2022-07-04 03:42:50 +00:00
SReaderStatus * pStatus = & pReader - > status ;
2022-07-01 07:19:02 +00:00
SDataBlockIter * pBlockIter = & pStatus - > blockIter ;
2022-06-16 08:58:00 +00:00
2022-07-04 03:42:50 +00:00
SBlockData * pBlockData = & pStatus - > fileBlockData ;
2022-06-27 02:46:20 +00:00
SFileDataBlockInfo * pFBlock = getCurrentBlockInfo ( pBlockIter ) ;
2022-07-29 10:15:44 +00:00
SBlock * pBlock = getCurrentBlock ( pBlockIter ) ;
2022-06-29 12:25:03 +00:00
SSDataBlock * pResBlock = pReader - > pResBlock ;
2022-07-29 09:53:30 +00:00
int32_t numOfOutputCols = blockDataGetNumOfCols ( pResBlock ) ;
2022-06-29 02:35:07 +00:00
2022-06-29 12:25:03 +00:00
SBlockLoadSuppInfo * pSupInfo = & pReader - > suppInfo ;
2022-06-30 15:38:18 +00:00
SFileBlockDumpInfo * pDumpInfo = & pReader - > status . fBlockDumpInfo ;
2022-06-27 02:46:20 +00:00
2022-06-29 12:25:03 +00:00
SColVal cv = { 0 } ;
2022-07-29 09:53:30 +00:00
int64_t st = taosGetTimestampUs ( ) ;
2022-06-30 15:38:18 +00:00
bool asc = ASCENDING_TRAVERSE ( pReader - > order ) ;
int32_t step = asc ? 1 : - 1 ;
2022-06-30 07:17:04 +00:00
2022-07-01 07:19:02 +00:00
int32_t rowIndex = 0 ;
2022-06-30 15:38:18 +00:00
int32_t remain = asc ? ( pBlockData - > nRow - pDumpInfo - > rowIndex ) : ( pDumpInfo - > rowIndex + 1 ) ;
2022-07-01 07:19:02 +00:00
int32_t endIndex = 0 ;
if ( remain < = pReader - > capacity ) {
endIndex = pBlockData - > nRow ;
} else {
endIndex = pDumpInfo - > rowIndex + step * pReader - > capacity ;
remain = pReader - > capacity ;
}
2022-07-04 03:42:50 +00:00
int32_t i = 0 ;
2022-06-30 15:38:18 +00:00
SColumnInfoData * pColData = taosArrayGet ( pResBlock - > pDataBlock , i ) ;
if ( pColData - > info . colId = = PRIMARYKEY_TIMESTAMP_COL_ID ) {
2022-07-01 07:19:02 +00:00
for ( int32_t j = pDumpInfo - > rowIndex ; j < endIndex & & j > = 0 ; j + = step ) {
2022-06-30 15:38:18 +00:00
colDataAppend ( pColData , rowIndex + + , ( const char * ) & pBlockData - > aTSKEY [ j ] , false ) ;
}
i + = 1 ;
}
2022-07-29 09:53:30 +00:00
int32_t colIndex = 0 ;
int32_t num = taosArrayGetSize ( pBlockData - > aIdx ) ;
while ( i < numOfOutputCols & & colIndex < num ) {
2022-06-30 15:38:18 +00:00
rowIndex = 0 ;
pColData = taosArrayGet ( pResBlock - > pDataBlock , i ) ;
2022-07-05 09:31:51 +00:00
SColData * pData = tBlockDataGetColDataByIdx ( pBlockData , colIndex ) ;
2022-08-21 07:56:06 +00:00
if ( pData - > cid < pColData - > info . colId ) {
colIndex + = 1 ;
} else if ( pData - > cid = = pColData - > info . colId ) {
2022-07-01 07:19:02 +00:00
for ( int32_t j = pDumpInfo - > rowIndex ; j < endIndex & & j > = 0 ; j + = step ) {
2022-06-30 15:38:18 +00:00
tColDataGetValue ( pData , j , & cv ) ;
doCopyColVal ( pColData , rowIndex + + , i , & cv , pSupInfo ) ;
2022-06-29 12:25:03 +00:00
}
2022-06-30 15:38:18 +00:00
colIndex + = 1 ;
2022-08-21 07:56:06 +00:00
i + = 1 ;
2022-07-21 12:44:36 +00:00
ASSERT ( rowIndex = = remain ) ;
2022-06-30 15:38:18 +00:00
} else { // the specified column does not exist in file block, fill with null data
colDataAppendNNULL ( pColData , 0 , remain ) ;
2022-08-21 07:56:06 +00:00
i + = 1 ;
2022-06-29 12:25:03 +00:00
}
2022-06-30 15:38:18 +00:00
}
2022-07-29 09:53:30 +00:00
while ( i < numOfOutputCols ) {
2022-06-30 15:38:18 +00:00
pColData = taosArrayGet ( pResBlock - > pDataBlock , i ) ;
colDataAppendNNULL ( pColData , 0 , remain ) ;
i + = 1 ;
2022-06-29 12:25:03 +00:00
}
2022-06-27 02:46:20 +00:00
2022-07-01 07:19:02 +00:00
pResBlock - > info . rows = remain ;
2022-07-04 03:42:50 +00:00
pDumpInfo - > rowIndex + = step * remain ;
2022-07-01 07:19:02 +00:00
2022-08-20 03:14:00 +00:00
setBlockAllDumped ( pDumpInfo , pBlock - > maxKey . ts , pReader - > order ) ;
2022-06-27 02:46:20 +00:00
2022-07-26 02:19:12 +00:00
double elapsedTime = ( taosGetTimestampUs ( ) - st ) / 1000.0 ;
2022-06-29 12:25:03 +00:00
pReader - > cost . blockLoadTime + = elapsedTime ;
2022-06-27 02:46:20 +00:00
2022-07-04 03:42:50 +00:00
int32_t unDumpedRows = asc ? pBlock - > nRow - pDumpInfo - > rowIndex : pDumpInfo - > rowIndex + 1 ;
2022-08-01 03:19:06 +00:00
tsdbDebug ( " %p copy file block to sdatablock, global index:%d, table index:%d, brange:% " PRId64 " -% " PRId64
2022-07-26 02:19:12 +00:00
" , rows:%d, remain:%d, minVer:% " PRId64 " , maxVer:% " PRId64 " , elapsed time:%.2f ms, %s " ,
2022-07-01 07:19:02 +00:00
pReader , pBlockIter - > index , pFBlock - > tbBlockIdx , pBlock - > minKey . ts , pBlock - > maxKey . ts , remain , unDumpedRows ,
2022-08-05 09:47:26 +00:00
pBlock - > minVer , pBlock - > maxVer , elapsedTime , pReader - > idStr ) ;
2022-07-01 07:19:02 +00:00
return TSDB_CODE_SUCCESS ;
}
2022-08-16 23:51:09 +00:00
static int32_t doLoadFileBlockData ( STsdbReader * pReader , SDataBlockIter * pBlockIter , SBlockData * pBlockData ) {
2022-07-01 07:19:02 +00:00
int64_t st = taosGetTimestampUs ( ) ;
2022-08-17 16:08:09 +00:00
SFileDataBlockInfo * pBlockInfo = getCurrentBlockInfo ( pBlockIter ) ;
2022-08-16 23:51:09 +00:00
SFileBlockDumpInfo * pDumpInfo = & pReader - > status . fBlockDumpInfo ;
2022-08-24 09:09:33 +00:00
ASSERT ( pBlockInfo ! = NULL ) ;
2022-07-26 02:19:12 +00:00
2022-08-24 09:09:33 +00:00
SBlock * pBlock = getCurrentBlock ( pBlockIter ) ;
int32_t code = tsdbReadDataBlock ( pReader - > pFileReader , pBlock , pBlockData ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
tsdbError ( " %p error occurs in loading file block, global index:%d, table index:%d, brange:% " PRId64 " -% " PRId64
" , rows:%d, code:%s %s " ,
2022-08-17 16:08:09 +00:00
pReader , pBlockIter - > index , pBlockInfo - > tbBlockIdx , pBlock - > minKey . ts , pBlock - > maxKey . ts , pBlock - > nRow ,
2022-08-24 09:09:33 +00:00
tstrerror ( code ) , pReader - > idStr ) ;
return code ;
}
2022-08-17 16:08:09 +00:00
2022-08-24 09:09:33 +00:00
double elapsedTime = ( taosGetTimestampUs ( ) - st ) / 1000.0 ;
2022-08-17 16:08:09 +00:00
2022-08-24 09:09:33 +00:00
tsdbDebug ( " %p load file block into buffer, global index:%d, index in table block list:%d, brange:% " PRId64 " -% " PRId64
" , rows:%d, minVer:% " PRId64 " , maxVer:% " PRId64 " , elapsed time:%.2f ms, %s " ,
pReader , pBlockIter - > index , pBlockInfo - > tbBlockIdx , pBlock - > minKey . ts , pBlock - > maxKey . ts , pBlock - > nRow ,
pBlock - > minVer , pBlock - > maxVer , elapsedTime , pReader - > idStr ) ;
2022-07-01 07:19:02 +00:00
pReader - > cost . blockLoadTime + = elapsedTime ;
pDumpInfo - > allDumped = false ;
2022-07-26 02:19:12 +00:00
2022-06-29 12:25:03 +00:00
return TSDB_CODE_SUCCESS ;
2022-06-27 02:46:20 +00:00
}
2022-06-16 08:58:00 +00:00
2022-06-27 02:46:20 +00:00
static void cleanupBlockOrderSupporter ( SBlockOrderSupporter * pSup ) {
taosMemoryFreeClear ( pSup - > numOfBlocksPerTable ) ;
taosMemoryFreeClear ( pSup - > indexPerTable ) ;
2022-06-16 08:58:00 +00:00
2022-06-27 02:46:20 +00:00
for ( int32_t i = 0 ; i < pSup - > numOfTables ; + + i ) {
SBlockOrderWrapper * pBlockInfo = pSup - > pDataBlockInfo [ i ] ;
taosMemoryFreeClear ( pBlockInfo ) ;
}
2022-06-16 08:58:00 +00:00
2022-06-27 02:46:20 +00:00
taosMemoryFreeClear ( pSup - > pDataBlockInfo ) ;
}
2022-06-16 08:58:00 +00:00
2022-06-27 02:46:20 +00:00
static int32_t initBlockOrderSupporter ( SBlockOrderSupporter * pSup , int32_t numOfTables ) {
ASSERT ( numOfTables > = 1 ) ;
2022-06-16 08:58:00 +00:00
2022-06-27 02:46:20 +00:00
pSup - > numOfBlocksPerTable = taosMemoryCalloc ( 1 , sizeof ( int32_t ) * numOfTables ) ;
2022-07-04 03:42:50 +00:00
pSup - > indexPerTable = taosMemoryCalloc ( 1 , sizeof ( int32_t ) * numOfTables ) ;
pSup - > pDataBlockInfo = taosMemoryCalloc ( 1 , POINTER_BYTES * numOfTables ) ;
2022-06-16 08:58:00 +00:00
2022-06-27 02:46:20 +00:00
if ( pSup - > numOfBlocksPerTable = = NULL | | pSup - > indexPerTable = = NULL | | pSup - > pDataBlockInfo = = NULL ) {
cleanupBlockOrderSupporter ( pSup ) ;
return TSDB_CODE_OUT_OF_MEMORY ;
}
2022-06-16 08:58:00 +00:00
2022-06-27 02:46:20 +00:00
return TSDB_CODE_SUCCESS ;
}
2022-06-16 08:58:00 +00:00
2022-06-27 02:46:20 +00:00
static int32_t fileDataBlockOrderCompar ( const void * pLeft , const void * pRight , void * param ) {
2022-07-04 03:42:50 +00:00
int32_t leftIndex = * ( int32_t * ) pLeft ;
2022-06-27 02:46:20 +00:00
int32_t rightIndex = * ( int32_t * ) pRight ;
2022-06-16 08:58:00 +00:00
2022-06-27 02:46:20 +00:00
SBlockOrderSupporter * pSupporter = ( SBlockOrderSupporter * ) param ;
2022-06-16 08:58:00 +00:00
2022-06-27 02:46:20 +00:00
int32_t leftTableBlockIndex = pSupporter - > indexPerTable [ leftIndex ] ;
int32_t rightTableBlockIndex = pSupporter - > indexPerTable [ rightIndex ] ;
2022-06-16 08:58:00 +00:00
2022-06-27 02:46:20 +00:00
if ( leftTableBlockIndex > pSupporter - > numOfBlocksPerTable [ leftIndex ] ) {
/* left block is empty */
return 1 ;
} else if ( rightTableBlockIndex > pSupporter - > numOfBlocksPerTable [ rightIndex ] ) {
/* right block is empty */
return - 1 ;
}
2022-06-16 08:58:00 +00:00
2022-07-04 03:42:50 +00:00
SBlockOrderWrapper * pLeftBlock = & pSupporter - > pDataBlockInfo [ leftIndex ] [ leftTableBlockIndex ] ;
2022-06-27 02:46:20 +00:00
SBlockOrderWrapper * pRightBlock = & pSupporter - > pDataBlockInfo [ rightIndex ] [ rightTableBlockIndex ] ;
2022-06-16 08:58:00 +00:00
2022-07-26 02:19:12 +00:00
return pLeftBlock - > offset > pRightBlock - > offset ? 1 : - 1 ;
}
static int32_t doSetCurrentBlock ( SDataBlockIter * pBlockIter ) {
2022-08-24 09:09:33 +00:00
SFileDataBlockInfo * pBlockInfo = getCurrentBlockInfo ( pBlockIter ) ;
if ( pBlockInfo ! = NULL ) {
STableBlockScanInfo * pScanInfo = taosHashGet ( pBlockIter - > pTableMap , & pBlockInfo - > uid , sizeof ( pBlockInfo - > uid ) ) ;
int32_t * mapDataIndex = taosArrayGet ( pScanInfo - > pBlockList , pBlockInfo - > tbBlockIdx ) ;
2022-08-16 23:51:09 +00:00
tMapDataGetItemByIdx ( & pScanInfo - > mapData , * mapDataIndex , & pBlockIter - > block , tGetBlock ) ;
}
2022-07-26 02:19:12 +00:00
#if 0
qDebug ( " check file block, table uid:% " PRIu64 " index:%d offset:% " PRId64 " , " , pScanInfo - > uid , * mapDataIndex , pBlockIter - > block . aSubBlock [ 0 ] . offset ) ;
# endif
return TSDB_CODE_SUCCESS ;
2022-06-27 02:46:20 +00:00
}
2022-06-16 08:58:00 +00:00
2022-08-17 16:08:09 +00:00
static int32_t initBlockIterator ( STsdbReader * pReader , SDataBlockIter * pBlockIter , int32_t numOfBlocks ) {
2022-06-30 15:38:18 +00:00
bool asc = ASCENDING_TRAVERSE ( pReader - > order ) ;
2022-06-27 02:46:20 +00:00
2022-08-17 16:08:09 +00:00
pBlockIter - > numOfBlocks = numOfBlocks ;
2022-07-04 06:10:29 +00:00
taosArrayClear ( pBlockIter - > blockList ) ;
2022-08-26 11:19:48 +00:00
pBlockIter - > pTableMap = pReader - > status . pTableMap ;
2022-07-04 06:10:29 +00:00
2022-07-03 15:00:12 +00:00
// access data blocks according to the offset of each block in asc/desc order.
int32_t numOfTables = ( int32_t ) taosHashGetSize ( pReader - > status . pTableMap ) ;
2022-06-27 02:46:20 +00:00
2022-07-25 03:17:45 +00:00
int64_t st = taosGetTimestampUs ( ) ;
2022-06-27 02:46:20 +00:00
2022-07-25 03:17:45 +00:00
SBlockOrderSupporter sup = { 0 } ;
2022-07-29 10:15:44 +00:00
int32_t code = initBlockOrderSupporter ( & sup , numOfTables ) ;
2022-07-03 15:00:12 +00:00
if ( code ! = TSDB_CODE_SUCCESS ) {
return code ;
}
2022-06-27 02:46:20 +00:00
2022-07-03 15:00:12 +00:00
int32_t cnt = 0 ;
void * ptr = NULL ;
while ( 1 ) {
ptr = taosHashIterate ( pReader - > status . pTableMap , ptr ) ;
if ( ptr = = NULL ) {
break ;
}
2022-06-27 02:46:20 +00:00
2022-07-03 15:00:12 +00:00
STableBlockScanInfo * pTableScanInfo = ( STableBlockScanInfo * ) ptr ;
if ( pTableScanInfo - > pBlockList = = NULL | | taosArrayGetSize ( pTableScanInfo - > pBlockList ) = = 0 ) {
continue ;
}
2022-06-27 02:46:20 +00:00
2022-07-03 15:00:12 +00:00
size_t num = taosArrayGetSize ( pTableScanInfo - > pBlockList ) ;
sup . numOfBlocksPerTable [ sup . numOfTables ] = num ;
2022-06-27 02:46:20 +00:00
2022-07-03 15:00:12 +00:00
char * buf = taosMemoryMalloc ( sizeof ( SBlockOrderWrapper ) * num ) ;
if ( buf = = NULL ) {
cleanupBlockOrderSupporter ( & sup ) ;
return TSDB_CODE_TDB_OUT_OF_MEMORY ;
}
2022-06-27 02:46:20 +00:00
2022-07-03 15:00:12 +00:00
sup . pDataBlockInfo [ sup . numOfTables ] = ( SBlockOrderWrapper * ) buf ;
2022-07-26 03:43:45 +00:00
SBlock block = { 0 } ;
2022-07-03 15:00:12 +00:00
for ( int32_t k = 0 ; k < num ; + + k ) {
SBlockOrderWrapper wrapper = { 0 } ;
2022-07-26 02:19:12 +00:00
int32_t * mapDataIndex = taosArrayGet ( pTableScanInfo - > pBlockList , k ) ;
tMapDataGetItemByIdx ( & pTableScanInfo - > mapData , * mapDataIndex , & block , tGetBlock ) ;
2022-07-03 15:00:12 +00:00
wrapper . uid = pTableScanInfo - > uid ;
2022-07-26 02:19:12 +00:00
wrapper . offset = block . aSubBlock [ 0 ] . offset ;
2022-06-27 02:46:20 +00:00
2022-07-03 15:00:12 +00:00
sup . pDataBlockInfo [ sup . numOfTables ] [ k ] = wrapper ;
cnt + + ;
}
sup . numOfTables + = 1 ;
}
2022-06-27 02:46:20 +00:00
2022-08-17 16:08:09 +00:00
ASSERT ( numOfBlocks = = cnt ) ;
2022-06-27 02:46:20 +00:00
2022-07-04 03:42:50 +00:00
// since there is only one table qualified, blocks are not sorted
2022-08-17 16:08:09 +00:00
if ( sup . numOfTables = = 1 ) {
for ( int32_t i = 0 ; i < numOfBlocks ; + + i ) {
2022-07-04 03:42:50 +00:00
SFileDataBlockInfo blockInfo = { . uid = sup . pDataBlockInfo [ 0 ] [ i ] . uid , . tbBlockIdx = i } ;
taosArrayPush ( pBlockIter - > blockList , & blockInfo ) ;
2020-07-17 06:27:03 +00:00
}
2022-06-29 01:40:31 +00:00
2022-07-25 03:17:45 +00:00
int64_t et = taosGetTimestampUs ( ) ;
2022-07-29 10:15:44 +00:00
tsdbDebug ( " %p create blocks info struct completed for one table, %d blocks not sorted, elapsed time:%.2f ms %s " ,
2022-08-17 16:08:09 +00:00
pReader , numOfBlocks , ( et - st ) / 1000.0 , pReader - > idStr ) ;
2022-07-13 15:15:58 +00:00
2022-08-17 16:08:09 +00:00
pBlockIter - > index = asc ? 0 : ( numOfBlocks - 1 ) ;
2022-07-13 15:15:58 +00:00
cleanupBlockOrderSupporter ( & sup ) ;
2022-07-26 02:19:12 +00:00
doSetCurrentBlock ( pBlockIter ) ;
2022-07-04 03:42:50 +00:00
return TSDB_CODE_SUCCESS ;
2021-03-09 10:00:39 +00:00
}
2022-06-27 02:46:20 +00:00
2022-07-04 03:42:50 +00:00
tsdbDebug ( " %p create data blocks info struct completed, %d blocks in %d tables %s " , pReader , cnt , sup . numOfTables ,
pReader - > idStr ) ;
2022-07-02 04:05:03 +00:00
2022-08-17 16:08:09 +00:00
ASSERT ( cnt < = numOfBlocks & & sup . numOfTables < = numOfTables ) ;
2022-06-27 02:46:20 +00:00
2022-07-04 03:42:50 +00:00
SMultiwayMergeTreeInfo * pTree = NULL ;
uint8_t ret = tMergeTreeCreate ( & pTree , sup . numOfTables , & sup , fileDataBlockOrderCompar ) ;
if ( ret ! = TSDB_CODE_SUCCESS ) {
cleanupBlockOrderSupporter ( & sup ) ;
return TSDB_CODE_TDB_OUT_OF_MEMORY ;
2021-03-09 10:00:39 +00:00
}
2022-06-27 02:46:20 +00:00
2022-07-04 03:42:50 +00:00
int32_t numOfTotal = 0 ;
while ( numOfTotal < cnt ) {
int32_t pos = tMergeTreeGetChosenIndex ( pTree ) ;
int32_t index = sup . indexPerTable [ pos ] + + ;
2022-06-27 02:46:20 +00:00
2022-07-04 03:42:50 +00:00
SFileDataBlockInfo blockInfo = { . uid = sup . pDataBlockInfo [ pos ] [ index ] . uid , . tbBlockIdx = index } ;
taosArrayPush ( pBlockIter - > blockList , & blockInfo ) ;
2022-06-27 02:46:20 +00:00
2022-07-04 03:42:50 +00:00
// set data block index overflow, in order to disable the offset comparator
if ( sup . indexPerTable [ pos ] > = sup . numOfBlocksPerTable [ pos ] ) {
sup . indexPerTable [ pos ] = sup . numOfBlocksPerTable [ pos ] + 1 ;
}
2022-06-27 02:46:20 +00:00
2022-07-04 03:42:50 +00:00
numOfTotal + = 1 ;
tMergeTreeAdjust ( pTree , tMergeTreeGetAdjustIndex ( pTree ) ) ;
2021-03-09 10:00:39 +00:00
}
2022-06-27 02:46:20 +00:00
2022-07-25 03:17:45 +00:00
int64_t et = taosGetTimestampUs ( ) ;
2022-08-17 16:08:09 +00:00
tsdbDebug ( " %p %d data blocks access order completed, elapsed time:%.2f ms %s " , pReader , numOfBlocks , ( et - st ) / 1000.0 ,
2022-07-29 10:15:44 +00:00
pReader - > idStr ) ;
2022-07-04 03:42:50 +00:00
cleanupBlockOrderSupporter ( & sup ) ;
taosMemoryFree ( pTree ) ;
2022-06-27 02:46:20 +00:00
2022-08-17 16:08:09 +00:00
pBlockIter - > index = asc ? 0 : ( numOfBlocks - 1 ) ;
2022-07-26 02:19:12 +00:00
doSetCurrentBlock ( pBlockIter ) ;
2022-07-04 03:42:50 +00:00
return TSDB_CODE_SUCCESS ;
2022-06-27 02:46:20 +00:00
}
2022-06-16 08:58:00 +00:00
2022-06-29 02:35:07 +00:00
static bool blockIteratorNext ( SDataBlockIter * pBlockIter ) {
2022-06-30 15:38:18 +00:00
bool asc = ASCENDING_TRAVERSE ( pBlockIter - > order ) ;
2022-07-04 03:42:50 +00:00
int32_t step = asc ? 1 : - 1 ;
2022-08-17 16:08:09 +00:00
if ( ( pBlockIter - > index > = pBlockIter - > numOfBlocks - 1 & & asc ) | | ( pBlockIter - > index < = 0 & & ( ! asc ) ) ) {
2022-06-28 02:32:42 +00:00
return false ;
}
2022-06-30 15:38:18 +00:00
pBlockIter - > index + = step ;
2022-07-26 02:19:12 +00:00
doSetCurrentBlock ( pBlockIter ) ;
2022-06-28 02:32:42 +00:00
return true ;
}
2022-06-30 15:38:18 +00:00
/**
* This is an two rectangles overlap cases .
*/
2022-07-02 15:37:31 +00:00
static int32_t dataBlockPartiallyRequired ( STimeWindow * pWindow , SVersionRange * pVerRange , SBlock * pBlock ) {
2022-06-30 15:38:18 +00:00
return ( pWindow - > ekey < pBlock - > maxKey . ts & & pWindow - > ekey > = pBlock - > minKey . ts ) | |
( pWindow - > skey > pBlock - > minKey . ts & & pWindow - > skey < = pBlock - > maxKey . ts ) | |
2022-08-05 09:47:26 +00:00
( pVerRange - > minVer > pBlock - > minVer & & pVerRange - > minVer < = pBlock - > maxVer ) | |
( pVerRange - > maxVer < pBlock - > maxVer & & pVerRange - > maxVer > = pBlock - > minVer ) ;
2022-06-27 02:46:20 +00:00
}
2022-06-16 11:32:05 +00:00
2022-07-04 03:42:50 +00:00
static SBlock * getNeighborBlockOfSameTable ( SFileDataBlockInfo * pFBlockInfo , STableBlockScanInfo * pTableBlockScanInfo ,
int32_t * nextIndex , int32_t order ) {
2022-07-02 04:05:03 +00:00
bool asc = ASCENDING_TRAVERSE ( order ) ;
if ( asc & & pFBlockInfo - > tbBlockIdx > = taosArrayGetSize ( pTableBlockScanInfo - > pBlockList ) - 1 ) {
return NULL ;
2022-06-28 02:32:42 +00:00
}
2022-07-04 03:42:50 +00:00
if ( ! asc & & pFBlockInfo - > tbBlockIdx = = 0 ) {
2022-07-02 04:05:03 +00:00
return NULL ;
}
2022-07-04 03:42:50 +00:00
int32_t step = asc ? 1 : - 1 ;
2022-07-02 04:05:03 +00:00
* nextIndex = pFBlockInfo - > tbBlockIdx + step ;
2022-07-26 02:19:12 +00:00
2022-07-29 10:15:44 +00:00
SBlock * pBlock = taosMemoryCalloc ( 1 , sizeof ( SBlock ) ) ;
2022-07-26 02:19:12 +00:00
int32_t * indexInMapdata = taosArrayGet ( pTableBlockScanInfo - > pBlockList , * nextIndex ) ;
tMapDataGetItemByIdx ( & pTableBlockScanInfo - > mapData , * indexInMapdata , pBlock , tGetBlock ) ;
return pBlock ;
2022-07-02 04:05:03 +00:00
}
static int32_t findFileBlockInfoIndex ( SDataBlockIter * pBlockIter , SFileDataBlockInfo * pFBlockInfo ) {
ASSERT ( pBlockIter ! = NULL & & pFBlockInfo ! = NULL ) ;
2022-07-04 03:42:50 +00:00
int32_t step = ASCENDING_TRAVERSE ( pBlockIter - > order ) ? 1 : - 1 ;
2022-07-02 04:05:03 +00:00
int32_t index = pBlockIter - > index ;
2022-08-17 16:08:09 +00:00
while ( index < pBlockIter - > numOfBlocks & & index > = 0 ) {
2022-07-02 04:05:03 +00:00
SFileDataBlockInfo * pFBlock = taosArrayGet ( pBlockIter - > blockList , index ) ;
if ( pFBlock - > uid = = pFBlockInfo - > uid & & pFBlock - > tbBlockIdx = = pFBlockInfo - > tbBlockIdx ) {
return index ;
}
index + = step ;
}
ASSERT ( 0 ) ;
return - 1 ;
}
2022-07-02 06:17:27 +00:00
static int32_t setFileBlockActiveInBlockIter ( SDataBlockIter * pBlockIter , int32_t index , int32_t step ) {
2022-08-17 16:08:09 +00:00
if ( index < 0 | | index > = pBlockIter - > numOfBlocks ) {
2022-07-02 04:05:03 +00:00
return - 1 ;
}
SFileDataBlockInfo fblock = * ( SFileDataBlockInfo * ) taosArrayGet ( pBlockIter - > blockList , index ) ;
2022-07-02 06:17:27 +00:00
pBlockIter - > index + = step ;
if ( index ! = pBlockIter - > index ) {
taosArrayRemove ( pBlockIter - > blockList , index ) ;
taosArrayInsert ( pBlockIter - > blockList , pBlockIter - > index , & fblock ) ;
2022-07-02 04:05:03 +00:00
2022-07-02 06:17:27 +00:00
SFileDataBlockInfo * pBlockInfo = taosArrayGet ( pBlockIter - > blockList , pBlockIter - > index ) ;
ASSERT ( pBlockInfo - > uid = = fblock . uid & & pBlockInfo - > tbBlockIdx = = fblock . tbBlockIdx ) ;
}
2022-07-02 04:05:03 +00:00
2022-07-26 07:52:47 +00:00
doSetCurrentBlock ( pBlockIter ) ;
2022-07-02 04:05:03 +00:00
return TSDB_CODE_SUCCESS ;
}
static bool overlapWithNeighborBlock ( SBlock * pBlock , SBlock * pNeighbor , int32_t order ) {
// it is the last block in current file, no chance to overlap with neighbor blocks.
if ( ASCENDING_TRAVERSE ( order ) ) {
return pBlock - > maxKey . ts = = pNeighbor - > minKey . ts ;
} else {
return pBlock - > minKey . ts = = pNeighbor - > maxKey . ts ;
}
2022-06-27 02:46:20 +00:00
}
2022-06-16 11:32:05 +00:00
2022-06-28 02:32:42 +00:00
static bool bufferDataInFileBlockGap ( int32_t order , TSDBKEY key , SBlock * pBlock ) {
2022-06-27 02:46:20 +00:00
bool ascScan = ASCENDING_TRAVERSE ( order ) ;
2022-06-16 11:32:05 +00:00
2022-06-28 02:32:42 +00:00
return ( ascScan & & ( key . ts ! = TSKEY_INITIAL_VAL & & key . ts < = pBlock - > minKey . ts ) ) | |
2022-07-04 03:42:50 +00:00
( ! ascScan & & ( key . ts ! = TSKEY_INITIAL_VAL & & key . ts > = pBlock - > maxKey . ts ) ) ;
2022-06-27 02:46:20 +00:00
}
2022-06-16 11:32:05 +00:00
2022-06-29 02:35:07 +00:00
static bool keyOverlapFileBlock ( TSDBKEY key , SBlock * pBlock , SVersionRange * pVerRange ) {
2022-08-05 09:47:26 +00:00
return ( key . ts > = pBlock - > minKey . ts & & key . ts < = pBlock - > maxKey . ts ) & & ( pBlock - > maxVer > = pVerRange - > minVer ) & &
( pBlock - > minVer < = pVerRange - > maxVer ) ;
2022-06-29 02:35:07 +00:00
}
2022-07-19 06:00:45 +00:00
static bool doCheckforDatablockOverlap ( STableBlockScanInfo * pBlockScanInfo , const SBlock * pBlock ) {
size_t num = taosArrayGetSize ( pBlockScanInfo - > delSkyline ) ;
for ( int32_t i = pBlockScanInfo - > fileDelIndex ; i < num ; i + = 1 ) {
TSDBKEY * p = taosArrayGet ( pBlockScanInfo - > delSkyline , i ) ;
if ( p - > ts > = pBlock - > minKey . ts & & p - > ts < = pBlock - > maxKey . ts ) {
2022-08-05 09:47:26 +00:00
if ( p - > version > = pBlock - > minVer ) {
2022-07-19 06:00:45 +00:00
return true ;
}
} else if ( p - > ts < pBlock - > minKey . ts ) { // p->ts < pBlock->minKey.ts
2022-08-05 09:47:26 +00:00
if ( p - > version > = pBlock - > minVer ) {
2022-07-19 06:00:45 +00:00
if ( i < num - 1 ) {
TSDBKEY * pnext = taosArrayGet ( pBlockScanInfo - > delSkyline , i + 1 ) ;
if ( i + 1 = = num - 1 ) { // pnext is the last point
if ( pnext - > ts > = pBlock - > minKey . ts ) {
return true ;
}
} else {
2022-08-05 09:47:26 +00:00
if ( pnext - > ts > = pBlock - > minKey . ts & & pnext - > version > = pBlock - > minVer ) {
2022-07-19 06:00:45 +00:00
return true ;
}
}
} else { // it must be the last point
ASSERT ( p - > version = = 0 ) ;
}
}
} else { // (p->ts > pBlock->maxKey.ts) {
return false ;
}
}
return false ;
}
2022-07-08 03:02:12 +00:00
static bool overlapWithDelSkyline ( STableBlockScanInfo * pBlockScanInfo , const SBlock * pBlock , int32_t order ) {
2022-07-07 14:40:20 +00:00
if ( pBlockScanInfo - > delSkyline = = NULL ) {
return false ;
}
2022-07-19 06:00:45 +00:00
// ts is not overlap
2022-07-07 14:40:20 +00:00
TSDBKEY * pFirst = taosArrayGet ( pBlockScanInfo - > delSkyline , 0 ) ;
2022-07-12 09:28:14 +00:00
TSDBKEY * pLast = taosArrayGetLast ( pBlockScanInfo - > delSkyline ) ;
2022-07-07 14:40:20 +00:00
if ( pBlock - > minKey . ts > pLast - > ts | | pBlock - > maxKey . ts < pFirst - > ts ) {
return false ;
}
// version is not overlap
2022-07-19 06:00:45 +00:00
if ( ASCENDING_TRAVERSE ( order ) ) {
return doCheckforDatablockOverlap ( pBlockScanInfo , pBlock ) ;
} else {
int32_t index = pBlockScanInfo - > fileDelIndex ;
2022-07-20 02:29:21 +00:00
while ( 1 ) {
2022-07-19 06:00:45 +00:00
TSDBKEY * p = taosArrayGet ( pBlockScanInfo - > delSkyline , index ) ;
if ( p - > ts > pBlock - > minKey . ts & & index > 0 ) {
index - = 1 ;
} else { // find the first point that is smaller than the minKey.ts of dataBlock.
break ;
2022-07-07 14:40:20 +00:00
}
}
2022-07-19 06:00:45 +00:00
return doCheckforDatablockOverlap ( pBlockScanInfo , pBlock ) ;
}
2022-07-07 14:40:20 +00:00
}
2022-07-02 15:37:31 +00:00
// 1. the version of all rows should be less than the endVersion
// 2. current block should not overlap with next neighbor block
// 3. current timestamp should not be overlap with each other
// 4. output buffer should be large enough to hold all rows in current block
2022-07-07 14:40:20 +00:00
// 5. delete info should not overlap with current block data
2022-07-04 03:42:50 +00:00
static bool fileBlockShouldLoad ( STsdbReader * pReader , SFileDataBlockInfo * pFBlock , SBlock * pBlock ,
2022-08-17 16:08:09 +00:00
STableBlockScanInfo * pScanInfo , TSDBKEY key , SLastBlockReader * pLastBlockReader ) {
2022-07-02 04:05:03 +00:00
int32_t neighborIndex = 0 ;
SBlock * pNeighbor = getNeighborBlockOfSameTable ( pFBlock , pScanInfo , & neighborIndex , pReader - > order ) ;
2022-07-07 14:40:20 +00:00
// overlap with neighbor
2022-07-02 04:05:03 +00:00
bool overlapWithNeighbor = false ;
if ( pNeighbor ) {
overlapWithNeighbor = overlapWithNeighborBlock ( pBlock , pNeighbor , pReader - > order ) ;
2022-07-26 02:19:12 +00:00
taosMemoryFree ( pNeighbor ) ;
2022-07-02 04:05:03 +00:00
}
2022-07-07 14:40:20 +00:00
// has duplicated ts of different version in this block
2022-07-12 09:28:14 +00:00
bool hasDup = ( pBlock - > nSubBlock = = 1 ) ? pBlock - > hasDup : true ;
bool overlapWithDel = overlapWithDelSkyline ( pScanInfo , pBlock , pReader - > order ) ;
2022-07-02 07:22:49 +00:00
2022-08-17 16:08:09 +00:00
// todo here we need to each key in the last files to identify if it is really overlapped with last block
bool overlapWithlastBlock = false ;
2022-08-21 12:15:53 +00:00
if ( taosArrayGetSize ( pLastBlockReader - > pBlockL ) > 0 & & ( pLastBlockReader - > currentBlockIndex ! = - 1 ) ) {
2022-08-17 16:08:09 +00:00
SBlockL * pBlockL = taosArrayGet ( pLastBlockReader - > pBlockL , pLastBlockReader - > currentBlockIndex ) ;
overlapWithlastBlock = ! ( pBlock - > maxKey . ts < pBlockL - > minKey | | pBlock - > minKey . ts > pBlockL - > maxKey ) ;
}
2022-08-22 03:57:10 +00:00
bool moreThanOutputCapacity = pBlock - > nRow > pReader - > capacity ;
bool partiallyRequired = dataBlockPartiallyRequired ( & pReader - > window , & pReader - > verRange , pBlock ) ;
bool overlapWithKey = keyOverlapFileBlock ( key , pBlock , & pReader - > verRange ) ;
bool loadDataBlock = ( overlapWithNeighbor | | hasDup | | partiallyRequired | | overlapWithKey | |
moreThanOutputCapacity | | overlapWithDel | | overlapWithlastBlock ) ;
// log the reason why load the datablock for profile
if ( loadDataBlock ) {
tsdbDebug ( " %p uid:% " PRIu64
2022-08-22 06:28:13 +00:00
" need to load the datablock, overlapwithneighborblock:%d, hasDup:%d, partiallyRequired:%d, "
2022-08-22 03:57:10 +00:00
" overlapWithKey:%d, greaterThanBuf:%d, overlapWithDel:%d, overlapWithlastBlock:%d, %s " ,
pReader , pFBlock - > uid , overlapWithNeighbor , hasDup , partiallyRequired , overlapWithKey ,
moreThanOutputCapacity , overlapWithDel , overlapWithlastBlock , pReader - > idStr ) ;
}
return loadDataBlock ;
2022-06-29 02:35:07 +00:00
}
2022-07-02 15:37:31 +00:00
static int32_t buildDataBlockFromBuf ( STsdbReader * pReader , STableBlockScanInfo * pBlockScanInfo , int64_t endKey ) {
2022-07-04 15:28:27 +00:00
if ( ! ( pBlockScanInfo - > iiter . hasVal | | pBlockScanInfo - > iter . hasVal ) ) {
2022-06-28 02:32:42 +00:00
return TSDB_CODE_SUCCESS ;
}
2022-06-27 02:46:20 +00:00
2022-06-30 06:50:59 +00:00
SSDataBlock * pBlock = pReader - > pResBlock ;
int64_t st = taosGetTimestampUs ( ) ;
2022-07-02 15:37:31 +00:00
int32_t code = buildDataBlockFromBufImpl ( pBlockScanInfo , endKey , pReader - > capacity , pReader ) ;
2022-06-27 02:46:20 +00:00
2022-07-05 06:38:45 +00:00
blockDataUpdateTsWindow ( pBlock , 0 ) ;
2022-06-30 06:50:59 +00:00
pBlock - > info . uid = pBlockScanInfo - > uid ;
2022-07-05 06:38:45 +00:00
2022-06-30 06:50:59 +00:00
setComposedBlockFlag ( pReader , true ) ;
2022-07-05 06:38:45 +00:00
2022-07-26 02:19:12 +00:00
double elapsedTime = ( taosGetTimestampUs ( ) - st ) / 1000.0 ;
2022-08-02 08:48:49 +00:00
tsdbDebug ( " %p build data block from cache completed, elapsed time:%.2f ms, numOfRows:%d, brange:% " PRId64
2022-07-29 10:15:44 +00:00
" - % " PRId64 " %s " ,
pReader , elapsedTime , pBlock - > info . rows , pBlock - > info . window . skey , pBlock - > info . window . ekey ,
pReader - > idStr ) ;
2022-07-26 02:19:12 +00:00
pReader - > cost . buildmemBlock + = elapsedTime ;
2022-06-27 02:46:20 +00:00
return code ;
}
2022-08-11 10:19:44 +00:00
static bool tryCopyDistinctRowFromFileBlock ( STsdbReader * pReader , SBlockData * pBlockData , int64_t key ,
SFileBlockDumpInfo * pDumpInfo ) {
2022-08-03 02:52:06 +00:00
// opt version
// 1. it is not a border point
// 2. the direct next point is not an duplicated timestamp
if ( ( pDumpInfo - > rowIndex < pDumpInfo - > totalRows - 1 & & pReader - > order = = TSDB_ORDER_ASC ) | |
( pDumpInfo - > rowIndex > 0 & & pReader - > order = = TSDB_ORDER_DESC ) ) {
2022-08-11 10:19:44 +00:00
int32_t step = pReader - > order = = TSDB_ORDER_ASC ? 1 : - 1 ;
2022-08-03 02:52:06 +00:00
int64_t nextKey = pBlockData - > aTSKEY [ pDumpInfo - > rowIndex + step ] ;
2022-08-11 10:19:44 +00:00
if ( nextKey ! = key ) { // merge is not needed
2022-08-17 16:08:09 +00:00
doAppendRowFromFileBlock ( pReader - > pResBlock , pReader , pBlockData , pDumpInfo - > rowIndex ) ;
2022-08-03 02:52:06 +00:00
pDumpInfo - > rowIndex + = step ;
return true ;
}
}
return false ;
}
2022-08-09 02:16:00 +00:00
static FORCE_INLINE STSchema * doGetSchemaForTSRow ( int32_t sversion , STsdbReader * pReader , uint64_t uid ) {
// always set the newest schema version in pReader->pSchema
if ( pReader - > pSchema = = NULL ) {
pReader - > pSchema = metaGetTbTSchema ( pReader - > pTsdb - > pVnode - > pMeta , uid , - 1 ) ;
}
2022-08-11 10:19:44 +00:00
if ( pReader - > pSchema & & sversion = = pReader - > pSchema - > version ) {
2022-08-09 02:16:00 +00:00
return pReader - > pSchema ;
}
if ( pReader - > pMemSchema = = NULL ) {
int32_t code =
metaGetTbTSchemaEx ( pReader - > pTsdb - > pVnode - > pMeta , pReader - > suid , uid , sversion , & pReader - > pMemSchema ) ;
return pReader - > pMemSchema ;
}
if ( pReader - > pMemSchema - > version = = sversion ) {
return pReader - > pMemSchema ;
}
taosMemoryFree ( pReader - > pMemSchema ) ;
int32_t code = metaGetTbTSchemaEx ( pReader - > pTsdb - > pVnode - > pMeta , pReader - > suid , uid , sversion , & pReader - > pMemSchema ) ;
return pReader - > pMemSchema ;
}
2022-08-24 09:09:33 +00:00
static int32_t doMergeBufAndFileRows ( STsdbReader * pReader , STableBlockScanInfo * pBlockScanInfo , TSDBROW * pRow ,
2022-08-18 09:09:44 +00:00
SIterInfo * pIter , int64_t key , SLastBlockReader * pLastBlockReader ) {
SRowMerger merge = { 0 } ;
STSRow * pTSRow = NULL ;
SBlockData * pBlockData = & pReader - > status . fileBlockData ;
SFileBlockDumpInfo * pDumpInfo = & pReader - > status . fBlockDumpInfo ;
2022-08-18 14:57:26 +00:00
int64_t tsLast = INT64_MIN ;
2022-08-22 10:17:47 +00:00
if ( ( pLastBlockReader - > lastBlockData . nRow > 0 ) & & hasDataInLastBlock ( pLastBlockReader ) ) {
2022-08-18 14:57:26 +00:00
tsLast = getCurrentKeyInLastBlock ( pLastBlockReader ) ;
}
2022-08-18 09:09:44 +00:00
TSDBKEY k = TSDBROW_KEY ( pRow ) ;
TSDBROW fRow = tsdbRowFromBlockData ( pBlockData , pDumpInfo - > rowIndex ) ;
SBlockData * pLastBlockData = & pLastBlockReader - > lastBlockData ;
2022-08-18 14:57:26 +00:00
int64_t minKey = 0 ;
if ( pReader - > order = = TSDB_ORDER_ASC ) {
minKey = INT64_MAX ; // chosen the minimum value
2022-08-24 02:38:26 +00:00
if ( minKey > tsLast & & hasDataInLastBlock ( pLastBlockReader ) ) {
2022-08-18 14:57:26 +00:00
minKey = tsLast ;
}
2022-08-18 09:09:44 +00:00
2022-08-18 14:57:26 +00:00
if ( minKey > k . ts ) {
minKey = k . ts ;
}
2022-08-18 09:09:44 +00:00
2022-08-18 14:57:26 +00:00
if ( minKey > key & & pBlockData - > nRow > 0 ) {
minKey = key ;
}
} else {
minKey = INT64_MIN ;
2022-08-24 02:38:26 +00:00
if ( minKey < tsLast & & hasDataInLastBlock ( pLastBlockReader ) ) {
2022-08-18 14:57:26 +00:00
minKey = tsLast ;
}
if ( minKey < k . ts ) {
minKey = k . ts ;
}
if ( minKey < key & & pBlockData - > nRow > 0 ) {
minKey = key ;
}
2022-08-18 09:09:44 +00:00
}
bool init = false ;
2022-08-20 03:14:00 +00:00
// ASC: file block ---> last block -----> imem -----> mem
//DESC: mem -----> imem -----> last block -----> file block
2022-08-18 14:42:16 +00:00
if ( pReader - > order = = TSDB_ORDER_ASC ) {
if ( minKey = = key ) {
2022-08-18 09:09:44 +00:00
init = true ;
2022-08-18 14:42:16 +00:00
tRowMergerInit ( & merge , & fRow , pReader - > pSchema ) ;
doMergeRowsInFileBlocks ( pBlockData , pBlockScanInfo , pReader , & merge ) ;
2022-08-18 09:09:44 +00:00
}
2022-08-18 14:42:16 +00:00
if ( minKey = = tsLast ) {
2022-08-20 04:41:58 +00:00
TSDBROW fRow1 = tsdbRowFromBlockData ( pLastBlockData , * pLastBlockReader - > rowIndex ) ;
if ( init ) {
tRowMerge ( & merge , & fRow1 ) ;
} else {
2022-08-18 14:42:16 +00:00
init = true ;
tRowMergerInit ( & merge , & fRow1 , pReader - > pSchema ) ;
}
2022-08-21 10:59:21 +00:00
doMergeRowsInLastBlock ( pLastBlockReader , pBlockScanInfo , tsLast , & merge ) ;
2022-08-18 14:42:16 +00:00
}
2022-08-18 09:09:44 +00:00
2022-08-18 14:42:16 +00:00
if ( minKey = = k . ts ) {
2022-08-20 04:41:58 +00:00
if ( init ) {
tRowMerge ( & merge , pRow ) ;
} else {
2022-08-18 14:42:16 +00:00
init = true ;
STSchema * pSchema = doGetSchemaForTSRow ( TSDBROW_SVERSION ( pRow ) , pReader , pBlockScanInfo - > uid ) ;
tRowMergerInit ( & merge , pRow , pSchema ) ;
}
doMergeRowsInBuf ( pIter , pBlockScanInfo - > uid , k . ts , pBlockScanInfo - > delSkyline , & merge , pReader ) ;
}
} else {
if ( minKey = = k . ts ) {
init = true ;
2022-08-18 09:09:44 +00:00
STSchema * pSchema = doGetSchemaForTSRow ( TSDBROW_SVERSION ( pRow ) , pReader , pBlockScanInfo - > uid ) ;
tRowMergerInit ( & merge , pRow , pSchema ) ;
2022-08-18 14:42:16 +00:00
doMergeRowsInBuf ( pIter , pBlockScanInfo - > uid , k . ts , pBlockScanInfo - > delSkyline , & merge , pReader ) ;
2022-08-18 09:09:44 +00:00
}
2022-08-18 14:42:16 +00:00
if ( minKey = = tsLast ) {
2022-08-20 04:41:58 +00:00
TSDBROW fRow1 = tsdbRowFromBlockData ( pLastBlockData , * pLastBlockReader - > rowIndex ) ;
if ( init ) {
tRowMerge ( & merge , & fRow1 ) ;
} else {
2022-08-18 14:42:16 +00:00
init = true ;
tRowMergerInit ( & merge , & fRow1 , pReader - > pSchema ) ;
}
2022-08-21 10:59:21 +00:00
doMergeRowsInLastBlock ( pLastBlockReader , pBlockScanInfo , tsLast , & merge ) ;
2022-08-18 14:42:16 +00:00
}
if ( minKey = = key ) {
2022-08-20 04:41:58 +00:00
if ( init ) {
tRowMerge ( & merge , & fRow ) ;
} else {
2022-08-18 14:42:16 +00:00
init = true ;
tRowMergerInit ( & merge , & fRow , pReader - > pSchema ) ;
}
doMergeRowsInFileBlocks ( pBlockData , pBlockScanInfo , pReader , & merge ) ;
}
2022-08-18 09:09:44 +00:00
}
tRowMergerGetRow ( & merge , & pTSRow ) ;
doAppendRowFromTSRow ( pReader - > pResBlock , pReader , pTSRow , pBlockScanInfo - > uid ) ;
taosMemoryFree ( pTSRow ) ;
tRowMergerClear ( & merge ) ;
return TSDB_CODE_SUCCESS ;
}
2022-08-24 09:09:33 +00:00
static int32_t doMergeFileBlockAndLastBlock ( SLastBlockReader * pLastBlockReader , STsdbReader * pReader ,
STableBlockScanInfo * pBlockScanInfo , SBlockData * pBlockData ,
bool mergeBlockData ) {
SBlockData * pLastBlockData = & pLastBlockReader - > lastBlockData ;
int64_t tsLastBlock = getCurrentKeyInLastBlock ( pLastBlockReader ) ;
STSRow * pTSRow = NULL ;
SRowMerger merge = { 0 } ;
TSDBROW fRow = tsdbRowFromBlockData ( pLastBlockData , * pLastBlockReader - > rowIndex ) ;
tRowMergerInit ( & merge , & fRow , pReader - > pSchema ) ;
doMergeRowsInLastBlock ( pLastBlockReader , pBlockScanInfo , tsLastBlock , & merge ) ;
// merge with block data if ts == key
if ( mergeBlockData ) {
doMergeRowsInFileBlocks ( pBlockData , pBlockScanInfo , pReader , & merge ) ;
}
tRowMergerGetRow ( & merge , & pTSRow ) ;
doAppendRowFromTSRow ( pReader - > pResBlock , pReader , pTSRow , pBlockScanInfo - > uid ) ;
taosMemoryFree ( pTSRow ) ;
tRowMergerClear ( & merge ) ;
return TSDB_CODE_SUCCESS ;
}
2022-08-23 11:44:59 +00:00
static int32_t mergeFileBlockAndLastBlock ( STsdbReader * pReader , SLastBlockReader * pLastBlockReader , int64_t key ,
STableBlockScanInfo * pBlockScanInfo , SBlockData * pBlockData ) {
2022-07-02 04:05:03 +00:00
SFileBlockDumpInfo * pDumpInfo = & pReader - > status . fBlockDumpInfo ;
2022-08-23 11:44:59 +00:00
if ( pBlockData - > nRow > 0 ) {
// no last block available, only data block exists
if ( pLastBlockReader - > lastBlockData . nRow = = 0 | | ( ! hasDataInLastBlock ( pLastBlockReader ) ) ) {
return mergeRowsInFileBlocks ( pBlockData , pBlockScanInfo , key , pReader ) ;
}
// row in last file block
TSDBROW fRow = tsdbRowFromBlockData ( pBlockData , pDumpInfo - > rowIndex ) ;
int64_t ts = getCurrentKeyInLastBlock ( pLastBlockReader ) ;
ASSERT ( ts > = key ) ;
if ( ASCENDING_TRAVERSE ( pReader - > order ) ) {
if ( key < ts ) { // imem, mem are all empty, file blocks (data blocks and last block) exist
return mergeRowsInFileBlocks ( pBlockData , pBlockScanInfo , key , pReader ) ;
} else if ( key = = ts ) {
STSRow * pTSRow = NULL ;
SRowMerger merge = { 0 } ;
2022-07-02 04:05:03 +00:00
2022-08-03 02:52:06 +00:00
tRowMergerInit ( & merge , & fRow , pReader - > pSchema ) ;
doMergeRowsInFileBlocks ( pBlockData , pBlockScanInfo , pReader , & merge ) ;
2022-08-23 11:44:59 +00:00
doMergeRowsInLastBlock ( pLastBlockReader , pBlockScanInfo , ts , & merge ) ;
2022-07-02 04:05:03 +00:00
2022-08-23 11:44:59 +00:00
tRowMergerGetRow ( & merge , & pTSRow ) ;
doAppendRowFromTSRow ( pReader - > pResBlock , pReader , pTSRow , pBlockScanInfo - > uid ) ;
2022-07-02 12:39:23 +00:00
2022-08-23 11:44:59 +00:00
taosMemoryFree ( pTSRow ) ;
tRowMergerClear ( & merge ) ;
2022-08-03 02:52:06 +00:00
return TSDB_CODE_SUCCESS ;
} else {
2022-08-23 11:44:59 +00:00
ASSERT ( 0 ) ;
return TSDB_CODE_SUCCESS ;
2022-08-03 02:52:06 +00:00
}
2022-08-23 11:44:59 +00:00
} else { // desc order
2022-08-24 09:09:33 +00:00
return doMergeFileBlockAndLastBlock ( pLastBlockReader , pReader , pBlockScanInfo , pBlockData , true ) ;
2022-07-02 12:39:23 +00:00
}
2022-08-23 11:44:59 +00:00
} else { // only last block exists
2022-08-24 09:09:33 +00:00
return doMergeFileBlockAndLastBlock ( pLastBlockReader , pReader , pBlockScanInfo , NULL , false ) ;
2022-08-09 02:34:01 +00:00
}
2022-07-02 04:05:03 +00:00
}
2022-08-24 09:09:33 +00:00
static int32_t doMergeMultiLevelRows ( STsdbReader * pReader , STableBlockScanInfo * pBlockScanInfo , SBlockData * pBlockData ,
SLastBlockReader * pLastBlockReader ) {
2022-08-18 09:09:44 +00:00
SRowMerger merge = { 0 } ;
STSRow * pTSRow = NULL ;
SFileBlockDumpInfo * pDumpInfo = & pReader - > status . fBlockDumpInfo ;
SArray * pDelList = pBlockScanInfo - > delSkyline ;
2022-08-24 09:09:33 +00:00
TSDBROW * pRow = getValidMemRow ( & pBlockScanInfo - > iter , pDelList , pReader ) ;
TSDBROW * piRow = getValidMemRow ( & pBlockScanInfo - > iiter , pDelList , pReader ) ;
2022-08-18 09:09:44 +00:00
ASSERT ( pRow ! = NULL & & piRow ! = NULL ) ;
SBlockData * pLastBlockData = & pLastBlockReader - > lastBlockData ;
2022-08-22 10:17:47 +00:00
int64_t tsLast = INT64_MIN ;
if ( hasDataInLastBlock ( pLastBlockReader ) ) {
tsLast = getCurrentKeyInLastBlock ( pLastBlockReader ) ;
}
2022-08-18 09:09:44 +00:00
int64_t key = pBlockData - > aTSKEY [ pDumpInfo - > rowIndex ] ;
TSDBKEY k = TSDBROW_KEY ( pRow ) ;
TSDBKEY ik = TSDBROW_KEY ( piRow ) ;
2022-08-24 09:09:33 +00:00
int64_t minKey = 0 ;
2022-08-20 03:14:00 +00:00
if ( ASCENDING_TRAVERSE ( pReader - > order ) ) {
minKey = INT64_MAX ; // let's find the minimum
if ( minKey > k . ts ) {
minKey = k . ts ;
}
2022-08-18 09:09:44 +00:00
2022-08-20 03:14:00 +00:00
if ( minKey > ik . ts ) {
minKey = ik . ts ;
}
2022-08-18 09:09:44 +00:00
2022-08-20 03:14:00 +00:00
if ( minKey > key & & pBlockData - > nRow > 0 ) {
minKey = key ;
}
2022-08-18 09:09:44 +00:00
2022-08-22 10:17:47 +00:00
if ( minKey > tsLast & & hasDataInLastBlock ( pLastBlockReader ) ) {
2022-08-20 03:14:00 +00:00
minKey = tsLast ;
}
} else {
minKey = INT64_MIN ; // let find the maximum ts value
if ( minKey < k . ts ) {
minKey = k . ts ;
}
if ( minKey < ik . ts ) {
minKey = ik . ts ;
}
if ( minKey < key & & pBlockData - > nRow > 0 ) {
minKey = key ;
}
2022-08-22 10:17:47 +00:00
if ( minKey < tsLast & & hasDataInLastBlock ( pLastBlockReader ) ) {
2022-08-20 03:14:00 +00:00
minKey = tsLast ;
}
2022-08-18 09:09:44 +00:00
}
bool init = false ;
2022-08-20 03:14:00 +00:00
// ASC: file block -----> last block -----> imem -----> mem
// DESC: mem -----> imem -----> last block -----> file block
if ( ASCENDING_TRAVERSE ( pReader - > order ) ) {
if ( minKey = = key ) {
2022-08-18 09:09:44 +00:00
init = true ;
2022-08-20 03:14:00 +00:00
TSDBROW fRow = tsdbRowFromBlockData ( pBlockData , pDumpInfo - > rowIndex ) ;
tRowMergerInit ( & merge , & fRow , pReader - > pSchema ) ;
doMergeRowsInFileBlocks ( pBlockData , pBlockScanInfo , pReader , & merge ) ;
2022-08-18 09:09:44 +00:00
}
2022-08-20 03:14:00 +00:00
if ( minKey = = tsLast ) {
2022-08-20 04:41:58 +00:00
TSDBROW fRow1 = tsdbRowFromBlockData ( pLastBlockData , * pLastBlockReader - > rowIndex ) ;
if ( init ) {
tRowMerge ( & merge , & fRow1 ) ;
} else {
2022-08-20 03:14:00 +00:00
init = true ;
tRowMergerInit ( & merge , & fRow1 , pReader - > pSchema ) ;
}
2022-08-21 10:59:21 +00:00
doMergeRowsInLastBlock ( pLastBlockReader , pBlockScanInfo , tsLast , & merge ) ;
2022-08-20 03:14:00 +00:00
}
if ( minKey = = ik . ts ) {
2022-08-20 04:41:58 +00:00
if ( init ) {
tRowMerge ( & merge , piRow ) ;
} else {
2022-08-20 03:14:00 +00:00
init = true ;
STSchema * pSchema = doGetSchemaForTSRow ( TSDBROW_SVERSION ( piRow ) , pReader , pBlockScanInfo - > uid ) ;
tRowMergerInit ( & merge , piRow , pSchema ) ;
}
doMergeRowsInBuf ( & pBlockScanInfo - > iiter , pBlockScanInfo - > uid , ik . ts , pBlockScanInfo - > delSkyline , & merge , pReader ) ;
2022-08-18 09:09:44 +00:00
}
2022-08-20 03:14:00 +00:00
if ( minKey = = k . ts ) {
2022-08-20 04:41:58 +00:00
if ( init ) {
tRowMerge ( & merge , pRow ) ;
} else {
2022-08-20 03:14:00 +00:00
STSchema * pSchema = doGetSchemaForTSRow ( TSDBROW_SVERSION ( pRow ) , pReader , pBlockScanInfo - > uid ) ;
tRowMergerInit ( & merge , pRow , pSchema ) ;
}
doMergeRowsInBuf ( & pBlockScanInfo - > iter , pBlockScanInfo - > uid , k . ts , pBlockScanInfo - > delSkyline , & merge , pReader ) ;
}
} else {
if ( minKey = = k . ts ) {
init = true ;
2022-08-18 09:09:44 +00:00
STSchema * pSchema = doGetSchemaForTSRow ( TSDBROW_SVERSION ( pRow ) , pReader , pBlockScanInfo - > uid ) ;
tRowMergerInit ( & merge , pRow , pSchema ) ;
2022-08-20 03:14:00 +00:00
doMergeRowsInBuf ( & pBlockScanInfo - > iter , pBlockScanInfo - > uid , k . ts , pBlockScanInfo - > delSkyline , & merge , pReader ) ;
}
if ( minKey = = ik . ts ) {
2022-08-20 04:41:58 +00:00
if ( init ) {
tRowMerge ( & merge , piRow ) ;
} else {
2022-08-20 03:14:00 +00:00
init = true ;
STSchema * pSchema = doGetSchemaForTSRow ( TSDBROW_SVERSION ( piRow ) , pReader , pBlockScanInfo - > uid ) ;
tRowMergerInit ( & merge , piRow , pSchema ) ;
}
doMergeRowsInBuf ( & pBlockScanInfo - > iiter , pBlockScanInfo - > uid , ik . ts , pBlockScanInfo - > delSkyline , & merge , pReader ) ;
}
if ( minKey = = tsLast ) {
2022-08-20 04:41:58 +00:00
TSDBROW fRow1 = tsdbRowFromBlockData ( pLastBlockData , * pLastBlockReader - > rowIndex ) ;
if ( init ) {
tRowMerge ( & merge , & fRow1 ) ;
} else {
2022-08-20 03:14:00 +00:00
init = true ;
tRowMergerInit ( & merge , & fRow1 , pReader - > pSchema ) ;
}
2022-08-21 10:59:21 +00:00
doMergeRowsInLastBlock ( pLastBlockReader , pBlockScanInfo , tsLast , & merge ) ;
2022-08-20 03:14:00 +00:00
}
if ( minKey = = key ) {
2022-08-20 04:41:58 +00:00
TSDBROW fRow = tsdbRowFromBlockData ( pBlockData , pDumpInfo - > rowIndex ) ;
2022-08-20 03:14:00 +00:00
if ( ! init ) {
tRowMergerInit ( & merge , & fRow , pReader - > pSchema ) ;
2022-08-20 04:41:58 +00:00
} else {
tRowMerge ( & merge , & fRow ) ;
2022-08-20 03:14:00 +00:00
}
doMergeRowsInFileBlocks ( pBlockData , pBlockScanInfo , pReader , & merge ) ;
2022-08-18 09:09:44 +00:00
}
}
tRowMergerGetRow ( & merge , & pTSRow ) ;
doAppendRowFromTSRow ( pReader - > pResBlock , pReader , pTSRow , pBlockScanInfo - > uid ) ;
taosMemoryFree ( pTSRow ) ;
tRowMergerClear ( & merge ) ;
return TSDB_CODE_SUCCESS ;
}
2022-08-23 09:28:08 +00:00
#if 0
2022-08-17 16:08:09 +00:00
static int32_t doMergeThreeLevelRows ( STsdbReader * pReader , STableBlockScanInfo * pBlockScanInfo , SBlockData * pBlockData ) {
2022-07-02 12:39:23 +00:00
SRowMerger merge = { 0 } ;
STSRow * pTSRow = NULL ;
2022-07-02 06:17:27 +00:00
SFileBlockDumpInfo * pDumpInfo = & pReader - > status . fBlockDumpInfo ;
2022-07-06 10:29:11 +00:00
SArray * pDelList = pBlockScanInfo - > delSkyline ;
2022-07-02 06:17:27 +00:00
2022-08-24 09:09:33 +00:00
TSDBROW * pRow = getValidMemRow ( & pBlockScanInfo - > iter , pDelList , pReader ) ;
TSDBROW * piRow = getValidMemRow ( & pBlockScanInfo - > iiter , pDelList , pReader ) ;
2022-07-03 15:00:12 +00:00
ASSERT ( pRow ! = NULL & & piRow ! = NULL ) ;
2022-06-27 02:46:20 +00:00
2022-07-04 03:42:50 +00:00
int64_t key = pBlockData - > aTSKEY [ pDumpInfo - > rowIndex ] ;
2022-08-03 06:08:03 +00:00
bool freeTSRow = false ;
2022-06-27 02:46:20 +00:00
2022-07-02 12:39:23 +00:00
uint64_t uid = pBlockScanInfo - > uid ;
2022-06-27 02:46:20 +00:00
2022-07-02 12:39:23 +00:00
TSDBKEY k = TSDBROW_KEY ( pRow ) ;
TSDBKEY ik = TSDBROW_KEY ( piRow ) ;
if ( ASCENDING_TRAVERSE ( pReader - > order ) ) {
2022-07-02 04:05:03 +00:00
// [1&2] key <= [k.ts && ik.ts]
if ( key < = k . ts & & key < = ik . ts ) {
2022-06-28 02:32:42 +00:00
TSDBROW fRow = tsdbRowFromBlockData ( pBlockData , pDumpInfo - > rowIndex ) ;
tRowMergerInit ( & merge , & fRow , pReader - > pSchema ) ;
2022-07-02 12:39:23 +00:00
doMergeRowsInFileBlocks ( pBlockData , pBlockScanInfo , pReader , & merge ) ;
2022-06-27 02:46:20 +00:00
2022-07-02 04:05:03 +00:00
if ( ik . ts = = key ) {
tRowMerge ( & merge , piRow ) ;
2022-07-30 04:46:40 +00:00
doMergeRowsInBuf ( & pBlockScanInfo - > iiter , uid , key , pBlockScanInfo - > delSkyline , & merge , pReader ) ;
2022-06-28 02:32:42 +00:00
}
2022-07-02 04:05:03 +00:00
if ( k . ts = = key ) {
tRowMerge ( & merge , pRow ) ;
2022-07-30 04:46:40 +00:00
doMergeRowsInBuf ( & pBlockScanInfo - > iter , uid , key , pBlockScanInfo - > delSkyline , & merge , pReader ) ;
2022-06-28 02:32:42 +00:00
}
tRowMergerGetRow ( & merge , & pTSRow ) ;
2022-08-09 02:16:00 +00:00
doAppendRowFromTSRow ( pReader - > pResBlock , pReader , pTSRow , uid ) ;
2022-07-02 12:39:23 +00:00
return TSDB_CODE_SUCCESS ;
2022-07-02 04:05:03 +00:00
} else { // key > ik.ts || key > k.ts
2022-07-02 12:39:23 +00:00
ASSERT ( key ! = ik . ts ) ;
2022-06-28 02:32:42 +00:00
// [3] ik.ts < key <= k.ts
2022-07-02 04:05:03 +00:00
// [4] ik.ts < k.ts <= key
2022-06-28 02:32:42 +00:00
if ( ik . ts < k . ts ) {
2022-08-23 09:28:08 +00:00
doMergeMemTableMultiRows ( piRow , uid , & pBlockScanInfo - > iiter , pDelList , & pTSRow , pReader , & freeTSRow ) ;
2022-08-09 02:16:00 +00:00
doAppendRowFromTSRow ( pReader - > pResBlock , pReader , pTSRow , uid ) ;
2022-08-03 06:08:03 +00:00
if ( freeTSRow ) {
taosMemoryFree ( pTSRow ) ;
}
2022-06-28 02:32:42 +00:00
return TSDB_CODE_SUCCESS ;
}
2022-07-02 04:05:03 +00:00
// [5] k.ts < key <= ik.ts
// [6] k.ts < ik.ts <= key
2022-06-28 02:32:42 +00:00
if ( k . ts < ik . ts ) {
2022-08-23 09:28:08 +00:00
doMergeMemTableMultiRows ( pRow , uid , & pBlockScanInfo - > iter , pDelList , & pTSRow , pReader , & freeTSRow ) ;
2022-08-09 02:16:00 +00:00
doAppendRowFromTSRow ( pReader - > pResBlock , pReader , pTSRow , uid ) ;
2022-08-03 06:08:03 +00:00
if ( freeTSRow ) {
taosMemoryFree ( pTSRow ) ;
}
2022-06-28 02:32:42 +00:00
return TSDB_CODE_SUCCESS ;
}
2022-07-02 04:05:03 +00:00
// [7] k.ts == ik.ts < key
2022-06-28 02:32:42 +00:00
if ( k . ts = = ik . ts ) {
2022-07-02 12:39:23 +00:00
ASSERT ( key > ik . ts & & key > k . ts ) ;
2022-07-02 04:05:03 +00:00
doMergeMemIMemRows ( pRow , piRow , pBlockScanInfo , pReader , & pTSRow ) ;
2022-08-09 02:16:00 +00:00
doAppendRowFromTSRow ( pReader - > pResBlock , pReader , pTSRow , uid ) ;
2022-08-03 06:08:03 +00:00
taosMemoryFree ( pTSRow ) ;
2022-06-28 02:32:42 +00:00
return TSDB_CODE_SUCCESS ;
}
}
2022-07-02 12:39:23 +00:00
} else { // descending order scan
// [1/2] k.ts >= ik.ts && k.ts >= key
if ( k . ts > = ik . ts & & k . ts > = key ) {
2022-08-09 02:16:00 +00:00
STSchema * pSchema = doGetSchemaForTSRow ( TSDBROW_SVERSION ( pRow ) , pReader , pBlockScanInfo - > uid ) ;
2022-07-02 12:39:23 +00:00
2022-08-09 02:16:00 +00:00
tRowMergerInit ( & merge , pRow , pSchema ) ;
2022-07-30 04:46:40 +00:00
doMergeRowsInBuf ( & pBlockScanInfo - > iter , uid , key , pBlockScanInfo - > delSkyline , & merge , pReader ) ;
2022-07-02 12:39:23 +00:00
if ( ik . ts = = k . ts ) {
tRowMerge ( & merge , piRow ) ;
2022-07-30 04:46:40 +00:00
doMergeRowsInBuf ( & pBlockScanInfo - > iiter , uid , key , pBlockScanInfo - > delSkyline , & merge , pReader ) ;
2022-07-02 12:39:23 +00:00
}
if ( k . ts = = key ) {
TSDBROW fRow = tsdbRowFromBlockData ( pBlockData , pDumpInfo - > rowIndex ) ;
tRowMerge ( & merge , & fRow ) ;
doMergeRowsInFileBlocks ( pBlockData , pBlockScanInfo , pReader , & merge ) ;
}
tRowMergerGetRow ( & merge , & pTSRow ) ;
2022-08-09 02:16:00 +00:00
doAppendRowFromTSRow ( pReader - > pResBlock , pReader , pTSRow , uid ) ;
2022-07-02 12:39:23 +00:00
return TSDB_CODE_SUCCESS ;
} else {
2022-07-04 03:42:50 +00:00
ASSERT ( ik . ts ! = k . ts ) ; // this case has been included in the previous if branch
2022-07-02 12:39:23 +00:00
// [3] ik.ts > k.ts >= Key
// [4] ik.ts > key >= k.ts
if ( ik . ts > key ) {
2022-08-23 09:28:08 +00:00
doMergeMemTableMultiRows ( piRow , uid , & pBlockScanInfo - > iiter , pDelList , & pTSRow , pReader , & freeTSRow ) ;
2022-08-09 02:16:00 +00:00
doAppendRowFromTSRow ( pReader - > pResBlock , pReader , pTSRow , uid ) ;
2022-08-03 06:08:03 +00:00
if ( freeTSRow ) {
taosMemoryFree ( pTSRow ) ;
}
2022-07-02 12:39:23 +00:00
return TSDB_CODE_SUCCESS ;
}
// [5] key > ik.ts > k.ts
// [6] key > k.ts > ik.ts
if ( key > ik . ts ) {
TSDBROW fRow = tsdbRowFromBlockData ( pBlockData , pDumpInfo - > rowIndex ) ;
tRowMergerInit ( & merge , & fRow , pReader - > pSchema ) ;
doMergeRowsInFileBlocks ( pBlockData , pBlockScanInfo , pReader , & merge ) ;
tRowMergerGetRow ( & merge , & pTSRow ) ;
2022-08-09 02:16:00 +00:00
doAppendRowFromTSRow ( pReader - > pResBlock , pReader , pTSRow , uid ) ;
2022-08-03 06:08:03 +00:00
taosMemoryFree ( pTSRow ) ;
2022-07-02 12:39:23 +00:00
return TSDB_CODE_SUCCESS ;
}
//[7] key = ik.ts > k.ts
if ( key = = ik . ts ) {
2022-08-23 09:28:08 +00:00
doMergeMemTableMultiRows ( piRow , uid , & pBlockScanInfo - > iiter , pDelList , & pTSRow , pReader , & freeTSRow ) ;
2022-07-02 12:39:23 +00:00
TSDBROW fRow = tsdbRowFromBlockData ( pBlockData , pDumpInfo - > rowIndex ) ;
tRowMerge ( & merge , & fRow ) ;
doMergeRowsInFileBlocks ( pBlockData , pBlockScanInfo , pReader , & merge ) ;
tRowMergerGetRow ( & merge , & pTSRow ) ;
2022-08-09 02:16:00 +00:00
doAppendRowFromTSRow ( pReader - > pResBlock , pReader , pTSRow , uid ) ;
2022-08-03 06:08:03 +00:00
taosMemoryFree ( pTSRow ) ;
2022-07-02 12:39:23 +00:00
return TSDB_CODE_SUCCESS ;
}
}
}
ASSERT ( 0 ) ;
2022-07-08 03:51:35 +00:00
return - 1 ;
2022-07-02 12:39:23 +00:00
}
2022-08-23 09:28:08 +00:00
# endif
2022-07-02 12:39:23 +00:00
2022-07-06 10:29:11 +00:00
static bool isValidFileBlockRow ( SBlockData * pBlockData , SFileBlockDumpInfo * pDumpInfo ,
STableBlockScanInfo * pBlockScanInfo , STsdbReader * pReader ) {
2022-08-17 16:08:09 +00:00
// it is an multi-table data block
if ( pBlockData - > aUid ! = NULL ) {
uint64_t uid = pBlockData - > aUid [ pDumpInfo - > rowIndex ] ;
if ( uid ! = pBlockScanInfo - > uid ) { // move to next row
return false ;
}
}
2022-07-03 15:00:12 +00:00
// check for version and time range
int64_t ver = pBlockData - > aVersion [ pDumpInfo - > rowIndex ] ;
if ( ver > pReader - > verRange . maxVer | | ver < pReader - > verRange . minVer ) {
return false ;
}
int64_t ts = pBlockData - > aTSKEY [ pDumpInfo - > rowIndex ] ;
if ( ts > pReader - > window . ekey | | ts < pReader - > window . skey ) {
return false ;
}
2022-07-04 15:28:27 +00:00
TSDBKEY k = { . ts = ts , . version = ver } ;
2022-07-08 03:02:12 +00:00
if ( hasBeenDropped ( pBlockScanInfo - > delSkyline , & pBlockScanInfo - > fileDelIndex , & k , pReader - > order ) ) {
2022-07-04 15:28:27 +00:00
return false ;
}
2022-07-03 15:00:12 +00:00
return true ;
}
2022-07-04 03:42:50 +00:00
static bool outOfTimeWindow ( int64_t ts , STimeWindow * pWindow ) { return ( ts > pWindow - > ekey ) | | ( ts < pWindow - > skey ) ; }
2022-07-03 15:00:12 +00:00
2022-08-18 14:42:16 +00:00
static void initLastBlockReader ( SLastBlockReader * pLastBlockReader , uint64_t uid , int16_t * startPos ) {
2022-08-17 16:08:09 +00:00
pLastBlockReader - > uid = uid ;
pLastBlockReader - > rowIndex = startPos ;
2022-08-18 14:42:16 +00:00
if ( * startPos = = - 1 ) {
if ( ASCENDING_TRAVERSE ( pLastBlockReader - > order ) ) {
// do nothing
} else {
* startPos = pLastBlockReader - > lastBlockData . nRow ;
}
}
}
static void setAllRowsChecked ( SLastBlockReader * pLastBlockReader ) {
* pLastBlockReader - > rowIndex = ALL_ROWS_CHECKED_INDEX ;
2022-08-17 16:08:09 +00:00
}
2022-08-21 10:59:21 +00:00
static bool nextRowInLastBlock ( SLastBlockReader * pLastBlockReader , STableBlockScanInfo * pBlockScanInfo ) {
2022-08-25 07:31:48 +00:00
bool asc = ASCENDING_TRAVERSE ( pLastBlockReader - > order ) ;
int32_t step = ( asc ) ? 1 : - 1 ;
2022-08-18 14:42:16 +00:00
if ( * pLastBlockReader - > rowIndex = = ALL_ROWS_CHECKED_INDEX ) {
2022-08-17 16:08:09 +00:00
return false ;
}
2022-08-18 14:42:16 +00:00
* ( pLastBlockReader - > rowIndex ) + = step ;
2022-08-17 16:08:09 +00:00
SBlockData * pBlockData = & pLastBlockReader - > lastBlockData ;
2022-08-18 14:42:16 +00:00
for ( int32_t i = * ( pLastBlockReader - > rowIndex ) ; i < pBlockData - > nRow & & i > = 0 ; i + = step ) {
2022-08-25 07:31:48 +00:00
if ( pBlockData - > aUid ! = NULL ) {
if ( asc ) {
if ( pBlockData - > aUid [ i ] < pLastBlockReader - > uid ) {
continue ;
} else if ( pBlockData - > aUid [ i ] > pLastBlockReader - > uid ) {
break ;
}
} else {
if ( pBlockData - > aUid [ i ] > pLastBlockReader - > uid ) {
continue ;
} else if ( pBlockData - > aUid [ i ] < pLastBlockReader - > uid ) {
break ;
}
}
2022-08-17 16:08:09 +00:00
}
2022-08-21 10:59:21 +00:00
int64_t ts = pBlockData - > aTSKEY [ i ] ;
if ( ts < pLastBlockReader - > window . skey ) {
2022-08-17 16:08:09 +00:00
continue ;
}
2022-08-21 10:59:21 +00:00
int64_t ver = pBlockData - > aVersion [ i ] ;
if ( ver < pLastBlockReader - > verRange . minVer ) {
2022-08-17 16:08:09 +00:00
continue ;
}
2022-08-20 04:41:58 +00:00
// no data any more, todo opt handle desc case
2022-08-21 10:59:21 +00:00
if ( ts > pLastBlockReader - > window . ekey ) {
2022-08-20 04:41:58 +00:00
continue ;
2022-08-17 16:08:09 +00:00
}
2022-08-20 04:41:58 +00:00
// todo opt handle desc case
2022-08-21 10:59:21 +00:00
if ( ver > pLastBlockReader - > verRange . maxVer ) {
continue ;
}
TSDBKEY k = { . ts = ts , . version = ver } ;
2022-08-21 12:15:53 +00:00
if ( hasBeenDropped ( pBlockScanInfo - > delSkyline , & pBlockScanInfo - > lastBlockDelIndex , & k , pLastBlockReader - > order ) ) {
2022-08-20 04:41:58 +00:00
continue ;
2022-08-17 16:08:09 +00:00
}
2022-08-18 10:48:50 +00:00
* ( pLastBlockReader - > rowIndex ) = i ;
2022-08-17 16:08:09 +00:00
return true ;
}
2022-08-18 10:48:50 +00:00
// set all data is consumed in last block
2022-08-18 14:42:16 +00:00
setAllRowsChecked ( pLastBlockReader ) ;
2022-08-17 16:08:09 +00:00
return false ;
}
static int64_t getCurrentKeyInLastBlock ( SLastBlockReader * pLastBlockReader ) {
SBlockData * pBlockData = & pLastBlockReader - > lastBlockData ;
2022-08-18 10:48:50 +00:00
return pBlockData - > aTSKEY [ * pLastBlockReader - > rowIndex ] ;
2022-08-17 16:08:09 +00:00
}
static bool hasDataInLastBlock ( SLastBlockReader * pLastBlockReader ) {
2022-08-18 14:42:16 +00:00
if ( * pLastBlockReader - > rowIndex = = ALL_ROWS_CHECKED_INDEX ) {
2022-08-17 16:08:09 +00:00
return false ;
}
2022-08-25 15:04:07 +00:00
2022-08-23 11:44:59 +00:00
ASSERT ( pLastBlockReader - > lastBlockData . nRow > 0 ) ;
2022-08-17 16:08:09 +00:00
return true ;
}
2022-08-23 11:44:59 +00:00
int32_t mergeRowsInFileBlocks ( SBlockData * pBlockData , STableBlockScanInfo * pBlockScanInfo , int64_t key , STsdbReader * pReader ) {
SFileBlockDumpInfo * pDumpInfo = & pReader - > status . fBlockDumpInfo ;
TSDBROW fRow = tsdbRowFromBlockData ( pBlockData , pDumpInfo - > rowIndex ) ;
if ( tryCopyDistinctRowFromFileBlock ( pReader , pBlockData , key , pDumpInfo ) ) {
return TSDB_CODE_SUCCESS ;
} else {
STSRow * pTSRow = NULL ;
SRowMerger merge = { 0 } ;
tRowMergerInit ( & merge , & fRow , pReader - > pSchema ) ;
doMergeRowsInFileBlocks ( pBlockData , pBlockScanInfo , pReader , & merge ) ;
tRowMergerGetRow ( & merge , & pTSRow ) ;
doAppendRowFromTSRow ( pReader - > pResBlock , pReader , pTSRow , pBlockScanInfo - > uid ) ;
taosMemoryFree ( pTSRow ) ;
tRowMergerClear ( & merge ) ;
return TSDB_CODE_SUCCESS ;
}
2022-08-25 15:04:07 +00:00
2022-08-23 11:44:59 +00:00
return TSDB_CODE_SUCCESS ;
}
2022-08-21 10:59:21 +00:00
static int32_t buildComposedDataBlockImpl ( STsdbReader * pReader , STableBlockScanInfo * pBlockScanInfo ,
SBlockData * pBlockData , SLastBlockReader * pLastBlockReader ) {
2022-07-02 12:39:23 +00:00
SFileBlockDumpInfo * pDumpInfo = & pReader - > status . fBlockDumpInfo ;
2022-08-18 09:09:44 +00:00
int64_t key = ( pBlockData - > nRow > 0 ) ? pBlockData - > aTSKEY [ pDumpInfo - > rowIndex ] : INT64_MIN ;
2022-08-24 09:09:33 +00:00
TSDBROW * pRow = getValidMemRow ( & pBlockScanInfo - > iter , pBlockScanInfo - > delSkyline , pReader ) ;
TSDBROW * piRow = getValidMemRow ( & pBlockScanInfo - > iiter , pBlockScanInfo - > delSkyline , pReader ) ;
2022-07-02 12:39:23 +00:00
2022-07-04 15:28:27 +00:00
if ( pBlockScanInfo - > iter . hasVal & & pBlockScanInfo - > iiter . hasVal ) {
2022-08-24 09:09:33 +00:00
return doMergeMultiLevelRows ( pReader , pBlockScanInfo , pBlockData , pLastBlockReader ) ;
2022-07-01 07:19:02 +00:00
} else {
2022-08-18 09:09:44 +00:00
// imem + file + last block
2022-07-04 15:28:27 +00:00
if ( pBlockScanInfo - > iiter . hasVal ) {
2022-08-24 09:09:33 +00:00
return doMergeBufAndFileRows ( pReader , pBlockScanInfo , piRow , & pBlockScanInfo - > iiter , key , pLastBlockReader ) ;
2022-06-28 02:32:42 +00:00
}
2022-08-23 11:44:59 +00:00
// mem + file + last block
2022-07-04 15:28:27 +00:00
if ( pBlockScanInfo - > iter . hasVal ) {
2022-08-24 09:09:33 +00:00
return doMergeBufAndFileRows ( pReader , pBlockScanInfo , pRow , & pBlockScanInfo - > iter , key , pLastBlockReader ) ;
2022-06-27 02:46:20 +00:00
}
2022-06-28 02:32:42 +00:00
2022-08-23 11:44:59 +00:00
// files data blocks + last block
return mergeFileBlockAndLastBlock ( pReader , pLastBlockReader , key , pBlockScanInfo , pBlockData ) ;
2022-06-28 02:32:42 +00:00
}
}
2022-08-16 23:51:09 +00:00
static int32_t buildComposedDataBlock ( STsdbReader * pReader ) {
2022-06-28 02:32:42 +00:00
SSDataBlock * pResBlock = pReader - > pResBlock ;
2022-08-16 23:51:09 +00:00
SFileDataBlockInfo * pBlockInfo = getCurrentBlockInfo ( & pReader - > status . blockIter ) ;
2022-08-17 16:08:09 +00:00
STableBlockScanInfo * pBlockScanInfo = NULL ;
if ( pBlockInfo ! = NULL ) {
pBlockScanInfo = taosHashGet ( pReader - > status . pTableMap , & pBlockInfo - > uid , sizeof ( pBlockInfo - > uid ) ) ;
} else {
pBlockScanInfo = pReader - > status . pTableIter ;
}
2022-08-21 10:59:21 +00:00
SLastBlockReader * pLastBlockReader = pReader - > status . fileIter . pLastBlockReader ;
2022-07-03 15:00:12 +00:00
SFileBlockDumpInfo * pDumpInfo = & pReader - > status . fBlockDumpInfo ;
2022-07-04 03:42:50 +00:00
SBlockData * pBlockData = & pReader - > status . fileBlockData ;
int32_t step = ASCENDING_TRAVERSE ( pReader - > order ) ? 1 : - 1 ;
2022-07-03 15:00:12 +00:00
2022-07-25 03:17:45 +00:00
int64_t st = taosGetTimestampUs ( ) ;
2022-07-04 03:42:50 +00:00
while ( 1 ) {
2022-07-03 15:00:12 +00:00
// todo check the validate of row in file block
2022-08-23 11:44:59 +00:00
bool hasBlockData = false ;
2022-07-03 15:00:12 +00:00
{
2022-08-20 04:41:58 +00:00
while ( pBlockData - > nRow > 0 ) { // find the first qualified row in data block
2022-08-20 03:14:00 +00:00
if ( isValidFileBlockRow ( pBlockData , pDumpInfo , pBlockScanInfo , pReader ) ) {
hasBlockData = true ;
break ;
}
2022-07-03 15:00:12 +00:00
pDumpInfo - > rowIndex + = step ;
2022-07-26 02:19:12 +00:00
SBlock * pBlock = getCurrentBlock ( & pReader - > status . blockIter ) ;
2022-07-03 15:00:12 +00:00
if ( pDumpInfo - > rowIndex > = pBlock - > nRow | | pDumpInfo - > rowIndex < 0 ) {
2022-08-20 03:14:00 +00:00
setBlockAllDumped ( pDumpInfo , pBlock - > maxKey . ts , pReader - > order ) ;
2022-07-03 15:00:12 +00:00
break ;
}
}
2022-08-23 11:44:59 +00:00
}
2022-08-25 15:04:07 +00:00
2022-08-23 11:44:59 +00:00
bool hasBlockLData = hasDataInLastBlock ( pLastBlockReader ) ;
2022-08-17 16:08:09 +00:00
2022-08-23 11:44:59 +00:00
// no data in last block and block, no need to proceed.
if ( ( hasBlockData = = false ) & & ( hasBlockLData = = false ) ) {
break ;
2022-07-03 15:00:12 +00:00
}
2022-08-17 16:08:09 +00:00
buildComposedDataBlockImpl ( pReader , pBlockScanInfo , pBlockData , pLastBlockReader ) ;
2022-06-28 02:32:42 +00:00
2022-07-02 06:17:27 +00:00
// currently loaded file data block is consumed
2022-08-18 10:48:50 +00:00
if ( ( pBlockData - > nRow > 0 ) & & ( pDumpInfo - > rowIndex > = pBlockData - > nRow | | pDumpInfo - > rowIndex < 0 ) ) {
2022-08-18 09:09:44 +00:00
SBlock * pBlock = getCurrentBlock ( & pReader - > status . blockIter ) ;
2022-08-20 03:14:00 +00:00
setBlockAllDumped ( pDumpInfo , pBlock - > maxKey . ts , pReader - > order ) ;
2022-07-02 06:17:27 +00:00
break ;
}
if ( pResBlock - > info . rows > = pReader - > capacity ) {
break ;
2022-06-28 02:32:42 +00:00
}
}
pResBlock - > info . uid = pBlockScanInfo - > uid ;
2022-07-02 06:17:27 +00:00
blockDataUpdateTsWindow ( pResBlock , 0 ) ;
2022-06-28 02:32:42 +00:00
setComposedBlockFlag ( pReader , true ) ;
2022-07-25 03:17:45 +00:00
int64_t et = taosGetTimestampUs ( ) ;
2022-07-02 06:17:27 +00:00
2022-08-25 08:22:22 +00:00
if ( pResBlock - > info . rows > 0 ) {
tsdbDebug ( " %p uid:% " PRIu64 " , composed data block created, brange:% " PRIu64 " -% " PRIu64
" rows:%d, elapsed time:%.2f ms %s " ,
pReader , pBlockScanInfo - > uid , pResBlock - > info . window . skey , pResBlock - > info . window . ekey ,
pResBlock - > info . rows , ( et - st ) / 1000.0 , pReader - > idStr ) ;
}
2022-07-03 15:00:12 +00:00
2022-06-28 02:32:42 +00:00
return TSDB_CODE_SUCCESS ;
}
void setComposedBlockFlag ( STsdbReader * pReader , bool composed ) { pReader - > status . composedDataBlock = composed ; }
2022-07-04 15:28:27 +00:00
static int32_t initMemDataIterator ( STableBlockScanInfo * pBlockScanInfo , STsdbReader * pReader ) {
2022-06-28 02:32:42 +00:00
if ( pBlockScanInfo - > iterInit ) {
return TSDB_CODE_SUCCESS ;
}
2022-06-29 01:40:31 +00:00
int32_t code = TSDB_CODE_SUCCESS ;
2022-06-30 15:38:18 +00:00
TSDBKEY startKey = { 0 } ;
if ( ASCENDING_TRAVERSE ( pReader - > order ) ) {
startKey = ( TSDBKEY ) { . ts = pReader - > window . skey , . version = pReader - > verRange . minVer } ;
} else {
startKey = ( TSDBKEY ) { . ts = pReader - > window . ekey , . version = pReader - > verRange . maxVer } ;
}
int32_t backward = ( ! ASCENDING_TRAVERSE ( pReader - > order ) ) ;
2022-06-28 02:32:42 +00:00
STbData * d = NULL ;
2022-07-21 11:42:42 +00:00
if ( pReader - > pReadSnap - > pMem ! = NULL ) {
2022-08-15 10:16:07 +00:00
d = tsdbGetTbDataFromMemTable ( pReader - > pReadSnap - > pMem , pReader - > suid , pBlockScanInfo - > uid ) ;
2022-06-29 01:40:31 +00:00
if ( d ! = NULL ) {
2022-07-04 15:28:27 +00:00
code = tsdbTbDataIterCreate ( d , & startKey , backward , & pBlockScanInfo - > iter . iter ) ;
2022-06-30 06:50:59 +00:00
if ( code = = TSDB_CODE_SUCCESS ) {
2022-07-04 15:28:27 +00:00
pBlockScanInfo - > iter . hasVal = ( tsdbTbDataIterGet ( pBlockScanInfo - > iter . iter ) ! = NULL ) ;
2022-06-30 06:50:59 +00:00
2022-06-29 12:25:03 +00:00
tsdbDebug ( " %p uid:% " PRId64 " , check data in mem from skey:% " PRId64 " , order:%d, ts range in buf:% " PRId64
2022-06-30 15:38:18 +00:00
" -% " PRId64 " %s " ,
pReader , pBlockScanInfo - > uid , startKey . ts , pReader - > order , d - > minKey , d - > maxKey , pReader - > idStr ) ;
2022-06-30 06:50:59 +00:00
} else {
2022-06-30 15:38:18 +00:00
tsdbError ( " %p uid:% " PRId64 " , failed to create iterator for imem, code:%s, %s " , pReader , pBlockScanInfo - > uid ,
tstrerror ( code ) , pReader - > idStr ) ;
2022-06-30 06:50:59 +00:00
return code ;
2022-06-29 01:40:31 +00:00
}
}
2022-06-29 12:25:03 +00:00
} else {
2022-06-30 15:38:18 +00:00
tsdbDebug ( " %p uid:% " PRId64 " , no data in mem, %s " , pReader , pBlockScanInfo - > uid , pReader - > idStr ) ;
2022-06-27 02:46:20 +00:00
}
2022-06-28 02:32:42 +00:00
STbData * di = NULL ;
2022-07-21 11:42:42 +00:00
if ( pReader - > pReadSnap - > pIMem ! = NULL ) {
2022-08-15 10:16:07 +00:00
di = tsdbGetTbDataFromMemTable ( pReader - > pReadSnap - > pIMem , pReader - > suid , pBlockScanInfo - > uid ) ;
2022-06-29 01:40:31 +00:00
if ( di ! = NULL ) {
2022-07-04 15:28:27 +00:00
code = tsdbTbDataIterCreate ( di , & startKey , backward , & pBlockScanInfo - > iiter . iter ) ;
2022-06-30 06:50:59 +00:00
if ( code = = TSDB_CODE_SUCCESS ) {
2022-07-04 15:28:27 +00:00
pBlockScanInfo - > iiter . hasVal = ( tsdbTbDataIterGet ( pBlockScanInfo - > iiter . iter ) ! = NULL ) ;
2022-06-30 06:50:59 +00:00
2022-06-29 12:25:03 +00:00
tsdbDebug ( " %p uid:% " PRId64 " , check data in imem from skey:% " PRId64 " , order:%d, ts range in buf:% " PRId64
2022-06-30 06:50:59 +00:00
" -% " PRId64 " %s " ,
2022-06-30 15:38:18 +00:00
pReader , pBlockScanInfo - > uid , startKey . ts , pReader - > order , di - > minKey , di - > maxKey , pReader - > idStr ) ;
2022-06-30 06:50:59 +00:00
} else {
2022-06-30 15:38:18 +00:00
tsdbError ( " %p uid:% " PRId64 " , failed to create iterator for mem, code:%s, %s " , pReader , pBlockScanInfo - > uid ,
tstrerror ( code ) , pReader - > idStr ) ;
2022-06-30 06:50:59 +00:00
return code ;
2022-06-29 01:40:31 +00:00
}
}
2022-06-29 12:25:03 +00:00
} else {
tsdbDebug ( " %p uid:% " PRId64 " , no data in imem, %s " , pReader , pBlockScanInfo - > uid , pReader - > idStr ) ;
2022-06-28 02:32:42 +00:00
}
2022-07-04 15:28:27 +00:00
initDelSkylineIterator ( pBlockScanInfo , pReader , d , di ) ;
2022-06-28 02:32:42 +00:00
pBlockScanInfo - > iterInit = true ;
2022-06-27 02:46:20 +00:00
return TSDB_CODE_SUCCESS ;
}
2022-07-06 10:29:11 +00:00
int32_t initDelSkylineIterator ( STableBlockScanInfo * pBlockScanInfo , STsdbReader * pReader , STbData * pMemTbData ,
STbData * piMemTbData ) {
2022-07-04 06:10:29 +00:00
if ( pBlockScanInfo - > delSkyline ! = NULL ) {
return TSDB_CODE_SUCCESS ;
}
2022-07-04 15:28:27 +00:00
2022-07-04 06:10:29 +00:00
int32_t code = 0 ;
STsdb * pTsdb = pReader - > pTsdb ;
2022-07-04 15:28:27 +00:00
SArray * pDelData = taosArrayInit ( 4 , sizeof ( SDelData ) ) ;
2022-07-21 11:42:42 +00:00
SDelFile * pDelFile = pReader - > pReadSnap - > fs . pDelFile ;
2022-07-04 06:10:29 +00:00
if ( pDelFile ) {
SDelFReader * pDelFReader = NULL ;
2022-08-06 12:24:46 +00:00
code = tsdbDelFReaderOpen ( & pDelFReader , pDelFile , pTsdb ) ;
2022-07-21 03:27:20 +00:00
if ( code ! = TSDB_CODE_SUCCESS ) {
2022-07-04 06:10:29 +00:00
goto _err ;
}
SArray * aDelIdx = taosArrayInit ( 4 , sizeof ( SDelIdx ) ) ;
if ( aDelIdx = = NULL ) {
2022-07-21 03:27:20 +00:00
tsdbDelFReaderClose ( & pDelFReader ) ;
2022-07-04 06:10:29 +00:00
goto _err ;
}
2022-08-06 12:23:29 +00:00
code = tsdbReadDelIdx ( pDelFReader , aDelIdx ) ;
2022-07-21 03:27:20 +00:00
if ( code ! = TSDB_CODE_SUCCESS ) {
taosArrayDestroy ( aDelIdx ) ;
tsdbDelFReaderClose ( & pDelFReader ) ;
2022-07-04 15:28:27 +00:00
goto _err ;
}
2022-07-04 06:10:29 +00:00
2022-07-04 15:28:27 +00:00
SDelIdx idx = { . suid = pReader - > suid , . uid = pBlockScanInfo - > uid } ;
SDelIdx * pIdx = taosArraySearch ( aDelIdx , & idx , tCmprDelIdx , TD_EQ ) ;
2022-07-19 10:05:26 +00:00
if ( pIdx ! = NULL ) {
2022-08-06 12:23:29 +00:00
code = tsdbReadDelData ( pDelFReader , pIdx , pDelData ) ;
2022-07-21 03:35:31 +00:00
}
taosArrayDestroy ( aDelIdx ) ;
tsdbDelFReaderClose ( & pDelFReader ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
goto _err ;
2022-07-04 06:10:29 +00:00
}
2022-07-04 15:28:27 +00:00
}
2022-07-04 06:10:29 +00:00
2022-07-04 15:28:27 +00:00
SDelData * p = NULL ;
if ( pMemTbData ! = NULL ) {
p = pMemTbData - > pHead ;
while ( p ) {
taosArrayPush ( pDelData , p ) ;
p = p - > pNext ;
}
2022-07-04 06:10:29 +00:00
}
2022-07-04 15:28:27 +00:00
if ( piMemTbData ! = NULL ) {
p = piMemTbData - > pHead ;
while ( p ) {
taosArrayPush ( pDelData , p ) ;
p = p - > pNext ;
}
}
if ( taosArrayGetSize ( pDelData ) > 0 ) {
pBlockScanInfo - > delSkyline = taosArrayInit ( 4 , sizeof ( TSDBKEY ) ) ;
code = tsdbBuildDeleteSkyline ( pDelData , 0 , ( int32_t ) ( taosArrayGetSize ( pDelData ) - 1 ) , pBlockScanInfo - > delSkyline ) ;
}
taosArrayDestroy ( pDelData ) ;
2022-07-06 10:29:11 +00:00
pBlockScanInfo - > iter . index =
ASCENDING_TRAVERSE ( pReader - > order ) ? 0 : taosArrayGetSize ( pBlockScanInfo - > delSkyline ) - 1 ;
2022-07-04 15:28:27 +00:00
pBlockScanInfo - > iiter . index = pBlockScanInfo - > iter . index ;
pBlockScanInfo - > fileDelIndex = pBlockScanInfo - > iter . index ;
2022-08-21 12:15:53 +00:00
pBlockScanInfo - > lastBlockDelIndex = pBlockScanInfo - > iter . index ;
2022-07-04 06:10:29 +00:00
return code ;
2022-07-04 15:28:27 +00:00
_err :
taosArrayDestroy ( pDelData ) ;
return code ;
2022-07-04 06:10:29 +00:00
}
2022-08-20 03:14:00 +00:00
static TSDBKEY getCurrentKeyInBuf ( STableBlockScanInfo * pScanInfo , STsdbReader * pReader ) {
2022-06-28 02:32:42 +00:00
TSDBKEY key = { . ts = TSKEY_INITIAL_VAL } ;
2022-07-04 15:28:27 +00:00
initMemDataIterator ( pScanInfo , pReader ) ;
2022-08-24 09:09:33 +00:00
TSDBROW * pRow = getValidMemRow ( & pScanInfo - > iter , pScanInfo - > delSkyline , pReader ) ;
2022-07-03 15:00:12 +00:00
if ( pRow ! = NULL ) {
2022-06-28 02:32:42 +00:00
key = TSDBROW_KEY ( pRow ) ;
}
2022-08-24 09:09:33 +00:00
pRow = getValidMemRow ( & pScanInfo - > iiter , pScanInfo - > delSkyline , pReader ) ;
2022-07-03 15:00:12 +00:00
if ( pRow ! = NULL ) {
2022-06-28 02:32:42 +00:00
TSDBKEY k = TSDBROW_KEY ( pRow ) ;
if ( key . ts > k . ts ) {
key = k ;
}
}
return key ;
}
2022-08-17 16:08:09 +00:00
static int32_t moveToNextFile ( STsdbReader * pReader , SBlockNumber * pBlockNum ) {
2022-06-29 02:35:07 +00:00
SReaderStatus * pStatus = & pReader - > status ;
2022-08-21 14:17:12 +00:00
pBlockNum - > numOfBlocks = 0 ;
pBlockNum - > numOfLastBlocks = 0 ;
2022-07-25 03:17:45 +00:00
2022-07-29 10:15:44 +00:00
size_t numOfTables = taosHashGetSize ( pReader - > status . pTableMap ) ;
2022-07-25 03:17:45 +00:00
SArray * pIndexList = taosArrayInit ( numOfTables , sizeof ( SBlockIdx ) ) ;
2022-08-20 08:57:44 +00:00
SArray * pLastBlocks = pStatus - > fileIter . pLastBlockReader - > pBlockL ;
2022-08-21 14:17:12 +00:00
taosArrayClear ( pLastBlocks ) ;
2022-06-29 02:35:07 +00:00
while ( 1 ) {
2022-06-30 15:38:18 +00:00
bool hasNext = filesetIteratorNext ( & pStatus - > fileIter , pReader ) ;
2022-07-04 03:42:50 +00:00
if ( ! hasNext ) { // no data files on disk
2022-06-29 02:35:07 +00:00
break ;
}
2022-07-13 15:15:58 +00:00
taosArrayClear ( pIndexList ) ;
2022-06-29 02:35:07 +00:00
int32_t code = doLoadBlockIndex ( pReader , pReader - > pFileReader , pIndexList ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
2022-07-13 15:15:58 +00:00
taosArrayDestroy ( pIndexList ) ;
2022-06-29 02:35:07 +00:00
return code ;
}
2022-08-17 16:08:09 +00:00
code = tsdbReadBlockL ( pReader - > pFileReader , pLastBlocks ) ;
2022-08-16 23:51:09 +00:00
if ( code ! = TSDB_CODE_SUCCESS ) {
taosArrayDestroy ( pIndexList ) ;
return code ;
}
2022-08-17 16:08:09 +00:00
if ( taosArrayGetSize ( pIndexList ) > 0 | | taosArrayGetSize ( pLastBlocks ) > 0 ) {
SArray * pQLastBlock = taosArrayInit ( 4 , sizeof ( SBlockL ) ) ;
code = doLoadFileBlock ( pReader , pIndexList , pLastBlocks , pBlockNum , pQLastBlock ) ;
2022-06-29 02:35:07 +00:00
if ( code ! = TSDB_CODE_SUCCESS ) {
2022-07-13 15:15:58 +00:00
taosArrayDestroy ( pIndexList ) ;
2022-08-17 16:08:09 +00:00
taosArrayDestroy ( pQLastBlock ) ;
2022-06-29 02:35:07 +00:00
return code ;
}
2022-08-16 23:51:09 +00:00
if ( pBlockNum - > numOfBlocks + pBlockNum - > numOfLastBlocks > 0 ) {
ASSERT ( taosArrayGetSize ( pQLastBlock ) = = pBlockNum - > numOfLastBlocks ) ;
2022-08-17 16:08:09 +00:00
taosArrayClear ( pLastBlocks ) ;
taosArrayAddAll ( pLastBlocks , pQLastBlock ) ;
taosArrayDestroy ( pQLastBlock ) ;
2022-06-29 02:35:07 +00:00
break ;
}
2022-08-20 11:05:55 +00:00
taosArrayDestroy ( pQLastBlock ) ;
2022-06-29 02:35:07 +00:00
}
2022-08-16 23:51:09 +00:00
2022-06-29 02:35:07 +00:00
// no blocks in current file, try next files
}
2022-07-13 15:15:58 +00:00
taosArrayDestroy ( pIndexList ) ;
2022-06-29 02:35:07 +00:00
return TSDB_CODE_SUCCESS ;
}
2022-08-21 12:15:53 +00:00
static int32_t doLoadRelatedLastBlock ( SLastBlockReader * pLastBlockReader , STableBlockScanInfo * pBlockScanInfo , STsdbReader * pReader ) {
2022-08-17 16:08:09 +00:00
SArray * pBlocks = pLastBlockReader - > pBlockL ;
SBlockL * pBlock = NULL ;
2022-08-21 12:15:53 +00:00
uint64_t uid = pBlockScanInfo - > uid ;
2022-08-21 13:36:15 +00:00
int32_t totalLastBlocks = ( int32_t ) taosArrayGetSize ( pBlocks ) ;
2022-08-21 12:15:53 +00:00
initMemDataIterator ( pBlockScanInfo , pReader ) ;
2022-08-17 16:08:09 +00:00
2022-08-21 13:36:15 +00:00
// find the correct SBlockL. todo binary search
int32_t index = - 1 ;
for ( int32_t i = 0 ; i < totalLastBlocks ; + + i ) {
2022-08-17 16:08:09 +00:00
SBlockL * p = taosArrayGet ( pBlocks , i ) ;
if ( p - > minUid < = uid & & p - > maxUid > = uid ) {
2022-08-21 13:36:15 +00:00
index = i ;
2022-08-17 16:08:09 +00:00
pBlock = p ;
break ;
}
}
2022-08-21 13:36:15 +00:00
if ( index = = - 1 ) {
pLastBlockReader - > currentBlockIndex = index ;
2022-08-20 12:22:39 +00:00
tBlockDataReset ( & pLastBlockReader - > lastBlockData ) ;
2022-08-17 16:08:09 +00:00
return TSDB_CODE_SUCCESS ;
}
2022-08-21 13:36:15 +00:00
// the required last datablock has already loaded
if ( index = = pLastBlockReader - > currentBlockIndex ) {
return TSDB_CODE_SUCCESS ;
}
2022-08-22 03:57:10 +00:00
int64_t st = taosGetTimestampUs ( ) ;
2022-08-20 11:05:55 +00:00
int32_t code = tBlockDataInit ( & pLastBlockReader - > lastBlockData , pReader - > suid , pReader - > suid ? 0 : uid , pReader - > pSchema ) ;
2022-08-17 16:08:09 +00:00
if ( code ! = TSDB_CODE_SUCCESS ) {
2022-08-20 03:14:00 +00:00
tsdbError ( " %p init block data failed, code:%s %s " , pReader , tstrerror ( code ) , pReader - > idStr ) ;
2022-08-17 16:08:09 +00:00
return code ;
}
code = tsdbReadLastBlock ( pReader - > pFileReader , pBlock , & pLastBlockReader - > lastBlockData ) ;
2022-08-22 03:57:10 +00:00
double el = ( taosGetTimestampUs ( ) - st ) / 1000.0 ;
2022-08-17 16:08:09 +00:00
if ( code ! = TSDB_CODE_SUCCESS ) {
2022-08-21 13:36:15 +00:00
tsdbError ( " %p error occurs in loading last block into buffer, last block index:%d, total:%d code:%s %s " , pReader ,
pLastBlockReader - > currentBlockIndex , totalLastBlocks , tstrerror ( code ) , pReader - > idStr ) ;
} else {
tsdbDebug ( " %p load last block completed, uid:% " PRIu64
2022-08-22 05:26:09 +00:00
" last block index:%d, total:%d rows:%d, minVer:%d, maxVer:%d, brange:% " PRId64 " -% " PRId64
2022-08-22 03:57:10 +00:00
" elapsed time:%.2f ms, %s " ,
2022-08-22 05:26:09 +00:00
pReader , uid , index , totalLastBlocks , pBlock - > nRow , pBlock - > minVer , pBlock - > maxVer , pBlock - > minKey ,
pBlock - > maxKey , el , pReader - > idStr ) ;
2022-08-17 16:08:09 +00:00
}
2022-08-21 13:36:15 +00:00
pLastBlockReader - > currentBlockIndex = index ;
2022-08-22 03:57:10 +00:00
pReader - > cost . lastBlockLoad + = 1 ;
pReader - > cost . lastBlockLoadTime + = el ;
2022-08-17 16:08:09 +00:00
return TSDB_CODE_SUCCESS ;
}
2022-08-25 07:31:48 +00:00
static int32_t uidComparFunc ( const void * p1 , const void * p2 ) {
uint64_t pu1 = * ( uint64_t * ) p1 ;
uint64_t pu2 = * ( uint64_t * ) p2 ;
if ( pu1 = = pu2 ) {
return 0 ;
} else {
2022-08-25 08:34:00 +00:00
return ( pu1 < pu2 ) ? - 1 : 1 ;
2022-08-25 07:31:48 +00:00
}
}
2022-08-25 15:04:07 +00:00
static void extractOrderedTableUidList ( SUidOrderCheckInfo * pOrderCheckInfo , SReaderStatus * pStatus ) {
int32_t index = 0 ;
int32_t total = taosHashGetSize ( pStatus - > pTableMap ) ;
void * p = taosHashIterate ( pStatus - > pTableMap , NULL ) ;
while ( p ! = NULL ) {
STableBlockScanInfo * pScanInfo = p ;
pOrderCheckInfo - > tableUidList [ index + + ] = pScanInfo - > uid ;
p = taosHashIterate ( pStatus - > pTableMap , p ) ;
}
taosSort ( pOrderCheckInfo - > tableUidList , total , sizeof ( uint64_t ) , uidComparFunc ) ;
}
2022-08-25 07:31:48 +00:00
static int32_t initOrderCheckInfo ( SUidOrderCheckInfo * pOrderCheckInfo , SReaderStatus * pStatus ) {
if ( pOrderCheckInfo - > tableUidList = = NULL ) {
int32_t total = taosHashGetSize ( pStatus - > pTableMap ) ;
pOrderCheckInfo - > currentIndex = 0 ;
pOrderCheckInfo - > tableUidList = taosMemoryMalloc ( total * sizeof ( uint64_t ) ) ;
if ( pOrderCheckInfo - > tableUidList = = NULL ) {
return TSDB_CODE_OUT_OF_MEMORY ;
}
2022-08-25 15:04:07 +00:00
extractOrderedTableUidList ( pOrderCheckInfo , pStatus ) ;
2022-08-25 07:31:48 +00:00
uint64_t uid = pOrderCheckInfo - > tableUidList [ 0 ] ;
pStatus - > pTableIter = taosHashGet ( pStatus - > pTableMap , & uid , sizeof ( uid ) ) ;
} else {
2022-08-25 08:06:54 +00:00
if ( pStatus - > pTableIter = = NULL ) { // it is the last block of a new file
2022-08-25 15:04:07 +00:00
// ASSERT(pOrderCheckInfo->currentIndex == taosHashGetSize(pStatus->pTableMap));
2022-08-25 08:06:54 +00:00
pOrderCheckInfo - > currentIndex = 0 ;
2022-08-25 07:31:48 +00:00
uint64_t uid = pOrderCheckInfo - > tableUidList [ pOrderCheckInfo - > currentIndex ] ;
pStatus - > pTableIter = taosHashGet ( pStatus - > pTableMap , & uid , sizeof ( uid ) ) ;
2022-08-25 15:04:07 +00:00
// the tableMap has already updated
if ( pStatus - > pTableIter = = NULL ) {
void * p = taosMemoryRealloc ( pOrderCheckInfo - > tableUidList , taosHashGetSize ( pStatus - > pTableMap ) * sizeof ( uint64_t ) ) ;
if ( p = = NULL ) {
return TSDB_CODE_OUT_OF_MEMORY ;
}
pOrderCheckInfo - > tableUidList = p ;
extractOrderedTableUidList ( pOrderCheckInfo , pStatus ) ;
uid = pOrderCheckInfo - > tableUidList [ 0 ] ;
pStatus - > pTableIter = taosHashGet ( pStatus - > pTableMap , & uid , sizeof ( uid ) ) ;
}
2022-08-25 07:31:48 +00:00
}
}
return TSDB_CODE_SUCCESS ;
}
static bool moveToNextTable ( SUidOrderCheckInfo * pOrderedCheckInfo , SReaderStatus * pStatus ) {
pOrderedCheckInfo - > currentIndex + = 1 ;
if ( pOrderedCheckInfo - > currentIndex > = taosHashGetSize ( pStatus - > pTableMap ) ) {
pStatus - > pTableIter = NULL ;
return false ;
}
uint64_t uid = pOrderedCheckInfo - > tableUidList [ pOrderedCheckInfo - > currentIndex ] ;
pStatus - > pTableIter = taosHashGet ( pStatus - > pTableMap , & uid , sizeof ( uid ) ) ;
ASSERT ( pStatus - > pTableIter ! = NULL ) ;
return true ;
}
2022-08-17 16:08:09 +00:00
static int32_t doLoadLastBlockSequentially ( STsdbReader * pReader ) {
2022-08-18 10:48:50 +00:00
SReaderStatus * pStatus = & pReader - > status ;
2022-08-17 16:08:09 +00:00
SLastBlockReader * pLastBlockReader = pStatus - > fileIter . pLastBlockReader ;
2022-08-25 07:31:48 +00:00
SUidOrderCheckInfo * pOrderedCheckInfo = & pStatus - > uidCheckInfo ;
int32_t code = initOrderCheckInfo ( pOrderedCheckInfo , pStatus ) ;
2022-08-25 09:32:27 +00:00
if ( code ! = TSDB_CODE_SUCCESS | | ( taosHashGetSize ( pStatus - > pTableMap ) = = 0 ) ) {
2022-08-25 07:31:48 +00:00
return code ;
}
2022-08-18 10:48:50 +00:00
2022-08-25 07:31:48 +00:00
while ( 1 ) {
2022-08-18 10:48:50 +00:00
// load the last data block of current table
STableBlockScanInfo * pScanInfo = pStatus - > pTableIter ;
2022-08-25 07:31:48 +00:00
code = doLoadRelatedLastBlock ( pLastBlockReader , pScanInfo , pReader ) ;
2022-08-18 14:42:16 +00:00
if ( code ! = TSDB_CODE_SUCCESS ) {
2022-08-18 10:48:50 +00:00
return code ;
}
2022-08-20 08:57:44 +00:00
if ( pLastBlockReader - > currentBlockIndex ! = - 1 ) {
initLastBlockReader ( pLastBlockReader , pScanInfo - > uid , & pScanInfo - > indexInBlockL ) ;
2022-08-21 07:56:06 +00:00
int32_t index = pScanInfo - > indexInBlockL ;
2022-08-25 07:31:48 +00:00
2022-08-26 07:27:19 +00:00
if ( index = = INITIAL_ROW_INDEX_VAL | | index = = pLastBlockReader - > lastBlockData . nRow ) {
2022-08-21 10:59:21 +00:00
bool hasData = nextRowInLastBlock ( pLastBlockReader , pScanInfo ) ;
2022-08-20 08:57:44 +00:00
if ( ! hasData ) { // current table does not have rows in last block, try next table
2022-08-25 07:31:48 +00:00
bool hasNexTable = moveToNextTable ( pOrderedCheckInfo , pStatus ) ;
if ( ! hasNexTable ) {
2022-08-20 08:57:44 +00:00
return TSDB_CODE_SUCCESS ;
}
continue ;
2022-08-18 10:48:50 +00:00
}
2022-08-17 16:08:09 +00:00
}
2022-08-20 08:57:44 +00:00
} else { // no data in last block, try next table
2022-08-25 07:31:48 +00:00
bool hasNexTable = moveToNextTable ( pOrderedCheckInfo , pStatus ) ;
if ( ! hasNexTable ) {
2022-08-20 08:57:44 +00:00
return TSDB_CODE_SUCCESS ;
}
continue ;
2022-08-17 16:08:09 +00:00
}
2022-08-18 10:48:50 +00:00
code = doBuildDataBlock ( pReader ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
return code ;
}
if ( pReader - > pResBlock - > info . rows > 0 ) {
return TSDB_CODE_SUCCESS ;
}
2022-08-17 16:08:09 +00:00
2022-08-18 10:48:50 +00:00
// current table is exhausted, let's try next table
2022-08-25 07:31:48 +00:00
bool hasNexTable = moveToNextTable ( pOrderedCheckInfo , pStatus ) ;
if ( ! hasNexTable ) {
2022-08-18 10:48:50 +00:00
return TSDB_CODE_SUCCESS ;
}
2022-08-17 16:08:09 +00:00
}
}
2022-06-29 06:18:03 +00:00
static int32_t doBuildDataBlock ( STsdbReader * pReader ) {
2022-08-16 23:51:09 +00:00
TSDBKEY key = { 0 } ;
2022-08-22 03:09:12 +00:00
int32_t code = TSDB_CODE_SUCCESS ;
2022-08-18 10:48:50 +00:00
SBlock * pBlock = NULL ;
2022-08-22 03:09:12 +00:00
SReaderStatus * pStatus = & pReader - > status ;
SDataBlockIter * pBlockIter = & pStatus - > blockIter ;
2022-08-17 16:08:09 +00:00
STableBlockScanInfo * pScanInfo = NULL ;
SFileDataBlockInfo * pBlockInfo = getCurrentBlockInfo ( pBlockIter ) ;
SLastBlockReader * pLastBlockReader = pReader - > status . fileIter . pLastBlockReader ;
2022-06-29 06:18:03 +00:00
2022-08-17 16:08:09 +00:00
if ( pBlockInfo ! = NULL ) {
2022-08-20 03:14:00 +00:00
pScanInfo = taosHashGet ( pReader - > status . pTableMap , & pBlockInfo - > uid , sizeof ( pBlockInfo - > uid ) ) ;
} else {
pScanInfo = pReader - > status . pTableIter ;
}
if ( pBlockInfo ! = NULL ) {
2022-08-16 23:51:09 +00:00
pBlock = getCurrentBlock ( pBlockIter ) ;
2022-08-20 03:14:00 +00:00
}
{
key = getCurrentKeyInBuf ( pScanInfo , pReader ) ;
2022-08-17 16:08:09 +00:00
2022-08-18 10:48:50 +00:00
// load the last data block of current table
2022-08-21 12:15:53 +00:00
code = doLoadRelatedLastBlock ( pLastBlockReader , pScanInfo , pReader ) ;
2022-08-17 16:08:09 +00:00
if ( code ! = TSDB_CODE_SUCCESS ) {
2022-08-18 14:42:16 +00:00
return code ;
2022-08-17 16:08:09 +00:00
}
2022-08-21 10:59:21 +00:00
// note: the lastblock may be null here
2022-08-20 03:14:00 +00:00
initLastBlockReader ( pLastBlockReader , pScanInfo - > uid , & pScanInfo - > indexInBlockL ) ;
2022-08-26 07:27:19 +00:00
if ( pScanInfo - > indexInBlockL = = INITIAL_ROW_INDEX_VAL | | pScanInfo - > indexInBlockL = = pLastBlockReader - > lastBlockData . nRow ) {
2022-08-21 10:59:21 +00:00
bool hasData = nextRowInLastBlock ( pLastBlockReader , pScanInfo ) ;
2022-08-20 03:14:00 +00:00
}
2022-08-16 23:51:09 +00:00
}
2022-06-29 06:18:03 +00:00
2022-08-18 10:48:50 +00:00
if ( pBlockInfo = = NULL ) { // build data block from last data file
ASSERT ( pBlockIter - > numOfBlocks = = 0 ) ;
code = buildComposedDataBlock ( pReader ) ;
} else if ( fileBlockShouldLoad ( pReader , pBlockInfo , pBlock , pScanInfo , key , pLastBlockReader ) ) {
tBlockDataReset ( & pStatus - > fileBlockData ) ;
code = tBlockDataInit ( & pStatus - > fileBlockData , pReader - > suid , pScanInfo - > uid , pReader - > pSchema ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
2022-08-18 14:42:16 +00:00
return code ;
2022-08-18 10:48:50 +00:00
}
2022-08-16 23:51:09 +00:00
2022-08-18 10:48:50 +00:00
code = doLoadFileBlockData ( pReader , pBlockIter , & pStatus - > fileBlockData ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
return code ;
2022-06-29 06:18:03 +00:00
}
// build composed data block
2022-08-16 23:51:09 +00:00
code = buildComposedDataBlock ( pReader ) ;
2022-06-29 06:18:03 +00:00
} else if ( bufferDataInFileBlockGap ( pReader - > order , key , pBlock ) ) {
// data in memory that are earlier than current file block
2022-07-02 15:37:31 +00:00
// todo rows in buffer should be less than the file block in asc, greater than file block in desc
2022-07-04 03:42:50 +00:00
int64_t endKey = ( ASCENDING_TRAVERSE ( pReader - > order ) ) ? pBlock - > minKey . ts : pBlock - > maxKey . ts ;
2022-07-02 15:37:31 +00:00
code = buildDataBlockFromBuf ( pReader , pScanInfo , endKey ) ;
2022-08-22 06:28:13 +00:00
} else {
if ( hasDataInLastBlock ( pLastBlockReader ) & & ! ASCENDING_TRAVERSE ( pReader - > order ) ) {
// only return the rows in last block
int64_t tsLast = getCurrentKeyInLastBlock ( pLastBlockReader ) ;
ASSERT ( tsLast > = pBlock - > maxKey . ts ) ;
tBlockDataReset ( & pReader - > status . fileBlockData ) ;
code = buildComposedDataBlock ( pReader ) ;
} else { // whole block is required, return it directly
SDataBlockInfo * pInfo = & pReader - > pResBlock - > info ;
pInfo - > rows = pBlock - > nRow ;
pInfo - > uid = pScanInfo - > uid ;
pInfo - > window = ( STimeWindow ) { . skey = pBlock - > minKey . ts , . ekey = pBlock - > maxKey . ts } ;
setComposedBlockFlag ( pReader , false ) ;
setBlockAllDumped ( & pStatus - > fBlockDumpInfo , pBlock - > maxKey . ts , pReader - > order ) ;
}
2022-06-29 06:18:03 +00:00
}
return code ;
}
2022-06-29 12:25:03 +00:00
static int32_t buildBlockFromBufferSequentially ( STsdbReader * pReader ) {
2022-06-29 06:18:03 +00:00
SReaderStatus * pStatus = & pReader - > status ;
2022-07-04 03:42:50 +00:00
while ( 1 ) {
2022-06-29 06:18:03 +00:00
if ( pStatus - > pTableIter = = NULL ) {
pStatus - > pTableIter = taosHashIterate ( pStatus - > pTableMap , NULL ) ;
if ( pStatus - > pTableIter = = NULL ) {
2022-06-29 12:25:03 +00:00
return TSDB_CODE_SUCCESS ;
2022-06-29 06:18:03 +00:00
}
}
STableBlockScanInfo * pBlockScanInfo = pStatus - > pTableIter ;
2022-07-04 15:28:27 +00:00
initMemDataIterator ( pBlockScanInfo , pReader ) ;
2022-06-29 06:18:03 +00:00
2022-07-04 03:42:50 +00:00
int64_t endKey = ( ASCENDING_TRAVERSE ( pReader - > order ) ) ? INT64_MAX : INT64_MIN ;
2022-07-02 15:37:31 +00:00
int32_t code = buildDataBlockFromBuf ( pReader , pBlockScanInfo , endKey ) ;
2022-06-29 12:25:03 +00:00
if ( code ! = TSDB_CODE_SUCCESS ) {
return code ;
}
2022-06-29 06:18:03 +00:00
if ( pReader - > pResBlock - > info . rows > 0 ) {
2022-06-29 12:25:03 +00:00
return TSDB_CODE_SUCCESS ;
2022-06-29 06:18:03 +00:00
}
// current table is exhausted, let's try the next table
pStatus - > pTableIter = taosHashIterate ( pStatus - > pTableMap , pStatus - > pTableIter ) ;
if ( pStatus - > pTableIter = = NULL ) {
2022-06-29 12:25:03 +00:00
return TSDB_CODE_SUCCESS ;
2022-06-29 06:18:03 +00:00
}
}
}
2022-07-03 15:00:12 +00:00
// set the correct start position in case of the first/last file block, according to the query time window
2022-06-30 15:38:18 +00:00
static void initBlockDumpInfo ( STsdbReader * pReader , SDataBlockIter * pBlockIter ) {
2022-07-26 02:19:12 +00:00
SBlock * pBlock = getCurrentBlock ( pBlockIter ) ;
2022-06-30 15:38:18 +00:00
2022-07-03 15:00:12 +00:00
SReaderStatus * pStatus = & pReader - > status ;
SFileBlockDumpInfo * pDumpInfo = & pStatus - > fBlockDumpInfo ;
2022-06-30 15:38:18 +00:00
pDumpInfo - > totalRows = pBlock - > nRow ;
pDumpInfo - > allDumped = false ;
2022-07-04 03:42:50 +00:00
pDumpInfo - > rowIndex = ASCENDING_TRAVERSE ( pReader - > order ) ? 0 : pBlock - > nRow - 1 ;
2022-06-30 15:38:18 +00:00
}
2022-07-02 04:05:03 +00:00
static int32_t initForFirstBlockInFile ( STsdbReader * pReader , SDataBlockIter * pBlockIter ) {
2022-08-16 23:51:09 +00:00
SBlockNumber num = { 0 } ;
2022-08-17 16:08:09 +00:00
int32_t code = moveToNextFile ( pReader , & num ) ;
2022-06-30 06:50:59 +00:00
if ( code ! = TSDB_CODE_SUCCESS ) {
return code ;
}
// all data files are consumed, try data in buffer
2022-08-16 23:51:09 +00:00
if ( num . numOfBlocks + num . numOfLastBlocks = = 0 ) {
2022-06-30 06:50:59 +00:00
pReader - > status . loadFromFile = false ;
return code ;
}
// initialize the block iterator for a new fileset
2022-08-17 16:08:09 +00:00
if ( num . numOfBlocks > 0 ) {
code = initBlockIterator ( pReader , pBlockIter , num . numOfBlocks ) ;
2022-08-22 03:57:10 +00:00
} else { // no block data, only last block exists
2022-08-20 08:57:44 +00:00
tBlockDataReset ( & pReader - > status . fileBlockData ) ;
2022-08-26 07:27:19 +00:00
resetDataBlockIterator ( pBlockIter , pReader - > order ) ;
2022-08-17 16:08:09 +00:00
}
2022-07-03 15:00:12 +00:00
2022-08-21 14:17:12 +00:00
SLastBlockReader * pLReader = pReader - > status . fileIter . pLastBlockReader ;
pLReader - > currentBlockIndex = - 1 ;
2022-07-03 15:00:12 +00:00
// set the correct start position according to the query time window
2022-06-30 15:38:18 +00:00
initBlockDumpInfo ( pReader , pBlockIter ) ;
2022-06-30 06:50:59 +00:00
return code ;
}
2022-07-03 15:00:12 +00:00
static bool fileBlockPartiallyRead ( SFileBlockDumpInfo * pDumpInfo , bool asc ) {
2022-07-04 03:42:50 +00:00
return ( ! pDumpInfo - > allDumped ) & &
( ( pDumpInfo - > rowIndex > 0 & & asc ) | | ( pDumpInfo - > rowIndex < ( pDumpInfo - > totalRows - 1 ) & & ( ! asc ) ) ) ;
2022-07-03 15:00:12 +00:00
}
2022-06-29 09:14:00 +00:00
static int32_t buildBlockFromFiles ( STsdbReader * pReader ) {
2022-06-29 12:25:03 +00:00
int32_t code = TSDB_CODE_SUCCESS ;
2022-07-03 15:00:12 +00:00
bool asc = ASCENDING_TRAVERSE ( pReader - > order ) ;
2022-06-28 02:32:42 +00:00
SDataBlockIter * pBlockIter = & pReader - > status . blockIter ;
2022-08-17 16:08:09 +00:00
if ( pBlockIter - > numOfBlocks = = 0 ) {
_begin :
code = doLoadLastBlockSequentially ( pReader ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
return code ;
}
2022-08-18 14:42:16 +00:00
if ( pReader - > pResBlock - > info . rows > 0 ) {
return TSDB_CODE_SUCCESS ;
}
2022-08-18 10:48:50 +00:00
// all data blocks are checked in this last block file, now let's try the next file
2022-08-17 16:08:09 +00:00
if ( pReader - > status . pTableIter = = NULL ) {
code = initForFirstBlockInFile ( pReader , pBlockIter ) ;
// error happens or all the data files are completely checked
if ( ( code ! = TSDB_CODE_SUCCESS ) | | ( pReader - > status . loadFromFile = = false ) ) {
return code ;
}
2022-08-18 10:48:50 +00:00
// this file does not have data files, let's start check the last block file if exists
2022-08-17 16:08:09 +00:00
if ( pBlockIter - > numOfBlocks = = 0 ) {
goto _begin ;
}
}
code = doBuildDataBlock ( pReader ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
return code ;
}
if ( pReader - > pResBlock - > info . rows > 0 ) {
return TSDB_CODE_SUCCESS ;
}
}
2022-07-03 15:00:12 +00:00
while ( 1 ) {
2022-07-02 15:37:31 +00:00
SFileBlockDumpInfo * pDumpInfo = & pReader - > status . fBlockDumpInfo ;
2022-07-04 03:42:50 +00:00
if ( fileBlockPartiallyRead ( pDumpInfo , asc ) ) { // file data block is partially loaded
2022-08-16 23:51:09 +00:00
code = buildComposedDataBlock ( pReader ) ;
2022-07-03 15:00:12 +00:00
} else {
// current block are exhausted, try the next file block
if ( pDumpInfo - > allDumped ) {
// try next data block in current file
bool hasNext = blockIteratorNext ( & pReader - > status . blockIter ) ;
if ( hasNext ) { // check for the next block in the block accessed order list
initBlockDumpInfo ( pReader , pBlockIter ) ;
2022-08-17 16:08:09 +00:00
} else if ( taosArrayGetSize ( pReader - > status . fileIter . pLastBlockReader - > pBlockL ) > 0 ) { // data blocks in current file are exhausted, let's try the next file now
tBlockDataReset ( & pReader - > status . fileBlockData ) ;
2022-08-26 07:27:19 +00:00
resetDataBlockIterator ( pBlockIter , pReader - > order ) ;
2022-08-17 16:08:09 +00:00
goto _begin ;
} else {
2022-07-03 15:00:12 +00:00
code = initForFirstBlockInFile ( pReader , pBlockIter ) ;
// error happens or all the data files are completely checked
if ( ( code ! = TSDB_CODE_SUCCESS ) | | ( pReader - > status . loadFromFile = = false ) ) {
return code ;
}
2022-08-17 16:08:09 +00:00
// this file does not have blocks, let's start check the last block file
if ( pBlockIter - > numOfBlocks = = 0 ) {
goto _begin ;
}
2022-06-30 06:50:59 +00:00
}
2022-06-27 02:46:20 +00:00
}
2022-07-03 15:00:12 +00:00
code = doBuildDataBlock ( pReader ) ;
2022-06-28 02:32:42 +00:00
}
2022-07-03 15:00:12 +00:00
if ( code ! = TSDB_CODE_SUCCESS ) {
return code ;
}
if ( pReader - > pResBlock - > info . rows > 0 ) {
return TSDB_CODE_SUCCESS ;
}
}
2022-06-28 02:32:42 +00:00
}
2022-06-16 11:14:56 +00:00
2022-07-05 11:30:37 +00:00
static STsdb * getTsdbByRetentions ( SVnode * pVnode , TSKEY winSKey , SRetention * retentions , const char * idStr ,
int8_t * pLevel ) {
2022-07-05 05:57:07 +00:00
if ( VND_IS_RSMA ( pVnode ) ) {
2022-07-05 11:30:37 +00:00
int8_t level = 0 ;
2022-07-05 05:57:07 +00:00
int64_t now = taosGetTimestamp ( pVnode - > config . tsdbCfg . precision ) ;
2022-07-05 11:30:37 +00:00
for ( int8_t i = 0 ; i < TSDB_RETENTION_MAX ; + + i ) {
2022-07-05 05:57:07 +00:00
SRetention * pRetention = retentions + level ;
if ( pRetention - > keep < = 0 ) {
if ( level > 0 ) {
- - level ;
}
break ;
}
if ( ( now - pRetention - > keep ) < = winSKey ) {
break ;
}
+ + level ;
}
2022-07-05 11:30:37 +00:00
const char * str = ( idStr ! = NULL ) ? idStr : " " ;
2022-07-05 05:57:07 +00:00
if ( level = = TSDB_RETENTION_L0 ) {
2022-07-05 11:30:37 +00:00
* pLevel = TSDB_RETENTION_L0 ;
2022-08-03 06:33:29 +00:00
tsdbDebug ( " vgId:%d, rsma level %d is selected to query %s " , TD_VID ( pVnode ) , TSDB_RETENTION_L0 , str ) ;
2022-07-05 05:57:07 +00:00
return VND_RSMA0 ( pVnode ) ;
} else if ( level = = TSDB_RETENTION_L1 ) {
2022-07-05 11:30:37 +00:00
* pLevel = TSDB_RETENTION_L1 ;
2022-08-03 06:33:29 +00:00
tsdbDebug ( " vgId:%d, rsma level %d is selected to query %s " , TD_VID ( pVnode ) , TSDB_RETENTION_L1 , str ) ;
2022-07-05 05:57:07 +00:00
return VND_RSMA1 ( pVnode ) ;
} else {
2022-07-05 11:30:37 +00:00
* pLevel = TSDB_RETENTION_L2 ;
2022-08-03 06:33:29 +00:00
tsdbDebug ( " vgId:%d, rsma level %d is selected to query %s " , TD_VID ( pVnode ) , TSDB_RETENTION_L2 , str ) ;
2022-07-05 05:57:07 +00:00
return VND_RSMA2 ( pVnode ) ;
}
}
return VND_TSDB ( pVnode ) ;
}
2022-07-08 09:28:37 +00:00
SVersionRange getQueryVerRange ( SVnode * pVnode , SQueryTableDataCond * pCond , int8_t level ) {
2022-07-12 09:28:14 +00:00
int64_t startVer = ( pCond - > startVersion = = - 1 ) ? 0 : pCond - > startVersion ;
2022-07-08 09:28:37 +00:00
int64_t endVer = 0 ;
2022-07-12 09:28:14 +00:00
if ( pCond - > endVersion = =
- 1 ) { // user not specified end version, set current maximum version of vnode as the endVersion
2022-07-08 09:28:37 +00:00
endVer = pVnode - > state . applied ;
} else {
2022-07-12 09:28:14 +00:00
endVer = ( pCond - > endVersion > pVnode - > state . applied ) ? pVnode - > state . applied : pCond - > endVersion ;
2022-07-05 11:30:37 +00:00
}
2022-07-08 09:28:37 +00:00
return ( SVersionRange ) { . minVer = startVer , . maxVer = endVer } ;
2022-07-05 11:30:37 +00:00
}
2022-07-08 03:02:12 +00:00
bool hasBeenDropped ( const SArray * pDelList , int32_t * index , TSDBKEY * pKey , int32_t order ) {
2022-07-04 15:28:27 +00:00
ASSERT ( pKey ! = NULL ) ;
if ( pDelList = = NULL ) {
return false ;
}
2022-07-12 09:28:14 +00:00
size_t num = taosArrayGetSize ( pDelList ) ;
bool asc = ASCENDING_TRAVERSE ( order ) ;
int32_t step = asc ? 1 : - 1 ;
2022-07-04 15:28:27 +00:00
2022-07-08 03:02:12 +00:00
if ( asc ) {
if ( * index > = num - 1 ) {
TSDBKEY * last = taosArrayGetLast ( pDelList ) ;
ASSERT ( pKey - > ts > = last - > ts ) ;
if ( pKey - > ts > last - > ts ) {
2022-07-04 15:28:27 +00:00
return false ;
2022-07-08 03:02:12 +00:00
} else if ( pKey - > ts = = last - > ts ) {
TSDBKEY * prev = taosArrayGet ( pDelList , num - 2 ) ;
return ( prev - > version > = pKey - > version ) ;
2022-07-04 15:28:27 +00:00
}
} else {
2022-07-08 03:02:12 +00:00
TSDBKEY * pCurrent = taosArrayGet ( pDelList , * index ) ;
TSDBKEY * pNext = taosArrayGet ( pDelList , ( * index ) + 1 ) ;
if ( pKey - > ts < pCurrent - > ts ) {
return false ;
}
if ( pCurrent - > ts < = pKey - > ts & & pNext - > ts > = pKey - > ts & & pCurrent - > version > = pKey - > version ) {
return true ;
}
while ( pNext - > ts < = pKey - > ts & & ( * index ) < num - 1 ) {
( * index ) + = 1 ;
if ( ( * index ) < num - 1 ) {
pCurrent = taosArrayGet ( pDelList , * index ) ;
pNext = taosArrayGet ( pDelList , ( * index ) + 1 ) ;
// it is not a consecutive deletion range, ignore it
if ( pCurrent - > version = = 0 & & pNext - > version > 0 ) {
continue ;
}
if ( pCurrent - > ts < = pKey - > ts & & pNext - > ts > = pKey - > ts & & pCurrent - > version > = pKey - > version ) {
return true ;
}
}
}
return false ;
2022-07-04 15:28:27 +00:00
}
} else {
2022-07-08 03:02:12 +00:00
if ( * index < = 0 ) {
TSDBKEY * pFirst = taosArrayGet ( pDelList , 0 ) ;
2022-07-04 15:28:27 +00:00
2022-07-08 03:02:12 +00:00
if ( pKey - > ts < pFirst - > ts ) {
return false ;
} else if ( pKey - > ts = = pFirst - > ts ) {
return pFirst - > version > = pKey - > version ;
} else {
ASSERT ( 0 ) ;
}
2022-07-04 15:28:27 +00:00
} else {
2022-07-08 03:02:12 +00:00
TSDBKEY * pCurrent = taosArrayGet ( pDelList , * index ) ;
TSDBKEY * pPrev = taosArrayGet ( pDelList , ( * index ) - 1 ) ;
if ( pKey - > ts > pCurrent - > ts ) {
return false ;
}
if ( pPrev - > ts < = pKey - > ts & & pCurrent - > ts > = pKey - > ts & & pPrev - > version > = pKey - > version ) {
return true ;
}
while ( pPrev - > ts > = pKey - > ts & & ( * index ) > 1 ) {
( * index ) + = step ;
if ( ( * index ) > = 1 ) {
pCurrent = taosArrayGet ( pDelList , * index ) ;
pPrev = taosArrayGet ( pDelList , ( * index ) - 1 ) ;
// it is not a consecutive deletion range, ignore it
if ( pCurrent - > version > 0 & & pPrev - > version = = 0 ) {
continue ;
}
if ( pPrev - > ts < = pKey - > ts & & pCurrent - > ts > = pKey - > ts & & pPrev - > version > = pKey - > version ) {
return true ;
}
}
2022-07-04 15:28:27 +00:00
}
return false ;
}
}
2022-07-08 03:02:12 +00:00
return false ;
2022-07-04 15:28:27 +00:00
}
2022-08-24 09:09:33 +00:00
TSDBROW * getValidMemRow ( SIterInfo * pIter , const SArray * pDelList , STsdbReader * pReader ) {
2022-07-04 15:28:27 +00:00
if ( ! pIter - > hasVal ) {
2022-06-27 02:46:20 +00:00
return NULL ;
}
2022-06-16 11:32:05 +00:00
2022-07-04 15:28:27 +00:00
TSDBROW * pRow = tsdbTbDataIterGet ( pIter - > iter ) ;
2022-08-11 10:19:44 +00:00
TSDBKEY key = { . ts = pRow - > pTSRow - > ts , . version = pRow - > version } ;
2022-07-03 15:00:12 +00:00
if ( outOfTimeWindow ( key . ts , & pReader - > window ) ) {
2022-07-04 15:28:27 +00:00
pIter - > hasVal = false ;
2022-06-27 02:46:20 +00:00
return NULL ;
}
2022-06-16 11:32:05 +00:00
2022-07-04 15:28:27 +00:00
// it is a valid data version
2022-07-06 10:29:11 +00:00
if ( ( key . version < = pReader - > verRange . maxVer & & key . version > = pReader - > verRange . minVer ) & &
2022-07-08 03:02:12 +00:00
( ! hasBeenDropped ( pDelList , & pIter - > index , & key , pReader - > order ) ) ) {
2022-06-27 02:46:20 +00:00
return pRow ;
}
2022-06-16 11:32:05 +00:00
2022-07-04 03:42:50 +00:00
while ( 1 ) {
2022-07-04 15:28:27 +00:00
pIter - > hasVal = tsdbTbDataIterNext ( pIter - > iter ) ;
if ( ! pIter - > hasVal ) {
2022-06-27 02:46:20 +00:00
return NULL ;
}
2022-06-16 11:32:05 +00:00
2022-07-04 15:28:27 +00:00
pRow = tsdbTbDataIterGet ( pIter - > iter ) ;
2022-06-16 11:32:05 +00:00
2022-06-27 02:46:20 +00:00
key = TSDBROW_KEY ( pRow ) ;
2022-07-03 15:00:12 +00:00
if ( outOfTimeWindow ( key . ts , & pReader - > window ) ) {
2022-07-04 15:28:27 +00:00
pIter - > hasVal = false ;
2022-06-27 02:46:20 +00:00
return NULL ;
}
2022-06-16 11:32:05 +00:00
2022-07-06 10:29:11 +00:00
if ( key . version < = pReader - > verRange . maxVer & & key . version > = pReader - > verRange . minVer & &
2022-07-08 03:02:12 +00:00
( ! hasBeenDropped ( pDelList , & pIter - > index , & key , pReader - > order ) ) ) {
2022-06-27 02:46:20 +00:00
return pRow ;
}
}
}
2022-06-16 11:32:05 +00:00
2022-07-30 04:46:40 +00:00
int32_t doMergeRowsInBuf ( SIterInfo * pIter , uint64_t uid , int64_t ts , SArray * pDelList , SRowMerger * pMerger ,
STsdbReader * pReader ) {
2022-06-27 02:46:20 +00:00
while ( 1 ) {
2022-07-04 15:28:27 +00:00
pIter - > hasVal = tsdbTbDataIterNext ( pIter - > iter ) ;
if ( ! pIter - > hasVal ) {
2022-06-27 02:46:20 +00:00
break ;
}
2022-06-16 11:32:05 +00:00
2022-07-03 15:00:12 +00:00
// data exists but not valid
2022-08-24 09:09:33 +00:00
TSDBROW * pRow = getValidMemRow ( pIter , pDelList , pReader ) ;
2022-07-03 15:00:12 +00:00
if ( pRow = = NULL ) {
break ;
}
// ts is not identical, quit
2022-06-27 02:46:20 +00:00
TSDBKEY k = TSDBROW_KEY ( pRow ) ;
2022-06-30 15:38:18 +00:00
if ( k . ts ! = ts ) {
2022-06-27 02:46:20 +00:00
break ;
}
2022-08-09 02:16:00 +00:00
STSchema * pTSchema = doGetSchemaForTSRow ( TSDBROW_SVERSION ( pRow ) , pReader , uid ) ;
2022-07-30 04:46:40 +00:00
tRowMergerAdd ( pMerger , pRow , pTSchema ) ;
2022-06-27 02:46:20 +00:00
}
return TSDB_CODE_SUCCESS ;
}
2022-07-02 04:05:03 +00:00
static int32_t doMergeRowsInFileBlockImpl ( SBlockData * pBlockData , int32_t rowIndex , int64_t key , SRowMerger * pMerger ,
2022-07-04 03:42:50 +00:00
SVersionRange * pVerRange , int32_t step ) {
2022-07-02 04:05:03 +00:00
while ( pBlockData - > aTSKEY [ rowIndex ] = = key & & rowIndex < pBlockData - > nRow & & rowIndex > = 0 ) {
if ( pBlockData - > aVersion [ rowIndex ] > pVerRange - > maxVer | | pBlockData - > aVersion [ rowIndex ] < pVerRange - > minVer ) {
2022-07-12 09:44:10 +00:00
rowIndex + = step ;
2022-07-02 04:05:03 +00:00
continue ;
}
TSDBROW fRow = tsdbRowFromBlockData ( pBlockData , rowIndex ) ;
tRowMerge ( pMerger , & fRow ) ;
rowIndex + = step ;
}
return rowIndex ;
}
typedef enum {
CHECK_FILEBLOCK_CONT = 0x1 ,
CHECK_FILEBLOCK_QUIT = 0x2 ,
} CHECK_FILEBLOCK_STATE ;
static int32_t checkForNeighborFileBlock ( STsdbReader * pReader , STableBlockScanInfo * pScanInfo , SBlock * pBlock ,
2022-07-04 03:42:50 +00:00
SFileDataBlockInfo * pFBlock , SRowMerger * pMerger , int64_t key ,
CHECK_FILEBLOCK_STATE * state ) {
2022-07-02 04:05:03 +00:00
SFileBlockDumpInfo * pDumpInfo = & pReader - > status . fBlockDumpInfo ;
2022-07-04 03:42:50 +00:00
SBlockData * pBlockData = & pReader - > status . fileBlockData ;
2022-07-02 04:05:03 +00:00
2022-07-05 09:02:21 +00:00
* state = CHECK_FILEBLOCK_QUIT ;
2022-07-04 03:42:50 +00:00
int32_t step = ASCENDING_TRAVERSE ( pReader - > order ) ? 1 : - 1 ;
2022-07-02 04:05:03 +00:00
int32_t nextIndex = - 1 ;
SBlock * pNeighborBlock = getNeighborBlockOfSameTable ( pFBlock , pScanInfo , & nextIndex , pReader - > order ) ;
2022-07-04 03:42:50 +00:00
if ( pNeighborBlock = = NULL ) { // do nothing
2022-07-02 04:05:03 +00:00
return 0 ;
}
bool overlap = overlapWithNeighborBlock ( pBlock , pNeighborBlock , pReader - > order ) ;
2022-07-26 02:19:12 +00:00
taosMemoryFree ( pNeighborBlock ) ;
2022-07-02 04:05:03 +00:00
if ( overlap ) { // load next block
2022-07-04 03:42:50 +00:00
SReaderStatus * pStatus = & pReader - > status ;
2022-07-02 04:05:03 +00:00
SDataBlockIter * pBlockIter = & pStatus - > blockIter ;
2022-07-04 03:42:50 +00:00
// 1. find the next neighbor block in the scan block list
2022-07-02 04:05:03 +00:00
SFileDataBlockInfo fb = { . uid = pFBlock - > uid , . tbBlockIdx = nextIndex } ;
2022-07-04 03:42:50 +00:00
int32_t neighborIndex = findFileBlockInfoIndex ( pBlockIter , & fb ) ;
2022-07-02 04:05:03 +00:00
2022-07-04 03:42:50 +00:00
// 2. remove it from the scan block list
2022-07-02 06:17:27 +00:00
setFileBlockActiveInBlockIter ( pBlockIter , neighborIndex , step ) ;
2022-07-02 04:05:03 +00:00
2022-07-04 03:42:50 +00:00
// 3. load the neighbor block, and set it to be the currently accessed file data block
2022-07-26 12:40:39 +00:00
tBlockDataReset ( & pStatus - > fileBlockData ) ;
2022-08-22 09:43:55 +00:00
int32_t code = tBlockDataInit ( & pStatus - > fileBlockData , pReader - > suid , pFBlock - > uid , pReader - > pSchema ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
return code ;
}
code = doLoadFileBlockData ( pReader , pBlockIter , & pStatus - > fileBlockData ) ;
2022-07-02 04:05:03 +00:00
if ( code ! = TSDB_CODE_SUCCESS ) {
return code ;
}
2022-07-04 03:42:50 +00:00
// 4. check the data values
2022-07-02 04:05:03 +00:00
initBlockDumpInfo ( pReader , pBlockIter ) ;
pDumpInfo - > rowIndex =
doMergeRowsInFileBlockImpl ( pBlockData , pDumpInfo - > rowIndex , key , pMerger , & pReader - > verRange , step ) ;
2022-07-21 07:47:22 +00:00
if ( pDumpInfo - > rowIndex > = pDumpInfo - > totalRows ) {
2022-07-02 04:05:03 +00:00
* state = CHECK_FILEBLOCK_CONT ;
}
}
return TSDB_CODE_SUCCESS ;
}
2022-07-04 03:42:50 +00:00
int32_t doMergeRowsInFileBlocks ( SBlockData * pBlockData , STableBlockScanInfo * pScanInfo , STsdbReader * pReader ,
SRowMerger * pMerger ) {
2022-06-28 02:32:42 +00:00
SFileBlockDumpInfo * pDumpInfo = & pReader - > status . fBlockDumpInfo ;
2022-07-02 04:05:03 +00:00
bool asc = ASCENDING_TRAVERSE ( pReader - > order ) ;
2022-06-28 02:32:42 +00:00
int64_t key = pBlockData - > aTSKEY [ pDumpInfo - > rowIndex ] ;
2022-07-02 06:17:27 +00:00
int32_t step = asc ? 1 : - 1 ;
2022-06-28 02:32:42 +00:00
2022-07-02 12:39:23 +00:00
pDumpInfo - > rowIndex + = step ;
2022-08-02 04:56:33 +00:00
if ( ( pDumpInfo - > rowIndex < = pBlockData - > nRow - 1 & & asc ) | | ( pDumpInfo - > rowIndex > = 0 & & ! asc ) ) {
2022-07-02 12:39:23 +00:00
pDumpInfo - > rowIndex =
doMergeRowsInFileBlockImpl ( pBlockData , pDumpInfo - > rowIndex , key , pMerger , & pReader - > verRange , step ) ;
}
2022-06-28 02:32:42 +00:00
2022-07-02 12:39:23 +00:00
// all rows are consumed, let's try next file block
if ( ( pDumpInfo - > rowIndex > = pBlockData - > nRow & & asc ) | | ( pDumpInfo - > rowIndex < 0 & & ! asc ) ) {
while ( 1 ) {
CHECK_FILEBLOCK_STATE st ;
2022-07-02 06:17:27 +00:00
2022-07-02 12:39:23 +00:00
SFileDataBlockInfo * pFileBlockInfo = getCurrentBlockInfo ( & pReader - > status . blockIter ) ;
2022-07-29 10:15:44 +00:00
SBlock * pCurrentBlock = getCurrentBlock ( & pReader - > status . blockIter ) ;
2022-07-02 12:39:23 +00:00
checkForNeighborFileBlock ( pReader , pScanInfo , pCurrentBlock , pFileBlockInfo , pMerger , key , & st ) ;
if ( st = = CHECK_FILEBLOCK_QUIT ) {
break ;
2022-07-01 07:19:02 +00:00
}
2022-06-28 02:32:42 +00:00
}
2022-06-27 02:46:20 +00:00
}
2022-06-28 02:32:42 +00:00
2022-06-27 02:46:20 +00:00
return TSDB_CODE_SUCCESS ;
}
2022-08-21 10:59:21 +00:00
int32_t doMergeRowsInLastBlock ( SLastBlockReader * pLastBlockReader , STableBlockScanInfo * pScanInfo , int64_t ts , SRowMerger * pMerger ) {
while ( nextRowInLastBlock ( pLastBlockReader , pScanInfo ) ) {
2022-08-17 16:08:09 +00:00
int64_t next1 = getCurrentKeyInLastBlock ( pLastBlockReader ) ;
if ( next1 = = ts ) {
2022-08-18 10:48:50 +00:00
TSDBROW fRow1 = tsdbRowFromBlockData ( & pLastBlockReader - > lastBlockData , * pLastBlockReader - > rowIndex ) ;
2022-08-17 16:08:09 +00:00
tRowMerge ( pMerger , & fRow1 ) ;
} else {
break ;
}
}
return TSDB_CODE_SUCCESS ;
}
2022-08-23 09:28:08 +00:00
void doMergeMemTableMultiRows ( TSDBROW * pRow , uint64_t uid , SIterInfo * pIter , SArray * pDelList , STSRow * * pTSRow ,
2022-08-03 06:08:03 +00:00
STsdbReader * pReader , bool * freeTSRow ) {
2022-08-09 02:16:00 +00:00
TSDBROW * pNextRow = NULL ;
2022-08-11 10:19:44 +00:00
TSDBROW current = * pRow ;
2022-06-30 06:50:59 +00:00
2022-08-03 06:08:03 +00:00
{ // if the timestamp of the next valid row has a different ts, return current row directly
pIter - > hasVal = tsdbTbDataIterNext ( pIter - > iter ) ;
2022-07-02 04:05:03 +00:00
2022-08-03 06:08:03 +00:00
if ( ! pIter - > hasVal ) {
* pTSRow = current . pTSRow ;
* freeTSRow = false ;
return ;
} else { // has next point in mem/imem
2022-08-24 09:09:33 +00:00
pNextRow = getValidMemRow ( pIter , pDelList , pReader ) ;
2022-08-05 08:10:45 +00:00
if ( pNextRow = = NULL ) {
* pTSRow = current . pTSRow ;
* freeTSRow = false ;
return ;
}
2022-08-09 02:16:00 +00:00
if ( current . pTSRow - > ts ! = pNextRow - > pTSRow - > ts ) {
2022-08-03 06:08:03 +00:00
* pTSRow = current . pTSRow ;
* freeTSRow = false ;
return ;
}
2022-08-02 04:56:33 +00:00
}
2022-06-30 06:50:59 +00:00
}
2022-07-02 04:05:03 +00:00
SRowMerger merge = { 0 } ;
2022-08-03 06:08:03 +00:00
// get the correct schema for data in memory
2022-08-09 02:16:00 +00:00
STSchema * pTSchema = doGetSchemaForTSRow ( TSDBROW_SVERSION ( & current ) , pReader , uid ) ;
2022-06-27 02:46:20 +00:00
2022-08-11 10:19:44 +00:00
if ( pReader - > pSchema = = NULL ) {
pReader - > pSchema = pTSchema ;
2022-07-30 04:46:40 +00:00
}
2022-06-27 02:46:20 +00:00
2022-08-09 02:16:00 +00:00
tRowMergerInit2 ( & merge , pReader - > pSchema , & current , pTSchema ) ;
STSchema * pTSchema1 = doGetSchemaForTSRow ( TSDBROW_SVERSION ( pNextRow ) , pReader , uid ) ;
tRowMergerAdd ( & merge , pNextRow , pTSchema1 ) ;
doMergeRowsInBuf ( pIter , uid , current . pTSRow - > ts , pDelList , & merge , pReader ) ;
2022-07-02 04:05:03 +00:00
tRowMergerGetRow ( & merge , pTSRow ) ;
2022-07-10 09:34:21 +00:00
tRowMergerClear ( & merge ) ;
2022-07-30 07:23:28 +00:00
2022-08-03 06:08:03 +00:00
* freeTSRow = true ;
2022-07-02 04:05:03 +00:00
}
2022-07-04 03:42:50 +00:00
void doMergeMemIMemRows ( TSDBROW * pRow , TSDBROW * piRow , STableBlockScanInfo * pBlockScanInfo , STsdbReader * pReader ,
STSRow * * pTSRow ) {
2022-06-27 02:46:20 +00:00
SRowMerger merge = { 0 } ;
2022-07-02 04:05:03 +00:00
TSDBKEY k = TSDBROW_KEY ( pRow ) ;
TSDBKEY ik = TSDBROW_KEY ( piRow ) ;
2022-07-02 12:39:23 +00:00
if ( ASCENDING_TRAVERSE ( pReader - > order ) ) { // ascending order imem --> mem
2022-08-09 02:16:00 +00:00
STSchema * pSchema = doGetSchemaForTSRow ( TSDBROW_SVERSION ( pRow ) , pReader , pBlockScanInfo - > uid ) ;
2022-07-02 12:39:23 +00:00
2022-08-09 02:16:00 +00:00
tRowMergerInit ( & merge , piRow , pSchema ) ;
2022-07-30 04:46:40 +00:00
doMergeRowsInBuf ( & pBlockScanInfo - > iiter , pBlockScanInfo - > uid , ik . ts , pBlockScanInfo - > delSkyline , & merge , pReader ) ;
2022-07-02 04:05:03 +00:00
2022-07-02 12:39:23 +00:00
tRowMerge ( & merge , pRow ) ;
2022-07-30 04:46:40 +00:00
doMergeRowsInBuf ( & pBlockScanInfo - > iter , pBlockScanInfo - > uid , k . ts , pBlockScanInfo - > delSkyline , & merge , pReader ) ;
2022-07-02 12:39:23 +00:00
} else {
2022-08-09 02:16:00 +00:00
STSchema * pSchema = doGetSchemaForTSRow ( TSDBROW_SVERSION ( pRow ) , pReader , pBlockScanInfo - > uid ) ;
2022-07-02 04:05:03 +00:00
2022-08-09 02:16:00 +00:00
tRowMergerInit ( & merge , pRow , pSchema ) ;
2022-07-30 04:46:40 +00:00
doMergeRowsInBuf ( & pBlockScanInfo - > iter , pBlockScanInfo - > uid , k . ts , pBlockScanInfo - > delSkyline , & merge , pReader ) ;
2022-07-02 12:39:23 +00:00
tRowMerge ( & merge , piRow ) ;
2022-07-30 04:46:40 +00:00
doMergeRowsInBuf ( & pBlockScanInfo - > iiter , pBlockScanInfo - > uid , k . ts , pBlockScanInfo - > delSkyline , & merge , pReader ) ;
2022-07-02 12:39:23 +00:00
}
2022-07-02 04:05:03 +00:00
tRowMergerGetRow ( & merge , pTSRow ) ;
}
2022-08-11 10:19:44 +00:00
int32_t tsdbGetNextRowInMem ( STableBlockScanInfo * pBlockScanInfo , STsdbReader * pReader , STSRow * * pTSRow , int64_t endKey ,
bool * freeTSRow ) {
2022-08-24 09:09:33 +00:00
TSDBROW * pRow = getValidMemRow ( & pBlockScanInfo - > iter , pBlockScanInfo - > delSkyline , pReader ) ;
TSDBROW * piRow = getValidMemRow ( & pBlockScanInfo - > iiter , pBlockScanInfo - > delSkyline , pReader ) ;
2022-07-06 10:29:11 +00:00
SArray * pDelList = pBlockScanInfo - > delSkyline ;
2022-08-23 09:28:08 +00:00
uint64_t uid = pBlockScanInfo - > uid ;
2022-06-27 02:46:20 +00:00
2022-07-02 15:37:31 +00:00
// todo refactor
bool asc = ASCENDING_TRAVERSE ( pReader - > order ) ;
2022-07-04 15:28:27 +00:00
if ( pBlockScanInfo - > iter . hasVal ) {
2022-07-02 15:37:31 +00:00
TSDBKEY k = TSDBROW_KEY ( pRow ) ;
if ( ( k . ts > = endKey & & asc ) | | ( k . ts < = endKey & & ! asc ) ) {
pRow = NULL ;
}
}
2022-07-04 15:28:27 +00:00
if ( pBlockScanInfo - > iiter . hasVal ) {
2022-07-02 15:37:31 +00:00
TSDBKEY k = TSDBROW_KEY ( piRow ) ;
if ( ( k . ts > = endKey & & asc ) | | ( k . ts < = endKey & & ! asc ) ) {
piRow = NULL ;
}
}
2022-07-04 15:28:27 +00:00
if ( pBlockScanInfo - > iter . hasVal & & pBlockScanInfo - > iiter . hasVal & & pRow ! = NULL & & piRow ! = NULL ) {
2022-07-04 03:42:50 +00:00
TSDBKEY k = TSDBROW_KEY ( pRow ) ;
2022-07-02 12:39:23 +00:00
TSDBKEY ik = TSDBROW_KEY ( piRow ) ;
2022-06-27 02:46:20 +00:00
2022-08-23 11:44:59 +00:00
if ( ik . ts ! = k . ts ) {
if ( ( ( ik . ts < k . ts ) & & asc ) | | ( ( ik . ts > k . ts ) & & ( ! asc ) ) ) { // ik.ts < k.ts
doMergeMemTableMultiRows ( piRow , uid , & pBlockScanInfo - > iiter , pDelList , pTSRow , pReader , freeTSRow ) ;
} else if ( ( ( k . ts < ik . ts ) & & asc ) | | ( ( k . ts > ik . ts ) & & ( ! asc ) ) ) {
doMergeMemTableMultiRows ( pRow , uid , & pBlockScanInfo - > iter , pDelList , pTSRow , pReader , freeTSRow ) ;
}
2022-07-02 12:39:23 +00:00
} else { // ik.ts == k.ts
doMergeMemIMemRows ( pRow , piRow , pBlockScanInfo , pReader , pTSRow ) ;
2022-08-03 06:08:03 +00:00
* freeTSRow = true ;
2022-06-27 02:46:20 +00:00
}
2022-07-02 12:39:23 +00:00
return TSDB_CODE_SUCCESS ;
2022-06-27 02:46:20 +00:00
}
2022-07-04 15:28:27 +00:00
if ( pBlockScanInfo - > iter . hasVal & & pRow ! = NULL ) {
2022-08-23 09:28:08 +00:00
doMergeMemTableMultiRows ( pRow , pBlockScanInfo - > uid , & pBlockScanInfo - > iter , pDelList , pTSRow , pReader , freeTSRow ) ;
2022-06-27 02:46:20 +00:00
return TSDB_CODE_SUCCESS ;
}
2022-07-04 15:28:27 +00:00
if ( pBlockScanInfo - > iiter . hasVal & & piRow ! = NULL ) {
2022-08-23 09:28:08 +00:00
doMergeMemTableMultiRows ( piRow , uid , & pBlockScanInfo - > iiter , pDelList , pTSRow , pReader , freeTSRow ) ;
2022-06-27 02:46:20 +00:00
return TSDB_CODE_SUCCESS ;
}
return TSDB_CODE_SUCCESS ;
}
2022-08-09 02:16:00 +00:00
int32_t doAppendRowFromTSRow ( SSDataBlock * pBlock , STsdbReader * pReader , STSRow * pTSRow , uint64_t uid ) {
2022-06-28 02:32:42 +00:00
int32_t numOfRows = pBlock - > info . rows ;
int32_t numOfCols = ( int32_t ) taosArrayGetSize ( pBlock - > pDataBlock ) ;
2022-06-28 03:37:26 +00:00
SBlockLoadSuppInfo * pSupInfo = & pReader - > suppInfo ;
2022-08-11 10:19:44 +00:00
STSchema * pSchema = doGetSchemaForTSRow ( pTSRow - > sver , pReader , uid ) ;
2022-06-28 03:37:26 +00:00
2022-06-28 02:32:42 +00:00
SColVal colVal = { 0 } ;
2022-06-30 06:50:59 +00:00
int32_t i = 0 , j = 0 ;
2022-06-27 02:46:20 +00:00
2022-06-30 06:50:59 +00:00
SColumnInfoData * pColInfoData = taosArrayGet ( pBlock - > pDataBlock , i ) ;
if ( pColInfoData - > info . colId = = PRIMARYKEY_TIMESTAMP_COL_ID ) {
colDataAppend ( pColInfoData , numOfRows , ( const char * ) & pTSRow - > ts , false ) ;
i + = 1 ;
}
while ( i < numOfCols & & j < pSchema - > numOfCols ) {
pColInfoData = taosArrayGet ( pBlock - > pDataBlock , i ) ;
col_id_t colId = pColInfoData - > info . colId ;
if ( colId = = pSchema - > columns [ j ] . colId ) {
2022-08-09 02:16:00 +00:00
tTSRowGetVal ( pTSRow , pSchema , j , & colVal ) ;
2022-06-30 06:50:59 +00:00
doCopyColVal ( pColInfoData , numOfRows , i , & colVal , pSupInfo ) ;
i + = 1 ;
j + = 1 ;
} else if ( colId < pSchema - > columns [ j ] . colId ) {
colDataAppendNULL ( pColInfoData , numOfRows ) ;
i + = 1 ;
} else if ( colId > pSchema - > columns [ j ] . colId ) {
j + = 1 ;
2022-06-28 03:37:26 +00:00
}
2022-06-28 02:32:42 +00:00
}
2022-06-30 15:38:18 +00:00
// set null value since current column does not exist in the "pSchema"
2022-07-04 03:42:50 +00:00
while ( i < numOfCols ) {
2022-06-30 15:38:18 +00:00
pColInfoData = taosArrayGet ( pBlock - > pDataBlock , i ) ;
colDataAppendNULL ( pColInfoData , numOfRows ) ;
i + = 1 ;
}
2022-06-28 02:32:42 +00:00
pBlock - > info . rows + = 1 ;
return TSDB_CODE_SUCCESS ;
}
2022-08-17 16:08:09 +00:00
int32_t doAppendRowFromFileBlock ( SSDataBlock * pResBlock , STsdbReader * pReader , SBlockData * pBlockData , int32_t rowIndex ) {
2022-07-29 09:53:30 +00:00
int32_t i = 0 , j = 0 ;
int32_t outputRowIndex = pResBlock - > info . rows ;
SBlockLoadSuppInfo * pSupInfo = & pReader - > suppInfo ;
SColumnInfoData * pColData = taosArrayGet ( pResBlock - > pDataBlock , i ) ;
if ( pColData - > info . colId = = PRIMARYKEY_TIMESTAMP_COL_ID ) {
colDataAppendInt64 ( pColData , outputRowIndex , & pBlockData - > aTSKEY [ rowIndex ] ) ;
2022-07-29 13:09:33 +00:00
i + = 1 ;
2022-07-29 09:53:30 +00:00
}
SColVal cv = { 0 } ;
int32_t numOfInputCols = taosArrayGetSize ( pBlockData - > aIdx ) ;
int32_t numOfOutputCols = blockDataGetNumOfCols ( pResBlock ) ;
2022-08-02 04:56:33 +00:00
while ( i < numOfOutputCols & & j < numOfInputCols ) {
2022-07-29 09:53:30 +00:00
SColumnInfoData * pCol = taosArrayGet ( pResBlock - > pDataBlock , i ) ;
2022-08-02 04:56:33 +00:00
SColData * pData = tBlockDataGetColDataByIdx ( pBlockData , j ) ;
2022-07-29 09:53:30 +00:00
if ( pData - > cid = = pCol - > info . colId ) {
2022-07-29 13:09:33 +00:00
tColDataGetValue ( pData , rowIndex , & cv ) ;
doCopyColVal ( pCol , outputRowIndex , i , & cv , pSupInfo ) ;
2022-07-29 09:53:30 +00:00
j + = 1 ;
} else { // the specified column does not exist in file block, fill with null data
colDataAppendNULL ( pCol , outputRowIndex ) ;
}
i + = 1 ;
}
while ( i < numOfOutputCols ) {
SColumnInfoData * pCol = taosArrayGet ( pResBlock - > pDataBlock , i ) ;
2022-07-29 13:09:33 +00:00
colDataAppendNULL ( pCol , outputRowIndex ) ;
2022-07-29 09:53:30 +00:00
i + = 1 ;
}
pResBlock - > info . rows + = 1 ;
return TSDB_CODE_SUCCESS ;
}
2022-07-04 03:42:50 +00:00
int32_t buildDataBlockFromBufImpl ( STableBlockScanInfo * pBlockScanInfo , int64_t endKey , int32_t capacity ,
STsdbReader * pReader ) {
2022-06-27 02:46:20 +00:00
SSDataBlock * pBlock = pReader - > pResBlock ;
do {
STSRow * pTSRow = NULL ;
2022-08-11 10:19:44 +00:00
bool freeTSRow = false ;
2022-08-03 06:08:03 +00:00
tsdbGetNextRowInMem ( pBlockScanInfo , pReader , & pTSRow , endKey , & freeTSRow ) ;
2022-07-01 07:19:02 +00:00
if ( pTSRow = = NULL ) {
break ;
2022-06-27 02:46:20 +00:00
}
2022-08-09 02:16:00 +00:00
doAppendRowFromTSRow ( pBlock , pReader , pTSRow , pBlockScanInfo - > uid ) ;
2022-08-03 06:08:03 +00:00
if ( freeTSRow ) {
taosMemoryFree ( pTSRow ) ;
}
2022-06-27 02:46:20 +00:00
// no data in buffer, return immediately
2022-07-04 15:28:27 +00:00
if ( ! ( pBlockScanInfo - > iter . hasVal | | pBlockScanInfo - > iiter . hasVal ) ) {
2022-06-27 02:46:20 +00:00
break ;
}
2022-06-28 02:32:42 +00:00
if ( pBlock - > info . rows > = capacity ) {
2022-06-27 02:46:20 +00:00
break ;
}
} while ( 1 ) ;
2022-06-28 02:32:42 +00:00
ASSERT ( pBlock - > info . rows < = capacity ) ;
2022-06-27 02:46:20 +00:00
return TSDB_CODE_SUCCESS ;
}
2022-06-16 11:32:05 +00:00
2022-07-04 15:28:27 +00:00
// todo refactor, use arraylist instead
2022-07-04 05:21:02 +00:00
int32_t tsdbSetTableId ( STsdbReader * pReader , int64_t uid ) {
2022-07-04 15:28:27 +00:00
ASSERT ( pReader ! = NULL ) ;
taosHashClear ( pReader - > status . pTableMap ) ;
2022-08-26 07:27:19 +00:00
STableBlockScanInfo info = { . lastKey = 0 , . uid = uid , . indexInBlockL = INITIAL_ROW_INDEX_VAL } ;
2022-07-04 15:28:27 +00:00
taosHashPut ( pReader - > status . pTableMap , & info . uid , sizeof ( uint64_t ) , & info , sizeof ( info ) ) ;
2022-07-04 05:21:02 +00:00
return TDB_CODE_SUCCESS ;
}
2022-05-28 08:15:24 +00:00
void * tsdbGetIdx ( SMeta * pMeta ) {
if ( pMeta = = NULL ) {
return NULL ;
}
return metaGetIdx ( pMeta ) ;
}
2022-07-06 10:29:11 +00:00
2022-06-05 13:46:07 +00:00
void * tsdbGetIvtIdx ( SMeta * pMeta ) {
if ( pMeta = = NULL ) {
return NULL ;
}
return metaGetIvtIdx ( pMeta ) ;
}
2022-06-02 03:01:05 +00:00
2022-08-05 09:47:26 +00:00
uint64_t getReaderMaxVersion ( STsdbReader * pReader ) { return pReader - > verRange . maxVer ; }
2022-08-01 08:52:37 +00:00
2022-06-26 10:44:49 +00:00
2022-06-16 11:14:56 +00:00
// ====================================== EXPOSED APIs ======================================
2022-07-04 03:42:50 +00:00
int32_t tsdbReaderOpen ( SVnode * pVnode , SQueryTableDataCond * pCond , SArray * pTableList , STsdbReader * * ppReader ,
const char * idstr ) {
2022-07-25 03:17:45 +00:00
int32_t code = tsdbReaderCreate ( pVnode , pCond , ppReader , 4096 , idstr ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
2022-06-27 02:46:20 +00:00
goto _err ;
}
2022-06-16 11:32:05 +00:00
2022-07-25 03:17:45 +00:00
// check for query time window
2022-06-27 02:46:20 +00:00
STsdbReader * pReader = * ppReader ;
2022-07-04 06:10:29 +00:00
if ( isEmptyQueryTimeWindow ( & pReader - > window ) ) {
2022-06-27 02:46:20 +00:00
tsdbDebug ( " %p query window not overlaps with the data set, no result returned, %s " , pReader , pReader - > idStr ) ;
return TSDB_CODE_SUCCESS ;
}
2022-06-16 11:32:05 +00:00
2022-07-25 03:17:45 +00:00
if ( pCond - > type = = TIMEWINDOW_RANGE_EXTERNAL ) {
// update the SQueryTableDataCond to create inner reader
STimeWindow w = pCond - > twindows ;
2022-07-29 10:15:44 +00:00
int32_t order = pCond - > order ;
2022-07-25 03:17:45 +00:00
if ( order = = TSDB_ORDER_ASC ) {
pCond - > twindows . ekey = pCond - > twindows . skey ;
pCond - > twindows . skey = INT64_MIN ;
pCond - > order = TSDB_ORDER_DESC ;
} else {
pCond - > twindows . skey = pCond - > twindows . ekey ;
pCond - > twindows . ekey = INT64_MAX ;
pCond - > order = TSDB_ORDER_ASC ;
}
2022-08-16 23:51:09 +00:00
// here we only need one more row, so the capacity is set to be ONE.
2022-07-25 03:17:45 +00:00
code = tsdbReaderCreate ( pVnode , pCond , & pReader - > innerReader [ 0 ] , 1 , idstr ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
goto _err ;
}
if ( order = = TSDB_ORDER_ASC ) {
pCond - > twindows . skey = w . ekey ;
pCond - > twindows . ekey = INT64_MAX ;
2022-07-29 10:15:44 +00:00
} else {
2022-07-25 03:17:45 +00:00
pCond - > twindows . skey = INT64_MIN ;
pCond - > twindows . ekey = w . ekey ;
}
code = tsdbReaderCreate ( pVnode , pCond , & pReader - > innerReader [ 1 ] , 1 , idstr ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
goto _err ;
}
}
if ( pCond - > suid ! = 0 ) {
2022-08-05 13:12:18 +00:00
pReader - > pSchema = metaGetTbTSchema ( pReader - > pTsdb - > pVnode - > pMeta , pReader - > suid , pCond - > schemaVersion ) ;
2022-07-25 03:17:45 +00:00
} else if ( taosArrayGetSize ( pTableList ) > 0 ) {
STableKeyInfo * pKey = taosArrayGet ( pTableList , 0 ) ;
2022-08-05 13:12:18 +00:00
pReader - > pSchema = metaGetTbTSchema ( pReader - > pTsdb - > pVnode - > pMeta , pKey - > uid , pCond - > schemaVersion ) ;
2022-07-25 03:17:45 +00:00
}
2022-06-30 06:50:59 +00:00
int32_t numOfTables = taosArrayGetSize ( pTableList ) ;
pReader - > status . pTableMap = createDataBlockScanInfo ( pReader , pTableList - > pData , numOfTables ) ;
2022-06-27 02:46:20 +00:00
if ( pReader - > status . pTableMap = = NULL ) {
tsdbReaderClose ( pReader ) ;
* ppReader = NULL ;
2020-12-25 05:10:58 +00:00
2022-06-27 02:46:20 +00:00
code = TSDB_CODE_TDB_OUT_OF_MEMORY ;
goto _err ;
}
2022-06-16 11:32:05 +00:00
2022-07-22 04:56:15 +00:00
code = tsdbTakeReadSnap ( pReader - > pTsdb , & pReader - > pReadSnap ) ;
2022-07-25 03:17:45 +00:00
if ( code ! = TSDB_CODE_SUCCESS ) {
goto _err ;
}
2022-07-21 11:56:18 +00:00
2022-07-25 03:17:45 +00:00
if ( pReader - > type = = TIMEWINDOW_RANGE_CONTAINED ) {
SDataBlockIter * pBlockIter = & pReader - > status . blockIter ;
2022-07-03 15:00:12 +00:00
2022-08-18 14:42:16 +00:00
initFilesetIterator ( & pReader - > status . fileIter , pReader - > pReadSnap - > fs . aDFileSet , pReader ) ;
2022-08-26 07:27:19 +00:00
resetDataBlockIterator ( & pReader - > status . blockIter , pReader - > order ) ;
2022-07-25 03:17:45 +00:00
// no data in files, let's try buffer in memory
if ( pReader - > status . fileIter . numOfFiles = = 0 ) {
pReader - > status . loadFromFile = false ;
} else {
code = initForFirstBlockInFile ( pReader , pBlockIter ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
return code ;
}
}
2022-07-03 15:00:12 +00:00
} else {
2022-07-29 10:15:44 +00:00
STsdbReader * pPrevReader = pReader - > innerReader [ 0 ] ;
2022-07-25 03:17:45 +00:00
SDataBlockIter * pBlockIter = & pPrevReader - > status . blockIter ;
2022-08-10 06:21:31 +00:00
code = tsdbTakeReadSnap ( pPrevReader - > pTsdb , & pPrevReader - > pReadSnap ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
goto _err ;
}
2022-08-18 14:42:16 +00:00
initFilesetIterator ( & pPrevReader - > status . fileIter , pPrevReader - > pReadSnap - > fs . aDFileSet , pPrevReader ) ;
2022-08-26 07:27:19 +00:00
resetDataBlockIterator ( & pPrevReader - > status . blockIter , pPrevReader - > order ) ;
2022-07-25 03:17:45 +00:00
// no data in files, let's try buffer in memory
if ( pPrevReader - > status . fileIter . numOfFiles = = 0 ) {
pPrevReader - > status . loadFromFile = false ;
} else {
code = initForFirstBlockInFile ( pPrevReader , pBlockIter ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
return code ;
}
2022-07-03 15:00:12 +00:00
}
}
2022-06-30 06:50:59 +00:00
tsdbDebug ( " %p total numOfTable:%d in this query %s " , pReader , numOfTables , pReader - > idStr ) ;
2022-06-16 11:32:05 +00:00
return code ;
2022-06-16 12:53:25 +00:00
_err :
2022-08-02 08:48:49 +00:00
tsdbError ( " failed to create data reader, code:%s %s " , tstrerror ( code ) , pReader - > idStr ) ;
2022-06-16 12:53:25 +00:00
return code ;
2022-06-16 11:14:56 +00:00
}
void tsdbReaderClose ( STsdbReader * pReader ) {
2022-07-04 03:42:50 +00:00
if ( pReader = = NULL ) {
return ;
2022-04-08 15:48:01 +00:00
}
2022-06-16 11:14:56 +00:00
2022-07-10 09:34:21 +00:00
SBlockLoadSuppInfo * pSupInfo = & pReader - > suppInfo ;
2022-07-21 11:42:42 +00:00
tsdbUntakeReadSnap ( pReader - > pTsdb , pReader - > pReadSnap ) ;
2022-07-19 07:21:15 +00:00
2022-07-10 09:34:21 +00:00
taosMemoryFreeClear ( pSupInfo - > plist ) ;
taosMemoryFree ( pSupInfo - > colIds ) ;
taosArrayDestroy ( pSupInfo - > pColAgg ) ;
2022-07-12 09:28:14 +00:00
for ( int32_t i = 0 ; i < blockDataGetNumOfCols ( pReader - > pResBlock ) ; + + i ) {
2022-07-10 09:34:21 +00:00
if ( pSupInfo - > buildBuf [ i ] ! = NULL ) {
taosMemoryFreeClear ( pSupInfo - > buildBuf [ i ] ) ;
}
}
taosMemoryFree ( pSupInfo - > buildBuf ) ;
2022-08-08 03:22:24 +00:00
tBlockDataDestroy ( & pReader - > status . fileBlockData , true ) ;
2022-07-10 09:34:21 +00:00
cleanupDataBlockIterator ( & pReader - > status . blockIter ) ;
2022-07-26 03:43:45 +00:00
size_t numOfTables = taosHashGetSize ( pReader - > status . pTableMap ) ;
2022-07-10 09:34:21 +00:00
destroyBlockScanInfo ( pReader - > status . pTableMap ) ;
2022-07-04 03:42:50 +00:00
blockDataDestroy ( pReader - > pResBlock ) ;
2022-07-07 07:56:43 +00:00
2022-07-12 13:10:10 +00:00
if ( pReader - > pFileReader ! = NULL ) {
tsdbDataFReaderClose ( & pReader - > pFileReader ) ;
}
2022-06-16 11:14:56 +00:00
2022-08-25 07:31:48 +00:00
taosMemoryFree ( pReader - > status . uidCheckInfo . tableUidList ) ;
2022-08-20 11:05:55 +00:00
SFilesetIter * pFilesetIter = & pReader - > status . fileIter ;
if ( pFilesetIter - > pLastBlockReader ! = NULL ) {
tBlockDataDestroy ( & pFilesetIter - > pLastBlockReader - > lastBlockData , true ) ;
taosArrayDestroy ( pFilesetIter - > pLastBlockReader - > pBlockL ) ;
taosMemoryFree ( pFilesetIter - > pLastBlockReader ) ;
}
2022-07-04 03:42:50 +00:00
SIOCostSummary * pCost = & pReader - > cost ;
2022-06-16 11:14:56 +00:00
2022-07-29 10:15:44 +00:00
tsdbDebug ( " %p :io-cost summary: head-file:% " PRIu64 " , head-file time:%.2f ms, SMA:% " PRId64
2022-08-11 10:19:44 +00:00
" SMA-time:%.2f ms, fileBlocks:% " PRId64
" , fileBlocks-time:%.2f ms, "
2022-08-22 03:57:10 +00:00
" build in-memory-block-time:%.2f ms, lastBlocks:% " PRId64
" , lastBlocks-time:%.2f ms, STableBlockScanInfo size:%.2f Kb %s " ,
pReader , pCost - > headFileLoad , pCost - > headFileLoadTime , pCost - > smaDataLoad , pCost - > smaLoadTime ,
pCost - > numOfBlocks , pCost - > blockLoadTime , pCost - > buildmemBlock , pCost - > lastBlockLoad ,
pCost - > lastBlockLoadTime , numOfTables * sizeof ( STableBlockScanInfo ) / 1000.0 , pReader - > idStr ) ;
2022-06-16 11:14:56 +00:00
2022-07-04 03:42:50 +00:00
taosMemoryFree ( pReader - > idStr ) ;
taosMemoryFree ( pReader - > pSchema ) ;
2022-08-11 10:19:44 +00:00
if ( pReader - > pMemSchema ! = pReader - > pSchema ) {
taosMemoryFree ( pReader - > pMemSchema ) ;
}
2022-07-04 03:42:50 +00:00
taosMemoryFreeClear ( pReader ) ;
2022-06-16 11:14:56 +00:00
}
2022-07-25 03:17:45 +00:00
static bool doTsdbNextDataBlock ( STsdbReader * pReader ) {
2022-06-27 02:46:20 +00:00
// cleanup the data that belongs to the previous data block
2022-06-29 06:18:03 +00:00
SSDataBlock * pBlock = pReader - > pResBlock ;
blockDataCleanup ( pBlock ) ;
2022-06-16 11:32:05 +00:00
2022-06-28 02:32:42 +00:00
SReaderStatus * pStatus = & pReader - > status ;
2022-06-27 02:46:20 +00:00
2022-07-25 03:17:45 +00:00
if ( pStatus - > loadFromFile ) {
int32_t code = buildBlockFromFiles ( pReader ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
return false ;
}
2022-06-29 01:40:31 +00:00
2022-07-25 03:17:45 +00:00
if ( pBlock - > info . rows > 0 ) {
return true ;
} else {
2022-06-29 12:25:03 +00:00
buildBlockFromBufferSequentially ( pReader ) ;
2022-06-29 06:18:03 +00:00
return pBlock - > info . rows > 0 ;
2022-06-27 02:46:20 +00:00
}
2022-07-25 03:17:45 +00:00
} else { // no data in files, let's try the buffer
buildBlockFromBufferSequentially ( pReader ) ;
return pBlock - > info . rows > 0 ;
2022-06-27 02:46:20 +00:00
}
2022-07-25 03:17:45 +00:00
2022-06-29 06:18:03 +00:00
return false ;
2022-06-16 11:14:56 +00:00
}
2022-07-25 03:17:45 +00:00
bool tsdbNextDataBlock ( STsdbReader * pReader ) {
if ( isEmptyQueryTimeWindow ( & pReader - > window ) ) {
return false ;
}
if ( pReader - > innerReader [ 0 ] ! = NULL ) {
bool ret = doTsdbNextDataBlock ( pReader - > innerReader [ 0 ] ) ;
if ( ret ) {
pReader - > step = EXTERNAL_ROWS_PREV ;
return ret ;
}
tsdbReaderClose ( pReader - > innerReader [ 0 ] ) ;
pReader - > innerReader [ 0 ] = NULL ;
}
pReader - > step = EXTERNAL_ROWS_MAIN ;
bool ret = doTsdbNextDataBlock ( pReader ) ;
if ( ret ) {
return ret ;
}
if ( pReader - > innerReader [ 1 ] ! = NULL ) {
bool ret1 = doTsdbNextDataBlock ( pReader - > innerReader [ 1 ] ) ;
if ( ret1 ) {
pReader - > step = EXTERNAL_ROWS_NEXT ;
return ret1 ;
}
tsdbReaderClose ( pReader - > innerReader [ 1 ] ) ;
pReader - > innerReader [ 1 ] = NULL ;
}
return false ;
}
static void setBlockInfo ( STsdbReader * pReader , SDataBlockInfo * pDataBlockInfo ) {
2022-06-28 02:32:42 +00:00
ASSERT ( pDataBlockInfo ! = NULL & & pReader ! = NULL ) ;
pDataBlockInfo - > rows = pReader - > pResBlock - > info . rows ;
pDataBlockInfo - > uid = pReader - > pResBlock - > info . uid ;
pDataBlockInfo - > window = pReader - > pResBlock - > info . window ;
2022-06-16 08:58:00 +00:00
}
2022-07-25 03:17:45 +00:00
void tsdbRetrieveDataBlockInfo ( STsdbReader * pReader , SDataBlockInfo * pDataBlockInfo ) {
if ( pReader - > type = = TIMEWINDOW_RANGE_EXTERNAL ) {
2022-07-29 10:15:44 +00:00
if ( pReader - > step = = EXTERNAL_ROWS_MAIN ) {
2022-07-25 03:17:45 +00:00
setBlockInfo ( pReader , pDataBlockInfo ) ;
2022-07-29 10:15:44 +00:00
} else if ( pReader - > step = = EXTERNAL_ROWS_PREV ) {
2022-07-25 03:17:45 +00:00
setBlockInfo ( pReader - > innerReader [ 0 ] , pDataBlockInfo ) ;
} else {
setBlockInfo ( pReader - > innerReader [ 1 ] , pDataBlockInfo ) ;
}
} else {
setBlockInfo ( pReader , pDataBlockInfo ) ;
}
}
2022-07-07 07:56:43 +00:00
int32_t tsdbRetrieveDatablockSMA ( STsdbReader * pReader , SColumnDataAgg * * * pBlockStatis , bool * allHave ) {
2022-06-16 11:32:05 +00:00
int32_t code = 0 ;
2022-06-30 15:38:18 +00:00
* allHave = false ;
2022-06-16 11:32:05 +00:00
2022-07-29 10:15:44 +00:00
if ( pReader - > type = = TIMEWINDOW_RANGE_EXTERNAL ) {
2022-07-25 03:17:45 +00:00
* pBlockStatis = NULL ;
return TSDB_CODE_SUCCESS ;
}
2022-07-07 03:26:58 +00:00
// there is no statistics data for composed block
2022-06-30 15:38:18 +00:00
if ( pReader - > status . composedDataBlock ) {
* pBlockStatis = NULL ;
return TSDB_CODE_SUCCESS ;
}
2022-06-16 11:32:05 +00:00
2022-07-29 10:15:44 +00:00
SFileDataBlockInfo * pFBlock = getCurrentBlockInfo ( & pReader - > status . blockIter ) ;
2022-06-16 11:32:05 +00:00
2022-07-26 02:19:12 +00:00
SBlock * pBlock = getCurrentBlock ( & pReader - > status . blockIter ) ;
2022-07-07 03:26:58 +00:00
int64_t stime = taosGetTimestampUs ( ) ;
2022-06-16 11:32:05 +00:00
2022-07-07 07:56:43 +00:00
SBlockLoadSuppInfo * pSup = & pReader - > suppInfo ;
2022-07-07 03:26:58 +00:00
if ( tBlockHasSma ( pBlock ) ) {
2022-08-06 14:20:30 +00:00
code = tsdbReadBlockSma ( pReader - > pFileReader , pBlock , pSup - > pColAgg ) ;
2022-07-07 03:26:58 +00:00
if ( code ! = TSDB_CODE_SUCCESS ) {
2022-07-07 07:56:43 +00:00
tsdbDebug ( " vgId:%d, failed to load block SMA for uid % " PRIu64 " , code:%s, %s " , 0 , pFBlock - > uid , tstrerror ( code ) ,
pReader - > idStr ) ;
2022-07-07 03:26:58 +00:00
return code ;
}
2022-07-07 07:32:56 +00:00
} else {
* pBlockStatis = NULL ;
return TSDB_CODE_SUCCESS ;
2022-07-07 03:26:58 +00:00
}
2022-06-16 11:32:05 +00:00
2022-07-07 07:56:43 +00:00
* allHave = true ;
2022-06-16 11:32:05 +00:00
2022-07-07 07:56:43 +00:00
// always load the first primary timestamp column data
SColumnDataAgg * pTsAgg = & pSup - > tsColAgg ;
2022-07-07 03:26:58 +00:00
2022-07-07 07:32:56 +00:00
pTsAgg - > numOfNull = 0 ;
pTsAgg - > colId = PRIMARYKEY_TIMESTAMP_COL_ID ;
2022-07-07 07:56:43 +00:00
pTsAgg - > min = pReader - > pResBlock - > info . window . skey ;
pTsAgg - > max = pReader - > pResBlock - > info . window . ekey ;
pSup - > plist [ 0 ] = pTsAgg ;
// update the number of NULL data rows
size_t numOfCols = blockDataGetNumOfCols ( pReader - > pResBlock ) ;
int32_t i = 0 , j = 0 ;
while ( j < numOfCols & & i < taosArrayGetSize ( pSup - > pColAgg ) ) {
SColumnDataAgg * pAgg = taosArrayGet ( pSup - > pColAgg , i ) ;
if ( pAgg - > colId = = pSup - > colIds [ j ] ) {
if ( IS_BSMA_ON ( & ( pReader - > pSchema - > columns [ i ] ) ) ) {
pSup - > plist [ j ] = pAgg ;
} else {
* allHave = false ;
}
2022-07-07 09:23:54 +00:00
i + = 1 ;
j + = 1 ;
2022-07-07 07:56:43 +00:00
} else if ( pAgg - > colId < pSup - > colIds [ j ] ) {
i + = 1 ;
} else if ( pSup - > colIds [ j ] < pAgg - > colId ) {
j + = 1 ;
}
}
2022-07-26 02:19:12 +00:00
double elapsed = ( taosGetTimestampUs ( ) - stime ) / 1000.0 ;
2022-07-07 07:56:43 +00:00
pReader - > cost . smaLoadTime + = elapsed ;
2022-08-22 03:57:10 +00:00
pReader - > cost . smaDataLoad + = 1 ;
2022-07-07 07:56:43 +00:00
* pBlockStatis = pSup - > plist ;
2022-07-26 02:19:12 +00:00
tsdbDebug ( " vgId:%d, succeed to load block SMA for uid % " PRIu64 " , elapsed time:%.2f ms, %s " , 0 , pFBlock - > uid ,
2022-07-07 07:32:56 +00:00
elapsed , pReader - > idStr ) ;
2022-06-16 11:32:05 +00:00
return code ;
2022-06-16 08:58:00 +00:00
}
2022-07-25 03:17:45 +00:00
static SArray * doRetrieveDataBlock ( STsdbReader * pReader ) {
2022-06-29 02:35:07 +00:00
SReaderStatus * pStatus = & pReader - > status ;
if ( pStatus - > composedDataBlock ) {
2022-06-28 02:32:42 +00:00
return pReader - > pResBlock - > pDataBlock ;
2022-07-01 07:19:02 +00:00
}
2022-06-28 02:32:42 +00:00
2022-07-04 03:42:50 +00:00
SFileDataBlockInfo * pFBlock = getCurrentBlockInfo ( & pStatus - > blockIter ) ;
2022-07-01 07:19:02 +00:00
STableBlockScanInfo * pBlockScanInfo = taosHashGet ( pStatus - > pTableMap , & pFBlock - > uid , sizeof ( pFBlock - > uid ) ) ;
2022-06-29 09:14:00 +00:00
2022-07-26 12:40:39 +00:00
tBlockDataReset ( & pStatus - > fileBlockData ) ;
2022-08-17 16:08:09 +00:00
int32_t code = tBlockDataInit ( & pStatus - > fileBlockData , pReader - > suid , pBlockScanInfo - > uid , pReader - > pSchema ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
2022-08-18 14:42:16 +00:00
terrno = code ;
return NULL ;
2022-08-17 16:08:09 +00:00
}
code = doLoadFileBlockData ( pReader , & pStatus - > blockIter , & pStatus - > fileBlockData ) ;
2022-07-01 07:19:02 +00:00
if ( code ! = TSDB_CODE_SUCCESS ) {
2022-08-08 03:22:24 +00:00
tBlockDataDestroy ( & pStatus - > fileBlockData , 1 ) ;
2022-07-01 07:19:02 +00:00
terrno = code ;
return NULL ;
2022-06-28 02:32:42 +00:00
}
2022-07-01 07:19:02 +00:00
copyBlockDataToSDataBlock ( pReader , pBlockScanInfo ) ;
return pReader - > pResBlock - > pDataBlock ;
2022-06-16 08:58:00 +00:00
}
2022-07-25 03:17:45 +00:00
SArray * tsdbRetrieveDataBlock ( STsdbReader * pReader , SArray * pIdList ) {
if ( pReader - > type = = TIMEWINDOW_RANGE_EXTERNAL ) {
if ( pReader - > step = = EXTERNAL_ROWS_PREV ) {
return doRetrieveDataBlock ( pReader - > innerReader [ 0 ] ) ;
} else if ( pReader - > step = = EXTERNAL_ROWS_NEXT ) {
return doRetrieveDataBlock ( pReader - > innerReader [ 1 ] ) ;
}
}
return doRetrieveDataBlock ( pReader ) ;
}
2022-07-10 02:15:27 +00:00
int32_t tsdbReaderReset ( STsdbReader * pReader , SQueryTableDataCond * pCond ) {
2022-07-04 15:28:27 +00:00
if ( isEmptyQueryTimeWindow ( & pReader - > window ) ) {
return TSDB_CODE_SUCCESS ;
}
2022-06-16 11:32:05 +00:00
2022-07-12 09:28:14 +00:00
pReader - > order = pCond - > order ;
2022-07-29 10:15:44 +00:00
pReader - > type = TIMEWINDOW_RANGE_CONTAINED ;
2022-07-04 15:28:27 +00:00
pReader - > status . loadFromFile = true ;
2022-07-06 10:29:11 +00:00
pReader - > status . pTableIter = NULL ;
2022-07-10 02:15:27 +00:00
pReader - > window = updateQueryTimeWindow ( pReader - > pTsdb , & pCond - > twindows ) ;
2022-06-16 11:32:05 +00:00
2022-07-04 15:28:27 +00:00
// allocate buffer in order to load data blocks from file
2022-07-07 07:32:56 +00:00
memset ( & pReader - > suppInfo . tsColAgg , 0 , sizeof ( SColumnDataAgg ) ) ;
2022-07-04 15:28:27 +00:00
memset ( pReader - > suppInfo . plist , 0 , POINTER_BYTES ) ;
2022-07-07 07:56:43 +00:00
pReader - > suppInfo . tsColAgg . colId = PRIMARYKEY_TIMESTAMP_COL_ID ;
2022-07-12 09:44:10 +00:00
tsdbDataFReaderClose ( & pReader - > pFileReader ) ;
2022-07-07 07:56:43 +00:00
2022-07-25 03:17:45 +00:00
int32_t numOfTables = taosHashGetSize ( pReader - > status . pTableMap ) ;
2022-07-12 09:28:14 +00:00
tsdbDataFReaderClose ( & pReader - > pFileReader ) ;
2022-08-18 14:42:16 +00:00
initFilesetIterator ( & pReader - > status . fileIter , pReader - > pReadSnap - > fs . aDFileSet , pReader ) ;
2022-08-26 07:27:19 +00:00
resetDataBlockIterator ( & pReader - > status . blockIter , pReader - > order ) ;
2022-07-06 05:33:21 +00:00
resetDataBlockScanInfo ( pReader - > status . pTableMap ) ;
2022-07-04 15:28:27 +00:00
2022-07-29 10:15:44 +00:00
int32_t code = 0 ;
2022-07-25 03:17:45 +00:00
SDataBlockIter * pBlockIter = & pReader - > status . blockIter ;
2022-07-04 15:28:27 +00:00
// no data in files, let's try buffer in memory
if ( pReader - > status . fileIter . numOfFiles = = 0 ) {
pReader - > status . loadFromFile = false ;
} else {
code = initForFirstBlockInFile ( pReader , pBlockIter ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
2022-07-29 10:15:44 +00:00
tsdbError ( " %p reset reader failed, numOfTables:%d, query range:% " PRId64 " - % " PRId64 " in query %s " , pReader ,
numOfTables , pReader - > window . skey , pReader - > window . ekey , pReader - > idStr ) ;
2022-07-04 15:28:27 +00:00
return code ;
}
}
2022-06-16 11:32:05 +00:00
2022-07-06 10:29:11 +00:00
tsdbDebug ( " %p reset reader, suid:% " PRIu64 " , numOfTables:%d, query range:% " PRId64 " - % " PRId64 " in query %s " ,
pReader , pReader - > suid , numOfTables , pReader - > window . skey , pReader - > window . ekey , pReader - > idStr ) ;
2022-07-25 03:17:45 +00:00
2022-07-04 15:28:27 +00:00
return code ;
2022-06-16 08:58:00 +00:00
}
2022-06-16 06:29:28 +00:00
2022-07-07 03:26:58 +00:00
static int32_t getBucketIndex ( int32_t startRow , int32_t bucketRange , int32_t numOfRows ) {
return ( numOfRows - startRow ) / bucketRange ;
}
2022-06-16 08:58:00 +00:00
2022-07-07 03:26:58 +00:00
int32_t tsdbGetFileBlocksDistInfo ( STsdbReader * pReader , STableBlockDistInfo * pTableBlockInfo ) {
int32_t code = TSDB_CODE_SUCCESS ;
pTableBlockInfo - > totalSize = 0 ;
pTableBlockInfo - > totalRows = 0 ;
2022-06-16 08:58:00 +00:00
2022-07-07 03:26:58 +00:00
// find the start data block in file
SReaderStatus * pStatus = & pReader - > status ;
2022-06-16 08:58:00 +00:00
2022-07-07 03:26:58 +00:00
STsdbCfg * pc = & pReader - > pTsdb - > pVnode - > config . tsdbCfg ;
pTableBlockInfo - > defMinRows = pc - > minRows ;
pTableBlockInfo - > defMaxRows = pc - > maxRows ;
2022-06-16 09:18:30 +00:00
2022-07-07 03:26:58 +00:00
int32_t bucketRange = ceil ( ( pc - > maxRows - pc - > minRows ) / 20.0 ) ;
2022-06-16 09:53:07 +00:00
2022-07-07 03:26:58 +00:00
pTableBlockInfo - > numOfFiles + = 1 ;
2022-06-16 09:18:30 +00:00
2022-07-07 03:26:58 +00:00
int32_t numOfTables = ( int32_t ) taosHashGetSize ( pStatus - > pTableMap ) ;
int defaultRows = 4096 ;
2022-06-16 09:18:30 +00:00
2022-07-07 03:26:58 +00:00
SDataBlockIter * pBlockIter = & pStatus - > blockIter ;
pTableBlockInfo - > numOfFiles + = pStatus - > fileIter . numOfFiles ;
2022-07-13 15:15:58 +00:00
2022-08-17 16:08:09 +00:00
if ( pBlockIter - > numOfBlocks > 0 ) {
pTableBlockInfo - > numOfBlocks + = pBlockIter - > numOfBlocks ;
2022-07-13 15:15:58 +00:00
}
2022-06-16 09:18:30 +00:00
2022-07-07 03:26:58 +00:00
pTableBlockInfo - > numOfTables = numOfTables ;
2022-08-17 16:08:09 +00:00
bool hasNext = ( pBlockIter - > numOfBlocks > 0 ) ;
2022-06-16 09:18:30 +00:00
2022-07-07 03:26:58 +00:00
while ( true ) {
if ( hasNext ) {
2022-07-26 12:40:39 +00:00
SBlock * pBlock = getCurrentBlock ( pBlockIter ) ;
2022-06-16 09:18:30 +00:00
2022-07-07 03:26:58 +00:00
int32_t numOfRows = pBlock - > nRow ;
pTableBlockInfo - > totalRows + = numOfRows ;
2022-06-16 09:18:30 +00:00
2022-07-07 03:26:58 +00:00
if ( numOfRows > pTableBlockInfo - > maxRows ) {
pTableBlockInfo - > maxRows = numOfRows ;
}
2022-06-16 11:14:56 +00:00
2022-07-07 03:26:58 +00:00
if ( numOfRows < pTableBlockInfo - > minRows ) {
pTableBlockInfo - > minRows = numOfRows ;
}
2022-06-16 11:14:56 +00:00
2022-07-07 03:26:58 +00:00
if ( numOfRows < defaultRows ) {
pTableBlockInfo - > numOfSmallBlocks + = 1 ;
}
2022-06-16 11:14:56 +00:00
2022-07-07 03:26:58 +00:00
int32_t bucketIndex = getBucketIndex ( pTableBlockInfo - > defMinRows , bucketRange , numOfRows ) ;
pTableBlockInfo - > blockRowsHisto [ bucketIndex ] + + ;
2022-07-07 07:32:56 +00:00
hasNext = blockIteratorNext ( & pStatus - > blockIter ) ;
2022-07-07 03:26:58 +00:00
} else {
code = initForFirstBlockInFile ( pReader , pBlockIter ) ;
if ( ( code ! = TSDB_CODE_SUCCESS ) | | ( pReader - > status . loadFromFile = = false ) ) {
break ;
}
2022-06-16 11:14:56 +00:00
2022-08-17 16:08:09 +00:00
pTableBlockInfo - > numOfBlocks + = pBlockIter - > numOfBlocks ;
hasNext = ( pBlockIter - > numOfBlocks > 0 ) ;
2022-07-07 03:26:58 +00:00
}
2022-06-16 11:14:56 +00:00
2022-07-15 13:02:24 +00:00
// tsdbDebug("%p %d blocks found in file for %d table(s), fid:%d, %s", pReader, numOfBlocks, numOfTables,
// pReader->pFileGroup->fid, pReader->idStr);
2022-07-07 03:26:58 +00:00
}
2022-06-16 09:18:30 +00:00
2022-06-16 11:14:56 +00:00
return code ;
}
2022-06-16 09:18:30 +00:00
2022-06-16 11:14:56 +00:00
int64_t tsdbGetNumOfRowsInMemTable ( STsdbReader * pReader ) {
2022-06-30 06:50:59 +00:00
int64_t rows = 0 ;
2022-06-16 11:32:05 +00:00
2022-06-30 06:50:59 +00:00
SReaderStatus * pStatus = & pReader - > status ;
pStatus - > pTableIter = taosHashIterate ( pStatus - > pTableMap , NULL ) ;
2022-06-16 11:32:05 +00:00
2022-06-30 06:50:59 +00:00
while ( pStatus - > pTableIter ! = NULL ) {
STableBlockScanInfo * pBlockScanInfo = pStatus - > pTableIter ;
STbData * d = NULL ;
if ( pReader - > pTsdb - > mem ! = NULL ) {
2022-08-15 10:16:07 +00:00
d = tsdbGetTbDataFromMemTable ( pReader - > pReadSnap - > pMem , pReader - > suid , pBlockScanInfo - > uid ) ;
2022-06-30 06:50:59 +00:00
if ( d ! = NULL ) {
rows + = tsdbGetNRowsInTbData ( d ) ;
}
}
STbData * di = NULL ;
if ( pReader - > pTsdb - > imem ! = NULL ) {
2022-08-15 10:16:07 +00:00
di = tsdbGetTbDataFromMemTable ( pReader - > pReadSnap - > pIMem , pReader - > suid , pBlockScanInfo - > uid ) ;
2022-06-30 06:50:59 +00:00
if ( di ! = NULL ) {
rows + = tsdbGetNRowsInTbData ( di ) ;
}
}
// current table is exhausted, let's try the next table
pStatus - > pTableIter = taosHashIterate ( pStatus - > pTableMap , pStatus - > pTableIter ) ;
}
2022-06-16 11:32:05 +00:00
2022-06-16 11:14:56 +00:00
return rows ;
2022-06-29 10:37:35 +00:00
}
2022-07-06 08:29:51 +00:00
2022-07-12 09:28:14 +00:00
int32_t tsdbGetTableSchema ( SVnode * pVnode , int64_t uid , STSchema * * pSchema , int64_t * suid ) {
2022-07-06 08:29:51 +00:00
int32_t sversion = 1 ;
SMetaReader mr = { 0 } ;
metaReaderInit ( & mr , pVnode - > pMeta , 0 ) ;
int32_t code = metaGetTableEntryByUid ( & mr , uid ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
terrno = TSDB_CODE_TDB_INVALID_TABLE_ID ;
metaReaderClear ( & mr ) ;
return terrno ;
}
* suid = 0 ;
2022-07-12 09:28:14 +00:00
2022-07-06 08:29:51 +00:00
if ( mr . me . type = = TSDB_CHILD_TABLE ) {
2022-07-16 10:58:29 +00:00
tDecoderClear ( & mr . coder ) ;
2022-07-06 08:29:51 +00:00
* suid = mr . me . ctbEntry . suid ;
code = metaGetTableEntryByUid ( & mr , * suid ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
terrno = TSDB_CODE_TDB_INVALID_TABLE_ID ;
metaReaderClear ( & mr ) ;
return terrno ;
}
sversion = mr . me . stbEntry . schemaRow . version ;
} else {
ASSERT ( mr . me . type = = TSDB_NORMAL_TABLE ) ;
sversion = mr . me . ntbEntry . schemaRow . version ;
}
metaReaderClear ( & mr ) ;
* pSchema = metaGetTbTSchema ( pVnode - > pMeta , uid , sversion ) ;
2022-07-12 09:28:14 +00:00
2022-07-06 08:29:51 +00:00
return TSDB_CODE_SUCCESS ;
}
2022-07-21 06:27:32 +00:00
int32_t tsdbTakeReadSnap ( STsdb * pTsdb , STsdbReadSnap * * ppSnap ) {
int32_t code = 0 ;
// alloc
* ppSnap = ( STsdbReadSnap * ) taosMemoryCalloc ( 1 , sizeof ( STsdbReadSnap ) ) ;
if ( * ppSnap = = NULL ) {
code = TSDB_CODE_OUT_OF_MEMORY ;
goto _exit ;
}
// lock
code = taosThreadRwlockRdlock ( & pTsdb - > rwLock ) ;
if ( code ) {
code = TAOS_SYSTEM_ERROR ( code ) ;
goto _exit ;
}
// take snapshot
( * ppSnap ) - > pMem = pTsdb - > mem ;
( * ppSnap ) - > pIMem = pTsdb - > imem ;
if ( ( * ppSnap ) - > pMem ) {
tsdbRefMemTable ( ( * ppSnap ) - > pMem ) ;
}
if ( ( * ppSnap ) - > pIMem ) {
tsdbRefMemTable ( ( * ppSnap ) - > pIMem ) ;
}
2022-07-22 01:40:02 +00:00
// fs
2022-07-21 11:42:42 +00:00
code = tsdbFSRef ( pTsdb , & ( * ppSnap ) - > fs ) ;
if ( code ) {
taosThreadRwlockUnlock ( & pTsdb - > rwLock ) ;
goto _exit ;
}
2022-07-21 06:27:32 +00:00
// unlock
code = taosThreadRwlockUnlock ( & pTsdb - > rwLock ) ;
if ( code ) {
code = TAOS_SYSTEM_ERROR ( code ) ;
goto _exit ;
}
2022-08-01 09:23:52 +00:00
tsdbTrace ( " vgId:%d, take read snapshot " , TD_VID ( pTsdb - > pVnode ) ) ;
2022-07-21 06:27:32 +00:00
_exit :
return code ;
}
void tsdbUntakeReadSnap ( STsdb * pTsdb , STsdbReadSnap * pSnap ) {
if ( pSnap ) {
if ( pSnap - > pMem ) {
tsdbUnrefMemTable ( pSnap - > pMem ) ;
}
if ( pSnap - > pIMem ) {
tsdbUnrefMemTable ( pSnap - > pIMem ) ;
}
2022-07-21 11:42:42 +00:00
tsdbFSUnref ( pTsdb , & pSnap - > fs ) ;
2022-07-22 01:40:02 +00:00
taosMemoryFree ( pSnap ) ;
2022-07-21 06:27:32 +00:00
}
2022-07-22 01:40:02 +00:00
2022-08-01 09:23:52 +00:00
tsdbTrace ( " vgId:%d, untake read snapshot " , TD_VID ( pTsdb - > pVnode ) ) ;
2022-07-21 06:27:32 +00:00
}