Merge branch '2.0' into refact/slguan
This commit is contained in:
commit
ddd05d9ccd
|
@ -85,7 +85,7 @@ int32_t tscGetDataBlockFromList(void* pHashList, SDataBlockList* pDataBlockList,
|
||||||
STableDataBlocks** dataBlocks);
|
STableDataBlocks** dataBlocks);
|
||||||
|
|
||||||
SVnodeSidList* tscGetVnodeSidList(SSuperTableMeta* pMetricmeta, int32_t vnodeIdx);
|
SVnodeSidList* tscGetVnodeSidList(SSuperTableMeta* pMetricmeta, int32_t vnodeIdx);
|
||||||
STableSidExtInfo* tscGetMeterSidInfo(SVnodeSidList* pSidList, int32_t idx);
|
STableIdInfo* tscGetMeterSidInfo(SVnodeSidList* pSidList, int32_t idx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
|
@ -62,7 +62,7 @@ typedef struct STableMeta {
|
||||||
int8_t numOfVpeers;
|
int8_t numOfVpeers;
|
||||||
int16_t sversion;
|
int16_t sversion;
|
||||||
SVnodeDesc vpeerDesc[TSDB_VNODES_SUPPORT];
|
SVnodeDesc vpeerDesc[TSDB_VNODES_SUPPORT];
|
||||||
int32_t vgid; // virtual group id, which current table belongs to
|
int32_t vgId; // virtual group id, which current table belongs to
|
||||||
int32_t sid; // the index of one table in a virtual node
|
int32_t sid; // the index of one table in a virtual node
|
||||||
uint64_t uid; // unique id of a table
|
uint64_t uid; // unique id of a table
|
||||||
SSchema schema[]; // if the table is TSDB_CHILD_TABLE, schema is acquired by super table meta info
|
SSchema schema[]; // if the table is TSDB_CHILD_TABLE, schema is acquired by super table meta info
|
||||||
|
@ -182,7 +182,7 @@ typedef struct STableDataBlocks {
|
||||||
char tableId[TSDB_TABLE_ID_LEN];
|
char tableId[TSDB_TABLE_ID_LEN];
|
||||||
int8_t tsSource; // where does the UNIX timestamp come from, server or client
|
int8_t tsSource; // where does the UNIX timestamp come from, server or client
|
||||||
bool ordered; // if current rows are ordered or not
|
bool ordered; // if current rows are ordered or not
|
||||||
int64_t vgid; // virtual group id
|
int64_t vgId; // virtual group id
|
||||||
int64_t prevTS; // previous timestamp, recorded to decide if the records array is ts ascending
|
int64_t prevTS; // previous timestamp, recorded to decide if the records array is ts ascending
|
||||||
int32_t numOfTables; // number of tables in current submit block
|
int32_t numOfTables; // number of tables in current submit block
|
||||||
|
|
||||||
|
|
|
@ -318,15 +318,16 @@ static int tscBuildMetricTagProjectionResult(SSqlObj *pSql) {
|
||||||
SVnodeSidList *pSidList = (SVnodeSidList *)((char *)pMetricMeta + pMetricMeta->list[i]);
|
SVnodeSidList *pSidList = (SVnodeSidList *)((char *)pMetricMeta + pMetricMeta->list[i]);
|
||||||
|
|
||||||
for (int32_t j = 0; j < pSidList->numOfSids; ++j) {
|
for (int32_t j = 0; j < pSidList->numOfSids; ++j) {
|
||||||
STableSidExtInfo *pSidExt = tscGetMeterSidInfo(pSidList, j);
|
STableIdInfo *pSidExt = tscGetMeterSidInfo(pSidList, j);
|
||||||
|
|
||||||
for (int32_t k = 0; k < pQueryInfo->fieldsInfo.numOfOutputCols; ++k) {
|
for (int32_t k = 0; k < pQueryInfo->fieldsInfo.numOfOutputCols; ++k) {
|
||||||
SColIndexEx *pColIndex = &tscSqlExprGet(pQueryInfo, k)->colInfo;
|
SColIndexEx *pColIndex = &tscSqlExprGet(pQueryInfo, k)->colInfo;
|
||||||
int16_t offsetId = pColIndex->colIdx;
|
int16_t offsetId = pColIndex->colIdx;
|
||||||
|
|
||||||
assert((pColIndex->flag & TSDB_COL_TAG) != 0);
|
assert((pColIndex->flag & TSDB_COL_TAG) != 0);
|
||||||
|
assert(0);
|
||||||
char * val = pSidExt->tags + vOffset[offsetId];
|
|
||||||
|
char * val = NULL;//pSidExt->tags + vOffset[offsetId];
|
||||||
TAOS_FIELD *pField = tscFieldInfoGetField(pQueryInfo, k);
|
TAOS_FIELD *pField = tscFieldInfoGetField(pQueryInfo, k);
|
||||||
|
|
||||||
memcpy(pRes->data + tscFieldInfoGetOffset(pQueryInfo, k) * totalNumOfResults + pField->bytes * rowIdx, val,
|
memcpy(pRes->data + tscFieldInfoGetOffset(pQueryInfo, k) * totalNumOfResults + pField->bytes * rowIdx, val,
|
||||||
|
|
|
@ -18,9 +18,10 @@
|
||||||
|
|
||||||
#define _XOPEN_SOURCE
|
#define _XOPEN_SOURCE
|
||||||
|
|
||||||
#include "hash.h"
|
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "tscSecondaryMerge.h"
|
|
||||||
|
#include "hash.h"
|
||||||
|
//#include "tscSecondaryMerge.h"
|
||||||
#include "tscUtil.h"
|
#include "tscUtil.h"
|
||||||
#include "tschemautil.h"
|
#include "tschemautil.h"
|
||||||
#include "tsclient.h"
|
#include "tsclient.h"
|
||||||
|
@ -32,6 +33,8 @@
|
||||||
#include "tstoken.h"
|
#include "tstoken.h"
|
||||||
#include "ttime.h"
|
#include "ttime.h"
|
||||||
|
|
||||||
|
#include "dataformat.h"
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
TSDB_USE_SERVER_TS = 0,
|
TSDB_USE_SERVER_TS = 0,
|
||||||
TSDB_USE_CLI_TS = 1,
|
TSDB_USE_CLI_TS = 1,
|
||||||
|
@ -393,7 +396,6 @@ static int32_t tsCheckTimestamp(STableDataBlocks *pDataBlocks, const char *start
|
||||||
int tsParseOneRowData(char **str, STableDataBlocks *pDataBlocks, SSchema schema[], SParsedDataColInfo *spd, char *error,
|
int tsParseOneRowData(char **str, STableDataBlocks *pDataBlocks, SSchema schema[], SParsedDataColInfo *spd, char *error,
|
||||||
int16_t timePrec, int32_t *code, char *tmpTokenBuf) {
|
int16_t timePrec, int32_t *code, char *tmpTokenBuf) {
|
||||||
int32_t index = 0;
|
int32_t index = 0;
|
||||||
// bool isPrevOptr; //fang, never used
|
|
||||||
SSQLToken sToken = {0};
|
SSQLToken sToken = {0};
|
||||||
char * payload = pDataBlocks->pData + pDataBlocks->size;
|
char * payload = pDataBlocks->pData + pDataBlocks->size;
|
||||||
|
|
||||||
|
@ -604,8 +606,8 @@ int32_t tscAllocateMemIfNeed(STableDataBlocks *pDataBlock, int32_t rowSize, int3
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tsSetBlockInfo(SShellSubmitBlock *pBlocks, const STableMeta *pTableMeta, int32_t numOfRows) {
|
static void tsSetBlockInfo(SSubmitBlk *pBlocks, const STableMeta *pTableMeta, int32_t numOfRows) {
|
||||||
pBlocks->sid = pTableMeta->sid;
|
pBlocks->tid = pTableMeta->sid;
|
||||||
pBlocks->uid = pTableMeta->uid;
|
pBlocks->uid = pTableMeta->uid;
|
||||||
pBlocks->sversion = pTableMeta->sversion;
|
pBlocks->sversion = pTableMeta->sversion;
|
||||||
pBlocks->numOfRows += numOfRows;
|
pBlocks->numOfRows += numOfRows;
|
||||||
|
@ -613,10 +615,10 @@ static void tsSetBlockInfo(SShellSubmitBlock *pBlocks, const STableMeta *pTableM
|
||||||
|
|
||||||
// data block is disordered, sort it in ascending order
|
// data block is disordered, sort it in ascending order
|
||||||
void sortRemoveDuplicates(STableDataBlocks *dataBuf) {
|
void sortRemoveDuplicates(STableDataBlocks *dataBuf) {
|
||||||
SShellSubmitBlock *pBlocks = (SShellSubmitBlock *)dataBuf->pData;
|
SSubmitBlk *pBlocks = (SSubmitBlk *)dataBuf->pData;
|
||||||
|
|
||||||
// size is less than the total size, since duplicated rows may be removed yet.
|
// size is less than the total size, since duplicated rows may be removed yet.
|
||||||
assert(pBlocks->numOfRows * dataBuf->rowSize + sizeof(SShellSubmitBlock) == dataBuf->size);
|
assert(pBlocks->numOfRows * dataBuf->rowSize + sizeof(SSubmitBlk) == dataBuf->size);
|
||||||
|
|
||||||
// if use server time, this block must be ordered
|
// if use server time, this block must be ordered
|
||||||
if (dataBuf->tsSource == TSDB_USE_SERVER_TS) {
|
if (dataBuf->tsSource == TSDB_USE_SERVER_TS) {
|
||||||
|
@ -624,7 +626,7 @@ void sortRemoveDuplicates(STableDataBlocks *dataBuf) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dataBuf->ordered) {
|
if (!dataBuf->ordered) {
|
||||||
char *pBlockData = pBlocks->payLoad;
|
char *pBlockData = pBlocks->data;
|
||||||
qsort(pBlockData, pBlocks->numOfRows, dataBuf->rowSize, rowDataCompar);
|
qsort(pBlockData, pBlocks->numOfRows, dataBuf->rowSize, rowDataCompar);
|
||||||
|
|
||||||
int32_t i = 0;
|
int32_t i = 0;
|
||||||
|
@ -650,7 +652,7 @@ void sortRemoveDuplicates(STableDataBlocks *dataBuf) {
|
||||||
dataBuf->ordered = true;
|
dataBuf->ordered = true;
|
||||||
|
|
||||||
pBlocks->numOfRows = i + 1;
|
pBlocks->numOfRows = i + 1;
|
||||||
dataBuf->size = sizeof(SShellSubmitBlock) + dataBuf->rowSize * pBlocks->numOfRows;
|
dataBuf->size = sizeof(SSubmitBlk) + dataBuf->rowSize * pBlocks->numOfRows;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -663,7 +665,7 @@ static int32_t doParseInsertStatement(SSqlObj *pSql, void *pTableHashList, char
|
||||||
|
|
||||||
STableDataBlocks *dataBuf = NULL;
|
STableDataBlocks *dataBuf = NULL;
|
||||||
int32_t ret = tscGetDataBlockFromList(pTableHashList, pCmd->pDataBlocks, pTableMeta->uid, TSDB_DEFAULT_PAYLOAD_SIZE,
|
int32_t ret = tscGetDataBlockFromList(pTableHashList, pCmd->pDataBlocks, pTableMeta->uid, TSDB_DEFAULT_PAYLOAD_SIZE,
|
||||||
sizeof(SShellSubmitBlock), tinfo.rowSize, pTableMetaInfo->name,
|
sizeof(SSubmitBlk), tinfo.rowSize, pTableMetaInfo->name,
|
||||||
pTableMeta, &dataBuf);
|
pTableMeta, &dataBuf);
|
||||||
if (ret != TSDB_CODE_SUCCESS) {
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -691,14 +693,14 @@ static int32_t doParseInsertStatement(SSqlObj *pSql, void *pTableHashList, char
|
||||||
SParamInfo *param = dataBuf->params + i;
|
SParamInfo *param = dataBuf->params + i;
|
||||||
if (param->idx == -1) {
|
if (param->idx == -1) {
|
||||||
param->idx = pCmd->numOfParams++;
|
param->idx = pCmd->numOfParams++;
|
||||||
param->offset -= sizeof(SShellSubmitBlock);
|
param->offset -= sizeof(SSubmitBlk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SShellSubmitBlock *pBlocks = (SShellSubmitBlock *)(dataBuf->pData);
|
SSubmitBlk *pBlocks = (SSubmitBlk *)(dataBuf->pData);
|
||||||
tsSetBlockInfo(pBlocks, pTableMeta, numOfRows);
|
tsSetBlockInfo(pBlocks, pTableMeta, numOfRows);
|
||||||
|
|
||||||
dataBuf->vgid = pTableMeta->vgid;
|
dataBuf->vgId = pTableMeta->vgId;
|
||||||
dataBuf->numOfTables = 1;
|
dataBuf->numOfTables = 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1058,7 +1060,6 @@ int doParseInsertSql(SSqlObj *pSql, char *str) {
|
||||||
goto _error_clean;
|
goto _error_clean;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *fp = pSql->fp;
|
|
||||||
ptrdiff_t pos = pSql->asyncTblPos - pSql->sqlstr;
|
ptrdiff_t pos = pSql->asyncTblPos - pSql->sqlstr;
|
||||||
|
|
||||||
if ((code = tscCheckIfCreateTable(&str, pSql)) != TSDB_CODE_SUCCESS) {
|
if ((code = tscCheckIfCreateTable(&str, pSql)) != TSDB_CODE_SUCCESS) {
|
||||||
|
@ -1068,17 +1069,15 @@ int doParseInsertSql(SSqlObj *pSql, char *str) {
|
||||||
* And during the getMeterMetaCallback function, the sql string will be parsed from the
|
* And during the getMeterMetaCallback function, the sql string will be parsed from the
|
||||||
* interrupted position.
|
* interrupted position.
|
||||||
*/
|
*/
|
||||||
if (fp != NULL) {
|
if (TSDB_CODE_ACTION_IN_PROGRESS == code) {
|
||||||
if (TSDB_CODE_ACTION_IN_PROGRESS == code) {
|
tscTrace("async insert and waiting to get meter meta, then continue parse sql from offset: %" PRId64, pos);
|
||||||
tscTrace("async insert and waiting to get meter meta, then continue parse sql from offset: %" PRId64, pos);
|
return code;
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo add to return
|
|
||||||
tscError("async insert parse error, code:%d, %s", code, tstrerror(code));
|
|
||||||
pSql->asyncTblPos = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo add to return
|
||||||
|
tscError("async insert parse error, code:%d, %s", code, tstrerror(code));
|
||||||
|
pSql->asyncTblPos = NULL;
|
||||||
|
|
||||||
goto _error_clean; // TODO: should _clean or _error_clean to async flow ????
|
goto _error_clean; // TODO: should _clean or _error_clean to async flow ????
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1096,15 +1095,13 @@ int doParseInsertSql(SSqlObj *pSql, char *str) {
|
||||||
goto _error_clean;
|
goto _error_clean;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t numOfCols = tscGetNumOfTags(pTableMetaInfo->pTableMeta);
|
|
||||||
STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
|
STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
|
||||||
|
|
||||||
if (sToken.type == TK_VALUES) {
|
if (sToken.type == TK_VALUES) {
|
||||||
SParsedDataColInfo spd = {.numOfCols = numOfCols};
|
SParsedDataColInfo spd = {.numOfCols = tinfo.numOfColumns};
|
||||||
|
|
||||||
SSchema *pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
|
SSchema *pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
|
||||||
|
tscSetAssignedColumnInfo(&spd, pSchema, tinfo.numOfColumns);
|
||||||
tscSetAssignedColumnInfo(&spd, pSchema, numOfCols);
|
|
||||||
|
|
||||||
if (validateDataSource(pCmd, DATA_FROM_SQL_STRING, sToken.z) != TSDB_CODE_SUCCESS) {
|
if (validateDataSource(pCmd, DATA_FROM_SQL_STRING, sToken.z) != TSDB_CODE_SUCCESS) {
|
||||||
goto _error_clean;
|
goto _error_clean;
|
||||||
|
@ -1146,7 +1143,7 @@ int doParseInsertSql(SSqlObj *pSql, char *str) {
|
||||||
STableDataBlocks *pDataBlock = NULL;
|
STableDataBlocks *pDataBlock = NULL;
|
||||||
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
||||||
|
|
||||||
int32_t ret = tscCreateDataBlock(PATH_MAX, tinfo.rowSize, sizeof(SShellSubmitBlock), pTableMetaInfo->name,
|
int32_t ret = tscCreateDataBlock(PATH_MAX, tinfo.rowSize, sizeof(SSubmitBlk), pTableMetaInfo->name,
|
||||||
pTableMeta, &pDataBlock);
|
pTableMeta, &pDataBlock);
|
||||||
if (ret != TSDB_CODE_SUCCESS) {
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
goto _error_clean;
|
goto _error_clean;
|
||||||
|
@ -1243,7 +1240,7 @@ int doParseInsertSql(SSqlObj *pSql, char *str) {
|
||||||
|
|
||||||
// submit to more than one vnode
|
// submit to more than one vnode
|
||||||
if (pCmd->pDataBlocks->nSize > 0) {
|
if (pCmd->pDataBlocks->nSize > 0) {
|
||||||
// merge according to vgid
|
// merge according to vgId
|
||||||
if ((code = tscMergeTableDataBlocks(pSql, pCmd->pDataBlocks)) != TSDB_CODE_SUCCESS) {
|
if ((code = tscMergeTableDataBlocks(pSql, pCmd->pDataBlocks)) != TSDB_CODE_SUCCESS) {
|
||||||
goto _error_clean;
|
goto _error_clean;
|
||||||
}
|
}
|
||||||
|
@ -1358,7 +1355,7 @@ static int doPackSendDataBlock(SSqlObj *pSql, int32_t numOfRows, STableDataBlock
|
||||||
assert(pCmd->numOfClause == 1);
|
assert(pCmd->numOfClause == 1);
|
||||||
STableMeta *pTableMeta = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0)->pTableMeta;
|
STableMeta *pTableMeta = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0)->pTableMeta;
|
||||||
|
|
||||||
SShellSubmitBlock *pBlocks = (SShellSubmitBlock *)(pTableDataBlocks->pData);
|
SSubmitBlk *pBlocks = (SSubmitBlk *)(pTableDataBlocks->pData);
|
||||||
tsSetBlockInfo(pBlocks, pTableMeta, numOfRows);
|
tsSetBlockInfo(pBlocks, pTableMeta, numOfRows);
|
||||||
|
|
||||||
if ((code = tscMergeTableDataBlocks(pSql, pCmd->pDataBlocks)) != TSDB_CODE_SUCCESS) {
|
if ((code = tscMergeTableDataBlocks(pSql, pCmd->pDataBlocks)) != TSDB_CODE_SUCCESS) {
|
||||||
|
@ -1399,7 +1396,7 @@ static int tscInsertDataFromFile(SSqlObj *pSql, FILE *fp, char *tmpTokenBuf) {
|
||||||
|
|
||||||
pCmd->pDataBlocks = tscCreateBlockArrayList();
|
pCmd->pDataBlocks = tscCreateBlockArrayList();
|
||||||
STableDataBlocks *pTableDataBlock = NULL;
|
STableDataBlocks *pTableDataBlock = NULL;
|
||||||
int32_t ret = tscCreateDataBlock(TSDB_PAYLOAD_SIZE, rowSize, sizeof(SShellSubmitBlock),
|
int32_t ret = tscCreateDataBlock(TSDB_PAYLOAD_SIZE, rowSize, sizeof(SSubmitBlk),
|
||||||
pTableMetaInfo->name, pTableMeta, &pTableDataBlock);
|
pTableMetaInfo->name, pTableMeta, &pTableDataBlock);
|
||||||
if (ret != TSDB_CODE_SUCCESS) {
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1440,7 +1437,7 @@ static int tscInsertDataFromFile(SSqlObj *pSql, FILE *fp, char *tmpTokenBuf) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pTableDataBlock = pCmd->pDataBlocks->pData[0];
|
pTableDataBlock = pCmd->pDataBlocks->pData[0];
|
||||||
pTableDataBlock->size = sizeof(SShellSubmitBlock);
|
pTableDataBlock->size = sizeof(SSubmitBlk);
|
||||||
pTableDataBlock->rowSize = tinfo.rowSize;
|
pTableDataBlock->rowSize = tinfo.rowSize;
|
||||||
|
|
||||||
numOfRows += pSql->res.numOfRows;
|
numOfRows += pSql->res.numOfRows;
|
||||||
|
|
|
@ -325,12 +325,12 @@ static int insertStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) {
|
||||||
|
|
||||||
for (int32_t i = 0; i < pCmd->pDataBlocks->nSize; ++i) {
|
for (int32_t i = 0; i < pCmd->pDataBlocks->nSize; ++i) {
|
||||||
STableDataBlocks* pBlock = pCmd->pDataBlocks->pData[i];
|
STableDataBlocks* pBlock = pCmd->pDataBlocks->pData[i];
|
||||||
uint32_t totalDataSize = pBlock->size - sizeof(SShellSubmitBlock);
|
uint32_t totalDataSize = pBlock->size - sizeof(SSubmitBlk);
|
||||||
uint32_t dataSize = totalDataSize / alloced;
|
uint32_t dataSize = totalDataSize / alloced;
|
||||||
assert(dataSize * alloced == totalDataSize);
|
assert(dataSize * alloced == totalDataSize);
|
||||||
|
|
||||||
if (alloced == binded) {
|
if (alloced == binded) {
|
||||||
totalDataSize += dataSize + sizeof(SShellSubmitBlock);
|
totalDataSize += dataSize + sizeof(SSubmitBlk);
|
||||||
if (totalDataSize > pBlock->nAllocSize) {
|
if (totalDataSize > pBlock->nAllocSize) {
|
||||||
const double factor = 1.5;
|
const double factor = 1.5;
|
||||||
void* tmp = realloc(pBlock->pData, (uint32_t)(totalDataSize * factor));
|
void* tmp = realloc(pBlock->pData, (uint32_t)(totalDataSize * factor));
|
||||||
|
@ -342,7 +342,7 @@ static int insertStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char* data = pBlock->pData + sizeof(SShellSubmitBlock) + dataSize * binded;
|
char* data = pBlock->pData + sizeof(SSubmitBlk) + dataSize * binded;
|
||||||
for (uint32_t j = 0; j < pBlock->numOfParams; ++j) {
|
for (uint32_t j = 0; j < pBlock->numOfParams; ++j) {
|
||||||
SParamInfo* param = pBlock->params + j;
|
SParamInfo* param = pBlock->params + j;
|
||||||
int code = doBindParam(data, param, bind + param->idx);
|
int code = doBindParam(data, param, bind + param->idx);
|
||||||
|
@ -365,10 +365,10 @@ static int insertStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) {
|
||||||
for (int32_t i = 0; i < pCmd->pDataBlocks->nSize; ++i) {
|
for (int32_t i = 0; i < pCmd->pDataBlocks->nSize; ++i) {
|
||||||
STableDataBlocks* pBlock = pCmd->pDataBlocks->pData[i];
|
STableDataBlocks* pBlock = pCmd->pDataBlocks->pData[i];
|
||||||
|
|
||||||
uint32_t totalDataSize = pBlock->size - sizeof(SShellSubmitBlock);
|
uint32_t totalDataSize = pBlock->size - sizeof(SSubmitBlk);
|
||||||
pBlock->size += totalDataSize / alloced;
|
pBlock->size += totalDataSize / alloced;
|
||||||
|
|
||||||
SShellSubmitBlock* pSubmit = (SShellSubmitBlock*)pBlock->pData;
|
SSubmitBlk* pSubmit = (SSubmitBlk*)pBlock->pData;
|
||||||
pSubmit->numOfRows += pSubmit->numOfRows / alloced;
|
pSubmit->numOfRows += pSubmit->numOfRows / alloced;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -398,10 +398,10 @@ static int insertStmtReset(STscStmt* pStmt) {
|
||||||
for (int32_t i = 0; i < pCmd->pDataBlocks->nSize; ++i) {
|
for (int32_t i = 0; i < pCmd->pDataBlocks->nSize; ++i) {
|
||||||
STableDataBlocks* pBlock = pCmd->pDataBlocks->pData[i];
|
STableDataBlocks* pBlock = pCmd->pDataBlocks->pData[i];
|
||||||
|
|
||||||
uint32_t totalDataSize = pBlock->size - sizeof(SShellSubmitBlock);
|
uint32_t totalDataSize = pBlock->size - sizeof(SSubmitBlk);
|
||||||
pBlock->size = sizeof(SShellSubmitBlock) + totalDataSize / alloced;
|
pBlock->size = sizeof(SSubmitBlk) + totalDataSize / alloced;
|
||||||
|
|
||||||
SShellSubmitBlock* pSubmit = (SShellSubmitBlock*)pBlock->pData;
|
SSubmitBlk* pSubmit = (SSubmitBlk*)pBlock->pData;
|
||||||
pSubmit->numOfRows = pSubmit->numOfRows / alloced;
|
pSubmit->numOfRows = pSubmit->numOfRows / alloced;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ SSchema *tscGetTableSchema(const STableMeta *pTableMeta) {
|
||||||
return pSTableMeta->schema;
|
return pSTableMeta->schema;
|
||||||
}
|
}
|
||||||
|
|
||||||
return pTableMeta->schema;
|
return (SSchema*) pTableMeta->schema;
|
||||||
}
|
}
|
||||||
|
|
||||||
SSchema* tscGetTableTagSchema(const STableMeta* pTableMeta) {
|
SSchema* tscGetTableTagSchema(const STableMeta* pTableMeta) {
|
||||||
|
@ -165,7 +165,7 @@ STableMeta* tscCreateTableMetaFromMsg(STableMetaMsg* pTableMetaMsg, size_t* size
|
||||||
|
|
||||||
pTableMeta->sid = pTableMetaMsg->sid;
|
pTableMeta->sid = pTableMetaMsg->sid;
|
||||||
pTableMeta->uid = pTableMetaMsg->uid;
|
pTableMeta->uid = pTableMetaMsg->uid;
|
||||||
pTableMeta->vgid = pTableMetaMsg->vgid;
|
pTableMeta->vgId = pTableMetaMsg->vgId;
|
||||||
|
|
||||||
pTableMeta->numOfVpeers = pTableMetaMsg->numOfVpeers;
|
pTableMeta->numOfVpeers = pTableMetaMsg->numOfVpeers;
|
||||||
memcpy(pTableMeta->vpeerDesc, pTableMetaMsg->vpeerDesc, sizeof(SVnodeDesc) * pTableMeta->numOfVpeers);
|
memcpy(pTableMeta->vpeerDesc, pTableMetaMsg->vpeerDesc, sizeof(SVnodeDesc) * pTableMeta->numOfVpeers);
|
||||||
|
|
|
@ -341,11 +341,7 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg) {
|
||||||
* the tscShouldFreeAsyncSqlObj will success and tscFreeSqlObj free it immediately.
|
* the tscShouldFreeAsyncSqlObj will success and tscFreeSqlObj free it immediately.
|
||||||
*/
|
*/
|
||||||
bool shouldFree = tscShouldFreeAsyncSqlObj(pSql);
|
bool shouldFree = tscShouldFreeAsyncSqlObj(pSql);
|
||||||
if (command == TSDB_SQL_INSERT) { // handle multi-vnode insertion situation
|
(*pSql->fp)(pSql->param, taosres, rpcMsg->code);
|
||||||
(*pSql->fp)(pSql, taosres, rpcMsg->code);
|
|
||||||
} else {
|
|
||||||
(*pSql->fp)(pSql->param, taosres, rpcMsg->code);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shouldFree) {
|
if (shouldFree) {
|
||||||
// If it is failed, all objects allocated during execution taos_connect_a should be released
|
// If it is failed, all objects allocated during execution taos_connect_a should be released
|
||||||
|
@ -512,14 +508,17 @@ int tscBuildRetrieveMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
pRetrieveMsg->free = htons(pQueryInfo->type);
|
pRetrieveMsg->free = htons(pQueryInfo->type);
|
||||||
pMsg += sizeof(pQueryInfo->type);
|
pMsg += sizeof(pQueryInfo->type);
|
||||||
|
|
||||||
pSql->cmd.payloadLen = pMsg - pStart;
|
pRetrieveMsg->header.vgId = htonl(1);
|
||||||
|
pMsg += sizeof(SRetrieveTableMsg);
|
||||||
|
|
||||||
|
pRetrieveMsg->header.contLen = htonl(pSql->cmd.payloadLen);
|
||||||
|
|
||||||
pSql->cmd.msgType = TSDB_MSG_TYPE_RETRIEVE;
|
pSql->cmd.msgType = TSDB_MSG_TYPE_RETRIEVE;
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tscUpdateVnodeInSubmitMsg(SSqlObj *pSql, char *buf) {
|
void tscUpdateVnodeInSubmitMsg(SSqlObj *pSql, char *buf) {
|
||||||
//SShellSubmitMsg *pShellMsg;
|
//SSubmitMsg *pShellMsg;
|
||||||
//char * pMsg;
|
//char * pMsg;
|
||||||
//STableMetaInfo * pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, pSql->cmd.clauseIndex, 0);
|
//STableMetaInfo * pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, pSql->cmd.clauseIndex, 0);
|
||||||
|
|
||||||
|
@ -528,34 +527,38 @@ void tscUpdateVnodeInSubmitMsg(SSqlObj *pSql, char *buf) {
|
||||||
//pMsg = buf + tsRpcHeadSize;
|
//pMsg = buf + tsRpcHeadSize;
|
||||||
|
|
||||||
//TODO set iplist
|
//TODO set iplist
|
||||||
//pShellMsg = (SShellSubmitMsg *)pMsg;
|
//pShellMsg = (SSubmitMsg *)pMsg;
|
||||||
//pShellMsg->vnode = htons(pTableMeta->vpeerDesc[pSql->index].vnode);
|
//pShellMsg->vnode = htons(pTableMeta->vpeerDesc[pSql->index].vnode);
|
||||||
//tscTrace("%p update submit msg vnode:%s:%d", pSql, taosIpStr(pTableMeta->vpeerDesc[pSql->index].ip),
|
//tscTrace("%p update submit msg vnode:%s:%d", pSql, taosIpStr(pTableMeta->vpeerDesc[pSql->index].ip),
|
||||||
// htons(pShellMsg->vnode));
|
// htons(pShellMsg->vnode));
|
||||||
}
|
}
|
||||||
|
|
||||||
int tscBuildSubmitMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
int tscBuildSubmitMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
SShellSubmitMsg *pShellMsg;
|
SSubmitMsg *pShellMsg;
|
||||||
char * pMsg, *pStart;
|
char * pMsg, *pStart;
|
||||||
|
|
||||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
|
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
|
||||||
|
STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, 0)->pTableMeta;
|
||||||
|
|
||||||
pStart = pSql->cmd.payload + tsRpcHeadSize;
|
pStart = pSql->cmd.payload + tsRpcHeadSize;
|
||||||
pMsg = pStart;
|
pMsg = pStart;
|
||||||
|
|
||||||
pShellMsg = (SShellSubmitMsg *)pMsg;
|
SMsgDesc* pMsgDesc = (SMsgDesc*) pMsg;
|
||||||
|
pMsgDesc->numOfVnodes = htonl(1); //set the number of vnodes
|
||||||
pShellMsg->import = htons(TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_INSERT) ? 0 : 1);
|
pMsg += sizeof(SMsgDesc);
|
||||||
pShellMsg->vnode = 0; //htons(pTableMeta->vpeerDesc[pTableMeta->index].vnode);
|
|
||||||
pShellMsg->numOfSid = htonl(pSql->cmd.numOfTablesInSubmit); // number of meters to be inserted
|
pShellMsg = (SSubmitMsg *)pMsg;
|
||||||
|
pShellMsg->header.vgId = htonl(pTableMeta->vgId);
|
||||||
|
pShellMsg->header.contLen = htonl(pSql->cmd.payloadLen);
|
||||||
|
pShellMsg->length = pShellMsg->header.contLen;
|
||||||
|
|
||||||
|
pShellMsg->numOfBlocks = htonl(pSql->cmd.numOfTablesInSubmit); // number of meters to be inserted
|
||||||
|
|
||||||
// pSql->cmd.payloadLen is set during parse sql routine, so we do not use it here
|
// pSql->cmd.payloadLen is set during parse sql routine, so we do not use it here
|
||||||
pSql->cmd.msgType = TSDB_MSG_TYPE_SUBMIT;
|
pSql->cmd.msgType = TSDB_MSG_TYPE_SUBMIT;
|
||||||
|
|
||||||
// tscTrace("%p update submit msg vnode:%s:%d", pSql, taosIpStr(pTableMeta->vpeerDesc[pTableMeta->index].ip),
|
// tscTrace("%p update submit msg vnode:%s:%d", pSql, taosIpStr(pTableMeta->vpeerDesc[pTableMeta->index].ip),
|
||||||
// htons(pShellMsg->vnode));
|
// htons(pShellMsg->vnode));
|
||||||
|
|
||||||
pSql->cmd.payloadLen = sizeof(SShellSubmitMsg);
|
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -598,7 +601,7 @@ static int32_t tscEstimateQueryMsgSize(SSqlCmd *pCmd, int32_t clauseIndex) {
|
||||||
SSuperTableMeta *pMetricMeta = pTableMetaInfo->pMetricMeta;
|
SSuperTableMeta *pMetricMeta = pTableMetaInfo->pMetricMeta;
|
||||||
SVnodeSidList *pVnodeSidList = tscGetVnodeSidList(pMetricMeta, pTableMetaInfo->vnodeIndex);
|
SVnodeSidList *pVnodeSidList = tscGetVnodeSidList(pMetricMeta, pTableMetaInfo->vnodeIndex);
|
||||||
|
|
||||||
int32_t meterInfoSize = (pMetricMeta->tagLen + sizeof(STableSidExtInfo)) * pVnodeSidList->numOfSids;
|
int32_t meterInfoSize = (pMetricMeta->tagLen + sizeof(STableIdInfo)) * pVnodeSidList->numOfSids;
|
||||||
int32_t outputColumnSize = pQueryInfo->exprsInfo.numOfExprs * sizeof(SSqlFuncExprMsg);
|
int32_t outputColumnSize = pQueryInfo->exprsInfo.numOfExprs * sizeof(SSqlFuncExprMsg);
|
||||||
|
|
||||||
int32_t size = meterInfoSize + outputColumnSize + srcColListSize + exprSize + MIN_QUERY_MSG_PKT_SIZE;
|
int32_t size = meterInfoSize + outputColumnSize + srcColListSize + exprSize + MIN_QUERY_MSG_PKT_SIZE;
|
||||||
|
@ -609,37 +612,34 @@ static int32_t tscEstimateQueryMsgSize(SSqlCmd *pCmd, int32_t clauseIndex) {
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *doSerializeTableInfo(SSqlObj *pSql, int32_t numOfTables, int32_t vnodeId, char *pMsg) {
|
static char *doSerializeTableInfo(SSqlObj *pSql, int32_t numOfTables, int32_t vgId, char *pMsg) {
|
||||||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, pSql->cmd.clauseIndex, 0);
|
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, pSql->cmd.clauseIndex, 0);
|
||||||
|
|
||||||
STableMeta * pTableMeta = pTableMetaInfo->pTableMeta;
|
STableMeta * pTableMeta = pTableMetaInfo->pTableMeta;
|
||||||
SSuperTableMeta *pMetricMeta = pTableMetaInfo->pMetricMeta;
|
SSuperTableMeta *pMetricMeta = pTableMetaInfo->pMetricMeta;
|
||||||
|
|
||||||
tscTrace("%p vid:%d, query on %d meters", pSql, vnodeId, numOfTables);
|
tscTrace("%p vgId:%d, query on %d tables", pSql, vgId, numOfTables);
|
||||||
if (UTIL_TABLE_IS_NOMRAL_TABLE(pTableMetaInfo)) {
|
if (UTIL_TABLE_IS_NOMRAL_TABLE(pTableMetaInfo)) {
|
||||||
#ifdef _DEBUG_VIEW
|
#ifdef _DEBUG_VIEW
|
||||||
tscTrace("%p sid:%d, uid:%" PRIu64, pSql, pTableMetaInfo->pTableMeta->sid, pTableMetaInfo->pTableMeta->uid);
|
tscTrace("%p sid:%d, uid:%" PRIu64, pSql, pTableMetaInfo->pTableMeta->sid, pTableMetaInfo->pTableMeta->uid);
|
||||||
#endif
|
#endif
|
||||||
STableSidExtInfo *pTableMetaInfo = (STableSidExtInfo *)pMsg;
|
STableIdInfo *pTableIdInfo = (STableIdInfo *)pMsg;
|
||||||
pTableMetaInfo->sid = htonl(pTableMeta->sid);
|
pTableIdInfo->sid = htonl(pTableMeta->sid);
|
||||||
pTableMetaInfo->uid = htobe64(pTableMeta->uid);
|
pTableIdInfo->uid = htobe64(pTableMeta->uid);
|
||||||
pTableMetaInfo->key = htobe64(tscGetSubscriptionProgress(pSql->pSubscription, pTableMeta->uid));
|
pTableIdInfo->key = htobe64(tscGetSubscriptionProgress(pSql->pSubscription, pTableMeta->uid));
|
||||||
pMsg += sizeof(STableSidExtInfo);
|
pMsg += sizeof(STableIdInfo);
|
||||||
} else {
|
} else {
|
||||||
SVnodeSidList *pVnodeSidList = tscGetVnodeSidList(pMetricMeta, pTableMetaInfo->vnodeIndex);
|
SVnodeSidList *pVnodeSidList = tscGetVnodeSidList(pMetricMeta, pTableMetaInfo->vnodeIndex);
|
||||||
|
|
||||||
for (int32_t i = 0; i < numOfTables; ++i) {
|
for (int32_t i = 0; i < numOfTables; ++i) {
|
||||||
STableSidExtInfo *pTableMetaInfo = (STableSidExtInfo *)pMsg;
|
STableIdInfo *pTableIdInfo = (STableIdInfo *)pMsg;
|
||||||
STableSidExtInfo *pQueryMeterInfo = tscGetMeterSidInfo(pVnodeSidList, i);
|
STableIdInfo *pQueryMeterInfo = tscGetMeterSidInfo(pVnodeSidList, i);
|
||||||
|
|
||||||
pTableMetaInfo->sid = htonl(pQueryMeterInfo->sid);
|
pTableIdInfo->sid = htonl(pQueryMeterInfo->sid);
|
||||||
pTableMetaInfo->uid = htobe64(pQueryMeterInfo->uid);
|
pTableIdInfo->uid = htobe64(pQueryMeterInfo->uid);
|
||||||
pTableMetaInfo->key = htobe64(tscGetSubscriptionProgress(pSql->pSubscription, pQueryMeterInfo->uid));
|
pTableIdInfo->key = htobe64(tscGetSubscriptionProgress(pSql->pSubscription, pQueryMeterInfo->uid));
|
||||||
|
|
||||||
pMsg += sizeof(STableSidExtInfo);
|
pMsg += sizeof(STableIdInfo);
|
||||||
|
|
||||||
memcpy(pMsg, pQueryMeterInfo->tags, pMetricMeta->tagLen);
|
|
||||||
pMsg += pMetricMeta->tagLen;
|
|
||||||
|
|
||||||
#ifdef _DEBUG_VIEW
|
#ifdef _DEBUG_VIEW
|
||||||
tscTrace("%p sid:%d, uid:%" PRId64, pSql, pQueryMeterInfo->sid, pQueryMeterInfo->uid);
|
tscTrace("%p sid:%d, uid:%" PRId64, pSql, pQueryMeterInfo->sid, pQueryMeterInfo->uid);
|
||||||
|
@ -679,6 +679,7 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
pQueryMsg->uid = pTableMeta->uid;
|
pQueryMsg->uid = pTableMeta->uid;
|
||||||
pQueryMsg->numOfTagsCols = 0;
|
pQueryMsg->numOfTagsCols = 0;
|
||||||
|
|
||||||
|
pQueryMsg->vgId = htonl(pTableMeta->vgId);
|
||||||
tscTrace("%p queried tables:%d, table id: %s", pSql, 1, pTableMetaInfo->name);
|
tscTrace("%p queried tables:%d, table id: %s", pSql, 1, pTableMetaInfo->name);
|
||||||
} else { // query on super table
|
} else { // query on super table
|
||||||
if (pTableMetaInfo->vnodeIndex < 0) {
|
if (pTableMetaInfo->vnodeIndex < 0) {
|
||||||
|
@ -696,7 +697,7 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
}
|
}
|
||||||
|
|
||||||
tscTrace("%p query on vid:%d, number of tables:%d", pSql, vnodeId, numOfTables);
|
tscTrace("%p query on vid:%d, number of tables:%d", pSql, vnodeId, numOfTables);
|
||||||
pQueryMsg->vnode = htons(vnodeId);
|
pQueryMsg->vgId = htons(vnodeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
pQueryMsg->numOfTables = htonl(numOfTables);
|
pQueryMsg->numOfTables = htonl(numOfTables);
|
||||||
|
@ -764,14 +765,14 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
SColumnBase *pCol = tscColumnBaseInfoGet(&pQueryInfo->colList, i);
|
SColumnBase *pCol = tscColumnBaseInfoGet(&pQueryInfo->colList, i);
|
||||||
SSchema * pColSchema = &pSchema[pCol->colIndex.columnIndex];
|
SSchema * pColSchema = &pSchema[pCol->colIndex.columnIndex];
|
||||||
|
|
||||||
if (pCol->colIndex.columnIndex >= tscGetNumOfColumns(pTableMeta) || pColSchema->type < TSDB_DATA_TYPE_BOOL ||
|
// if (pCol->colIndex.columnIndex >= tscGetNumOfColumns(pTableMeta) || pColSchema->type < TSDB_DATA_TYPE_BOOL ||
|
||||||
pColSchema->type > TSDB_DATA_TYPE_NCHAR) {
|
// pColSchema->type > TSDB_DATA_TYPE_NCHAR) {
|
||||||
tscError("%p vid:%d sid:%d id:%s, column index out of range, numOfColumns:%d, index:%d, column name:%s", pSql,
|
// tscError("%p vid:%d sid:%d id:%s, column index out of range, numOfColumns:%d, index:%d, column name:%s", pSql,
|
||||||
htons(pQueryMsg->vnode), pTableMeta->sid, pTableMetaInfo->name, tscGetNumOfColumns(pTableMeta), pCol->colIndex,
|
// htons(pQueryMsg->vnode), pTableMeta->sid, pTableMetaInfo->name, tscGetNumOfColumns(pTableMeta), pCol->colIndex,
|
||||||
pColSchema->name);
|
// pColSchema->name);
|
||||||
|
//
|
||||||
return -1; // 0 means build msg failed
|
// return -1; // 0 means build msg failed
|
||||||
}
|
// }
|
||||||
|
|
||||||
pQueryMsg->colList[i].colId = htons(pColSchema->colId);
|
pQueryMsg->colList[i].colId = htons(pColSchema->colId);
|
||||||
pQueryMsg->colList[i].bytes = htons(pColSchema->bytes);
|
pQueryMsg->colList[i].bytes = htons(pColSchema->bytes);
|
||||||
|
@ -865,7 +866,7 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
pQueryMsg->colNameLen = htonl(len);
|
pQueryMsg->colNameLen = htonl(len);
|
||||||
|
|
||||||
// serialize the table info (sid, uid, tags)
|
// serialize the table info (sid, uid, tags)
|
||||||
pMsg = doSerializeTableInfo(pSql, numOfTables, htons(pQueryMsg->vnode), pMsg);
|
pMsg = doSerializeTableInfo(pSql, numOfTables, htons(pQueryMsg->vgId), pMsg);
|
||||||
|
|
||||||
// only include the required tag column schema. If a tag is not required, it won't be sent to vnode
|
// only include the required tag column schema. If a tag is not required, it won't be sent to vnode
|
||||||
if (pTableMetaInfo->numOfTags > 0) {
|
if (pTableMetaInfo->numOfTags > 0) {
|
||||||
|
@ -946,7 +947,9 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
tscTrace("%p msg built success,len:%d bytes", pSql, msgLen);
|
tscTrace("%p msg built success,len:%d bytes", pSql, msgLen);
|
||||||
pCmd->payloadLen = msgLen;
|
pCmd->payloadLen = msgLen;
|
||||||
pSql->cmd.msgType = TSDB_MSG_TYPE_QUERY;
|
pSql->cmd.msgType = TSDB_MSG_TYPE_QUERY;
|
||||||
|
|
||||||
|
pQueryMsg->contLen = htonl(msgLen);
|
||||||
|
|
||||||
assert(msgLen + minMsgSize() <= size);
|
assert(msgLen + minMsgSize() <= size);
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
@ -1849,12 +1852,12 @@ int tscProcessTableMetaRsp(SSqlObj *pSql) {
|
||||||
|
|
||||||
pMetaMsg->sid = htonl(pMetaMsg->sid);
|
pMetaMsg->sid = htonl(pMetaMsg->sid);
|
||||||
pMetaMsg->sversion = htons(pMetaMsg->sversion);
|
pMetaMsg->sversion = htons(pMetaMsg->sversion);
|
||||||
pMetaMsg->vgid = htonl(pMetaMsg->vgid);
|
pMetaMsg->vgId = htonl(pMetaMsg->vgId);
|
||||||
pMetaMsg->uid = htobe64(pMetaMsg->uid);
|
pMetaMsg->uid = htobe64(pMetaMsg->uid);
|
||||||
pMetaMsg->contLen = htons(pMetaMsg->contLen);
|
pMetaMsg->contLen = htons(pMetaMsg->contLen);
|
||||||
|
|
||||||
if (pMetaMsg->sid < 0 || pMetaMsg->vgid < 0) {
|
if (pMetaMsg->sid < 0 || pMetaMsg->vgId < 0) {
|
||||||
tscError("invalid meter vgid:%d, sid%d", pMetaMsg->vgid, pMetaMsg->sid);
|
tscError("invalid meter vgId:%d, sid%d", pMetaMsg->vgId, pMetaMsg->sid);
|
||||||
return TSDB_CODE_INVALID_VALUE;
|
return TSDB_CODE_INVALID_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1948,11 +1951,11 @@ int tscProcessMultiMeterMetaRsp(SSqlObj *pSql) {
|
||||||
|
|
||||||
pMeta->sid = htonl(pMeta->sid);
|
pMeta->sid = htonl(pMeta->sid);
|
||||||
pMeta->sversion = htons(pMeta->sversion);
|
pMeta->sversion = htons(pMeta->sversion);
|
||||||
pMeta->vgid = htonl(pMeta->vgid);
|
pMeta->vgId = htonl(pMeta->vgId);
|
||||||
pMeta->uid = htobe64(pMeta->uid);
|
pMeta->uid = htobe64(pMeta->uid);
|
||||||
|
|
||||||
if (pMeta->sid <= 0 || pMeta->vgid < 0) {
|
if (pMeta->sid <= 0 || pMeta->vgId < 0) {
|
||||||
tscError("invalid meter vgid:%d, sid%d", pMeta->vgid, pMeta->sid);
|
tscError("invalid meter vgId:%d, sid%d", pMeta->vgId, pMeta->sid);
|
||||||
pSql->res.code = TSDB_CODE_INVALID_VALUE;
|
pSql->res.code = TSDB_CODE_INVALID_VALUE;
|
||||||
pSql->res.numOfTotal = i;
|
pSql->res.numOfTotal = i;
|
||||||
return TSDB_CODE_OTHERS;
|
return TSDB_CODE_OTHERS;
|
||||||
|
@ -2067,7 +2070,7 @@ int tscProcessMetricMetaRsp(SSqlObj *pSql) {
|
||||||
pMeta->numOfVnodes = htonl(pMeta->numOfVnodes);
|
pMeta->numOfVnodes = htonl(pMeta->numOfVnodes);
|
||||||
pMeta->tagLen = htons(pMeta->tagLen);
|
pMeta->tagLen = htons(pMeta->tagLen);
|
||||||
|
|
||||||
size += pMeta->numOfVnodes * sizeof(SVnodeSidList *) + pMeta->numOfTables * sizeof(STableSidExtInfo *);
|
size += pMeta->numOfVnodes * sizeof(SVnodeSidList *) + pMeta->numOfTables * sizeof(STableIdInfo *);
|
||||||
|
|
||||||
char *pBuf = calloc(1, size);
|
char *pBuf = calloc(1, size);
|
||||||
if (pBuf == NULL) {
|
if (pBuf == NULL) {
|
||||||
|
@ -2093,16 +2096,16 @@ int tscProcessMetricMetaRsp(SSqlObj *pSql) {
|
||||||
|
|
||||||
tscTrace("%p metricmeta:vid:%d,numOfTables:%d", pSql, i, pLists->numOfSids);
|
tscTrace("%p metricmeta:vid:%d,numOfTables:%d", pSql, i, pLists->numOfSids);
|
||||||
|
|
||||||
pBuf += sizeof(SVnodeSidList) + sizeof(STableSidExtInfo *) * pSidLists->numOfSids;
|
pBuf += sizeof(SVnodeSidList) + sizeof(STableIdInfo *) * pSidLists->numOfSids;
|
||||||
rsp += sizeof(SVnodeSidList);
|
rsp += sizeof(SVnodeSidList);
|
||||||
|
|
||||||
size_t elemSize = sizeof(STableSidExtInfo) + pNewMetricMeta->tagLen;
|
size_t elemSize = sizeof(STableIdInfo) + pNewMetricMeta->tagLen;
|
||||||
for (int32_t j = 0; j < pSidLists->numOfSids; ++j) {
|
for (int32_t j = 0; j < pSidLists->numOfSids; ++j) {
|
||||||
pLists->pSidExtInfoList[j] = pBuf - (char *)pLists;
|
pLists->pSidExtInfoList[j] = pBuf - (char *)pLists;
|
||||||
memcpy(pBuf, rsp, elemSize);
|
memcpy(pBuf, rsp, elemSize);
|
||||||
|
|
||||||
((STableSidExtInfo *)pBuf)->uid = htobe64(((STableSidExtInfo *)pBuf)->uid);
|
((STableIdInfo *)pBuf)->uid = htobe64(((STableIdInfo *)pBuf)->uid);
|
||||||
((STableSidExtInfo *)pBuf)->sid = htonl(((STableSidExtInfo *)pBuf)->sid);
|
((STableIdInfo *)pBuf)->sid = htonl(((STableIdInfo *)pBuf)->sid);
|
||||||
|
|
||||||
rsp += elemSize;
|
rsp += elemSize;
|
||||||
pBuf += elemSize;
|
pBuf += elemSize;
|
||||||
|
|
|
@ -130,7 +130,7 @@ STscObj *taosConnectImpl(const char *ip, const char *user, const char *pass, con
|
||||||
pSql->pTscObj = pObj;
|
pSql->pTscObj = pObj;
|
||||||
pSql->signature = pSql;
|
pSql->signature = pSql;
|
||||||
tsem_init(&pSql->rspSem, 0, 0);
|
tsem_init(&pSql->rspSem, 0, 0);
|
||||||
// tsem_init(&pSql->emptyRspSem, 0, 1);
|
|
||||||
pObj->pSql = pSql;
|
pObj->pSql = pSql;
|
||||||
pSql->fp = fp;
|
pSql->fp = fp;
|
||||||
pSql->param = param;
|
pSql->param = param;
|
||||||
|
@ -146,6 +146,8 @@ STscObj *taosConnectImpl(const char *ip, const char *user, const char *pass, con
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// tsRpcHeaderSize will be updated during RPC initialization, so only after it initialization, this value is valid
|
||||||
|
tsInsertHeadSize = tsRpcHeadSize + sizeof(SMsgDesc) + sizeof(SSubmitMsg);
|
||||||
return pObj;
|
return pObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -202,7 +202,7 @@ int tscUpdateSubscription(STscObj* pObj, SSub* pSub) {
|
||||||
for (int32_t i = 0; i < pMetricMeta->numOfVnodes; i++) {
|
for (int32_t i = 0; i < pMetricMeta->numOfVnodes; i++) {
|
||||||
SVnodeSidList *pVnodeSidList = tscGetVnodeSidList(pMetricMeta, i);
|
SVnodeSidList *pVnodeSidList = tscGetVnodeSidList(pMetricMeta, i);
|
||||||
for (int32_t j = 0; j < pVnodeSidList->numOfSids; j++) {
|
for (int32_t j = 0; j < pVnodeSidList->numOfSids; j++) {
|
||||||
STableSidExtInfo *pTableMetaInfo = tscGetMeterSidInfo(pVnodeSidList, j);
|
STableIdInfo *pTableMetaInfo = tscGetMeterSidInfo(pVnodeSidList, j);
|
||||||
int64_t uid = pTableMetaInfo->uid;
|
int64_t uid = pTableMetaInfo->uid;
|
||||||
progress[numOfTables].uid = uid;
|
progress[numOfTables].uid = uid;
|
||||||
progress[numOfTables++].key = tscGetSubscriptionProgress(pSub, uid);
|
progress[numOfTables++].key = tscGetSubscriptionProgress(pSub, uid);
|
||||||
|
|
|
@ -34,7 +34,6 @@ void * pTscMgmtConn;
|
||||||
void * pSlaveConn;
|
void * pSlaveConn;
|
||||||
void * tscCacheHandle;
|
void * tscCacheHandle;
|
||||||
int32_t globalCode = 0;
|
int32_t globalCode = 0;
|
||||||
int initialized = 0;
|
|
||||||
int slaveIndex;
|
int slaveIndex;
|
||||||
void * tscTmr;
|
void * tscTmr;
|
||||||
void * tscQhandle;
|
void * tscQhandle;
|
||||||
|
@ -187,9 +186,7 @@ void taos_init_imp() {
|
||||||
|
|
||||||
if (tscCacheHandle == NULL) tscCacheHandle = taosCacheInit(tscTmr, refreshTime);
|
if (tscCacheHandle == NULL) tscCacheHandle = taosCacheInit(tscTmr, refreshTime);
|
||||||
|
|
||||||
initialized = 1;
|
|
||||||
tscTrace("client is initialized successfully");
|
tscTrace("client is initialized successfully");
|
||||||
tsInsertHeadSize = tsRpcHeadSize + sizeof(SShellSubmitMsg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void taos_init() { pthread_once(&tscinit, taos_init_imp); }
|
void taos_init() { pthread_once(&tscinit, taos_init_imp); }
|
||||||
|
|
|
@ -191,7 +191,7 @@ SVnodeSidList* tscGetVnodeSidList(SSuperTableMeta* pMetricmeta, int32_t vnodeIdx
|
||||||
return (SVnodeSidList*)(pMetricmeta->list[vnodeIdx] + (char*)pMetricmeta);
|
return (SVnodeSidList*)(pMetricmeta->list[vnodeIdx] + (char*)pMetricmeta);
|
||||||
}
|
}
|
||||||
|
|
||||||
STableSidExtInfo* tscGetMeterSidInfo(SVnodeSidList* pSidList, int32_t idx) {
|
STableIdInfo* tscGetMeterSidInfo(SVnodeSidList* pSidList, int32_t idx) {
|
||||||
if (pSidList == NULL) {
|
if (pSidList == NULL) {
|
||||||
tscError("illegal sidlist");
|
tscError("illegal sidlist");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -206,7 +206,7 @@ STableSidExtInfo* tscGetMeterSidInfo(SVnodeSidList* pSidList, int32_t idx) {
|
||||||
|
|
||||||
assert(pSidList->pSidExtInfoList[idx] >= 0);
|
assert(pSidList->pSidExtInfoList[idx] >= 0);
|
||||||
|
|
||||||
return (STableSidExtInfo*)(pSidList->pSidExtInfoList[idx] + (char*)pSidList);
|
return (STableIdInfo*)(pSidList->pSidExtInfoList[idx] + (char*)pSidList);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tscIsTwoStageSTableQuery(SQueryInfo* pQueryInfo, int32_t tableIndex) {
|
bool tscIsTwoStageSTableQuery(SQueryInfo* pQueryInfo, int32_t tableIndex) {
|
||||||
|
@ -614,7 +614,7 @@ int32_t tscCopyDataBlockToPayload(SSqlObj* pSql, STableDataBlocks* pDataBlock) {
|
||||||
*/
|
*/
|
||||||
pCmd->payloadLen = pDataBlock->nAllocSize - tsRpcHeadSize;
|
pCmd->payloadLen = pDataBlock->nAllocSize - tsRpcHeadSize;
|
||||||
|
|
||||||
assert(pCmd->allocSize >= pCmd->payloadLen + tsRpcHeadSize + 100);
|
assert(pCmd->allocSize >= pCmd->payloadLen + tsRpcHeadSize + 100 && pCmd->payloadLen > 0);
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -695,6 +695,49 @@ int32_t tscGetDataBlockFromList(void* pHashList, SDataBlockList* pDataBlockList,
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void trimDataBlock(void* pDataBlock, STableDataBlocks* pTableDataBlock) {
|
||||||
|
int32_t firstPartLen = 0;
|
||||||
|
|
||||||
|
STableMeta* pTableMeta = pTableDataBlock->pTableMeta;
|
||||||
|
STableComInfo tinfo = tscGetTableInfo(pTableMeta);
|
||||||
|
SSchema* pSchema = tscGetTableSchema(pTableMeta);
|
||||||
|
|
||||||
|
memcpy(pDataBlock, pTableDataBlock->pData, sizeof(SSubmitBlk));
|
||||||
|
pDataBlock += sizeof(SSubmitBlk);
|
||||||
|
|
||||||
|
int32_t total = sizeof(int32_t)*2;
|
||||||
|
for(int32_t i = 0; i < tinfo.numOfColumns; ++i) {
|
||||||
|
switch (pSchema[i].type) {
|
||||||
|
case TSDB_DATA_TYPE_NCHAR:
|
||||||
|
case TSDB_DATA_TYPE_BINARY: {
|
||||||
|
assert(0); // not support binary yet
|
||||||
|
firstPartLen += sizeof(int32_t);break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
firstPartLen += tDataTypeDesc[pSchema[i].type].nSize;
|
||||||
|
total += tDataTypeDesc[pSchema[i].type].nSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char* p = pTableDataBlock->pData + sizeof(SSubmitBlk);
|
||||||
|
|
||||||
|
SSubmitBlk* pBlock = pTableDataBlock->pData;
|
||||||
|
int32_t rows = htons(pBlock->numOfRows);
|
||||||
|
|
||||||
|
for(int32_t i = 0; i < rows; ++i) {
|
||||||
|
*(int32_t*) pDataBlock = total;
|
||||||
|
pDataBlock += sizeof(int32_t);
|
||||||
|
|
||||||
|
*(int32_t*) pDataBlock = firstPartLen;
|
||||||
|
pDataBlock += sizeof(int32_t);
|
||||||
|
|
||||||
|
memcpy(pDataBlock, p, pTableDataBlock->rowSize);
|
||||||
|
|
||||||
|
p += pTableDataBlock->rowSize;
|
||||||
|
pDataBlock += pTableDataBlock->rowSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int32_t tscMergeTableDataBlocks(SSqlObj* pSql, SDataBlockList* pTableDataBlockList) {
|
int32_t tscMergeTableDataBlocks(SSqlObj* pSql, SDataBlockList* pTableDataBlockList) {
|
||||||
SSqlCmd* pCmd = &pSql->cmd;
|
SSqlCmd* pCmd = &pSql->cmd;
|
||||||
|
|
||||||
|
@ -705,8 +748,9 @@ int32_t tscMergeTableDataBlocks(SSqlObj* pSql, SDataBlockList* pTableDataBlockLi
|
||||||
STableDataBlocks* pOneTableBlock = pTableDataBlockList->pData[i];
|
STableDataBlocks* pOneTableBlock = pTableDataBlockList->pData[i];
|
||||||
|
|
||||||
STableDataBlocks* dataBuf = NULL;
|
STableDataBlocks* dataBuf = NULL;
|
||||||
int32_t ret =
|
|
||||||
tscGetDataBlockFromList(pVnodeDataBlockHashList, pVnodeDataBlockList, pOneTableBlock->vgid, TSDB_PAYLOAD_SIZE,
|
int32_t ret =
|
||||||
|
tscGetDataBlockFromList(pVnodeDataBlockHashList, pVnodeDataBlockList, pOneTableBlock->vgId, TSDB_PAYLOAD_SIZE,
|
||||||
tsInsertHeadSize, 0, pOneTableBlock->tableId, pOneTableBlock->pTableMeta, &dataBuf);
|
tsInsertHeadSize, 0, pOneTableBlock->tableId, pOneTableBlock->pTableMeta, &dataBuf);
|
||||||
if (ret != TSDB_CODE_SUCCESS) {
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
tscError("%p failed to prepare the data block buffer for merging table data, code:%d", pSql, ret);
|
tscError("%p failed to prepare the data block buffer for merging table data, code:%d", pSql, ret);
|
||||||
|
@ -715,7 +759,7 @@ int32_t tscMergeTableDataBlocks(SSqlObj* pSql, SDataBlockList* pTableDataBlockLi
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t destSize = dataBuf->size + pOneTableBlock->size;
|
int64_t destSize = dataBuf->size + pOneTableBlock->size + pOneTableBlock->size*sizeof(int32_t)*2;
|
||||||
if (dataBuf->nAllocSize < destSize) {
|
if (dataBuf->nAllocSize < destSize) {
|
||||||
while (dataBuf->nAllocSize < destSize) {
|
while (dataBuf->nAllocSize < destSize) {
|
||||||
dataBuf->nAllocSize = dataBuf->nAllocSize * 1.5;
|
dataBuf->nAllocSize = dataBuf->nAllocSize * 1.5;
|
||||||
|
@ -729,29 +773,33 @@ int32_t tscMergeTableDataBlocks(SSqlObj* pSql, SDataBlockList* pTableDataBlockLi
|
||||||
tscError("%p failed to allocate memory for merging submit block, size:%d", pSql, dataBuf->nAllocSize);
|
tscError("%p failed to allocate memory for merging submit block, size:%d", pSql, dataBuf->nAllocSize);
|
||||||
|
|
||||||
taosHashCleanup(pVnodeDataBlockHashList);
|
taosHashCleanup(pVnodeDataBlockHashList);
|
||||||
tfree(dataBuf->pData);
|
|
||||||
tscDestroyBlockArrayList(pVnodeDataBlockList);
|
tscDestroyBlockArrayList(pVnodeDataBlockList);
|
||||||
|
tfree(dataBuf->pData);
|
||||||
|
|
||||||
return TSDB_CODE_CLI_OUT_OF_MEMORY;
|
return TSDB_CODE_CLI_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SShellSubmitBlock* pBlocks = (SShellSubmitBlock*)pOneTableBlock->pData;
|
SSubmitBlk* pBlocks = (SSubmitBlk*) pOneTableBlock->pData;
|
||||||
sortRemoveDuplicates(pOneTableBlock);
|
sortRemoveDuplicates(pOneTableBlock);
|
||||||
|
|
||||||
char* e = (char*)pBlocks->payLoad + pOneTableBlock->rowSize*(pBlocks->numOfRows-1);
|
char* e = (char*)pBlocks->data + pOneTableBlock->rowSize*(pBlocks->numOfRows-1);
|
||||||
|
|
||||||
tscTrace("%p tableId:%s, sid:%d rows:%d sversion:%d skey:%" PRId64 ", ekey:%" PRId64, pSql, pOneTableBlock->tableId, pBlocks->sid,
|
tscTrace("%p tableId:%s, sid:%d rows:%d sversion:%d skey:%" PRId64 ", ekey:%" PRId64, pSql, pOneTableBlock->tableId,
|
||||||
pBlocks->numOfRows, pBlocks->sversion, GET_INT64_VAL(pBlocks->payLoad), GET_INT64_VAL(e));
|
pBlocks->tid, pBlocks->numOfRows, pBlocks->sversion, GET_INT64_VAL(pBlocks->data), GET_INT64_VAL(e));
|
||||||
|
|
||||||
pBlocks->sid = htonl(pBlocks->sid);
|
int32_t len = pBlocks->numOfRows * (pOneTableBlock->rowSize + sizeof(int32_t) * 2);
|
||||||
|
|
||||||
|
pBlocks->tid = htonl(pBlocks->tid);
|
||||||
pBlocks->uid = htobe64(pBlocks->uid);
|
pBlocks->uid = htobe64(pBlocks->uid);
|
||||||
pBlocks->sversion = htonl(pBlocks->sversion);
|
pBlocks->sversion = htonl(pBlocks->sversion);
|
||||||
pBlocks->numOfRows = htons(pBlocks->numOfRows);
|
pBlocks->numOfRows = htons(pBlocks->numOfRows);
|
||||||
|
|
||||||
memcpy(dataBuf->pData + dataBuf->size, pOneTableBlock->pData, pOneTableBlock->size);
|
pBlocks->len = htonl(len);
|
||||||
|
|
||||||
dataBuf->size += pOneTableBlock->size;
|
// erase the empty space reserved for binary data
|
||||||
|
trimDataBlock(dataBuf->pData + dataBuf->size, pOneTableBlock);
|
||||||
|
dataBuf->size += (len + sizeof(SSubmitBlk));
|
||||||
dataBuf->numOfTables += 1;
|
dataBuf->numOfTables += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -81,11 +81,13 @@ STSchema *tdDecodeSchema(void **psrc);
|
||||||
*/
|
*/
|
||||||
typedef void *SDataRow;
|
typedef void *SDataRow;
|
||||||
|
|
||||||
|
|
||||||
#define TD_DATA_ROW_HEAD_SIZE (2 * sizeof(int32_t))
|
#define TD_DATA_ROW_HEAD_SIZE (2 * sizeof(int32_t))
|
||||||
|
|
||||||
#define dataRowLen(r) (*(int32_t *)(r))
|
#define dataRowLen(r) (*(int32_t *)(r))
|
||||||
#define dataRowFLen(r) (*(int32_t *)((char *)(r) + sizeof(int32_t)))
|
#define dataRowFLen(r) (*(int32_t *)((char *)(r) + sizeof(int32_t)))
|
||||||
#define dataRowTuple(r) ((char *)(r) + TD_DATA_ROW_HEAD_SIZE)
|
#define dataRowTuple(r) ((char *)(r) + TD_DATA_ROW_HEAD_SIZE)
|
||||||
|
#define dataRowKey(r) (*(TSKEY *)(dataRowTuple(r)))
|
||||||
#define dataRowSetLen(r, l) (dataRowLen(r) = (l))
|
#define dataRowSetLen(r, l) (dataRowLen(r) = (l))
|
||||||
#define dataRowSetFLen(r, l) (dataRowFLen(r) = (l))
|
#define dataRowSetFLen(r, l) (dataRowFLen(r) = (l))
|
||||||
#define dataRowIdx(r, i) ((char *)(r) + i)
|
#define dataRowIdx(r, i) ((char *)(r) + i)
|
||||||
|
@ -101,23 +103,13 @@ int tdAppendColVal(SDataRow row, void *value, STColumn *pCol);
|
||||||
void tdDataRowReset(SDataRow row, STSchema *pSchema);
|
void tdDataRowReset(SDataRow row, STSchema *pSchema);
|
||||||
SDataRow tdDataRowDup(SDataRow row);
|
SDataRow tdDataRowDup(SDataRow row);
|
||||||
|
|
||||||
/* Data column definition
|
// ----------------- Data column structure
|
||||||
* +---------+---------+-----------------------+
|
typedef struct SDataCol {
|
||||||
* | int32_t | int32_t | |
|
int64_t len;
|
||||||
* +---------+---------+-----------------------+
|
char data[];
|
||||||
* | len | npoints | data |
|
} SDataCol;
|
||||||
* +---------+---------+-----------------------+
|
|
||||||
*/
|
|
||||||
typedef char *SDataCol;
|
|
||||||
|
|
||||||
/* Data columns definition
|
void tdConvertDataRowToCol(SDataCol *cols, STSchema *pSchema, int *iter);
|
||||||
* +---------+---------+-----------------------+--------+-----------------------+
|
|
||||||
* | int32_t | int32_t | | | |
|
|
||||||
* +---------+---------+-----------------------+--------+-----------------------+
|
|
||||||
* | len | npoints | SDataCol | .... | SDataCol |
|
|
||||||
* +---------+---------+-----------------------+--------+-----------------------+
|
|
||||||
*/
|
|
||||||
typedef char *SDataCols;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,7 +150,7 @@ void tdFreeSchema(STSchema *pSchema) {
|
||||||
*/
|
*/
|
||||||
void tdUpdateSchema(STSchema *pSchema) {
|
void tdUpdateSchema(STSchema *pSchema) {
|
||||||
STColumn *pCol = NULL;
|
STColumn *pCol = NULL;
|
||||||
int32_t offset = 0;
|
int32_t offset = TD_DATA_ROW_HEAD_SIZE;
|
||||||
for (int i = 0; i < schemaNCols(pSchema); i++) {
|
for (int i = 0; i < schemaNCols(pSchema); i++) {
|
||||||
pCol = schemaColAt(pSchema, i);
|
pCol = schemaColAt(pSchema, i);
|
||||||
colSetOffset(pCol, offset);
|
colSetOffset(pCol, offset);
|
||||||
|
@ -294,6 +294,16 @@ SDataRow tdDataRowDup(SDataRow row) {
|
||||||
return trow;
|
return trow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tdConvertDataRowToCol(SDataCol *cols, STSchema *pSchema, int *iter) {
|
||||||
|
int row = *iter;
|
||||||
|
|
||||||
|
for (int i = 0; i < schemaNCols(pSchema); i++) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
*iter = row + 1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the first part length of a data row for a schema
|
* Return the first part length of a data row for a schema
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -15,13 +15,16 @@
|
||||||
|
|
||||||
#define _DEFAULT_SOURCE
|
#define _DEFAULT_SOURCE
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
|
||||||
#include "taoserror.h"
|
#include "taoserror.h"
|
||||||
#include "taosmsg.h"
|
#include "taosmsg.h"
|
||||||
#include "tlog.h"
|
#include "tlog.h"
|
||||||
#include "tqueue.h"
|
#include "tqueue.h"
|
||||||
#include "trpc.h"
|
#include "trpc.h"
|
||||||
#include "dnodeRead.h"
|
|
||||||
#include "dnodeMgmt.h"
|
#include "dnodeMgmt.h"
|
||||||
|
#include "dnodeRead.h"
|
||||||
|
#include "queryExecutor.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int32_t code;
|
int32_t code;
|
||||||
|
@ -74,7 +77,9 @@ void dnodeRead(SRpcMsg *pMsg) {
|
||||||
int32_t leftLen = pMsg->contLen;
|
int32_t leftLen = pMsg->contLen;
|
||||||
char *pCont = (char *) pMsg->pCont;
|
char *pCont = (char *) pMsg->pCont;
|
||||||
SRpcContext *pRpcContext = NULL;
|
SRpcContext *pRpcContext = NULL;
|
||||||
|
|
||||||
|
dTrace("dnode read msg disposal");
|
||||||
|
|
||||||
// SMsgDesc *pDesc = pCont;
|
// SMsgDesc *pDesc = pCont;
|
||||||
// pDesc->numOfVnodes = htonl(pDesc->numOfVnodes);
|
// pDesc->numOfVnodes = htonl(pDesc->numOfVnodes);
|
||||||
// pCont += sizeof(SMsgDesc);
|
// pCont += sizeof(SMsgDesc);
|
||||||
|
@ -88,7 +93,7 @@ void dnodeRead(SRpcMsg *pMsg) {
|
||||||
|
|
||||||
while (leftLen > 0) {
|
while (leftLen > 0) {
|
||||||
SMsgHead *pHead = (SMsgHead *) pCont;
|
SMsgHead *pHead = (SMsgHead *) pCont;
|
||||||
pHead->vgId = 1; //htonl(pHead->vgId);
|
pHead->vgId = 1;//htonl(pHead->vgId);
|
||||||
pHead->contLen = pMsg->contLen; //htonl(pHead->contLen);
|
pHead->contLen = pMsg->contLen; //htonl(pHead->contLen);
|
||||||
|
|
||||||
void *pVnode = dnodeGetVnode(pHead->vgId);
|
void *pVnode = dnodeGetVnode(pHead->vgId);
|
||||||
|
@ -223,43 +228,81 @@ static void dnodeProcessReadResult(SReadMsg *pRead) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dnodeProcessQueryMsg(SReadMsg *pMsg) {
|
static void dnodeProcessQueryMsg(SReadMsg *pMsg) {
|
||||||
void *pQInfo = (void*)100;
|
SQueryTableMsg* pQueryTableMsg = (SQueryTableMsg*) pMsg->pCont;
|
||||||
dTrace("query msg is disposed, qInfo:%p", pQInfo);
|
|
||||||
|
SQInfo* pQInfo = NULL;
|
||||||
|
void* tsdb = dnodeGetVnodeTsdb(pMsg->pVnode);
|
||||||
|
int32_t code = qCreateQueryInfo(tsdb, pQueryTableMsg, &pQInfo);
|
||||||
|
|
||||||
SQueryTableRsp *pRsp = (SQueryTableRsp *) rpcMallocCont(sizeof(SQueryTableRsp));
|
SQueryTableRsp *pRsp = (SQueryTableRsp *) rpcMallocCont(sizeof(SQueryTableRsp));
|
||||||
pRsp->code = 0;
|
pRsp->code = code;
|
||||||
pRsp->qhandle = htobe64((uint64_t) (pQInfo));
|
pRsp->qhandle = htobe64((uint64_t) (pQInfo));
|
||||||
|
|
||||||
SRpcMsg rpcRsp = {
|
SRpcMsg rpcRsp = {
|
||||||
.handle = pMsg->rpcMsg.handle,
|
.handle = pMsg->rpcMsg.handle,
|
||||||
.pCont = pRsp,
|
.pCont = pRsp,
|
||||||
.contLen = sizeof(SQueryTableRsp),
|
.contLen = sizeof(SQueryTableRsp),
|
||||||
.code = 0,
|
.code = code,
|
||||||
.msgType = 0
|
.msgType = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
rpcSendResponse(&rpcRsp);
|
rpcSendResponse(&rpcRsp);
|
||||||
|
|
||||||
|
// do execute query
|
||||||
|
qTableQuery(pQInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dnodeProcessRetrieveMsg(SReadMsg *pMsg) {
|
static void dnodeProcessRetrieveMsg(SReadMsg *pMsg) {
|
||||||
SRetrieveTableMsg *pRetrieve = pMsg->pCont;
|
SRetrieveTableMsg *pRetrieve = pMsg->pCont;
|
||||||
void *pQInfo = htobe64(pRetrieve->qhandle);
|
void *pQInfo = htobe64(pRetrieve->qhandle);
|
||||||
|
|
||||||
dTrace("retrieve msg is disposed, qInfo:%p", pQInfo);
|
dTrace("QInfo:%p vgId:%d, retrieve msg is received", pQInfo, pRetrieve->header.vgId);
|
||||||
|
|
||||||
assert(pQInfo != NULL);
|
int32_t rowSize = 0;
|
||||||
int32_t contLen = 100;
|
int32_t numOfRows = 0;
|
||||||
SRetrieveTableRsp *pRsp = (SRetrieveTableRsp *) rpcMallocCont(contLen);
|
int32_t contLen = 0;
|
||||||
pRsp->numOfRows = 0;
|
|
||||||
pRsp->precision = 0;
|
SRpcMsg rpcRsp = {0};
|
||||||
pRsp->offset = 0;
|
|
||||||
pRsp->useconds = 0;
|
int32_t code = qRetrieveQueryResultInfo(pQInfo, &numOfRows, &rowSize);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
SRpcMsg rpcRsp = {
|
contLen = sizeof(SRetrieveTableRsp);
|
||||||
.handle = pMsg->rpcMsg.handle,
|
|
||||||
.pCont = pRsp,
|
SRetrieveTableRsp *pRsp = (SRetrieveTableRsp *)rpcMallocCont(contLen);
|
||||||
.contLen = contLen,
|
pRsp->numOfRows = 0;
|
||||||
.code = 0,
|
pRsp->precision = 0;
|
||||||
.msgType = 0
|
pRsp->offset = 0;
|
||||||
};
|
pRsp->useconds = 0;
|
||||||
|
|
||||||
|
rpcRsp = (SRpcMsg) {
|
||||||
|
.handle = pMsg->rpcMsg.handle,
|
||||||
|
.pCont = pRsp,
|
||||||
|
.contLen = contLen,
|
||||||
|
.code = code,
|
||||||
|
.msgType = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
//todo free qinfo
|
||||||
|
} else {
|
||||||
|
contLen = 100;
|
||||||
|
|
||||||
|
SRetrieveTableRsp *pRsp = (SRetrieveTableRsp *)rpcMallocCont(contLen);
|
||||||
|
pRsp->numOfRows = htonl(1);
|
||||||
|
pRsp->precision = htons(0);
|
||||||
|
pRsp->offset = htobe64(0);
|
||||||
|
pRsp->useconds = htobe64(0);
|
||||||
|
|
||||||
|
// todo set the data
|
||||||
|
*(int64_t*) pRsp->data = 1000;
|
||||||
|
|
||||||
|
rpcRsp = (SRpcMsg) {
|
||||||
|
.handle = pMsg->rpcMsg.handle,
|
||||||
|
.pCont = pRsp,
|
||||||
|
.contLen = contLen,
|
||||||
|
.code = code,
|
||||||
|
.msgType = 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
rpcSendResponse(&rpcRsp);
|
rpcSendResponse(&rpcRsp);
|
||||||
}
|
}
|
||||||
|
|
|
@ -275,7 +275,12 @@ static void dnodeProcessSubmitMsg(SWriteMsg *pMsg) {
|
||||||
pRsp->numOfRows = htonl(1);
|
pRsp->numOfRows = htonl(1);
|
||||||
pRsp->affectedRows = htonl(1);
|
pRsp->affectedRows = htonl(1);
|
||||||
pRsp->numOfFailedBlocks = 0;
|
pRsp->numOfFailedBlocks = 0;
|
||||||
|
|
||||||
|
void* tsdb = dnodeGetVnodeTsdb(pMsg->pVnode);
|
||||||
|
assert(tsdb != NULL);
|
||||||
|
|
||||||
|
tsdbInsertData(tsdb, pMsg->pCont);
|
||||||
|
|
||||||
SRpcMsg rpcRsp = {
|
SRpcMsg rpcRsp = {
|
||||||
.handle = pMsg->rpcMsg.handle,
|
.handle = pMsg->rpcMsg.handle,
|
||||||
.pCont = pRsp,
|
.pCont = pRsp,
|
||||||
|
@ -283,6 +288,7 @@ static void dnodeProcessSubmitMsg(SWriteMsg *pMsg) {
|
||||||
.code = 0,
|
.code = 0,
|
||||||
.msgType = 0
|
.msgType = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
rpcSendResponse(&rpcRsp);
|
rpcSendResponse(&rpcRsp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -188,21 +188,51 @@ extern char *taosMsg[];
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
|
|
||||||
typedef struct {
|
//typedef struct {
|
||||||
int32_t vnode;
|
// int32_t vnode;
|
||||||
int32_t sid;
|
// int32_t sid;
|
||||||
int32_t sversion;
|
// int32_t sversion;
|
||||||
uint64_t uid;
|
// uint64_t uid;
|
||||||
int16_t numOfRows;
|
// int16_t numOfRows;
|
||||||
char payLoad[];
|
// char payLoad[];
|
||||||
} SShellSubmitBlock;
|
//} SShellSubmitBlock;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int16_t import;
|
int32_t numOfVnodes;
|
||||||
int16_t vnode;
|
} SMsgDesc;
|
||||||
int32_t numOfSid; /* total number of sid */
|
|
||||||
char blks[]; /* numOfSid blocks, each blocks for one table */
|
typedef struct SMsgHead {
|
||||||
} SShellSubmitMsg;
|
int32_t contLen;
|
||||||
|
int32_t vgId;
|
||||||
|
} SMsgHead;
|
||||||
|
|
||||||
|
//typedef struct {
|
||||||
|
// SMsgDesc desc;
|
||||||
|
// SMsgHead header;
|
||||||
|
// int16_t import;
|
||||||
|
// int32_t numOfTables; // total number of sid
|
||||||
|
// char blks[]; // number of data blocks, each table has at least one data block
|
||||||
|
//} SShellSubmitMsg;
|
||||||
|
|
||||||
|
// Submit message for one table
|
||||||
|
typedef struct SSubmitBlk {
|
||||||
|
int64_t uid; // table unique id
|
||||||
|
int32_t tid; // table id
|
||||||
|
int32_t padding; // TODO just for padding here
|
||||||
|
int32_t sversion; // data schema version
|
||||||
|
int32_t len; // data part length, not including the SSubmitBlk head
|
||||||
|
int16_t numOfRows; // total number of rows in current submit block
|
||||||
|
char data[];
|
||||||
|
} SSubmitBlk;
|
||||||
|
|
||||||
|
// Submit message for this TSDB
|
||||||
|
typedef struct SSubmitMsg {
|
||||||
|
SMsgHead header;
|
||||||
|
int32_t length;
|
||||||
|
int32_t compressed:2;
|
||||||
|
int32_t numOfBlocks:30;
|
||||||
|
SSubmitBlk blocks[];
|
||||||
|
} SSubmitMsg;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int32_t index; // index of failed block in submit blocks
|
int32_t index; // index of failed block in submit blocks
|
||||||
|
@ -232,15 +262,6 @@ typedef struct {
|
||||||
uint32_t ip;
|
uint32_t ip;
|
||||||
} SVnodeDesc;
|
} SVnodeDesc;
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int32_t numOfVnodes;
|
|
||||||
} SMsgDesc;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int32_t contLen;
|
|
||||||
int32_t vgId;
|
|
||||||
} SMsgHead;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int32_t contLen;
|
int32_t contLen;
|
||||||
int32_t vgId;
|
int32_t vgId;
|
||||||
|
@ -434,15 +455,11 @@ typedef struct SColumnInfo {
|
||||||
SColumnFilterInfo *filters;
|
SColumnFilterInfo *filters;
|
||||||
} SColumnInfo;
|
} SColumnInfo;
|
||||||
|
|
||||||
/*
|
typedef struct STableIdInfo {
|
||||||
* enable vnode to understand how to group several tables with different tag;
|
|
||||||
*/
|
|
||||||
typedef struct STableSidExtInfo {
|
|
||||||
int32_t sid;
|
int32_t sid;
|
||||||
int64_t uid;
|
int64_t uid;
|
||||||
TSKEY key; // key for subscription
|
TSKEY key; // last accessed ts, for subscription
|
||||||
char tags[];
|
} STableIdInfo;
|
||||||
} STableSidExtInfo;
|
|
||||||
|
|
||||||
typedef struct STimeWindow {
|
typedef struct STimeWindow {
|
||||||
TSKEY skey;
|
TSKEY skey;
|
||||||
|
@ -455,10 +472,10 @@ typedef struct STimeWindow {
|
||||||
* the outputCols will be 3 while the numOfCols is 1.
|
* the outputCols will be 3 while the numOfCols is 1.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int16_t vnode;
|
int32_t contLen; // msg header
|
||||||
|
int16_t vgId;
|
||||||
|
|
||||||
int32_t numOfTables;
|
int32_t numOfTables;
|
||||||
uint64_t pSidExtInfo; // table id & tag info ptr, in windows pointer may
|
|
||||||
|
|
||||||
uint64_t uid;
|
uint64_t uid;
|
||||||
STimeWindow window;
|
STimeWindow window;
|
||||||
|
|
||||||
|
@ -504,19 +521,21 @@ typedef struct {
|
||||||
} SQueryTableMsg;
|
} SQueryTableMsg;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char code;
|
int32_t code;
|
||||||
uint64_t qhandle;
|
uint64_t qhandle;
|
||||||
} SQueryTableRsp;
|
} SQueryTableRsp;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
SMsgHead header;
|
||||||
uint64_t qhandle;
|
uint64_t qhandle;
|
||||||
uint16_t free;
|
uint16_t free;
|
||||||
} SRetrieveTableMsg;
|
} SRetrieveTableMsg;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct SRetrieveTableRsp {
|
||||||
int32_t numOfRows;
|
int32_t numOfRows;
|
||||||
|
int8_t completed; // all results are returned to client
|
||||||
int16_t precision;
|
int16_t precision;
|
||||||
int64_t offset; // updated offset value for multi-vnode projection query
|
int64_t offset; // updated offset value for multi-vnode projection query
|
||||||
int64_t useconds;
|
int64_t useconds;
|
||||||
char data[];
|
char data[];
|
||||||
} SRetrieveTableRsp;
|
} SRetrieveTableRsp;
|
||||||
|
@ -670,7 +689,7 @@ typedef struct {
|
||||||
SVnodeDesc vpeerDesc[TSDB_VNODES_SUPPORT];
|
SVnodeDesc vpeerDesc[TSDB_VNODES_SUPPORT];
|
||||||
int16_t index; // used locally
|
int16_t index; // used locally
|
||||||
int32_t numOfSids;
|
int32_t numOfSids;
|
||||||
int32_t pSidExtInfoList[]; // offset value of STableSidExtInfo
|
int32_t pSidExtInfoList[]; // offset value of STableIdInfo
|
||||||
} SVnodeSidList;
|
} SVnodeSidList;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -692,7 +711,7 @@ typedef struct STableMetaMsg {
|
||||||
int8_t numOfVpeers;
|
int8_t numOfVpeers;
|
||||||
SVnodeDesc vpeerDesc[TSDB_VNODES_SUPPORT];
|
SVnodeDesc vpeerDesc[TSDB_VNODES_SUPPORT];
|
||||||
int32_t sid;
|
int32_t sid;
|
||||||
int32_t vgid;
|
int32_t vgId;
|
||||||
uint64_t uid;
|
uint64_t uid;
|
||||||
SSchema schema[];
|
SSchema schema[];
|
||||||
} STableMetaMsg;
|
} STableMetaMsg;
|
||||||
|
|
|
@ -413,7 +413,7 @@ int32_t mgmtModifyChildTableTagValueByName(SChildTableObj *pTable, char *tagName
|
||||||
int32_t mgmtGetChildTableMeta(SDbObj *pDb, SChildTableObj *pTable, STableMetaMsg *pMeta, bool usePublicIp) {
|
int32_t mgmtGetChildTableMeta(SDbObj *pDb, SChildTableObj *pTable, STableMetaMsg *pMeta, bool usePublicIp) {
|
||||||
pMeta->uid = htobe64(pTable->uid);
|
pMeta->uid = htobe64(pTable->uid);
|
||||||
pMeta->sid = htonl(pTable->sid);
|
pMeta->sid = htonl(pTable->sid);
|
||||||
pMeta->vgid = htonl(pTable->vgId);
|
pMeta->vgId = htonl(pTable->vgId);
|
||||||
pMeta->sversion = htons(pTable->superTable->sversion);
|
pMeta->sversion = htons(pTable->superTable->sversion);
|
||||||
pMeta->precision = pDb->cfg.precision;
|
pMeta->precision = pDb->cfg.precision;
|
||||||
pMeta->numOfTags = pTable->superTable->numOfTags;
|
pMeta->numOfTags = pTable->superTable->numOfTags;
|
||||||
|
|
|
@ -553,11 +553,14 @@ void mgmtProcessDnodeStatusMsg(SRpcMsg *rpcMsg) {
|
||||||
pDnode->privateIp = htonl(pStatus->privateIp);
|
pDnode->privateIp = htonl(pStatus->privateIp);
|
||||||
pDnode->publicIp = htonl(pStatus->publicIp);
|
pDnode->publicIp = htonl(pStatus->publicIp);
|
||||||
pDnode->lastReboot = htonl(pStatus->lastReboot);
|
pDnode->lastReboot = htonl(pStatus->lastReboot);
|
||||||
pDnode->numOfTotalVnodes = htons(pStatus->numOfTotalVnodes);
|
|
||||||
pDnode->numOfCores = htons(pStatus->numOfCores);
|
pDnode->numOfCores = htons(pStatus->numOfCores);
|
||||||
pDnode->diskAvailable = pStatus->diskAvailable;
|
pDnode->diskAvailable = pStatus->diskAvailable;
|
||||||
pDnode->alternativeRole = pStatus->alternativeRole;
|
pDnode->alternativeRole = pStatus->alternativeRole;
|
||||||
|
|
||||||
|
if (pDnode->numOfTotalVnodes == 0) {
|
||||||
|
pDnode->numOfTotalVnodes = htons(pStatus->numOfTotalVnodes);
|
||||||
|
}
|
||||||
|
|
||||||
if (pStatus->dnodeId == 0) {
|
if (pStatus->dnodeId == 0) {
|
||||||
mTrace("dnode:%d, first access, privateIp:%s, name:%s, ", pDnode->dnodeId, taosIpStr(pDnode->privateIp), pDnode->dnodeName);
|
mTrace("dnode:%d, first access, privateIp:%s, name:%s, ", pDnode->dnodeId, taosIpStr(pDnode->privateIp), pDnode->dnodeName);
|
||||||
mgmtSetDnodeMaxVnodes(pDnode);
|
mgmtSetDnodeMaxVnodes(pDnode);
|
||||||
|
|
|
@ -493,7 +493,7 @@ static int32_t mgmtSetSchemaFromNormalTable(SSchema *pSchema, SNormalTableObj *p
|
||||||
int32_t mgmtGetNormalTableMeta(SDbObj *pDb, SNormalTableObj *pTable, STableMetaMsg *pMeta, bool usePublicIp) {
|
int32_t mgmtGetNormalTableMeta(SDbObj *pDb, SNormalTableObj *pTable, STableMetaMsg *pMeta, bool usePublicIp) {
|
||||||
pMeta->uid = htobe64(pTable->uid);
|
pMeta->uid = htobe64(pTable->uid);
|
||||||
pMeta->sid = htonl(pTable->sid);
|
pMeta->sid = htonl(pTable->sid);
|
||||||
pMeta->vgid = htonl(pTable->vgId);
|
pMeta->vgId = htonl(pTable->vgId);
|
||||||
pMeta->sversion = htons(pTable->sversion);
|
pMeta->sversion = htons(pTable->sversion);
|
||||||
pMeta->precision = pDb->cfg.precision;
|
pMeta->precision = pDb->cfg.precision;
|
||||||
pMeta->numOfTags = 0;
|
pMeta->numOfTags = 0;
|
||||||
|
|
|
@ -622,7 +622,7 @@ int32_t mgmtSetSchemaFromSuperTable(SSchema *pSchema, SSuperTableObj *pTable) {
|
||||||
int32_t mgmtGetSuperTableMeta(SDbObj *pDb, SSuperTableObj *pTable, STableMetaMsg *pMeta, bool usePublicIp) {
|
int32_t mgmtGetSuperTableMeta(SDbObj *pDb, SSuperTableObj *pTable, STableMetaMsg *pMeta, bool usePublicIp) {
|
||||||
pMeta->uid = htobe64(pTable->uid);
|
pMeta->uid = htobe64(pTable->uid);
|
||||||
pMeta->sid = htonl(pTable->sid);
|
pMeta->sid = htonl(pTable->sid);
|
||||||
pMeta->vgid = htonl(pTable->vgId);
|
pMeta->vgId = htonl(pTable->vgId);
|
||||||
pMeta->sversion = htons(pTable->sversion);
|
pMeta->sversion = htons(pTable->sversion);
|
||||||
pMeta->precision = pDb->cfg.precision;
|
pMeta->precision = pDb->cfg.precision;
|
||||||
pMeta->numOfTags = pTable->numOfTags;
|
pMeta->numOfTags = pTable->numOfTags;
|
||||||
|
|
|
@ -11,5 +11,5 @@ INCLUDE_DIRECTORIES(inc)
|
||||||
IF ((TD_LINUX_64) OR (TD_LINUX_32 AND TD_ARM))
|
IF ((TD_LINUX_64) OR (TD_LINUX_32 AND TD_ARM))
|
||||||
AUX_SOURCE_DIRECTORY(src SRC)
|
AUX_SOURCE_DIRECTORY(src SRC)
|
||||||
ADD_LIBRARY(query ${SRC})
|
ADD_LIBRARY(query ${SRC})
|
||||||
TARGET_LINK_LIBRARIES(query tutil m rt)
|
TARGET_LINK_LIBRARIES(query tsdb tutil m rt)
|
||||||
ENDIF ()
|
ENDIF ()
|
|
@ -124,9 +124,8 @@ typedef struct tTagSchema {
|
||||||
typedef struct tSidSet {
|
typedef struct tSidSet {
|
||||||
int32_t numOfSids;
|
int32_t numOfSids;
|
||||||
int32_t numOfSubSet;
|
int32_t numOfSubSet;
|
||||||
STableSidExtInfo **pSids;
|
STableIdInfo **pTableIdList;
|
||||||
int32_t * starterPos; // position of each subgroup, generated according to
|
int32_t * starterPos; // position of each subgroup, generated according to
|
||||||
|
|
||||||
SColumnModel *pColumnModel;
|
SColumnModel *pColumnModel;
|
||||||
SColumnOrderInfo orderIdx;
|
SColumnOrderInfo orderIdx;
|
||||||
} tSidSet;
|
} tSidSet;
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "taosdef.h"
|
#include "taosdef.h"
|
||||||
#include "tref.h"
|
#include "tref.h"
|
||||||
#include "tsqlfunction.h"
|
#include "tsqlfunction.h"
|
||||||
|
#include "tarray.h"
|
||||||
|
|
||||||
typedef struct SData {
|
typedef struct SData {
|
||||||
int32_t num;
|
int32_t num;
|
||||||
|
@ -39,7 +40,7 @@ enum {
|
||||||
|
|
||||||
struct SColumnFilterElem;
|
struct SColumnFilterElem;
|
||||||
typedef bool (*__filter_func_t)(struct SColumnFilterElem* pFilter, char* val1, char* val2);
|
typedef bool (*__filter_func_t)(struct SColumnFilterElem* pFilter, char* val1, char* val2);
|
||||||
typedef int (*__block_search_fn_t)(char* data, int num, int64_t key, int order);
|
typedef int32_t (*__block_search_fn_t)(char* data, int32_t num, int64_t key, int32_t order);
|
||||||
|
|
||||||
typedef struct SSqlGroupbyExpr {
|
typedef struct SSqlGroupbyExpr {
|
||||||
int16_t tableIndex;
|
int16_t tableIndex;
|
||||||
|
@ -142,7 +143,7 @@ typedef struct SQuery {
|
||||||
int32_t pos;
|
int32_t pos;
|
||||||
int64_t pointsOffset; // the number of points offset to save read data
|
int64_t pointsOffset; // the number of points offset to save read data
|
||||||
SData** sdata;
|
SData** sdata;
|
||||||
|
int32_t capacity;
|
||||||
SSingleColumnFilterInfo* pFilterInfo;
|
SSingleColumnFilterInfo* pFilterInfo;
|
||||||
} SQuery;
|
} SQuery;
|
||||||
|
|
||||||
|
@ -152,7 +153,6 @@ typedef struct SQueryCostSummary {
|
||||||
typedef struct SQueryRuntimeEnv {
|
typedef struct SQueryRuntimeEnv {
|
||||||
SResultInfo* resultInfo; // todo refactor to merge with SWindowResInfo
|
SResultInfo* resultInfo; // todo refactor to merge with SWindowResInfo
|
||||||
SQuery* pQuery;
|
SQuery* pQuery;
|
||||||
void* pTabObj;
|
|
||||||
SData** pInterpoBuf;
|
SData** pInterpoBuf;
|
||||||
SQLFunctionCtx* pCtx;
|
SQLFunctionCtx* pCtx;
|
||||||
int16_t numOfRowsPerPage;
|
int16_t numOfRowsPerPage;
|
||||||
|
@ -171,19 +171,21 @@ typedef struct SQueryRuntimeEnv {
|
||||||
|
|
||||||
typedef struct SQInfo {
|
typedef struct SQInfo {
|
||||||
uint64_t signature;
|
uint64_t signature;
|
||||||
|
void* pVnode;
|
||||||
TSKEY startTime;
|
TSKEY startTime;
|
||||||
int64_t elapsedTime;
|
int64_t elapsedTime;
|
||||||
SResultRec rec;
|
SResultRec rec;
|
||||||
int pointsReturned;
|
int32_t pointsReturned;
|
||||||
int pointsInterpo;
|
int32_t pointsInterpo;
|
||||||
int code; // error code to returned to client
|
int32_t code; // error code to returned to client
|
||||||
|
int32_t killed; // denotes if current query is killed
|
||||||
sem_t dataReady;
|
sem_t dataReady;
|
||||||
SHashObj* pTableList; // table list
|
SArray* pTableIdList; // table list
|
||||||
SQueryRuntimeEnv runtimeEnv;
|
SQueryRuntimeEnv runtimeEnv;
|
||||||
int32_t subgroupIdx;
|
int32_t subgroupIdx;
|
||||||
int32_t offset; /* offset in group result set of subgroup */
|
int32_t offset; /* offset in group result set of subgroup */
|
||||||
tSidSet* pSidSet;
|
// tSidSet* pSidSet;
|
||||||
|
|
||||||
T_REF_DECLARE()
|
T_REF_DECLARE()
|
||||||
/*
|
/*
|
||||||
* the query is executed position on which meter of the whole list.
|
* the query is executed position on which meter of the whole list.
|
||||||
|
@ -204,13 +206,13 @@ typedef struct SQInfo {
|
||||||
* @param pQInfo
|
* @param pQInfo
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
int32_t qCreateQueryInfo(void* pReadMsg, SQInfo** pQInfo);
|
int32_t qCreateQueryInfo(void* pVnode, SQueryTableMsg* pQueryTableMsg, SQInfo** pQInfo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* query on single table
|
* query on single table
|
||||||
* @param pReadMsg
|
* @param pReadMsg
|
||||||
*/
|
*/
|
||||||
void qTableQuery(void* pReadMsg);
|
void qTableQuery(SQInfo* pQInfo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* query on super table
|
* query on super table
|
||||||
|
@ -218,4 +220,13 @@ void qTableQuery(void* pReadMsg);
|
||||||
*/
|
*/
|
||||||
void qSuperTableQuery(void* pReadMsg);
|
void qSuperTableQuery(void* pReadMsg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wait for the query completed, and retrieve final results to client
|
||||||
|
* @param pQInfo
|
||||||
|
*/
|
||||||
|
int32_t qRetrieveQueryResultInfo(SQInfo* pQInfo, int32_t *numOfRows, int32_t* rowsize);
|
||||||
|
|
||||||
|
|
||||||
|
//int32_t qBuildQueryResult(SQInfo* pQInfo, void* pBuf);
|
||||||
|
|
||||||
#endif // TDENGINE_QUERYEXECUTOR_H
|
#endif // TDENGINE_QUERYEXECUTOR_H
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -287,7 +287,7 @@ void rpcClose(void *param) {
|
||||||
(*taosCleanUpConn[pRpc->connType])(pRpc->udphandle);
|
(*taosCleanUpConn[pRpc->connType])(pRpc->udphandle);
|
||||||
|
|
||||||
for (int i = 0; i < pRpc->sessions; ++i) {
|
for (int i = 0; i < pRpc->sessions; ++i) {
|
||||||
if (pRpc->connList[i].user[0]) {
|
if (pRpc->connList && pRpc->connList[i].user[0]) {
|
||||||
rpcCloseConn((void *)(pRpc->connList + i));
|
rpcCloseConn((void *)(pRpc->connList + i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -495,35 +495,35 @@ static void rpcCloseConn(void *thandle) {
|
||||||
SRpcConn *pConn = (SRpcConn *)thandle;
|
SRpcConn *pConn = (SRpcConn *)thandle;
|
||||||
SRpcInfo *pRpc = pConn->pRpc;
|
SRpcInfo *pRpc = pConn->pRpc;
|
||||||
|
|
||||||
|
if (pConn->user[0] == 0) return;
|
||||||
|
|
||||||
rpcLockConn(pConn);
|
rpcLockConn(pConn);
|
||||||
|
|
||||||
if (pConn->user[0]) {
|
pConn->user[0] = 0;
|
||||||
pConn->user[0] = 0;
|
if (taosCloseConn[pConn->connType]) (*taosCloseConn[pConn->connType])(pConn->chandle);
|
||||||
if (taosCloseConn[pConn->connType]) (*taosCloseConn[pConn->connType])(pConn->chandle);
|
|
||||||
|
|
||||||
taosTmrStopA(&pConn->pTimer);
|
taosTmrStopA(&pConn->pTimer);
|
||||||
taosTmrStopA(&pConn->pIdleTimer);
|
taosTmrStopA(&pConn->pIdleTimer);
|
||||||
|
|
||||||
if ( pRpc->connType == TAOS_CONN_SERVER) {
|
if ( pRpc->connType == TAOS_CONN_SERVER) {
|
||||||
char hashstr[40] = {0};
|
char hashstr[40] = {0};
|
||||||
sprintf(hashstr, "%x:%x:%x:%d", pConn->peerIp, pConn->linkUid, pConn->peerId, pConn->connType);
|
sprintf(hashstr, "%x:%x:%x:%d", pConn->peerIp, pConn->linkUid, pConn->peerId, pConn->connType);
|
||||||
taosDeleteStrHash(pRpc->hash, hashstr);
|
taosDeleteStrHash(pRpc->hash, hashstr);
|
||||||
rpcFreeMsg(pConn->pRspMsg); // it may have a response msg saved, but not request msg
|
rpcFreeMsg(pConn->pRspMsg); // it may have a response msg saved, but not request msg
|
||||||
pConn->pRspMsg = NULL;
|
pConn->pRspMsg = NULL;
|
||||||
pConn->inType = 0;
|
pConn->inType = 0;
|
||||||
pConn->inTranId = 0;
|
pConn->inTranId = 0;
|
||||||
} else {
|
} else {
|
||||||
pConn->outType = 0;
|
pConn->outType = 0;
|
||||||
pConn->outTranId = 0;
|
pConn->outTranId = 0;
|
||||||
pConn->pReqMsg = NULL;
|
pConn->pReqMsg = NULL;
|
||||||
}
|
|
||||||
|
|
||||||
taosFreeId(pRpc->idPool, pConn->sid);
|
|
||||||
pConn->pContext = NULL;
|
|
||||||
|
|
||||||
tTrace("%s %p, rpc connection is closed", pRpc->label, pConn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
taosFreeId(pRpc->idPool, pConn->sid);
|
||||||
|
pConn->pContext = NULL;
|
||||||
|
|
||||||
|
tTrace("%s %p, rpc connection is closed", pRpc->label, pConn);
|
||||||
|
|
||||||
rpcUnlockConn(pConn);
|
rpcUnlockConn(pConn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can use, redistribute, and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3
|
||||||
|
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#ifndef _TD_LIST_
|
||||||
|
#define _TD_LIST_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef enum { TD_LIST_FORWARD, TD_LIST_BACKWARD } TD_LIST_DIRECTION_T;
|
||||||
|
|
||||||
|
typedef struct _list_node {
|
||||||
|
struct _list_node *next;
|
||||||
|
struct _list_node *prev;
|
||||||
|
char data[];
|
||||||
|
} SListNode;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
struct _list_node *head;
|
||||||
|
struct _list_node *tail;
|
||||||
|
int numOfEles;
|
||||||
|
int eleSize;
|
||||||
|
} SList;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
SListNode * next;
|
||||||
|
TD_LIST_DIRECTION_T direction;
|
||||||
|
} SListIter;
|
||||||
|
|
||||||
|
#define listHead(l) (l)->head
|
||||||
|
#define listTail(l) (l)->tail
|
||||||
|
#define listNEles(l) (l)->numOfEles
|
||||||
|
#define listEleSize(l) (l)->eleSize
|
||||||
|
#define isListEmpty(l) ((l)->numOfEles == 0)
|
||||||
|
#define listNodeFree(n) free(n);
|
||||||
|
|
||||||
|
SList * tdListNew(int eleSize);
|
||||||
|
void tdListFree(SList *list);
|
||||||
|
void tdListEmpty(SList *list);
|
||||||
|
void tdListPrependNode(SList *list, SListNode *node);
|
||||||
|
void tdListAppendNode(SList *list, SListNode *node);
|
||||||
|
int tdListPrepend(SList *list, void *data);
|
||||||
|
int tdListAppend(SList *list, void *data);
|
||||||
|
SListNode *tdListPopHead(SList *list);
|
||||||
|
SListNode *tdListPopTail(SList *list);
|
||||||
|
SListNode *tdListPopNode(SList *list, SListNode *node);
|
||||||
|
void tdListMove(SList *src, SList *dst);
|
||||||
|
|
||||||
|
void tdListNodeGetData(SList *list, SListNode *node, void *target);
|
||||||
|
void tdListInitIter(SList *list, SListIter *pIter, TD_LIST_DIRECTION_T direction);
|
||||||
|
SListNode *tdListNext(SListIter *pIter);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,169 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can use, redistribute, and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3
|
||||||
|
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "tlist.h"
|
||||||
|
|
||||||
|
SList *tdListNew(int eleSize) {
|
||||||
|
SList *list = (SList *)malloc(sizeof(SList));
|
||||||
|
if (list == NULL) return NULL;
|
||||||
|
|
||||||
|
list->eleSize = eleSize;
|
||||||
|
list->numOfEles = 0;
|
||||||
|
list->head = list->tail = NULL;
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tdListEmpty(SList *list) {
|
||||||
|
SListNode *node = list->head;
|
||||||
|
while (node) {
|
||||||
|
list->head = node->next;
|
||||||
|
free(node);
|
||||||
|
node = list->head;
|
||||||
|
}
|
||||||
|
list->head = list->tail = 0;
|
||||||
|
list->numOfEles = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tdListFree(SList *list) {
|
||||||
|
tdListEmpty(list);
|
||||||
|
free(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tdListPrependNode(SList *list, SListNode *node) {
|
||||||
|
if (list->head == NULL) {
|
||||||
|
list->head = node;
|
||||||
|
list->tail = node;
|
||||||
|
} else {
|
||||||
|
node->next = list->head;
|
||||||
|
node->prev = NULL;
|
||||||
|
list->head->prev = node;
|
||||||
|
list->head = node;
|
||||||
|
}
|
||||||
|
list->numOfEles++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tdListAppendNode(SList *list, SListNode *node) {
|
||||||
|
if (list->head == NULL) {
|
||||||
|
list->head = node;
|
||||||
|
list->tail = node;
|
||||||
|
} else {
|
||||||
|
node->prev = list->tail;
|
||||||
|
node->next = NULL;
|
||||||
|
list->tail->next = node;
|
||||||
|
list->tail = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
list->numOfEles++;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tdListPrepend(SList *list, void *data) {
|
||||||
|
SListNode *node = (SListNode *)malloc(sizeof(SListNode) + list->eleSize);
|
||||||
|
if (node == NULL) return -1;
|
||||||
|
|
||||||
|
memcpy((void *)(node->data), data, list->eleSize);
|
||||||
|
tdListPrependNode(list, node);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tdListAppend(SList *list, void *data) {
|
||||||
|
SListNode *node = (SListNode *)malloc(sizeof(SListNode) + list->eleSize);
|
||||||
|
if (node == NULL) return -1;
|
||||||
|
|
||||||
|
memcpy((void *)(node->data), data, list->eleSize);
|
||||||
|
tdListAppendNode(list, node);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SListNode *tdListPopHead(SList *list) {
|
||||||
|
if (list->head == NULL) return NULL;
|
||||||
|
SListNode *node = list->head;
|
||||||
|
if (node->next == NULL) {
|
||||||
|
list->head = NULL;
|
||||||
|
list->tail = NULL;
|
||||||
|
} else {
|
||||||
|
list->head = node->next;
|
||||||
|
}
|
||||||
|
list->numOfEles--;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
SListNode *tdListPopTail(SList *list) {
|
||||||
|
if (list->tail == NULL) return NULL;
|
||||||
|
SListNode *node = list->tail;
|
||||||
|
if (node->prev == NULL) {
|
||||||
|
list->head = NULL;
|
||||||
|
list->tail = NULL;
|
||||||
|
} else {
|
||||||
|
list->tail = node->prev;
|
||||||
|
}
|
||||||
|
list->numOfEles--;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
SListNode *tdListPopNode(SList *list, SListNode *node) {
|
||||||
|
if (list->head == node) {
|
||||||
|
list->head = node->next;
|
||||||
|
}
|
||||||
|
if (list->tail == node) {
|
||||||
|
list->tail = node->prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node->prev != NULL) {
|
||||||
|
node->prev->next = node->next;
|
||||||
|
}
|
||||||
|
if (node->next != NULL) {
|
||||||
|
node->next->prev = node->prev;
|
||||||
|
}
|
||||||
|
list->numOfEles--;
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move all node elements from src to dst, the dst is assumed as an empty list
|
||||||
|
void tdListMove(SList *src, SList *dst) {
|
||||||
|
// assert(dst->eleSize == src->eleSize);
|
||||||
|
dst->numOfEles = src->numOfEles;
|
||||||
|
dst->head = src->head;
|
||||||
|
dst->tail = src->tail;
|
||||||
|
src->numOfEles = 0;
|
||||||
|
src->head = src->tail = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tdListNodeGetData(SList *list, SListNode *node, void *target) { memcpy(target, node->data, list->eleSize); }
|
||||||
|
|
||||||
|
void tdListInitIter(SList *list, SListIter *pIter, TD_LIST_DIRECTION_T direction) {
|
||||||
|
pIter->direction = direction;
|
||||||
|
if (direction == TD_LIST_FORWARD) {
|
||||||
|
pIter->next = list->head;
|
||||||
|
} else {
|
||||||
|
pIter->next = list->tail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SListNode *tdListNext(SListIter *pIter) {
|
||||||
|
SListNode *node = pIter->next;
|
||||||
|
if (node == NULL) return NULL;
|
||||||
|
if (pIter->direction == TD_LIST_FORWARD) {
|
||||||
|
pIter->next = node->next;
|
||||||
|
} else {
|
||||||
|
pIter->next = node->prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
|
@ -15,7 +15,6 @@
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
|
||||||
#include "tlog.h"
|
#include "tlog.h"
|
||||||
// #include "tsdb.h"
|
|
||||||
#include "tskiplist.h"
|
#include "tskiplist.h"
|
||||||
#include "tutil.h"
|
#include "tutil.h"
|
||||||
|
|
||||||
|
@ -395,6 +394,7 @@ SSkipListNode *tSkipListPut(SSkipList *pSkipList, SSkipListNode *pNode) {
|
||||||
SSkipListNode *px = pSkipList->pHead;
|
SSkipListNode *px = pSkipList->pHead;
|
||||||
SSkipListNode *forward[MAX_SKIP_LIST_LEVEL] = {0};
|
SSkipListNode *forward[MAX_SKIP_LIST_LEVEL] = {0};
|
||||||
|
|
||||||
|
bool identical = false;
|
||||||
for (int32_t i = pSkipList->level - 1; i >= 0; --i) {
|
for (int32_t i = pSkipList->level - 1; i >= 0; --i) {
|
||||||
SSkipListNode *p = SL_GET_FORWARD_POINTER(px, i);
|
SSkipListNode *p = SL_GET_FORWARD_POINTER(px, i);
|
||||||
while (p != NULL) {
|
while (p != NULL) {
|
||||||
|
@ -402,11 +402,16 @@ SSkipListNode *tSkipListPut(SSkipList *pSkipList, SSkipListNode *pNode) {
|
||||||
char *newDatakey = SL_GET_NODE_KEY(pSkipList, pNode);
|
char *newDatakey = SL_GET_NODE_KEY(pSkipList, pNode);
|
||||||
|
|
||||||
// if the forward element is less than the specified key, forward one step
|
// if the forward element is less than the specified key, forward one step
|
||||||
if (pSkipList->comparFn(key, newDatakey) < 0) {
|
int32_t ret = pSkipList->comparFn(key, newDatakey);
|
||||||
|
if (ret < 0) {
|
||||||
px = p;
|
px = p;
|
||||||
|
|
||||||
p = SL_GET_FORWARD_POINTER(px, i);
|
p = SL_GET_FORWARD_POINTER(px, i);
|
||||||
} else {
|
} else {
|
||||||
|
if (identical == false) {
|
||||||
|
identical = (ret == 0);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -418,17 +423,12 @@ SSkipListNode *tSkipListPut(SSkipList *pSkipList, SSkipListNode *pNode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the skip list does not allowed identical key inserted, the new data will be discarded.
|
// if the skip list does not allowed identical key inserted, the new data will be discarded.
|
||||||
if (pSkipList->keyInfo.dupKey == 0 && forward[0] != pSkipList->pHead) {
|
if (pSkipList->keyInfo.dupKey == 0 && identical) {
|
||||||
char *key = SL_GET_NODE_KEY(pSkipList, forward[0]);
|
if (pSkipList->lock) {
|
||||||
char *pNewDataKey = SL_GET_NODE_KEY(pSkipList, pNode);
|
pthread_rwlock_unlock(pSkipList->lock);
|
||||||
|
|
||||||
if (pSkipList->comparFn(key, pNewDataKey) == 0) {
|
|
||||||
if (pSkipList->lock) {
|
|
||||||
pthread_rwlock_unlock(pSkipList->lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
return forward[0];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return forward[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SKIP_LIST_RECORD_PERFORMANCE
|
#if SKIP_LIST_RECORD_PERFORMANCE
|
||||||
|
|
|
@ -58,6 +58,9 @@ int32_t tsdbDropRepo(tsdb_repo_t *repo);
|
||||||
tsdb_repo_t * tsdbOpenRepo(char *tsdbDir);
|
tsdb_repo_t * tsdbOpenRepo(char *tsdbDir);
|
||||||
int32_t tsdbCloseRepo(tsdb_repo_t *repo);
|
int32_t tsdbCloseRepo(tsdb_repo_t *repo);
|
||||||
int32_t tsdbConfigRepo(tsdb_repo_t *repo, STsdbCfg *pCfg);
|
int32_t tsdbConfigRepo(tsdb_repo_t *repo, STsdbCfg *pCfg);
|
||||||
|
int32_t tsdbTriggerCommit(tsdb_repo_t *repo);
|
||||||
|
int32_t tsdbLockRepo(tsdb_repo_t *repo);
|
||||||
|
int32_t tsdbUnLockRepo(tsdb_repo_t *repo);
|
||||||
|
|
||||||
// --------- TSDB TABLE DEFINITION
|
// --------- TSDB TABLE DEFINITION
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -87,15 +90,6 @@ int tsdbCreateTable(tsdb_repo_t *repo, STableCfg *pCfg);
|
||||||
int tsdbDropTable(tsdb_repo_t *pRepo, STableId tableId);
|
int tsdbDropTable(tsdb_repo_t *pRepo, STableId tableId);
|
||||||
int tsdbAlterTable(tsdb_repo_t *repo, STableCfg *pCfg);
|
int tsdbAlterTable(tsdb_repo_t *repo, STableCfg *pCfg);
|
||||||
|
|
||||||
// Submit message for one table
|
|
||||||
typedef struct {
|
|
||||||
STableId tableId;
|
|
||||||
int32_t padding; // TODO just for padding here
|
|
||||||
int32_t sversion; // data schema version
|
|
||||||
int32_t len; // data part length, not including the SSubmitBlk head
|
|
||||||
char data[];
|
|
||||||
} SSubmitBlk;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int32_t totalLen;
|
int32_t totalLen;
|
||||||
int32_t len;
|
int32_t len;
|
||||||
|
@ -105,15 +99,10 @@ typedef struct {
|
||||||
int tsdbInitSubmitBlkIter(SSubmitBlk *pBlock, SSubmitBlkIter *pIter);
|
int tsdbInitSubmitBlkIter(SSubmitBlk *pBlock, SSubmitBlkIter *pIter);
|
||||||
SDataRow tsdbGetSubmitBlkNext(SSubmitBlkIter *pIter);
|
SDataRow tsdbGetSubmitBlkNext(SSubmitBlkIter *pIter);
|
||||||
|
|
||||||
// Submit message for this TSDB
|
|
||||||
typedef struct {
|
|
||||||
int32_t length;
|
|
||||||
int32_t compressed;
|
|
||||||
SSubmitBlk blocks[];
|
|
||||||
} SSubmitMsg;
|
|
||||||
|
|
||||||
#define TSDB_SUBMIT_MSG_HEAD_SIZE sizeof(SSubmitMsg)
|
#define TSDB_SUBMIT_MSG_HEAD_SIZE sizeof(SSubmitMsg)
|
||||||
|
|
||||||
|
struct STsdbRepo;
|
||||||
|
|
||||||
// SSubmitMsg Iterator
|
// SSubmitMsg Iterator
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int32_t totalLen;
|
int32_t totalLen;
|
||||||
|
@ -242,7 +231,7 @@ typedef void *tsdbpos_t;
|
||||||
* @param pTableList table sid list
|
* @param pTableList table sid list
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
tsdb_query_handle_t *tsdbQueryByTableId(STsdbQueryCond *pCond, SArray *idList, SArray *pColumnInfo);
|
tsdb_query_handle_t *tsdbQueryByTableId(tsdb_repo_t* tsdb, STsdbQueryCond *pCond, SArray *idList, SArray *pColumnInfo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* move to next block
|
* move to next block
|
||||||
|
|
|
@ -17,45 +17,50 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
// #include "cache.h"
|
#include "taosdef.h"
|
||||||
|
#include "tlist.h"
|
||||||
|
#include "tsdb.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define TSDB_DEFAULT_CACHE_BLOCK_SIZE 16*1024*1024 /* 16M */
|
#define TSDB_DEFAULT_CACHE_BLOCK_SIZE 16 * 1024 * 1024 /* 16M */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int64_t skey; // start key
|
int blockId;
|
||||||
int64_t ekey; // end key
|
int offset;
|
||||||
int32_t numOfRows; // numOfRows
|
int remain;
|
||||||
} STableCacheInfo;
|
int padding;
|
||||||
|
char data[];
|
||||||
|
} STsdbCacheBlock;
|
||||||
|
|
||||||
typedef struct _tsdb_cache_block {
|
typedef struct {
|
||||||
char * pData;
|
int64_t index;
|
||||||
STableCacheInfo * pTableInfo;
|
SList * memPool;
|
||||||
struct _tsdb_cache_block *prev;
|
} STsdbCachePool;
|
||||||
struct _tsdb_cache_block *next;
|
|
||||||
} STSDBCacheBlock;
|
|
||||||
|
|
||||||
// Use a doublely linked list to implement this
|
typedef struct {
|
||||||
typedef struct STSDBCache {
|
TSKEY keyFirst;
|
||||||
// Number of blocks the cache is allocated
|
TSKEY keyLast;
|
||||||
int32_t numOfBlocks;
|
int64_t numOfPoints;
|
||||||
STSDBCacheBlock *cacheList;
|
SList * list;
|
||||||
void * current;
|
} SCacheMem;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int maxBytes;
|
||||||
|
int cacheBlockSize;
|
||||||
|
int totalCacheBlocks;
|
||||||
|
STsdbCachePool pool;
|
||||||
|
STsdbCacheBlock *curBlock;
|
||||||
|
SCacheMem * mem;
|
||||||
|
SCacheMem * imem;
|
||||||
|
tsdb_repo_t * pRepo;
|
||||||
} STsdbCache;
|
} STsdbCache;
|
||||||
|
|
||||||
// ---- Operation on STSDBCacheBlock
|
STsdbCache *tsdbInitCache(int maxBytes, int cacheBlockSize, tsdb_repo_t *pRepo);
|
||||||
#define TSDB_CACHE_BLOCK_DATA(pBlock) ((pBlock)->pData)
|
void tsdbFreeCache(STsdbCache *pCache);
|
||||||
#define TSDB_CACHE_AVAIL_SPACE(pBlock) ((char *)((pBlock)->pTableInfo) - ((pBlock)->pData))
|
void * tsdbAllocFromCache(STsdbCache *pCache, int bytes, TSKEY key);
|
||||||
#define TSDB_TABLE_INFO_OF_CACHE(pBlock, tableId) ((pBlock)->pTableInfo)[tableId]
|
|
||||||
#define TSDB_NEXT_CACHE_BLOCK(pBlock) ((pBlock)->next)
|
|
||||||
#define TSDB_PREV_CACHE_BLOCK(pBlock) ((pBlock)->prev)
|
|
||||||
|
|
||||||
STsdbCache *tsdbInitCache(int64_t maxSize);
|
|
||||||
int32_t tsdbFreeCache(STsdbCache *pCache);
|
|
||||||
void * tsdbAllocFromCache(STsdbCache *pCache, int64_t bytes);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,16 +18,20 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "taosdef.h"
|
#include "taosdef.h"
|
||||||
|
#include "tglobalcfg.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define tsdbGetKeyFileId(key, daysPerFile, precision) ((key) / tsMsPerDay[(precision)] / (daysPerFile))
|
||||||
|
#define tsdbGetMaxNumOfFiles(keep, daysPerFile) ((keep) / (daysPerFile) + 3)
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
TSDB_FILE_TYPE_HEAD, // .head file type
|
TSDB_FILE_TYPE_HEAD = 0, // .head file type
|
||||||
TSDB_FILE_TYPE_DATA, // .data file type
|
TSDB_FILE_TYPE_DATA, // .data file type
|
||||||
TSDB_FILE_TYPE_LAST, // .last file type
|
TSDB_FILE_TYPE_LAST, // .last file type
|
||||||
TSDB_FILE_TYPE_META // .meta file type
|
TSDB_FILE_TYPE_MAX
|
||||||
} TSDB_FILE_TYPE;
|
} TSDB_FILE_TYPE;
|
||||||
|
|
||||||
extern const char *tsdbFileSuffix[];
|
extern const char *tsdbFileSuffix[];
|
||||||
|
@ -38,16 +42,15 @@ typedef struct {
|
||||||
} SFileInfo;
|
} SFileInfo;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int fd;
|
int8_t type;
|
||||||
int64_t size; // total size of the file
|
char fname[128];
|
||||||
int64_t tombSize; // unused file size
|
int64_t size; // total size of the file
|
||||||
|
int64_t tombSize; // unused file size
|
||||||
} SFile;
|
} SFile;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int32_t fileId;
|
int32_t fileId;
|
||||||
SFile fhead;
|
SFile files[TSDB_FILE_TYPE_MAX];
|
||||||
SFile fdata;
|
|
||||||
SFile flast;
|
|
||||||
} SFileGroup;
|
} SFileGroup;
|
||||||
|
|
||||||
// TSDB file handle
|
// TSDB file handle
|
||||||
|
@ -56,17 +59,38 @@ typedef struct {
|
||||||
int32_t keep;
|
int32_t keep;
|
||||||
int32_t minRowPerFBlock;
|
int32_t minRowPerFBlock;
|
||||||
int32_t maxRowsPerFBlock;
|
int32_t maxRowsPerFBlock;
|
||||||
|
int32_t maxTables;
|
||||||
SFileGroup fGroup[];
|
SFileGroup fGroup[];
|
||||||
} STsdbFileH;
|
} STsdbFileH;
|
||||||
|
|
||||||
#define IS_VALID_TSDB_FILE_TYPE(type) ((type) >= TSDB_FILE_TYPE_HEAD && (type) <= TSDB_FILE_TYPE_META)
|
/**
|
||||||
|
* if numOfSubBlocks == -1, then the SCompBlock is a sub-block
|
||||||
|
* if numOfSubBlocks == 1, then the SCompBlock refers to the data block, and offset/len refer to
|
||||||
|
* the data block offset and length
|
||||||
|
* if numOfSubBlocks > 1, then the offset/len refer to the offset of the first sub-block in the
|
||||||
|
* binary
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
int64_t last : 1; // If the block in data file or last file
|
||||||
|
int64_t offset : 63; // Offset of data block or sub-block index depending on numOfSubBlocks
|
||||||
|
int32_t algorithm : 8; // Compression algorithm
|
||||||
|
int32_t numOfPoints : 24; // Number of total points
|
||||||
|
int32_t sversion; // Schema version
|
||||||
|
int32_t len; // Data block length or nothing
|
||||||
|
int16_t numOfSubBlocks; // Number of sub-blocks;
|
||||||
|
int16_t numOfCols;
|
||||||
|
TSKEY keyFirst;
|
||||||
|
TSKEY keyLast;
|
||||||
|
} SCompBlock;
|
||||||
|
|
||||||
|
#define IS_VALID_TSDB_FILE_TYPE(type) ((type) >= TSDB_FILE_TYPE_HEAD && (type) < TSDB_FILE_TYPE_MAX)
|
||||||
|
|
||||||
STsdbFileH *tsdbInitFile(char *dataDir, int32_t daysPerFile, int32_t keep, int32_t minRowsPerFBlock,
|
STsdbFileH *tsdbInitFile(char *dataDir, int32_t daysPerFile, int32_t keep, int32_t minRowsPerFBlock,
|
||||||
int32_t maxRowsPerFBlock);
|
int32_t maxRowsPerFBlock, int32_t maxTables);
|
||||||
void tsdbCloseFile(STsdbFileH *pFileH);
|
|
||||||
|
|
||||||
char *tsdbGetFileName(char *dirName, char *fname, TSDB_FILE_TYPE type);
|
|
||||||
|
|
||||||
|
void tsdbCloseFile(STsdbFileH *pFileH);
|
||||||
|
int tsdbCreateFileGroup(char *dataDir, int fileId, SFileGroup *pFGroup, int maxTables);
|
||||||
|
void tsdbGetKeyRangeOfFileId(int32_t daysPerFile, int8_t precision, int32_t fileId, TSKEY *minKey, TSKEY *maxKey);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -33,22 +33,28 @@ extern "C" {
|
||||||
|
|
||||||
#define IS_CREATE_STABLE(pCfg) ((pCfg)->tagValues != NULL)
|
#define IS_CREATE_STABLE(pCfg) ((pCfg)->tagValues != NULL)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
TSKEY keyFirst;
|
||||||
|
TSKEY keyLast;
|
||||||
|
int32_t numOfPoints;
|
||||||
|
void * pData;
|
||||||
|
} SMemTable;
|
||||||
|
|
||||||
// ---------- TSDB TABLE DEFINITION
|
// ---------- TSDB TABLE DEFINITION
|
||||||
typedef struct STable {
|
typedef struct STable {
|
||||||
int8_t type;
|
int8_t type;
|
||||||
STableId tableId;
|
STableId tableId;
|
||||||
int32_t superUid; // Super table UID
|
int64_t superUid; // Super table UID
|
||||||
int32_t sversion;
|
int32_t sversion;
|
||||||
STSchema * schema;
|
STSchema * schema;
|
||||||
STSchema * tagSchema;
|
STSchema * tagSchema;
|
||||||
SDataRow tagVal;
|
SDataRow tagVal;
|
||||||
union {
|
SMemTable * mem;
|
||||||
void *pData; // For TSDB_NORMAL_TABLE and TSDB_CHILD_TABLE, it is the skiplist for cache data
|
SMemTable * imem;
|
||||||
void *pIndex; // For TSDB_SUPER_TABLE, it is the skiplist index
|
void * pIndex; // For TSDB_SUPER_TABLE, it is the skiplist index
|
||||||
} content;
|
|
||||||
void * eventHandler; // TODO
|
void * eventHandler; // TODO
|
||||||
void * streamHandler; // TODO
|
void * streamHandler; // TODO
|
||||||
struct STable *next; // TODO: remove the next
|
struct STable *next; // TODO: remove the next
|
||||||
} STable;
|
} STable;
|
||||||
|
|
||||||
void * tsdbEncodeTable(STable *pTable, int *contLen);
|
void * tsdbEncodeTable(STable *pTable, int *contLen);
|
||||||
|
@ -68,6 +74,8 @@ typedef struct {
|
||||||
void *map; // table map of (uid ===> table)
|
void *map; // table map of (uid ===> table)
|
||||||
|
|
||||||
SMetaFile *mfh; // meta file handle
|
SMetaFile *mfh; // meta file handle
|
||||||
|
int maxRowBytes;
|
||||||
|
int maxCols;
|
||||||
} STsdbMeta;
|
} STsdbMeta;
|
||||||
|
|
||||||
STsdbMeta *tsdbInitMeta(const char *rootDir, int32_t maxTables);
|
STsdbMeta *tsdbInitMeta(const char *rootDir, int32_t maxTables);
|
||||||
|
@ -90,11 +98,14 @@ int32_t tsdbFreeMeta(STsdbMeta *pMeta);
|
||||||
#define TSDB_TABLE_OF_ID(pHandle, id) ((pHandle)->pTables)[id]
|
#define TSDB_TABLE_OF_ID(pHandle, id) ((pHandle)->pTables)[id]
|
||||||
#define TSDB_GET_TABLE_OF_NAME(pHandle, name) /* TODO */
|
#define TSDB_GET_TABLE_OF_NAME(pHandle, name) /* TODO */
|
||||||
|
|
||||||
|
STsdbMeta* tsdbGetMeta(tsdb_repo_t* pRepo);
|
||||||
|
|
||||||
int32_t tsdbCreateTableImpl(STsdbMeta *pMeta, STableCfg *pCfg);
|
int32_t tsdbCreateTableImpl(STsdbMeta *pMeta, STableCfg *pCfg);
|
||||||
int32_t tsdbDropTableImpl(STsdbMeta *pMeta, STableId tableId);
|
int32_t tsdbDropTableImpl(STsdbMeta *pMeta, STableId tableId);
|
||||||
STable *tsdbIsValidTableToInsert(STsdbMeta *pMeta, STableId tableId);
|
STable *tsdbIsValidTableToInsert(STsdbMeta *pMeta, STableId tableId);
|
||||||
int32_t tsdbInsertRowToTableImpl(SSkipListNode *pNode, STable *pTable);
|
// int32_t tsdbInsertRowToTableImpl(SSkipListNode *pNode, STable *pTable);
|
||||||
STable *tsdbGetTableByUid(STsdbMeta *pMeta, int64_t uid);
|
STable *tsdbGetTableByUid(STsdbMeta *pMeta, int64_t uid);
|
||||||
|
char *getTupleKey(const void * data);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,24 +14,126 @@
|
||||||
*/
|
*/
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "tsdb.h"
|
||||||
#include "tsdbCache.h"
|
#include "tsdbCache.h"
|
||||||
|
|
||||||
STsdbCache *tsdbInitCache(int64_t maxSize) {
|
static int tsdbAllocBlockFromPool(STsdbCache *pCache);
|
||||||
STsdbCache *pCacheHandle = (STsdbCache *)malloc(sizeof(STsdbCache));
|
static void tsdbFreeBlockList(SCacheMem *mem);
|
||||||
if (pCacheHandle == NULL) {
|
|
||||||
// TODO : deal with the error
|
STsdbCache *tsdbInitCache(int maxBytes, int cacheBlockSize, tsdb_repo_t *pRepo) {
|
||||||
return NULL;
|
STsdbCache *pCache = (STsdbCache *)calloc(1, sizeof(STsdbCache));
|
||||||
|
if (pCache == NULL) return NULL;
|
||||||
|
|
||||||
|
if (cacheBlockSize < 0) cacheBlockSize = TSDB_DEFAULT_CACHE_BLOCK_SIZE;
|
||||||
|
|
||||||
|
pCache->maxBytes = maxBytes;
|
||||||
|
pCache->cacheBlockSize = cacheBlockSize;
|
||||||
|
pCache->pRepo = pRepo;
|
||||||
|
|
||||||
|
int nBlocks = maxBytes / cacheBlockSize + 1;
|
||||||
|
if (nBlocks <= 1) nBlocks = 2;
|
||||||
|
pCache->totalCacheBlocks = nBlocks;
|
||||||
|
|
||||||
|
STsdbCachePool *pPool = &(pCache->pool);
|
||||||
|
pPool->index = 0;
|
||||||
|
pPool->memPool = tdListNew(sizeof(STsdbCacheBlock *));
|
||||||
|
if (pPool->memPool == NULL) goto _err;
|
||||||
|
|
||||||
|
for (int i = 0; i < nBlocks; i++) {
|
||||||
|
STsdbCacheBlock *pBlock = (STsdbCacheBlock *)malloc(sizeof(STsdbCacheBlock) + cacheBlockSize);
|
||||||
|
if (pBlock == NULL) {
|
||||||
|
goto _err;
|
||||||
|
}
|
||||||
|
pBlock->offset = 0;
|
||||||
|
pBlock->remain = cacheBlockSize;
|
||||||
|
tdListAppend(pPool->memPool, (void *)(&pBlock));
|
||||||
}
|
}
|
||||||
|
|
||||||
return pCacheHandle;
|
pCache->mem = NULL;
|
||||||
|
pCache->imem = NULL;
|
||||||
|
|
||||||
|
return pCache;
|
||||||
|
|
||||||
|
_err:
|
||||||
|
tsdbFreeCache(pCache);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tsdbFreeCache(STsdbCache *pHandle) { return 0; }
|
void tsdbFreeCache(STsdbCache *pCache) {
|
||||||
|
tsdbFreeBlockList(pCache->imem);
|
||||||
|
tsdbFreeBlockList(pCache->mem);
|
||||||
|
tsdbFreeBlockList(pCache->pool.memPool);
|
||||||
|
free(pCache);
|
||||||
|
}
|
||||||
|
|
||||||
void *tsdbAllocFromCache(STsdbCache *pCache, int64_t bytes) {
|
void *tsdbAllocFromCache(STsdbCache *pCache, int bytes, TSKEY key) {
|
||||||
// TODO: implement here
|
if (pCache == NULL) return NULL;
|
||||||
void *ptr = malloc(bytes);
|
if (bytes > pCache->cacheBlockSize) return NULL;
|
||||||
if (ptr == NULL) return NULL;
|
|
||||||
|
if (pCache->curBlock == NULL || pCache->curBlock->remain < bytes) {
|
||||||
|
if (pCache->curBlock !=NULL && (pCache->mem->list) >= pCache->totalCacheBlocks/2) {
|
||||||
|
tsdbTriggerCommit(pCache->pRepo);
|
||||||
|
}
|
||||||
|
if (tsdbAllocBlockFromPool(pCache) < 0) {
|
||||||
|
// TODO: deal with the error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void *ptr = (void *)(pCache->curBlock->data + pCache->curBlock->offset);
|
||||||
|
pCache->curBlock->offset += bytes;
|
||||||
|
pCache->curBlock->remain -= bytes;
|
||||||
|
memset(ptr, 0, bytes);
|
||||||
|
if (key < pCache->mem->keyFirst) pCache->mem->keyFirst = key;
|
||||||
|
if (key > pCache->mem->keyLast) pCache->mem->keyLast = key;
|
||||||
|
pCache->mem->numOfPoints++;
|
||||||
|
|
||||||
return ptr;
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tsdbFreeBlockList(SCacheMem *mem) {
|
||||||
|
if (mem == NULL) return;
|
||||||
|
SList * list = mem->list;
|
||||||
|
SListNode * node = NULL;
|
||||||
|
STsdbCacheBlock *pBlock = NULL;
|
||||||
|
while ((node = tdListPopHead(list)) != NULL) {
|
||||||
|
tdListNodeGetData(list, node, (void *)(&pBlock));
|
||||||
|
free(pBlock);
|
||||||
|
listNodeFree(node);
|
||||||
|
}
|
||||||
|
tdListFree(list);
|
||||||
|
free(mem);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tsdbAllocBlockFromPool(STsdbCache *pCache) {
|
||||||
|
STsdbCachePool *pPool = &(pCache->pool);
|
||||||
|
|
||||||
|
tsdbLockRepo(pCache->pRepo);
|
||||||
|
if (listNEles(pPool->memPool) == 0) {
|
||||||
|
tsdbUnLockRepo(pCache->pRepo);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
SListNode *node = tdListPopHead(pPool->memPool);
|
||||||
|
|
||||||
|
STsdbCacheBlock *pBlock = NULL;
|
||||||
|
tdListNodeGetData(pPool->memPool, node, (void *)(&pBlock));
|
||||||
|
pBlock->blockId = pPool->index++;
|
||||||
|
pBlock->offset = 0;
|
||||||
|
pBlock->remain = pCache->cacheBlockSize;
|
||||||
|
|
||||||
|
if (pCache->mem == NULL) { // Create a new one
|
||||||
|
pCache->mem = (SCacheMem *)malloc(sizeof(SCacheMem));
|
||||||
|
if (pCache->mem == NULL) return NULL;
|
||||||
|
pCache->mem->keyFirst = INT64_MAX;
|
||||||
|
pCache->mem->keyLast = 0;
|
||||||
|
pCache->mem->numOfPoints = 0;
|
||||||
|
pCache->mem->list = tdListNew(sizeof(STsdbCacheBlock *));
|
||||||
|
}
|
||||||
|
|
||||||
|
tdListAppendNode(pCache->mem->list, node);
|
||||||
|
pCache->curBlock = pBlock;
|
||||||
|
|
||||||
|
tsdbUnLockRepo(pCache->pRepo);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
|
@ -12,82 +12,159 @@
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* 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/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <dirent.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "tsdbFile.h"
|
#include "tsdbFile.h"
|
||||||
#include "tglobalcfg.h"
|
|
||||||
|
|
||||||
// int64_t tsMsPerDay[] = {
|
#define TSDB_FILE_HEAD_SIZE 512
|
||||||
// 86400000L, // TSDB_PRECISION_MILLI
|
#define TSDB_FILE_DELIMITER 0xF00AFA0F
|
||||||
// 86400000000L, // TSDB_PRECISION_MICRO
|
|
||||||
// 86400000000000L // TSDB_PRECISION_NANO
|
|
||||||
// };
|
|
||||||
|
|
||||||
#define tsdbGetKeyFileId(key, daysPerFile, precision) ((key) / tsMsPerDay[(precision)] / (daysPerFile))
|
|
||||||
#define tsdbGetMaxNumOfFiles(keep, daysPerFile) ((keep) / (daysPerFile) + 3)
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
int32_t len;
|
||||||
|
int32_t padding; // For padding purpose
|
||||||
int64_t offset;
|
int64_t offset;
|
||||||
} SCompHeader;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int64_t uid;
|
|
||||||
int64_t last : 1;
|
|
||||||
int64_t numOfBlocks : 63;
|
|
||||||
int32_t delimiter;
|
|
||||||
} SCompInfo;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
TSKEY keyFirst;
|
|
||||||
TSKEY keyLast;
|
|
||||||
int32_t numOfBlocks;
|
|
||||||
int32_t offset;
|
|
||||||
} SCompIdx;
|
} SCompIdx;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
TSKEY keyFirst;
|
int32_t delimiter; // For recovery usage
|
||||||
TSKEY keyLast;
|
int32_t checksum; // TODO: decide if checksum logic in this file or make it one API
|
||||||
int64_t offset;
|
int64_t uid;
|
||||||
int32_t len;
|
int32_t padding; // For padding purpose
|
||||||
int32_t sversion;
|
int32_t numOfBlocks; // TODO: make the struct padding
|
||||||
} SCompBlock;
|
SCompBlock blocks[];
|
||||||
|
} SCompInfo;
|
||||||
|
|
||||||
|
// TODO: take pre-calculation into account
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int64_t uid;
|
int16_t colId; // Column ID
|
||||||
} SBlock;
|
int16_t len; // Column length
|
||||||
|
int32_t type : 8;
|
||||||
|
int32_t offset : 24;
|
||||||
|
} SCompCol;
|
||||||
|
|
||||||
|
// TODO: Take recover into account
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int16_t colId;
|
int32_t delimiter; // For recovery usage
|
||||||
int16_t bytes;
|
int32_t numOfCols; // For recovery usage
|
||||||
int32_t nNullPoints;
|
int64_t uid; // For recovery usage
|
||||||
int32_t type:8;
|
SCompCol cols[];
|
||||||
int32_t offset:24;
|
} SCompData;
|
||||||
int32_t len;
|
|
||||||
// fields for pre-aggregate
|
|
||||||
// TODO: pre-aggregation should be seperated
|
|
||||||
int64_t sum;
|
|
||||||
int64_t max;
|
|
||||||
int64_t min;
|
|
||||||
int16_t maxIdx;
|
|
||||||
int16_t minIdx;
|
|
||||||
} SField;
|
|
||||||
|
|
||||||
const char *tsdbFileSuffix[] = {
|
const char *tsdbFileSuffix[] = {
|
||||||
".head", // TSDB_FILE_TYPE_HEAD
|
".head", // TSDB_FILE_TYPE_HEAD
|
||||||
".data", // TSDB_FILE_TYPE_DATA
|
".data", // TSDB_FILE_TYPE_DATA
|
||||||
".last", // TSDB_FILE_TYPE_LAST
|
".last" // TSDB_FILE_TYPE_LAST
|
||||||
".meta" // TSDB_FILE_TYPE_META
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int tsdbWriteFileHead(int fd, SFile *pFile) {
|
||||||
|
char head[TSDB_FILE_HEAD_SIZE] = "\0";
|
||||||
|
|
||||||
|
pFile->size += TSDB_FILE_HEAD_SIZE;
|
||||||
|
|
||||||
|
// TODO: write version and File statistic to the head
|
||||||
|
lseek(fd, 0, SEEK_SET);
|
||||||
|
if (write(fd, head, TSDB_FILE_HEAD_SIZE) < 0) return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tsdbWriteHeadFileIdx(int fd, int maxTables, SFile *pFile) {
|
||||||
|
int size = sizeof(SCompIdx) * maxTables;
|
||||||
|
void *buf = calloc(1, size);
|
||||||
|
if (buf == NULL) return -1;
|
||||||
|
|
||||||
|
if (lseek(fd, TSDB_FILE_HEAD_SIZE, SEEK_SET) < 0) {
|
||||||
|
free(buf);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (write(fd, buf, size) < 0) {
|
||||||
|
free(buf);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pFile->size += size;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tsdbGetFileName(char *dataDir, int fileId, int8_t type, char *fname) {
|
||||||
|
if (dataDir == NULL || fname == NULL || !IS_VALID_TSDB_FILE_TYPE(type)) return -1;
|
||||||
|
|
||||||
|
sprintf(fname, "%s/f%d%s", dataDir, fileId, tsdbFileSuffix[type]);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a file and set the SFile object
|
||||||
|
*/
|
||||||
|
static int tsdbCreateFile(char *dataDir, int fileId, int8_t type, int maxTables, SFile *pFile) {
|
||||||
|
memset((void *)pFile, 0, sizeof(SFile));
|
||||||
|
pFile->type = type;
|
||||||
|
|
||||||
|
tsdbGetFileName(dataDir, fileId, type, pFile->fname);
|
||||||
|
if (access(pFile->fname, F_OK) == 0) {
|
||||||
|
// File already exists
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fd = open(pFile->fname, O_WRONLY | O_CREAT, 0755);
|
||||||
|
if (fd < 0) return -1;
|
||||||
|
|
||||||
|
if (type == TSDB_FILE_TYPE_HEAD) {
|
||||||
|
if (tsdbWriteHeadFileIdx(fd, maxTables, pFile) < 0) {
|
||||||
|
close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tsdbWriteFileHead(fd, pFile) < 0) {
|
||||||
|
close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tsdbRemoveFile(SFile *pFile) {
|
||||||
|
if (pFile == NULL) return -1;
|
||||||
|
return remove(pFile->fname);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a file group with fileId and return a SFileGroup object
|
||||||
|
int tsdbCreateFileGroup(char *dataDir, int fileId, SFileGroup *pFGroup, int maxTables) {
|
||||||
|
if (dataDir == NULL || pFGroup == NULL) return -1;
|
||||||
|
|
||||||
|
memset((void *)pFGroup, 0, sizeof(SFileGroup));
|
||||||
|
|
||||||
|
for (int type = TSDB_FILE_TYPE_HEAD; type < TSDB_FILE_TYPE_MAX; type++) {
|
||||||
|
if (tsdbCreateFile(dataDir, fileId, type, maxTables, &(pFGroup->files[type])) < 0) {
|
||||||
|
// TODO: deal with the error here, remove the created files
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pFGroup->fileId = fileId;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the TSDB file handle
|
* Initialize the TSDB file handle
|
||||||
*/
|
*/
|
||||||
STsdbFileH *tsdbInitFile(char *dataDir, int32_t daysPerFile, int32_t keep, int32_t minRowsPerFBlock,
|
STsdbFileH *tsdbInitFile(char *dataDir, int32_t daysPerFile, int32_t keep, int32_t minRowsPerFBlock,
|
||||||
int32_t maxRowsPerFBlock) {
|
int32_t maxRowsPerFBlock, int32_t maxTables) {
|
||||||
STsdbFileH *pTsdbFileH =
|
STsdbFileH *pTsdbFileH =
|
||||||
(STsdbFileH *)calloc(1, sizeof(STsdbFileH) + sizeof(SFileGroup) * tsdbGetMaxNumOfFiles(keep, daysPerFile));
|
(STsdbFileH *)calloc(1, sizeof(STsdbFileH) + sizeof(SFileGroup) * tsdbGetMaxNumOfFiles(keep, daysPerFile));
|
||||||
if (pTsdbFileH == NULL) return NULL;
|
if (pTsdbFileH == NULL) return NULL;
|
||||||
|
@ -96,6 +173,7 @@ STsdbFileH *tsdbInitFile(char *dataDir, int32_t daysPerFile, int32_t keep, int32
|
||||||
pTsdbFileH->keep = keep;
|
pTsdbFileH->keep = keep;
|
||||||
pTsdbFileH->minRowPerFBlock = minRowsPerFBlock;
|
pTsdbFileH->minRowPerFBlock = minRowsPerFBlock;
|
||||||
pTsdbFileH->maxRowsPerFBlock = maxRowsPerFBlock;
|
pTsdbFileH->maxRowsPerFBlock = maxRowsPerFBlock;
|
||||||
|
pTsdbFileH->maxTables = maxTables;
|
||||||
|
|
||||||
// Open the directory to read information of each file
|
// Open the directory to read information of each file
|
||||||
DIR *dir = opendir(dataDir);
|
DIR *dir = opendir(dataDir);
|
||||||
|
@ -104,8 +182,9 @@ STsdbFileH *tsdbInitFile(char *dataDir, int32_t daysPerFile, int32_t keep, int32
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct dirent *dp;
|
|
||||||
char fname[256];
|
char fname[256];
|
||||||
|
|
||||||
|
struct dirent *dp;
|
||||||
while ((dp = readdir(dir)) != NULL) {
|
while ((dp = readdir(dir)) != NULL) {
|
||||||
if (strncmp(dp->d_name, ".", 1) == 0 || strncmp(dp->d_name, "..", 2) == 0) continue;
|
if (strncmp(dp->d_name, ".", 1) == 0 || strncmp(dp->d_name, "..", 2) == 0) continue;
|
||||||
if (true /* check if the file is the .head file */) {
|
if (true /* check if the file is the .head file */) {
|
||||||
|
@ -125,24 +204,7 @@ STsdbFileH *tsdbInitFile(char *dataDir, int32_t daysPerFile, int32_t keep, int32
|
||||||
return pTsdbFileH;
|
return pTsdbFileH;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
void tsdbGetKeyRangeOfFileId(int32_t daysPerFile, int8_t precision, int32_t fileId, TSKEY *minKey,
|
||||||
* Closet the file handle
|
|
||||||
*/
|
|
||||||
void tsdbCloseFile(STsdbFileH *pFileH) {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
char *tsdbGetFileName(char *dirName, char *fname, TSDB_FILE_TYPE type) {
|
|
||||||
if (!IS_VALID_TSDB_FILE_TYPE(type)) return NULL;
|
|
||||||
|
|
||||||
char *fileName = (char *)malloc(strlen(dirName) + strlen(fname) + strlen(tsdbFileSuffix[type]) + 5);
|
|
||||||
if (fileName == NULL) return NULL;
|
|
||||||
|
|
||||||
sprintf(fileName, "%s/%s%s", dirName, fname, tsdbFileSuffix[type]);
|
|
||||||
return fileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void tsdbGetKeyRangeOfFileId(int32_t daysPerFile, int8_t precision, int32_t fileId, TSKEY *minKey,
|
|
||||||
TSKEY *maxKey) {
|
TSKEY *maxKey) {
|
||||||
*minKey = fileId * daysPerFile * tsMsPerDay[precision];
|
*minKey = fileId * daysPerFile * tsMsPerDay[precision];
|
||||||
*maxKey = *minKey + daysPerFile * tsMsPerDay[precision] - 1;
|
*maxKey = *minKey + daysPerFile * tsMsPerDay[precision] - 1;
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
|
|
||||||
#define TSDB_CFG_FILE_NAME "CONFIG"
|
#define TSDB_CFG_FILE_NAME "CONFIG"
|
||||||
#define TSDB_DATA_DIR_NAME "data"
|
#define TSDB_DATA_DIR_NAME "data"
|
||||||
|
#define TSDB_DEFAULT_FILE_BLOCK_ROW_OPTION 0.7
|
||||||
|
|
||||||
enum { TSDB_REPO_STATE_ACTIVE, TSDB_REPO_STATE_CLOSED, TSDB_REPO_STATE_CONFIGURING };
|
enum { TSDB_REPO_STATE_ACTIVE, TSDB_REPO_STATE_CLOSED, TSDB_REPO_STATE_CONFIGURING };
|
||||||
|
|
||||||
|
@ -58,13 +59,16 @@ typedef struct _tsdb_repo {
|
||||||
// The cache Handle
|
// The cache Handle
|
||||||
STsdbCache *tsdbCache;
|
STsdbCache *tsdbCache;
|
||||||
|
|
||||||
|
// The TSDB file handle
|
||||||
|
STsdbFileH *tsdbFileH;
|
||||||
|
|
||||||
// Disk tier handle for multi-tier storage
|
// Disk tier handle for multi-tier storage
|
||||||
void *diskTier;
|
void *diskTier;
|
||||||
|
|
||||||
// File Store
|
pthread_mutex_t mutex;
|
||||||
void *tsdbFiles;
|
|
||||||
|
|
||||||
pthread_mutex_t tsdbMutex;
|
int commit;
|
||||||
|
pthread_t commitThread;
|
||||||
|
|
||||||
// A limiter to monitor the resources used by tsdb
|
// A limiter to monitor the resources used by tsdb
|
||||||
void *limiter;
|
void *limiter;
|
||||||
|
@ -79,6 +83,8 @@ static int32_t tsdbDestroyRepoEnv(STsdbRepo *pRepo);
|
||||||
static int tsdbOpenMetaFile(char *tsdbDir);
|
static int tsdbOpenMetaFile(char *tsdbDir);
|
||||||
static int32_t tsdbInsertDataToTable(tsdb_repo_t *repo, SSubmitBlk *pBlock);
|
static int32_t tsdbInsertDataToTable(tsdb_repo_t *repo, SSubmitBlk *pBlock);
|
||||||
static int32_t tsdbRestoreCfg(STsdbRepo *pRepo, STsdbCfg *pCfg);
|
static int32_t tsdbRestoreCfg(STsdbRepo *pRepo, STsdbCfg *pCfg);
|
||||||
|
static int32_t tsdbGetDataDirName(STsdbRepo *pRepo, char *fname);
|
||||||
|
static void * tsdbCommitToFile(void *arg);
|
||||||
|
|
||||||
#define TSDB_GET_TABLE_BY_ID(pRepo, sid) (((STSDBRepo *)pRepo)->pTableList)[sid]
|
#define TSDB_GET_TABLE_BY_ID(pRepo, sid) (((STSDBRepo *)pRepo)->pTableList)[sid]
|
||||||
#define TSDB_GET_TABLE_BY_NAME(pRepo, name)
|
#define TSDB_GET_TABLE_BY_NAME(pRepo, name)
|
||||||
|
@ -144,6 +150,7 @@ tsdb_repo_t *tsdbCreateRepo(char *rootDir, STsdbCfg *pCfg, void *limiter /* TODO
|
||||||
pRepo->rootDir = strdup(rootDir);
|
pRepo->rootDir = strdup(rootDir);
|
||||||
pRepo->config = *pCfg;
|
pRepo->config = *pCfg;
|
||||||
pRepo->limiter = limiter;
|
pRepo->limiter = limiter;
|
||||||
|
pthread_mutex_init(&pRepo->mutex, NULL);
|
||||||
|
|
||||||
// Create the environment files and directories
|
// Create the environment files and directories
|
||||||
if (tsdbSetRepoEnv(pRepo) < 0) {
|
if (tsdbSetRepoEnv(pRepo) < 0) {
|
||||||
|
@ -162,7 +169,7 @@ tsdb_repo_t *tsdbCreateRepo(char *rootDir, STsdbCfg *pCfg, void *limiter /* TODO
|
||||||
pRepo->tsdbMeta = pMeta;
|
pRepo->tsdbMeta = pMeta;
|
||||||
|
|
||||||
// Initialize cache
|
// Initialize cache
|
||||||
STsdbCache *pCache = tsdbInitCache(pCfg->maxCacheSize);
|
STsdbCache *pCache = tsdbInitCache(pCfg->maxCacheSize, -1, (tsdb_repo_t *)pRepo);
|
||||||
if (pCache == NULL) {
|
if (pCache == NULL) {
|
||||||
free(pRepo->rootDir);
|
free(pRepo->rootDir);
|
||||||
tsdbFreeMeta(pRepo->tsdbMeta);
|
tsdbFreeMeta(pRepo->tsdbMeta);
|
||||||
|
@ -171,6 +178,19 @@ tsdb_repo_t *tsdbCreateRepo(char *rootDir, STsdbCfg *pCfg, void *limiter /* TODO
|
||||||
}
|
}
|
||||||
pRepo->tsdbCache = pCache;
|
pRepo->tsdbCache = pCache;
|
||||||
|
|
||||||
|
// Initialize file handle
|
||||||
|
char dataDir[128] = "\0";
|
||||||
|
tsdbGetDataDirName(pRepo, dataDir);
|
||||||
|
pRepo->tsdbFileH =
|
||||||
|
tsdbInitFile(dataDir, pCfg->daysPerFile, pCfg->keep, pCfg->minRowsPerFileBlock, pCfg->maxRowsPerFileBlock, pCfg->maxTables);
|
||||||
|
if (pRepo->tsdbFileH == NULL) {
|
||||||
|
free(pRepo->rootDir);
|
||||||
|
tsdbFreeCache(pRepo->tsdbCache);
|
||||||
|
tsdbFreeMeta(pRepo->tsdbMeta);
|
||||||
|
free(pRepo);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
pRepo->state = TSDB_REPO_STATE_ACTIVE;
|
pRepo->state = TSDB_REPO_STATE_ACTIVE;
|
||||||
|
|
||||||
return (tsdb_repo_t *)pRepo;
|
return (tsdb_repo_t *)pRepo;
|
||||||
|
@ -230,7 +250,7 @@ tsdb_repo_t *tsdbOpenRepo(char *tsdbDir) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pRepo->tsdbCache = tsdbInitCache(pRepo->config.maxCacheSize);
|
pRepo->tsdbCache = tsdbInitCache(pRepo->config.maxCacheSize, -1, (tsdb_repo_t *)pRepo);
|
||||||
if (pRepo->tsdbCache == NULL) {
|
if (pRepo->tsdbCache == NULL) {
|
||||||
tsdbFreeMeta(pRepo->tsdbMeta);
|
tsdbFreeMeta(pRepo->tsdbMeta);
|
||||||
free(pRepo->rootDir);
|
free(pRepo->rootDir);
|
||||||
|
@ -284,6 +304,45 @@ int32_t tsdbConfigRepo(tsdb_repo_t *repo, STsdbCfg *pCfg) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t tsdbTriggerCommit(tsdb_repo_t *repo) {
|
||||||
|
STsdbRepo *pRepo = (STsdbRepo *)repo;
|
||||||
|
|
||||||
|
tsdbLockRepo(repo);
|
||||||
|
if (pRepo->commit) {
|
||||||
|
tsdbUnLockRepo(repo);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
pRepo->commit = 1;
|
||||||
|
// Loop to move pData to iData
|
||||||
|
for (int i = 0; i < pRepo->config.maxTables; i++) {
|
||||||
|
STable *pTable = pRepo->tsdbMeta->tables[i];
|
||||||
|
if (pTable != NULL && pTable->mem != NULL) {
|
||||||
|
pTable->imem = pTable->mem;
|
||||||
|
pTable->mem = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// TODO: Loop to move mem to imem
|
||||||
|
pRepo->tsdbCache->imem = pRepo->tsdbCache->mem;
|
||||||
|
pRepo->tsdbCache->mem = NULL;
|
||||||
|
pRepo->tsdbCache->curBlock = NULL;
|
||||||
|
|
||||||
|
// TODO: here should set as detached or use join for memory leak
|
||||||
|
pthread_create(&(pRepo->commitThread), NULL, tsdbCommitToFile, (void *)repo);
|
||||||
|
tsdbUnLockRepo(repo);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t tsdbLockRepo(tsdb_repo_t *repo) {
|
||||||
|
STsdbRepo *pRepo = (STsdbRepo *)repo;
|
||||||
|
return pthread_mutex_lock(repo);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t tsdbUnLockRepo(tsdb_repo_t *repo) {
|
||||||
|
STsdbRepo *pRepo = (STsdbRepo *)repo;
|
||||||
|
return pthread_mutex_unlock(repo);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the TSDB repository information, including some statistics
|
* Get the TSDB repository information, including some statistics
|
||||||
* @param pRepo the TSDB repository handle
|
* @param pRepo the TSDB repository handle
|
||||||
|
@ -440,6 +499,10 @@ SDataRow tsdbGetSubmitBlkNext(SSubmitBlkIter *pIter) {
|
||||||
int tsdbInitSubmitMsgIter(SSubmitMsg *pMsg, SSubmitMsgIter *pIter) {
|
int tsdbInitSubmitMsgIter(SSubmitMsg *pMsg, SSubmitMsgIter *pIter) {
|
||||||
if (pMsg == NULL || pIter == NULL) return -1;
|
if (pMsg == NULL || pIter == NULL) return -1;
|
||||||
|
|
||||||
|
pMsg->length = htonl(pMsg->length);
|
||||||
|
pMsg->numOfBlocks = htonl(pMsg->numOfBlocks);
|
||||||
|
pMsg->compressed = htonl(pMsg->compressed);
|
||||||
|
|
||||||
pIter->totalLen = pMsg->length;
|
pIter->totalLen = pMsg->length;
|
||||||
pIter->len = TSDB_SUBMIT_MSG_HEAD_SIZE;
|
pIter->len = TSDB_SUBMIT_MSG_HEAD_SIZE;
|
||||||
if (pMsg->length <= TSDB_SUBMIT_MSG_HEAD_SIZE) {
|
if (pMsg->length <= TSDB_SUBMIT_MSG_HEAD_SIZE) {
|
||||||
|
@ -454,7 +517,15 @@ int tsdbInitSubmitMsgIter(SSubmitMsg *pMsg, SSubmitMsgIter *pIter) {
|
||||||
SSubmitBlk *tsdbGetSubmitMsgNext(SSubmitMsgIter *pIter) {
|
SSubmitBlk *tsdbGetSubmitMsgNext(SSubmitMsgIter *pIter) {
|
||||||
SSubmitBlk *pBlock = pIter->pBlock;
|
SSubmitBlk *pBlock = pIter->pBlock;
|
||||||
if (pBlock == NULL) return NULL;
|
if (pBlock == NULL) return NULL;
|
||||||
|
|
||||||
|
pBlock->len = htonl(pBlock->len);
|
||||||
|
pBlock->numOfRows = htons(pBlock->numOfRows);
|
||||||
|
pBlock->uid = htobe64(pBlock->uid);
|
||||||
|
pBlock->tid = htonl(pBlock->tid);
|
||||||
|
|
||||||
|
pBlock->sversion = htonl(pBlock->sversion);
|
||||||
|
pBlock->padding = htonl(pBlock->padding);
|
||||||
|
|
||||||
pIter->len = pIter->len + sizeof(SSubmitBlk) + pBlock->len;
|
pIter->len = pIter->len + sizeof(SSubmitBlk) + pBlock->len;
|
||||||
if (pIter->len >= pIter->totalLen) {
|
if (pIter->len >= pIter->totalLen) {
|
||||||
pIter->pBlock = NULL;
|
pIter->pBlock = NULL;
|
||||||
|
@ -465,6 +536,11 @@ SSubmitBlk *tsdbGetSubmitMsgNext(SSubmitMsgIter *pIter) {
|
||||||
return pBlock;
|
return pBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STsdbMeta* tsdbGetMeta(tsdb_repo_t* pRepo) {
|
||||||
|
STsdbRepo *tsdb = (STsdbRepo *)pRepo;
|
||||||
|
return tsdb->tsdbMeta;
|
||||||
|
}
|
||||||
|
|
||||||
// Check the configuration and set default options
|
// Check the configuration and set default options
|
||||||
static int32_t tsdbCheckAndSetDefaultCfg(STsdbCfg *pCfg) {
|
static int32_t tsdbCheckAndSetDefaultCfg(STsdbCfg *pCfg) {
|
||||||
// Check precision
|
// Check precision
|
||||||
|
@ -612,9 +688,6 @@ static int32_t tsdbDestroyRepoEnv(STsdbRepo *pRepo) {
|
||||||
|
|
||||||
rmdir(dirName);
|
rmdir(dirName);
|
||||||
|
|
||||||
char *metaFname = tsdbGetFileName(pRepo->rootDir, "tsdb", TSDB_FILE_TYPE_META);
|
|
||||||
remove(metaFname);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -628,10 +701,21 @@ static int32_t tdInsertRowToTable(STsdbRepo *pRepo, SDataRow row, STable *pTable
|
||||||
int32_t level = 0;
|
int32_t level = 0;
|
||||||
int32_t headSize = 0;
|
int32_t headSize = 0;
|
||||||
|
|
||||||
tSkipListRandNodeInfo(pTable->content.pData, &level, &headSize);
|
if (pTable->mem == NULL) {
|
||||||
|
pTable->mem = (SMemTable *)calloc(1, sizeof(SMemTable));
|
||||||
|
if (pTable->mem == NULL) return -1;
|
||||||
|
pTable->mem->pData = tSkipListCreate(5, TSDB_DATA_TYPE_TIMESTAMP, TYPE_BYTES[TSDB_DATA_TYPE_TIMESTAMP], 0, 0, getTupleKey);
|
||||||
|
pTable->mem->keyFirst = INT64_MAX;
|
||||||
|
pTable->mem->keyLast = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
tSkipListRandNodeInfo(pTable->mem->pData, &level, &headSize);
|
||||||
|
|
||||||
|
TSKEY key = dataRowKey(row);
|
||||||
|
printf("insert:%lld, size:%d\n", key, pTable->mem->numOfPoints);
|
||||||
|
|
||||||
// Copy row into the memory
|
// Copy row into the memory
|
||||||
SSkipListNode *pNode = tsdbAllocFromCache(pRepo->tsdbCache, headSize + dataRowLen(row));
|
SSkipListNode *pNode = tsdbAllocFromCache(pRepo->tsdbCache, headSize + dataRowLen(row), key);
|
||||||
if (pNode == NULL) {
|
if (pNode == NULL) {
|
||||||
// TODO: deal with allocate failure
|
// TODO: deal with allocate failure
|
||||||
}
|
}
|
||||||
|
@ -640,7 +724,19 @@ static int32_t tdInsertRowToTable(STsdbRepo *pRepo, SDataRow row, STable *pTable
|
||||||
dataRowCpy(SL_GET_NODE_DATA(pNode), row);
|
dataRowCpy(SL_GET_NODE_DATA(pNode), row);
|
||||||
|
|
||||||
// Insert the skiplist node into the data
|
// Insert the skiplist node into the data
|
||||||
tsdbInsertRowToTableImpl(pNode, pTable);
|
if (pTable->mem == NULL) {
|
||||||
|
pTable->mem = (SMemTable *)calloc(1, sizeof(SMemTable));
|
||||||
|
if (pTable->mem == NULL) return -1;
|
||||||
|
pTable->mem->pData = tSkipListCreate(5, TSDB_DATA_TYPE_TIMESTAMP, TYPE_BYTES[TSDB_DATA_TYPE_TIMESTAMP], 0, 0, getTupleKey);
|
||||||
|
pTable->mem->keyFirst = INT64_MAX;
|
||||||
|
pTable->mem->keyLast = 0;
|
||||||
|
}
|
||||||
|
tSkipListPut(pTable->mem->pData, pNode);
|
||||||
|
if (key > pTable->mem->keyLast) pTable->mem->keyLast = key;
|
||||||
|
if (key < pTable->mem->keyFirst) pTable->mem->keyFirst = key;
|
||||||
|
|
||||||
|
pTable->mem->numOfPoints = tSkipListGetSize(pTable->mem->pData);
|
||||||
|
// pTable->mem->numOfPoints++;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -648,7 +744,8 @@ static int32_t tdInsertRowToTable(STsdbRepo *pRepo, SDataRow row, STable *pTable
|
||||||
static int32_t tsdbInsertDataToTable(tsdb_repo_t *repo, SSubmitBlk *pBlock) {
|
static int32_t tsdbInsertDataToTable(tsdb_repo_t *repo, SSubmitBlk *pBlock) {
|
||||||
STsdbRepo *pRepo = (STsdbRepo *)repo;
|
STsdbRepo *pRepo = (STsdbRepo *)repo;
|
||||||
|
|
||||||
STable *pTable = tsdbIsValidTableToInsert(pRepo->tsdbMeta, pBlock->tableId);
|
STableId tableId = {.uid = pBlock->uid, .tid = pBlock->tid};
|
||||||
|
STable *pTable = tsdbIsValidTableToInsert(pRepo->tsdbMeta, tableId);
|
||||||
if (pTable == NULL) return -1;
|
if (pTable == NULL) return -1;
|
||||||
|
|
||||||
SSubmitBlkIter blkIter;
|
SSubmitBlkIter blkIter;
|
||||||
|
@ -662,4 +759,106 @@ static int32_t tsdbInsertDataToTable(tsdb_repo_t *repo, SSubmitBlk *pBlock) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tsdbReadRowsFromCache(SSkipListIterator *pIter, TSKEY maxKey, int maxRowsToRead, SDataCol **cols, STSchema *pSchema) {
|
||||||
|
int numOfRows = 0;
|
||||||
|
do {
|
||||||
|
SSkipListNode *node = tSkipListIterGet(pIter);
|
||||||
|
if (node == NULL) break;
|
||||||
|
|
||||||
|
SDataRow row = SL_GET_NODE_DATA(node);
|
||||||
|
if (dataRowKey(row) > maxKey) break;
|
||||||
|
// Convert row data to column data
|
||||||
|
// for (int i = 0; i < schemaNCols(pSchema); i++) {
|
||||||
|
// STColumn *pCol = schemaColAt(pSchema, i);
|
||||||
|
// memcpy(cols[i]->data + TYPE_BYTES[colType(pCol)] * numOfRows, dataRowAt(row, pCol->offset),
|
||||||
|
// TYPE_BYTES[colType(pCol)]);
|
||||||
|
// }
|
||||||
|
|
||||||
|
numOfRows++;
|
||||||
|
if (numOfRows > maxRowsToRead) break;
|
||||||
|
} while (tSkipListIterNext(pIter));
|
||||||
|
return numOfRows;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Commit to file
|
||||||
|
static void *tsdbCommitToFile(void *arg) {
|
||||||
|
// TODO
|
||||||
|
STsdbRepo * pRepo = (STsdbRepo *)arg;
|
||||||
|
STsdbMeta * pMeta = pRepo->tsdbMeta;
|
||||||
|
STsdbCache *pCache = pRepo->tsdbCache;
|
||||||
|
STsdbCfg * pCfg = &(pRepo->config);
|
||||||
|
if (pCache->imem == NULL) return;
|
||||||
|
|
||||||
|
int sfid = tsdbGetKeyFileId(pCache->imem->keyFirst, pCfg->daysPerFile, pCfg->precision);
|
||||||
|
int efid = tsdbGetKeyFileId(pCache->imem->keyLast, pCfg->daysPerFile, pCfg->precision);
|
||||||
|
|
||||||
|
SSkipListIterator **iters = (SSkipListIterator **)calloc(pCfg->maxTables, sizeof(SSkipListIterator *));
|
||||||
|
if (iters == NULL) {
|
||||||
|
// TODO: deal with the error
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int maxCols = pMeta->maxCols;
|
||||||
|
int maxBytes = pMeta->maxRowBytes;
|
||||||
|
SDataCol **cols = (SDataCol **)malloc(sizeof(SDataCol *) * maxCols);
|
||||||
|
void *buf = malloc((maxBytes + sizeof(SDataCol)) * pCfg->maxRowsPerFileBlock);
|
||||||
|
|
||||||
|
for (int fid = sfid; fid <= efid; fid++) {
|
||||||
|
TSKEY minKey = 0, maxKey = 0;
|
||||||
|
tsdbGetKeyRangeOfFileId(pCfg->daysPerFile, pCfg->precision, fid, &minKey, &maxKey);
|
||||||
|
|
||||||
|
for (int tid = 0; tid < pCfg->maxTables; tid++) {
|
||||||
|
STable *pTable = pMeta->tables[tid];
|
||||||
|
if (pTable == NULL || pTable->imem == NULL) continue;
|
||||||
|
if (iters[tid] == NULL) { // create table iterator
|
||||||
|
iters[tid] = tSkipListCreateIter(pTable->imem->pData);
|
||||||
|
// TODO: deal with the error
|
||||||
|
if (iters[tid] == NULL) break;
|
||||||
|
if (!tSkipListIterNext(iters[tid])) {
|
||||||
|
// assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Init row data part
|
||||||
|
cols[0] = (SDataCol *)buf;
|
||||||
|
for (int col = 1; col < schemaNCols(pTable->schema); col++) {
|
||||||
|
cols[col] = (SDataCol *)((char *)(cols[col - 1]) + sizeof(SDataCol) + colBytes(schemaColAt(pTable->schema, col-1)) * pCfg->maxRowsPerFileBlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loop the iterator
|
||||||
|
int rowsRead = 0;
|
||||||
|
while ((rowsRead = tsdbReadRowsFromCache(iters[tid], maxKey, pCfg->maxRowsPerFileBlock, cols, pTable->schema)) >
|
||||||
|
0) {
|
||||||
|
// printf("rowsRead:%d-----------\n", rowsRead);
|
||||||
|
int k = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free the iterator
|
||||||
|
for (int tid = 0; tid < pCfg->maxTables; tid++) {
|
||||||
|
if (iters[tid] != NULL) tSkipListDestroyIter(iters[tid]);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(buf);
|
||||||
|
free(cols);
|
||||||
|
free(iters);
|
||||||
|
|
||||||
|
tsdbLockRepo(arg);
|
||||||
|
tdListMove(pCache->imem->list, pCache->pool.memPool);
|
||||||
|
free(pCache->imem);
|
||||||
|
pCache->imem = NULL;
|
||||||
|
pRepo->commit = 0;
|
||||||
|
// TODO: free the skiplist
|
||||||
|
for (int i = 0; i < pCfg->maxTables; i++) {
|
||||||
|
STable *pTable = pMeta->tables[i];
|
||||||
|
if (pTable && pTable->imem) { // Here has memory leak
|
||||||
|
pTable->imem = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tsdbUnLockRepo(arg);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
|
@ -18,7 +18,6 @@ static int tsdbAddTableIntoMap(STsdbMeta *pMeta, STable *pTable);
|
||||||
static int tsdbAddTableIntoIndex(STsdbMeta *pMeta, STable *pTable);
|
static int tsdbAddTableIntoIndex(STsdbMeta *pMeta, STable *pTable);
|
||||||
static int tsdbRemoveTableFromIndex(STsdbMeta *pMeta, STable *pTable);
|
static int tsdbRemoveTableFromIndex(STsdbMeta *pMeta, STable *pTable);
|
||||||
static int tsdbEstimateTableEncodeSize(STable *pTable);
|
static int tsdbEstimateTableEncodeSize(STable *pTable);
|
||||||
static char * getTupleKey(const void *data);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encode a TSDB table object as a binary content
|
* Encode a TSDB table object as a binary content
|
||||||
|
@ -102,12 +101,9 @@ int tsdbRestoreTable(void *pHandle, void *cont, int contLen) {
|
||||||
if (pTable == NULL) return -1;
|
if (pTable == NULL) return -1;
|
||||||
|
|
||||||
if (pTable->type == TSDB_SUPER_TABLE) {
|
if (pTable->type == TSDB_SUPER_TABLE) {
|
||||||
pTable->content.pIndex =
|
pTable->pIndex =
|
||||||
tSkipListCreate(TSDB_SUPER_TABLE_SL_LEVEL, TSDB_DATA_TYPE_TIMESTAMP, sizeof(int64_t), 1, 0, getTupleKey);
|
tSkipListCreate(TSDB_SUPER_TABLE_SL_LEVEL, TSDB_DATA_TYPE_TIMESTAMP, sizeof(int64_t), 1, 0, getTupleKey);
|
||||||
} else {
|
}
|
||||||
pTable->content.pData = tSkipListCreate(TSDB_SUPER_TABLE_SL_LEVEL, TSDB_DATA_TYPE_TIMESTAMP,
|
|
||||||
TYPE_BYTES[TSDB_DATA_TYPE_TIMESTAMP], 0, 0, getTupleKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
tsdbAddTableToMeta(pMeta, pTable, false);
|
tsdbAddTableToMeta(pMeta, pTable, false);
|
||||||
|
|
||||||
|
@ -137,6 +133,8 @@ STsdbMeta *tsdbInitMeta(const char *rootDir, int32_t maxTables) {
|
||||||
pMeta->nTables = 0;
|
pMeta->nTables = 0;
|
||||||
pMeta->superList = NULL;
|
pMeta->superList = NULL;
|
||||||
pMeta->tables = (STable **)calloc(maxTables, sizeof(STable *));
|
pMeta->tables = (STable **)calloc(maxTables, sizeof(STable *));
|
||||||
|
pMeta->maxRowBytes = 0;
|
||||||
|
pMeta->maxCols = 0;
|
||||||
if (pMeta->tables == NULL) {
|
if (pMeta->tables == NULL) {
|
||||||
free(pMeta);
|
free(pMeta);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -208,10 +206,10 @@ int32_t tsdbCreateTableImpl(STsdbMeta *pMeta, STableCfg *pCfg) {
|
||||||
super->schema = tdDupSchema(pCfg->schema);
|
super->schema = tdDupSchema(pCfg->schema);
|
||||||
super->tagSchema = tdDupSchema(pCfg->tagSchema);
|
super->tagSchema = tdDupSchema(pCfg->tagSchema);
|
||||||
super->tagVal = tdDataRowDup(pCfg->tagValues);
|
super->tagVal = tdDataRowDup(pCfg->tagValues);
|
||||||
super->content.pIndex = tSkipListCreate(TSDB_SUPER_TABLE_SL_LEVEL, TSDB_DATA_TYPE_TIMESTAMP, sizeof(int64_t), 1,
|
super->pIndex = tSkipListCreate(TSDB_SUPER_TABLE_SL_LEVEL, TSDB_DATA_TYPE_TIMESTAMP, sizeof(int64_t), 1,
|
||||||
0, getTupleKey); // Allow duplicate key, no lock
|
0, getTupleKey); // Allow duplicate key, no lock
|
||||||
|
|
||||||
if (super->content.pIndex == NULL) {
|
if (super->pIndex == NULL) {
|
||||||
tdFreeSchema(super->schema);
|
tdFreeSchema(super->schema);
|
||||||
tdFreeSchema(super->tagSchema);
|
tdFreeSchema(super->tagSchema);
|
||||||
tdFreeDataRow(super->tagVal);
|
tdFreeDataRow(super->tagVal);
|
||||||
|
@ -223,7 +221,7 @@ int32_t tsdbCreateTableImpl(STsdbMeta *pMeta, STableCfg *pCfg) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
STable *table = (STable *)malloc(sizeof(STable));
|
STable *table = (STable *)calloc(1, sizeof(STable));
|
||||||
if (table == NULL) {
|
if (table == NULL) {
|
||||||
if (newSuper) tsdbFreeTable(super);
|
if (newSuper) tsdbFreeTable(super);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -238,8 +236,11 @@ int32_t tsdbCreateTableImpl(STsdbMeta *pMeta, STableCfg *pCfg) {
|
||||||
table->type = TSDB_NORMAL_TABLE;
|
table->type = TSDB_NORMAL_TABLE;
|
||||||
table->superUid = -1;
|
table->superUid = -1;
|
||||||
table->schema = tdDupSchema(pCfg->schema);
|
table->schema = tdDupSchema(pCfg->schema);
|
||||||
|
if (schemaNCols(table->schema) > pMeta->maxCols) pMeta->maxCols = schemaNCols(table->schema);
|
||||||
|
tdUpdateSchema(table->schema);
|
||||||
|
int bytes = tdMaxRowBytesFromSchema(table->schema);
|
||||||
|
if (bytes > pMeta->maxRowBytes) pMeta->maxRowBytes = bytes;
|
||||||
}
|
}
|
||||||
table->content.pData = tSkipListCreate(TSDB_SUPER_TABLE_SL_LEVEL, TSDB_DATA_TYPE_TIMESTAMP, TYPE_BYTES[TSDB_DATA_TYPE_TIMESTAMP], 0, 0, getTupleKey);
|
|
||||||
|
|
||||||
// Register to meta
|
// Register to meta
|
||||||
if (newSuper) tsdbAddTableToMeta(pMeta, super, true);
|
if (newSuper) tsdbAddTableToMeta(pMeta, super, true);
|
||||||
|
@ -299,10 +300,10 @@ int32_t tsdbDropTableImpl(STsdbMeta *pMeta, STableId tableId) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tsdbInsertRowToTableImpl(SSkipListNode *pNode, STable *pTable) {
|
// int32_t tsdbInsertRowToTableImpl(SSkipListNode *pNode, STable *pTable) {
|
||||||
tSkipListPut(pTable->content.pData, pNode);
|
// tSkipListPut(pTable->mem->pData, pNode);
|
||||||
return 0;
|
// return 0;
|
||||||
}
|
// }
|
||||||
|
|
||||||
static int tsdbFreeTable(STable *pTable) {
|
static int tsdbFreeTable(STable *pTable) {
|
||||||
// TODO: finish this function
|
// TODO: finish this function
|
||||||
|
@ -314,10 +315,8 @@ static int tsdbFreeTable(STable *pTable) {
|
||||||
|
|
||||||
// Free content
|
// Free content
|
||||||
if (TSDB_TABLE_IS_SUPER_TABLE(pTable)) {
|
if (TSDB_TABLE_IS_SUPER_TABLE(pTable)) {
|
||||||
tSkipListDestroy(pTable->content.pIndex);
|
tSkipListDestroy(pTable->pIndex);
|
||||||
} else {
|
}
|
||||||
tSkipListDestroy(pTable->content.pData);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(pTable);
|
free(pTable);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -404,7 +403,7 @@ static int tsdbEstimateTableEncodeSize(STable *pTable) {
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *getTupleKey(const void * data) {
|
char *getTupleKey(const void * data) {
|
||||||
SDataRow row = (SDataRow)data;
|
SDataRow row = (SDataRow)data;
|
||||||
|
|
||||||
return dataRowAt(row, TD_DATA_ROW_HEAD_SIZE);
|
return dataRowAt(row, TD_DATA_ROW_HEAD_SIZE);
|
||||||
|
|
|
@ -14,5 +14,378 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "tsdb.h"
|
#include "tutil.h"
|
||||||
|
|
||||||
|
#include "tsdb.h"
|
||||||
|
#include "tsdbFile.h"
|
||||||
|
#include "tsdbMeta.h"
|
||||||
|
|
||||||
|
#define EXTRA_BYTES 2
|
||||||
|
#define PRIMARY_TSCOL_REQUIRED(c) (((SColumnInfoEx *)taosArrayGet(c, 0))->info.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX)
|
||||||
|
#define QUERY_IS_ASC_QUERY(o) (o == TSQL_SO_ASC)
|
||||||
|
#define QH_GET_NUM_OF_COLS(handle) (taosArrayGetSize((handle)->pColumns))
|
||||||
|
|
||||||
|
typedef struct SField {
|
||||||
|
// todo need the definition
|
||||||
|
} SField;
|
||||||
|
|
||||||
|
typedef struct SHeaderFileInfo {
|
||||||
|
int32_t fileId;
|
||||||
|
} SHeaderFileInfo;
|
||||||
|
|
||||||
|
typedef struct SQueryHandlePos {
|
||||||
|
int32_t fileId;
|
||||||
|
int32_t slot;
|
||||||
|
int32_t pos;
|
||||||
|
int32_t fileIndex;
|
||||||
|
} SQueryHandlePos;
|
||||||
|
|
||||||
|
typedef struct SDataBlockLoadInfo {
|
||||||
|
int32_t fileListIndex;
|
||||||
|
int32_t fileId;
|
||||||
|
int32_t slotIdx;
|
||||||
|
int32_t sid;
|
||||||
|
SArray *pLoadedCols;
|
||||||
|
} SDataBlockLoadInfo;
|
||||||
|
|
||||||
|
typedef struct SLoadCompBlockInfo {
|
||||||
|
int32_t sid; /* meter sid */
|
||||||
|
int32_t fileId;
|
||||||
|
int32_t fileListIndex;
|
||||||
|
} SLoadCompBlockInfo;
|
||||||
|
|
||||||
|
typedef struct SQueryFilesInfo {
|
||||||
|
SArray *pFileInfo;
|
||||||
|
int32_t current; // the memory mapped header file, NOTE: only one header file can be mmap.
|
||||||
|
int32_t vnodeId;
|
||||||
|
|
||||||
|
int32_t headerFd; // header file fd
|
||||||
|
int64_t headerFileSize;
|
||||||
|
int32_t dataFd;
|
||||||
|
int32_t lastFd;
|
||||||
|
|
||||||
|
char headerFilePath[PATH_MAX]; // current opened header file name
|
||||||
|
char dataFilePath[PATH_MAX]; // current opened data file name
|
||||||
|
char lastFilePath[PATH_MAX]; // current opened last file path
|
||||||
|
char dbFilePathPrefix[PATH_MAX];
|
||||||
|
} SQueryFilesInfo;
|
||||||
|
|
||||||
|
typedef struct STableQueryRec {
|
||||||
|
TSKEY lastKey;
|
||||||
|
STable * pTableObj;
|
||||||
|
int64_t offsetInHeaderFile;
|
||||||
|
int32_t numOfBlocks;
|
||||||
|
int32_t start;
|
||||||
|
SCompBlock *pBlock;
|
||||||
|
} STableQueryRec;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
SCompBlock *compBlock;
|
||||||
|
SField * fields;
|
||||||
|
} SCompBlockFields;
|
||||||
|
|
||||||
|
typedef struct STableDataBlockInfoEx {
|
||||||
|
SCompBlockFields pBlock;
|
||||||
|
STableQueryRec * pMeterDataInfo;
|
||||||
|
int32_t blockIndex;
|
||||||
|
int32_t groupIdx; /* number of group is less than the total number of meters */
|
||||||
|
} STableDataBlockInfoEx;
|
||||||
|
|
||||||
|
typedef struct STsdbQueryHandle {
|
||||||
|
struct STsdbRepo* pTsdb;
|
||||||
|
|
||||||
|
SQueryHandlePos cur; // current position
|
||||||
|
SQueryHandlePos start; // the start position, used for secondary/third iteration
|
||||||
|
int32_t unzipBufSize;
|
||||||
|
char *unzipBuffer;
|
||||||
|
char *secondaryUnzipBuffer;
|
||||||
|
|
||||||
|
SDataBlockLoadInfo dataBlockLoadInfo; /* record current block load information */
|
||||||
|
SLoadCompBlockInfo compBlockLoadInfo; /* record current compblock information in SQuery */
|
||||||
|
|
||||||
|
SQueryFilesInfo vnodeFileInfo;
|
||||||
|
|
||||||
|
int16_t numOfRowsPerPage;
|
||||||
|
uint16_t flag; // denotes reversed scan of data or not
|
||||||
|
int16_t order;
|
||||||
|
STimeWindow window; // the primary query time window that applies to all queries
|
||||||
|
TSKEY lastKey;
|
||||||
|
int32_t blockBufferSize;
|
||||||
|
SCompBlock *pBlock;
|
||||||
|
int32_t numOfBlocks;
|
||||||
|
SField ** pFields;
|
||||||
|
SArray * pColumns; // column list, SColumnInfoEx array list
|
||||||
|
SArray * pTableIdList; // table id object list
|
||||||
|
bool locateStart;
|
||||||
|
int32_t realNumOfRows;
|
||||||
|
bool loadDataAfterSeek; // load data after seek.
|
||||||
|
|
||||||
|
STableDataBlockInfoEx *pDataBlockInfoEx;
|
||||||
|
STableQueryRec * pTableQueryInfo;
|
||||||
|
int32_t tableIndex;
|
||||||
|
bool isFirstSlot;
|
||||||
|
void * qinfo; // query info handle, for debug purpose
|
||||||
|
} STsdbQueryHandle;
|
||||||
|
|
||||||
|
int32_t doAllocateBuf(STsdbQueryHandle *pQueryHandle, int32_t rowsPerFileBlock) {
|
||||||
|
// record the maximum column width among columns of this meter/metric
|
||||||
|
SColumnInfoEx *pColumn = taosArrayGet(pQueryHandle->pColumns, 0);
|
||||||
|
|
||||||
|
int32_t maxColWidth = pColumn->info.bytes;
|
||||||
|
for (int32_t i = 1; i < QH_GET_NUM_OF_COLS(pQueryHandle); ++i) {
|
||||||
|
int32_t bytes = pColumn[i].info.bytes;
|
||||||
|
if (bytes > maxColWidth) {
|
||||||
|
maxColWidth = bytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// only one unzip buffer required, since we can unzip each column one by one
|
||||||
|
pQueryHandle->unzipBufSize = (size_t)(maxColWidth * rowsPerFileBlock + EXTRA_BYTES); // plus extra_bytes
|
||||||
|
pQueryHandle->unzipBuffer = (char *)calloc(1, pQueryHandle->unzipBufSize);
|
||||||
|
|
||||||
|
pQueryHandle->secondaryUnzipBuffer = (char *)calloc(1, pQueryHandle->unzipBufSize);
|
||||||
|
|
||||||
|
if (pQueryHandle->unzipBuffer == NULL || pQueryHandle->secondaryUnzipBuffer == NULL) {
|
||||||
|
goto _error_clean;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
|
||||||
|
_error_clean:
|
||||||
|
tfree(pQueryHandle->unzipBuffer);
|
||||||
|
tfree(pQueryHandle->secondaryUnzipBuffer);
|
||||||
|
|
||||||
|
return TSDB_CODE_SERV_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void initQueryFileInfoFD(SQueryFilesInfo *pVnodeFilesInfo) {
|
||||||
|
pVnodeFilesInfo->current = -1;
|
||||||
|
pVnodeFilesInfo->headerFileSize = -1;
|
||||||
|
|
||||||
|
pVnodeFilesInfo->headerFd = FD_INITIALIZER; // set the initial value
|
||||||
|
pVnodeFilesInfo->dataFd = FD_INITIALIZER;
|
||||||
|
pVnodeFilesInfo->lastFd = FD_INITIALIZER;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vnodeInitDataBlockLoadInfo(SDataBlockLoadInfo *pBlockLoadInfo) {
|
||||||
|
pBlockLoadInfo->slotIdx = -1;
|
||||||
|
pBlockLoadInfo->fileId = -1;
|
||||||
|
pBlockLoadInfo->sid = -1;
|
||||||
|
pBlockLoadInfo->fileListIndex = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vnodeInitCompBlockLoadInfo(SLoadCompBlockInfo *pCompBlockLoadInfo) {
|
||||||
|
pCompBlockLoadInfo->sid = -1;
|
||||||
|
pCompBlockLoadInfo->fileId = -1;
|
||||||
|
pCompBlockLoadInfo->fileListIndex = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fileOrderComparFn(const void *p1, const void *p2) {
|
||||||
|
SHeaderFileInfo *pInfo1 = (SHeaderFileInfo *)p1;
|
||||||
|
SHeaderFileInfo *pInfo2 = (SHeaderFileInfo *)p2;
|
||||||
|
|
||||||
|
if (pInfo1->fileId == pInfo2->fileId) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (pInfo1->fileId > pInfo2->fileId) ? 1 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vnodeRecordAllFiles(int32_t vnodeId, SQueryFilesInfo *pVnodeFilesInfo) {
|
||||||
|
char suffix[] = ".head";
|
||||||
|
pVnodeFilesInfo->pFileInfo = taosArrayInit(4, sizeof(int32_t));
|
||||||
|
|
||||||
|
struct dirent *pEntry = NULL;
|
||||||
|
pVnodeFilesInfo->vnodeId = vnodeId;
|
||||||
|
char* tsDirectory = "";
|
||||||
|
|
||||||
|
sprintf(pVnodeFilesInfo->dbFilePathPrefix, "%s/vnode%d/db/", tsDirectory, vnodeId);
|
||||||
|
DIR *pDir = opendir(pVnodeFilesInfo->dbFilePathPrefix);
|
||||||
|
if (pDir == NULL) {
|
||||||
|
// dError("QInfo:%p failed to open directory:%s, %s", pQInfo, pVnodeFilesInfo->dbFilePathPrefix,
|
||||||
|
// strerror(errno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((pEntry = readdir(pDir)) != NULL) {
|
||||||
|
if ((pEntry->d_name[0] == '.' && pEntry->d_name[1] == '\0') || (strcmp(pEntry->d_name, "..") == 0)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pEntry->d_type & DT_DIR) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t len = strlen(pEntry->d_name);
|
||||||
|
if (strcasecmp(&pEntry->d_name[len - 5], suffix) != 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t vid = 0;
|
||||||
|
int32_t fid = 0;
|
||||||
|
sscanf(pEntry->d_name, "v%df%d", &vid, &fid);
|
||||||
|
if (vid != vnodeId) { /* ignore error files */
|
||||||
|
// dError("QInfo:%p error data file:%s in vid:%d, ignore", pQInfo, pEntry->d_name, vnodeId);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// int32_t firstFid = pVnode->fileId - pVnode->numOfFiles + 1;
|
||||||
|
// if (fid > pVnode->fileId || fid < firstFid) {
|
||||||
|
// dError("QInfo:%p error data file:%s in vid:%d, fid:%d, fid range:%d-%d", pQInfo, pEntry->d_name, vnodeId,
|
||||||
|
// fid, firstFid, pVnode->fileId);
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
|
||||||
|
assert(fid >= 0 && vid >= 0);
|
||||||
|
taosArrayPush(pVnodeFilesInfo->pFileInfo, &fid);
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir(pDir);
|
||||||
|
|
||||||
|
// dTrace("QInfo:%p find %d data files in %s to be checked", pQInfo, pVnodeFilesInfo->numOfFiles,
|
||||||
|
// pVnodeFilesInfo->dbFilePathPrefix);
|
||||||
|
|
||||||
|
// order the files information according their names */
|
||||||
|
size_t numOfFiles = taosArrayGetSize(pVnodeFilesInfo->pFileInfo);
|
||||||
|
qsort(pVnodeFilesInfo->pFileInfo->pData, numOfFiles, sizeof(SHeaderFileInfo), fileOrderComparFn);
|
||||||
|
}
|
||||||
|
|
||||||
|
tsdb_query_handle_t *tsdbQueryByTableId(tsdb_repo_t* tsdb, STsdbQueryCond *pCond, SArray *idList, SArray *pColumnInfo) {
|
||||||
|
// todo 1. filter not exist table
|
||||||
|
|
||||||
|
// todo 2. add the reference count for each table that is involved in query
|
||||||
|
|
||||||
|
STsdbQueryHandle *pQueryHandle = calloc(1, sizeof(STsdbQueryHandle));
|
||||||
|
pQueryHandle->order = pCond->order;
|
||||||
|
pQueryHandle->window = pCond->twindow;
|
||||||
|
pQueryHandle->pTsdb = tsdb;
|
||||||
|
|
||||||
|
pQueryHandle->pTableIdList = idList;
|
||||||
|
pQueryHandle->pColumns = pColumnInfo;
|
||||||
|
pQueryHandle->loadDataAfterSeek = false;
|
||||||
|
pQueryHandle->isFirstSlot = true;
|
||||||
|
|
||||||
|
pQueryHandle->lastKey = pQueryHandle->window.skey; // ascending query
|
||||||
|
|
||||||
|
// malloc buffer in order to load data from file
|
||||||
|
int32_t numOfCols = taosArrayGetSize(pColumnInfo);
|
||||||
|
size_t bufferCapacity = 4096;
|
||||||
|
|
||||||
|
pQueryHandle->pColumns = taosArrayInit(numOfCols, sizeof(SColumnInfoEx));
|
||||||
|
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||||
|
SColumnInfoEx *pCol = taosArrayGet(pColumnInfo, i);
|
||||||
|
SColumnInfoEx pDest = {{0}, 0};
|
||||||
|
|
||||||
|
pDest.pData = calloc(1, EXTRA_BYTES + bufferCapacity * pCol->info.bytes);
|
||||||
|
pDest.info = pCol->info;
|
||||||
|
taosArrayPush(pQueryHandle->pColumns, &pDest);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (doAllocateBuf(pQueryHandle, bufferCapacity) != TSDB_CODE_SUCCESS) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
initQueryFileInfoFD(&pQueryHandle->vnodeFileInfo);
|
||||||
|
vnodeInitDataBlockLoadInfo(&pQueryHandle->dataBlockLoadInfo);
|
||||||
|
vnodeInitCompBlockLoadInfo(&pQueryHandle->compBlockLoadInfo);
|
||||||
|
|
||||||
|
int32_t vnodeId = 1;
|
||||||
|
vnodeRecordAllFiles(vnodeId, &pQueryHandle->vnodeFileInfo);
|
||||||
|
|
||||||
|
return (tsdb_query_handle_t)pQueryHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t next = 1;
|
||||||
|
bool tsdbNextDataBlock(tsdb_query_handle_t *pQueryHandle) {
|
||||||
|
if (next == 0) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
next = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tsdbReadRowsFromCache(SSkipListIterator *pIter, TSKEY maxKey, int maxRowsToRead,
|
||||||
|
TSKEY* skey, TSKEY* ekey, STsdbQueryHandle* pHandle) {
|
||||||
|
int numOfRows = 0;
|
||||||
|
int32_t numOfCols = taosArrayGetSize(pHandle->pColumns);
|
||||||
|
*skey = INT64_MIN;
|
||||||
|
|
||||||
|
while(tSkipListIterNext(pIter)) {
|
||||||
|
SSkipListNode *node = tSkipListIterGet(pIter);
|
||||||
|
if (node == NULL) break;
|
||||||
|
|
||||||
|
SDataRow row = SL_GET_NODE_DATA(node);
|
||||||
|
if (dataRowKey(row) > maxKey) break;
|
||||||
|
// Convert row data to column data
|
||||||
|
|
||||||
|
if (*skey == INT64_MIN) {
|
||||||
|
*skey = dataRowKey(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
*ekey = dataRowKey(row);
|
||||||
|
|
||||||
|
int32_t offset = 0;
|
||||||
|
for(int32_t i = 0; i < numOfCols; ++i) {
|
||||||
|
SColumnInfoEx* pColInfo = taosArrayGet(pHandle->pColumns, 0);
|
||||||
|
memcpy(pColInfo->pData + numOfRows*pColInfo->info.bytes, dataRowTuple(row) + offset, pColInfo->info.bytes);
|
||||||
|
offset += pColInfo->info.bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
numOfRows++;
|
||||||
|
if (numOfRows > maxRowsToRead) break;
|
||||||
|
};
|
||||||
|
|
||||||
|
return numOfRows;
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy data from cache into data block
|
||||||
|
SDataBlockInfo tsdbRetrieveDataBlockInfo(tsdb_query_handle_t *pQueryHandle) {
|
||||||
|
STsdbQueryHandle* pHandle = (STsdbQueryHandle*) pQueryHandle;
|
||||||
|
STableIdInfo* idInfo = taosArrayGet(pHandle->pTableIdList, 0);
|
||||||
|
|
||||||
|
STableId tableId = {.uid = idInfo->uid, .tid = idInfo->sid};
|
||||||
|
STable *pTable = tsdbIsValidTableToInsert(tsdbGetMeta(pHandle->pTsdb), tableId);
|
||||||
|
assert(pTable != NULL);
|
||||||
|
|
||||||
|
TSKEY skey = 0, ekey = 0;
|
||||||
|
int32_t rows = 0;
|
||||||
|
|
||||||
|
if (pTable->mem != NULL) {
|
||||||
|
SSkipListIterator* iter = tSkipListCreateIter(pTable->mem->pData);
|
||||||
|
rows = tsdbReadRowsFromCache(iter, INT64_MAX, 4000, &skey, &ekey, pHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
SDataBlockInfo blockInfo = {
|
||||||
|
.uid = tableId.uid,
|
||||||
|
.sid = tableId.tid,
|
||||||
|
.size = rows,
|
||||||
|
.window = {.skey = skey, .ekey = ekey}
|
||||||
|
};
|
||||||
|
|
||||||
|
return blockInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return null for data block in cache
|
||||||
|
int32_t tsdbRetrieveDataBlockStatisInfo(tsdb_query_handle_t *pQueryHandle, SDataStatis **pBlockStatis) {
|
||||||
|
*pBlockStatis = NULL;
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
SArray *tsdbRetrieveDataBlock(tsdb_query_handle_t *pQueryHandle, SArray *pIdList) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t tsdbResetQuery(tsdb_query_handle_t *pQueryHandle, STimeWindow *window, tsdbpos_t position, int16_t order) {}
|
||||||
|
|
||||||
|
int32_t tsdbDataBlockSeek(tsdb_query_handle_t *pQueryHandle, tsdbpos_t pos) {}
|
||||||
|
|
||||||
|
tsdbpos_t tsdbDataBlockTell(tsdb_query_handle_t *pQueryHandle) { return NULL; }
|
||||||
|
|
||||||
|
SArray *tsdbRetrieveDataRow(tsdb_query_handle_t *pQueryHandle, SArray *pIdList, SQueryRowCond *pCond) {}
|
||||||
|
|
||||||
|
tsdb_query_handle_t *tsdbQueryFromTagConds(STsdbQueryCond *pCond, int16_t stableId, const char *pTagFilterStr) {}
|
||||||
|
|
||||||
|
STableIDList *tsdbGetTableList(tsdb_query_handle_t *pQueryHandle) {}
|
||||||
|
|
||||||
|
STableIDList *tsdbQueryTableList(int16_t stableId, const char *pTagCond) {}
|
||||||
|
|
|
@ -1,11 +1,19 @@
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include "tsdb.h"
|
#include "tsdb.h"
|
||||||
#include "dataformat.h"
|
#include "dataformat.h"
|
||||||
|
#include "tsdbFile.h"
|
||||||
#include "tsdbMeta.h"
|
#include "tsdbMeta.h"
|
||||||
|
|
||||||
TEST(TsdbTest, tableEncodeDecode) {
|
double getCurTime() {
|
||||||
|
struct timeval tv;
|
||||||
|
gettimeofday(&tv, NULL);
|
||||||
|
return tv.tv_sec + tv.tv_usec * 1E-6;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(TsdbTest, DISABLED_tableEncodeDecode) {
|
||||||
STable *pTable = (STable *)malloc(sizeof(STable));
|
STable *pTable = (STable *)malloc(sizeof(STable));
|
||||||
|
|
||||||
pTable->type = TSDB_NORMAL_TABLE;
|
pTable->type = TSDB_NORMAL_TABLE;
|
||||||
|
@ -39,7 +47,6 @@ TEST(TsdbTest, tableEncodeDecode) {
|
||||||
ASSERT_EQ(pTable->superUid, tTable->superUid);
|
ASSERT_EQ(pTable->superUid, tTable->superUid);
|
||||||
ASSERT_EQ(pTable->sversion, tTable->sversion);
|
ASSERT_EQ(pTable->sversion, tTable->sversion);
|
||||||
ASSERT_EQ(memcmp(pTable->schema, tTable->schema, sizeof(STSchema) + sizeof(STColumn) * nCols), 0);
|
ASSERT_EQ(memcmp(pTable->schema, tTable->schema, sizeof(STSchema) + sizeof(STColumn) * nCols), 0);
|
||||||
ASSERT_EQ(tTable->content.pData, nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(TsdbTest, createRepo) {
|
TEST(TsdbTest, createRepo) {
|
||||||
|
@ -71,39 +78,59 @@ TEST(TsdbTest, createRepo) {
|
||||||
tsdbCreateTable(pRepo, &tCfg);
|
tsdbCreateTable(pRepo, &tCfg);
|
||||||
|
|
||||||
// // 3. Loop to write some simple data
|
// // 3. Loop to write some simple data
|
||||||
int nRows = 10;
|
int nRows = 10000000;
|
||||||
SSubmitMsg *pMsg = (SSubmitMsg *)malloc(sizeof(SSubmitMsg) + sizeof(SSubmitBlk) + tdMaxRowBytesFromSchema(schema) * nRows);
|
int rowsPerSubmit = 100;
|
||||||
|
|
||||||
SSubmitBlk *pBlock = pMsg->blocks;
|
|
||||||
pBlock->tableId = {.uid = 987607499877672L, .tid = 0};
|
|
||||||
pBlock->sversion = 0;
|
|
||||||
pBlock->len = 0;
|
|
||||||
int64_t start_time = 1584081000000;
|
int64_t start_time = 1584081000000;
|
||||||
for (int i = 0; i < nRows; i++) {
|
|
||||||
int64_t ttime = start_time + 1000 * i;
|
|
||||||
SDataRow row = (SDataRow)(pBlock->data + pBlock->len);
|
|
||||||
tdInitDataRow(row, schema);
|
|
||||||
|
|
||||||
for (int j = 0; j < schemaNCols(schema); j++) {
|
SSubmitMsg *pMsg = (SSubmitMsg *)malloc(sizeof(SSubmitMsg) + sizeof(SSubmitBlk) + tdMaxRowBytesFromSchema(schema) * rowsPerSubmit);
|
||||||
if (j == 0) { // Just for timestamp
|
|
||||||
tdAppendColVal(row, (void *)(&ttime), schemaColAt(schema, j));
|
double stime = getCurTime();
|
||||||
} else { // For int
|
|
||||||
int val = 10;
|
for (int k = 0; k < nRows/rowsPerSubmit; k++) {
|
||||||
tdAppendColVal(row, (void *)(&val), schemaColAt(schema, j));
|
SSubmitBlk *pBlock = pMsg->blocks;
|
||||||
|
pBlock->tableId = {.uid = 987607499877672L, .tid = 0};
|
||||||
|
pBlock->sversion = 0;
|
||||||
|
pBlock->len = 0;
|
||||||
|
for (int i = 0; i < rowsPerSubmit; i++) {
|
||||||
|
// start_time += 1000;
|
||||||
|
start_time -= 1000;
|
||||||
|
SDataRow row = (SDataRow)(pBlock->data + pBlock->len);
|
||||||
|
tdInitDataRow(row, schema);
|
||||||
|
|
||||||
|
for (int j = 0; j < schemaNCols(schema); j++) {
|
||||||
|
if (j == 0) { // Just for timestamp
|
||||||
|
tdAppendColVal(row, (void *)(&start_time), schemaColAt(schema, j));
|
||||||
|
} else { // For int
|
||||||
|
int val = 10;
|
||||||
|
tdAppendColVal(row, (void *)(&val), schemaColAt(schema, j));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
pBlock->len += dataRowLen(row);
|
||||||
}
|
}
|
||||||
pBlock->len += dataRowLen(row);
|
pMsg->length = pMsg->length + sizeof(SSubmitBlk) + pBlock->len;
|
||||||
|
|
||||||
|
tsdbInsertData(pRepo, pMsg);
|
||||||
}
|
}
|
||||||
pMsg->length = pMsg->length + sizeof(SSubmitBlk) + pBlock->len;
|
|
||||||
|
|
||||||
tsdbInsertData(pRepo, pMsg);
|
double etime = getCurTime();
|
||||||
|
|
||||||
|
printf("Spent %f seconds to write %d records\n", etime - stime, nRows);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// tsdbTriggerCommit(pRepo);
|
||||||
|
|
||||||
int k = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(TsdbTest, openRepo) {
|
TEST(TsdbTest, DISABLED_openRepo) {
|
||||||
tsdb_repo_t *pRepo = tsdbOpenRepo("/home/ubuntu/work/ttest/vnode0");
|
tsdb_repo_t *pRepo = tsdbOpenRepo("/home/ubuntu/work/ttest/vnode0");
|
||||||
ASSERT_NE(pRepo, nullptr);
|
ASSERT_NE(pRepo, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(TsdbTest, DISABLED_createFileGroup) {
|
||||||
|
SFileGroup fGroup;
|
||||||
|
|
||||||
|
ASSERT_EQ(tsdbCreateFileGroup("/home/ubuntu/work/ttest/vnode0/data", 1820, &fGroup, 1000), 0);
|
||||||
|
|
||||||
|
int k = 0;
|
||||||
}
|
}
|
Loading…
Reference in New Issue