count state
This commit is contained in:
parent
f6e55d358b
commit
d795798648
|
@ -217,6 +217,12 @@ enum {
|
||||||
TABLE_SCAN__BLOCK_ORDER = 2,
|
TABLE_SCAN__BLOCK_ORDER = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef enum ETableCountState {
|
||||||
|
TABLE_COUNT_STATE_NONE = 0, // before start scan
|
||||||
|
TABLE_COUNT_STATE_SCAN = 1, // scanning
|
||||||
|
TABLE_COUNT_STATE_END = 2, // finish or noneed to process
|
||||||
|
} ETableCountState;
|
||||||
|
|
||||||
typedef struct SAggSupporter {
|
typedef struct SAggSupporter {
|
||||||
SSHashObj* pResultRowHashTable; // quick locate the window object for each result
|
SSHashObj* pResultRowHashTable; // quick locate the window object for each result
|
||||||
char* keyBuf; // window key buffer
|
char* keyBuf; // window key buffer
|
||||||
|
@ -262,17 +268,18 @@ typedef struct STableScanInfo {
|
||||||
int32_t scanTimes;
|
int32_t scanTimes;
|
||||||
SSDataBlock* pResBlock;
|
SSDataBlock* pResBlock;
|
||||||
SHashObj* pIgnoreTables;
|
SHashObj* pIgnoreTables;
|
||||||
SHashObj* pValuedTables; // non empty table uids
|
SHashObj* pRemainTables; // remain table to process
|
||||||
SSampleExecInfo sample; // sample execution info
|
SSampleExecInfo sample; // sample execution info
|
||||||
int32_t currentGroupId;
|
int32_t currentGroupId;
|
||||||
int32_t currentTable;
|
int32_t currentTable;
|
||||||
int8_t scanMode;
|
int8_t scanMode;
|
||||||
int8_t assignBlockUid;
|
int8_t assignBlockUid;
|
||||||
|
uint8_t countState; // empty table count state
|
||||||
|
bool isOneGroup; // whether or not only one group in this scan
|
||||||
bool hasGroupByTag;
|
bool hasGroupByTag;
|
||||||
bool countOnly;
|
bool countOnly;
|
||||||
bool filesetDelimited;
|
bool filesetDelimited;
|
||||||
bool needCountEmptyTable;
|
bool needCountEmptyTable;
|
||||||
bool processingEmptyTable;
|
|
||||||
} STableScanInfo;
|
} STableScanInfo;
|
||||||
|
|
||||||
typedef struct STableMergeScanInfo {
|
typedef struct STableMergeScanInfo {
|
||||||
|
|
|
@ -655,26 +655,44 @@ void setTbNameColData(const SSDataBlock* pBlock, SColumnInfoData* pColInfoData,
|
||||||
colDataDestroy(&infoData);
|
colDataDestroy(&infoData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t initRemainTable(STableScanInfo* pTableScanInfo, const STableKeyInfo* pList, int32_t num) {
|
||||||
// record processed (non empty) table
|
|
||||||
static int32_t markTableProcessed(STableScanInfo* pTableScanInfo, uint64_t uid) {
|
|
||||||
if (!pTableScanInfo->needCountEmptyTable) {
|
if (!pTableScanInfo->needCountEmptyTable) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
if (NULL == pTableScanInfo->pValuedTables) {
|
pTableScanInfo->isOneGroup = true;
|
||||||
|
if (NULL == pTableScanInfo->pRemainTables) {
|
||||||
int32_t tableNum = taosArrayGetSize(pTableScanInfo->base.pTableListInfo->pTableList);
|
int32_t tableNum = taosArrayGetSize(pTableScanInfo->base.pTableListInfo->pTableList);
|
||||||
pTableScanInfo->pValuedTables =
|
pTableScanInfo->pRemainTables =
|
||||||
taosHashInit(tableNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, HASH_NO_LOCK);
|
taosHashInit(tableNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, HASH_NO_LOCK);
|
||||||
if (NULL == pTableScanInfo->pValuedTables) {
|
if (NULL == pTableScanInfo->pRemainTables) {
|
||||||
|
pTableScanInfo->countState = TABLE_COUNT_STATE_END;
|
||||||
return TSDB_CODE_OUT_OF_MEMORY;
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
uint64_t groupId = 0;
|
||||||
taosHashPut(pTableScanInfo->pValuedTables, &uid, sizeof(uid), &pTableScanInfo->scanTimes,
|
for (int32_t i = 0; i < num; i++) {
|
||||||
sizeof(pTableScanInfo->scanTimes));
|
const STableKeyInfo* pInfo = pList + i;
|
||||||
|
if (pTableScanInfo->isOneGroup) {
|
||||||
|
if (i == 0) {
|
||||||
|
groupId = pInfo->groupId;
|
||||||
|
} else if (groupId != pInfo->groupId) {
|
||||||
|
pTableScanInfo->isOneGroup = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
taosHashPut(pTableScanInfo->pRemainTables, &(pInfo->uid), sizeof(pInfo->uid), &(pInfo->groupId), sizeof(pInfo->groupId));
|
||||||
|
}
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void markTableProcessed(STableScanInfo* pTableScanInfo, uint64_t uid) {
|
||||||
|
// case0 group scanning, mark
|
||||||
|
// case1 stream scan: no need to mark
|
||||||
|
if (pTableScanInfo->countState > TABLE_COUNT_STATE_SCAN) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
taosHashRemove(pTableScanInfo->pRemainTables, &uid, sizeof(uid));
|
||||||
|
}
|
||||||
|
|
||||||
static SSDataBlock* getBlockForEmptyTable(SOperatorInfo* pOperator, const STableKeyInfo* tbInfo) {
|
static SSDataBlock* getBlockForEmptyTable(SOperatorInfo* pOperator, const STableKeyInfo* tbInfo) {
|
||||||
STableScanInfo* pTableScanInfo = pOperator->info;
|
STableScanInfo* pTableScanInfo = pOperator->info;
|
||||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||||
|
@ -770,14 +788,17 @@ static SSDataBlock* doGroupedTableScan(SOperatorInfo* pOperator, const STableKey
|
||||||
STableScanInfo* pTableScanInfo = pOperator->info;
|
STableScanInfo* pTableScanInfo = pOperator->info;
|
||||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||||
SStorageAPI* pAPI = &pTaskInfo->storageAPI;
|
SStorageAPI* pAPI = &pTaskInfo->storageAPI;
|
||||||
// Only when all tables are scanned can you determine how many groups the tag has
|
|
||||||
bool outputAll = true;
|
|
||||||
|
|
||||||
// The read handle is not initialized yet, since no qualified tables exists
|
// The read handle is not initialized yet, since no qualified tables exists
|
||||||
if (pTableScanInfo->base.dataReader == NULL || pOperator->status == OP_EXEC_DONE) {
|
if (pTableScanInfo->base.dataReader == NULL || pOperator->status == OP_EXEC_DONE) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (TABLE_COUNT_STATE_NONE == pTableScanInfo->countState) {
|
||||||
|
initRemainTable(pTableScanInfo, pList, num);
|
||||||
|
pTableScanInfo->countState = TABLE_COUNT_STATE_SCAN;
|
||||||
|
}
|
||||||
|
|
||||||
// do the ascending order traverse in the first place.
|
// do the ascending order traverse in the first place.
|
||||||
while (pTableScanInfo->scanTimes < pTableScanInfo->scanInfo.numOfAsc) {
|
while (pTableScanInfo->scanTimes < pTableScanInfo->scanInfo.numOfAsc) {
|
||||||
SSDataBlock* p = doTableScanImpl(pOperator);
|
SSDataBlock* p = doTableScanImpl(pOperator);
|
||||||
|
@ -829,37 +850,28 @@ static SSDataBlock* doGroupedTableScan(SOperatorInfo* pOperator, const STableKey
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pTableScanInfo->needCountEmptyTable) {
|
if (pTableScanInfo->needCountEmptyTable) {
|
||||||
// pList is NULL in mode TABLE_SCAN__TABLE_ORDER for streamscan, no need to process
|
int32_t tb_cnt = taosHashGetSize(pTableScanInfo->pRemainTables);
|
||||||
// pList not NULL, group by group, num >= 1
|
if (tb_cnt) {
|
||||||
int32_t tb_cnt = taosHashGetSize(pTableScanInfo->pValuedTables);
|
if (!pTableScanInfo->isOneGroup) {
|
||||||
if (pList && num > tb_cnt) {
|
// get first empty table uid, mark processed & rm from hash
|
||||||
if (!pTableScanInfo->processingEmptyTable) {
|
void *pIte = taosHashIterate(pTableScanInfo->pRemainTables, NULL);
|
||||||
pTableScanInfo->processingEmptyTable = true;
|
if (pIte != NULL) {
|
||||||
pTableScanInfo->currentTable = 0;
|
size_t keySize = 0;
|
||||||
|
uint64_t* pUid = taosHashGetKey(pIte, &keySize);
|
||||||
|
STableKeyInfo info = {.uid = *pUid, .groupId = *(uint64_t*)pIte};
|
||||||
|
taosHashCancelIterate(pTableScanInfo->pRemainTables, pIte);
|
||||||
|
markTableProcessed(pTableScanInfo, *pUid);
|
||||||
|
return getBlockForEmptyTable(pOperator, &info);
|
||||||
}
|
}
|
||||||
if (pTableScanInfo->currentTable < num) {
|
|
||||||
if (outputAll) {
|
|
||||||
// loop: get empty table uid & process
|
|
||||||
while (pTableScanInfo->currentTable < num) {
|
|
||||||
const STableKeyInfo* info = pList + pTableScanInfo->currentTable++;
|
|
||||||
if (pTableScanInfo->pValuedTables &&
|
|
||||||
NULL != taosHashGet(pTableScanInfo->pValuedTables, &info->uid, sizeof(info->uid))) {
|
|
||||||
} else {
|
} else {
|
||||||
return getBlockForEmptyTable(pOperator, info);
|
// output one table for this group
|
||||||
}
|
taosHashClear(pTableScanInfo->pRemainTables);
|
||||||
}
|
|
||||||
} else if (tb_cnt == 0) {
|
|
||||||
// only need one & all empty table in this group
|
|
||||||
// output first one
|
|
||||||
pTableScanInfo->currentTable = num;
|
|
||||||
return getBlockForEmptyTable(pOperator, pList);
|
return getBlockForEmptyTable(pOperator, pList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pTableScanInfo->processingEmptyTable = false;
|
pTableScanInfo->countState = TABLE_COUNT_STATE_END;
|
||||||
}
|
}
|
||||||
taosHashClear(pTableScanInfo->pValuedTables);
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -937,6 +949,7 @@ static SSDataBlock* startNextGroupScan(SOperatorInfo* pOperator) {
|
||||||
int32_t num = 0;
|
int32_t num = 0;
|
||||||
STableKeyInfo* pList = NULL;
|
STableKeyInfo* pList = NULL;
|
||||||
tableListGetGroupList(pInfo->base.pTableListInfo, pInfo->currentGroupId, &pList, &num);
|
tableListGetGroupList(pInfo->base.pTableListInfo, pInfo->currentGroupId, &pList, &num);
|
||||||
|
pInfo->countState = TABLE_COUNT_STATE_NONE;
|
||||||
|
|
||||||
pAPI->tsdReader.tsdSetQueryTableList(pInfo->base.dataReader, pList, num);
|
pAPI->tsdReader.tsdSetQueryTableList(pInfo->base.dataReader, pList, num);
|
||||||
pAPI->tsdReader.tsdReaderResetStatus(pInfo->base.dataReader, &pInfo->base.cond);
|
pAPI->tsdReader.tsdReaderResetStatus(pInfo->base.dataReader, &pInfo->base.cond);
|
||||||
|
@ -968,6 +981,7 @@ static SSDataBlock* groupSeqTableScan(SOperatorInfo* pOperator) {
|
||||||
}
|
}
|
||||||
|
|
||||||
tableListGetGroupList(pInfo->base.pTableListInfo, pInfo->currentGroupId, &pList, &num);
|
tableListGetGroupList(pInfo->base.pTableListInfo, pInfo->currentGroupId, &pList, &num);
|
||||||
|
pInfo->countState = TABLE_COUNT_STATE_NONE;
|
||||||
ASSERT(pInfo->base.dataReader == NULL);
|
ASSERT(pInfo->base.dataReader == NULL);
|
||||||
|
|
||||||
int32_t code = pAPI->tsdReader.tsdReaderOpen(pInfo->base.readHandle.vnode, &pInfo->base.cond, pList, num, pInfo->pResBlock,
|
int32_t code = pAPI->tsdReader.tsdReaderOpen(pInfo->base.readHandle.vnode, &pInfo->base.cond, pList, num, pInfo->pResBlock,
|
||||||
|
@ -1034,6 +1048,7 @@ static SSDataBlock* doTableScan(SOperatorInfo* pOperator) {
|
||||||
if (pInfo->scanMode == TABLE_SCAN__TABLE_ORDER) {
|
if (pInfo->scanMode == TABLE_SCAN__TABLE_ORDER) {
|
||||||
int32_t numOfTables = 0; // tableListGetSize(pTaskInfo->pTableListInfo);
|
int32_t numOfTables = 0; // tableListGetSize(pTaskInfo->pTableListInfo);
|
||||||
STableKeyInfo tInfo = {0};
|
STableKeyInfo tInfo = {0};
|
||||||
|
pInfo->countState = TABLE_COUNT_STATE_END;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
SSDataBlock* result = doGroupedTableScan(pOperator, NULL, 0);
|
SSDataBlock* result = doGroupedTableScan(pOperator, NULL, 0);
|
||||||
|
@ -1096,7 +1111,7 @@ static void destroyTableScanOperatorInfo(void* param) {
|
||||||
STableScanInfo* pTableScanInfo = (STableScanInfo*)param;
|
STableScanInfo* pTableScanInfo = (STableScanInfo*)param;
|
||||||
blockDataDestroy(pTableScanInfo->pResBlock);
|
blockDataDestroy(pTableScanInfo->pResBlock);
|
||||||
taosHashCleanup(pTableScanInfo->pIgnoreTables);
|
taosHashCleanup(pTableScanInfo->pIgnoreTables);
|
||||||
taosHashCleanup(pTableScanInfo->pValuedTables);
|
taosHashCleanup(pTableScanInfo->pRemainTables);
|
||||||
destroyTableScanBase(&pTableScanInfo->base, &pTableScanInfo->base.readerAPI);
|
destroyTableScanBase(&pTableScanInfo->base, &pTableScanInfo->base.readerAPI);
|
||||||
taosMemoryFreeClear(param);
|
taosMemoryFreeClear(param);
|
||||||
}
|
}
|
||||||
|
@ -1161,7 +1176,6 @@ SOperatorInfo* createTableScanOperatorInfo(STableScanPhysiNode* pTableScanNode,
|
||||||
pOperator->exprSupp.numOfExprs = numOfCols;
|
pOperator->exprSupp.numOfExprs = numOfCols;
|
||||||
|
|
||||||
pInfo->needCountEmptyTable = tsCountAlwaysReturnValue && pTableScanNode->needCountEmptyTable;
|
pInfo->needCountEmptyTable = tsCountAlwaysReturnValue && pTableScanNode->needCountEmptyTable;
|
||||||
pInfo->processingEmptyTable = false;
|
|
||||||
|
|
||||||
pInfo->base.pTableListInfo = pTableListInfo;
|
pInfo->base.pTableListInfo = pTableListInfo;
|
||||||
pInfo->base.metaCache.pTableMetaEntryCache = taosLRUCacheInit(1024 * 128, -1, .5);
|
pInfo->base.metaCache.pTableMetaEntryCache = taosLRUCacheInit(1024 * 128, -1, .5);
|
||||||
|
|
Loading…
Reference in New Issue