fix hb crash
This commit is contained in:
commit
d9544f8d33
|
@ -6,7 +6,7 @@ ExternalProject_Add(bdb
|
|||
SOURCE_DIR "${CMAKE_CONTRIB_DIR}/bdb"
|
||||
BINARY_DIR "${CMAKE_CONTRIB_DIR}/bdb"
|
||||
#BUILD_IN_SOURCE TRUE
|
||||
CONFIGURE_COMMAND "./dist/configure"
|
||||
CONFIGURE_COMMAND COMMAND ./dist/configure --enable-debug
|
||||
BUILD_COMMAND "$(MAKE)"
|
||||
INSTALL_COMMAND ""
|
||||
TEST_COMMAND ""
|
||||
|
|
|
@ -1179,6 +1179,13 @@ typedef struct {
|
|||
uint64_t taskId;
|
||||
} SSinkDataReq;
|
||||
|
||||
typedef struct {
|
||||
SMsgHead header;
|
||||
uint64_t sId;
|
||||
uint64_t queryId;
|
||||
uint64_t taskId;
|
||||
} SQueryContinueReq;
|
||||
|
||||
|
||||
typedef struct {
|
||||
SMsgHead header;
|
||||
|
@ -1471,7 +1478,7 @@ typedef struct {
|
|||
typedef struct {
|
||||
SMsgHead head;
|
||||
char name[TSDB_TABLE_FNAME_LEN];
|
||||
int8_t ignoreNotExists;
|
||||
int64_t suid;
|
||||
} SVDropTbReq;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -170,6 +170,8 @@ enum {
|
|||
TD_DEF_MSG_TYPE(TDMT_VND_DROP_TOPIC, "vnode-drop-topic", NULL, NULL)
|
||||
TD_DEF_MSG_TYPE(TDMT_VND_SHOW_TABLES, "vnode-show-tables", SVShowTablesReq, SVShowTablesRsp)
|
||||
TD_DEF_MSG_TYPE(TDMT_VND_SHOW_TABLES_FETCH, "vnode-show-tables-fetch", SVShowTablesFetchReq, SVShowTablesFetchRsp)
|
||||
TD_DEF_MSG_TYPE(TDMT_VND_QUERY_CONTINUE, "vnode-query-continue", NULL, NULL)
|
||||
TD_DEF_MSG_TYPE(TDMT_VND_SCHEDULE_DATA_SINK, "vnode-schedule-data-sink", NULL, NULL)
|
||||
|
||||
TD_DEF_MSG_TYPE(TDMT_VND_SUBSCRIBE, "vnode-subscribe", SMVSubscribeReq, SMVSubscribeRsp)
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ typedef struct SOutputData {
|
|||
int8_t compressed;
|
||||
char* pData;
|
||||
bool queryEnd;
|
||||
bool needSchedule;
|
||||
int32_t scheduleJobNo;
|
||||
int32_t bufStatus;
|
||||
int64_t useconds;
|
||||
int8_t precision;
|
||||
|
|
|
@ -22,9 +22,18 @@ extern "C" {
|
|||
|
||||
#include "trpc.h"
|
||||
|
||||
|
||||
enum {
|
||||
NODE_TYPE_VNODE = 1,
|
||||
NODE_TYPE_QNODE,
|
||||
NODE_TYPE_SNODE,
|
||||
};
|
||||
|
||||
|
||||
|
||||
typedef struct SQWorkerCfg {
|
||||
uint32_t maxSchedulerNum;
|
||||
uint32_t maxResCacheNum;
|
||||
uint32_t maxTaskNum;
|
||||
uint32_t maxSchTaskNum;
|
||||
} SQWorkerCfg;
|
||||
|
||||
|
@ -39,11 +48,17 @@ typedef struct {
|
|||
uint64_t numOfErrors;
|
||||
} SQWorkerStat;
|
||||
|
||||
typedef int32_t (*putReqToQueryQFp)(void *, struct SRpcMsg *);
|
||||
|
||||
int32_t qWorkerInit(SQWorkerCfg *cfg, void **qWorkerMgmt);
|
||||
|
||||
int32_t qWorkerInit(int8_t nodeType, int32_t nodeId, SQWorkerCfg *cfg, void **qWorkerMgmt, void *nodeObj, putReqToQueryQFp fp);
|
||||
|
||||
int32_t qWorkerProcessQueryMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg);
|
||||
|
||||
int32_t qWorkerProcessCQueryMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg);
|
||||
|
||||
int32_t qWorkerProcessDataSinkMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg);
|
||||
|
||||
int32_t qWorkerProcessReadyMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg);
|
||||
|
||||
int32_t qWorkerProcessStatusMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg);
|
||||
|
|
|
@ -59,6 +59,11 @@ typedef struct SQueryResult {
|
|||
char *msg;
|
||||
} SQueryResult;
|
||||
|
||||
typedef struct STaskInfo {
|
||||
SQueryNodeAddr addr;
|
||||
SSubQueryMsg *msg;
|
||||
} STaskInfo;
|
||||
|
||||
int32_t schedulerInit(SSchedulerCfg *cfg);
|
||||
|
||||
/**
|
||||
|
@ -101,6 +106,17 @@ void scheduleFreeJob(void *pJob);
|
|||
|
||||
void schedulerDestroy(void);
|
||||
|
||||
/**
|
||||
* convert dag to task list
|
||||
* @param pDag
|
||||
* @param pTasks SArray**<STaskInfo>
|
||||
* @return
|
||||
*/
|
||||
int32_t schedulerConvertDagToTaskList(SQueryDag* pDag, SArray **pTasks);
|
||||
|
||||
void schedulerFreeTaskList(SArray *taskList);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -356,7 +356,11 @@ int32_t* taosGetErrno();
|
|||
#define TSDB_CODE_QRY_TASK_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x0712) //"Task already exist")
|
||||
#define TSDB_CODE_QRY_RES_CACHE_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0713) //"Task result cache not exist")
|
||||
#define TSDB_CODE_QRY_TASK_CANCELLED TAOS_DEF_ERROR_CODE(0, 0x0714) //"Task cancelled")
|
||||
|
||||
#define TSDB_CODE_QRY_TASK_DROPPED TAOS_DEF_ERROR_CODE(0, 0x0715) //"Task dropped")
|
||||
#define TSDB_CODE_QRY_TASK_CANCELLING TAOS_DEF_ERROR_CODE(0, 0x0716) //"Task cancelling")
|
||||
#define TSDB_CODE_QRY_TASK_DROPPING TAOS_DEF_ERROR_CODE(0, 0x0717) //"Task dropping")
|
||||
#define TSDB_CODE_QRY_DUPLICATTED_OPERATION TAOS_DEF_ERROR_CODE(0, 0x0718) //"Duplicatted operation")
|
||||
#define TSDB_CODE_QRY_TASK_MSG_ERROR TAOS_DEF_ERROR_CODE(0, 0x0719) //"Task message error")
|
||||
|
||||
// grant
|
||||
#define TSDB_CODE_GRANT_EXPIRED TAOS_DEF_ERROR_CODE(0, 0x0800) //"License expired")
|
||||
|
|
|
@ -58,7 +58,7 @@ static char* getClusterKey(const char* user, const char* auth, const char* ip, i
|
|||
return strdup(key);
|
||||
}
|
||||
|
||||
static STscObj* taosConnectImpl(const char *ip, const char *user, const char *auth, const char *db, uint16_t port, __taos_async_fn_t fp, void *param, SAppInstInfo* pAppInfo);
|
||||
static STscObj* taosConnectImpl(const char *user, const char *auth, const char *db, uint16_t port, __taos_async_fn_t fp, void *param, SAppInstInfo* pAppInfo);
|
||||
static void setResSchemaInfo(SReqResultInfo* pResInfo, const SDataBlockSchema* pDataBlockSchema);
|
||||
|
||||
TAOS *taos_connect_internal(const char *ip, const char *user, const char *pass, const char *auth, const char *db, uint16_t port) {
|
||||
|
@ -71,18 +71,18 @@ TAOS *taos_connect_internal(const char *ip, const char *user, const char *pass,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
char tmp[TSDB_DB_NAME_LEN] = {0};
|
||||
char localDb[TSDB_DB_NAME_LEN] = {0};
|
||||
if (db != NULL) {
|
||||
if(!validateDbName(db)) {
|
||||
terrno = TSDB_CODE_TSC_INVALID_DB_LENGTH;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tstrncpy(tmp, db, sizeof(tmp));
|
||||
strdequote(tmp);
|
||||
tstrncpy(localDb, db, sizeof(localDb));
|
||||
strdequote(localDb);
|
||||
}
|
||||
|
||||
char secretEncrypt[32] = {0};
|
||||
char secretEncrypt[TSDB_PASSWORD_LEN + 1] = {0};
|
||||
if (auth == NULL) {
|
||||
if (!validatePassword(pass)) {
|
||||
terrno = TSDB_CODE_TSC_INVALID_PASS_LENGTH;
|
||||
|
@ -111,6 +111,7 @@ TAOS *taos_connect_internal(const char *ip, const char *user, const char *pass,
|
|||
|
||||
char* key = getClusterKey(user, secretEncrypt, ip, port);
|
||||
|
||||
// TODO: race condition here.
|
||||
SAppInstInfo** pInst = taosHashGet(appInfo.pInstMap, key, strlen(key));
|
||||
if (pInst == NULL) {
|
||||
SAppInstInfo* p = calloc(1, sizeof(struct SAppInstInfo));
|
||||
|
@ -123,7 +124,7 @@ TAOS *taos_connect_internal(const char *ip, const char *user, const char *pass,
|
|||
}
|
||||
|
||||
tfree(key);
|
||||
return taosConnectImpl(ip, user, &secretEncrypt[0], db, port, NULL, NULL, *pInst);
|
||||
return taosConnectImpl(user, &secretEncrypt[0], localDb, port, NULL, NULL, *pInst);
|
||||
}
|
||||
|
||||
int32_t buildRequest(STscObj *pTscObj, const char *sql, int sqlLen, SRequestObj** pRequest) {
|
||||
|
@ -259,6 +260,7 @@ int32_t scheduleQuery(SRequestObj* pRequest, SQueryDag* pDag) {
|
|||
return scheduleAsyncExecJob(pRequest->pTscObj->pAppInfo->pTransporter, NULL, pDag, &pRequest->body.pQueryJob);
|
||||
}
|
||||
|
||||
<<<<<<<<< Temporary merge branch 1
|
||||
typedef struct tmq_t tmq_t;
|
||||
|
||||
typedef struct SMqClientTopic {
|
||||
|
@ -290,8 +292,8 @@ typedef struct tmq_topic_vgroup_list_t {
|
|||
typedef void (tmq_commit_cb(tmq_t*, tmq_resp_err_t, tmq_topic_vgroup_list_t*, void* param));
|
||||
|
||||
typedef struct tmq_conf_t{
|
||||
char groupId[256];
|
||||
char clientId[256];
|
||||
char* clientId;
|
||||
char* groupId;
|
||||
char* ip;
|
||||
uint16_t port;
|
||||
tmq_commit_cb* commit_cb;
|
||||
|
@ -358,11 +360,10 @@ tmq_t* tmqCreateConsumerImpl(TAOS* conn, tmq_conf_t* conf) {
|
|||
}
|
||||
|
||||
TAOS_RES *taos_create_topic(TAOS* taos, const char* topicName, const char* sql, int sqlLen) {
|
||||
STscObj* pTscObj = (STscObj*)taos;
|
||||
SRequestObj* pRequest = NULL;
|
||||
SQueryNode* pQueryNode = NULL;
|
||||
SQueryDag* pDag = NULL;
|
||||
char *pStr = NULL;
|
||||
STscObj *pTscObj = (STscObj*)taos;
|
||||
SRequestObj *pRequest = NULL;
|
||||
SQueryNode *pQueryNode = NULL;
|
||||
char *pStr = NULL;
|
||||
|
||||
terrno = TSDB_CODE_SUCCESS;
|
||||
if (taos == NULL || topicName == NULL || sql == NULL) {
|
||||
|
@ -451,7 +452,7 @@ _return:
|
|||
}
|
||||
|
||||
typedef struct tmq_message_t {
|
||||
int32_t numOfRows;
|
||||
int32_t numOfRows;
|
||||
char* topicName;
|
||||
TAOS_ROW row[];
|
||||
} tmq_message_t;
|
||||
|
@ -465,7 +466,7 @@ tmq_resp_err_t* tmq_commit(tmq_t* mq, void* callback, int32_t async) {
|
|||
}
|
||||
|
||||
void tmq_message_destroy(tmq_message_t* mq_message) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -539,7 +540,7 @@ int initEpSetFromCfg(const char *firstEp, const char *secondEp, SCorEpSet *pEpSe
|
|||
return 0;
|
||||
}
|
||||
|
||||
STscObj* taosConnectImpl(const char *ip, const char *user, const char *auth, const char *db, uint16_t port, __taos_async_fn_t fp, void *param, SAppInstInfo* pAppInfo) {
|
||||
STscObj* taosConnectImpl(const char *user, const char *auth, const char *db, uint16_t port, __taos_async_fn_t fp, void *param, SAppInstInfo* pAppInfo) {
|
||||
STscObj *pTscObj = createTscObj(user, auth, db, pAppInfo);
|
||||
if (NULL == pTscObj) {
|
||||
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
|
@ -598,7 +599,9 @@ static SMsgSendInfo* buildConnectMsg(SRequestObj *pRequest) {
|
|||
STscObj *pObj = pRequest->pTscObj;
|
||||
|
||||
char* db = getConnectionDB(pObj);
|
||||
tstrncpy(pConnect->db, db, sizeof(pConnect->db));
|
||||
if (db != NULL) {
|
||||
tstrncpy(pConnect->db, db, sizeof(pConnect->db));
|
||||
}
|
||||
tfree(db);
|
||||
|
||||
pConnect->pid = htonl(appInfo.pid);
|
||||
|
@ -798,9 +801,12 @@ void setResultDataPtr(SReqResultInfo* pResultInfo, TAOS_FIELD* pFields, int32_t
|
|||
char* getConnectionDB(STscObj* pObj) {
|
||||
char *p = NULL;
|
||||
pthread_mutex_lock(&pObj->mutex);
|
||||
p = strndup(pObj->db, tListLen(pObj->db));
|
||||
pthread_mutex_unlock(&pObj->mutex);
|
||||
size_t len = strlen(pObj->db);
|
||||
if (len > 0) {
|
||||
p = strndup(pObj->db, tListLen(pObj->db));
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&pObj->mutex);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ int main(int argc, char** argv) {
|
|||
TEST(testCase, driverInit_Test) { taos_init(); }
|
||||
|
||||
TEST(testCase, connect_Test) {
|
||||
TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
|
||||
TAOS* pConn = taos_connect("localhost", "root", "taosdata", "abc1", 0);
|
||||
if (pConn == NULL) {
|
||||
printf("failed to connect to server, reason:%s\n", taos_errstr(NULL));
|
||||
}
|
||||
|
@ -149,36 +149,27 @@ TEST(testCase, connect_Test) {
|
|||
//}
|
||||
//
|
||||
//TEST(testCase, create_db_Test) {
|
||||
// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
|
||||
// assert(pConn != NULL);
|
||||
//
|
||||
// TAOS_RES* pRes = taos_query(pConn, "drop database abc1");
|
||||
// if (taos_errno(pRes) != 0) {
|
||||
// printf("failed to drop database, reason:%s\n", taos_errstr(pRes));
|
||||
// }
|
||||
//
|
||||
// taos_free_result(pRes);
|
||||
//
|
||||
// pRes = taos_query(pConn, "create database abc1 vgroups 2");
|
||||
// if (taos_errno(pRes) != 0) {
|
||||
// printf("error in create db, reason:%s\n", taos_errstr(pRes));
|
||||
// }
|
||||
//
|
||||
// TAOS_FIELD* pFields = taos_fetch_fields(pRes);
|
||||
// ASSERT_TRUE(pFields == NULL);
|
||||
//
|
||||
// int32_t numOfFields = taos_num_fields(pRes);
|
||||
// ASSERT_EQ(numOfFields, 0);
|
||||
//
|
||||
// taos_free_result(pRes);
|
||||
//
|
||||
// pRes = taos_query(pConn, "create database if not exists abc1 vgroups 4");
|
||||
// if (taos_errno(pRes) != 0) {
|
||||
// printf("failed to create database abc1, reason:%s\n", taos_errstr(pRes));
|
||||
// }
|
||||
//
|
||||
// taos_free_result(pRes);
|
||||
// taos_close(pConn);
|
||||
//TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
|
||||
//assert(pConn != NULL);
|
||||
|
||||
//TAOS_RES* pRes = taos_query(pConn, "create database abc1 vgroups 2");
|
||||
//if (taos_errno(pRes) != 0) {
|
||||
//printf("error in create db, reason:%s\n", taos_errstr(pRes));
|
||||
//}
|
||||
|
||||
//TAOS_FIELD* pFields = taos_fetch_fields(pRes);
|
||||
//ASSERT_TRUE(pFields == NULL);
|
||||
|
||||
//int32_t numOfFields = taos_num_fields(pRes);
|
||||
//ASSERT_EQ(numOfFields, 0);
|
||||
|
||||
//taos_free_result(pRes);
|
||||
|
||||
//pRes = taos_query(pConn, "create database abc1 vgroups 4");
|
||||
//if (taos_errno(pRes) != 0) {
|
||||
//printf("error in create db, reason:%s\n", taos_errstr(pRes));
|
||||
//}
|
||||
//taos_close(pConn);
|
||||
//}
|
||||
//
|
||||
//TEST(testCase, create_dnode_Test) {
|
||||
|
@ -263,7 +254,7 @@ TEST(testCase, connect_Test) {
|
|||
// taos_free_result(pRes);
|
||||
// taos_close(pConn);
|
||||
//}
|
||||
//
|
||||
|
||||
//TEST(testCase, create_stable_Test) {
|
||||
// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
|
||||
// assert(pConn != NULL);
|
||||
|
@ -274,13 +265,7 @@ TEST(testCase, connect_Test) {
|
|||
// }
|
||||
// taos_free_result(pRes);
|
||||
//
|
||||
// pRes = taos_query(pConn, "use abc1");
|
||||
// if (taos_errno(pRes) != 0) {
|
||||
// printf("error in use db, reason:%s\n", taos_errstr(pRes));
|
||||
// }
|
||||
// taos_free_result(pRes);
|
||||
//
|
||||
// pRes = taos_query(pConn, "create stable st1(ts timestamp, k int) tags(a int)");
|
||||
// pRes = taos_query(pConn, "create table if not exists abc1.st1(ts timestamp, k int) tags(a int)");
|
||||
// if (taos_errno(pRes) != 0) {
|
||||
// printf("error in create stable, reason:%s\n", taos_errstr(pRes));
|
||||
// }
|
||||
|
@ -295,19 +280,40 @@ TEST(testCase, connect_Test) {
|
|||
// taos_close(pConn);
|
||||
//}
|
||||
//
|
||||
//TEST(testCase, create_table_Test) {
|
||||
// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
|
||||
// assert(pConn != NULL);
|
||||
// pRes = taos_query(pConn, "create stable if not exists abc1.`123_$^)` (ts timestamp, `abc` int) tags(a int)");
|
||||
// if (taos_errno(pRes) != 0) {
|
||||
// printf("failed to create super table 123_$^), reason:%s\n", taos_errstr(pRes));
|
||||
// }
|
||||
//
|
||||
// TAOS_RES* pRes = taos_query(pConn, "use abc1");
|
||||
// taos_free_result(pRes);
|
||||
//
|
||||
// pRes = taos_query(pConn, "create table tm0(ts timestamp, k int)");
|
||||
// taos_free_result(pRes);
|
||||
// pRes = taos_query(pConn, "drop stable `123_$^)`");
|
||||
// if (taos_errno(pRes) != 0) {
|
||||
// printf("failed to drop super table 123_$^), reason:%s\n", taos_errstr(pRes));
|
||||
// }
|
||||
//
|
||||
// taos_close(pConn);
|
||||
//}
|
||||
//
|
||||
|
||||
TEST(testCase, create_table_Test) {
|
||||
TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
|
||||
assert(pConn != NULL);
|
||||
|
||||
TAOS_RES* pRes = taos_query(pConn, "use abc1");
|
||||
taos_free_result(pRes);
|
||||
|
||||
pRes = taos_query(pConn, "create table if not exists tm0(ts timestamp, k int)");
|
||||
ASSERT_EQ(taos_errno(pRes), 0);
|
||||
|
||||
taos_free_result(pRes);
|
||||
|
||||
pRes = taos_query(pConn, "create table if not exists tm0(ts timestamp, k blob)");
|
||||
ASSERT_NE(taos_errno(pRes), 0);
|
||||
|
||||
taos_free_result(pRes);
|
||||
taos_close(pConn);
|
||||
}
|
||||
|
||||
//TEST(testCase, create_ctable_Test) {
|
||||
// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
|
||||
// assert(pConn != NULL);
|
||||
|
@ -326,37 +332,37 @@ TEST(testCase, connect_Test) {
|
|||
// taos_free_result(pRes);
|
||||
// taos_close(pConn);
|
||||
//}
|
||||
//
|
||||
//TEST(testCase, show_stable_Test) {
|
||||
// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
|
||||
// assert(pConn != NULL);
|
||||
//
|
||||
|
||||
TEST(testCase, show_stable_Test) {
|
||||
TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
|
||||
assert(pConn != nullptr);
|
||||
|
||||
// TAOS_RES* pRes = taos_query(pConn, "use abc1");
|
||||
// if (taos_errno(pRes) != 0) {
|
||||
// printf("failed to use db, reason:%s\n", taos_errstr(pRes));
|
||||
// }
|
||||
// taos_free_result(pRes);
|
||||
//
|
||||
// pRes = taos_query(pConn, "show stables");
|
||||
// if (taos_errno(pRes) != 0) {
|
||||
// printf("failed to show stables, reason:%s\n", taos_errstr(pRes));
|
||||
// taos_free_result(pRes);
|
||||
// ASSERT_TRUE(false);
|
||||
// }
|
||||
//
|
||||
// TAOS_ROW pRow = NULL;
|
||||
// TAOS_FIELD* pFields = taos_fetch_fields(pRes);
|
||||
// int32_t numOfFields = taos_num_fields(pRes);
|
||||
//
|
||||
// char str[512] = {0};
|
||||
// while ((pRow = taos_fetch_row(pRes)) != NULL) {
|
||||
// int32_t code = taos_print_row(str, pRow, pFields, numOfFields);
|
||||
// printf("%s\n", str);
|
||||
// }
|
||||
//
|
||||
// taos_free_result(pRes);
|
||||
// taos_close(pConn);
|
||||
//}
|
||||
|
||||
TAOS_RES* pRes = taos_query(pConn, "show abc1.stables");
|
||||
if (taos_errno(pRes) != 0) {
|
||||
printf("failed to show stables, reason:%s\n", taos_errstr(pRes));
|
||||
taos_free_result(pRes);
|
||||
ASSERT_TRUE(false);
|
||||
}
|
||||
|
||||
TAOS_ROW pRow = NULL;
|
||||
TAOS_FIELD* pFields = taos_fetch_fields(pRes);
|
||||
int32_t numOfFields = taos_num_fields(pRes);
|
||||
|
||||
char str[512] = {0};
|
||||
while ((pRow = taos_fetch_row(pRes)) != NULL) {
|
||||
int32_t code = taos_print_row(str, pRow, pFields, numOfFields);
|
||||
printf("%s\n", str);
|
||||
}
|
||||
|
||||
taos_free_result(pRes);
|
||||
taos_close(pConn);
|
||||
}
|
||||
//
|
||||
//TEST(testCase, show_vgroup_Test) {
|
||||
// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
|
||||
|
@ -515,29 +521,29 @@ TEST(testCase, connect_Test) {
|
|||
// taosHashCleanup(phash);
|
||||
//}
|
||||
//
|
||||
TEST(testCase, create_topic_Test) {
|
||||
TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
|
||||
assert(pConn != NULL);
|
||||
|
||||
TAOS_RES* pRes = taos_query(pConn, "use abc1");
|
||||
if (taos_errno(pRes) != 0) {
|
||||
printf("error in use db, reason:%s\n", taos_errstr(pRes));
|
||||
}
|
||||
taos_free_result(pRes);
|
||||
|
||||
TAOS_FIELD* pFields = taos_fetch_fields(pRes);
|
||||
ASSERT_TRUE(pFields == nullptr);
|
||||
|
||||
int32_t numOfFields = taos_num_fields(pRes);
|
||||
ASSERT_EQ(numOfFields, 0);
|
||||
|
||||
taos_free_result(pRes);
|
||||
|
||||
char* sql = "select * from tu";
|
||||
pRes = taos_create_topic(pConn, "test_topic_1", sql, strlen(sql));
|
||||
taos_free_result(pRes);
|
||||
taos_close(pConn);
|
||||
}
|
||||
//TEST(testCase, create_topic_Test) {
|
||||
// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
|
||||
// assert(pConn != NULL);
|
||||
//
|
||||
// TAOS_RES* pRes = taos_query(pConn, "use abc1");
|
||||
// if (taos_errno(pRes) != 0) {
|
||||
// printf("error in use db, reason:%s\n", taos_errstr(pRes));
|
||||
// }
|
||||
// taos_free_result(pRes);
|
||||
//
|
||||
// TAOS_FIELD* pFields = taos_fetch_fields(pRes);
|
||||
// ASSERT_TRUE(pFields == nullptr);
|
||||
//
|
||||
// int32_t numOfFields = taos_num_fields(pRes);
|
||||
// ASSERT_EQ(numOfFields, 0);
|
||||
//
|
||||
// taos_free_result(pRes);
|
||||
//
|
||||
// char* sql = "select * from tu";
|
||||
// pRes = taos_create_topic(pConn, "test_topic_1", sql, strlen(sql));
|
||||
// taos_free_result(pRes);
|
||||
// taos_close(pConn);
|
||||
//}
|
||||
//
|
||||
//TEST(testCase, insert_test) {
|
||||
// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
|
||||
|
@ -612,25 +618,8 @@ TEST(testCase, create_topic_Test) {
|
|||
// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
|
||||
// ASSERT_NE(pConn, nullptr);
|
||||
//
|
||||
//// TAOS_RES* pRes = taos_query(pConn, "create database abc1 vgroups 2");
|
||||
//// if (taos_errno(pRes) != 0) {
|
||||
//// printf("failed to use db, reason:%s\n", taos_errstr(pRes));
|
||||
//// taos_free_result(pRes);
|
||||
//// return;
|
||||
//// }
|
||||
//
|
||||
//// taos_free_result(pRes);
|
||||
//
|
||||
// TAOS_RES* pRes = taos_query(pConn, "use abc1");
|
||||
//
|
||||
//// pRes = taos_query(pConn, "create table m1 (ts timestamp, k int) tags(a int)");
|
||||
// taos_free_result(pRes);
|
||||
////
|
||||
//// pRes = taos_query(pConn, "create table tu using m1 tags(1)");
|
||||
//// taos_free_result(pRes);
|
||||
////
|
||||
//// pRes = taos_query(pConn, "insert into tu values(now, 1)");
|
||||
//// taos_free_result(pRes);
|
||||
//
|
||||
// pRes = taos_query(pConn, "select ts,k from m1");
|
||||
// if (taos_errno(pRes) != 0) {
|
||||
|
|
|
@ -421,6 +421,10 @@ static int32_t dndOpenVnodes(SDnode *pDnode) {
|
|||
pMgmt->totalVnodes = numOfVnodes;
|
||||
|
||||
int32_t threadNum = pDnode->env.numOfCores;
|
||||
#if 1
|
||||
threadNum = 1;
|
||||
#endif
|
||||
|
||||
int32_t vnodesPerThread = numOfVnodes / threadNum + 1;
|
||||
|
||||
SVnodeThread *threads = calloc(threadNum, sizeof(SVnodeThread));
|
||||
|
|
|
@ -5,4 +5,5 @@ add_subdirectory(bnode)
|
|||
add_subdirectory(snode)
|
||||
add_subdirectory(mnode)
|
||||
add_subdirectory(vnode)
|
||||
add_subdirectory(stb)
|
||||
add_subdirectory(sut)
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
aux_source_directory(. DSTB_SRC)
|
||||
add_executable(dnode_test_stb ${DSTB_SRC})
|
||||
target_link_libraries(
|
||||
dnode_test_stb
|
||||
PUBLIC sut
|
||||
)
|
||||
|
||||
add_test(
|
||||
NAME dnode_test_stb
|
||||
COMMAND dnode_test_stb
|
||||
)
|
|
@ -0,0 +1,139 @@
|
|||
/**
|
||||
* @file db.cpp
|
||||
* @author slguan (slguan@taosdata.com)
|
||||
* @brief DNODE module vnode tests
|
||||
* @version 0.1
|
||||
* @date 2021-12-20
|
||||
*
|
||||
* @copyright Copyright (c) 2021
|
||||
*
|
||||
*/
|
||||
|
||||
#include "sut.h"
|
||||
|
||||
class DndTestVnode : public ::testing::Test {
|
||||
protected:
|
||||
static void SetUpTestSuite() { test.Init("/tmp/dnode_test_stb", 9116); }
|
||||
static void TearDownTestSuite() { test.Cleanup(); }
|
||||
|
||||
static Testbase test;
|
||||
|
||||
public:
|
||||
void SetUp() override {}
|
||||
void TearDown() override {}
|
||||
};
|
||||
|
||||
Testbase DndTestVnode::test;
|
||||
|
||||
TEST_F(DndTestVnode, 01_Create_Restart_Drop_Vnode) {
|
||||
{
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
int32_t contLen = sizeof(SCreateVnodeReq);
|
||||
|
||||
SCreateVnodeReq* pReq = (SCreateVnodeReq*)rpcMallocCont(contLen);
|
||||
pReq->vgId = htonl(2);
|
||||
pReq->dnodeId = htonl(1);
|
||||
strcpy(pReq->db, "1.d1");
|
||||
pReq->dbUid = htobe64(9527);
|
||||
pReq->vgVersion = htonl(1);
|
||||
pReq->cacheBlockSize = htonl(16);
|
||||
pReq->totalBlocks = htonl(10);
|
||||
pReq->daysPerFile = htonl(10);
|
||||
pReq->daysToKeep0 = htonl(3650);
|
||||
pReq->daysToKeep1 = htonl(3650);
|
||||
pReq->daysToKeep2 = htonl(3650);
|
||||
pReq->minRows = htonl(100);
|
||||
pReq->minRows = htonl(4096);
|
||||
pReq->commitTime = htonl(3600);
|
||||
pReq->fsyncPeriod = htonl(3000);
|
||||
pReq->walLevel = 1;
|
||||
pReq->precision = 0;
|
||||
pReq->compression = 2;
|
||||
pReq->replica = 1;
|
||||
pReq->quorum = 1;
|
||||
pReq->update = 0;
|
||||
pReq->cacheLastRow = 0;
|
||||
pReq->selfIndex = 0;
|
||||
for (int r = 0; r < pReq->replica; ++r) {
|
||||
SReplica* pReplica = &pReq->replicas[r];
|
||||
pReplica->id = htonl(1);
|
||||
pReplica->port = htons(9527);
|
||||
}
|
||||
|
||||
SRpcMsg* pRsp = test.SendReq(TDMT_DND_CREATE_VNODE, pReq, contLen);
|
||||
ASSERT_NE(pRsp, nullptr);
|
||||
if (i == 0) {
|
||||
ASSERT_EQ(pRsp->code, 0);
|
||||
test.Restart();
|
||||
} else {
|
||||
ASSERT_EQ(pRsp->code, TSDB_CODE_DND_VNODE_ALREADY_DEPLOYED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
int32_t contLen = sizeof(SAlterVnodeReq);
|
||||
|
||||
SAlterVnodeReq* pReq = (SAlterVnodeReq*)rpcMallocCont(contLen);
|
||||
pReq->vgId = htonl(2);
|
||||
pReq->dnodeId = htonl(1);
|
||||
strcpy(pReq->db, "1.d1");
|
||||
pReq->dbUid = htobe64(9527);
|
||||
pReq->vgVersion = htonl(2);
|
||||
pReq->cacheBlockSize = htonl(16);
|
||||
pReq->totalBlocks = htonl(10);
|
||||
pReq->daysPerFile = htonl(10);
|
||||
pReq->daysToKeep0 = htonl(3650);
|
||||
pReq->daysToKeep1 = htonl(3650);
|
||||
pReq->daysToKeep2 = htonl(3650);
|
||||
pReq->minRows = htonl(100);
|
||||
pReq->minRows = htonl(4096);
|
||||
pReq->commitTime = htonl(3600);
|
||||
pReq->fsyncPeriod = htonl(3000);
|
||||
pReq->walLevel = 1;
|
||||
pReq->precision = 0;
|
||||
pReq->compression = 2;
|
||||
pReq->replica = 1;
|
||||
pReq->quorum = 1;
|
||||
pReq->update = 0;
|
||||
pReq->cacheLastRow = 0;
|
||||
pReq->selfIndex = 0;
|
||||
for (int r = 0; r < pReq->replica; ++r) {
|
||||
SReplica* pReplica = &pReq->replicas[r];
|
||||
pReplica->id = htonl(1);
|
||||
pReplica->port = htons(9527);
|
||||
}
|
||||
|
||||
SRpcMsg* pRsp = test.SendReq(TDMT_DND_ALTER_VNODE, pReq, contLen);
|
||||
ASSERT_NE(pRsp, nullptr);
|
||||
ASSERT_EQ(pRsp->code, 0);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
int32_t contLen = sizeof(SDropVnodeReq);
|
||||
|
||||
SDropVnodeReq* pReq = (SDropVnodeReq*)rpcMallocCont(contLen);
|
||||
pReq->vgId = htonl(2);
|
||||
pReq->dnodeId = htonl(1);
|
||||
strcpy(pReq->db, "1.d1");
|
||||
pReq->dbUid = htobe64(9527);
|
||||
|
||||
SRpcMsg rpcMsg = {0};
|
||||
rpcMsg.pCont = pReq;
|
||||
rpcMsg.contLen = sizeof(SDropVnodeReq);
|
||||
rpcMsg.msgType = TDMT_DND_DROP_VNODE;
|
||||
|
||||
SRpcMsg* pRsp = test.SendReq(TDMT_DND_DROP_VNODE, pReq, contLen);
|
||||
ASSERT_NE(pRsp, nullptr);
|
||||
if (i == 0) {
|
||||
ASSERT_EQ(pRsp->code, 0);
|
||||
test.Restart();
|
||||
} else {
|
||||
ASSERT_EQ(pRsp->code, TSDB_CODE_DND_VNODE_NOT_DEPLOYED);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -613,32 +613,14 @@ static int32_t mndSetUpdateDbRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj
|
|||
static int32_t mndUpdateDb(SMnode *pMnode, SMnodeMsg *pReq, SDbObj *pOld, SDbObj *pNew) {
|
||||
int32_t code = -1;
|
||||
STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, &pReq->rpcMsg);
|
||||
if (pTrans == NULL) {
|
||||
mError("db:%s, failed to update since %s", pOld->name, terrstr());
|
||||
return terrno;
|
||||
}
|
||||
if (pTrans == NULL) goto UPDATE_DB_OVER;
|
||||
|
||||
mDebug("trans:%d, used to update db:%s", pTrans->id, pOld->name);
|
||||
|
||||
if (mndSetUpdateDbRedoLogs(pMnode, pTrans, pOld, pNew) != 0) {
|
||||
mError("trans:%d, failed to set redo log since %s", pTrans->id, terrstr());
|
||||
goto UPDATE_DB_OVER;
|
||||
}
|
||||
|
||||
if (mndSetUpdateDbCommitLogs(pMnode, pTrans, pOld, pNew) != 0) {
|
||||
mError("trans:%d, failed to set commit log since %s", pTrans->id, terrstr());
|
||||
goto UPDATE_DB_OVER;
|
||||
}
|
||||
|
||||
if (mndSetUpdateDbRedoActions(pMnode, pTrans, pOld, pNew) != 0) {
|
||||
mError("trans:%d, failed to set redo actions since %s", pTrans->id, terrstr());
|
||||
goto UPDATE_DB_OVER;
|
||||
}
|
||||
|
||||
if (mndTransPrepare(pMnode, pTrans) != 0) {
|
||||
mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
|
||||
goto UPDATE_DB_OVER;
|
||||
}
|
||||
if (mndSetUpdateDbRedoLogs(pMnode, pTrans, pOld, pNew) != 0) goto UPDATE_DB_OVER;
|
||||
if (mndSetUpdateDbCommitLogs(pMnode, pTrans, pOld, pNew) != 0) goto UPDATE_DB_OVER;
|
||||
if (mndSetUpdateDbRedoActions(pMnode, pTrans, pOld, pNew) != 0) goto UPDATE_DB_OVER;
|
||||
if (mndTransPrepare(pMnode, pTrans) != 0) goto UPDATE_DB_OVER;
|
||||
|
||||
code = 0;
|
||||
|
||||
|
|
|
@ -182,7 +182,12 @@ static void mndCancelGetNextConn(SMnode *pMnode, void *pIter) {
|
|||
}
|
||||
|
||||
static int32_t mndProcessConnectReq(SMnodeMsg *pReq) {
|
||||
SMnode *pMnode = pReq->pMnode;
|
||||
SMnode *pMnode = pReq->pMnode;
|
||||
SUserObj *pUser = NULL;
|
||||
SDbObj *pDb = NULL;
|
||||
SConnObj *pConn = NULL;
|
||||
int32_t code = -1;
|
||||
|
||||
SConnectReq *pConnReq = pReq->rpcMsg.pCont;
|
||||
pConnReq->pid = htonl(pConnReq->pid);
|
||||
pConnReq->startTime = htobe64(pConnReq->startTime);
|
||||
|
@ -190,54 +195,61 @@ static int32_t mndProcessConnectReq(SMnodeMsg *pReq) {
|
|||
SRpcConnInfo info = {0};
|
||||
if (rpcGetConnInfo(pReq->rpcMsg.handle, &info) != 0) {
|
||||
mError("user:%s, failed to login while get connection info since %s", pReq->user, terrstr());
|
||||
return -1;
|
||||
goto CONN_OVER;
|
||||
}
|
||||
|
||||
char ip[30];
|
||||
taosIp2String(info.clientIp, ip);
|
||||
|
||||
pUser = mndAcquireUser(pMnode, pReq->user);
|
||||
if (pUser == NULL) {
|
||||
mError("user:%s, failed to login while acquire user since %s", pReq->user, terrstr());
|
||||
goto CONN_OVER;
|
||||
}
|
||||
|
||||
if (pConnReq->db[0]) {
|
||||
snprintf(pReq->db, TSDB_DB_FNAME_LEN, "%d%s%s", pReq->acctId, TS_PATH_DELIMITER, pConnReq->db);
|
||||
SDbObj *pDb = mndAcquireDb(pMnode, pReq->db);
|
||||
snprintf(pReq->db, TSDB_DB_FNAME_LEN, "%d%s%s", pUser->acctId, TS_PATH_DELIMITER, pConnReq->db);
|
||||
pDb = mndAcquireDb(pMnode, pReq->db);
|
||||
if (pDb == NULL) {
|
||||
terrno = TSDB_CODE_MND_INVALID_DB;
|
||||
mError("user:%s, failed to login from %s while use db:%s since %s", pReq->user, ip, pConnReq->db, terrstr());
|
||||
return -1;
|
||||
goto CONN_OVER;
|
||||
}
|
||||
mndReleaseDb(pMnode, pDb);
|
||||
}
|
||||
|
||||
SConnObj *pConn = mndCreateConn(pMnode, &info, pConnReq->pid, pConnReq->app, pConnReq->startTime);
|
||||
pConn = mndCreateConn(pMnode, &info, pConnReq->pid, pConnReq->app, pConnReq->startTime);
|
||||
if (pConn == NULL) {
|
||||
mError("user:%s, failed to login from %s while create connection since %s", pReq->user, ip, terrstr());
|
||||
return -1;
|
||||
goto CONN_OVER;
|
||||
}
|
||||
|
||||
SConnectRsp *pRsp = rpcMallocCont(sizeof(SConnectRsp));
|
||||
if (pRsp == NULL) {
|
||||
mndReleaseConn(pMnode, pConn);
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
mError("user:%s, failed to login from %s while create rsp since %s", pReq->user, ip, terrstr());
|
||||
return -1;
|
||||
}
|
||||
|
||||
SUserObj *pUser = mndAcquireUser(pMnode, pReq->user);
|
||||
if (pUser != NULL) {
|
||||
pRsp->acctId = htonl(pUser->acctId);
|
||||
pRsp->superUser = pUser->superUser;
|
||||
mndReleaseUser(pMnode, pUser);
|
||||
goto CONN_OVER;
|
||||
}
|
||||
|
||||
pRsp->acctId = htonl(pUser->acctId);
|
||||
pRsp->superUser = pUser->superUser;
|
||||
pRsp->clusterId = htobe64(pMnode->clusterId);
|
||||
pRsp->connId = htonl(pConn->id);
|
||||
mndGetMnodeEpSet(pMnode, &pRsp->epSet);
|
||||
mndReleaseConn(pMnode, pConn);
|
||||
|
||||
pReq->contLen = sizeof(SConnectRsp);
|
||||
pReq->pCont = pRsp;
|
||||
|
||||
mDebug("user:%s, login from %s, conn:%d, app:%s", info.user, ip, pConn->id, pConnReq->app);
|
||||
return 0;
|
||||
|
||||
code = 0;
|
||||
|
||||
CONN_OVER:
|
||||
|
||||
mndReleaseUser(pMnode, pUser);
|
||||
mndReleaseDb(pMnode, pDb);
|
||||
mndReleaseConn(pMnode, pConn);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t mndSaveQueryStreamList(SConnObj *pConn, SHeartBeatReq *pReq) {
|
||||
|
|
|
@ -31,16 +31,16 @@ static SSdbRaw *mndStbActionEncode(SStbObj *pStb);
|
|||
static SSdbRow *mndStbActionDecode(SSdbRaw *pRaw);
|
||||
static int32_t mndStbActionInsert(SSdb *pSdb, SStbObj *pStb);
|
||||
static int32_t mndStbActionDelete(SSdb *pSdb, SStbObj *pStb);
|
||||
static int32_t mndStbActionUpdate(SSdb *pSdb, SStbObj *pOldStb, SStbObj *pNewStb);
|
||||
static int32_t mndProcesSMCreateStbReq(SMnodeMsg *pMsg);
|
||||
static int32_t mndProcesSMAlterStbReq(SMnodeMsg *pMsg);
|
||||
static int32_t mndProcesSMDropStbReq(SMnodeMsg *pMsg);
|
||||
static int32_t mndProcessCreateStbInRsp(SMnodeMsg *pMsg);
|
||||
static int32_t mndProcessAlterStbInRsp(SMnodeMsg *pMsg);
|
||||
static int32_t mndProcessDropStbInRsp(SMnodeMsg *pMsg);
|
||||
static int32_t mndProcessStbMetaMsg(SMnodeMsg *pMsg);
|
||||
static int32_t mndGetStbMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaRsp *pMeta);
|
||||
static int32_t mndRetrieveStb(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows);
|
||||
static int32_t mndStbActionUpdate(SSdb *pSdb, SStbObj *pOld, SStbObj *pNew);
|
||||
static int32_t mndProcessMCreateStbReq(SMnodeMsg *pReq);
|
||||
static int32_t mndProcessMAlterStbReq(SMnodeMsg *pReq);
|
||||
static int32_t mndProcessMDropStbReq(SMnodeMsg *pReq);
|
||||
static int32_t mndProcessVCreateStbRsp(SMnodeMsg *pRsp);
|
||||
static int32_t mndProcessVAlterStbRsp(SMnodeMsg *pRsp);
|
||||
static int32_t mndProcessVDropStbRsp(SMnodeMsg *pRsp);
|
||||
static int32_t mndProcessStbMetaReq(SMnodeMsg *pReq);
|
||||
static int32_t mndGetStbMeta(SMnodeMsg *pReq, SShowObj *pShow, STableMetaRsp *pMeta);
|
||||
static int32_t mndRetrieveStb(SMnodeMsg *pReq, SShowObj *pShow, char *data, int32_t rows);
|
||||
static void mndCancelGetNextStb(SMnode *pMnode, void *pIter);
|
||||
|
||||
int32_t mndInitStb(SMnode *pMnode) {
|
||||
|
@ -52,13 +52,13 @@ int32_t mndInitStb(SMnode *pMnode) {
|
|||
.updateFp = (SdbUpdateFp)mndStbActionUpdate,
|
||||
.deleteFp = (SdbDeleteFp)mndStbActionDelete};
|
||||
|
||||
mndSetMsgHandle(pMnode, TDMT_MND_CREATE_STB, mndProcesSMCreateStbReq);
|
||||
mndSetMsgHandle(pMnode, TDMT_MND_ALTER_STB, mndProcesSMAlterStbReq);
|
||||
mndSetMsgHandle(pMnode, TDMT_MND_DROP_STB, mndProcesSMDropStbReq);
|
||||
mndSetMsgHandle(pMnode, TDMT_VND_CREATE_STB_RSP, mndProcessCreateStbInRsp);
|
||||
mndSetMsgHandle(pMnode, TDMT_VND_ALTER_STB_RSP, mndProcessAlterStbInRsp);
|
||||
mndSetMsgHandle(pMnode, TDMT_VND_DROP_STB_RSP, mndProcessDropStbInRsp);
|
||||
mndSetMsgHandle(pMnode, TDMT_MND_STB_META, mndProcessStbMetaMsg);
|
||||
mndSetMsgHandle(pMnode, TDMT_MND_CREATE_STB, mndProcessMCreateStbReq);
|
||||
mndSetMsgHandle(pMnode, TDMT_MND_ALTER_STB, mndProcessMAlterStbReq);
|
||||
mndSetMsgHandle(pMnode, TDMT_MND_DROP_STB, mndProcessMDropStbReq);
|
||||
mndSetMsgHandle(pMnode, TDMT_VND_CREATE_STB_RSP, mndProcessVCreateStbRsp);
|
||||
mndSetMsgHandle(pMnode, TDMT_VND_ALTER_STB_RSP, mndProcessVAlterStbRsp);
|
||||
mndSetMsgHandle(pMnode, TDMT_VND_DROP_STB_RSP, mndProcessVDropStbRsp);
|
||||
mndSetMsgHandle(pMnode, TDMT_MND_STB_META, mndProcessStbMetaReq);
|
||||
|
||||
mndAddShowMetaHandle(pMnode, TSDB_MGMT_TABLE_STB, mndGetStbMeta);
|
||||
mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_STB, mndRetrieveStb);
|
||||
|
@ -177,27 +177,27 @@ static int32_t mndStbActionDelete(SSdb *pSdb, SStbObj *pStb) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mndStbActionUpdate(SSdb *pSdb, SStbObj *pOldStb, SStbObj *pNewStb) {
|
||||
mTrace("stb:%s, perform update action, old row:%p new row:%p", pOldStb->name, pOldStb, pNewStb);
|
||||
atomic_exchange_32(&pOldStb->updateTime, pNewStb->updateTime);
|
||||
atomic_exchange_32(&pOldStb->version, pNewStb->version);
|
||||
static int32_t mndStbActionUpdate(SSdb *pSdb, SStbObj *pOld, SStbObj *pNew) {
|
||||
mTrace("stb:%s, perform update action, old row:%p new row:%p", pOld->name, pOld, pNew);
|
||||
atomic_exchange_32(&pOld->updateTime, pNew->updateTime);
|
||||
atomic_exchange_32(&pOld->version, pNew->version);
|
||||
|
||||
taosWLockLatch(&pOldStb->lock);
|
||||
pOldStb->numOfColumns = pNewStb->numOfColumns;
|
||||
pOldStb->numOfTags = pNewStb->numOfTags;
|
||||
int32_t totalCols = pNewStb->numOfTags + pNewStb->numOfColumns;
|
||||
taosWLockLatch(&pOld->lock);
|
||||
pOld->numOfColumns = pNew->numOfColumns;
|
||||
pOld->numOfTags = pNew->numOfTags;
|
||||
int32_t totalCols = pNew->numOfTags + pNew->numOfColumns;
|
||||
int32_t totalSize = totalCols * sizeof(SSchema);
|
||||
|
||||
if (pOldStb->numOfTags + pOldStb->numOfColumns < totalCols) {
|
||||
if (pOld->numOfTags + pOld->numOfColumns < totalCols) {
|
||||
void *pSchema = malloc(totalSize);
|
||||
if (pSchema != NULL) {
|
||||
free(pOldStb->pSchema);
|
||||
pOldStb->pSchema = pSchema;
|
||||
free(pOld->pSchema);
|
||||
pOld->pSchema = pSchema;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(pOldStb->pSchema, pNewStb->pSchema, totalSize);
|
||||
taosWUnLockLatch(&pOldStb->lock);
|
||||
memcpy(pOld->pSchema, pNew->pSchema, totalSize);
|
||||
taosWUnLockLatch(&pOld->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -215,7 +215,7 @@ void mndReleaseStb(SMnode *pMnode, SStbObj *pStb) {
|
|||
sdbRelease(pSdb, pStb);
|
||||
}
|
||||
|
||||
static SDbObj *mndAcquireDbByStb(SMnode *pMnode, char *stbName) {
|
||||
static SDbObj *mndAcquireDbByStb(SMnode *pMnode, const char *stbName) {
|
||||
SName name = {0};
|
||||
tNameFromString(&name, stbName, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE);
|
||||
|
||||
|
@ -225,17 +225,17 @@ static SDbObj *mndAcquireDbByStb(SMnode *pMnode, char *stbName) {
|
|||
return mndAcquireDb(pMnode, db);
|
||||
}
|
||||
|
||||
static void *mndBuildCreateStbMsg(SMnode *pMnode, SVgObj *pVgroup, SStbObj *pStb, int *pContLen) {
|
||||
static void *mndBuildCreateStbReq(SMnode *pMnode, SVgObj *pVgroup, SStbObj *pStb, int32_t *pContLen) {
|
||||
SVCreateTbReq req;
|
||||
void *buf;
|
||||
int bsize;
|
||||
int32_t bsize;
|
||||
SMsgHead *pMsgHead;
|
||||
|
||||
req.ver = 0;
|
||||
SName name = {0};
|
||||
tNameFromString(&name, pStb->name, T_NAME_ACCT|T_NAME_DB|T_NAME_TABLE);
|
||||
tNameFromString(&name, pStb->name, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE);
|
||||
|
||||
req.name = (char*) tNameGetTableName(&name);
|
||||
req.name = (char *)tNameGetTableName(&name);
|
||||
req.ttl = 0;
|
||||
req.keep = 0;
|
||||
req.type = TD_SUPER_TABLE;
|
||||
|
@ -264,7 +264,7 @@ static void *mndBuildCreateStbMsg(SMnode *pMnode, SVgObj *pVgroup, SStbObj *pStb
|
|||
return buf;
|
||||
}
|
||||
|
||||
static SVDropTbReq *mndBuildDropStbMsg(SMnode *pMnode, SVgObj *pVgroup, SStbObj *pStb) {
|
||||
static SVDropTbReq *mndBuildDropStbReq(SMnode *pMnode, SVgObj *pVgroup, SStbObj *pStb) {
|
||||
int32_t contLen = sizeof(SVDropTbReq);
|
||||
|
||||
SVDropTbReq *pDrop = calloc(1, contLen);
|
||||
|
@ -276,12 +276,12 @@ static SVDropTbReq *mndBuildDropStbMsg(SMnode *pMnode, SVgObj *pVgroup, SStbObj
|
|||
pDrop->head.contLen = htonl(contLen);
|
||||
pDrop->head.vgId = htonl(pVgroup->vgId);
|
||||
memcpy(pDrop->name, pStb->name, TSDB_TABLE_FNAME_LEN);
|
||||
// pDrop->suid = htobe64(pStb->uid);
|
||||
pDrop->suid = htobe64(pStb->uid);
|
||||
|
||||
return pDrop;
|
||||
}
|
||||
|
||||
static int32_t mndCheckCreateStbMsg(SMCreateStbReq *pCreate) {
|
||||
static int32_t mndCheckCreateStbReq(SMCreateStbReq *pCreate) {
|
||||
pCreate->numOfColumns = htonl(pCreate->numOfColumns);
|
||||
pCreate->numOfTags = htonl(pCreate->numOfTags);
|
||||
int32_t totalCols = pCreate->numOfColumns + pCreate->numOfTags;
|
||||
|
@ -356,15 +356,15 @@ static int32_t mndSetCreateStbRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj
|
|||
SSdb *pSdb = pMnode->pSdb;
|
||||
SVgObj *pVgroup = NULL;
|
||||
void *pIter = NULL;
|
||||
int contLen;
|
||||
int32_t contLen;
|
||||
|
||||
while (1) {
|
||||
pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
|
||||
if (pIter == NULL) break;
|
||||
if (pVgroup->dbUid != pDb->uid) continue;
|
||||
|
||||
void *pMsg = mndBuildCreateStbMsg(pMnode, pVgroup, pStb, &contLen);
|
||||
if (pMsg == NULL) {
|
||||
void *pReq = mndBuildCreateStbReq(pMnode, pVgroup, pStb, &contLen);
|
||||
if (pReq == NULL) {
|
||||
sdbCancelFetch(pSdb, pIter);
|
||||
sdbRelease(pSdb, pVgroup);
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
|
@ -373,11 +373,11 @@ static int32_t mndSetCreateStbRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj
|
|||
|
||||
STransAction action = {0};
|
||||
action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
|
||||
action.pCont = pMsg;
|
||||
action.pCont = pReq;
|
||||
action.contLen = contLen;
|
||||
action.msgType = TDMT_VND_CREATE_STB;
|
||||
if (mndTransAppendRedoAction(pTrans, &action) != 0) {
|
||||
free(pMsg);
|
||||
free(pReq);
|
||||
sdbCancelFetch(pSdb, pIter);
|
||||
sdbRelease(pSdb, pVgroup);
|
||||
return -1;
|
||||
|
@ -398,8 +398,8 @@ static int32_t mndSetCreateStbUndoActions(SMnode *pMnode, STrans *pTrans, SDbObj
|
|||
if (pIter == NULL) break;
|
||||
if (pVgroup->dbUid != pDb->uid) continue;
|
||||
|
||||
SVDropTbReq *pMsg = mndBuildDropStbMsg(pMnode, pVgroup, pStb);
|
||||
if (pMsg == NULL) {
|
||||
SVDropTbReq *pReq = mndBuildDropStbReq(pMnode, pVgroup, pStb);
|
||||
if (pReq == NULL) {
|
||||
sdbCancelFetch(pSdb, pIter);
|
||||
sdbRelease(pSdb, pVgroup);
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
|
@ -408,11 +408,11 @@ static int32_t mndSetCreateStbUndoActions(SMnode *pMnode, STrans *pTrans, SDbObj
|
|||
|
||||
STransAction action = {0};
|
||||
action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
|
||||
action.pCont = pMsg;
|
||||
action.pCont = pReq;
|
||||
action.contLen = sizeof(SVDropTbReq);
|
||||
action.msgType = TDMT_VND_DROP_STB;
|
||||
if (mndTransAppendUndoAction(pTrans, &action) != 0) {
|
||||
free(pMsg);
|
||||
free(pReq);
|
||||
sdbCancelFetch(pSdb, pIter);
|
||||
sdbRelease(pSdb, pVgroup);
|
||||
return -1;
|
||||
|
@ -423,7 +423,7 @@ static int32_t mndSetCreateStbUndoActions(SMnode *pMnode, STrans *pTrans, SDbObj
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mndCreateStb(SMnode *pMnode, SMnodeMsg *pMsg, SMCreateStbReq *pCreate, SDbObj *pDb) {
|
||||
static int32_t mndCreateStb(SMnode *pMnode, SMnodeMsg *pReq, SMCreateStbReq *pCreate, SDbObj *pDb) {
|
||||
SStbObj stbObj = {0};
|
||||
tstrncpy(stbObj.name, pCreate->name, TSDB_TABLE_FNAME_LEN);
|
||||
tstrncpy(stbObj.db, pDb->name, TSDB_DB_FNAME_LEN);
|
||||
|
@ -449,43 +449,17 @@ static int32_t mndCreateStb(SMnode *pMnode, SMnodeMsg *pMsg, SMCreateStbReq *pCr
|
|||
}
|
||||
|
||||
int32_t code = 0;
|
||||
STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, &pMsg->rpcMsg);
|
||||
if (pTrans == NULL) {
|
||||
mError("stb:%s, failed to create since %s", pCreate->name, terrstr());
|
||||
return -1;
|
||||
}
|
||||
STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, &pReq->rpcMsg);
|
||||
if (pTrans == NULL) goto CREATE_STB_OVER;
|
||||
|
||||
mDebug("trans:%d, used to create stb:%s", pTrans->id, pCreate->name);
|
||||
|
||||
if (mndSetCreateStbRedoLogs(pMnode, pTrans, pDb, &stbObj) != 0) {
|
||||
mError("trans:%d, failed to set redo log since %s", pTrans->id, terrstr());
|
||||
goto CREATE_STB_OVER;
|
||||
}
|
||||
|
||||
if (mndSetCreateStbUndoLogs(pMnode, pTrans, pDb, &stbObj) != 0) {
|
||||
mError("trans:%d, failed to set undo log since %s", pTrans->id, terrstr());
|
||||
goto CREATE_STB_OVER;
|
||||
}
|
||||
|
||||
if (mndSetCreateStbCommitLogs(pMnode, pTrans, pDb, &stbObj) != 0) {
|
||||
mError("trans:%d, failed to set commit log since %s", pTrans->id, terrstr());
|
||||
goto CREATE_STB_OVER;
|
||||
}
|
||||
|
||||
if (mndSetCreateStbRedoActions(pMnode, pTrans, pDb, &stbObj) != 0) {
|
||||
mError("trans:%d, failed to set redo actions since %s", pTrans->id, terrstr());
|
||||
goto CREATE_STB_OVER;
|
||||
}
|
||||
|
||||
if (mndSetCreateStbUndoActions(pMnode, pTrans, pDb, &stbObj) != 0) {
|
||||
mError("trans:%d, failed to set redo actions since %s", pTrans->id, terrstr());
|
||||
goto CREATE_STB_OVER;
|
||||
}
|
||||
|
||||
if (mndTransPrepare(pMnode, pTrans) != 0) {
|
||||
mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
|
||||
mndTransDrop(pTrans);
|
||||
return -1;
|
||||
}
|
||||
if (mndSetCreateStbRedoLogs(pMnode, pTrans, pDb, &stbObj) != 0) goto CREATE_STB_OVER;
|
||||
if (mndSetCreateStbUndoLogs(pMnode, pTrans, pDb, &stbObj) != 0) goto CREATE_STB_OVER;
|
||||
if (mndSetCreateStbCommitLogs(pMnode, pTrans, pDb, &stbObj) != 0) goto CREATE_STB_OVER;
|
||||
if (mndSetCreateStbRedoActions(pMnode, pTrans, pDb, &stbObj) != 0) goto CREATE_STB_OVER;
|
||||
if (mndSetCreateStbUndoActions(pMnode, pTrans, pDb, &stbObj) != 0) goto CREATE_STB_OVER;
|
||||
if (mndTransPrepare(pMnode, pTrans) != 0) goto CREATE_STB_OVER;
|
||||
|
||||
code = 0;
|
||||
|
||||
|
@ -494,13 +468,13 @@ CREATE_STB_OVER:
|
|||
return code;
|
||||
}
|
||||
|
||||
static int32_t mndProcesSMCreateStbReq(SMnodeMsg *pMsg) {
|
||||
SMnode *pMnode = pMsg->pMnode;
|
||||
SMCreateStbReq *pCreate = pMsg->rpcMsg.pCont;
|
||||
static int32_t mndProcessMCreateStbReq(SMnodeMsg *pReq) {
|
||||
SMnode *pMnode = pReq->pMnode;
|
||||
SMCreateStbReq *pCreate = pReq->rpcMsg.pCont;
|
||||
|
||||
mDebug("stb:%s, start to create", pCreate->name);
|
||||
|
||||
if (mndCheckCreateStbMsg(pCreate) != 0) {
|
||||
if (mndCheckCreateStbReq(pCreate) != 0) {
|
||||
mError("stb:%s, failed to create since %s", pCreate->name, terrstr());
|
||||
return -1;
|
||||
}
|
||||
|
@ -536,7 +510,7 @@ static int32_t mndProcesSMCreateStbReq(SMnodeMsg *pMsg) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
int32_t code = mndCreateStb(pMnode, pMsg, pCreate, pDb);
|
||||
int32_t code = mndCreateStb(pMnode, pReq, pCreate, pDb);
|
||||
mndReleaseDb(pMnode, pDb);
|
||||
|
||||
if (code != 0) {
|
||||
|
@ -548,12 +522,12 @@ static int32_t mndProcesSMCreateStbReq(SMnodeMsg *pMsg) {
|
|||
return TSDB_CODE_MND_ACTION_IN_PROGRESS;
|
||||
}
|
||||
|
||||
static int32_t mndProcessCreateStbInRsp(SMnodeMsg *pMsg) {
|
||||
mndTransProcessRsp(pMsg);
|
||||
static int32_t mndProcessVCreateStbRsp(SMnodeMsg *pRsp) {
|
||||
mndTransProcessRsp(pRsp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mndCheckAlterStbMsg(SMAlterStbReq *pAlter) {
|
||||
static int32_t mndCheckAlterStbReq(SMAlterStbReq *pAlter) {
|
||||
SSchema *pSchema = &pAlter->schema;
|
||||
pSchema->colId = htonl(pSchema->colId);
|
||||
pSchema->bytes = htonl(pSchema->bytes);
|
||||
|
@ -578,15 +552,15 @@ static int32_t mndCheckAlterStbMsg(SMAlterStbReq *pAlter) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mndUpdateStb(SMnode *pMnode, SMnodeMsg *pMsg, SStbObj *pOldStb, SStbObj *pNewStb) { return 0; }
|
||||
static int32_t mndUpdateStb(SMnode *pMnode, SMnodeMsg *pReq, SStbObj *pOld, SStbObj *pNew) { return 0; }
|
||||
|
||||
static int32_t mndProcesSMAlterStbReq(SMnodeMsg *pMsg) {
|
||||
SMnode *pMnode = pMsg->pMnode;
|
||||
SMAlterStbReq *pAlter = pMsg->rpcMsg.pCont;
|
||||
static int32_t mndProcessMAlterStbReq(SMnodeMsg *pReq) {
|
||||
SMnode *pMnode = pReq->pMnode;
|
||||
SMAlterStbReq *pAlter = pReq->rpcMsg.pCont;
|
||||
|
||||
mDebug("stb:%s, start to alter", pAlter->name);
|
||||
|
||||
if (mndCheckAlterStbMsg(pAlter) != 0) {
|
||||
if (mndCheckAlterStbReq(pAlter) != 0) {
|
||||
mError("stb:%s, failed to alter since %s", pAlter->name, terrstr());
|
||||
return -1;
|
||||
}
|
||||
|
@ -601,7 +575,7 @@ static int32_t mndProcesSMAlterStbReq(SMnodeMsg *pMsg) {
|
|||
SStbObj stbObj = {0};
|
||||
memcpy(&stbObj, pStb, sizeof(SStbObj));
|
||||
|
||||
int32_t code = mndUpdateStb(pMnode, pMsg, pStb, &stbObj);
|
||||
int32_t code = mndUpdateStb(pMnode, pReq, pStb, &stbObj);
|
||||
mndReleaseStb(pMnode, pStb);
|
||||
|
||||
if (code != 0) {
|
||||
|
@ -612,8 +586,8 @@ static int32_t mndProcesSMAlterStbReq(SMnodeMsg *pMsg) {
|
|||
return TSDB_CODE_MND_ACTION_IN_PROGRESS;
|
||||
}
|
||||
|
||||
static int32_t mndProcessAlterStbInRsp(SMnodeMsg *pMsg) {
|
||||
mndTransProcessRsp(pMsg);
|
||||
static int32_t mndProcessVAlterStbRsp(SMnodeMsg *pRsp) {
|
||||
mndTransProcessRsp(pRsp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -648,44 +622,19 @@ static int32_t mndSetDropStbRedoActions(SMnode *pMnode, STrans *pTrans, SStbObj
|
|||
|
||||
static int32_t mndSetDropStbUndoActions(SMnode *pMnode, STrans *pTrans, SStbObj *pStb) { return 0; }
|
||||
|
||||
static int32_t mndDropStb(SMnode *pMnode, SMnodeMsg *pMsg, SStbObj *pStb) {
|
||||
static int32_t mndDropStb(SMnode *pMnode, SMnodeMsg *pReq, SStbObj *pStb) {
|
||||
int32_t code = -1;
|
||||
STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, &pMsg->rpcMsg);
|
||||
if (pTrans == NULL) {
|
||||
mError("stb:%s, failed to drop since %s", pStb->name, terrstr());
|
||||
return -1;
|
||||
}
|
||||
STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, &pReq->rpcMsg);
|
||||
if (pTrans == NULL)goto DROP_STB_OVER;
|
||||
|
||||
mDebug("trans:%d, used to drop stb:%s", pTrans->id, pStb->name);
|
||||
|
||||
if (mndSetDropStbRedoLogs(pMnode, pTrans, pStb) != 0) {
|
||||
mError("trans:%d, failed to set redo log since %s", pTrans->id, terrstr());
|
||||
goto DROP_STB_OVER;
|
||||
}
|
||||
|
||||
if (mndSetDropStbUndoLogs(pMnode, pTrans, pStb) != 0) {
|
||||
mError("trans:%d, failed to set undo log since %s", pTrans->id, terrstr());
|
||||
goto DROP_STB_OVER;
|
||||
}
|
||||
|
||||
if (mndSetDropStbCommitLogs(pMnode, pTrans, pStb) != 0) {
|
||||
mError("trans:%d, failed to set commit log since %s", pTrans->id, terrstr());
|
||||
goto DROP_STB_OVER;
|
||||
}
|
||||
|
||||
if (mndSetDropStbRedoActions(pMnode, pTrans, pStb) != 0) {
|
||||
mError("trans:%d, failed to set redo actions since %s", pTrans->id, terrstr());
|
||||
goto DROP_STB_OVER;
|
||||
}
|
||||
|
||||
if (mndSetDropStbUndoActions(pMnode, pTrans, pStb) != 0) {
|
||||
mError("trans:%d, failed to set redo actions since %s", pTrans->id, terrstr());
|
||||
goto DROP_STB_OVER;
|
||||
}
|
||||
|
||||
if (mndTransPrepare(pMnode, pTrans) != 0) {
|
||||
mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
|
||||
goto DROP_STB_OVER;
|
||||
}
|
||||
if (mndSetDropStbRedoLogs(pMnode, pTrans, pStb) != 0) goto DROP_STB_OVER;
|
||||
if (mndSetDropStbUndoLogs(pMnode, pTrans, pStb) != 0) goto DROP_STB_OVER;
|
||||
if (mndSetDropStbCommitLogs(pMnode, pTrans, pStb) != 0) goto DROP_STB_OVER;
|
||||
if (mndSetDropStbRedoActions(pMnode, pTrans, pStb) != 0) goto DROP_STB_OVER;
|
||||
if (mndSetDropStbUndoActions(pMnode, pTrans, pStb) != 0) goto DROP_STB_OVER;
|
||||
if (mndTransPrepare(pMnode, pTrans) != 0) goto DROP_STB_OVER;
|
||||
|
||||
code = 0;
|
||||
|
||||
|
@ -694,9 +643,9 @@ DROP_STB_OVER:
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mndProcesSMDropStbReq(SMnodeMsg *pMsg) {
|
||||
SMnode *pMnode = pMsg->pMnode;
|
||||
SMDropStbReq *pDrop = pMsg->rpcMsg.pCont;
|
||||
static int32_t mndProcessMDropStbReq(SMnodeMsg *pReq) {
|
||||
SMnode *pMnode = pReq->pMnode;
|
||||
SMDropStbReq *pDrop = pReq->rpcMsg.pCont;
|
||||
|
||||
mDebug("stb:%s, start to drop", pDrop->name);
|
||||
|
||||
|
@ -712,7 +661,7 @@ static int32_t mndProcesSMDropStbReq(SMnodeMsg *pMsg) {
|
|||
}
|
||||
}
|
||||
|
||||
int32_t code = mndDropStb(pMnode, pMsg, pStb);
|
||||
int32_t code = mndDropStb(pMnode, pReq, pStb);
|
||||
mndReleaseStb(pMnode, pStb);
|
||||
|
||||
if (code != 0) {
|
||||
|
@ -724,14 +673,14 @@ static int32_t mndProcesSMDropStbReq(SMnodeMsg *pMsg) {
|
|||
return TSDB_CODE_MND_ACTION_IN_PROGRESS;
|
||||
}
|
||||
|
||||
static int32_t mndProcessDropStbInRsp(SMnodeMsg *pMsg) {
|
||||
mndTransProcessRsp(pMsg);
|
||||
static int32_t mndProcessVDropStbRsp(SMnodeMsg *pRsp) {
|
||||
mndTransProcessRsp(pRsp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mndProcessStbMetaMsg(SMnodeMsg *pMsg) {
|
||||
SMnode *pMnode = pMsg->pMnode;
|
||||
STableInfoReq *pInfo = pMsg->rpcMsg.pCont;
|
||||
static int32_t mndProcessStbMetaReq(SMnodeMsg *pReq) {
|
||||
SMnode *pMnode = pReq->pMnode;
|
||||
STableInfoReq *pInfo = pReq->rpcMsg.pCont;
|
||||
|
||||
mDebug("stb:%s, start to retrieve meta", pInfo->tableFname);
|
||||
|
||||
|
@ -786,8 +735,8 @@ static int32_t mndProcessStbMetaMsg(SMnodeMsg *pMsg) {
|
|||
mndReleaseDb(pMnode, pDb);
|
||||
mndReleaseStb(pMnode, pStb);
|
||||
|
||||
pMsg->pCont = pMeta;
|
||||
pMsg->contLen = contLen;
|
||||
pReq->pCont = pMeta;
|
||||
pReq->contLen = contLen;
|
||||
|
||||
mDebug("stb:%s, meta is retrieved, cols:%d tags:%d", pInfo->tableFname, pStb->numOfColumns, pStb->numOfTags);
|
||||
return 0;
|
||||
|
@ -820,8 +769,8 @@ static int32_t mndGetNumOfStbs(SMnode *pMnode, char *dbName, int32_t *pNumOfStbs
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mndGetStbMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaRsp *pMeta) {
|
||||
SMnode *pMnode = pMsg->pMnode;
|
||||
static int32_t mndGetStbMeta(SMnodeMsg *pReq, SShowObj *pShow, STableMetaRsp *pMeta) {
|
||||
SMnode *pMnode = pReq->pMnode;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
|
||||
if (mndGetNumOfStbs(pMnode, pShow->db, &pShow->numOfRows) != 0) {
|
||||
|
@ -883,8 +832,8 @@ static void mndExtractTableName(char *tableId, char *name) {
|
|||
}
|
||||
}
|
||||
|
||||
static int32_t mndRetrieveStb(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows) {
|
||||
SMnode *pMnode = pMsg->pMnode;
|
||||
static int32_t mndRetrieveStb(SMnodeMsg *pReq, SShowObj *pShow, char *data, int32_t rows) {
|
||||
SMnode *pMnode = pReq->pMnode;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
int32_t numOfRows = 0;
|
||||
SStbObj *pStb = NULL;
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
aux_source_directory(. STB_SRC)
|
||||
add_executable(dnode_test_stb ${STB_SRC})
|
||||
add_executable(mnode_test_stb ${STB_SRC})
|
||||
target_link_libraries(
|
||||
dnode_test_stb
|
||||
mnode_test_stb
|
||||
PUBLIC sut
|
||||
)
|
||||
|
||||
add_test(
|
||||
NAME dnode_test_stb
|
||||
COMMAND dnode_test_stb
|
||||
NAME mnode_test_stb
|
||||
COMMAND mnode_test_stb
|
||||
)
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* 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_META_CACHE_H_
|
||||
#define _TD_META_CACHE_H_
|
||||
|
||||
#include "meta.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct SMetaCache SMetaCache;
|
||||
|
||||
int metaOpenCache(SMeta *pMeta);
|
||||
void metaCloseCache(SMeta *pMeta);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_TD_META_CACHE_H_*/
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* 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_META_CFG_H_
|
||||
#define _TD_META_CFG_H_
|
||||
|
||||
#include "meta.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const SMetaCfg defaultMetaOptions;
|
||||
|
||||
int metaValidateOptions(const SMetaCfg *);
|
||||
void metaOptionsCopy(SMetaCfg *pDest, const SMetaCfg *pSrc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_TD_META_CFG_H_*/
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* 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_META_DB_H_
|
||||
#define _TD_META_DB_H_
|
||||
|
||||
#include "meta.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct SMetaDB SMetaDB;
|
||||
|
||||
int metaOpenDB(SMeta *pMeta);
|
||||
void metaCloseDB(SMeta *pMeta);
|
||||
int metaSaveTableToDB(SMeta *pMeta, STbCfg *pTbCfg);
|
||||
int metaRemoveTableFromDb(SMeta *pMeta, tb_uid_t uid);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_TD_META_DB_H_*/
|
|
@ -19,18 +19,49 @@
|
|||
#include "mallocator.h"
|
||||
|
||||
#include "meta.h"
|
||||
#include "metaCache.h"
|
||||
#include "metaCfg.h"
|
||||
#include "metaDB.h"
|
||||
#include "metaIdx.h"
|
||||
#include "metaTbCfg.h"
|
||||
#include "metaTbTag.h"
|
||||
#include "metaTbUid.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct SMetaCache SMetaCache;
|
||||
typedef struct SMetaIdx SMetaIdx;
|
||||
typedef struct SMetaDB SMetaDB;
|
||||
|
||||
// SMetaDB
|
||||
int metaOpenDB(SMeta* pMeta);
|
||||
void metaCloseDB(SMeta* pMeta);
|
||||
int metaSaveTableToDB(SMeta* pMeta, STbCfg* pTbCfg);
|
||||
int metaRemoveTableFromDb(SMeta* pMeta, tb_uid_t uid);
|
||||
|
||||
// SMetaCache
|
||||
int metaOpenCache(SMeta* pMeta);
|
||||
void metaCloseCache(SMeta* pMeta);
|
||||
|
||||
// SMetaCfg
|
||||
extern const SMetaCfg defaultMetaOptions;
|
||||
// int metaValidateOptions(const SMetaCfg*);
|
||||
void metaOptionsCopy(SMetaCfg* pDest, const SMetaCfg* pSrc);
|
||||
|
||||
// SMetaIdx
|
||||
int metaOpenIdx(SMeta* pMeta);
|
||||
void metaCloseIdx(SMeta* pMeta);
|
||||
int metaSaveTableToIdx(SMeta* pMeta, const STbCfg* pTbOptions);
|
||||
int metaRemoveTableFromIdx(SMeta* pMeta, tb_uid_t uid);
|
||||
|
||||
// STbUidGnrt
|
||||
typedef struct STbUidGenerator {
|
||||
tb_uid_t nextUid;
|
||||
} STbUidGenerator;
|
||||
|
||||
// STableUidGenerator
|
||||
int metaOpenUidGnrt(SMeta* pMeta);
|
||||
void metaCloseUidGnrt(SMeta* pMeta);
|
||||
|
||||
// tb_uid_t
|
||||
#define IVLD_TB_UID 0
|
||||
tb_uid_t metaGenerateUid(SMeta* pMeta);
|
||||
|
||||
struct SMeta {
|
||||
char* path;
|
||||
SMetaCfg options;
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* 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_META_IDX_H_
|
||||
#define _TD_META_IDX_H_
|
||||
|
||||
#include "meta.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct SMetaIdx SMetaIdx;
|
||||
|
||||
int metaOpenIdx(SMeta *pMeta);
|
||||
void metaCloseIdx(SMeta *pMeta);
|
||||
int metaSaveTableToIdx(SMeta *pMeta, const STbCfg *pTbOptions);
|
||||
int metaRemoveTableFromIdx(SMeta *pMeta, tb_uid_t uid);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_TD_META_IDX_H_*/
|
|
@ -1,27 +0,0 @@
|
|||
/*
|
||||
* 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 _VNODE_QUERY_H_
|
||||
#define _VNODE_QUERY_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_VNODE_QUERY_H_*/
|
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
* 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_META_TABLE_CFG_H_
|
||||
#define _TD_META_TABLE_CFG_H_
|
||||
|
||||
#include "meta.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int metaValidateTbCfg(SMeta *pMeta, const STbCfg *);
|
||||
size_t metaEncodeTbObjFromTbOptions(const STbCfg *, void *pBuf, size_t bsize);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_TD_META_TABLE_CFG_H_*/
|
|
@ -1,27 +0,0 @@
|
|||
/*
|
||||
* 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_META_TB_TAG_H_
|
||||
#define _TD_META_TB_TAG_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_TD_META_TB_TAG_H_*/
|
|
@ -1,42 +0,0 @@
|
|||
/*
|
||||
* 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_META_UID_H_
|
||||
#define _TD_META_UID_H_
|
||||
|
||||
#include "meta.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ------------------------ APIS EXPOSED ------------------------ */
|
||||
typedef struct STbUidGenerator {
|
||||
tb_uid_t nextUid;
|
||||
} STbUidGenerator;
|
||||
|
||||
// STableUidGenerator
|
||||
int metaOpenUidGnrt(SMeta *pMeta);
|
||||
void metaCloseUidGnrt(SMeta *pMeta);
|
||||
|
||||
// tb_uid_t
|
||||
#define IVLD_TB_UID 0
|
||||
tb_uid_t metaGenerateUid(SMeta *pMeta);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_TD_META_UID_H_*/
|
|
@ -1,29 +0,0 @@
|
|||
/*
|
||||
* 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_TSDB_HEALTH_H_
|
||||
#define _TD_TSDB_HEALTH_H_
|
||||
|
||||
#if 0
|
||||
|
||||
bool tsdbUrgeQueryFree(STsdbRepo* pRepo);
|
||||
int32_t tsdbInsertNewBlock(STsdbRepo* pRepo);
|
||||
|
||||
bool tsdbIdleMemEnough();
|
||||
bool tsdbAllowNewBlock(STsdbRepo* pRepo);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _TD_TSDB_BUFFER_H_ */
|
|
@ -1,49 +0,0 @@
|
|||
/*
|
||||
* 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 TSDB_ROW_MERGE_BUF_H
|
||||
#define TSDB_ROW_MERGE_BUF_H
|
||||
|
||||
#if 0
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "tsdb.h"
|
||||
#include "tchecksum.h"
|
||||
#include "tsdbReadImpl.h"
|
||||
|
||||
typedef void* SMergeBuf;
|
||||
|
||||
SDataRow tsdbMergeTwoRows(SMergeBuf *pBuf, SMemRow row1, SMemRow row2, STSchema *pSchema1, STSchema *pSchema2);
|
||||
|
||||
static FORCE_INLINE int tsdbMergeBufMakeSureRoom(SMergeBuf *pBuf, STSchema* pSchema1, STSchema* pSchema2) {
|
||||
size_t len1 = dataRowMaxBytesFromSchema(pSchema1);
|
||||
size_t len2 = dataRowMaxBytesFromSchema(pSchema2);
|
||||
return tsdbMakeRoom(pBuf, MAX(len1, len2));
|
||||
}
|
||||
|
||||
static FORCE_INLINE void tsdbFreeMergeBuf(SMergeBuf buf) {
|
||||
taosTZfree(buf);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* ifndef TSDB_ROW_MERGE_BUF_H */
|
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
* 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_VNODE_DEF_H_
|
||||
#define _TD_VNODE_DEF_H_
|
||||
|
||||
#include "mallocator.h"
|
||||
// #include "sync.h"
|
||||
#include "tcoding.h"
|
||||
#include "tfs.h"
|
||||
#include "tlist.h"
|
||||
#include "tlockfree.h"
|
||||
#include "tmacro.h"
|
||||
#include "wal.h"
|
||||
|
||||
#include "vnode.h"
|
||||
|
||||
#include "vnodeQuery.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct SVState SVState;
|
||||
typedef struct SVBufPool SVBufPool;
|
||||
|
||||
typedef struct SVnodeTask {
|
||||
TD_DLIST_NODE(SVnodeTask);
|
||||
void* arg;
|
||||
int (*execute)(void*);
|
||||
} SVnodeTask;
|
||||
|
||||
typedef struct SVnodeMgr {
|
||||
td_mode_flag_t vnodeInitFlag;
|
||||
// For commit
|
||||
bool stop;
|
||||
uint16_t nthreads;
|
||||
pthread_t* threads;
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t hasTask;
|
||||
TD_DLIST(SVnodeTask) queue;
|
||||
// For vnode Mgmt
|
||||
SDnode* pDnode;
|
||||
PutReqToVQueryQFp putReqToVQueryQFp;
|
||||
} SVnodeMgr;
|
||||
|
||||
extern SVnodeMgr vnodeMgr;
|
||||
|
||||
// SVState
|
||||
struct SVState {
|
||||
int64_t processed;
|
||||
int64_t committed;
|
||||
int64_t applied;
|
||||
};
|
||||
|
||||
struct SVnode {
|
||||
int32_t vgId;
|
||||
char* path;
|
||||
SVnodeCfg config;
|
||||
SVState state;
|
||||
SVBufPool* pBufPool;
|
||||
SMeta* pMeta;
|
||||
STsdb* pTsdb;
|
||||
STQ* pTq;
|
||||
SWal* pWal;
|
||||
tsem_t canCommit;
|
||||
SQHandle* pQuery;
|
||||
SDnode* pDnode;
|
||||
};
|
||||
|
||||
int vnodeScheduleTask(SVnodeTask* task);
|
||||
|
||||
int32_t vnodePutReqToVQueryQ(SVnode* pVnode, struct SRpcMsg* pReq);
|
||||
|
||||
// For Log
|
||||
extern int32_t vDebugFlag;
|
||||
|
||||
#define vFatal(...) \
|
||||
do { \
|
||||
if (vDebugFlag & DEBUG_FATAL) { \
|
||||
taosPrintLog("VND FATAL ", 255, __VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
#define vError(...) \
|
||||
do { \
|
||||
if (vDebugFlag & DEBUG_ERROR) { \
|
||||
taosPrintLog("VND ERROR ", 255, __VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
#define vWarn(...) \
|
||||
do { \
|
||||
if (vDebugFlag & DEBUG_WARN) { \
|
||||
taosPrintLog("VND WARN ", 255, __VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
#define vInfo(...) \
|
||||
do { \
|
||||
if (vDebugFlag & DEBUG_INFO) { \
|
||||
taosPrintLog("VND ", 255, __VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
#define vDebug(...) \
|
||||
do { \
|
||||
if (vDebugFlag & DEBUG_DEBUG) { \
|
||||
taosPrintLog("VND ", tsdbDebugFlag, __VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
#define vTrace(...) \
|
||||
do { \
|
||||
if (vDebugFlag & DEBUG_TRACE) { \
|
||||
taosPrintLog("VND ", tsdbDebugFlag, __VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
// vnodeCfg.h
|
||||
extern const SVnodeCfg defaultVnodeOptions;
|
||||
|
||||
int vnodeValidateOptions(const SVnodeCfg*);
|
||||
void vnodeOptionsCopy(SVnodeCfg* pDest, const SVnodeCfg* pSrc);
|
||||
|
||||
// For commit
|
||||
#define vnodeShouldCommit vnodeBufPoolIsFull
|
||||
int vnodeSyncCommit(SVnode* pVnode);
|
||||
int vnodeAsyncCommit(SVnode* pVnode);
|
||||
|
||||
// SVBufPool
|
||||
|
||||
int vnodeOpenBufPool(SVnode* pVnode);
|
||||
void vnodeCloseBufPool(SVnode* pVnode);
|
||||
int vnodeBufPoolSwitch(SVnode* pVnode);
|
||||
int vnodeBufPoolRecycle(SVnode* pVnode);
|
||||
void* vnodeMalloc(SVnode* pVnode, uint64_t size);
|
||||
bool vnodeBufPoolIsFull(SVnode* pVnode);
|
||||
|
||||
SMemAllocatorFactory* vBufPoolGetMAF(SVnode* pVnode);
|
||||
|
||||
// SVMemAllocator
|
||||
typedef struct SVArenaNode {
|
||||
TD_SLIST_NODE(SVArenaNode);
|
||||
uint64_t size; // current node size
|
||||
void* ptr;
|
||||
char data[];
|
||||
} SVArenaNode;
|
||||
|
||||
typedef struct SVMemAllocator {
|
||||
T_REF_DECLARE()
|
||||
TD_DLIST_NODE(SVMemAllocator);
|
||||
uint64_t capacity;
|
||||
uint64_t ssize;
|
||||
uint64_t lsize;
|
||||
SVArenaNode* pNode;
|
||||
TD_SLIST(SVArenaNode) nlist;
|
||||
} SVMemAllocator;
|
||||
|
||||
SVMemAllocator* vmaCreate(uint64_t capacity, uint64_t ssize, uint64_t lsize);
|
||||
void vmaDestroy(SVMemAllocator* pVMA);
|
||||
void vmaReset(SVMemAllocator* pVMA);
|
||||
void* vmaMalloc(SVMemAllocator* pVMA, uint64_t size);
|
||||
void vmaFree(SVMemAllocator* pVMA, void* ptr);
|
||||
bool vmaIsFull(SVMemAllocator* pVMA);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_TD_VNODE_DEF_H_*/
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
* 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_VNODE_BUFFER_POOL_H_
|
||||
#define _TD_VNODE_BUFFER_POOL_H_
|
||||
|
||||
#include "tlist.h"
|
||||
#include "vnode.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct SVBufPool SVBufPool;
|
||||
|
||||
int vnodeOpenBufPool(SVnode *pVnode);
|
||||
void vnodeCloseBufPool(SVnode *pVnode);
|
||||
int vnodeBufPoolSwitch(SVnode *pVnode);
|
||||
int vnodeBufPoolRecycle(SVnode *pVnode);
|
||||
void *vnodeMalloc(SVnode *pVnode, uint64_t size);
|
||||
bool vnodeBufPoolIsFull(SVnode *pVnode);
|
||||
|
||||
SMemAllocatorFactory *vBufPoolGetMAF(SVnode *pVnode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_TD_VNODE_BUFFER_POOL_H_*/
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* 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_VNODE_CFG_H_
|
||||
#define _TD_VNODE_CFG_H_
|
||||
|
||||
#include "vnode.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const SVnodeCfg defaultVnodeOptions;
|
||||
|
||||
int vnodeValidateOptions(const SVnodeCfg *);
|
||||
void vnodeOptionsCopy(SVnodeCfg *pDest, const SVnodeCfg *pSrc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_TD_VNODE_CFG_H_*/
|
|
@ -1,33 +0,0 @@
|
|||
/*
|
||||
* 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_VNODE_COMMIT_H_
|
||||
#define _TD_VNODE_COMMIT_H_
|
||||
|
||||
#include "vnode.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define vnodeShouldCommit vnodeBufPoolIsFull
|
||||
int vnodeSyncCommit(SVnode *pVnode);
|
||||
int vnodeAsyncCommit(SVnode *pVnode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_TD_VNODE_COMMIT_H_*/
|
|
@ -1,96 +0,0 @@
|
|||
/*
|
||||
* 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_VNODE_DEF_H_
|
||||
#define _TD_VNODE_DEF_H_
|
||||
|
||||
#include "mallocator.h"
|
||||
// #include "sync.h"
|
||||
#include "tcoding.h"
|
||||
#include "tlist.h"
|
||||
#include "tlockfree.h"
|
||||
#include "tmacro.h"
|
||||
#include "wal.h"
|
||||
#include "tfs.h"
|
||||
|
||||
#include "vnode.h"
|
||||
|
||||
#include "vnodeBufferPool.h"
|
||||
#include "vnodeCfg.h"
|
||||
#include "vnodeCommit.h"
|
||||
#include "vnodeMemAllocator.h"
|
||||
#include "vnodeQuery.h"
|
||||
#include "vnodeStateMgr.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct SVnodeTask {
|
||||
TD_DLIST_NODE(SVnodeTask);
|
||||
void* arg;
|
||||
int (*execute)(void*);
|
||||
} SVnodeTask;
|
||||
|
||||
typedef struct SVnodeMgr {
|
||||
td_mode_flag_t vnodeInitFlag;
|
||||
// For commit
|
||||
bool stop;
|
||||
uint16_t nthreads;
|
||||
pthread_t* threads;
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t hasTask;
|
||||
TD_DLIST(SVnodeTask) queue;
|
||||
// For vnode Mgmt
|
||||
SDnode* pDnode;
|
||||
PutReqToVQueryQFp putReqToVQueryQFp;
|
||||
} SVnodeMgr;
|
||||
|
||||
extern SVnodeMgr vnodeMgr;
|
||||
|
||||
struct SVnode {
|
||||
int32_t vgId;
|
||||
char* path;
|
||||
SVnodeCfg config;
|
||||
SVState state;
|
||||
SVBufPool* pBufPool;
|
||||
SMeta* pMeta;
|
||||
STsdb* pTsdb;
|
||||
STQ* pTq;
|
||||
SWal* pWal;
|
||||
tsem_t canCommit;
|
||||
SQHandle* pQuery;
|
||||
SDnode* pDnode;
|
||||
};
|
||||
|
||||
int vnodeScheduleTask(SVnodeTask* task);
|
||||
|
||||
int32_t vnodePutReqToVQueryQ(SVnode *pVnode, struct SRpcMsg *pReq);
|
||||
|
||||
// For Log
|
||||
extern int32_t vDebugFlag;
|
||||
|
||||
#define vFatal(...) do { if (vDebugFlag & DEBUG_FATAL) { taosPrintLog("VND FATAL ", 255, __VA_ARGS__); }} while(0)
|
||||
#define vError(...) do { if (vDebugFlag & DEBUG_ERROR) { taosPrintLog("VND ERROR ", 255, __VA_ARGS__); }} while(0)
|
||||
#define vWarn(...) do { if (vDebugFlag & DEBUG_WARN) { taosPrintLog("VND WARN ", 255, __VA_ARGS__); }} while(0)
|
||||
#define vInfo(...) do { if (vDebugFlag & DEBUG_INFO) { taosPrintLog("VND ", 255, __VA_ARGS__); }} while(0)
|
||||
#define vDebug(...) do { if (vDebugFlag & DEBUG_DEBUG) { taosPrintLog("VND ", tsdbDebugFlag, __VA_ARGS__); }} while(0)
|
||||
#define vTrace(...) do { if (vDebugFlag & DEBUG_TRACE) { taosPrintLog("VND ", tsdbDebugFlag, __VA_ARGS__); }} while(0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_TD_VNODE_DEF_H_*/
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
* 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_VNODE_INT_H_
|
||||
#define _TD_VNODE_INT_H_
|
||||
|
||||
#include "vnode.h"
|
||||
|
||||
#include "meta.h"
|
||||
// #include "sync.h"
|
||||
#include "tlog.h"
|
||||
#include "tq.h"
|
||||
#include "tsdb.h"
|
||||
#include "wal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int32_t vDebugFlag;
|
||||
|
||||
#define vFatal(...) { if (vDebugFlag & DEBUG_FATAL) { taosPrintLog("VND FATAL ", 255, __VA_ARGS__); }}
|
||||
#define vError(...) { if (vDebugFlag & DEBUG_ERROR) { taosPrintLog("VND ERROR ", 255, __VA_ARGS__); }}
|
||||
#define vWarn(...) { if (vDebugFlag & DEBUG_WARN) { taosPrintLog("VND WARN ", 255, __VA_ARGS__); }}
|
||||
#define vInfo(...) { if (vDebugFlag & DEBUG_INFO) { taosPrintLog("VND ", 255, __VA_ARGS__); }}
|
||||
#define vDebug(...) { if (vDebugFlag & DEBUG_DEBUG) { taosPrintLog("VND ", vDebugFlag, __VA_ARGS__); }}
|
||||
#define vTrace(...) { if (vDebugFlag & DEBUG_TRACE) { taosPrintLog("VND ", vDebugFlag, __VA_ARGS__); }}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_TD_VNODE_INT_H_*/
|
|
@ -1,53 +0,0 @@
|
|||
/*
|
||||
* 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_VNODE_MEM_ALLOCATOR_H_
|
||||
#define _TD_VNODE_MEM_ALLOCATOR_H_
|
||||
|
||||
#include "os.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct SVArenaNode {
|
||||
TD_SLIST_NODE(SVArenaNode);
|
||||
uint64_t size; // current node size
|
||||
void * ptr;
|
||||
char data[];
|
||||
} SVArenaNode;
|
||||
|
||||
typedef struct SVMemAllocator {
|
||||
T_REF_DECLARE()
|
||||
TD_DLIST_NODE(SVMemAllocator);
|
||||
uint64_t capacity;
|
||||
uint64_t ssize;
|
||||
uint64_t lsize;
|
||||
SVArenaNode *pNode;
|
||||
TD_SLIST(SVArenaNode) nlist;
|
||||
} SVMemAllocator;
|
||||
|
||||
SVMemAllocator *vmaCreate(uint64_t capacity, uint64_t ssize, uint64_t lsize);
|
||||
void vmaDestroy(SVMemAllocator *pVMA);
|
||||
void vmaReset(SVMemAllocator *pVMA);
|
||||
void * vmaMalloc(SVMemAllocator *pVMA, uint64_t size);
|
||||
void vmaFree(SVMemAllocator *pVMA, void *ptr);
|
||||
bool vmaIsFull(SVMemAllocator *pVMA);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_TD_VNODE_MEM_ALLOCATOR_H_*/
|
|
@ -22,6 +22,7 @@ extern "C" {
|
|||
#include "qworker.h"
|
||||
#include "vnode.h"
|
||||
|
||||
|
||||
typedef struct SQWorkerMgmt SQHandle;
|
||||
|
||||
int vnodeQueryOpen(SVnode *pVnode);
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
/*
|
||||
* 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_VNODE_STATE_MGR_H_
|
||||
#define _TD_VNODE_STATE_MGR_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
int64_t processed;
|
||||
int64_t committed;
|
||||
int64_t applied;
|
||||
} SVState;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_TD_VNODE_STATE_MGR_H_*/
|
|
@ -1,31 +0,0 @@
|
|||
/*
|
||||
* 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_VNODE_WRITE_H_
|
||||
#define _TD_VNODE_WRITE_H_
|
||||
|
||||
#include "vnode.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void vnodeProcessWriteMsg(SVnode* pVnode, SVnodeMsg* pMsg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_TD_VNODE_WRITE_H_*/
|
|
@ -30,11 +30,11 @@ SMeta *metaOpen(const char *path, const SMetaCfg *pMetaCfg, SMemAllocatorFactory
|
|||
pMetaCfg = &defaultMetaOptions;
|
||||
}
|
||||
|
||||
// Validate the options
|
||||
if (metaValidateOptions(pMetaCfg) < 0) {
|
||||
// TODO: deal with error
|
||||
return NULL;
|
||||
}
|
||||
// // Validate the options
|
||||
// if (metaValidateOptions(pMetaCfg) < 0) {
|
||||
// // TODO: deal with error
|
||||
// return NULL;
|
||||
// }
|
||||
|
||||
// Allocate handle
|
||||
pMeta = metaNew(path, pMetaCfg, pMAF);
|
||||
|
|
|
@ -17,10 +17,10 @@
|
|||
|
||||
int metaCreateTable(SMeta *pMeta, STbCfg *pTbCfg) {
|
||||
// Validate the tbOptions
|
||||
if (metaValidateTbCfg(pMeta, pTbCfg) < 0) {
|
||||
// TODO: handle error
|
||||
return -1;
|
||||
}
|
||||
// if (metaValidateTbCfg(pMeta, pTbCfg) < 0) {
|
||||
// // TODO: handle error
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// TODO: add atomicity
|
||||
|
||||
|
|
|
@ -1,98 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// #include "os.h"
|
||||
// #include "tmsg.h"
|
||||
// #include "tarray.h"
|
||||
// #include "query.h"
|
||||
// #include "tglobal.h"
|
||||
// #include "tlist.h"
|
||||
// #include "tsdbint.h"
|
||||
// #include "tsdbBuffer.h"
|
||||
// #include "tsdbLog.h"
|
||||
// #include "tsdbHealth.h"
|
||||
// #include "ttimer.h"
|
||||
// #include "tthread.h"
|
||||
|
||||
|
||||
// // return malloc new block count
|
||||
// int32_t tsdbInsertNewBlock(STsdbRepo * pRepo) {
|
||||
// STsdbBufPool *pPool = pRepo->pPool;
|
||||
// int32_t cnt = 0;
|
||||
|
||||
// if(tsdbAllowNewBlock(pRepo)) {
|
||||
// STsdbBufBlock *pBufBlock = tsdbNewBufBlock(pPool->bufBlockSize);
|
||||
// if (pBufBlock) {
|
||||
// if (tdListAppend(pPool->bufBlockList, (void *)(&pBufBlock)) < 0) {
|
||||
// // append error
|
||||
// tsdbFreeBufBlock(pBufBlock);
|
||||
// } else {
|
||||
// pPool->nElasticBlocks ++;
|
||||
// cnt ++ ;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return cnt;
|
||||
// }
|
||||
|
||||
// // switch anther thread to run
|
||||
// void* cbKillQueryFree(void* param) {
|
||||
// STsdbRepo* pRepo = (STsdbRepo*)param;
|
||||
// // vnode
|
||||
// if(pRepo->appH.notifyStatus) {
|
||||
// pRepo->appH.notifyStatus(pRepo->appH.appH, TSDB_STATUS_COMMIT_NOBLOCK, TSDB_CODE_SUCCESS);
|
||||
// }
|
||||
|
||||
// // free
|
||||
// if(pRepo->pthread){
|
||||
// void* p = pRepo->pthread;
|
||||
// pRepo->pthread = NULL;
|
||||
// free(p);
|
||||
// }
|
||||
|
||||
// return NULL;
|
||||
// }
|
||||
|
||||
// // return true do free , false do nothing
|
||||
// bool tsdbUrgeQueryFree(STsdbRepo * pRepo) {
|
||||
// // check previous running
|
||||
// if(pRepo->pthread && taosThreadRunning(pRepo->pthread)) {
|
||||
// tsdbWarn("vgId:%d pre urge thread is runing. nBlocks=%d nElasticBlocks=%d", REPO_ID(pRepo), pRepo->pPool->nBufBlocks, pRepo->pPool->nElasticBlocks);
|
||||
// return false;
|
||||
// }
|
||||
// // create new
|
||||
// pRepo->pthread = taosCreateThread(cbKillQueryFree, pRepo);
|
||||
// if(pRepo->pthread == NULL) {
|
||||
// tsdbError("vgId:%d create urge thread error.", REPO_ID(pRepo));
|
||||
// return false;
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// bool tsdbAllowNewBlock(STsdbRepo* pRepo) {
|
||||
// int32_t nMaxElastic = pRepo->config.totalBlocks/3;
|
||||
// STsdbBufPool* pPool = pRepo->pPool;
|
||||
// if(pPool->nElasticBlocks >= nMaxElastic) {
|
||||
// tsdbWarn("vgId:%d tsdbAllowNewBlock return fasle. nElasticBlock(%d) >= MaxElasticBlocks(%d)", REPO_ID(pRepo), pPool->nElasticBlocks, nMaxElastic);
|
||||
// return false;
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// bool tsdbNoProblem(STsdbRepo* pRepo) {
|
||||
// if(listNEles(pRepo->pPool->bufBlockList) == 0)
|
||||
// return false;
|
||||
// return true;
|
||||
// }
|
|
@ -85,7 +85,6 @@ enum {
|
|||
typedef struct STableCheckInfo {
|
||||
uint64_t tableId;
|
||||
TSKEY lastKey;
|
||||
STable* pTableObj;
|
||||
SBlockInfo* pCompInfo;
|
||||
int32_t compSize;
|
||||
int32_t numOfBlocks:29; // number of qualified data blocks not the original blocks
|
||||
|
@ -141,8 +140,6 @@ typedef struct STsdbReadHandle {
|
|||
STableBlockInfo* pDataBlockInfo;
|
||||
SDataCols *pDataCols; // in order to hold current file data block
|
||||
int32_t allocSize; // allocated data block size
|
||||
// STsdb
|
||||
// STsdbMemTable * pMemTable;
|
||||
SArray *defaultLoadColumn;// default load column
|
||||
SDataBlockLoadInfo dataBlockLoadInfo; /* record current block load information */
|
||||
SLoadCompBlockInfo compBlockLoadInfo; /* record current compblock information in SQueryAttr */
|
||||
|
@ -204,8 +201,8 @@ static SArray* getDefaultLoadColumns(STsdbReadHandle* pTsdbReadHandle, bool load
|
|||
int16_t colId = *(int16_t*)taosArrayGet(pLocalIdList, 0);
|
||||
|
||||
// the primary timestamp column does not be included in the the specified load column list, add it
|
||||
if (loadTS && colId != 0) {
|
||||
int16_t columnId = 0;
|
||||
if (loadTS && colId != PRIMARYKEY_TIMESTAMP_COL_ID) {
|
||||
int16_t columnId = PRIMARYKEY_TIMESTAMP_COL_ID;
|
||||
taosArrayInsert(pLocalIdList, 0, &columnId);
|
||||
}
|
||||
|
||||
|
@ -292,7 +289,7 @@ static SArray* createCheckInfoFromTableGroup(STsdbReadHandle* pTsdbReadHandle, S
|
|||
for (int32_t j = 0; j < gsize; ++j) {
|
||||
STableKeyInfo* pKeyInfo = (STableKeyInfo*) taosArrayGet(group, j);
|
||||
|
||||
STableCheckInfo info = { .lastKey = pKeyInfo->lastKey, .pTableObj = pKeyInfo->pTable };
|
||||
STableCheckInfo info = { .lastKey = pKeyInfo->lastKey};
|
||||
// assert(info.pTableObj != NULL && (info.pTableObj->type == TSDB_NORMAL_TABLE ||
|
||||
// info.pTableObj->type == TSDB_CHILD_TABLE || info.pTableObj->type == TSDB_STREAM_TABLE));
|
||||
|
||||
|
@ -315,10 +312,9 @@ static SArray* createCheckInfoFromTableGroup(STsdbReadHandle* pTsdbReadHandle, S
|
|||
|
||||
// taosArraySort(pTableCheckInfo, tsdbCheckInfoCompar);
|
||||
size_t gsize = taosArrayGetSize(pTableCheckInfo);
|
||||
for (int32_t i = 0; i < gsize; ++i) {
|
||||
STableCheckInfo* pInfo = (STableCheckInfo*) taosArrayGet(pTableCheckInfo, i);
|
||||
taosArrayPush(pTable, &pInfo->pTableObj);
|
||||
}
|
||||
// for (int32_t i = 0; i < gsize; ++i) {
|
||||
// STableCheckInfo* pInfo = (STableCheckInfo*) taosArrayGet(pTableCheckInfo, i);
|
||||
// }
|
||||
|
||||
*psTable = pTable;
|
||||
return pTableCheckInfo;
|
||||
|
@ -347,15 +343,11 @@ static void resetCheckInfo(STsdbReadHandle* pTsdbReadHandle) {
|
|||
// only one table, not need to sort again
|
||||
static SArray* createCheckInfoFromCheckInfo(STableCheckInfo* pCheckInfo, TSKEY skey, SArray** psTable) {
|
||||
SArray* pNew = taosArrayInit(1, sizeof(STableCheckInfo));
|
||||
SArray* pTable = taosArrayInit(1, sizeof(STable*));
|
||||
|
||||
STableCheckInfo info = { .lastKey = skey, .pTableObj = pCheckInfo->pTableObj};
|
||||
STableCheckInfo info = { .lastKey = skey};
|
||||
|
||||
info.tableId = pCheckInfo->tableId;
|
||||
taosArrayPush(pNew, &info);
|
||||
taosArrayPush(pTable, &pCheckInfo->pTableObj);
|
||||
|
||||
*psTable = pTable;
|
||||
return pNew;
|
||||
}
|
||||
|
||||
|
@ -461,9 +453,6 @@ static STsdbReadHandle* tsdbQueryTablesImpl(STsdb* tsdb, STsdbQueryCond* pCond,
|
|||
pReadHandle->defaultLoadColumn = getDefaultLoadColumns(pReadHandle, true);
|
||||
}
|
||||
|
||||
// STsdbMeta* pMeta = NULL;//tsdbGetMeta(tsdb);
|
||||
// assert(pMeta != NULL);
|
||||
|
||||
pReadHandle->pDataCols = tdNewDataCols(1000, pReadHandle->pTsdb->config.maxRowsPerFileBlock);
|
||||
if (pReadHandle->pDataCols == NULL) {
|
||||
tsdbError("%p failed to malloc buf for pDataCols, %"PRIu64, pReadHandle, pReadHandle->qId);
|
||||
|
@ -641,12 +630,6 @@ SArray* tsdbGetQueriedTableList(tsdbReadHandleT *pHandle) {
|
|||
|
||||
size_t size = taosArrayGetSize(pTsdbReadHandle->pTableCheckInfo);
|
||||
SArray* res = taosArrayInit(size, POINTER_BYTES);
|
||||
|
||||
for(int32_t i = 0; i < size; ++i) {
|
||||
STableCheckInfo* pCheckInfo = taosArrayGet(pTsdbReadHandle->pTableCheckInfo, i);
|
||||
taosArrayPush(res, &pCheckInfo->pTableObj);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -1049,7 +1032,10 @@ static int32_t loadBlockInfo(STsdbReadHandle * pTsdbReadHandle, int32_t index, i
|
|||
STableCheckInfo* pCheckInfo = taosArrayGet(pTsdbReadHandle->pTableCheckInfo, index);
|
||||
pCheckInfo->numOfBlocks = 0;
|
||||
|
||||
if (tsdbSetReadTable(&pTsdbReadHandle->rhelper, pCheckInfo->pTableObj) != TSDB_CODE_SUCCESS) {
|
||||
STable table = {.uid = pCheckInfo->tableId, .tid = pCheckInfo->tableId};
|
||||
table.pSchema = metaGetTbTSchema(pTsdbReadHandle->pTsdb->pMeta, pCheckInfo->tableId, 0);
|
||||
|
||||
if (tsdbSetReadTable(&pTsdbReadHandle->rhelper, &table) != TSDB_CODE_SUCCESS) {
|
||||
code = terrno;
|
||||
return code;
|
||||
}
|
||||
|
@ -1149,7 +1135,7 @@ static int32_t getFileCompInfo(STsdbReadHandle* pTsdbReadHandle, int32_t* numOfB
|
|||
static int32_t doLoadFileDataBlock(STsdbReadHandle* pTsdbReadHandle, SBlock* pBlock, STableCheckInfo* pCheckInfo, int32_t slotIndex) {
|
||||
int64_t st = taosGetTimestampUs();
|
||||
|
||||
STSchema *pSchema = NULL;//tsdbGetTableSchema(pCheckInfo->pTableObj);
|
||||
STSchema *pSchema = metaGetTbTSchema(pTsdbReadHandle->pTsdb->pMeta, pCheckInfo->tableId, 0);
|
||||
int32_t code = tdInitDataCols(pTsdbReadHandle->pDataCols, pSchema);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
tsdbError("%p failed to malloc buf for pDataCols, 0x%"PRIx64, pTsdbReadHandle, pTsdbReadHandle->qId);
|
||||
|
@ -1184,7 +1170,7 @@ static int32_t doLoadFileDataBlock(STsdbReadHandle* pTsdbReadHandle, SBlock* pBl
|
|||
|
||||
pBlockLoadInfo->fileGroup = pTsdbReadHandle->pFileGroup;
|
||||
pBlockLoadInfo->slot = pTsdbReadHandle->cur.slot;
|
||||
pBlockLoadInfo->uid = pCheckInfo->pTableObj->uid;
|
||||
pBlockLoadInfo->uid = pCheckInfo->tableId;
|
||||
|
||||
SDataCols* pCols = pTsdbReadHandle->rhelper.pDCols[0];
|
||||
assert(pCols->numOfRows != 0 && pCols->numOfRows <= pBlock->numOfRows);
|
||||
|
@ -1878,7 +1864,7 @@ static void doMergeTwoLevelData(STsdbReadHandle* pTsdbReadHandle, STableCheckInf
|
|||
int32_t step = ASCENDING_TRAVERSE(pTsdbReadHandle->order)? 1:-1;
|
||||
int32_t numOfCols = (int32_t)(QH_GET_NUM_OF_COLS(pTsdbReadHandle));
|
||||
|
||||
STable* pTable = pCheckInfo->pTableObj;
|
||||
STable* pTable = NULL;
|
||||
int32_t endPos = getEndPosInDataBlock(pTsdbReadHandle, &blockInfo);
|
||||
|
||||
tsdbDebug("%p uid:%" PRIu64" start merge data block, file block range:%"PRIu64"-%"PRIu64" rows:%d, start:%d,"
|
||||
|
@ -1932,7 +1918,7 @@ static void doMergeTwoLevelData(STsdbReadHandle* pTsdbReadHandle, STableCheckInf
|
|||
rv2 = memRowVersion(row2);
|
||||
}
|
||||
|
||||
mergeTwoRowFromMem(pTsdbReadHandle, pTsdbReadHandle->outputCapacity, numOfRows, row1, row2, numOfCols, pTable, pSchema1, pSchema2, true);
|
||||
mergeTwoRowFromMem(pTsdbReadHandle, pTsdbReadHandle->outputCapacity, numOfRows, row1, row2, numOfCols, pCheckInfo->tableId, pSchema1, pSchema2, true);
|
||||
numOfRows += 1;
|
||||
if (cur->win.skey == TSKEY_INITIAL_VAL) {
|
||||
cur->win.skey = key;
|
||||
|
@ -1958,7 +1944,7 @@ static void doMergeTwoLevelData(STsdbReadHandle* pTsdbReadHandle, STableCheckInf
|
|||
}
|
||||
|
||||
bool forceSetNull = pCfg->update != TD_ROW_PARTIAL_UPDATE;
|
||||
mergeTwoRowFromMem(pTsdbReadHandle, pTsdbReadHandle->outputCapacity, numOfRows, row1, row2, numOfCols, pTable, pSchema1, pSchema2, forceSetNull);
|
||||
mergeTwoRowFromMem(pTsdbReadHandle, pTsdbReadHandle->outputCapacity, numOfRows, row1, row2, numOfCols, pCheckInfo->tableId, pSchema1, pSchema2, forceSetNull);
|
||||
numOfRows += 1;
|
||||
if (cur->win.skey == TSKEY_INITIAL_VAL) {
|
||||
cur->win.skey = key;
|
||||
|
@ -2745,7 +2731,7 @@ static bool loadCachedLastRow(STsdbReadHandle* pTsdbReadHandle) {
|
|||
// if (ret != TSDB_CODE_SUCCESS) {
|
||||
// return false;
|
||||
// }
|
||||
mergeTwoRowFromMem(pTsdbReadHandle, pTsdbReadHandle->outputCapacity, 0, pRow, NULL, numOfCols, pCheckInfo->pTableObj, NULL, NULL, true);
|
||||
mergeTwoRowFromMem(pTsdbReadHandle, pTsdbReadHandle->outputCapacity, 0, pRow, NULL, numOfCols, pCheckInfo->tableId, NULL, NULL, true);
|
||||
tfree(pRow);
|
||||
|
||||
// update the last key value
|
||||
|
@ -3389,14 +3375,14 @@ SArray* tsdbRetrieveDataBlock(tsdbReadHandleT* pTsdbReadHandle, SArray* pIdList)
|
|||
if (pHandle->cur.mixBlock) {
|
||||
return pHandle->pColumns;
|
||||
} else {
|
||||
SDataBlockInfo binfo = {0};/*GET_FILE_DATA_BLOCK_INFO(pCheckInfo, pBlockInfo->compBlock);*/
|
||||
SDataBlockInfo binfo = GET_FILE_DATA_BLOCK_INFO(pCheckInfo, pBlockInfo->compBlock);
|
||||
assert(pHandle->realNumOfRows <= binfo.rows);
|
||||
|
||||
// data block has been loaded, todo extract method
|
||||
SDataBlockLoadInfo* pBlockLoadInfo = &pHandle->dataBlockLoadInfo;
|
||||
|
||||
if (pBlockLoadInfo->slot == pHandle->cur.slot && pBlockLoadInfo->fileGroup->fid == pHandle->cur.fid &&
|
||||
pBlockLoadInfo->uid == pCheckInfo->pTableObj->tid) {
|
||||
pBlockLoadInfo->uid == pCheckInfo->tableId) {
|
||||
return pHandle->pColumns;
|
||||
} else { // only load the file block
|
||||
SBlock* pBlock = pBlockInfo->compBlock;
|
||||
|
|
|
@ -551,7 +551,7 @@ static int tsdbCheckAndDecodeColumnData(SDataCol *pDataCol, void *content, int32
|
|||
static int tsdbLoadBlockDataColsImpl(SReadH *pReadh, SBlock *pBlock, SDataCols *pDataCols, int16_t *colIds,
|
||||
int numOfColIds) {
|
||||
ASSERT(pBlock->numOfSubBlocks == 0 || pBlock->numOfSubBlocks == 1);
|
||||
ASSERT(colIds[0] == 0);
|
||||
ASSERT(colIds[0] == PRIMARYKEY_TIMESTAMP_COL_ID);
|
||||
|
||||
SDFile * pDFile = (pBlock->last) ? TSDB_READ_LAST_FILE(pReadh) : TSDB_READ_DATA_FILE(pReadh);
|
||||
SBlockCol blockCol = {0};
|
||||
|
@ -588,7 +588,7 @@ static int tsdbLoadBlockDataColsImpl(SReadH *pReadh, SBlock *pBlock, SDataCols *
|
|||
if (pDataCol == NULL) continue;
|
||||
ASSERT(pDataCol->colId == colId);
|
||||
|
||||
if (colId == 0) { // load the key row
|
||||
if (colId == PRIMARYKEY_TIMESTAMP_COL_ID) { // load the key row
|
||||
blockCol.colId = colId;
|
||||
blockCol.len = pBlock->keyLen;
|
||||
blockCol.type = pDataCol->type;
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
* 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 "tsdbRowMergeBuf.h"
|
||||
// #include "tdataformat.h"
|
||||
|
||||
// // row1 has higher priority
|
||||
// SMemRow tsdbMergeTwoRows(SMergeBuf *pBuf, SMemRow row1, SMemRow row2, STSchema *pSchema1, STSchema *pSchema2) {
|
||||
// if(row2 == NULL) return row1;
|
||||
// if(row1 == NULL) return row2;
|
||||
// ASSERT(pSchema1->version == memRowVersion(row1));
|
||||
// ASSERT(pSchema2->version == memRowVersion(row2));
|
||||
|
||||
// if(tsdbMergeBufMakeSureRoom(pBuf, pSchema1, pSchema2) < 0) {
|
||||
// return NULL;
|
||||
// }
|
||||
// return mergeTwoMemRows(*pBuf, row1, row2, pSchema1, pSchema2);
|
||||
// }
|
|
@ -13,7 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "vnodeDef.h"
|
||||
#include "vnd.h"
|
||||
|
||||
static SVArenaNode *vArenaNodeNew(uint64_t capacity);
|
||||
static void vArenaNodeFree(SVArenaNode *pNode);
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "vnodeDef.h"
|
||||
#include "vnd.h"
|
||||
|
||||
/* ------------------------ STRUCTURES ------------------------ */
|
||||
#define VNODE_BUF_POOL_SHARDS 3
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "vnodeDef.h"
|
||||
#include "vnd.h"
|
||||
|
||||
const SVnodeCfg defaultVnodeOptions = {
|
||||
.wsize = 96 * 1024 * 1024, .ssize = 1 * 1024 * 1024, .lsize = 1024, .walCfg = {.level = TAOS_WAL_WRITE}}; /* TODO */
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "vnodeDef.h"
|
||||
#include "vnd.h"
|
||||
|
||||
static int vnodeStartCommit(SVnode *pVnode);
|
||||
static int vnodeEndCommit(SVnode *pVnode);
|
||||
|
|
|
@ -14,7 +14,8 @@
|
|||
*/
|
||||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "vnodeInt.h"
|
||||
#include "vnd.h"
|
||||
// #include "vnodeInt.h"
|
||||
|
||||
int32_t vnodeAlter(SVnode *pVnode, const SVnodeCfg *pCfg) { return 0; }
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "vnodeDef.h"
|
||||
#include "vnd.h"
|
||||
|
||||
static SVnode *vnodeNew(const char *path, const SVnodeCfg *pVnodeCfg);
|
||||
static void vnodeFree(SVnode *pVnode);
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "vnodeDef.h"
|
||||
#include "vnd.h"
|
||||
|
||||
SVnodeMgr vnodeMgr = {.vnodeInitFlag = TD_MOD_UNINITIALIZED};
|
||||
|
||||
|
|
|
@ -14,16 +14,27 @@
|
|||
*/
|
||||
|
||||
#include "vnodeQuery.h"
|
||||
#include "vnodeDef.h"
|
||||
#include "vnd.h"
|
||||
|
||||
static int32_t vnodeGetTableList(SVnode *pVnode, SRpcMsg *pMsg);
|
||||
static int vnodeGetTableMeta(SVnode *pVnode, SRpcMsg *pMsg, SRpcMsg **pRsp);
|
||||
|
||||
int vnodeQueryOpen(SVnode *pVnode) { return qWorkerInit(NULL, &pVnode->pQuery); }
|
||||
int vnodeQueryOpen(SVnode *pVnode) { return qWorkerInit(NODE_TYPE_VNODE, pVnode->vgId, NULL, &pVnode->pQuery, pVnode, vnodePutReqToVQueryQ); }
|
||||
|
||||
int vnodeProcessQueryReq(SVnode *pVnode, SRpcMsg *pMsg, SRpcMsg **pRsp) {
|
||||
vTrace("query message is processed");
|
||||
return qWorkerProcessQueryMsg(pVnode->pTsdb, pVnode->pQuery, pMsg);
|
||||
vTrace("query message is processing");
|
||||
|
||||
switch (pMsg->msgType) {
|
||||
case TDMT_VND_QUERY:
|
||||
return qWorkerProcessQueryMsg(pVnode->pTsdb, pVnode->pQuery, pMsg);
|
||||
case TDMT_VND_QUERY_CONTINUE:
|
||||
return qWorkerProcessCQueryMsg(pVnode->pTsdb, pVnode->pQuery, pMsg);
|
||||
case TDMT_VND_SCHEDULE_DATA_SINK:
|
||||
return qWorkerProcessDataSinkMsg(pVnode->pTsdb, pVnode->pQuery, pMsg);
|
||||
default:
|
||||
vError("unknown msg type:%d in query queue", pMsg->msgType);
|
||||
return TSDB_CODE_VND_APP_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
int vnodeProcessFetchReq(SVnode *pVnode, SRpcMsg *pMsg, SRpcMsg **pRsp) {
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "vnodeDef.h"
|
||||
#include "vnd.h"
|
||||
|
||||
int vnodeProcessNoWalWMsgs(SVnode *pVnode, SRpcMsg *pMsg) {
|
||||
switch (pMsg->msgType) {
|
||||
|
@ -84,6 +84,7 @@ int vnodeApplyWMsg(SVnode *pVnode, SRpcMsg *pMsg, SRpcMsg **pRsp) {
|
|||
// TODO: handle error
|
||||
}
|
||||
vTrace("vgId:%d process create table %s", pVnode->vgId, pCreateTbReq->name);
|
||||
free(pCreateTbReq->name);
|
||||
if (pCreateTbReq->type == TD_SUPER_TABLE) {
|
||||
free(pCreateTbReq->stbCfg.pSchema);
|
||||
free(pCreateTbReq->stbCfg.pTagSchema);
|
||||
|
|
|
@ -47,6 +47,11 @@ enum {
|
|||
CTG_RENT_STABLE,
|
||||
};
|
||||
|
||||
typedef struct SCTGDebug {
|
||||
int32_t lockDebug;
|
||||
} SCTGDebug;
|
||||
|
||||
|
||||
typedef struct SVgroupListCache {
|
||||
int32_t vgroupVersion;
|
||||
SHashObj *cache; // key:vgId, value:SVgroupInfo
|
||||
|
@ -134,20 +139,22 @@ typedef uint32_t (*tableNameHashFp)(const char *, uint32_t);
|
|||
#define CTG_RET(c) do { int32_t _code = c; if (_code != TSDB_CODE_SUCCESS) { terrno = _code; } return _code; } while (0)
|
||||
#define CTG_ERR_JRET(c) do { code = c; if (code != TSDB_CODE_SUCCESS) { terrno = code; goto _return; } } while (0)
|
||||
|
||||
#define CTG_LOCK_DEBUG(...) do { if (gCTGDebug.lockDebug) { qDebug(__VA_ARGS__); } } while (0)
|
||||
|
||||
#define TD_RWLATCH_WRITE_FLAG_COPY 0x40000000
|
||||
|
||||
#define CTG_LOCK(type, _lock) do { \
|
||||
if (CTG_READ == (type)) { \
|
||||
assert(atomic_load_32((_lock)) >= 0); \
|
||||
qDebug("CTG RLOCK%p:%d, %s:%d B", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
CTG_LOCK_DEBUG("CTG RLOCK%p:%d, %s:%d B", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
taosRLockLatch(_lock); \
|
||||
qDebug("CTG RLOCK%p:%d, %s:%d E", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
CTG_LOCK_DEBUG("CTG RLOCK%p:%d, %s:%d E", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
assert(atomic_load_32((_lock)) > 0); \
|
||||
} else { \
|
||||
assert(atomic_load_32((_lock)) >= 0); \
|
||||
qDebug("CTG WLOCK%p:%d, %s:%d B", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
CTG_LOCK_DEBUG("CTG WLOCK%p:%d, %s:%d B", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
taosWLockLatch(_lock); \
|
||||
qDebug("CTG WLOCK%p:%d, %s:%d E", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
CTG_LOCK_DEBUG("CTG WLOCK%p:%d, %s:%d E", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
assert(atomic_load_32((_lock)) == TD_RWLATCH_WRITE_FLAG_COPY); \
|
||||
} \
|
||||
} while (0)
|
||||
|
@ -155,15 +162,15 @@ typedef uint32_t (*tableNameHashFp)(const char *, uint32_t);
|
|||
#define CTG_UNLOCK(type, _lock) do { \
|
||||
if (CTG_READ == (type)) { \
|
||||
assert(atomic_load_32((_lock)) > 0); \
|
||||
qDebug("CTG RULOCK%p:%d, %s:%d B", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
CTG_LOCK_DEBUG("CTG RULOCK%p:%d, %s:%d B", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
taosRUnLockLatch(_lock); \
|
||||
qDebug("CTG RULOCK%p:%d, %s:%d E", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
CTG_LOCK_DEBUG("CTG RULOCK%p:%d, %s:%d E", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
assert(atomic_load_32((_lock)) >= 0); \
|
||||
} else { \
|
||||
assert(atomic_load_32((_lock)) == TD_RWLATCH_WRITE_FLAG_COPY); \
|
||||
qDebug("CTG WULOCK%p:%d, %s:%d B", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
CTG_LOCK_DEBUG("CTG WULOCK%p:%d, %s:%d B", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
taosWUnLockLatch(_lock); \
|
||||
qDebug("CTG WULOCK%p:%d, %s:%d E", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
CTG_LOCK_DEBUG("CTG WULOCK%p:%d, %s:%d E", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
assert(atomic_load_32((_lock)) >= 0); \
|
||||
} \
|
||||
} while (0)
|
||||
|
|
|
@ -20,6 +20,9 @@
|
|||
|
||||
SCatalogMgmt ctgMgmt = {0};
|
||||
|
||||
SCTGDebug gCTGDebug = {0};
|
||||
|
||||
|
||||
int32_t ctgGetDBVgroupFromCache(struct SCatalog* pCatalog, const char *dbName, SDBVgroupInfo **dbInfo, bool *inCache) {
|
||||
if (NULL == pCatalog->dbCache.cache) {
|
||||
*inCache = false;
|
||||
|
|
|
@ -374,6 +374,12 @@ typedef struct STaskParam {
|
|||
struct SUdfInfo *pUdfInfo;
|
||||
} STaskParam;
|
||||
|
||||
typedef struct SExchangeInfo {
|
||||
int32_t numOfSources;
|
||||
SEpSet *pEpset;
|
||||
int32_t bytes; // total load bytes from remote
|
||||
} SExchangeInfo;
|
||||
|
||||
typedef struct STableScanInfo {
|
||||
void *pTsdbReadHandle;
|
||||
int32_t numOfBlocks;
|
||||
|
@ -393,12 +399,9 @@ typedef struct STableScanInfo {
|
|||
SSDataBlock block;
|
||||
int32_t numOfOutput;
|
||||
int64_t elapsedTime;
|
||||
int32_t tableIndex;
|
||||
|
||||
int32_t prevGroupId; // previous table group id
|
||||
|
||||
int32_t scanFlag; // table scan flag to denote if it is a repeat/reverse/main scan
|
||||
STimeWindow window;
|
||||
} STableScanInfo;
|
||||
|
||||
typedef struct STagScanInfo {
|
||||
|
@ -542,8 +545,10 @@ typedef struct SOrderOperatorInfo {
|
|||
|
||||
void appendUpstream(SOperatorInfo* p, SOperatorInfo* pUpstream);
|
||||
|
||||
SOperatorInfo* createExchangeOperatorInfo(const SVgroupInfo* pVgroups, int32_t numOfSources, int32_t numOfOutput, SExecTaskInfo* pTaskInfo);
|
||||
|
||||
SOperatorInfo* createDataBlocksOptScanInfo(void* pTsdbReadHandle, int32_t order, int32_t numOfOutput, int32_t repeatTime, int32_t reverseTime, SExecTaskInfo* pTaskInfo);
|
||||
SOperatorInfo* createTableScanOperator(void* pTsdbReadHandle, int32_t order, int32_t numOfOutput, int32_t repeatTime, SExecTaskInfo* pTaskInfo);
|
||||
SOperatorInfo* createTableScanOperatorInfo(void* pTsdbReadHandle, int32_t order, int32_t numOfOutput, int32_t repeatTime, SExecTaskInfo* pTaskInfo);
|
||||
SOperatorInfo* createTableSeqScanOperator(void* pTsdbReadHandle, STaskRuntimeEnv* pRuntimeEnv);
|
||||
|
||||
SOperatorInfo* createAggregateOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||
|
|
|
@ -182,6 +182,12 @@ static void getDataLength(SDataSinkHandle* pHandle, int32_t* pLen, bool* pQueryE
|
|||
|
||||
static int32_t getDataBlock(SDataSinkHandle* pHandle, SOutputData* pOutput) {
|
||||
SDataDispatchHandle* pDispatcher = (SDataDispatchHandle*)pHandle;
|
||||
if (NULL == pDispatcher->nextOutput.pData) {
|
||||
assert(pDispatcher->queryEnd);
|
||||
pOutput->useconds = pDispatcher->useconds;
|
||||
pOutput->precision = pDispatcher->schema.precision;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
SDataCacheEntry* pEntry = (SDataCacheEntry*)(pDispatcher->nextOutput.pData);
|
||||
memcpy(pOutput->pData, pEntry->data, pEntry->dataLen);
|
||||
pOutput->numOfRows = pEntry->numOfRows;
|
||||
|
@ -190,7 +196,7 @@ static int32_t getDataBlock(SDataSinkHandle* pHandle, SOutputData* pOutput) {
|
|||
pOutput->bufStatus = updateStatus(pDispatcher);
|
||||
pthread_mutex_lock(&pDispatcher->mutex);
|
||||
pOutput->queryEnd = pDispatcher->queryEnd;
|
||||
pOutput->needSchedule = false;
|
||||
pOutput->scheduleJobNo = 0;
|
||||
pOutput->useconds = pDispatcher->useconds;
|
||||
pOutput->precision = pDispatcher->schema.precision;
|
||||
pthread_mutex_unlock(&pDispatcher->mutex);
|
||||
|
|
|
@ -178,8 +178,10 @@ int32_t qExecTask(qTaskInfo_t tinfo, DataSinkHandle* handle) {
|
|||
publishOperatorProfEvent(pTaskInfo->pRoot, QUERY_PROF_BEFORE_OPERATOR_EXEC);
|
||||
int64_t st = 0;
|
||||
|
||||
*handle = pTaskInfo->dsHandle;
|
||||
|
||||
if (handle) {
|
||||
*handle = pTaskInfo->dsHandle;
|
||||
}
|
||||
|
||||
while(1) {
|
||||
st = taosGetTimestampUs();
|
||||
SSDataBlock* pRes = pTaskInfo->pRoot->exec(pTaskInfo->pRoot, &newgroup);
|
||||
|
|
|
@ -3564,8 +3564,6 @@ static void setupEnvForReverseScan(STableScanInfo *pTableScanInfo, SQLFunctionCt
|
|||
// }
|
||||
|
||||
// reverse order time range
|
||||
SWAP(pTableScanInfo->window.skey, pTableScanInfo->window.ekey, TSKEY);
|
||||
|
||||
SET_REVERSE_SCAN_FLAG(pTableScanInfo);
|
||||
// setTaskStatus(pTableScanInfo, QUERY_NOT_COMPLETED);
|
||||
|
||||
|
@ -4913,10 +4911,86 @@ static SSDataBlock* doBlockInfoScan(void* param, bool* newgroup) {
|
|||
pOperator->status = OP_EXEC_DONE;
|
||||
return pBlock;
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t loadRemoteDataCallback(void* param, const SDataBuf* pMsg, int32_t code) {
|
||||
|
||||
}
|
||||
|
||||
SOperatorInfo* createTableScanOperator(void* pTsdbReadHandle, int32_t order, int32_t numOfOutput, int32_t repeatTime, SExecTaskInfo* pTaskInfo) {
|
||||
static SSDataBlock* doLoadRemoteData(void* param, bool* newgroup) {
|
||||
SOperatorInfo* pOperator = (SOperatorInfo*) param;
|
||||
|
||||
SExchangeInfo *pExchangeInfo = pOperator->info;
|
||||
SExecTaskInfo *pTaskInfo = pOperator->pTaskInfo;
|
||||
|
||||
*newgroup = false;
|
||||
|
||||
SResFetchReq *pMsg = calloc(1, sizeof(SResFetchReq));
|
||||
if (NULL == pMsg) { // todo handle malloc error
|
||||
|
||||
}
|
||||
|
||||
SEpSet epSet;
|
||||
|
||||
int64_t sId = -1, queryId = 0, taskId = 1, vgId = 1;
|
||||
pMsg->header.vgId = htonl(vgId);
|
||||
|
||||
pMsg->sId = htobe64(sId);
|
||||
pMsg->taskId = htobe64(taskId);
|
||||
pMsg->queryId = htobe64(queryId);
|
||||
|
||||
// send the fetch remote task result reques
|
||||
SMsgSendInfo* pMsgSendInfo = calloc(1, sizeof(SMsgSendInfo));
|
||||
if (NULL == pMsgSendInfo) {
|
||||
qError("QID:%"PRIx64 ",TID:%"PRIx64 " calloc %d failed", queryId, taskId, (int32_t)sizeof(SMsgSendInfo));
|
||||
}
|
||||
|
||||
pMsgSendInfo->param = NULL;
|
||||
pMsgSendInfo->msgInfo.pData = pMsg;
|
||||
pMsgSendInfo->msgInfo.len = sizeof(SResFetchReq);
|
||||
pMsgSendInfo->msgType = TDMT_VND_FETCH;
|
||||
pMsgSendInfo->fp = loadRemoteDataCallback;
|
||||
|
||||
int64_t transporterId = 0;
|
||||
void* pTransporter = NULL;
|
||||
int32_t code = asyncSendMsgToServer(pTransporter, &epSet, &transporterId, pMsgSendInfo);
|
||||
|
||||
printf("abc\n");
|
||||
getchar();
|
||||
|
||||
// add it into the sink node
|
||||
|
||||
}
|
||||
|
||||
SOperatorInfo* createExchangeOperatorInfo(const SVgroupInfo* pVgroups, int32_t numOfSources, int32_t numOfOutput, SExecTaskInfo* pTaskInfo) {
|
||||
assert(numOfSources > 0);
|
||||
|
||||
SExchangeInfo* pInfo = calloc(1, sizeof(SExchangeInfo));
|
||||
SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo));
|
||||
|
||||
if (pInfo == NULL || pOperator == NULL) {
|
||||
tfree(pInfo);
|
||||
tfree(pOperator);
|
||||
terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pInfo->numOfSources = numOfSources;
|
||||
|
||||
pOperator->name = "ExchangeOperator";
|
||||
pOperator->operatorType = OP_Exchange;
|
||||
pOperator->blockingOptr = false;
|
||||
pOperator->status = OP_IN_EXECUTING;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->numOfOutput = numOfOutput;
|
||||
pOperator->pRuntimeEnv = NULL;
|
||||
pOperator->exec = doLoadRemoteData;
|
||||
pOperator->pTaskInfo = pTaskInfo;
|
||||
|
||||
return pOperator;
|
||||
}
|
||||
|
||||
SOperatorInfo* createTableScanOperatorInfo(void* pTsdbReadHandle, int32_t order, int32_t numOfOutput, int32_t repeatTime, SExecTaskInfo* pTaskInfo) {
|
||||
assert(repeatTime > 0 && numOfOutput > 0);
|
||||
|
||||
STableScanInfo* pInfo = calloc(1, sizeof(STableScanInfo));
|
||||
|
@ -4995,7 +5069,7 @@ SOperatorInfo* createTableSeqScanOperator(void* pTsdbReadHandle, STaskRuntimeEnv
|
|||
|
||||
SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo));
|
||||
pOperator->name = "TableSeqScanOperator";
|
||||
// pOperator->operatorType = OP_TableSeqScan;
|
||||
pOperator->operatorType = OP_TableSeqScan;
|
||||
pOperator->blockingOptr = false;
|
||||
pOperator->status = OP_IN_EXECUTING;
|
||||
pOperator->info = pInfo;
|
||||
|
@ -7284,7 +7358,7 @@ SOperatorInfo* doCreateOperatorTreeNode(SPhyNode* pPhyNode, SExecTaskInfo* pTask
|
|||
if (pPhyNode->info.type == OP_TableScan) {
|
||||
SScanPhyNode* pScanPhyNode = (SScanPhyNode*)pPhyNode;
|
||||
size_t numOfCols = taosArrayGetSize(pPhyNode->pTargets);
|
||||
return createTableScanOperator(param, pScanPhyNode->order, numOfCols, pScanPhyNode->count, pTaskInfo);
|
||||
return createTableScanOperatorInfo(param, pScanPhyNode->order, numOfCols, pScanPhyNode->count, pTaskInfo);
|
||||
} else if (pPhyNode->info.type == OP_DataBlocksOptScan) {
|
||||
SScanPhyNode* pScanPhyNode = (SScanPhyNode*)pPhyNode;
|
||||
size_t numOfCols = taosArrayGetSize(pPhyNode->pTargets);
|
||||
|
@ -7308,6 +7382,7 @@ int32_t doCreateExecTaskInfo(SSubplan* pPlan, SExecTaskInfo** pTaskInfo, void* r
|
|||
cond.numOfCols = taosArrayGetSize(pTableScanNode->scan.node.pTargets);
|
||||
cond.colList = calloc(cond.numOfCols, sizeof(SColumnInfo));
|
||||
cond.twindow = pTableScanNode->window;
|
||||
cond.type = BLOCK_LOAD_OFFSET_SEQ_ORDER;
|
||||
|
||||
for(int32_t i = 0; i < cond.numOfCols; ++i) {
|
||||
SExprInfo* pExprInfo = taosArrayGetP(pTableScanNode->scan.node.pTargets, i);
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
SCreateUserReq* buildUserManipulationMsg(SSqlInfo* pInfo, int32_t* outputLen, int64_t id, char* msgBuf, int32_t msgLen);
|
||||
SCreateAcctReq* buildAcctManipulationMsg(SSqlInfo* pInfo, int32_t* outputLen, int64_t id, char* msgBuf, int32_t msgLen);
|
||||
SDropUserReq* buildDropUserMsg(SSqlInfo* pInfo, int32_t* outputLen, int64_t id, char* msgBuf, int32_t msgLen);
|
||||
SShowReq* buildShowMsg(SShowInfo* pShowInfo, SParseContext* pParseCtx, char* msgBuf, int32_t msgLen);
|
||||
SShowReq* buildShowMsg(SShowInfo* pShowInfo, SParseContext* pParseCtx, SMsgBuf* pMsgBuf);
|
||||
SCreateDbReq* buildCreateDbMsg(SCreateDbInfo* pCreateDbInfo, SParseContext *pCtx, SMsgBuf* pMsgBuf);
|
||||
SMCreateStbReq* buildCreateStbMsg(SCreateTableSql* pCreateTableSql, int32_t* len, SParseContext* pParseCtx, SMsgBuf* pMsgBuf);
|
||||
SMDropStbReq* buildDropStableMsg(SSqlInfo* pInfo, int32_t* len, SParseContext* pParseCtx, SMsgBuf* pMsgBuf);
|
||||
|
|
|
@ -972,14 +972,15 @@ void tSetDbName(SToken *pCpxName, SToken *pDb) {
|
|||
void tSetColumnInfo(SField *pField, SToken *pName, SField *pType) {
|
||||
int32_t maxLen = sizeof(pField->name) / sizeof(pField->name[0]);
|
||||
|
||||
// column name is too long, set the it to be invalid.
|
||||
// The column name is too long, set it to be invalid.
|
||||
if ((int32_t) pName->n >= maxLen) {
|
||||
pName->n = -1;
|
||||
pField->name[0] = 0;
|
||||
} else {
|
||||
strncpy(pField->name, pName->z, pName->n);
|
||||
pField->name[pName->n] = 0;
|
||||
}
|
||||
|
||||
// denote an invalid data type in the column definition.
|
||||
pField->type = pType->type;
|
||||
if(!isValidDataType(pField->type)){
|
||||
pField->bytes = 0;
|
||||
|
|
|
@ -85,8 +85,12 @@ SDropUserReq* buildDropUserMsg(SSqlInfo* pInfo, int32_t *msgLen, int64_t id, cha
|
|||
return pMsg;
|
||||
}
|
||||
|
||||
SShowReq* buildShowMsg(SShowInfo* pShowInfo, SParseContext *pCtx, char* msgBuf, int32_t msgLen) {
|
||||
SShowReq* buildShowMsg(SShowInfo* pShowInfo, SParseContext *pCtx, SMsgBuf* pMsgBuf) {
|
||||
SShowReq* pShowMsg = calloc(1, sizeof(SShowReq));
|
||||
if (pShowMsg == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return pShowMsg;
|
||||
}
|
||||
|
||||
pShowMsg->type = pShowInfo->showType;
|
||||
if (pShowInfo->showType != TSDB_MGMT_TABLE_VNODES) {
|
||||
|
@ -105,7 +109,22 @@ SShowReq* buildShowMsg(SShowInfo* pShowInfo, SParseContext *pCtx, char* msgBuf,
|
|||
|
||||
if (pShowInfo->showType == TSDB_MGMT_TABLE_STB || pShowInfo->showType == TSDB_MGMT_TABLE_VGROUP) {
|
||||
SName n = {0};
|
||||
tNameSetDbName(&n, pCtx->acctId, pCtx->db, strlen(pCtx->db));
|
||||
|
||||
if (pShowInfo->prefix.n > 0) {
|
||||
if (pShowInfo->prefix.n >= TSDB_DB_FNAME_LEN) {
|
||||
terrno = buildInvalidOperationMsg(pMsgBuf, "prefix name is too long");
|
||||
tfree(pShowMsg);
|
||||
return NULL;
|
||||
}
|
||||
tNameSetDbName(&n, pCtx->acctId, pShowInfo->prefix.z, pShowInfo->prefix.n);
|
||||
} else if (pCtx->db == NULL || strlen(pCtx->db) == 0) {
|
||||
terrno = buildInvalidOperationMsg(pMsgBuf, "database is not specified");
|
||||
tfree(pShowMsg);
|
||||
return NULL;
|
||||
} else {
|
||||
tNameSetDbName(&n, pCtx->acctId, pCtx->db, strlen(pCtx->db));
|
||||
}
|
||||
|
||||
tNameGetFullDbName(&n, pShowMsg->db);
|
||||
}
|
||||
|
||||
|
@ -240,6 +259,9 @@ SMCreateStbReq* buildCreateStbMsg(SCreateTableSql* pCreateTableSql, int32_t* len
|
|||
}
|
||||
|
||||
SMCreateStbReq* pCreateStbMsg = (SMCreateStbReq*)calloc(1, sizeof(SMCreateStbReq) + (numOfCols + numOfTags) * sizeof(SSchema));
|
||||
if (pCreateStbMsg == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char* pMsg = NULL;
|
||||
#if 0
|
||||
|
|
|
@ -109,7 +109,11 @@ static int32_t setShowInfo(SShowInfo* pShowInfo, SParseContext* pCtx, void** out
|
|||
}
|
||||
|
||||
*pEpSet = pCtx->mgmtEpSet;
|
||||
*output = buildShowMsg(pShowInfo, pCtx, pMsgBuf->buf, pMsgBuf->len);
|
||||
*output = buildShowMsg(pShowInfo, pCtx, pMsgBuf);
|
||||
if (*output == NULL) {
|
||||
return terrno;
|
||||
}
|
||||
|
||||
*outputLen = sizeof(SShowReq) /* + htons(pShowMsg->payloadLen)*/;
|
||||
}
|
||||
|
||||
|
@ -312,9 +316,9 @@ int32_t doCheckForCreateTable(SCreateTableSql* pCreateTable, SMsgBuf* pMsgBuf) {
|
|||
assert(pFieldList != NULL);
|
||||
|
||||
// if sql specifies db, use it, otherwise use default db
|
||||
SToken* pzTableName = &(pCreateTable->name);
|
||||
SToken* pNameToken = &(pCreateTable->name);
|
||||
|
||||
if (parserValidateNameToken(pzTableName) != TSDB_CODE_SUCCESS) {
|
||||
if (parserValidateIdToken(pNameToken) != TSDB_CODE_SUCCESS) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg1);
|
||||
}
|
||||
|
||||
|
@ -973,6 +977,7 @@ SVnodeModifOpStmtInfo* qParserValidateCreateTbSqlNode(SSqlInfo* pInfo, SParseCon
|
|||
int32_t msgLen = 0;
|
||||
int32_t code = doCheckAndBuildCreateTableReq(pCreateTable, pCtx, pMsgBuf, (char**) &pModifSqlStmt, &msgLen);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
terrno = code;
|
||||
tfree(pModifSqlStmt);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -124,12 +124,13 @@ int32_t parserValidatePassword(SToken* pToken, SMsgBuf* pMsgBuf) {
|
|||
}
|
||||
|
||||
int32_t parserValidateNameToken(SToken* pToken) {
|
||||
if (pToken == NULL || pToken->z == NULL || pToken->type != TK_ID) {
|
||||
if (pToken == NULL || pToken->z == NULL || pToken->type != TK_ID || pToken->n == 0) {
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
// it is a token quoted with escape char '`'
|
||||
if (pToken->z[0] == TS_ESCAPE_CHAR && pToken->z[pToken->n - 1] == TS_ESCAPE_CHAR) {
|
||||
pToken->n = strdequote(pToken->z);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1945,17 +1946,30 @@ int32_t KvRowAppend(const void *value, int32_t len, void *param) {
|
|||
|
||||
int32_t createSName(SName* pName, SToken* pTableName, SParseContext* pParseCtx, SMsgBuf* pMsgBuf) {
|
||||
const char* msg1 = "name too long";
|
||||
const char* msg2 = "invalid database name";
|
||||
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
char* p = strnchr(pTableName->z, TS_PATH_DELIMITER[0], pTableName->n, false);
|
||||
char* p = strnchr(pTableName->z, TS_PATH_DELIMITER[0], pTableName->n, true);
|
||||
|
||||
if (p != NULL) { // db has been specified in sql string so we ignore current db path
|
||||
tNameSetAcctId(pName, pParseCtx->acctId);
|
||||
assert(*p == TS_PATH_DELIMITER[0]);
|
||||
|
||||
char name[TSDB_TABLE_FNAME_LEN] = {0};
|
||||
strncpy(name, pTableName->z, pTableName->n);
|
||||
int32_t dbLen = p - pTableName->z;
|
||||
char name[TSDB_DB_FNAME_LEN] = {0};
|
||||
strncpy(name, pTableName->z, dbLen);
|
||||
dbLen = strdequote(name);
|
||||
|
||||
code = tNameFromString(pName, name, T_NAME_DB|T_NAME_TABLE);
|
||||
code = tNameSetDbName(pName, pParseCtx->acctId, name, dbLen);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg1);
|
||||
}
|
||||
|
||||
int32_t tbLen = pTableName->n - dbLen - 1;
|
||||
char tbname[TSDB_TABLE_FNAME_LEN] = {0};
|
||||
strncpy(tbname, p + 1, tbLen);
|
||||
/*tbLen = */strdequote(tbname);
|
||||
|
||||
code = tNameFromString(pName, tbname, T_NAME_TABLE);
|
||||
if (code != 0) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg1);
|
||||
}
|
||||
|
@ -1964,10 +1978,17 @@ int32_t createSName(SName* pName, SToken* pTableName, SParseContext* pParseCtx,
|
|||
return buildInvalidOperationMsg(pMsgBuf, msg1);
|
||||
}
|
||||
|
||||
tNameSetDbName(pName, pParseCtx->acctId, pParseCtx->db, strlen(pParseCtx->db));
|
||||
assert(pTableName->n < TSDB_TABLE_FNAME_LEN);
|
||||
|
||||
char name[TSDB_TABLE_FNAME_LEN] = {0};
|
||||
strncpy(name, pTableName->z, pTableName->n);
|
||||
strdequote(name);
|
||||
|
||||
code = tNameSetDbName(pName, pParseCtx->acctId, pParseCtx->db, strlen(pParseCtx->db));
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
code = buildInvalidOperationMsg(pMsgBuf, msg2);
|
||||
return code;
|
||||
}
|
||||
|
||||
code = tNameFromString(pName, name, T_NAME_TABLE);
|
||||
if (code != 0) {
|
||||
|
|
|
@ -30,7 +30,8 @@ static void copyString(const cJSON* json, const char* name, char* dst) {
|
|||
}
|
||||
|
||||
static int64_t getNumber(const cJSON* json, const char* name) {
|
||||
return cJSON_GetNumberValue(cJSON_GetObjectItem(json, name));
|
||||
double d = cJSON_GetNumberValue(cJSON_GetObjectItem(json, name));
|
||||
return (int64_t) d;
|
||||
}
|
||||
|
||||
static bool addObject(cJSON* json, const char* name, FToJson func, const void* obj) {
|
||||
|
@ -541,17 +542,27 @@ static const char* jkTimeWindowEndKey = "EndKey";
|
|||
|
||||
static bool timeWindowToJson(const void* obj, cJSON* json) {
|
||||
const STimeWindow* win = (const STimeWindow*)obj;
|
||||
bool res = cJSON_AddNumberToObject(json, jkTimeWindowStartKey, win->skey);
|
||||
|
||||
char tmp[32] = {0};
|
||||
sprintf(tmp, "%"PRId64, win->skey);
|
||||
|
||||
bool res = cJSON_AddStringToObject(json, jkTimeWindowStartKey, tmp);
|
||||
if (res) {
|
||||
res = cJSON_AddNumberToObject(json, jkTimeWindowEndKey, win->ekey);
|
||||
memset(tmp, 0, tListLen(tmp));
|
||||
sprintf(tmp, "%"PRId64, win->ekey);
|
||||
res = cJSON_AddStringToObject(json, jkTimeWindowEndKey, tmp);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static bool timeWindowFromJson(const cJSON* json, void* obj) {
|
||||
STimeWindow* win = (STimeWindow*)obj;
|
||||
win->skey = getNumber(json, jkTimeWindowStartKey);
|
||||
win->ekey = getNumber(json, jkTimeWindowEndKey);
|
||||
|
||||
char* p = getString(json, jkTimeWindowStartKey);
|
||||
win->skey = strtoll(p, NULL, 10);
|
||||
|
||||
p = getString(json, jkTimeWindowEndKey);
|
||||
win->ekey = strtoll(p, NULL, 10);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -65,9 +65,9 @@ int32_t qCreateQueryDag(const struct SQueryNode* pNode, struct SQueryDag** pDag,
|
|||
}
|
||||
|
||||
if (pLogicPlan->info.type != QNODE_MODIFY) {
|
||||
// char* str = NULL;
|
||||
// queryPlanToString(pLogicPlan, &str);
|
||||
// printf("%s\n", str);
|
||||
char* str = NULL;
|
||||
queryPlanToString(pLogicPlan, &str);
|
||||
printf("%s\n", str);
|
||||
}
|
||||
|
||||
code = optimizeQueryPlan(pLogicPlan);
|
||||
|
|
|
@ -23,18 +23,34 @@ extern "C" {
|
|||
#include "tlockfree.h"
|
||||
|
||||
#define QWORKER_DEFAULT_SCHEDULER_NUMBER 10000
|
||||
#define QWORKER_DEFAULT_RES_CACHE_NUMBER 10000
|
||||
#define QWORKER_DEFAULT_TASK_NUMBER 10000
|
||||
#define QWORKER_DEFAULT_SCH_TASK_NUMBER 10000
|
||||
|
||||
enum {
|
||||
QW_READY_NOT_RECEIVED = 0,
|
||||
QW_READY_RECEIVED,
|
||||
QW_READY_RESPONSED,
|
||||
QW_PHASE_PRE_QUERY = 1,
|
||||
QW_PHASE_POST_QUERY,
|
||||
QW_PHASE_PRE_CQUERY,
|
||||
QW_PHASE_POST_CQUERY,
|
||||
QW_PHASE_PRE_SINK,
|
||||
QW_PHASE_POST_SINK,
|
||||
QW_PHASE_PRE_FETCH,
|
||||
QW_PHASE_POST_FETCH,
|
||||
};
|
||||
|
||||
enum {
|
||||
QW_TASK_INFO_STATUS = 1,
|
||||
QW_TASK_INFO_READY,
|
||||
QW_EVENT_CANCEL = 1,
|
||||
QW_EVENT_READY,
|
||||
QW_EVENT_FETCH,
|
||||
QW_EVENT_DROP,
|
||||
QW_EVENT_CQUERY,
|
||||
|
||||
QW_EVENT_MAX,
|
||||
};
|
||||
|
||||
enum {
|
||||
QW_EVENT_NOT_RECEIVED = 0,
|
||||
QW_EVENT_RECEIVED,
|
||||
QW_EVENT_PROCESSED,
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -57,22 +73,48 @@ enum {
|
|||
QW_ADD_ACQUIRE,
|
||||
};
|
||||
|
||||
typedef struct SQWDebug {
|
||||
int32_t lockDebug;
|
||||
} SQWDebug;
|
||||
|
||||
typedef struct SQWMsg {
|
||||
void *node;
|
||||
char *msg;
|
||||
int32_t msgLen;
|
||||
void *connection;
|
||||
} SQWMsg;
|
||||
|
||||
typedef struct SQWPhaseInput {
|
||||
int8_t status;
|
||||
int32_t code;
|
||||
qTaskInfo_t taskHandle;
|
||||
DataSinkHandle sinkHandle;
|
||||
} SQWPhaseInput;
|
||||
|
||||
typedef struct SQWPhaseOutput {
|
||||
int32_t rspCode;
|
||||
bool needStop;
|
||||
bool needRsp;
|
||||
} SQWPhaseOutput;
|
||||
|
||||
|
||||
typedef struct SQWTaskStatus {
|
||||
SRWLatch lock;
|
||||
int32_t code;
|
||||
int8_t status;
|
||||
int8_t ready;
|
||||
bool cancel;
|
||||
bool drop;
|
||||
} SQWTaskStatus;
|
||||
|
||||
typedef struct SQWorkerTaskHandlesCache {
|
||||
typedef struct SQWTaskCtx {
|
||||
SRWLatch lock;
|
||||
bool needRsp;
|
||||
int32_t phase;
|
||||
|
||||
int32_t sinkId;
|
||||
int32_t readyCode;
|
||||
|
||||
int8_t events[QW_EVENT_MAX];
|
||||
|
||||
qTaskInfo_t taskHandle;
|
||||
DataSinkHandle sinkHandle;
|
||||
} SQWorkerTaskHandlesCache;
|
||||
} SQWTaskCtx;
|
||||
|
||||
typedef struct SQWSchStatus {
|
||||
int32_t lastAccessTs; // timestamp in second
|
||||
|
@ -82,53 +124,89 @@ typedef struct SQWSchStatus {
|
|||
|
||||
// Qnode/Vnode level task management
|
||||
typedef struct SQWorkerMgmt {
|
||||
SQWorkerCfg cfg;
|
||||
SRWLatch schLock;
|
||||
SRWLatch resLock;
|
||||
SHashObj *schHash; //key: schedulerId, value: SQWSchStatus
|
||||
SHashObj *resHash; //key: queryId+taskId, value: SQWorkerResCache
|
||||
SQWorkerCfg cfg;
|
||||
int8_t nodeType;
|
||||
int32_t nodeId;
|
||||
SRWLatch schLock;
|
||||
SRWLatch ctxLock;
|
||||
SHashObj *schHash; //key: schedulerId, value: SQWSchStatus
|
||||
SHashObj *ctxHash; //key: queryId+taskId, value: SQWTaskCtx
|
||||
void *nodeObj;
|
||||
putReqToQueryQFp putToQueueFp;
|
||||
} SQWorkerMgmt;
|
||||
|
||||
#define QW_GOT_RES_DATA(data) (true)
|
||||
#define QW_LOW_RES_DATA(data) (false)
|
||||
#define QW_FPARAMS_DEF SQWorkerMgmt *mgmt, uint64_t sId, uint64_t qId, uint64_t tId
|
||||
#define QW_IDS() sId, qId, tId
|
||||
#define QW_FPARAMS() mgmt, QW_IDS()
|
||||
|
||||
#define QW_IS_EVENT_RECEIVED(ctx, event) (atomic_load_8(&(ctx)->events[event]) == QW_EVENT_RECEIVED)
|
||||
#define QW_IS_EVENT_PROCESSED(ctx, event) (atomic_load_8(&(ctx)->events[event]) == QW_EVENT_PROCESSED)
|
||||
#define QW_SET_EVENT_RECEIVED(ctx, event) atomic_store_8(&(ctx)->events[event], QW_EVENT_RECEIVED)
|
||||
#define QW_SET_EVENT_PROCESSED(ctx, event) atomic_store_8(&(ctx)->events[event], QW_EVENT_PROCESSED)
|
||||
|
||||
#define QW_IN_EXECUTOR(ctx) ((ctx)->phase == QW_PHASE_PRE_QUERY || (ctx)->phase == QW_PHASE_PRE_CQUERY || (ctx)->phase == QW_PHASE_PRE_FETCH || (ctx)->phase == QW_PHASE_PRE_SINK)
|
||||
|
||||
#define QW_TASK_NOT_EXIST(code) (TSDB_CODE_QRY_SCH_NOT_EXIST == (code) || TSDB_CODE_QRY_TASK_NOT_EXIST == (code))
|
||||
#define QW_TASK_ALREADY_EXIST(code) (TSDB_CODE_QRY_TASK_ALREADY_EXIST == (code))
|
||||
#define QW_TASK_READY_RESP(status) (status == JOB_TASK_STATUS_SUCCEED || status == JOB_TASK_STATUS_FAILED || status == JOB_TASK_STATUS_CANCELLED || status == JOB_TASK_STATUS_PARTIAL_SUCCEED)
|
||||
#define QW_SET_QTID(id, qid, tid) do { *(uint64_t *)(id) = (qid); *(uint64_t *)((char *)(id) + sizeof(qid)) = (tid); } while (0)
|
||||
#define QW_GET_QTID(id, qid, tid) do { (qid) = *(uint64_t *)(id); (tid) = *(uint64_t *)((char *)(id) + sizeof(qid)); } while (0)
|
||||
|
||||
#define QW_TASK_READY(status) (status == JOB_TASK_STATUS_SUCCEED || status == JOB_TASK_STATUS_FAILED || status == JOB_TASK_STATUS_CANCELLED || status == JOB_TASK_STATUS_PARTIAL_SUCCEED)
|
||||
#define QW_SET_QTID(id, qId, tId) do { *(uint64_t *)(id) = (qId); *(uint64_t *)((char *)(id) + sizeof(qId)) = (tId); } while (0)
|
||||
#define QW_GET_QTID(id, qId, tId) do { (qId) = *(uint64_t *)(id); (tId) = *(uint64_t *)((char *)(id) + sizeof(qId)); } while (0)
|
||||
|
||||
#define QW_ERR_RET(c) do { int32_t _code = c; if (_code != TSDB_CODE_SUCCESS) { terrno = _code; return _code; } } while (0)
|
||||
#define QW_RET(c) do { int32_t _code = c; if (_code != TSDB_CODE_SUCCESS) { terrno = _code; } return _code; } while (0)
|
||||
#define QW_ERR_LRET(c,...) do { int32_t _code = c; if (_code != TSDB_CODE_SUCCESS) { qError(__VA_ARGS__); terrno = _code; return _code; } } while (0)
|
||||
#define QW_ERR_JRET(c) do { code = c; if (code != TSDB_CODE_SUCCESS) { terrno = code; goto _return; } } while (0)
|
||||
|
||||
#define QW_ELOG(param, ...) qError("QW:%p " param, mgmt, __VA_ARGS__)
|
||||
#define QW_DLOG(param, ...) qDebug("QW:%p " param, mgmt, __VA_ARGS__)
|
||||
|
||||
#define QW_SCH_ELOG(param, ...) qError("QW:%p SID:%"PRIx64" " param, mgmt, sId, __VA_ARGS__)
|
||||
#define QW_SCH_DLOG(param, ...) qDebug("QW:%p SID:%"PRIx64" " param, mgmt, sId, __VA_ARGS__)
|
||||
|
||||
#define QW_TASK_ELOG(param, ...) qError("QW:%p QID:%"PRIx64",TID:%"PRIx64" " param, mgmt, qId, tId, __VA_ARGS__)
|
||||
#define QW_TASK_WLOG(param, ...) qWarn("QW:%p QID:%"PRIx64",TID:%"PRIx64" " param, mgmt, qId, tId, __VA_ARGS__)
|
||||
#define QW_TASK_DLOG(param, ...) qDebug("QW:%p QID:%"PRIx64",TID:%"PRIx64" " param, mgmt, qId, tId, __VA_ARGS__)
|
||||
|
||||
#define QW_SCH_TASK_ELOG(param, ...) qError("QW:%p SID:%"PRIx64",QID:%"PRIx64",TID:%"PRIx64" " param, mgmt, sId, qId, tId, __VA_ARGS__)
|
||||
#define QW_SCH_TASK_WLOG(param, ...) qWarn("QW:%p SID:%"PRIx64",QID:%"PRIx64",TID:%"PRIx64" " param, mgmt, sId, qId, tId, __VA_ARGS__)
|
||||
#define QW_SCH_TASK_DLOG(param, ...) qDebug("QW:%p SID:%"PRIx64",QID:%"PRIx64",TID:%"PRIx64" " param, mgmt, sId, qId, tId, __VA_ARGS__)
|
||||
|
||||
#define QW_LOCK_DEBUG(...) do { if (gQWDebug.lockDebug) { qDebug(__VA_ARGS__); } } while (0)
|
||||
|
||||
#define TD_RWLATCH_WRITE_FLAG_COPY 0x40000000
|
||||
|
||||
#define QW_LOCK(type, _lock) do { \
|
||||
if (QW_READ == (type)) { \
|
||||
if ((*(_lock)) < 0) assert(0); \
|
||||
taosRLockLatch(_lock); \
|
||||
qDebug("QW RLOCK%p, %s:%d", (_lock), __FILE__, __LINE__); \
|
||||
assert(atomic_load_32((_lock)) >= 0); \
|
||||
QW_LOCK_DEBUG("QW RLOCK%p:%d, %s:%d B", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
taosRLockLatch(_lock); \
|
||||
QW_LOCK_DEBUG("QW RLOCK%p:%d, %s:%d E", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
assert(atomic_load_32((_lock)) > 0); \
|
||||
} else { \
|
||||
if ((*(_lock)) < 0) assert(0); \
|
||||
assert(atomic_load_32((_lock)) >= 0); \
|
||||
QW_LOCK_DEBUG("QW WLOCK%p:%d, %s:%d B", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
taosWLockLatch(_lock); \
|
||||
qDebug("QW WLOCK%p, %s:%d", (_lock), __FILE__, __LINE__); \
|
||||
QW_LOCK_DEBUG("QW WLOCK%p:%d, %s:%d E", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
assert(atomic_load_32((_lock)) == TD_RWLATCH_WRITE_FLAG_COPY); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define QW_UNLOCK(type, _lock) do { \
|
||||
if (QW_READ == (type)) { \
|
||||
if ((*(_lock)) <= 0) assert(0); \
|
||||
assert(atomic_load_32((_lock)) > 0); \
|
||||
QW_LOCK_DEBUG("QW RULOCK%p:%d, %s:%d B", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
taosRUnLockLatch(_lock); \
|
||||
qDebug("QW RULOCK%p, %s:%d", (_lock), __FILE__, __LINE__); \
|
||||
QW_LOCK_DEBUG("QW RULOCK%p:%d, %s:%d E", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
assert(atomic_load_32((_lock)) >= 0); \
|
||||
} else { \
|
||||
if ((*(_lock)) <= 0) assert(0); \
|
||||
assert(atomic_load_32((_lock)) == TD_RWLATCH_WRITE_FLAG_COPY); \
|
||||
QW_LOCK_DEBUG("QW WULOCK%p:%d, %s:%d B", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
taosWUnLockLatch(_lock); \
|
||||
qDebug("QW WULOCK%p, %s:%d", (_lock), __FILE__, __LINE__); \
|
||||
QW_LOCK_DEBUG("QW WULOCK%p:%d, %s:%d E", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
assert(atomic_load_32((_lock)) >= 0); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static int32_t qwAcquireScheduler(int32_t rwType, SQWorkerMgmt *mgmt, uint64_t sId, SQWSchStatus **sch, int32_t nOpt);
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* 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_QWORKER_MSG_H_
|
||||
#define _TD_QWORKER_MSG_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "qworkerInt.h"
|
||||
#include "dataSinkMgt.h"
|
||||
|
||||
int32_t qwProcessQuery(SQWorkerMgmt *mgmt, uint64_t sId, uint64_t qId, uint64_t tId, SQWMsg *qwMsg);
|
||||
int32_t qwProcessCQuery(SQWorkerMgmt *mgmt, uint64_t sId, uint64_t qId, uint64_t tId, SQWMsg *qwMsg);
|
||||
int32_t qwProcessReady(SQWorkerMgmt *mgmt, uint64_t sId, uint64_t qId, uint64_t tId, SQWMsg *qwMsg);
|
||||
int32_t qwProcessFetch(SQWorkerMgmt *mgmt, uint64_t sId, uint64_t qId, uint64_t tId, SQWMsg *qwMsg);
|
||||
int32_t qwProcessDrop(SQWorkerMgmt *mgmt, uint64_t sId, uint64_t qId, uint64_t tId, SQWMsg *qwMsg);
|
||||
|
||||
int32_t qwBuildAndSendDropRsp(void *connection, int32_t code);
|
||||
int32_t qwBuildAndSendFetchRsp(void *connection, SRetrieveTableRsp *pRsp, int32_t dataLength, int32_t code);
|
||||
void qwBuildFetchRsp(void *msg, SOutputData *input, int32_t len);
|
||||
int32_t qwBuildAndSendCQueryMsg(SQWorkerMgmt *mgmt, uint64_t sId, uint64_t qId, uint64_t tId, void *connection);
|
||||
int32_t qwBuildAndSendSchSinkMsg(SQWorkerMgmt *mgmt, uint64_t sId, uint64_t qId, uint64_t tId, void *connection);
|
||||
int32_t qwBuildAndSendReadyRsp(void *connection, int32_t code);
|
||||
int32_t qwBuildAndSendQueryRsp(void *connection, int32_t code);
|
||||
void qwFreeFetchRsp(void *msg);
|
||||
int32_t qwMallocFetchRsp(int32_t length, SRetrieveTableRsp **rsp);
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_TD_QWORKER_INT_H_*/
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,553 @@
|
|||
#include "qworker.h"
|
||||
#include <common.h>
|
||||
#include "executor.h"
|
||||
#include "planner.h"
|
||||
#include "query.h"
|
||||
#include "qworkerInt.h"
|
||||
#include "qworkerMsg.h"
|
||||
#include "tmsg.h"
|
||||
#include "tname.h"
|
||||
#include "dataSinkMgt.h"
|
||||
|
||||
|
||||
int32_t qwMallocFetchRsp(int32_t length, SRetrieveTableRsp **rsp) {
|
||||
int32_t msgSize = sizeof(SRetrieveTableRsp) + length;
|
||||
|
||||
SRetrieveTableRsp *pRsp = (SRetrieveTableRsp *)rpcMallocCont(msgSize);
|
||||
if (NULL == pRsp) {
|
||||
qError("rpcMallocCont %d failed", msgSize);
|
||||
QW_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
memset(pRsp, 0, sizeof(SRetrieveTableRsp));
|
||||
|
||||
*rsp = pRsp;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void qwBuildFetchRsp(void *msg, SOutputData *input, int32_t len) {
|
||||
SRetrieveTableRsp *rsp = (SRetrieveTableRsp *)msg;
|
||||
|
||||
rsp->useconds = htobe64(input->useconds);
|
||||
rsp->completed = input->queryEnd;
|
||||
rsp->precision = input->precision;
|
||||
rsp->compressed = input->compressed;
|
||||
rsp->compLen = htonl(len);
|
||||
rsp->numOfRows = htonl(input->numOfRows);
|
||||
}
|
||||
|
||||
|
||||
void qwFreeFetchRsp(void *msg) {
|
||||
if (msg) {
|
||||
rpcFreeCont(msg);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t qwBuildAndSendQueryRsp(void *connection, int32_t code) {
|
||||
SRpcMsg *pMsg = (SRpcMsg *)connection;
|
||||
SQueryTableRsp *pRsp = (SQueryTableRsp *)rpcMallocCont(sizeof(SQueryTableRsp));
|
||||
pRsp->code = code;
|
||||
|
||||
SRpcMsg rpcRsp = {
|
||||
.handle = pMsg->handle,
|
||||
.ahandle = pMsg->ahandle,
|
||||
.pCont = pRsp,
|
||||
.contLen = sizeof(*pRsp),
|
||||
.code = code,
|
||||
};
|
||||
|
||||
rpcSendResponse(&rpcRsp);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t qwBuildAndSendReadyRsp(void *connection, int32_t code) {
|
||||
SRpcMsg *pMsg = (SRpcMsg *)connection;
|
||||
SResReadyRsp *pRsp = (SResReadyRsp *)rpcMallocCont(sizeof(SResReadyRsp));
|
||||
pRsp->code = code;
|
||||
|
||||
SRpcMsg rpcRsp = {
|
||||
.handle = pMsg->handle,
|
||||
.ahandle = pMsg->ahandle,
|
||||
.pCont = pRsp,
|
||||
.contLen = sizeof(*pRsp),
|
||||
.code = code,
|
||||
};
|
||||
|
||||
rpcSendResponse(&rpcRsp);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t qwBuildAndSendStatusRsp(SRpcMsg *pMsg, SSchedulerStatusRsp *sStatus) {
|
||||
int32_t size = 0;
|
||||
|
||||
if (sStatus) {
|
||||
size = sizeof(SSchedulerStatusRsp) + sizeof(sStatus->status[0]) * sStatus->num;
|
||||
} else {
|
||||
size = sizeof(SSchedulerStatusRsp);
|
||||
}
|
||||
|
||||
SSchedulerStatusRsp *pRsp = (SSchedulerStatusRsp *)rpcMallocCont(size);
|
||||
|
||||
if (sStatus) {
|
||||
memcpy(pRsp, sStatus, size);
|
||||
} else {
|
||||
pRsp->num = 0;
|
||||
}
|
||||
|
||||
SRpcMsg rpcRsp = {
|
||||
.msgType = pMsg->msgType + 1,
|
||||
.handle = pMsg->handle,
|
||||
.ahandle = pMsg->ahandle,
|
||||
.pCont = pRsp,
|
||||
.contLen = size,
|
||||
.code = 0,
|
||||
};
|
||||
|
||||
rpcSendResponse(&rpcRsp);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t qwBuildAndSendFetchRsp(void *connection, SRetrieveTableRsp *pRsp, int32_t dataLength, int32_t code) {
|
||||
SRpcMsg *pMsg = (SRpcMsg *)connection;
|
||||
|
||||
if (NULL == pRsp) {
|
||||
pRsp = (SRetrieveTableRsp *)rpcMallocCont(sizeof(SRetrieveTableRsp));
|
||||
memset(pRsp, 0, sizeof(SRetrieveTableRsp));
|
||||
dataLength = 0;
|
||||
}
|
||||
|
||||
SRpcMsg rpcRsp = {
|
||||
.handle = pMsg->handle,
|
||||
.ahandle = pMsg->ahandle,
|
||||
.pCont = pRsp,
|
||||
.contLen = sizeof(*pRsp) + dataLength,
|
||||
.code = code,
|
||||
};
|
||||
|
||||
rpcSendResponse(&rpcRsp);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t qwBuildAndSendCancelRsp(SRpcMsg *pMsg, int32_t code) {
|
||||
STaskCancelRsp *pRsp = (STaskCancelRsp *)rpcMallocCont(sizeof(STaskCancelRsp));
|
||||
pRsp->code = code;
|
||||
|
||||
SRpcMsg rpcRsp = {
|
||||
.handle = pMsg->handle,
|
||||
.ahandle = pMsg->ahandle,
|
||||
.pCont = pRsp,
|
||||
.contLen = sizeof(*pRsp),
|
||||
.code = code,
|
||||
};
|
||||
|
||||
rpcSendResponse(&rpcRsp);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t qwBuildAndSendDropRsp(void *connection, int32_t code) {
|
||||
SRpcMsg *pMsg = (SRpcMsg *)connection;
|
||||
STaskDropRsp *pRsp = (STaskDropRsp *)rpcMallocCont(sizeof(STaskDropRsp));
|
||||
pRsp->code = code;
|
||||
|
||||
SRpcMsg rpcRsp = {
|
||||
.handle = pMsg->handle,
|
||||
.ahandle = pMsg->ahandle,
|
||||
.pCont = pRsp,
|
||||
.contLen = sizeof(*pRsp),
|
||||
.code = code,
|
||||
};
|
||||
|
||||
rpcSendResponse(&rpcRsp);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t qwBuildAndSendShowRsp(SRpcMsg *pMsg, int32_t code) {
|
||||
int32_t numOfCols = 6;
|
||||
int32_t msgSize = sizeof(SVShowTablesRsp) + sizeof(SSchema) * numOfCols;
|
||||
|
||||
SVShowTablesRsp *pRsp = (SVShowTablesRsp *)rpcMallocCont(msgSize);
|
||||
|
||||
int32_t cols = 0;
|
||||
SSchema *pSchema = pRsp->metaInfo.pSchema;
|
||||
|
||||
const SSchema *s = tGetTbnameColumnSchema();
|
||||
*pSchema = createSchema(s->type, htonl(s->bytes), htonl(++cols), "name");
|
||||
pSchema++;
|
||||
|
||||
int32_t type = TSDB_DATA_TYPE_TIMESTAMP;
|
||||
*pSchema = createSchema(type, htonl(tDataTypes[type].bytes), htonl(++cols), "created");
|
||||
pSchema++;
|
||||
|
||||
type = TSDB_DATA_TYPE_SMALLINT;
|
||||
*pSchema = createSchema(type, htonl(tDataTypes[type].bytes), htonl(++cols), "columns");
|
||||
pSchema++;
|
||||
|
||||
*pSchema = createSchema(s->type, htonl(s->bytes), htonl(++cols), "stable");
|
||||
pSchema++;
|
||||
|
||||
type = TSDB_DATA_TYPE_BIGINT;
|
||||
*pSchema = createSchema(type, htonl(tDataTypes[type].bytes), htonl(++cols), "uid");
|
||||
pSchema++;
|
||||
|
||||
type = TSDB_DATA_TYPE_INT;
|
||||
*pSchema = createSchema(type, htonl(tDataTypes[type].bytes), htonl(++cols), "vgId");
|
||||
|
||||
assert(cols == numOfCols);
|
||||
pRsp->metaInfo.numOfColumns = htonl(cols);
|
||||
|
||||
SRpcMsg rpcMsg = {
|
||||
.handle = pMsg->handle,
|
||||
.ahandle = pMsg->ahandle,
|
||||
.pCont = pRsp,
|
||||
.contLen = msgSize,
|
||||
.code = code,
|
||||
};
|
||||
|
||||
rpcSendResponse(&rpcMsg);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t qwBuildAndSendShowFetchRsp(SRpcMsg *pMsg, SVShowTablesFetchReq* pFetchReq) {
|
||||
SVShowTablesFetchRsp *pRsp = (SVShowTablesFetchRsp *)rpcMallocCont(sizeof(SVShowTablesFetchRsp));
|
||||
int32_t handle = htonl(pFetchReq->id);
|
||||
|
||||
pRsp->numOfRows = 0;
|
||||
SRpcMsg rpcMsg = {
|
||||
.handle = pMsg->handle,
|
||||
.ahandle = pMsg->ahandle,
|
||||
.pCont = pRsp,
|
||||
.contLen = sizeof(*pRsp),
|
||||
.code = 0,
|
||||
};
|
||||
|
||||
rpcSendResponse(&rpcMsg);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int32_t qwBuildAndSendSchSinkMsg(SQWorkerMgmt *mgmt, uint64_t sId, uint64_t qId, uint64_t tId, void *connection) {
|
||||
SRpcMsg *pMsg = (SRpcMsg *)connection;
|
||||
SSinkDataReq * req = (SSinkDataReq *)rpcMallocCont(sizeof(SSinkDataReq));
|
||||
if (NULL == req) {
|
||||
qError("rpcMallocCont %d failed", (int32_t)sizeof(SSinkDataReq));
|
||||
QW_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
req->header.vgId = mgmt->nodeId;
|
||||
req->sId = sId;
|
||||
req->queryId = qId;
|
||||
req->taskId = tId;
|
||||
|
||||
SRpcMsg pNewMsg = {
|
||||
.handle = pMsg->handle,
|
||||
.ahandle = pMsg->ahandle,
|
||||
.msgType = TDMT_VND_SCHEDULE_DATA_SINK,
|
||||
.pCont = req,
|
||||
.contLen = sizeof(SSinkDataReq),
|
||||
.code = 0,
|
||||
};
|
||||
|
||||
int32_t code = (*mgmt->putToQueueFp)(mgmt->nodeObj, &pNewMsg);
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
qError("put data sink schedule msg to queue failed, code:%x", code);
|
||||
rpcFreeCont(req);
|
||||
QW_ERR_RET(code);
|
||||
}
|
||||
|
||||
qDebug("put data sink schedule msg to query queue");
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int32_t qwBuildAndSendCQueryMsg(SQWorkerMgmt *mgmt, uint64_t sId, uint64_t qId, uint64_t tId, void *connection) {
|
||||
SRpcMsg *pMsg = (SRpcMsg *)connection;
|
||||
SQueryContinueReq * req = (SQueryContinueReq *)rpcMallocCont(sizeof(SQueryContinueReq));
|
||||
if (NULL == req) {
|
||||
QW_SCH_TASK_ELOG("rpcMallocCont %d failed", (int32_t)sizeof(SQueryContinueReq));
|
||||
QW_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
req->header.vgId = mgmt->nodeId;
|
||||
req->sId = sId;
|
||||
req->queryId = qId;
|
||||
req->taskId = tId;
|
||||
|
||||
SRpcMsg pNewMsg = {
|
||||
.handle = pMsg->handle,
|
||||
.ahandle = pMsg->ahandle,
|
||||
.msgType = TDMT_VND_QUERY_CONTINUE,
|
||||
.pCont = req,
|
||||
.contLen = sizeof(SQueryContinueReq),
|
||||
.code = 0,
|
||||
};
|
||||
|
||||
int32_t code = (*mgmt->putToQueueFp)(mgmt->nodeObj, &pNewMsg);
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
QW_SCH_TASK_ELOG("put query continue msg to queue failed, code:%x", code);
|
||||
rpcFreeCont(req);
|
||||
QW_ERR_RET(code);
|
||||
}
|
||||
|
||||
QW_SCH_TASK_DLOG("put query continue msg to query queue, vgId:%d", mgmt->nodeId);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t qWorkerProcessQueryMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg) {
|
||||
if (NULL == node || NULL == qWorkerMgmt || NULL == pMsg) {
|
||||
QW_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
}
|
||||
|
||||
int32_t code = 0;
|
||||
SSubQueryMsg *msg = pMsg->pCont;
|
||||
SQWorkerMgmt *mgmt = (SQWorkerMgmt *)qWorkerMgmt;
|
||||
|
||||
if (NULL == msg || pMsg->contLen <= sizeof(*msg)) {
|
||||
QW_ELOG("invalid query msg, contLen:%d", pMsg->contLen);
|
||||
QW_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
}
|
||||
|
||||
msg->sId = be64toh(msg->sId);
|
||||
msg->queryId = be64toh(msg->queryId);
|
||||
msg->taskId = be64toh(msg->taskId);
|
||||
msg->contentLen = ntohl(msg->contentLen);
|
||||
|
||||
uint64_t sId = msg->sId;
|
||||
uint64_t qId = msg->queryId;
|
||||
uint64_t tId = msg->taskId;
|
||||
|
||||
SQWMsg qwMsg = {.node = node, .msg = msg->msg, .msgLen = msg->contentLen, .connection = pMsg};
|
||||
|
||||
QW_SCH_TASK_DLOG("processQuery start, node:%p", node);
|
||||
|
||||
QW_RET(qwProcessQuery(QW_FPARAMS(), &qwMsg));
|
||||
|
||||
QW_SCH_TASK_DLOG("processQuery end, node:%p", node);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t qWorkerProcessCQueryMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg) {
|
||||
int32_t code = 0;
|
||||
int8_t status = 0;
|
||||
bool queryDone = false;
|
||||
SQueryContinueReq *msg = (SQueryContinueReq *)pMsg->pCont;
|
||||
bool needStop = false;
|
||||
SQWTaskCtx *handles = NULL;
|
||||
SQWorkerMgmt *mgmt = (SQWorkerMgmt *)qWorkerMgmt;
|
||||
|
||||
if (NULL == msg || pMsg->contLen <= sizeof(*msg)) {
|
||||
QW_ELOG("invalid cquery msg, contLen:%d", pMsg->contLen);
|
||||
QW_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
}
|
||||
|
||||
msg->sId = be64toh(msg->sId);
|
||||
msg->queryId = be64toh(msg->queryId);
|
||||
msg->taskId = be64toh(msg->taskId);
|
||||
|
||||
uint64_t sId = msg->sId;
|
||||
uint64_t qId = msg->queryId;
|
||||
uint64_t tId = msg->taskId;
|
||||
|
||||
SQWMsg qwMsg = {.node = node, .msg = NULL, .msgLen = 0, .connection = pMsg};
|
||||
|
||||
QW_SCH_TASK_DLOG("processCQuery start, node:%p", node);
|
||||
|
||||
QW_ERR_RET(qwProcessCQuery(QW_FPARAMS(), &qwMsg));
|
||||
|
||||
QW_SCH_TASK_DLOG("processCQuery end, node:%p", node);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int32_t qWorkerProcessDataSinkMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg){
|
||||
if (NULL == node || NULL == qWorkerMgmt || NULL == pMsg) {
|
||||
return TSDB_CODE_QRY_INVALID_INPUT;
|
||||
}
|
||||
|
||||
SSinkDataReq *msg = pMsg->pCont;
|
||||
if (NULL == msg || pMsg->contLen < sizeof(*msg)) {
|
||||
qError("invalid sink data msg");
|
||||
QW_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
}
|
||||
|
||||
//dsScheduleProcess();
|
||||
//TODO
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t qWorkerProcessReadyMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg){
|
||||
if (NULL == node || NULL == qWorkerMgmt || NULL == pMsg) {
|
||||
return TSDB_CODE_QRY_INVALID_INPUT;
|
||||
}
|
||||
|
||||
SResReadyReq *msg = pMsg->pCont;
|
||||
if (NULL == msg || pMsg->contLen < sizeof(*msg)) {
|
||||
qError("invalid task status msg");
|
||||
QW_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
}
|
||||
|
||||
SQWorkerMgmt *mgmt = (SQWorkerMgmt *)qWorkerMgmt;
|
||||
|
||||
msg->sId = be64toh(msg->sId);
|
||||
msg->queryId = be64toh(msg->queryId);
|
||||
msg->taskId = be64toh(msg->taskId);
|
||||
|
||||
uint64_t sId = msg->sId;
|
||||
uint64_t qId = msg->queryId;
|
||||
uint64_t tId = msg->taskId;
|
||||
|
||||
SQWMsg qwMsg = {.node = node, .msg = NULL, .msgLen = 0, .connection = pMsg};
|
||||
|
||||
QW_SCH_TASK_DLOG("processReady start, node:%p", node);
|
||||
|
||||
QW_ERR_RET(qwProcessReady(qWorkerMgmt, msg->sId, msg->queryId, msg->taskId, &qwMsg));
|
||||
|
||||
QW_SCH_TASK_DLOG("processReady end, node:%p", node);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t qWorkerProcessStatusMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg) {
|
||||
if (NULL == node || NULL == qWorkerMgmt || NULL == pMsg) {
|
||||
return TSDB_CODE_QRY_INVALID_INPUT;
|
||||
}
|
||||
|
||||
int32_t code = 0;
|
||||
SSchTasksStatusReq *msg = pMsg->pCont;
|
||||
if (NULL == msg || pMsg->contLen < sizeof(*msg)) {
|
||||
qError("invalid task status msg");
|
||||
QW_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
}
|
||||
|
||||
msg->sId = htobe64(msg->sId);
|
||||
|
||||
SSchedulerStatusRsp *sStatus = NULL;
|
||||
|
||||
//QW_ERR_JRET(qwGetSchTasksStatus(qWorkerMgmt, msg->sId, &sStatus));
|
||||
|
||||
_return:
|
||||
|
||||
QW_ERR_RET(qwBuildAndSendStatusRsp(pMsg, sStatus));
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t qWorkerProcessFetchMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg) {
|
||||
if (NULL == node || NULL == qWorkerMgmt || NULL == pMsg) {
|
||||
return TSDB_CODE_QRY_INVALID_INPUT;
|
||||
}
|
||||
|
||||
SResFetchReq *msg = pMsg->pCont;
|
||||
SQWorkerMgmt *mgmt = (SQWorkerMgmt *)qWorkerMgmt;
|
||||
|
||||
if (NULL == msg || pMsg->contLen < sizeof(*msg)) {
|
||||
QW_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
}
|
||||
|
||||
msg->sId = be64toh(msg->sId);
|
||||
msg->queryId = be64toh(msg->queryId);
|
||||
msg->taskId = be64toh(msg->taskId);
|
||||
|
||||
uint64_t sId = msg->sId;
|
||||
uint64_t qId = msg->queryId;
|
||||
uint64_t tId = msg->taskId;
|
||||
|
||||
SQWMsg qwMsg = {.node = node, .msg = NULL, .msgLen = 0, .connection = pMsg};
|
||||
|
||||
QW_SCH_TASK_DLOG("processFetch start, node:%p", node);
|
||||
|
||||
QW_ERR_RET(qwProcessFetch(QW_FPARAMS(), &qwMsg));
|
||||
|
||||
QW_SCH_TASK_DLOG("processFetch end, node:%p", node);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t qWorkerProcessCancelMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg) {
|
||||
if (NULL == node || NULL == qWorkerMgmt || NULL == pMsg) {
|
||||
return TSDB_CODE_QRY_INVALID_INPUT;
|
||||
}
|
||||
|
||||
int32_t code = 0;
|
||||
STaskCancelReq *msg = pMsg->pCont;
|
||||
if (NULL == msg || pMsg->contLen < sizeof(*msg)) {
|
||||
qError("invalid task cancel msg");
|
||||
QW_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
}
|
||||
|
||||
msg->sId = htobe64(msg->sId);
|
||||
msg->queryId = htobe64(msg->queryId);
|
||||
msg->taskId = htobe64(msg->taskId);
|
||||
|
||||
//QW_ERR_JRET(qwCancelTask(qWorkerMgmt, msg->sId, msg->queryId, msg->taskId));
|
||||
|
||||
_return:
|
||||
|
||||
QW_ERR_RET(qwBuildAndSendCancelRsp(pMsg, code));
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t qWorkerProcessDropMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg) {
|
||||
if (NULL == node || NULL == qWorkerMgmt || NULL == pMsg) {
|
||||
return TSDB_CODE_QRY_INVALID_INPUT;
|
||||
}
|
||||
|
||||
int32_t code = 0;
|
||||
STaskDropReq *msg = pMsg->pCont;
|
||||
SQWorkerMgmt *mgmt = (SQWorkerMgmt *)qWorkerMgmt;
|
||||
|
||||
if (NULL == msg || pMsg->contLen < sizeof(*msg)) {
|
||||
QW_ELOG("invalid task drop msg, msg:%p, msgLen:%d", msg, pMsg->contLen);
|
||||
QW_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
}
|
||||
|
||||
msg->sId = be64toh(msg->sId);
|
||||
msg->queryId = be64toh(msg->queryId);
|
||||
msg->taskId = be64toh(msg->taskId);
|
||||
|
||||
uint64_t sId = msg->sId;
|
||||
uint64_t qId = msg->queryId;
|
||||
uint64_t tId = msg->taskId;
|
||||
|
||||
SQWMsg qwMsg = {.node = node, .msg = NULL, .msgLen = 0, .connection = pMsg};
|
||||
|
||||
QW_SCH_TASK_DLOG("processDrop start, node:%p", node);
|
||||
|
||||
QW_ERR_RET(qwProcessDrop(QW_FPARAMS(), &qwMsg));
|
||||
|
||||
QW_SCH_TASK_DLOG("processDrop end, node:%p", node);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t qWorkerProcessShowMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg) {
|
||||
if (NULL == node || NULL == qWorkerMgmt || NULL == pMsg) {
|
||||
return TSDB_CODE_QRY_INVALID_INPUT;
|
||||
}
|
||||
|
||||
int32_t code = 0;
|
||||
SVShowTablesReq *pReq = pMsg->pCont;
|
||||
QW_ERR_RET(qwBuildAndSendShowRsp(pMsg, code));
|
||||
}
|
||||
|
||||
int32_t qWorkerProcessShowFetchMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg) {
|
||||
if (NULL == node || NULL == qWorkerMgmt || NULL == pMsg) {
|
||||
return TSDB_CODE_QRY_INVALID_INPUT;
|
||||
}
|
||||
|
||||
SVShowTablesFetchReq *pFetchReq = pMsg->pCont;
|
||||
QW_ERR_RET(qwBuildAndSendShowFetchRsp(pMsg, pFetchReq));
|
||||
}
|
||||
|
||||
|
|
@ -42,6 +42,11 @@ int32_t qwtStringToPlan(const char* str, SSubplan** subplan) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t qwtPutReqToQueue(void *node, struct SRpcMsg *pMsg) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void qwtRpcSendResponse(const SRpcMsg *pRsp) {
|
||||
if (TDMT_VND_TASKS_STATUS_RSP == pRsp->msgType) {
|
||||
SSchedulerStatusRsp *rsp = (SSchedulerStatusRsp *)pRsp->pCont;
|
||||
|
@ -258,7 +263,7 @@ TEST(seqTest, normalCase) {
|
|||
stubSetStringToPlan();
|
||||
stubSetRpcSendResponse();
|
||||
|
||||
code = qWorkerInit(NULL, &mgmt);
|
||||
code = qWorkerInit(NODE_TYPE_VNODE, 1, NULL, &mgmt, mockPointer, qwtPutReqToQueue);
|
||||
ASSERT_EQ(code, 0);
|
||||
|
||||
statusMsg.sId = htobe64(1);
|
||||
|
@ -328,7 +333,7 @@ TEST(seqTest, cancelFirst) {
|
|||
stubSetStringToPlan();
|
||||
stubSetRpcSendResponse();
|
||||
|
||||
code = qWorkerInit(NULL, &mgmt);
|
||||
code = qWorkerInit(NODE_TYPE_VNODE, 1, NULL, &mgmt, mockPointer, qwtPutReqToQueue);
|
||||
ASSERT_EQ(code, 0);
|
||||
|
||||
statusMsg.sId = htobe64(1);
|
||||
|
@ -402,7 +407,7 @@ TEST(seqTest, randCase) {
|
|||
|
||||
srand(time(NULL));
|
||||
|
||||
code = qWorkerInit(NULL, &mgmt);
|
||||
code = qWorkerInit(NODE_TYPE_VNODE, 1, NULL, &mgmt, mockPointer, qwtPutReqToQueue);
|
||||
ASSERT_EQ(code, 0);
|
||||
|
||||
int32_t t = 0;
|
||||
|
@ -446,7 +451,7 @@ TEST(seqTest, multithreadRand) {
|
|||
|
||||
srand(time(NULL));
|
||||
|
||||
code = qWorkerInit(NULL, &mgmt);
|
||||
code = qWorkerInit(NODE_TYPE_VNODE, 1, NULL, &mgmt, mockPointer, qwtPutReqToQueue);
|
||||
ASSERT_EQ(code, 0);
|
||||
|
||||
pthread_attr_t thattr;
|
||||
|
|
|
@ -36,11 +36,31 @@ enum {
|
|||
SCH_WRITE,
|
||||
};
|
||||
|
||||
typedef struct SSchApiStat {
|
||||
|
||||
} SSchApiStat;
|
||||
|
||||
typedef struct SSchRuntimeStat {
|
||||
|
||||
} SSchRuntimeStat;
|
||||
|
||||
typedef struct SSchJobStat {
|
||||
|
||||
} SSchJobStat;
|
||||
|
||||
typedef struct SSchedulerStat {
|
||||
SSchApiStat api;
|
||||
SSchRuntimeStat runtime;
|
||||
SSchJobStat job;
|
||||
} SSchedulerStat;
|
||||
|
||||
|
||||
typedef struct SSchedulerMgmt {
|
||||
uint64_t taskId; // sequential taksId
|
||||
uint64_t sId; // schedulerId
|
||||
SSchedulerCfg cfg;
|
||||
SHashObj *jobs; // key: queryId, value: SQueryJob*
|
||||
uint64_t taskId; // sequential taksId
|
||||
uint64_t sId; // schedulerId
|
||||
SSchedulerCfg cfg;
|
||||
SHashObj *jobs; // key: queryId, value: SQueryJob*
|
||||
SSchedulerStat stat;
|
||||
} SSchedulerMgmt;
|
||||
|
||||
typedef struct SSchCallbackParam {
|
||||
|
|
|
@ -1374,6 +1374,83 @@ int32_t scheduleAsyncExecJob(void *transport, SArray *nodeList, SQueryDag* pDag,
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t schedulerConvertDagToTaskList(SQueryDag* pDag, SArray **pTasks) {
|
||||
if (NULL == pDag || pDag->numOfSubplans <= 0 || taosArrayGetSize(pDag->pSubplans) <= 0) {
|
||||
SCH_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
}
|
||||
|
||||
int32_t levelNum = taosArrayGetSize(pDag->pSubplans);
|
||||
if (1 != levelNum) {
|
||||
qError("invalid level num: %d", levelNum);
|
||||
SCH_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
}
|
||||
|
||||
SArray *plans = taosArrayGet(pDag->pSubplans, 0);
|
||||
int32_t taskNum = taosArrayGetSize(plans);
|
||||
if (taskNum <= 0) {
|
||||
qError("invalid task num: %d", taskNum);
|
||||
SCH_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
}
|
||||
|
||||
SArray *info = taosArrayInit(taskNum, sizeof(STaskInfo));
|
||||
if (NULL == info) {
|
||||
qError("taosArrayInit %d taskInfo failed", taskNum);
|
||||
SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
STaskInfo tInfo = {0};
|
||||
char *msg = NULL;
|
||||
int32_t msgLen = 0;
|
||||
int32_t code = 0;
|
||||
|
||||
for (int32_t i = 0; i < taskNum; ++i) {
|
||||
SSubplan *plan = taosArrayGetP(plans, i);
|
||||
|
||||
tInfo.addr = plan->execNode;
|
||||
|
||||
code = qSubPlanToString(plan, &msg, &msgLen);
|
||||
if (TSDB_CODE_SUCCESS != code || NULL == msg || msgLen <= 0) {
|
||||
qError("subplanToString error, code:%x, msg:%p, len:%d", code, msg, msgLen);
|
||||
SCH_ERR_JRET(code);
|
||||
}
|
||||
|
||||
int32_t msgSize = sizeof(SSubQueryMsg) + msgLen;
|
||||
msg = calloc(1, msgSize);
|
||||
if (NULL == msg) {
|
||||
qError("calloc %d failed", msgSize);
|
||||
SCH_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
SSubQueryMsg *pMsg = msg;
|
||||
|
||||
pMsg->header.vgId = htonl(tInfo.addr.nodeId);
|
||||
|
||||
pMsg->sId = htobe64(schMgmt.sId);
|
||||
pMsg->queryId = htobe64(plan->id.queryId);
|
||||
pMsg->taskId = htobe64(atomic_add_fetch_64(&schMgmt.taskId, 1));
|
||||
pMsg->contentLen = htonl(msgLen);
|
||||
memcpy(pMsg->msg, msg, msgLen);
|
||||
|
||||
tInfo.msg = pMsg;
|
||||
|
||||
if (NULL == taosArrayPush(info, &tInfo)) {
|
||||
qError("taosArrayPush failed, idx:%d", i);
|
||||
free(msg);
|
||||
SCH_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
}
|
||||
|
||||
*pTasks = info;
|
||||
info = NULL;
|
||||
|
||||
_return:
|
||||
|
||||
schedulerFreeTaskList(info);
|
||||
|
||||
SCH_RET(code);
|
||||
}
|
||||
|
||||
|
||||
int32_t scheduleFetchRows(SSchJob *pJob, void** pData) {
|
||||
if (NULL == pJob || NULL == pData) {
|
||||
SCH_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
|
@ -1462,35 +1539,38 @@ void scheduleFreeJob(void *job) {
|
|||
}
|
||||
|
||||
SSchJob *pJob = job;
|
||||
uint64_t queryId = pJob->queryId;
|
||||
|
||||
if (0 != taosHashRemove(schMgmt.jobs, &pJob->queryId, sizeof(pJob->queryId))) {
|
||||
SCH_JOB_ELOG("taosHashRemove job from list failed, may already freed, pJob:%p", pJob);
|
||||
return;
|
||||
}
|
||||
|
||||
schCheckAndUpdateJobStatus(pJob, JOB_TASK_STATUS_DROPPING);
|
||||
|
||||
SCH_JOB_DLOG("job removed from list, no further ref, ref:%d", atomic_load_32(&pJob->ref));
|
||||
|
||||
while (true) {
|
||||
int32_t ref = atomic_load_32(&pJob->ref);
|
||||
if (0 == ref) {
|
||||
break;
|
||||
} else if (ref > 0) {
|
||||
usleep(1);
|
||||
} else {
|
||||
assert(0);
|
||||
if (SCH_GET_JOB_STATUS(pJob) > 0) {
|
||||
if (0 != taosHashRemove(schMgmt.jobs, &pJob->queryId, sizeof(pJob->queryId))) {
|
||||
SCH_JOB_ELOG("taosHashRemove job from list failed, may already freed, pJob:%p", pJob);
|
||||
return;
|
||||
}
|
||||
|
||||
schCheckAndUpdateJobStatus(pJob, JOB_TASK_STATUS_DROPPING);
|
||||
|
||||
SCH_JOB_DLOG("job removed from list, no further ref, ref:%d", atomic_load_32(&pJob->ref));
|
||||
|
||||
while (true) {
|
||||
int32_t ref = atomic_load_32(&pJob->ref);
|
||||
if (0 == ref) {
|
||||
break;
|
||||
} else if (ref > 0) {
|
||||
usleep(1);
|
||||
} else {
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
SCH_JOB_DLOG("job no ref now, status:%d", SCH_GET_JOB_STATUS(pJob));
|
||||
|
||||
if (pJob->status == JOB_TASK_STATUS_EXECUTING) {
|
||||
schCancelJob(pJob);
|
||||
}
|
||||
|
||||
schDropJobAllTasks(pJob);
|
||||
}
|
||||
|
||||
SCH_JOB_DLOG("job no ref now, status:%d", SCH_GET_JOB_STATUS(pJob));
|
||||
|
||||
if (pJob->status == JOB_TASK_STATUS_EXECUTING) {
|
||||
schCancelJob(pJob);
|
||||
}
|
||||
|
||||
schDropJobAllTasks(pJob);
|
||||
|
||||
pJob->subPlans = NULL; // it is a reference to pDag->pSubplans
|
||||
|
||||
int32_t numOfLevels = taosArrayGetSize(pJob->levels);
|
||||
|
@ -1515,6 +1595,22 @@ void scheduleFreeJob(void *job) {
|
|||
tfree(pJob->res);
|
||||
|
||||
tfree(pJob);
|
||||
|
||||
qDebug("QID:%"PRIx64" job freed", queryId);
|
||||
}
|
||||
|
||||
void schedulerFreeTaskList(SArray *taskList) {
|
||||
if (NULL == taskList) {
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t taskNum = taosArrayGetSize(taskList);
|
||||
for (int32_t i = 0; i < taskNum; ++i) {
|
||||
STaskInfo *info = taosArrayGet(taskList, i);
|
||||
tfree(info->msg);
|
||||
}
|
||||
|
||||
taosArrayDestroy(taskList);
|
||||
}
|
||||
|
||||
void schedulerDestroy(void) {
|
||||
|
|
|
@ -79,6 +79,7 @@ void schtBuildQueryDag(SQueryDag *dag) {
|
|||
scanPlan->level = 1;
|
||||
scanPlan->pParents = taosArrayInit(1, POINTER_BYTES);
|
||||
scanPlan->pNode = (SPhyNode*)calloc(1, sizeof(SPhyNode));
|
||||
scanPlan->msgType = TDMT_VND_QUERY;
|
||||
|
||||
mergePlan->id.queryId = qId;
|
||||
mergePlan->id.templateId = 0x4444444444;
|
||||
|
@ -89,6 +90,7 @@ void schtBuildQueryDag(SQueryDag *dag) {
|
|||
mergePlan->pChildren = taosArrayInit(1, POINTER_BYTES);
|
||||
mergePlan->pParents = NULL;
|
||||
mergePlan->pNode = (SPhyNode*)calloc(1, sizeof(SPhyNode));
|
||||
mergePlan->msgType = TDMT_VND_QUERY;
|
||||
|
||||
SSubplan *mergePointer = (SSubplan *)taosArrayPush(merge, &mergePlan);
|
||||
SSubplan *scanPointer = (SSubplan *)taosArrayPush(scan, &scanPlan);
|
||||
|
@ -163,6 +165,11 @@ void schtExecNode(SSubplan* subplan, uint64_t templateId, SQueryNodeAddr* ep) {
|
|||
|
||||
}
|
||||
|
||||
void schtRpcSendRequest(void *shandle, const SEpSet *pEpSet, SRpcMsg *pMsg, int64_t *pRid) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void schtSetPlanToString() {
|
||||
static Stub stub;
|
||||
|
@ -190,6 +197,20 @@ void schtSetExecNode() {
|
|||
}
|
||||
}
|
||||
|
||||
void schtSetRpcSendRequest() {
|
||||
static Stub stub;
|
||||
stub.set(rpcSendRequest, schtRpcSendRequest);
|
||||
{
|
||||
AddrAny any("libtransport.so");
|
||||
std::map<std::string,void*> result;
|
||||
any.get_global_func_addr_dynsym("^rpcSendRequest$", result);
|
||||
for (const auto& f : result) {
|
||||
stub.set(f.second, schtRpcSendRequest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void *schtSendRsp(void *param) {
|
||||
SSchJob *job = NULL;
|
||||
int32_t code = 0;
|
||||
|
|
|
@ -28,11 +28,13 @@ extern "C" {
|
|||
struct TDB {
|
||||
pgsize_t pageSize;
|
||||
tdb_db_t type;
|
||||
char * fname;
|
||||
char * dbname;
|
||||
union {
|
||||
TDB_BTREE *btree;
|
||||
TDB_HASH * hash;
|
||||
TDB_HEAP * heap;
|
||||
} dbam; // Different access methods
|
||||
} dbam; // db access method
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -27,4 +27,11 @@ if (${BUILD_WITH_UV})
|
|||
add_definitions(-DUSE_UV)
|
||||
endif(${BUILD_WITH_UV})
|
||||
|
||||
if (${BUILD_TEST})
|
||||
add_subdirectory(test)
|
||||
endif(${BUILD_TEST})
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -21,10 +21,6 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef USE_UV
|
||||
|
||||
#else
|
||||
|
||||
#define RPC_CONN_TCP 2
|
||||
|
||||
extern int tsRpcOverhead;
|
||||
|
@ -75,7 +71,6 @@ typedef struct {
|
|||
} SRpcDigest;
|
||||
|
||||
#pragma pack(pop)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -21,8 +21,6 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef USE_UV
|
||||
#else
|
||||
void *taosInitTcpServer(uint32_t ip, uint16_t port, char *label, int numOfThreads, void *fp, void *shandle);
|
||||
void taosStopTcpServer(void *param);
|
||||
void taosCleanUpTcpServer(void *param);
|
||||
|
@ -35,8 +33,6 @@ void *taosOpenTcpClientConnection(void *shandle, void *thandle, uint32_t ip, uin
|
|||
void taosCloseTcpConnection(void *chandle);
|
||||
int taosSendTcpData(uint32_t ip, uint16_t port, void *data, int len, void *chandle);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -16,15 +16,65 @@
|
|||
#ifndef _TD_TRANSPORT_INT_H_
|
||||
#define _TD_TRANSPORT_INT_H_
|
||||
|
||||
#include "rpcHead.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef USE_UV
|
||||
|
||||
#else
|
||||
#include <stddef.h>
|
||||
typedef void *queue[2];
|
||||
|
||||
/* Private macros. */
|
||||
#define QUEUE_NEXT(q) (*(queue **)&((*(q))[0]))
|
||||
#define QUEUE_PREV(q) (*(queue **)&((*(q))[1]))
|
||||
|
||||
#define QUEUE_PREV_NEXT(q) (QUEUE_NEXT(QUEUE_PREV(q)))
|
||||
#define QUEUE_NEXT_PREV(q) (QUEUE_PREV(QUEUE_NEXT(q)))
|
||||
|
||||
/* Initialize an empty queue. */
|
||||
#define QUEUE_INIT(q) \
|
||||
{ \
|
||||
QUEUE_NEXT(q) = (q); \
|
||||
QUEUE_PREV(q) = (q); \
|
||||
}
|
||||
|
||||
/* Return true if the queue has no element. */
|
||||
#define QUEUE_IS_EMPTY(q) ((const queue *)(q) == (const queue *)QUEUE_NEXT(q))
|
||||
|
||||
/* Insert an element at the back of a queue. */
|
||||
#define QUEUE_PUSH(q, e) \
|
||||
{ \
|
||||
QUEUE_NEXT(e) = (q); \
|
||||
QUEUE_PREV(e) = QUEUE_PREV(q); \
|
||||
QUEUE_PREV_NEXT(e) = (e); \
|
||||
QUEUE_PREV(q) = (e); \
|
||||
}
|
||||
|
||||
/* Remove the given element from the queue. Any element can be removed at any *
|
||||
* time. */
|
||||
#define QUEUE_REMOVE(e) \
|
||||
{ \
|
||||
QUEUE_PREV_NEXT(e) = QUEUE_NEXT(e); \
|
||||
QUEUE_NEXT_PREV(e) = QUEUE_PREV(e); \
|
||||
}
|
||||
|
||||
/* Return the element at the front of the queue. */
|
||||
#define QUEUE_HEAD(q) (QUEUE_NEXT(q))
|
||||
|
||||
/* Return the element at the back of the queue. */
|
||||
#define QUEUE_TAIL(q) (QUEUE_PREV(q))
|
||||
|
||||
/* Iterate over the element of a queue. * Mutating the queue while iterating
|
||||
* results in undefined behavior. */
|
||||
#define QUEUE_FOREACH(q, e) for ((q) = QUEUE_NEXT(e); (q) != (e); (q) = QUEUE_NEXT(q))
|
||||
|
||||
/* Return the structure holding the given element. */
|
||||
#define QUEUE_DATA(e, type, field) ((type *)((void *)((char *)(e)-offsetof(type, field))))
|
||||
|
||||
#endif // USE_LIBUV
|
||||
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -22,9 +22,6 @@
|
|||
#include "ttimer.h"
|
||||
#include "tutil.h"
|
||||
|
||||
#ifdef USE_UV
|
||||
|
||||
#else
|
||||
typedef struct SConnHash {
|
||||
char fqdn[TSDB_FQDN_LEN];
|
||||
uint16_t port;
|
||||
|
@ -295,4 +292,3 @@ static void rpcUnlockCache(int64_t *lockedBy) {
|
|||
assert(false);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -13,9 +13,6 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef USE_UV
|
||||
#include <uv.h>
|
||||
#endif
|
||||
#include "lz4.h"
|
||||
#include "os.h"
|
||||
#include "rpcCache.h"
|
||||
|
@ -30,11 +27,23 @@
|
|||
#include "tmd5.h"
|
||||
#include "tmempool.h"
|
||||
#include "tmsg.h"
|
||||
#include "transportInt.h"
|
||||
#include "tref.h"
|
||||
#include "trpc.h"
|
||||
#include "ttimer.h"
|
||||
#include "tutil.h"
|
||||
|
||||
static pthread_once_t tsRpcInitOnce = PTHREAD_ONCE_INIT;
|
||||
|
||||
int tsRpcMaxUdpSize = 15000; // bytes
|
||||
int tsProgressTimer = 100;
|
||||
// not configurable
|
||||
int tsRpcMaxRetry;
|
||||
int tsRpcHeadSize;
|
||||
int tsRpcOverhead;
|
||||
|
||||
#ifndef USE_UV
|
||||
|
||||
typedef struct {
|
||||
int sessions; // number of sessions allowed
|
||||
int numOfThreads; // number of threads to process incoming messages
|
||||
|
@ -50,235 +59,21 @@ typedef struct {
|
|||
char secret[TSDB_PASSWORD_LEN]; // secret for the link
|
||||
char ckey[TSDB_PASSWORD_LEN]; // ciphering key
|
||||
|
||||
void (*cfp)(void* parent, SRpcMsg*, SEpSet*);
|
||||
int (*afp)(void* parent, char* user, char* spi, char* encrypt, char* secret, char* ckey);
|
||||
void (*cfp)(void *parent, SRpcMsg *, SEpSet *);
|
||||
int (*afp)(void *parent, char *user, char *spi, char *encrypt, char *secret, char *ckey);
|
||||
|
||||
int32_t refCount;
|
||||
void* parent;
|
||||
void* idPool; // handle to ID pool
|
||||
void* tmrCtrl; // handle to timer
|
||||
SHashObj* hash; // handle returned by hash utility
|
||||
void* tcphandle; // returned handle from TCP initialization
|
||||
void* udphandle; // returned handle from UDP initialization
|
||||
void* pCache; // connection cache
|
||||
void * parent;
|
||||
void * idPool; // handle to ID pool
|
||||
void * tmrCtrl; // handle to timer
|
||||
SHashObj * hash; // handle returned by hash utility
|
||||
void * tcphandle; // returned handle from TCP initialization
|
||||
void * udphandle; // returned handle from UDP initialization
|
||||
void * pCache; // connection cache
|
||||
pthread_mutex_t mutex;
|
||||
struct SRpcConn* connList; // connection list
|
||||
struct SRpcConn *connList; // connection list
|
||||
} SRpcInfo;
|
||||
|
||||
#ifdef USE_UV
|
||||
|
||||
#define container_of(ptr, type, member) ((type*)((char*)(ptr)-offsetof(type, member)))
|
||||
|
||||
typedef struct SThreadObj {
|
||||
pthread_t thread;
|
||||
uv_pipe_t* pipe;
|
||||
uv_loop_t* loop;
|
||||
uv_async_t* workerAsync; //
|
||||
int fd;
|
||||
} SThreadObj;
|
||||
|
||||
typedef struct SServerObj {
|
||||
uv_tcp_t server;
|
||||
uv_loop_t* loop;
|
||||
int workerIdx;
|
||||
int numOfThread;
|
||||
SThreadObj** pThreadObj;
|
||||
uv_pipe_t** pipe;
|
||||
} SServerObj;
|
||||
|
||||
typedef struct SConnCtx {
|
||||
uv_tcp_t* pClient;
|
||||
uv_timer_t* pTimer;
|
||||
uv_async_t* pWorkerAsync;
|
||||
int ref;
|
||||
} SConnCtx;
|
||||
|
||||
static void allocBuffer(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf);
|
||||
static void onTimeout(uv_timer_t* handle);
|
||||
static void onRead(uv_stream_t* cli, ssize_t nread, const uv_buf_t* buf);
|
||||
static void onWrite(uv_write_t* req, int status);
|
||||
static void onAccept(uv_stream_t* stream, int status);
|
||||
void onConnection(uv_stream_t* q, ssize_t nread, const uv_buf_t* buf);
|
||||
static void workerAsyncCB(uv_async_t* handle);
|
||||
static void* workerThread(void* arg);
|
||||
|
||||
int32_t rpcInit() { return -1; }
|
||||
void rpcCleanup() { return; };
|
||||
void* rpcOpen(const SRpcInit* pInit) {
|
||||
SRpcInfo* pRpc = calloc(1, sizeof(SRpcInfo));
|
||||
if (pRpc == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (pInit->label) {
|
||||
tstrncpy(pRpc->label, pInit->label, sizeof(pRpc->label));
|
||||
}
|
||||
pRpc->numOfThreads = pInit->numOfThreads > TSDB_MAX_RPC_THREADS ? TSDB_MAX_RPC_THREADS : pInit->numOfThreads;
|
||||
|
||||
SServerObj* srv = calloc(1, sizeof(SServerObj));
|
||||
srv->loop = (uv_loop_t*)malloc(sizeof(uv_loop_t));
|
||||
srv->numOfThread = pRpc->numOfThreads;
|
||||
srv->workerIdx = 0;
|
||||
srv->pThreadObj = (SThreadObj**)calloc(srv->numOfThread, sizeof(SThreadObj*));
|
||||
srv->pipe = (uv_pipe_t**)calloc(srv->numOfThread, sizeof(uv_pipe_t*));
|
||||
uv_loop_init(srv->loop);
|
||||
|
||||
for (int i = 0; i < srv->numOfThread; i++) {
|
||||
srv->pThreadObj[i] = (SThreadObj*)calloc(1, sizeof(SThreadObj));
|
||||
srv->pipe[i] = (uv_pipe_t*)calloc(2, sizeof(uv_pipe_t));
|
||||
int fds[2];
|
||||
if (uv_socketpair(AF_UNIX, SOCK_STREAM, fds, UV_NONBLOCK_PIPE, UV_NONBLOCK_PIPE) != 0) {
|
||||
return NULL;
|
||||
}
|
||||
uv_pipe_init(srv->loop, &(srv->pipe[i][0]), 1);
|
||||
uv_pipe_open(&(srv->pipe[i][0]), fds[1]); // init write
|
||||
|
||||
srv->pThreadObj[i]->fd = fds[0];
|
||||
srv->pThreadObj[i]->pipe = &(srv->pipe[i][1]); // init read
|
||||
int err = pthread_create(&(srv->pThreadObj[i]->thread), NULL, workerThread, (void*)(srv->pThreadObj[i]));
|
||||
if (err == 0) {
|
||||
tError("sucess to create worker thread %d", i);
|
||||
// printf("thread %d create\n", i);
|
||||
} else {
|
||||
tError("failed to create worker thread %d", i);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
uv_tcp_init(srv->loop, &srv->server);
|
||||
struct sockaddr_in bind_addr;
|
||||
uv_ip4_addr("0.0.0.0", pInit->localPort, &bind_addr);
|
||||
uv_tcp_bind(&srv->server, (const struct sockaddr*)&bind_addr, 0);
|
||||
int err = 0;
|
||||
if ((err = uv_listen((uv_stream_t*)&srv->server, 128, onAccept)) != 0) {
|
||||
tError("Listen error %s\n", uv_err_name(err));
|
||||
return NULL;
|
||||
}
|
||||
uv_run(srv->loop, UV_RUN_DEFAULT);
|
||||
|
||||
return pRpc;
|
||||
}
|
||||
void rpcClose(void* arg) { return; }
|
||||
void* rpcMallocCont(int contLen) { return NULL; }
|
||||
void rpcFreeCont(void* cont) { return; }
|
||||
void* rpcReallocCont(void* ptr, int contLen) { return NULL; }
|
||||
|
||||
void rpcSendRequest(void* thandle, const SEpSet* pEpSet, SRpcMsg* pMsg, int64_t* rid) { return; }
|
||||
|
||||
void rpcSendResponse(const SRpcMsg* pMsg) {}
|
||||
|
||||
void rpcSendRedirectRsp(void* pConn, const SEpSet* pEpSet) {}
|
||||
int rpcGetConnInfo(void* thandle, SRpcConnInfo* pInfo) { return -1; }
|
||||
void rpcSendRecv(void* shandle, SEpSet* pEpSet, SRpcMsg* pReq, SRpcMsg* pRsp) { return; }
|
||||
int rpcReportProgress(void* pConn, char* pCont, int contLen) { return -1; }
|
||||
void rpcCancelRequest(int64_t rid) { return; }
|
||||
|
||||
void allocBuffer(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) {
|
||||
buf->base = malloc(suggested_size);
|
||||
buf->len = suggested_size;
|
||||
}
|
||||
|
||||
void onTimeout(uv_timer_t* handle) {
|
||||
// opt
|
||||
tDebug("time out");
|
||||
}
|
||||
void onRead(uv_stream_t* cli, ssize_t nread, const uv_buf_t* buf) {
|
||||
// opt
|
||||
tDebug("data already was read on a stream");
|
||||
}
|
||||
|
||||
void onWrite(uv_write_t* req, int status) {
|
||||
// opt
|
||||
if (req) tDebug("data already was written on stream");
|
||||
}
|
||||
|
||||
void workerAsyncCB(uv_async_t* handle) {
|
||||
// opt
|
||||
SThreadObj* pObj = container_of(handle, SThreadObj, workerAsync);
|
||||
}
|
||||
void onAccept(uv_stream_t* stream, int status) {
|
||||
if (status == -1) {
|
||||
return;
|
||||
}
|
||||
SServerObj* pObj = container_of(stream, SServerObj, server);
|
||||
tDebug("new conntion accepted by main server, dispatch to one worker thread");
|
||||
|
||||
uv_tcp_t* cli = (uv_tcp_t*)malloc(sizeof(uv_tcp_t));
|
||||
uv_tcp_init(pObj->loop, cli);
|
||||
if (uv_accept(stream, (uv_stream_t*)cli) == 0) {
|
||||
uv_write_t* wr = (uv_write_t*)malloc(sizeof(uv_write_t));
|
||||
|
||||
uv_buf_t buf = uv_buf_init("a", 1);
|
||||
// despatch to worker thread
|
||||
pObj->workerIdx = (pObj->workerIdx + 1) % pObj->numOfThread;
|
||||
uv_write2(wr, (uv_stream_t*)&(pObj->pipe[pObj->workerIdx][0]), &buf, 1, (uv_stream_t*)cli, onWrite);
|
||||
} else {
|
||||
uv_close((uv_handle_t*)cli, NULL);
|
||||
}
|
||||
}
|
||||
void onConnection(uv_stream_t* q, ssize_t nread, const uv_buf_t* buf) {
|
||||
if (nread < 0) {
|
||||
if (nread != UV_EOF) {
|
||||
tError("read error %s", uv_err_name(nread));
|
||||
}
|
||||
// TODO(log other failure reason)
|
||||
uv_close((uv_handle_t*)q, NULL);
|
||||
return;
|
||||
}
|
||||
SThreadObj* pObj = (SThreadObj*)container_of(q, struct SThreadObj, pipe);
|
||||
|
||||
uv_pipe_t* pipe = (uv_pipe_t*)q;
|
||||
if (!uv_pipe_pending_count(pipe)) {
|
||||
tError("No pending count");
|
||||
return;
|
||||
}
|
||||
uv_handle_type pending = uv_pipe_pending_type(pipe);
|
||||
assert(pending == UV_TCP);
|
||||
|
||||
SConnCtx* pConn = malloc(sizeof(SConnCtx));
|
||||
/* init conn timer*/
|
||||
pConn->pTimer = malloc(sizeof(uv_timer_t));
|
||||
uv_timer_init(pObj->loop, pConn->pTimer);
|
||||
|
||||
pConn->pClient = (uv_tcp_t*)malloc(sizeof(uv_tcp_t));
|
||||
pConn->pWorkerAsync = pObj->workerAsync; // thread safty
|
||||
uv_tcp_init(pObj->loop, pConn->pClient);
|
||||
|
||||
if (uv_accept(q, (uv_stream_t*)(pConn->pClient)) == 0) {
|
||||
uv_os_fd_t fd;
|
||||
uv_fileno((const uv_handle_t*)pConn->pClient, &fd);
|
||||
tDebug("new connection created: %d", fd);
|
||||
uv_timer_start(pConn->pTimer, onTimeout, 10, 0);
|
||||
uv_read_start((uv_stream_t*)(pConn->pClient), allocBuffer, onRead);
|
||||
} else {
|
||||
uv_timer_stop(pConn->pTimer);
|
||||
free(pConn->pTimer);
|
||||
uv_close((uv_handle_t*)pConn->pClient, NULL);
|
||||
free(pConn->pClient);
|
||||
free(pConn);
|
||||
}
|
||||
}
|
||||
|
||||
void* workerThread(void* arg) {
|
||||
SThreadObj* pObj = (SThreadObj*)arg;
|
||||
int fd = pObj->fd;
|
||||
pObj->loop = (uv_loop_t*)malloc(sizeof(uv_loop_t));
|
||||
uv_loop_init(pObj->loop);
|
||||
|
||||
uv_pipe_init(pObj->loop, pObj->pipe, 1);
|
||||
uv_pipe_open(pObj->pipe, fd);
|
||||
|
||||
pObj->workerAsync = malloc(sizeof(uv_async_t));
|
||||
uv_async_init(pObj->loop, pObj->workerAsync, workerAsyncCB);
|
||||
uv_read_start((uv_stream_t*)pObj->pipe, allocBuffer, onConnection);
|
||||
}
|
||||
#else
|
||||
|
||||
#define RPC_MSG_OVERHEAD (sizeof(SRpcReqContext) + sizeof(SRpcHead) + sizeof(SRpcDigest))
|
||||
#define rpcHeadFromCont(cont) ((SRpcHead*)((char*)cont - sizeof(SRpcHead)))
|
||||
#define rpcContFromHead(msg) (msg + sizeof(SRpcHead))
|
||||
#define rpcMsgLenFromCont(contLen) (contLen + sizeof(SRpcHead))
|
||||
#define rpcContLenFromMsg(msgLen) (msgLen - sizeof(SRpcHead))
|
||||
#define rpcIsReq(type) (type & 1U)
|
||||
|
||||
typedef struct {
|
||||
SRpcInfo * pRpc; // associated SRpcInfo
|
||||
SEpSet epSet; // ip list provided by app
|
||||
|
@ -299,6 +94,13 @@ typedef struct {
|
|||
char msg[0]; // RpcHead starts from here
|
||||
} SRpcReqContext;
|
||||
|
||||
#define RPC_MSG_OVERHEAD (sizeof(SRpcReqContext) + sizeof(SRpcHead) + sizeof(SRpcDigest))
|
||||
#define rpcHeadFromCont(cont) ((SRpcHead *)((char *)cont - sizeof(SRpcHead)))
|
||||
#define rpcContFromHead(msg) (msg + sizeof(SRpcHead))
|
||||
#define rpcMsgLenFromCont(contLen) (contLen + sizeof(SRpcHead))
|
||||
#define rpcContLenFromMsg(msgLen) (msgLen - sizeof(SRpcHead))
|
||||
#define rpcIsReq(type) (type & 1U)
|
||||
|
||||
typedef struct SRpcConn {
|
||||
char info[48]; // debug info: label + pConn + ahandle
|
||||
int sid; // session ID
|
||||
|
@ -336,15 +138,6 @@ typedef struct SRpcConn {
|
|||
SRpcReqContext *pContext; // request context
|
||||
} SRpcConn;
|
||||
|
||||
static pthread_once_t tsRpcInitOnce = PTHREAD_ONCE_INIT;
|
||||
|
||||
int tsRpcMaxUdpSize = 15000; // bytes
|
||||
int tsProgressTimer = 100;
|
||||
// not configurable
|
||||
int tsRpcMaxRetry;
|
||||
int tsRpcHeadSize;
|
||||
int tsRpcOverhead;
|
||||
|
||||
static int tsRpcRefId = -1;
|
||||
static int32_t tsRpcNum = 0;
|
||||
// static pthread_once_t tsRpcInit = PTHREAD_ONCE_INIT;
|
||||
|
@ -442,7 +235,8 @@ void *rpcOpen(const SRpcInit *pInit) {
|
|||
pRpc = (SRpcInfo *)calloc(1, sizeof(SRpcInfo));
|
||||
if (pRpc == NULL) return NULL;
|
||||
|
||||
if (pInit->label) tstrncpy(pRpc->label, pInit->label, sizeof(pRpc->label));
|
||||
if (pInit->label) tstrncpy(pRpc->label, pInit->label, strlen(pInit->label));
|
||||
|
||||
pRpc->connType = pInit->connType;
|
||||
if (pRpc->connType == TAOS_CONN_CLIENT) {
|
||||
pRpc->numOfThreads = pInit->numOfThreads;
|
||||
|
|
|
@ -14,9 +14,6 @@
|
|||
*/
|
||||
|
||||
#include "rpcTcp.h"
|
||||
#ifdef USE_UV
|
||||
#include <uv.h>
|
||||
#endif
|
||||
#include "os.h"
|
||||
#include "rpcHead.h"
|
||||
#include "rpcLog.h"
|
||||
|
@ -24,9 +21,6 @@
|
|||
#include "taoserror.h"
|
||||
#include "tutil.h"
|
||||
|
||||
#ifdef USE_UV
|
||||
|
||||
#else
|
||||
typedef struct SFdObj {
|
||||
void * signature;
|
||||
SOCKET fd; // TCP socket FD
|
||||
|
@ -665,5 +659,3 @@ static void taosFreeFdObj(SFdObj *pFdObj) {
|
|||
|
||||
tfree(pFdObj);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -22,9 +22,6 @@
|
|||
#include "ttimer.h"
|
||||
#include "tutil.h"
|
||||
|
||||
#ifdef USE_UV
|
||||
// no support upd currently
|
||||
#else
|
||||
#define RPC_MAX_UDP_CONNS 256
|
||||
#define RPC_MAX_UDP_PKTS 1000
|
||||
#define RPC_UDP_BUF_TIME 5 // mseconds
|
||||
|
@ -260,4 +257,3 @@ int taosSendUdpData(uint32_t ip, uint16_t port, void *data, int dataLen, void *c
|
|||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -12,3 +12,735 @@
|
|||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifdef USE_UV
|
||||
|
||||
#include <uv.h>
|
||||
#include "lz4.h"
|
||||
#include "os.h"
|
||||
#include "rpcCache.h"
|
||||
#include "rpcHead.h"
|
||||
#include "rpcLog.h"
|
||||
#include "rpcTcp.h"
|
||||
#include "rpcUdp.h"
|
||||
#include "taoserror.h"
|
||||
#include "tglobal.h"
|
||||
#include "thash.h"
|
||||
#include "tidpool.h"
|
||||
#include "tmd5.h"
|
||||
#include "tmempool.h"
|
||||
#include "tmsg.h"
|
||||
#include "transportInt.h"
|
||||
#include "tref.h"
|
||||
#include "trpc.h"
|
||||
#include "ttimer.h"
|
||||
#include "tutil.h"
|
||||
|
||||
#define container_of(ptr, type, member) ((type*)((char*)(ptr)-offsetof(type, member)))
|
||||
#define RPC_RESERVE_SIZE (sizeof(SRpcReqContext))
|
||||
static const char* notify = "a";
|
||||
|
||||
typedef struct {
|
||||
int sessions; // number of sessions allowed
|
||||
int numOfThreads; // number of threads to process incoming messages
|
||||
int idleTime; // milliseconds;
|
||||
uint16_t localPort;
|
||||
int8_t connType;
|
||||
int index; // for UDP server only, round robin for multiple threads
|
||||
char label[TSDB_LABEL_LEN];
|
||||
|
||||
char user[TSDB_UNI_LEN]; // meter ID
|
||||
char spi; // security parameter index
|
||||
char encrypt; // encrypt algorithm
|
||||
char secret[TSDB_PASSWORD_LEN]; // secret for the link
|
||||
char ckey[TSDB_PASSWORD_LEN]; // ciphering key
|
||||
|
||||
void (*cfp)(void* parent, SRpcMsg*, SEpSet*);
|
||||
int (*afp)(void* parent, char* user, char* spi, char* encrypt, char* secret, char* ckey);
|
||||
|
||||
int32_t refCount;
|
||||
void* parent;
|
||||
void* idPool; // handle to ID pool
|
||||
void* tmrCtrl; // handle to timer
|
||||
SHashObj* hash; // handle returned by hash utility
|
||||
void* tcphandle; // returned handle from TCP initialization
|
||||
void* udphandle; // returned handle from UDP initialization
|
||||
void* pCache; // connection cache
|
||||
pthread_mutex_t mutex;
|
||||
struct SRpcConn* connList; // connection list
|
||||
} SRpcInfo;
|
||||
|
||||
typedef struct {
|
||||
SRpcInfo* pRpc; // associated SRpcInfo
|
||||
SEpSet epSet; // ip list provided by app
|
||||
void* ahandle; // handle provided by app
|
||||
struct SRpcConn* pConn; // pConn allocated
|
||||
tmsg_t msgType; // message type
|
||||
uint8_t* pCont; // content provided by app
|
||||
int32_t contLen; // content length
|
||||
int32_t code; // error code
|
||||
int16_t numOfTry; // number of try for different servers
|
||||
int8_t oldInUse; // server EP inUse passed by app
|
||||
int8_t redirect; // flag to indicate redirect
|
||||
int8_t connType; // connection type
|
||||
int64_t rid; // refId returned by taosAddRef
|
||||
SRpcMsg* pRsp; // for synchronous API
|
||||
tsem_t* pSem; // for synchronous API
|
||||
SEpSet* pSet; // for synchronous API
|
||||
char msg[0]; // RpcHead starts from here
|
||||
} SRpcReqContext;
|
||||
|
||||
typedef struct SThreadObj {
|
||||
pthread_t thread;
|
||||
uv_pipe_t* pipe;
|
||||
int fd;
|
||||
uv_loop_t* loop;
|
||||
uv_async_t* workerAsync; //
|
||||
queue conn;
|
||||
pthread_mutex_t connMtx;
|
||||
void* shandle;
|
||||
} SThreadObj;
|
||||
|
||||
#define RPC_MSG_OVERHEAD (sizeof(SRpcReqContext) + sizeof(SRpcHead) + sizeof(SRpcDigest))
|
||||
#define rpcHeadFromCont(cont) ((SRpcHead*)((char*)cont - sizeof(SRpcHead)))
|
||||
#define rpcContFromHead(msg) (msg + sizeof(SRpcHead))
|
||||
#define rpcMsgLenFromCont(contLen) (contLen + sizeof(SRpcHead))
|
||||
#define rpcContLenFromMsg(msgLen) (msgLen - sizeof(SRpcHead))
|
||||
#define rpcIsReq(type) (type & 1U)
|
||||
|
||||
typedef struct SServerObj {
|
||||
pthread_t thread;
|
||||
uv_tcp_t server;
|
||||
uv_loop_t* loop;
|
||||
int workerIdx;
|
||||
int numOfThread;
|
||||
SThreadObj** pThreadObj;
|
||||
uv_pipe_t** pipe;
|
||||
uint32_t ip;
|
||||
uint32_t port;
|
||||
} SServerObj;
|
||||
|
||||
typedef struct SConnBuffer {
|
||||
char* buf;
|
||||
int len;
|
||||
int cap;
|
||||
int left;
|
||||
} SConnBuffer;
|
||||
|
||||
typedef struct SRpcConn {
|
||||
uv_tcp_t* pTcp;
|
||||
uv_write_t* pWriter;
|
||||
uv_timer_t* pTimer;
|
||||
|
||||
uv_async_t* pWorkerAsync;
|
||||
queue queue;
|
||||
int ref;
|
||||
int persist; // persist connection or not
|
||||
SConnBuffer connBuf; // read buf,
|
||||
SConnBuffer writeBuf; // write buf
|
||||
int count;
|
||||
void* shandle; // rpc init
|
||||
void* ahandle; //
|
||||
void* hostThread;
|
||||
// del later
|
||||
char secured;
|
||||
int spi;
|
||||
char info[64];
|
||||
char user[TSDB_UNI_LEN]; // user ID for the link
|
||||
char secret[TSDB_PASSWORD_LEN];
|
||||
char ckey[TSDB_PASSWORD_LEN]; // ciphering key
|
||||
} SRpcConn;
|
||||
|
||||
// auth function
|
||||
static int uvAuthMsg(SRpcConn* pConn, char* msg, int msgLen);
|
||||
static int rpcAuthenticateMsg(void* pMsg, int msgLen, void* pAuth, void* pKey);
|
||||
static void rpcBuildAuthHead(void* pMsg, int msgLen, void* pAuth, void* pKey);
|
||||
static int rpcAddAuthPart(SRpcConn* pConn, char* msg, int msgLen);
|
||||
// compress data
|
||||
static int32_t rpcCompressRpcMsg(char* pCont, int32_t contLen);
|
||||
static SRpcHead* rpcDecompressRpcMsg(SRpcHead* pHead);
|
||||
|
||||
static void uvAllocConnBufferCb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf);
|
||||
static void uvAllocReadBufferCb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf);
|
||||
static void uvOnReadCb(uv_stream_t* cli, ssize_t nread, const uv_buf_t* buf);
|
||||
static void uvOnTimeoutCb(uv_timer_t* handle);
|
||||
static void uvOnWriteCb(uv_write_t* req, int status);
|
||||
static void uvOnAcceptCb(uv_stream_t* stream, int status);
|
||||
static void uvOnConnectionCb(uv_stream_t* q, ssize_t nread, const uv_buf_t* buf);
|
||||
static void uvWorkerAsyncCb(uv_async_t* handle);
|
||||
|
||||
static SRpcConn* connCreate();
|
||||
static void connDestroy(SRpcConn* conn);
|
||||
static void uvConnDestroy(uv_handle_t* handle);
|
||||
|
||||
static void* workerThread(void* arg);
|
||||
static void* acceptThread(void* arg);
|
||||
|
||||
void* taosInitClient(uint32_t ip, uint32_t port, char* label, int numOfThreads, void* fp, void* shandle);
|
||||
void* taosInitServer(uint32_t ip, uint32_t port, char* label, int numOfThreads, void* fp, void* shandle);
|
||||
|
||||
void* taosInitServer(uint32_t ip, uint32_t port, char* label, int numOfThreads, void* fp, void* shandle) {
|
||||
SServerObj* srv = calloc(1, sizeof(SServerObj));
|
||||
srv->loop = (uv_loop_t*)malloc(sizeof(uv_loop_t));
|
||||
srv->numOfThread = numOfThreads;
|
||||
srv->workerIdx = 0;
|
||||
srv->pThreadObj = (SThreadObj**)calloc(srv->numOfThread, sizeof(SThreadObj*));
|
||||
srv->pipe = (uv_pipe_t**)calloc(srv->numOfThread, sizeof(uv_pipe_t*));
|
||||
srv->ip = ip;
|
||||
srv->port = port;
|
||||
uv_loop_init(srv->loop);
|
||||
|
||||
for (int i = 0; i < srv->numOfThread; i++) {
|
||||
SThreadObj* thrd = (SThreadObj*)calloc(1, sizeof(SThreadObj));
|
||||
srv->pipe[i] = (uv_pipe_t*)calloc(2, sizeof(uv_pipe_t));
|
||||
int fds[2];
|
||||
if (uv_socketpair(AF_UNIX, SOCK_STREAM, fds, UV_NONBLOCK_PIPE, UV_NONBLOCK_PIPE) != 0) {
|
||||
return NULL;
|
||||
}
|
||||
uv_pipe_init(srv->loop, &(srv->pipe[i][0]), 1);
|
||||
uv_pipe_open(&(srv->pipe[i][0]), fds[1]); // init write
|
||||
|
||||
thrd->shandle = shandle;
|
||||
thrd->fd = fds[0];
|
||||
thrd->pipe = &(srv->pipe[i][1]); // init read
|
||||
int err = pthread_create(&(thrd->thread), NULL, workerThread, (void*)(thrd));
|
||||
if (err == 0) {
|
||||
tDebug("sucess to create worker-thread %d", i);
|
||||
// printf("thread %d create\n", i);
|
||||
} else {
|
||||
// TODO: clear all other resource later
|
||||
tError("failed to create worker-thread %d", i);
|
||||
}
|
||||
srv->pThreadObj[i] = thrd;
|
||||
}
|
||||
|
||||
int err = pthread_create(&srv->thread, NULL, acceptThread, (void*)srv);
|
||||
if (err == 0) {
|
||||
tDebug("success to create accept-thread");
|
||||
} else {
|
||||
// clear all resource later
|
||||
}
|
||||
|
||||
return srv;
|
||||
}
|
||||
void uvAllocReadBufferCb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) {
|
||||
/*
|
||||
* formate of data buffer:
|
||||
* |<-------SRpcReqContext------->|<------------data read from socket----------->|
|
||||
*/
|
||||
static const int CAPACITY = 1024;
|
||||
|
||||
SRpcConn* ctx = handle->data;
|
||||
SConnBuffer* pBuf = &ctx->connBuf;
|
||||
if (pBuf->cap == 0) {
|
||||
pBuf->buf = (char*)calloc(CAPACITY + RPC_RESERVE_SIZE, sizeof(char));
|
||||
pBuf->len = 0;
|
||||
pBuf->cap = CAPACITY;
|
||||
pBuf->left = -1;
|
||||
|
||||
buf->base = pBuf->buf + RPC_RESERVE_SIZE;
|
||||
buf->len = CAPACITY;
|
||||
} else {
|
||||
if (pBuf->len >= pBuf->cap) {
|
||||
if (pBuf->left == -1) {
|
||||
pBuf->cap *= 2;
|
||||
pBuf->buf = realloc(pBuf->buf, pBuf->cap + RPC_RESERVE_SIZE);
|
||||
} else if (pBuf->len + pBuf->left > pBuf->cap) {
|
||||
pBuf->cap = pBuf->len + pBuf->left;
|
||||
pBuf->buf = realloc(pBuf->buf, pBuf->len + pBuf->left + RPC_RESERVE_SIZE);
|
||||
}
|
||||
}
|
||||
buf->base = pBuf->buf + pBuf->len + RPC_RESERVE_SIZE;
|
||||
buf->len = pBuf->cap - pBuf->len;
|
||||
}
|
||||
}
|
||||
// check data read from socket completely or not
|
||||
//
|
||||
static bool isReadAll(SConnBuffer* data) {
|
||||
// TODO(yihao): handle pipeline later
|
||||
SRpcHead rpcHead;
|
||||
int32_t headLen = sizeof(rpcHead);
|
||||
if (data->len >= headLen) {
|
||||
memcpy((char*)&rpcHead, data->buf + RPC_RESERVE_SIZE, headLen);
|
||||
int32_t msgLen = (int32_t)htonl((uint32_t)rpcHead.msgLen);
|
||||
if (msgLen > data->len) {
|
||||
data->left = msgLen - data->len;
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
static void uvDoProcess(SRecvInfo* pRecv) {
|
||||
SRpcHead* pHead = (SRpcHead*)pRecv->msg;
|
||||
SRpcInfo* pRpc = (SRpcInfo*)pRecv->shandle;
|
||||
SRpcConn* pConn = pRecv->thandle;
|
||||
|
||||
tDump(pRecv->msg, pRecv->msgLen);
|
||||
|
||||
terrno = 0;
|
||||
SRpcReqContext* pContest;
|
||||
|
||||
// do auth and check
|
||||
}
|
||||
static int uvAuthMsg(SRpcConn* pConn, char* msg, int len) {
|
||||
SRpcHead* pHead = (SRpcHead*)msg;
|
||||
int code = 0;
|
||||
|
||||
if ((pConn->secured && pHead->spi == 0) || (pHead->spi == 0 && pConn->spi == 0)) {
|
||||
// secured link, or no authentication
|
||||
pHead->msgLen = (int32_t)htonl((uint32_t)pHead->msgLen);
|
||||
// tTrace("%s, secured link, no auth is required", pConn->info);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!rpcIsReq(pHead->msgType)) {
|
||||
// for response, if code is auth failure, it shall bypass the auth process
|
||||
code = htonl(pHead->code);
|
||||
if (code == TSDB_CODE_RPC_INVALID_TIME_STAMP || code == TSDB_CODE_RPC_AUTH_FAILURE ||
|
||||
code == TSDB_CODE_RPC_INVALID_VERSION || code == TSDB_CODE_RPC_AUTH_REQUIRED ||
|
||||
code == TSDB_CODE_MND_USER_NOT_EXIST || code == TSDB_CODE_RPC_NOT_READY) {
|
||||
pHead->msgLen = (int32_t)htonl((uint32_t)pHead->msgLen);
|
||||
// tTrace("%s, dont check authentication since code is:0x%x", pConn->info, code);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
code = 0;
|
||||
if (pHead->spi == pConn->spi) {
|
||||
// authentication
|
||||
SRpcDigest* pDigest = (SRpcDigest*)((char*)pHead + len - sizeof(SRpcDigest));
|
||||
|
||||
int32_t delta;
|
||||
delta = (int32_t)htonl(pDigest->timeStamp);
|
||||
delta -= (int32_t)taosGetTimestampSec();
|
||||
if (abs(delta) > 900) {
|
||||
tWarn("%s, time diff:%d is too big, msg discarded", pConn->info, delta);
|
||||
code = TSDB_CODE_RPC_INVALID_TIME_STAMP;
|
||||
} else {
|
||||
if (rpcAuthenticateMsg(pHead, len - TSDB_AUTH_LEN, pDigest->auth, pConn->secret) < 0) {
|
||||
// tDebug("%s, authentication failed, msg discarded", pConn->info);
|
||||
code = TSDB_CODE_RPC_AUTH_FAILURE;
|
||||
} else {
|
||||
pHead->msgLen = (int32_t)htonl((uint32_t)pHead->msgLen) - sizeof(SRpcDigest);
|
||||
if (!rpcIsReq(pHead->msgType)) pConn->secured = 1; // link is secured for client
|
||||
// tTrace("%s, message is authenticated", pConn->info);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tDebug("%s, auth spi:%d not matched with received:%d", pConn->info, pConn->spi, pHead->spi);
|
||||
code = pHead->spi ? TSDB_CODE_RPC_AUTH_FAILURE : TSDB_CODE_RPC_AUTH_REQUIRED;
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
// refers specifically to query or insert timeout
|
||||
static void uvHandleActivityTimeout(uv_timer_t* handle) {
|
||||
// impl later
|
||||
SRpcConn* conn = handle->data;
|
||||
}
|
||||
static void uvProcessData(SRpcConn* pConn) {
|
||||
SRecvInfo info;
|
||||
SRecvInfo* p = &info;
|
||||
SConnBuffer* pBuf = &pConn->connBuf;
|
||||
p->msg = pBuf->buf + RPC_RESERVE_SIZE;
|
||||
p->msgLen = pBuf->len;
|
||||
p->ip = 0;
|
||||
p->port = 0;
|
||||
p->shandle = pConn->shandle; //
|
||||
p->thandle = pConn;
|
||||
p->chandle = NULL;
|
||||
|
||||
//
|
||||
SRpcHead* pHead = (SRpcHead*)p->msg;
|
||||
assert(rpcIsReq(pHead->msgType));
|
||||
|
||||
SRpcInfo* pRpc = (SRpcInfo*)p->shandle;
|
||||
pConn->ahandle = (void*)pHead->ahandle;
|
||||
// auth here
|
||||
|
||||
int8_t code = uvAuthMsg(pConn, (char*)pHead, p->msgLen);
|
||||
if (code != 0) {
|
||||
terrno = code;
|
||||
return;
|
||||
}
|
||||
pHead->code = htonl(pHead->code);
|
||||
|
||||
SRpcMsg rpcMsg;
|
||||
|
||||
pHead = rpcDecompressRpcMsg(pHead);
|
||||
rpcMsg.contLen = rpcContLenFromMsg(pHead->msgLen);
|
||||
rpcMsg.pCont = pHead->content;
|
||||
rpcMsg.msgType = pHead->msgType;
|
||||
rpcMsg.code = pHead->code;
|
||||
rpcMsg.ahandle = pConn->ahandle;
|
||||
rpcMsg.handle = pConn;
|
||||
|
||||
(*(pRpc->cfp))(pRpc->parent, &rpcMsg, NULL);
|
||||
uv_timer_start(pConn->pTimer, uvHandleActivityTimeout, pRpc->idleTime, 0);
|
||||
// auth
|
||||
// validate msg type
|
||||
}
|
||||
void uvOnReadCb(uv_stream_t* cli, ssize_t nread, const uv_buf_t* buf) {
|
||||
// opt
|
||||
SRpcConn* ctx = cli->data;
|
||||
SConnBuffer* pBuf = &ctx->connBuf;
|
||||
if (nread > 0) {
|
||||
pBuf->len += nread;
|
||||
if (isReadAll(pBuf)) {
|
||||
tDebug("alread read complete packet");
|
||||
uvProcessData(ctx);
|
||||
} else {
|
||||
tDebug("read half packet, continue to read");
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (terrno != 0) {
|
||||
// handle err code
|
||||
}
|
||||
|
||||
if (nread != UV_EOF) {
|
||||
tDebug("Read error %s\n", uv_err_name(nread));
|
||||
}
|
||||
uv_close((uv_handle_t*)cli, uvConnDestroy);
|
||||
}
|
||||
void uvAllocConnBufferCb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) {
|
||||
buf->base = malloc(sizeof(char));
|
||||
buf->len = 2;
|
||||
}
|
||||
|
||||
void uvOnTimeoutCb(uv_timer_t* handle) {
|
||||
// opt
|
||||
tDebug("time out");
|
||||
}
|
||||
|
||||
void uvOnWriteCb(uv_write_t* req, int status) {
|
||||
SRpcConn* conn = req->data;
|
||||
if (status == 0) {
|
||||
tDebug("data already was written on stream");
|
||||
} else {
|
||||
connDestroy(conn);
|
||||
}
|
||||
// opt
|
||||
}
|
||||
|
||||
void uvWorkerAsyncCb(uv_async_t* handle) {
|
||||
SThreadObj* pThrd = container_of(handle, SThreadObj, workerAsync);
|
||||
SRpcConn* conn = NULL;
|
||||
|
||||
// opt later
|
||||
pthread_mutex_lock(&pThrd->connMtx);
|
||||
if (!QUEUE_IS_EMPTY(&pThrd->conn)) {
|
||||
queue* head = QUEUE_HEAD(&pThrd->conn);
|
||||
conn = QUEUE_DATA(head, SRpcConn, queue);
|
||||
QUEUE_REMOVE(&conn->queue);
|
||||
}
|
||||
pthread_mutex_unlock(&pThrd->connMtx);
|
||||
if (conn == NULL) {
|
||||
tError("except occurred, do nothing");
|
||||
return;
|
||||
}
|
||||
uv_buf_t wb = uv_buf_init(conn->writeBuf.buf, conn->writeBuf.len);
|
||||
uv_write(conn->pWriter, (uv_stream_t*)conn->pTcp, &wb, 1, uvOnWriteCb);
|
||||
}
|
||||
|
||||
void uvOnAcceptCb(uv_stream_t* stream, int status) {
|
||||
if (status == -1) {
|
||||
return;
|
||||
}
|
||||
SServerObj* pObj = container_of(stream, SServerObj, server);
|
||||
|
||||
uv_tcp_t* cli = (uv_tcp_t*)malloc(sizeof(uv_tcp_t));
|
||||
uv_tcp_init(pObj->loop, cli);
|
||||
|
||||
if (uv_accept(stream, (uv_stream_t*)cli) == 0) {
|
||||
uv_write_t* wr = (uv_write_t*)malloc(sizeof(uv_write_t));
|
||||
|
||||
uv_buf_t buf = uv_buf_init((char*)notify, strlen(notify));
|
||||
|
||||
pObj->workerIdx = (pObj->workerIdx + 1) % pObj->numOfThread;
|
||||
tDebug("new conntion accepted by main server, dispatch to %dth worker-thread", pObj->workerIdx);
|
||||
uv_write2(wr, (uv_stream_t*)&(pObj->pipe[pObj->workerIdx][0]), &buf, 1, (uv_stream_t*)cli, uvOnWriteCb);
|
||||
} else {
|
||||
uv_close((uv_handle_t*)cli, NULL);
|
||||
}
|
||||
}
|
||||
void uvOnConnectionCb(uv_stream_t* q, ssize_t nread, const uv_buf_t* buf) {
|
||||
tDebug("connection coming");
|
||||
if (nread < 0) {
|
||||
if (nread != UV_EOF) {
|
||||
tError("read error %s", uv_err_name(nread));
|
||||
}
|
||||
// TODO(log other failure reason)
|
||||
uv_close((uv_handle_t*)q, NULL);
|
||||
return;
|
||||
}
|
||||
// free memory allocated by
|
||||
assert(nread == strlen(notify));
|
||||
assert(buf->base[0] == notify[0]);
|
||||
free(buf->base);
|
||||
|
||||
SThreadObj* pThrd = q->data;
|
||||
|
||||
uv_pipe_t* pipe = (uv_pipe_t*)q;
|
||||
if (!uv_pipe_pending_count(pipe)) {
|
||||
tError("No pending count");
|
||||
return;
|
||||
}
|
||||
|
||||
uv_handle_type pending = uv_pipe_pending_type(pipe);
|
||||
assert(pending == UV_TCP);
|
||||
|
||||
SRpcConn* pConn = connCreate();
|
||||
pConn->shandle = pThrd->shandle;
|
||||
/* init conn timer*/
|
||||
pConn->pTimer = malloc(sizeof(uv_timer_t));
|
||||
uv_timer_init(pThrd->loop, pConn->pTimer);
|
||||
pConn->pTimer->data = pConn;
|
||||
|
||||
pConn->hostThread = pThrd;
|
||||
pConn->pWorkerAsync = pThrd->workerAsync; // thread safty
|
||||
|
||||
// init client handle
|
||||
pConn->pTcp = (uv_tcp_t*)malloc(sizeof(uv_tcp_t));
|
||||
uv_tcp_init(pThrd->loop, pConn->pTcp);
|
||||
pConn->pTcp->data = pConn;
|
||||
|
||||
// init write request, just
|
||||
pConn->pWriter = calloc(1, sizeof(uv_write_t));
|
||||
pConn->pWriter->data = pConn;
|
||||
|
||||
if (uv_accept(q, (uv_stream_t*)(pConn->pTcp)) == 0) {
|
||||
uv_os_fd_t fd;
|
||||
uv_fileno((const uv_handle_t*)pConn->pTcp, &fd);
|
||||
tDebug("new connection created: %d", fd);
|
||||
uv_read_start((uv_stream_t*)(pConn->pTcp), uvAllocReadBufferCb, uvOnReadCb);
|
||||
} else {
|
||||
connDestroy(pConn);
|
||||
}
|
||||
}
|
||||
|
||||
void* acceptThread(void* arg) {
|
||||
// opt
|
||||
SServerObj* srv = (SServerObj*)arg;
|
||||
uv_tcp_init(srv->loop, &srv->server);
|
||||
|
||||
struct sockaddr_in bind_addr;
|
||||
|
||||
uv_ip4_addr("0.0.0.0", srv->port, &bind_addr);
|
||||
uv_tcp_bind(&srv->server, (const struct sockaddr*)&bind_addr, 0);
|
||||
int err = 0;
|
||||
if ((err = uv_listen((uv_stream_t*)&srv->server, 128, uvOnAcceptCb)) != 0) {
|
||||
tError("Listen error %s\n", uv_err_name(err));
|
||||
return NULL;
|
||||
}
|
||||
uv_run(srv->loop, UV_RUN_DEFAULT);
|
||||
}
|
||||
void* workerThread(void* arg) {
|
||||
SThreadObj* pThrd = (SThreadObj*)arg;
|
||||
|
||||
pThrd->loop = (uv_loop_t*)malloc(sizeof(uv_loop_t));
|
||||
uv_loop_init(pThrd->loop);
|
||||
|
||||
uv_pipe_init(pThrd->loop, pThrd->pipe, 1);
|
||||
uv_pipe_open(pThrd->pipe, pThrd->fd);
|
||||
|
||||
pThrd->pipe->data = pThrd;
|
||||
|
||||
QUEUE_INIT(&pThrd->conn);
|
||||
|
||||
pThrd->workerAsync = malloc(sizeof(uv_async_t));
|
||||
uv_async_init(pThrd->loop, pThrd->workerAsync, uvWorkerAsyncCb);
|
||||
|
||||
uv_read_start((uv_stream_t*)pThrd->pipe, uvAllocConnBufferCb, uvOnConnectionCb);
|
||||
uv_run(pThrd->loop, UV_RUN_DEFAULT);
|
||||
}
|
||||
static SRpcConn* connCreate() {
|
||||
SRpcConn* pConn = (SRpcConn*)calloc(1, sizeof(SRpcConn));
|
||||
return pConn;
|
||||
}
|
||||
static void connDestroy(SRpcConn* conn) {
|
||||
if (conn == NULL) {
|
||||
return;
|
||||
}
|
||||
uv_timer_stop(conn->pTimer);
|
||||
free(conn->pTimer);
|
||||
uv_close((uv_handle_t*)conn->pTcp, NULL);
|
||||
free(conn->connBuf.buf);
|
||||
free(conn->pTcp);
|
||||
free(conn->pWriter);
|
||||
free(conn);
|
||||
// handle
|
||||
}
|
||||
static void uvConnDestroy(uv_handle_t* handle) {
|
||||
SRpcConn* conn = handle->data;
|
||||
connDestroy(conn);
|
||||
}
|
||||
void* rpcOpen(const SRpcInit* pInit) {
|
||||
SRpcInfo* pRpc = calloc(1, sizeof(SRpcInfo));
|
||||
if (pRpc == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (pInit->label) {
|
||||
tstrncpy(pRpc->label, pInit->label, strlen(pInit->label));
|
||||
}
|
||||
pRpc->numOfThreads = pInit->numOfThreads > TSDB_MAX_RPC_THREADS ? TSDB_MAX_RPC_THREADS : pInit->numOfThreads;
|
||||
pRpc->tcphandle = taosInitServer(0, pInit->localPort, pRpc->label, pRpc->numOfThreads, NULL, pRpc);
|
||||
return pRpc;
|
||||
}
|
||||
void rpcClose(void* arg) { return; }
|
||||
void* rpcMallocCont(int contLen) { return NULL; }
|
||||
void rpcFreeCont(void* cont) { return; }
|
||||
void* rpcReallocCont(void* ptr, int contLen) { return NULL; }
|
||||
|
||||
void rpcSendRequest(void* thandle, const SEpSet* pEpSet, SRpcMsg* pMsg, int64_t* rid) {
|
||||
// impl later
|
||||
return;
|
||||
}
|
||||
|
||||
void rpcSendResponse(const SRpcMsg* pMsg) {
|
||||
SRpcConn* pConn = pMsg->handle;
|
||||
SThreadObj* pThrd = pConn->hostThread;
|
||||
|
||||
// opt later
|
||||
pthread_mutex_lock(&pThrd->connMtx);
|
||||
QUEUE_PUSH(&pThrd->conn, &pConn->queue);
|
||||
pthread_mutex_unlock(&pThrd->connMtx);
|
||||
|
||||
uv_async_send(pConn->pWorkerAsync);
|
||||
}
|
||||
|
||||
void rpcSendRedirectRsp(void* pConn, const SEpSet* pEpSet) {}
|
||||
int rpcGetConnInfo(void* thandle, SRpcConnInfo* pInfo) { return -1; }
|
||||
void rpcSendRecv(void* shandle, SEpSet* pEpSet, SRpcMsg* pReq, SRpcMsg* pRsp) { return; }
|
||||
int rpcReportProgress(void* pConn, char* pCont, int contLen) { return -1; }
|
||||
void rpcCancelRequest(int64_t rid) { return; }
|
||||
|
||||
static int rpcAuthenticateMsg(void* pMsg, int msgLen, void* pAuth, void* pKey) {
|
||||
T_MD5_CTX context;
|
||||
int ret = -1;
|
||||
|
||||
tMD5Init(&context);
|
||||
tMD5Update(&context, (uint8_t*)pKey, TSDB_PASSWORD_LEN);
|
||||
tMD5Update(&context, (uint8_t*)pMsg, msgLen);
|
||||
tMD5Update(&context, (uint8_t*)pKey, TSDB_PASSWORD_LEN);
|
||||
tMD5Final(&context);
|
||||
|
||||
if (memcmp(context.digest, pAuth, sizeof(context.digest)) == 0) ret = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
static void rpcBuildAuthHead(void* pMsg, int msgLen, void* pAuth, void* pKey) {
|
||||
T_MD5_CTX context;
|
||||
|
||||
tMD5Init(&context);
|
||||
tMD5Update(&context, (uint8_t*)pKey, TSDB_PASSWORD_LEN);
|
||||
tMD5Update(&context, (uint8_t*)pMsg, msgLen);
|
||||
tMD5Update(&context, (uint8_t*)pKey, TSDB_PASSWORD_LEN);
|
||||
tMD5Final(&context);
|
||||
|
||||
memcpy(pAuth, context.digest, sizeof(context.digest));
|
||||
}
|
||||
|
||||
static int rpcAddAuthPart(SRpcConn* pConn, char* msg, int msgLen) {
|
||||
SRpcHead* pHead = (SRpcHead*)msg;
|
||||
|
||||
if (pConn->spi && pConn->secured == 0) {
|
||||
// add auth part
|
||||
pHead->spi = pConn->spi;
|
||||
SRpcDigest* pDigest = (SRpcDigest*)(msg + msgLen);
|
||||
pDigest->timeStamp = htonl(taosGetTimestampSec());
|
||||
msgLen += sizeof(SRpcDigest);
|
||||
pHead->msgLen = (int32_t)htonl((uint32_t)msgLen);
|
||||
rpcBuildAuthHead(pHead, msgLen - TSDB_AUTH_LEN, pDigest->auth, pConn->secret);
|
||||
} else {
|
||||
pHead->spi = 0;
|
||||
pHead->msgLen = (int32_t)htonl((uint32_t)msgLen);
|
||||
}
|
||||
|
||||
return msgLen;
|
||||
}
|
||||
|
||||
static int32_t rpcCompressRpcMsg(char* pCont, int32_t contLen) {
|
||||
SRpcHead* pHead = rpcHeadFromCont(pCont);
|
||||
int32_t finalLen = 0;
|
||||
int overhead = sizeof(SRpcComp);
|
||||
|
||||
if (!NEEDTO_COMPRESSS_MSG(contLen)) {
|
||||
return contLen;
|
||||
}
|
||||
|
||||
char* buf = malloc(contLen + overhead + 8); // 8 extra bytes
|
||||
if (buf == NULL) {
|
||||
tError("failed to allocate memory for rpc msg compression, contLen:%d", contLen);
|
||||
return contLen;
|
||||
}
|
||||
|
||||
int32_t compLen = LZ4_compress_default(pCont, buf, contLen, contLen + overhead);
|
||||
tDebug("compress rpc msg, before:%d, after:%d, overhead:%d", contLen, compLen, overhead);
|
||||
|
||||
/*
|
||||
* only the compressed size is less than the value of contLen - overhead, the compression is applied
|
||||
* The first four bytes is set to 0, the second four bytes are utilized to keep the original length of message
|
||||
*/
|
||||
if (compLen > 0 && compLen < contLen - overhead) {
|
||||
SRpcComp* pComp = (SRpcComp*)pCont;
|
||||
pComp->reserved = 0;
|
||||
pComp->contLen = htonl(contLen);
|
||||
memcpy(pCont + overhead, buf, compLen);
|
||||
|
||||
pHead->comp = 1;
|
||||
tDebug("compress rpc msg, before:%d, after:%d", contLen, compLen);
|
||||
finalLen = compLen + overhead;
|
||||
} else {
|
||||
finalLen = contLen;
|
||||
}
|
||||
|
||||
free(buf);
|
||||
return finalLen;
|
||||
}
|
||||
|
||||
static SRpcHead* rpcDecompressRpcMsg(SRpcHead* pHead) {
|
||||
int overhead = sizeof(SRpcComp);
|
||||
SRpcHead* pNewHead = NULL;
|
||||
uint8_t* pCont = pHead->content;
|
||||
SRpcComp* pComp = (SRpcComp*)pHead->content;
|
||||
|
||||
if (pHead->comp) {
|
||||
// decompress the content
|
||||
assert(pComp->reserved == 0);
|
||||
int contLen = htonl(pComp->contLen);
|
||||
|
||||
// prepare the temporary buffer to decompress message
|
||||
char* temp = (char*)malloc(contLen + RPC_MSG_OVERHEAD);
|
||||
pNewHead = (SRpcHead*)(temp + sizeof(SRpcReqContext)); // reserve SRpcReqContext
|
||||
|
||||
if (pNewHead) {
|
||||
int compLen = rpcContLenFromMsg(pHead->msgLen) - overhead;
|
||||
int origLen = LZ4_decompress_safe((char*)(pCont + overhead), (char*)pNewHead->content, compLen, contLen);
|
||||
assert(origLen == contLen);
|
||||
|
||||
memcpy(pNewHead, pHead, sizeof(SRpcHead));
|
||||
pNewHead->msgLen = rpcMsgLenFromCont(origLen);
|
||||
/// rpcFreeMsg(pHead); // free the compressed message buffer
|
||||
pHead = pNewHead;
|
||||
tTrace("decomp malloc mem:%p", temp);
|
||||
} else {
|
||||
tError("failed to allocate memory to decompress msg, contLen:%d", contLen);
|
||||
}
|
||||
}
|
||||
|
||||
return pHead;
|
||||
}
|
||||
int32_t rpcInit(void) {
|
||||
// impl later
|
||||
return -1;
|
||||
}
|
||||
|
||||
void rpcCleanup(void) {
|
||||
// impl later
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
add_executable(transportTest "")
|
||||
target_sources(transportTest
|
||||
PRIVATE
|
||||
"transportTests.cc"
|
||||
)
|
||||
|
||||
target_include_directories(transportTest
|
||||
PUBLIC
|
||||
"${CMAKE_SOURCE_DIR}/include/libs/transport"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../inc"
|
||||
)
|
||||
|
||||
target_link_libraries (transportTest
|
||||
os
|
||||
util
|
||||
common
|
||||
gtest_main
|
||||
transport
|
||||
)
|
||||
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifdef USE_UV
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
#include "transportInt.h"
|
||||
#include "trpc.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
struct QueueElem {
|
||||
queue q;
|
||||
int val;
|
||||
};
|
||||
class QueueObj {
|
||||
public:
|
||||
QueueObj() {
|
||||
// avoid formate
|
||||
QUEUE_INIT(&head);
|
||||
}
|
||||
void Push(QueueElem *el) {
|
||||
// avoid formate
|
||||
QUEUE_PUSH(&head, &el->q);
|
||||
}
|
||||
QueueElem *Pop() {
|
||||
QueueElem *el = NULL;
|
||||
if (!IsEmpty()) {
|
||||
queue *h = QUEUE_HEAD(&head);
|
||||
el = QUEUE_DATA(h, QueueElem, q);
|
||||
QUEUE_REMOVE(&el->q);
|
||||
}
|
||||
return el;
|
||||
}
|
||||
bool IsEmpty() {
|
||||
// avoid formate
|
||||
return QUEUE_IS_EMPTY(&head);
|
||||
}
|
||||
void RmElem(QueueElem *el) {
|
||||
// impl
|
||||
QUEUE_REMOVE(&el->q);
|
||||
}
|
||||
void ForEach(std::vector<int> &result) {
|
||||
queue *h;
|
||||
QUEUE_FOREACH(h, &head) {
|
||||
// add more
|
||||
QueueElem *el = QUEUE_DATA(h, QueueElem, q);
|
||||
result.push_back(el->val);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
queue head;
|
||||
};
|
||||
|
||||
class QueueEnv : public ::testing::Test {
|
||||
protected:
|
||||
virtual void SetUp() {
|
||||
// TODO
|
||||
q = new QueueObj();
|
||||
}
|
||||
virtual void TearDown() {
|
||||
delete q;
|
||||
// formate
|
||||
}
|
||||
QueueObj *q;
|
||||
};
|
||||
|
||||
TEST_F(QueueEnv, testPushAndPop) {
|
||||
// add more test
|
||||
assert(q->IsEmpty());
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
QueueElem *el = (QueueElem *)malloc(sizeof(QueueElem));
|
||||
el->val = i;
|
||||
q->Push(el);
|
||||
}
|
||||
int i = 0;
|
||||
while (!q->IsEmpty()) {
|
||||
QueueElem *el = q->Pop();
|
||||
assert(el->val == i++);
|
||||
free(el);
|
||||
}
|
||||
assert(q->IsEmpty());
|
||||
}
|
||||
TEST_F(QueueEnv, testRm) {
|
||||
// add more test
|
||||
|
||||
std::vector<QueueElem *> set;
|
||||
assert(q->IsEmpty());
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
QueueElem *el = (QueueElem *)malloc(sizeof(QueueElem));
|
||||
el->val = i;
|
||||
q->Push(el);
|
||||
set.push_back(el);
|
||||
}
|
||||
for (int i = set.size() - 1; i >= 0; i--) {
|
||||
QueueElem *el = set[i];
|
||||
q->RmElem(el);
|
||||
free(el);
|
||||
}
|
||||
assert(q->IsEmpty());
|
||||
}
|
||||
TEST_F(QueueEnv, testIter) {
|
||||
// add more test
|
||||
assert(q->IsEmpty());
|
||||
std::vector<int> vals;
|
||||
for (int i = 0; i < 100; i++) {
|
||||
QueueElem *el = (QueueElem *)malloc(sizeof(QueueElem));
|
||||
el->val = i;
|
||||
q->Push(el);
|
||||
vals.push_back(i);
|
||||
}
|
||||
std::vector<int> result;
|
||||
q->ForEach(result);
|
||||
assert(result.size() == vals.size());
|
||||
}
|
||||
|
||||
#endif
|
|
@ -354,6 +354,14 @@ TAOS_DEFINE_ERROR(TSDB_CODE_QRY_SCH_NOT_EXIST, "Scheduler not exist")
|
|||
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_TASK_NOT_EXIST, "Task not exist")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_TASK_ALREADY_EXIST, "Task already exist")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_RES_CACHE_NOT_EXIST, "Task result cache not exist")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_TASK_CANCELLED, "Task cancelled")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_TASK_DROPPED, "Task dropped")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_TASK_CANCELLING, "Task cancelling")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_TASK_DROPPING, "Task dropping")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_DUPLICATTED_OPERATION, "Duplicatted operation")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_TASK_MSG_ERROR, "Task message error")
|
||||
|
||||
|
||||
|
||||
// grant
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_EXPIRED, "License expired")
|
||||
|
|
|
@ -187,13 +187,19 @@ void *threadFunc(void *param) {
|
|||
int64_t curMs = 0;
|
||||
int64_t beginMs = taosGetTimestampMs();
|
||||
pInfo->startMs = beginMs;
|
||||
for (int64_t t = pInfo->tableBeginIndex; t < pInfo->tableEndIndex; ++t) {
|
||||
int64_t batch = (pInfo->tableEndIndex - t);
|
||||
batch = MIN(batch, batchNum);
|
||||
int64_t t = pInfo->tableBeginIndex;
|
||||
for (; t <= pInfo->tableEndIndex;) {
|
||||
//int64_t batch = (pInfo->tableEndIndex - t);
|
||||
//batch = MIN(batch, batchNum);
|
||||
|
||||
int32_t len = sprintf(qstr, "create table");
|
||||
for (int32_t i = 0; i < batch; ++i) {
|
||||
len += sprintf(qstr + len, " t%" PRId64 " using %s tags(%" PRId64 ")", t + i, stbName, t + i);
|
||||
for (int32_t i = 0; i < batchNum;) {
|
||||
len += sprintf(qstr + len, " %s_t%" PRId64 " using %s tags(%" PRId64 ")", stbName, t, stbName, t);
|
||||
t++;
|
||||
i++;
|
||||
if (t > pInfo->tableEndIndex) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int64_t startTs = taosGetTimestampUs();
|
||||
|
@ -212,11 +218,11 @@ void *threadFunc(void *param) {
|
|||
curMs = taosGetTimestampMs();
|
||||
if (curMs - beginMs > 10000) {
|
||||
beginMs = curMs;
|
||||
//printf("==== tableBeginIndex: %"PRId64", t: %"PRId64"\n", pInfo->tableBeginIndex, t);
|
||||
printCreateProgress(pInfo, t);
|
||||
}
|
||||
t += (batch - 1);
|
||||
}
|
||||
printCreateProgress(pInfo, pInfo->tableEndIndex);
|
||||
printCreateProgress(pInfo, t);
|
||||
}
|
||||
|
||||
if (insertData) {
|
||||
|
|
Loading…
Reference in New Issue