commit
61127a95ee
|
@ -72,9 +72,6 @@
|
||||||
# time interval of heart beat from shell to dnode, seconds
|
# time interval of heart beat from shell to dnode, seconds
|
||||||
# shellActivityTimer 3
|
# shellActivityTimer 3
|
||||||
|
|
||||||
# time of keeping table meta data in cache, seconds
|
|
||||||
# tableMetaKeepTimer 7200
|
|
||||||
|
|
||||||
# minimum sliding window time, milli-second
|
# minimum sliding window time, milli-second
|
||||||
# minSlidingTime 10
|
# minSlidingTime 10
|
||||||
|
|
||||||
|
|
|
@ -300,8 +300,8 @@ typedef struct STscObj {
|
||||||
void * pTimer;
|
void * pTimer;
|
||||||
char user[TSDB_USER_LEN];
|
char user[TSDB_USER_LEN];
|
||||||
char pass[TSDB_KEY_LEN];
|
char pass[TSDB_KEY_LEN];
|
||||||
char acctId[TSDB_ACCT_LEN];
|
char acctId[TSDB_ACCT_ID_LEN];
|
||||||
char db[TSDB_ACCT_LEN + TSDB_DB_NAME_LEN];
|
char db[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN];
|
||||||
char sversion[TSDB_VERSION_LEN];
|
char sversion[TSDB_VERSION_LEN];
|
||||||
char writeAuth : 1;
|
char writeAuth : 1;
|
||||||
char superAuth : 1;
|
char superAuth : 1;
|
||||||
|
|
|
@ -221,7 +221,7 @@ static int32_t handlePassword(SSqlCmd* pCmd, SStrToken* pPwd) {
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pPwd->n >= TSDB_PASSWORD_LEN) {
|
if (pPwd->n >= TSDB_KEY_LEN) {
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1242,7 +1242,7 @@ int32_t setObjFullName(char* fullName, const char* account, SStrToken* pDB, SStr
|
||||||
|
|
||||||
/* db name is not specified, the tableName dose not include db name */
|
/* db name is not specified, the tableName dose not include db name */
|
||||||
if (pDB != NULL) {
|
if (pDB != NULL) {
|
||||||
if (pDB->n >= TSDB_ACCT_LEN + TSDB_DB_NAME_LEN || pDB->n == 0) {
|
if (pDB->n >= TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN || pDB->n == 0) {
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
return TSDB_CODE_TSC_INVALID_SQL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1975,9 +1975,6 @@ int tscProcessMultiMeterMetaRsp(SSqlObj *pSql) {
|
||||||
//
|
//
|
||||||
// rsp += tagLen;
|
// rsp += tagLen;
|
||||||
// int32_t size = (int32_t)(rsp - ((char *)pMeta)); // Consistent with STableMeta in cache
|
// int32_t size = (int32_t)(rsp - ((char *)pMeta)); // Consistent with STableMeta in cache
|
||||||
//
|
|
||||||
// pMeta->index = 0;
|
|
||||||
// (void)taosCachePut(tscMetaCache, pMeta->tableId, (char *)pMeta, size, tsTableMetaKeepTimer);
|
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ static bool validUserName(const char* user) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool validPassword(const char* passwd) {
|
static bool validPassword(const char* passwd) {
|
||||||
return validImpl(passwd, TSDB_PASSWORD_LEN - 1);
|
return validImpl(passwd, TSDB_KEY_LEN - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static SSqlObj *taosConnectImpl(const char *ip, const char *user, const char *pass, const char *auth, const char *db,
|
static SSqlObj *taosConnectImpl(const char *ip, const char *user, const char *pass, const char *auth, const char *db,
|
||||||
|
@ -238,11 +238,11 @@ TAOS *taos_connect_c(const char *ip, uint8_t ipLen, const char *user, uint8_t us
|
||||||
uint8_t passLen, const char *db, uint8_t dbLen, uint16_t port) {
|
uint8_t passLen, const char *db, uint8_t dbLen, uint16_t port) {
|
||||||
char ipBuf[TSDB_EP_LEN] = {0};
|
char ipBuf[TSDB_EP_LEN] = {0};
|
||||||
char userBuf[TSDB_USER_LEN] = {0};
|
char userBuf[TSDB_USER_LEN] = {0};
|
||||||
char passBuf[TSDB_PASSWORD_LEN] = {0};
|
char passBuf[TSDB_KEY_LEN] = {0};
|
||||||
char dbBuf[TSDB_DB_NAME_LEN] = {0};
|
char dbBuf[TSDB_DB_NAME_LEN] = {0};
|
||||||
strncpy(ipBuf, ip, MIN(TSDB_EP_LEN - 1, ipLen));
|
strncpy(ipBuf, ip, MIN(TSDB_EP_LEN - 1, ipLen));
|
||||||
strncpy(userBuf, user, MIN(TSDB_USER_LEN - 1, userLen));
|
strncpy(userBuf, user, MIN(TSDB_USER_LEN - 1, userLen));
|
||||||
strncpy(passBuf, pass, MIN(TSDB_PASSWORD_LEN - 1, passLen));
|
strncpy(passBuf, pass, MIN(TSDB_KEY_LEN - 1, passLen));
|
||||||
strncpy(dbBuf, db, MIN(TSDB_DB_NAME_LEN - 1, dbLen));
|
strncpy(dbBuf, db, MIN(TSDB_DB_NAME_LEN - 1, dbLen));
|
||||||
return taos_connect(ipBuf, userBuf, passBuf, dbBuf, port);
|
return taos_connect(ipBuf, userBuf, passBuf, dbBuf, port);
|
||||||
}
|
}
|
||||||
|
@ -978,7 +978,7 @@ static int tscParseTblNameList(SSqlObj *pSql, const char *tblNameList, int32_t t
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (++pCmd->count > TSDB_MULTI_METERMETA_MAX_NUM) {
|
if (++pCmd->count > TSDB_MULTI_TABLEMETA_MAX_NUM) {
|
||||||
code = TSDB_CODE_TSC_INVALID_TABLE_ID_LENGTH;
|
code = TSDB_CODE_TSC_INVALID_TABLE_ID_LENGTH;
|
||||||
sprintf(pCmd->payload, "tables over the max number");
|
sprintf(pCmd->payload, "tables over the max number");
|
||||||
return code;
|
return code;
|
||||||
|
|
|
@ -162,6 +162,10 @@ TEST(testCase, parse_time) {
|
||||||
|
|
||||||
taosParseTime(t13, &time, strlen(t13), TSDB_TIME_PRECISION_MILLI, 0);
|
taosParseTime(t13, &time, strlen(t13), TSDB_TIME_PRECISION_MILLI, 0);
|
||||||
EXPECT_EQ(time, -28800 * MILLISECOND_PER_SECOND);
|
EXPECT_EQ(time, -28800 * MILLISECOND_PER_SECOND);
|
||||||
|
|
||||||
|
char* t = "2021-01-08T02:11:40.000+00:00";
|
||||||
|
taosParseTime(t, &time, strlen(t), TSDB_TIME_PRECISION_MILLI, 0);
|
||||||
|
printf("%ld\n", time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,6 @@ extern int32_t tsRetrieveBlockingModel;// retrieve threads will be blocked
|
||||||
extern int8_t tsKeepOriginalColumnName;
|
extern int8_t tsKeepOriginalColumnName;
|
||||||
|
|
||||||
// client
|
// client
|
||||||
extern int32_t tsTableMetaKeepTimer;
|
|
||||||
extern int32_t tsMaxSQLStringLen;
|
extern int32_t tsMaxSQLStringLen;
|
||||||
extern int8_t tsTscEnableRecordSql;
|
extern int8_t tsTscEnableRecordSql;
|
||||||
extern int32_t tsMaxNumOfOrderedResults;
|
extern int32_t tsMaxNumOfOrderedResults;
|
||||||
|
|
|
@ -72,7 +72,6 @@ char tsTempDir[TSDB_FILENAME_LEN] = "/tmp/";
|
||||||
int32_t tsCompressMsgSize = -1;
|
int32_t tsCompressMsgSize = -1;
|
||||||
|
|
||||||
// client
|
// client
|
||||||
int32_t tsTableMetaKeepTimer = 7200; // second
|
|
||||||
int32_t tsMaxSQLStringLen = TSDB_MAX_SQL_LEN;
|
int32_t tsMaxSQLStringLen = TSDB_MAX_SQL_LEN;
|
||||||
int8_t tsTscEnableRecordSql = 0;
|
int8_t tsTscEnableRecordSql = 0;
|
||||||
|
|
||||||
|
@ -596,16 +595,6 @@ static void doInitGlobalConfig(void) {
|
||||||
cfg.unitType = TAOS_CFG_UTYPE_SECOND;
|
cfg.unitType = TAOS_CFG_UTYPE_SECOND;
|
||||||
taosInitConfigOption(cfg);
|
taosInitConfigOption(cfg);
|
||||||
|
|
||||||
cfg.option = "tableMetaKeepTimer";
|
|
||||||
cfg.ptr = &tsTableMetaKeepTimer;
|
|
||||||
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
|
||||||
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_CLIENT;
|
|
||||||
cfg.minValue = 1;
|
|
||||||
cfg.maxValue = 8640000;
|
|
||||||
cfg.ptrLength = 0;
|
|
||||||
cfg.unitType = TAOS_CFG_UTYPE_SECOND;
|
|
||||||
taosInitConfigOption(cfg);
|
|
||||||
|
|
||||||
cfg.option = "minSlidingTime";
|
cfg.option = "minSlidingTime";
|
||||||
cfg.ptr = &tsMinSlidingTime;
|
cfg.ptr = &tsMinSlidingTime;
|
||||||
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
||||||
|
|
|
@ -43,7 +43,7 @@ typedef struct {
|
||||||
int32_t master;
|
int32_t master;
|
||||||
int32_t num; // number of continuous streams
|
int32_t num; // number of continuous streams
|
||||||
char user[TSDB_USER_LEN];
|
char user[TSDB_USER_LEN];
|
||||||
char pass[TSDB_PASSWORD_LEN];
|
char pass[TSDB_KEY_LEN];
|
||||||
char db[TSDB_DB_NAME_LEN];
|
char db[TSDB_DB_NAME_LEN];
|
||||||
FCqWrite cqWrite;
|
FCqWrite cqWrite;
|
||||||
struct SCqObj *pHead;
|
struct SCqObj *pHead;
|
||||||
|
|
|
@ -256,10 +256,8 @@ int32_t tStrToInteger(const char* z, int16_t type, int32_t n, int64_t* value, bo
|
||||||
#define TSDB_USER_LEN TSDB_UNI_LEN
|
#define TSDB_USER_LEN TSDB_UNI_LEN
|
||||||
|
|
||||||
// ACCOUNT is a 32 bit positive integer
|
// ACCOUNT is a 32 bit positive integer
|
||||||
// this is the length of its string representation
|
// this is the length of its string representation, including the terminator zero
|
||||||
// including the terminator zero
|
#define TSDB_ACCT_ID_LEN 11
|
||||||
#define TSDB_ACCT_LEN 11
|
|
||||||
#define TSDB_PASSWORD_LEN TSDB_UNI_LEN
|
|
||||||
|
|
||||||
#define TSDB_MAX_COLUMNS 1024
|
#define TSDB_MAX_COLUMNS 1024
|
||||||
#define TSDB_MIN_COLUMNS 2 //PRIMARY COLUMN(timestamp) + other columns
|
#define TSDB_MIN_COLUMNS 2 //PRIMARY COLUMN(timestamp) + other columns
|
||||||
|
@ -267,7 +265,7 @@ int32_t tStrToInteger(const char* z, int16_t type, int32_t n, int64_t* value, bo
|
||||||
#define TSDB_NODE_NAME_LEN 64
|
#define TSDB_NODE_NAME_LEN 64
|
||||||
#define TSDB_TABLE_NAME_LEN 193 // it is a null-terminated string
|
#define TSDB_TABLE_NAME_LEN 193 // it is a null-terminated string
|
||||||
#define TSDB_DB_NAME_LEN 33
|
#define TSDB_DB_NAME_LEN 33
|
||||||
#define TSDB_TABLE_FNAME_LEN (TSDB_ACCT_LEN + TSDB_DB_NAME_LEN + TSDB_TABLE_NAME_LEN)
|
#define TSDB_TABLE_FNAME_LEN (TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN + TSDB_TABLE_NAME_LEN)
|
||||||
#define TSDB_COL_NAME_LEN 65
|
#define TSDB_COL_NAME_LEN 65
|
||||||
#define TSDB_MAX_SAVED_SQL_LEN TSDB_MAX_COLUMNS * 64
|
#define TSDB_MAX_SAVED_SQL_LEN TSDB_MAX_COLUMNS * 64
|
||||||
#define TSDB_MAX_SQL_LEN TSDB_PAYLOAD_SIZE
|
#define TSDB_MAX_SQL_LEN TSDB_PAYLOAD_SIZE
|
||||||
|
@ -293,11 +291,6 @@ int32_t tStrToInteger(const char* z, int16_t type, int32_t n, int64_t* value, bo
|
||||||
#define TSDB_EP_LEN (TSDB_FQDN_LEN+6)
|
#define TSDB_EP_LEN (TSDB_FQDN_LEN+6)
|
||||||
#define TSDB_IPv4ADDR_LEN 16
|
#define TSDB_IPv4ADDR_LEN 16
|
||||||
#define TSDB_FILENAME_LEN 128
|
#define TSDB_FILENAME_LEN 128
|
||||||
#define TSDB_METER_VNODE_BITS 20
|
|
||||||
#define TSDB_METER_SID_MASK 0xFFFFF
|
|
||||||
#define TSDB_SHELL_VNODE_BITS 24
|
|
||||||
#define TSDB_SHELL_SID_MASK 0xFF
|
|
||||||
#define TSDB_HTTP_TOKEN_LEN 20
|
|
||||||
#define TSDB_SHOW_SQL_LEN 512
|
#define TSDB_SHOW_SQL_LEN 512
|
||||||
#define TSDB_SLOW_QUERY_SQL_LEN 512
|
#define TSDB_SLOW_QUERY_SQL_LEN 512
|
||||||
|
|
||||||
|
@ -311,9 +304,6 @@ int32_t tStrToInteger(const char* z, int16_t type, int32_t n, int64_t* value, bo
|
||||||
#define TSDB_MQTT_TOPIC_LEN 64
|
#define TSDB_MQTT_TOPIC_LEN 64
|
||||||
#define TSDB_MQTT_CLIENT_ID_LEN 32
|
#define TSDB_MQTT_CLIENT_ID_LEN 32
|
||||||
|
|
||||||
#define TSDB_METER_STATE_OFFLINE 0
|
|
||||||
#define TSDB_METER_STATE_ONLLINE 1
|
|
||||||
|
|
||||||
#define TSDB_DEFAULT_PKT_SIZE 65480 //same as RPC_MAX_UDP_SIZE
|
#define TSDB_DEFAULT_PKT_SIZE 65480 //same as RPC_MAX_UDP_SIZE
|
||||||
|
|
||||||
#define TSDB_PAYLOAD_SIZE TSDB_DEFAULT_PKT_SIZE
|
#define TSDB_PAYLOAD_SIZE TSDB_DEFAULT_PKT_SIZE
|
||||||
|
@ -333,7 +323,7 @@ int32_t tStrToInteger(const char* z, int16_t type, int32_t n, int64_t* value, bo
|
||||||
|
|
||||||
#define TSDB_TBNAME_COLUMN_INDEX (-1)
|
#define TSDB_TBNAME_COLUMN_INDEX (-1)
|
||||||
#define TSDB_UD_COLUMN_INDEX (-100)
|
#define TSDB_UD_COLUMN_INDEX (-100)
|
||||||
#define TSDB_MULTI_METERMETA_MAX_NUM 100000 // maximum batch size allowed to load metermeta
|
#define TSDB_MULTI_TABLEMETA_MAX_NUM 100000 // maximum batch size allowed to load table meta
|
||||||
|
|
||||||
#define TSDB_MIN_CACHE_BLOCK_SIZE 1
|
#define TSDB_MIN_CACHE_BLOCK_SIZE 1
|
||||||
#define TSDB_MAX_CACHE_BLOCK_SIZE 128 // 128MB for each vnode
|
#define TSDB_MAX_CACHE_BLOCK_SIZE 128 // 128MB for each vnode
|
||||||
|
|
|
@ -268,7 +268,7 @@ typedef struct {
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int32_t len; // one create table message
|
int32_t len; // one create table message
|
||||||
char tableId[TSDB_TABLE_FNAME_LEN];
|
char tableId[TSDB_TABLE_FNAME_LEN];
|
||||||
char db[TSDB_ACCT_LEN + TSDB_DB_NAME_LEN];
|
char db[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN];
|
||||||
int8_t igExists;
|
int8_t igExists;
|
||||||
int8_t getMeta;
|
int8_t getMeta;
|
||||||
int16_t numOfTags;
|
int16_t numOfTags;
|
||||||
|
@ -290,7 +290,7 @@ typedef struct {
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char tableId[TSDB_TABLE_FNAME_LEN];
|
char tableId[TSDB_TABLE_FNAME_LEN];
|
||||||
char db[TSDB_ACCT_LEN + TSDB_DB_NAME_LEN];
|
char db[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN];
|
||||||
int16_t type; /* operation type */
|
int16_t type; /* operation type */
|
||||||
int16_t numOfCols; /* number of schema */
|
int16_t numOfCols; /* number of schema */
|
||||||
int32_t tagValLen;
|
int32_t tagValLen;
|
||||||
|
@ -322,7 +322,7 @@ typedef struct {
|
||||||
} SConnectMsg;
|
} SConnectMsg;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char acctId[TSDB_ACCT_LEN];
|
char acctId[TSDB_ACCT_ID_LEN];
|
||||||
char serverVersion[TSDB_VERSION_LEN];
|
char serverVersion[TSDB_VERSION_LEN];
|
||||||
char clusterId[TSDB_CLUSTER_ID_LEN];
|
char clusterId[TSDB_CLUSTER_ID_LEN];
|
||||||
int8_t writeAuth;
|
int8_t writeAuth;
|
||||||
|
@ -534,7 +534,7 @@ typedef struct {
|
||||||
} SVnodeLoad;
|
} SVnodeLoad;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char db[TSDB_ACCT_LEN + TSDB_DB_NAME_LEN];
|
char db[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN];
|
||||||
int32_t cacheBlockSize; //MB
|
int32_t cacheBlockSize; //MB
|
||||||
int32_t totalBlocks;
|
int32_t totalBlocks;
|
||||||
int32_t maxTables;
|
int32_t maxTables;
|
||||||
|
@ -682,7 +682,7 @@ typedef struct {
|
||||||
} SVnodeDesc;
|
} SVnodeDesc;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char db[TSDB_ACCT_LEN + TSDB_DB_NAME_LEN];
|
char db[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN];
|
||||||
SVnodeCfg cfg;
|
SVnodeCfg cfg;
|
||||||
SVnodeDesc nodes[TSDB_MAX_REPLICA];
|
SVnodeDesc nodes[TSDB_MAX_REPLICA];
|
||||||
} SCreateVnodeMsg, SAlterVnodeMsg;
|
} SCreateVnodeMsg, SAlterVnodeMsg;
|
||||||
|
@ -761,7 +761,7 @@ typedef struct {
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int8_t type;
|
int8_t type;
|
||||||
char db[TSDB_ACCT_LEN + TSDB_DB_NAME_LEN];
|
char db[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN];
|
||||||
uint16_t payloadLen;
|
uint16_t payloadLen;
|
||||||
char payload[];
|
char payload[];
|
||||||
} SShowMsg;
|
} SShowMsg;
|
||||||
|
|
|
@ -26,7 +26,7 @@ typedef int32_t (*FCqWrite)(int32_t vgId, void *pHead, int32_t qtype, void *pMsg
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int32_t vgId;
|
int32_t vgId;
|
||||||
char user[TSDB_USER_LEN];
|
char user[TSDB_USER_LEN];
|
||||||
char pass[TSDB_PASSWORD_LEN];
|
char pass[TSDB_KEY_LEN];
|
||||||
char db[TSDB_DB_NAME_LEN];
|
char db[TSDB_DB_NAME_LEN];
|
||||||
FCqWrite cqWrite;
|
FCqWrite cqWrite;
|
||||||
} SCqCfg;
|
} SCqCfg;
|
||||||
|
|
|
@ -138,7 +138,7 @@ typedef struct SVgObj {
|
||||||
int64_t createdTime;
|
int64_t createdTime;
|
||||||
int32_t lbDnodeId;
|
int32_t lbDnodeId;
|
||||||
int32_t lbTime;
|
int32_t lbTime;
|
||||||
char dbName[TSDB_ACCT_LEN + TSDB_DB_NAME_LEN];
|
char dbName[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN];
|
||||||
int8_t inUse;
|
int8_t inUse;
|
||||||
int8_t accessState;
|
int8_t accessState;
|
||||||
int8_t status;
|
int8_t status;
|
||||||
|
@ -179,7 +179,7 @@ typedef struct {
|
||||||
} SDbCfg;
|
} SDbCfg;
|
||||||
|
|
||||||
typedef struct SDbObj {
|
typedef struct SDbObj {
|
||||||
char name[TSDB_ACCT_LEN + TSDB_DB_NAME_LEN];
|
char name[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN];
|
||||||
int8_t reserved0[4];
|
int8_t reserved0[4];
|
||||||
char acct[TSDB_USER_LEN];
|
char acct[TSDB_USER_LEN];
|
||||||
int64_t createdTime;
|
int64_t createdTime;
|
||||||
|
|
|
@ -565,7 +565,7 @@ int32_t mnodeCreateVgroup(SMnodeMsg *pMsg) {
|
||||||
SDbObj *pDb = pMsg->pDb;
|
SDbObj *pDb = pMsg->pDb;
|
||||||
|
|
||||||
SVgObj *pVgroup = (SVgObj *)calloc(1, sizeof(SVgObj));
|
SVgObj *pVgroup = (SVgObj *)calloc(1, sizeof(SVgObj));
|
||||||
tstrncpy(pVgroup->dbName, pDb->name, TSDB_ACCT_LEN + TSDB_DB_NAME_LEN);
|
tstrncpy(pVgroup->dbName, pDb->name, TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN);
|
||||||
pVgroup->numOfVnodes = pDb->cfg.replications;
|
pVgroup->numOfVnodes = pDb->cfg.replications;
|
||||||
pVgroup->createdTime = taosGetTimestampMs();
|
pVgroup->createdTime = taosGetTimestampMs();
|
||||||
pVgroup->accessState = TSDB_VN_ALL_ACCCESS;
|
pVgroup->accessState = TSDB_VN_ALL_ACCCESS;
|
||||||
|
|
|
@ -10,3 +10,5 @@ ELSEIF (TD_WINDOWS)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
ADD_SUBDIRECTORY(src/detail)
|
ADD_SUBDIRECTORY(src/detail)
|
||||||
|
ADD_SUBDIRECTORY(tests)
|
||||||
|
|
||||||
|
|
|
@ -486,7 +486,7 @@ int64_t taosTimeTruncate(int64_t t, const SInterval* pInterval, int32_t precisio
|
||||||
start = (delta / pInterval->sliding + factor) * pInterval->sliding;
|
start = (delta / pInterval->sliding + factor) * pInterval->sliding;
|
||||||
|
|
||||||
if (pInterval->intervalUnit == 'd' || pInterval->intervalUnit == 'w') {
|
if (pInterval->intervalUnit == 'd' || pInterval->intervalUnit == 'w') {
|
||||||
/*
|
/*
|
||||||
* here we revised the start time of day according to the local time zone,
|
* here we revised the start time of day according to the local time zone,
|
||||||
* but in case of DST, the start time of one day need to be dynamically decided.
|
* but in case of DST, the start time of one day need to be dynamically decided.
|
||||||
*/
|
*/
|
||||||
|
@ -501,9 +501,24 @@ int64_t taosTimeTruncate(int64_t t, const SInterval* pInterval, int32_t precisio
|
||||||
start += (int64_t)(timezone * TSDB_TICK_PER_SECOND(precision));
|
start += (int64_t)(timezone * TSDB_TICK_PER_SECOND(precision));
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t end = start + pInterval->interval - 1;
|
int64_t end = 0;
|
||||||
if (end < t) {
|
|
||||||
start += pInterval->sliding;
|
// not enough time range
|
||||||
|
if (INT64_MAX - start > pInterval->interval - 1) {
|
||||||
|
end = start + pInterval->interval - 1;
|
||||||
|
|
||||||
|
while(end < t && ((start + pInterval->sliding) <= INT64_MAX)) { // move forward to the correct time window
|
||||||
|
start += pInterval->sliding;
|
||||||
|
|
||||||
|
if (INT64_MAX - start > pInterval->interval - 1) {
|
||||||
|
end = start + pInterval->interval - 1;
|
||||||
|
} else {
|
||||||
|
end = INT64_MAX;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
end = INT64_MAX;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||||
|
PROJECT(TDengine)
|
||||||
|
|
||||||
|
FIND_PATH(HEADER_GTEST_INCLUDE_DIR gtest.h /usr/include/gtest /usr/local/include/gtest)
|
||||||
|
FIND_LIBRARY(LIB_GTEST_STATIC_DIR libgtest.a /usr/lib/ /usr/local/lib)
|
||||||
|
|
||||||
|
IF (HEADER_GTEST_INCLUDE_DIR AND LIB_GTEST_STATIC_DIR)
|
||||||
|
MESSAGE(STATUS "gTest library found, build unit test")
|
||||||
|
|
||||||
|
INCLUDE_DIRECTORIES(${HEADER_GTEST_INCLUDE_DIR})
|
||||||
|
AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} SOURCE_LIST)
|
||||||
|
|
||||||
|
ADD_EXECUTABLE(osTest ${SOURCE_LIST})
|
||||||
|
TARGET_LINK_LIBRARIES(osTest taos osdetail tutil common gtest pthread)
|
||||||
|
ENDIF()
|
|
@ -0,0 +1,34 @@
|
||||||
|
#include "os.h"
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <cassert>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "taos.h"
|
||||||
|
#include "tstoken.h"
|
||||||
|
#include "tutil.h"
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
|
|
||||||
|
// test function in os module
|
||||||
|
TEST(testCase, parse_time) {
|
||||||
|
taos_options(TSDB_OPTION_TIMEZONE, "GMT-8");
|
||||||
|
deltaToUtcInitOnce();
|
||||||
|
|
||||||
|
// window: 1500000001000, 1500002000000
|
||||||
|
// pQuery->interval: interval: 86400000, sliding:3600000
|
||||||
|
int64_t key = 1500000001000;
|
||||||
|
SInterval interval = {0};
|
||||||
|
interval.interval = 86400000;
|
||||||
|
interval.intervalUnit = 'd';
|
||||||
|
interval.sliding = 3600000;
|
||||||
|
interval.slidingUnit = 'h';
|
||||||
|
|
||||||
|
int64_t s = taosTimeTruncate(key, &interval, TSDB_TIME_PRECISION_MILLI);
|
||||||
|
ASSERT_TRUE(s + interval.interval >= key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
#define HTTP_GC_TARGET_SIZE 512
|
#define HTTP_GC_TARGET_SIZE 512
|
||||||
#define HTTP_WRITE_RETRY_TIMES 500
|
#define HTTP_WRITE_RETRY_TIMES 500
|
||||||
#define HTTP_WRITE_WAIT_TIME_MS 5
|
#define HTTP_WRITE_WAIT_TIME_MS 5
|
||||||
#define HTTP_SESSION_ID_LEN (TSDB_USER_LEN + TSDB_PASSWORD_LEN)
|
#define HTTP_SESSION_ID_LEN (TSDB_USER_LEN + TSDB_KEY_LEN)
|
||||||
|
|
||||||
typedef enum HttpReqType {
|
typedef enum HttpReqType {
|
||||||
HTTP_REQTYPE_OTHERS = 0,
|
HTTP_REQTYPE_OTHERS = 0,
|
||||||
|
@ -147,7 +147,7 @@ typedef struct HttpContext {
|
||||||
uint8_t parsed;
|
uint8_t parsed;
|
||||||
char ipstr[22];
|
char ipstr[22];
|
||||||
char user[TSDB_USER_LEN]; // parsed from auth token or login message
|
char user[TSDB_USER_LEN]; // parsed from auth token or login message
|
||||||
char pass[TSDB_PASSWORD_LEN];
|
char pass[TSDB_KEY_LEN];
|
||||||
TAOS * taos;
|
TAOS * taos;
|
||||||
void * ppContext;
|
void * ppContext;
|
||||||
HttpSession *session;
|
HttpSession *session;
|
||||||
|
|
|
@ -51,7 +51,7 @@ int32_t httpParseBasicAuthToken(HttpContext *pContext, char *token, int32_t len)
|
||||||
|
|
||||||
char *password = user + 1;
|
char *password = user + 1;
|
||||||
int32_t pass_len = (int32_t)((base64 + outlen) - password);
|
int32_t pass_len = (int32_t)((base64 + outlen) - password);
|
||||||
if (pass_len < 1 || pass_len >= TSDB_PASSWORD_LEN) {
|
if (pass_len < 1 || pass_len >= TSDB_KEY_LEN) {
|
||||||
httpError("context:%p, fd:%d, basic token:%s parse password error", pContext, pContext->fd, token);
|
httpError("context:%p, fd:%d, basic token:%s parse password error", pContext, pContext->fd, token);
|
||||||
free(base64);
|
free(base64);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -73,7 +73,7 @@ int32_t httpParseTaosdAuthToken(HttpContext *pContext, char *token, int32_t len)
|
||||||
if (base64) free(base64);
|
if (base64) free(base64);
|
||||||
return 01;
|
return 01;
|
||||||
}
|
}
|
||||||
if (outlen != (TSDB_USER_LEN + TSDB_PASSWORD_LEN)) {
|
if (outlen != (TSDB_USER_LEN + TSDB_KEY_LEN)) {
|
||||||
httpError("context:%p, fd:%d, taosd token:%s length error", pContext, pContext->fd, token);
|
httpError("context:%p, fd:%d, taosd token:%s length error", pContext, pContext->fd, token);
|
||||||
free(base64);
|
free(base64);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -103,8 +103,8 @@ int32_t httpGenTaosdAuthToken(HttpContext *pContext, char *token, int32_t maxLen
|
||||||
size = sizeof(pContext->pass);
|
size = sizeof(pContext->pass);
|
||||||
tstrncpy(buffer + sizeof(pContext->user), pContext->pass, size);
|
tstrncpy(buffer + sizeof(pContext->user), pContext->pass, size);
|
||||||
|
|
||||||
char *encrypt = taosDesEncode(KEY_DES_4, buffer, TSDB_USER_LEN + TSDB_PASSWORD_LEN);
|
char *encrypt = taosDesEncode(KEY_DES_4, buffer, TSDB_USER_LEN + TSDB_KEY_LEN);
|
||||||
char *base64 = base64_encode((const unsigned char *)encrypt, TSDB_USER_LEN + TSDB_PASSWORD_LEN);
|
char *base64 = base64_encode((const unsigned char *)encrypt, TSDB_USER_LEN + TSDB_KEY_LEN);
|
||||||
|
|
||||||
size_t len = strlen(base64);
|
size_t len = strlen(base64);
|
||||||
tstrncpy(token, base64, len + 1);
|
tstrncpy(token, base64, len + 1);
|
||||||
|
|
|
@ -59,11 +59,11 @@ bool gcGetUserFromUrl(HttpContext* pContext) {
|
||||||
|
|
||||||
bool gcGetPassFromUrl(HttpContext* pContext) {
|
bool gcGetPassFromUrl(HttpContext* pContext) {
|
||||||
HttpParser* pParser = pContext->parser;
|
HttpParser* pParser = pContext->parser;
|
||||||
if (pParser->path[GC_PASS_URL_POS].pos >= TSDB_PASSWORD_LEN || pParser->path[GC_PASS_URL_POS].pos <= 0) {
|
if (pParser->path[GC_PASS_URL_POS].pos >= TSDB_KEY_LEN || pParser->path[GC_PASS_URL_POS].pos <= 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
tstrncpy(pContext->pass, pParser->path[GC_PASS_URL_POS].str, TSDB_PASSWORD_LEN);
|
tstrncpy(pContext->pass, pParser->path[GC_PASS_URL_POS].str, TSDB_KEY_LEN);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,11 +72,11 @@ bool restGetUserFromUrl(HttpContext* pContext) {
|
||||||
|
|
||||||
bool restGetPassFromUrl(HttpContext* pContext) {
|
bool restGetPassFromUrl(HttpContext* pContext) {
|
||||||
HttpParser* pParser = pContext->parser;
|
HttpParser* pParser = pContext->parser;
|
||||||
if (pParser->path[REST_PASS_URL_POS].pos >= TSDB_PASSWORD_LEN || pParser->path[REST_PASS_URL_POS].pos <= 0) {
|
if (pParser->path[REST_PASS_URL_POS].pos >= TSDB_KEY_LEN || pParser->path[REST_PASS_URL_POS].pos <= 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
tstrncpy(pContext->pass, pParser->path[REST_PASS_URL_POS].str, TSDB_PASSWORD_LEN);
|
tstrncpy(pContext->pass, pParser->path[REST_PASS_URL_POS].str, TSDB_KEY_LEN);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -324,7 +324,7 @@ bool tgGetUserFromUrl(HttpContext *pContext) {
|
||||||
|
|
||||||
bool tgGetPassFromUrl(HttpContext *pContext) {
|
bool tgGetPassFromUrl(HttpContext *pContext) {
|
||||||
HttpParser *pParser = pContext->parser;
|
HttpParser *pParser = pContext->parser;
|
||||||
if (pParser->path[TG_PASS_URL_POS].pos >= TSDB_PASSWORD_LEN || pParser->path[TG_PASS_URL_POS].pos <= 0) {
|
if (pParser->path[TG_PASS_URL_POS].pos >= TSDB_KEY_LEN || pParser->path[TG_PASS_URL_POS].pos <= 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,32 +16,36 @@
|
||||||
#ifndef TDENGINE_QPERCENTILE_H
|
#ifndef TDENGINE_QPERCENTILE_H
|
||||||
#define TDENGINE_QPERCENTILE_H
|
#define TDENGINE_QPERCENTILE_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "qExtbuffer.h"
|
#include "qExtbuffer.h"
|
||||||
#include "qResultbuf.h"
|
#include "qResultbuf.h"
|
||||||
#include "qTsbuf.h"
|
#include "qTsbuf.h"
|
||||||
|
|
||||||
typedef struct MinMaxEntry {
|
typedef struct MinMaxEntry {
|
||||||
union {
|
union {
|
||||||
double dMinVal;
|
double dMinVal;
|
||||||
int32_t iMinVal;
|
int64_t i64MinVal;
|
||||||
int64_t i64MinVal;
|
uint64_t u64MinVal;
|
||||||
};
|
};
|
||||||
union {
|
union {
|
||||||
double dMaxVal;
|
double dMaxVal;
|
||||||
int32_t iMaxVal;
|
|
||||||
int64_t i64MaxVal;
|
int64_t i64MaxVal;
|
||||||
|
int64_t u64MaxVal;
|
||||||
};
|
};
|
||||||
} MinMaxEntry;
|
} MinMaxEntry;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int32_t size;
|
int32_t size;
|
||||||
int32_t pageId;
|
int32_t pageId;
|
||||||
tFilePage *data;
|
tFilePage *data;
|
||||||
} SSlotInfo;
|
} SSlotInfo;
|
||||||
|
|
||||||
typedef struct tMemBucketSlot {
|
typedef struct tMemBucketSlot {
|
||||||
SSlotInfo info;
|
SSlotInfo info;
|
||||||
MinMaxEntry range;
|
MinMaxEntry range;
|
||||||
} tMemBucketSlot;
|
} tMemBucketSlot;
|
||||||
|
|
||||||
struct tMemBucket;
|
struct tMemBucket;
|
||||||
|
@ -52,16 +56,16 @@ typedef struct tMemBucket {
|
||||||
int16_t type;
|
int16_t type;
|
||||||
int16_t bytes;
|
int16_t bytes;
|
||||||
int32_t total;
|
int32_t total;
|
||||||
int32_t elemPerPage; // number of elements for each object
|
int32_t elemPerPage; // number of elements for each object
|
||||||
int32_t maxCapacity; // maximum allowed number of elements that can be sort directly to get the result
|
int32_t maxCapacity; // maximum allowed number of elements that can be sort directly to get the result
|
||||||
int32_t bufPageSize; // disk page size
|
int32_t bufPageSize; // disk page size
|
||||||
MinMaxEntry range; // value range
|
MinMaxEntry range; // value range
|
||||||
int32_t times; // count that has been checked for deciding the correct data value buckets.
|
int32_t times; // count that has been checked for deciding the correct data value buckets.
|
||||||
__compar_fn_t comparFn;
|
__compar_fn_t comparFn;
|
||||||
|
|
||||||
tMemBucketSlot *pSlots;
|
tMemBucketSlot * pSlots;
|
||||||
SDiskbasedResultBuf *pBuffer;
|
SDiskbasedResultBuf *pBuffer;
|
||||||
__perc_hash_func_t hashFunc;
|
__perc_hash_func_t hashFunc;
|
||||||
} tMemBucket;
|
} tMemBucket;
|
||||||
|
|
||||||
tMemBucket *tMemBucketCreate(int16_t nElemSize, int16_t dataType, double minval, double maxval);
|
tMemBucket *tMemBucketCreate(int16_t nElemSize, int16_t dataType, double minval, double maxval);
|
||||||
|
@ -73,3 +77,7 @@ int32_t tMemBucketPut(tMemBucket *pBucket, const void *data, size_t size);
|
||||||
double getPercentile(tMemBucket *pMemBucket, double percent);
|
double getPercentile(tMemBucket *pMemBucket, double percent);
|
||||||
|
|
||||||
#endif // TDENGINE_QPERCENTILE_H
|
#endif // TDENGINE_QPERCENTILE_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -2545,7 +2545,7 @@ static void percentile_next_step(SQLFunctionCtx *pCtx) {
|
||||||
if (pInfo->numOfElems == 0) {
|
if (pInfo->numOfElems == 0) {
|
||||||
pResInfo->complete = true;
|
pResInfo->complete = true;
|
||||||
} else {
|
} else {
|
||||||
pInfo->pMemBucket = tMemBucketCreate(pCtx->inputBytes, pCtx->inputType, GET_DOUBLE_VAL(&pInfo->minval), GET_DOUBLE_VAL(&pInfo->maxval));
|
pInfo->pMemBucket = tMemBucketCreate(pCtx->inputBytes, pCtx->inputType, pInfo->minval, pInfo->maxval);
|
||||||
}
|
}
|
||||||
|
|
||||||
pInfo->stage += 1;
|
pInfo->stage += 1;
|
||||||
|
|
|
@ -12,14 +12,14 @@
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
#include "os.h"
|
||||||
|
|
||||||
#include "qPercentile.h"
|
#include "qPercentile.h"
|
||||||
#include "qResultbuf.h"
|
#include "qResultbuf.h"
|
||||||
#include "os.h"
|
|
||||||
#include "queryLog.h"
|
#include "queryLog.h"
|
||||||
#include "taosdef.h"
|
#include "taosdef.h"
|
||||||
#include "tulog.h"
|
|
||||||
#include "tcompare.h"
|
#include "tcompare.h"
|
||||||
|
#include "ttype.h"
|
||||||
|
|
||||||
#define DEFAULT_NUM_OF_SLOT 1024
|
#define DEFAULT_NUM_OF_SLOT 1024
|
||||||
|
|
||||||
|
@ -48,25 +48,15 @@ static tFilePage *loadDataFromFilePage(tMemBucket *pMemBucket, int32_t slotIdx)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void resetBoundingBox(MinMaxEntry* range, int32_t type) {
|
static void resetBoundingBox(MinMaxEntry* range, int32_t type) {
|
||||||
switch (type) {
|
if (IS_SIGNED_NUMERIC_TYPE(type)) {
|
||||||
case TSDB_DATA_TYPE_BIGINT: {
|
range->i64MaxVal = INT64_MIN;
|
||||||
range->i64MaxVal = INT64_MIN;
|
range->i64MinVal = INT64_MAX;
|
||||||
range->i64MinVal = INT64_MAX;
|
} else if (IS_UNSIGNED_NUMERIC_TYPE(type)) {
|
||||||
break;
|
range->u64MaxVal = 0;
|
||||||
};
|
range->u64MinVal = UINT64_MAX;
|
||||||
case TSDB_DATA_TYPE_INT:
|
} else {
|
||||||
case TSDB_DATA_TYPE_SMALLINT:
|
range->dMaxVal = -DBL_MAX;
|
||||||
case TSDB_DATA_TYPE_TINYINT: {
|
range->dMinVal = DBL_MAX;
|
||||||
range->iMaxVal = INT32_MIN;
|
|
||||||
range->iMinVal = INT32_MAX;
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
case TSDB_DATA_TYPE_DOUBLE:
|
|
||||||
case TSDB_DATA_TYPE_FLOAT: {
|
|
||||||
range->dMaxVal = -DBL_MAX;
|
|
||||||
range->dMinVal = DBL_MAX;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,23 +65,15 @@ static int32_t setBoundingBox(MinMaxEntry* range, int16_t type, double minval, d
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(type) {
|
if (IS_SIGNED_NUMERIC_TYPE(type)) {
|
||||||
case TSDB_DATA_TYPE_TINYINT:
|
range->i64MinVal = (int64_t) minval;
|
||||||
case TSDB_DATA_TYPE_SMALLINT:
|
range->i64MaxVal = (int64_t) maxval;
|
||||||
case TSDB_DATA_TYPE_INT:
|
} else if (IS_UNSIGNED_NUMERIC_TYPE(type)){
|
||||||
range->iMinVal = (int32_t) minval;
|
range->u64MinVal = (uint64_t) minval;
|
||||||
range->iMaxVal = (int32_t) maxval;
|
range->u64MaxVal = (uint64_t) maxval;
|
||||||
break;
|
} else {
|
||||||
|
range->dMinVal = minval;
|
||||||
case TSDB_DATA_TYPE_BIGINT:
|
range->dMaxVal = maxval;
|
||||||
range->i64MinVal = (int64_t) minval;
|
|
||||||
range->i64MaxVal = (int64_t) maxval;
|
|
||||||
break;
|
|
||||||
case TSDB_DATA_TYPE_FLOAT:
|
|
||||||
case TSDB_DATA_TYPE_DOUBLE:
|
|
||||||
range->dMinVal = minval;
|
|
||||||
range->dMaxVal = maxval;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -120,117 +102,56 @@ double findOnlyResult(tMemBucket *pMemBucket) {
|
||||||
tFilePage* pPage = getResBufPage(pMemBucket->pBuffer, pgInfo->pageId);
|
tFilePage* pPage = getResBufPage(pMemBucket->pBuffer, pgInfo->pageId);
|
||||||
assert(pPage->num == 1);
|
assert(pPage->num == 1);
|
||||||
|
|
||||||
switch (pMemBucket->type) {
|
double v = 0;
|
||||||
case TSDB_DATA_TYPE_INT:
|
GET_TYPED_DATA(v, double, pMemBucket->type, pPage->data);
|
||||||
return *(int32_t *)pPage->data;
|
return v;
|
||||||
case TSDB_DATA_TYPE_SMALLINT:
|
|
||||||
return *(int16_t *)pPage->data;
|
|
||||||
case TSDB_DATA_TYPE_TINYINT:
|
|
||||||
return *(int8_t *)pPage->data;
|
|
||||||
case TSDB_DATA_TYPE_BIGINT:
|
|
||||||
return (double)(*(int64_t *)pPage->data);
|
|
||||||
case TSDB_DATA_TYPE_DOUBLE: {
|
|
||||||
double dv = GET_DOUBLE_VAL(pPage->data);
|
|
||||||
return dv;
|
|
||||||
}
|
|
||||||
case TSDB_DATA_TYPE_FLOAT: {
|
|
||||||
float fv = GET_FLOAT_VAL(pPage->data);
|
|
||||||
return fv;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tBucketBigIntHash(tMemBucket *pBucket, const void *value) {
|
int32_t tBucketIntHash(tMemBucket *pBucket, const void *value) {
|
||||||
int64_t v = *(int64_t *)value;
|
int64_t v = 0;
|
||||||
|
GET_TYPED_DATA(v, int64_t, pBucket->type, value);
|
||||||
|
|
||||||
int32_t index = -1;
|
int32_t index = -1;
|
||||||
|
// divide the value range into 1024 buckets
|
||||||
int32_t halfSlot = pBucket->numOfSlots >> 1;
|
uint64_t span = pBucket->range.i64MaxVal - pBucket->range.i64MinVal;
|
||||||
// int32_t bits = 32;//bitsOfNumber(pBucket->numOfSlots) - 1;
|
if (span < pBucket->numOfSlots) {
|
||||||
|
int64_t delta = v - pBucket->range.i64MinVal;
|
||||||
if (pBucket->range.i64MaxVal == INT64_MIN) {
|
index = (delta % pBucket->numOfSlots);
|
||||||
if (v >= 0) {
|
|
||||||
index = (v >> (64 - 9)) + halfSlot;
|
|
||||||
} else { // v<0
|
|
||||||
index = ((-v) >> (64 - 9));
|
|
||||||
index = -index + (halfSlot - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return index;
|
|
||||||
} else {
|
} else {
|
||||||
// out of range
|
double slotSpan = (double)span / pBucket->numOfSlots;
|
||||||
if (v < pBucket->range.i64MinVal || v > pBucket->range.i64MaxVal) {
|
index = (int32_t)((v - pBucket->range.i64MinVal) / slotSpan);
|
||||||
return -1;
|
if (v == pBucket->range.i64MaxVal) {
|
||||||
|
index -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo hash for bigint and float and double
|
|
||||||
int64_t span = pBucket->range.i64MaxVal - pBucket->range.i64MinVal;
|
|
||||||
if (span < pBucket->numOfSlots) {
|
|
||||||
int32_t delta = (int32_t)(v - pBucket->range.i64MinVal);
|
|
||||||
index = delta % pBucket->numOfSlots;
|
|
||||||
} else {
|
|
||||||
double slotSpan = (double)span / pBucket->numOfSlots;
|
|
||||||
index = (int32_t)((v - pBucket->range.i64MinVal) / slotSpan);
|
|
||||||
if (v == pBucket->range.i64MaxVal) {
|
|
||||||
index -= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return index;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert(v >= pBucket->range.i64MinVal && v <= pBucket->range.i64MaxVal && index >= 0 && index < pBucket->numOfSlots);
|
||||||
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo refactor to more generic
|
int32_t tBucketUintHash(tMemBucket *pBucket, const void *value) {
|
||||||
int32_t tBucketIntHash(tMemBucket *pBucket, const void *value) {
|
int64_t v = 0;
|
||||||
int32_t v = 0;
|
GET_TYPED_DATA(v, uint64_t, pBucket->type, value);
|
||||||
switch(pBucket->type) {
|
|
||||||
case TSDB_DATA_TYPE_SMALLINT: v = *(int16_t*) value; break;
|
|
||||||
case TSDB_DATA_TYPE_TINYINT: v = *(int8_t*) value; break;
|
|
||||||
default: v = *(int32_t*) value;break;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t index = -1;
|
int32_t index = -1;
|
||||||
if (pBucket->range.iMaxVal == INT32_MIN) {
|
// divide the value range into 1024 buckets
|
||||||
/*
|
uint64_t span = pBucket->range.u64MaxVal - pBucket->range.u64MinVal;
|
||||||
* taking negative integer into consideration,
|
if (span < pBucket->numOfSlots) {
|
||||||
* there is only half of pBucket->segs available for non-negative integer
|
int64_t delta = v - pBucket->range.u64MinVal;
|
||||||
*/
|
index = (int32_t) (delta % pBucket->numOfSlots);
|
||||||
int32_t halfSlot = pBucket->numOfSlots >> 1;
|
|
||||||
int32_t bits = 32;//bitsOfNumber(pBucket->numOfSlots) - 1;
|
|
||||||
|
|
||||||
if (v >= 0) {
|
|
||||||
index = (v >> (bits - 9)) + halfSlot;
|
|
||||||
} else { // v < 0
|
|
||||||
index = ((-v) >> (32 - 9));
|
|
||||||
index = -index + (halfSlot - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return index;
|
|
||||||
} else {
|
} else {
|
||||||
// out of range
|
double slotSpan = (double)span / pBucket->numOfSlots;
|
||||||
if (v < pBucket->range.iMinVal || v > pBucket->range.iMaxVal) {
|
index = (int32_t)((v - pBucket->range.u64MinVal) / slotSpan);
|
||||||
return -1;
|
if (v == pBucket->range.u64MaxVal) {
|
||||||
|
index -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// divide a range of [iMinVal, iMaxVal] into 1024 buckets
|
|
||||||
int32_t span = pBucket->range.iMaxVal - pBucket->range.iMinVal;
|
|
||||||
if (span < pBucket->numOfSlots) {
|
|
||||||
int32_t delta = v - pBucket->range.iMinVal;
|
|
||||||
index = (delta % pBucket->numOfSlots);
|
|
||||||
} else {
|
|
||||||
double slotSpan = (double)span / pBucket->numOfSlots;
|
|
||||||
index = (int32_t)((v - pBucket->range.iMinVal) / slotSpan);
|
|
||||||
if (v == pBucket->range.iMaxVal) {
|
|
||||||
index -= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return index;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert(v >= pBucket->range.u64MinVal && v <= pBucket->range.i64MaxVal && index >= 0 && index < pBucket->numOfSlots);
|
||||||
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tBucketDoubleHash(tMemBucket *pBucket, const void *value) {
|
int32_t tBucketDoubleHash(tMemBucket *pBucket, const void *value) {
|
||||||
|
@ -243,62 +164,30 @@ int32_t tBucketDoubleHash(tMemBucket *pBucket, const void *value) {
|
||||||
|
|
||||||
int32_t index = -1;
|
int32_t index = -1;
|
||||||
|
|
||||||
if (pBucket->range.dMinVal == DBL_MAX) {
|
// divide a range of [dMinVal, dMaxVal] into 1024 buckets
|
||||||
/*
|
double span = pBucket->range.dMaxVal - pBucket->range.dMinVal;
|
||||||
* taking negative integer into consideration,
|
if (span < pBucket->numOfSlots) {
|
||||||
* there is only half of pBucket->segs available for non-negative integer
|
int32_t delta = (int32_t)(v - pBucket->range.dMinVal);
|
||||||
*/
|
index = (delta % pBucket->numOfSlots);
|
||||||
double x = DBL_MAX / (pBucket->numOfSlots >> 1);
|
|
||||||
double posx = (v + DBL_MAX) / x;
|
|
||||||
return ((int32_t)posx) % pBucket->numOfSlots;
|
|
||||||
} else {
|
} else {
|
||||||
|
double slotSpan = span / pBucket->numOfSlots;
|
||||||
// out of range
|
index = (int32_t)((v - pBucket->range.dMinVal) / slotSpan);
|
||||||
if (v < pBucket->range.dMinVal || v > pBucket->range.dMaxVal) {
|
if (v == pBucket->range.dMaxVal) {
|
||||||
return -1;
|
index -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// divide a range of [dMinVal, dMaxVal] into 1024 buckets
|
|
||||||
double span = pBucket->range.dMaxVal - pBucket->range.dMinVal;
|
|
||||||
if (span < pBucket->numOfSlots) {
|
|
||||||
int32_t delta = (int32_t)(v - pBucket->range.dMinVal);
|
|
||||||
index = (delta % pBucket->numOfSlots);
|
|
||||||
} else {
|
|
||||||
double slotSpan = span / pBucket->numOfSlots;
|
|
||||||
index = (int32_t)((v - pBucket->range.dMinVal) / slotSpan);
|
|
||||||
if (v == pBucket->range.dMaxVal) {
|
|
||||||
index -= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index < 0 || index > pBucket->numOfSlots) {
|
|
||||||
uError("error in hash process. slot id: %d", index);
|
|
||||||
}
|
|
||||||
|
|
||||||
return index;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert(v >= pBucket->range.dMinVal && v <= pBucket->range.dMaxVal && index >= 0 && index < pBucket->numOfSlots);
|
||||||
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __perc_hash_func_t getHashFunc(int32_t type) {
|
static __perc_hash_func_t getHashFunc(int32_t type) {
|
||||||
switch (type) {
|
if (IS_SIGNED_NUMERIC_TYPE(type)) {
|
||||||
case TSDB_DATA_TYPE_INT:
|
return tBucketIntHash;
|
||||||
case TSDB_DATA_TYPE_SMALLINT:
|
} else if (IS_UNSIGNED_NUMERIC_TYPE(type)) {
|
||||||
case TSDB_DATA_TYPE_TINYINT: {
|
return tBucketUintHash;
|
||||||
return tBucketIntHash;
|
} else {
|
||||||
};
|
return tBucketDoubleHash;
|
||||||
|
|
||||||
case TSDB_DATA_TYPE_DOUBLE:
|
|
||||||
case TSDB_DATA_TYPE_FLOAT: {
|
|
||||||
return tBucketDoubleHash;
|
|
||||||
};
|
|
||||||
|
|
||||||
case TSDB_DATA_TYPE_BIGINT: {
|
|
||||||
return tBucketBigIntHash;
|
|
||||||
};
|
|
||||||
|
|
||||||
default: {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,7 +217,7 @@ tMemBucket *tMemBucketCreate(int16_t nElemSize, int16_t dataType, double minval,
|
||||||
pBucket->maxCapacity = 200000;
|
pBucket->maxCapacity = 200000;
|
||||||
|
|
||||||
if (setBoundingBox(&pBucket->range, pBucket->type, minval, maxval) != 0) {
|
if (setBoundingBox(&pBucket->range, pBucket->type, minval, maxval) != 0) {
|
||||||
uError("MemBucket:%p, invalid value range: %f-%f", pBucket, minval, maxval);
|
qError("MemBucket:%p, invalid value range: %f-%f", pBucket, minval, maxval);
|
||||||
free(pBucket);
|
free(pBucket);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -338,7 +227,7 @@ tMemBucket *tMemBucketCreate(int16_t nElemSize, int16_t dataType, double minval,
|
||||||
|
|
||||||
pBucket->hashFunc = getHashFunc(pBucket->type);
|
pBucket->hashFunc = getHashFunc(pBucket->type);
|
||||||
if (pBucket->hashFunc == NULL) {
|
if (pBucket->hashFunc == NULL) {
|
||||||
uError("MemBucket:%p, not support data type %d, failed", pBucket, pBucket->type);
|
qError("MemBucket:%p, not support data type %d, failed", pBucket, pBucket->type);
|
||||||
free(pBucket);
|
free(pBucket);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -357,7 +246,7 @@ tMemBucket *tMemBucketCreate(int16_t nElemSize, int16_t dataType, double minval,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
uDebug("MemBucket:%p, elem size:%d", pBucket, pBucket->bytes);
|
qDebug("MemBucket:%p, elem size:%d", pBucket, pBucket->bytes);
|
||||||
return pBucket;
|
return pBucket;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -372,77 +261,41 @@ void tMemBucketDestroy(tMemBucket *pBucket) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void tMemBucketUpdateBoundingBox(MinMaxEntry *r, const char *data, int32_t dataType) {
|
void tMemBucketUpdateBoundingBox(MinMaxEntry *r, const char *data, int32_t dataType) {
|
||||||
switch (dataType) {
|
if (IS_SIGNED_NUMERIC_TYPE(dataType)) {
|
||||||
case TSDB_DATA_TYPE_INT: {
|
int64_t v = 0;
|
||||||
int32_t val = *(int32_t *)data;
|
GET_TYPED_DATA(v, int64_t, dataType, data);
|
||||||
if (r->iMinVal > val) {
|
|
||||||
r->iMinVal = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (r->iMaxVal < val) {
|
if (r->i64MinVal > v) {
|
||||||
r->iMaxVal = val;
|
r->i64MinVal = v;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
};
|
|
||||||
case TSDB_DATA_TYPE_BIGINT: {
|
|
||||||
int64_t val = *(int64_t *)data;
|
|
||||||
if (r->i64MinVal > val) {
|
|
||||||
r->i64MinVal = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (r->i64MaxVal < val) {
|
if (r->i64MaxVal < v) {
|
||||||
r->i64MaxVal = val;
|
r->i64MaxVal = v;
|
||||||
}
|
}
|
||||||
break;
|
} else if (IS_UNSIGNED_NUMERIC_TYPE(dataType)) {
|
||||||
};
|
uint64_t v = 0;
|
||||||
case TSDB_DATA_TYPE_SMALLINT: {
|
GET_TYPED_DATA(v, uint64_t, dataType, data);
|
||||||
int32_t val = *(int16_t *)data;
|
|
||||||
if (r->iMinVal > val) {
|
|
||||||
r->iMinVal = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (r->iMaxVal < val) {
|
if (r->i64MinVal > v) {
|
||||||
r->iMaxVal = val;
|
r->i64MinVal = v;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
};
|
|
||||||
case TSDB_DATA_TYPE_TINYINT: {
|
|
||||||
int32_t val = *(int8_t *)data;
|
|
||||||
if (r->iMinVal > val) {
|
|
||||||
r->iMinVal = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (r->iMaxVal < val) {
|
if (r->i64MaxVal < v) {
|
||||||
r->iMaxVal = val;
|
r->i64MaxVal = v;
|
||||||
}
|
}
|
||||||
|
} else if (IS_FLOAT_TYPE(dataType)) {
|
||||||
|
double v = 0;
|
||||||
|
GET_TYPED_DATA(v, double, dataType, data);
|
||||||
|
|
||||||
break;
|
if (r->dMinVal > v) {
|
||||||
};
|
r->dMinVal = v;
|
||||||
case TSDB_DATA_TYPE_DOUBLE: {
|
}
|
||||||
// double val = *(double *)data;
|
|
||||||
double val = GET_DOUBLE_VAL(data);
|
|
||||||
if (r->dMinVal > val) {
|
|
||||||
r->dMinVal = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (r->dMaxVal < val) {
|
if (r->dMaxVal < v) {
|
||||||
r->dMaxVal = val;
|
r->dMaxVal = v;
|
||||||
}
|
}
|
||||||
break;
|
} else {
|
||||||
};
|
assert(0);
|
||||||
case TSDB_DATA_TYPE_FLOAT: {
|
|
||||||
double val = GET_FLOAT_VAL(data);
|
|
||||||
|
|
||||||
if (r->dMinVal > val) {
|
|
||||||
r->dMinVal = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (r->dMaxVal < val) {
|
|
||||||
r->dMaxVal = val;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
default: { assert(false); }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,16 +305,13 @@ void tMemBucketUpdateBoundingBox(MinMaxEntry *r, const char *data, int32_t dataT
|
||||||
int32_t tMemBucketPut(tMemBucket *pBucket, const void *data, size_t size) {
|
int32_t tMemBucketPut(tMemBucket *pBucket, const void *data, size_t size) {
|
||||||
assert(pBucket != NULL && data != NULL && size > 0);
|
assert(pBucket != NULL && data != NULL && size > 0);
|
||||||
|
|
||||||
pBucket->total += (int32_t)size;
|
int32_t count = 0;
|
||||||
|
|
||||||
int32_t bytes = pBucket->bytes;
|
int32_t bytes = pBucket->bytes;
|
||||||
for (int32_t i = 0; i < size; ++i) {
|
for (int32_t i = 0; i < size; ++i) {
|
||||||
char *d = (char *) data + i * bytes;
|
char *d = (char *) data + i * bytes;
|
||||||
|
count += 1;
|
||||||
|
|
||||||
int32_t index = (pBucket->hashFunc)(pBucket, d);
|
int32_t index = (pBucket->hashFunc)(pBucket, d);
|
||||||
if (index == -1) { // the value is out of range, do not add it into bucket
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
tMemBucketSlot *pSlot = &pBucket->pSlots[index];
|
tMemBucketSlot *pSlot = &pBucket->pSlots[index];
|
||||||
tMemBucketUpdateBoundingBox(&pSlot->range, d, pBucket->type);
|
tMemBucketUpdateBoundingBox(&pSlot->range, d, pBucket->type);
|
||||||
|
@ -489,64 +339,11 @@ int32_t tMemBucketPut(tMemBucket *pBucket, const void *data, size_t size) {
|
||||||
pSlot->info.size += 1;
|
pSlot->info.size += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pBucket->total += count;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
static UNUSED_FUNC void findMaxMinValue(tMemBucket *pMemBucket, double *maxVal, double *minVal) {
|
|
||||||
*minVal = DBL_MAX;
|
|
||||||
*maxVal = -DBL_MAX;
|
|
||||||
|
|
||||||
for (int32_t i = 0; i < pMemBucket->numOfSlots; ++i) {
|
|
||||||
tMemBucketSlot *pSlot = &pMemBucket->pSlots[i];
|
|
||||||
if (pSlot->info.size == 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (pMemBucket->type) {
|
|
||||||
case TSDB_DATA_TYPE_INT:
|
|
||||||
case TSDB_DATA_TYPE_SMALLINT:
|
|
||||||
case TSDB_DATA_TYPE_TINYINT: {
|
|
||||||
double minv = pSlot->range.iMinVal;
|
|
||||||
double maxv = pSlot->range.iMaxVal;
|
|
||||||
|
|
||||||
if (*minVal > minv) {
|
|
||||||
*minVal = minv;
|
|
||||||
}
|
|
||||||
if (*maxVal < maxv) {
|
|
||||||
*maxVal = maxv;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case TSDB_DATA_TYPE_DOUBLE:
|
|
||||||
case TSDB_DATA_TYPE_FLOAT: {
|
|
||||||
double minv = pSlot->range.dMinVal;
|
|
||||||
double maxv = pSlot->range.dMaxVal;
|
|
||||||
|
|
||||||
if (*minVal > minv) {
|
|
||||||
*minVal = minv;
|
|
||||||
}
|
|
||||||
if (*maxVal < maxv) {
|
|
||||||
*maxVal = maxv;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case TSDB_DATA_TYPE_BIGINT: {
|
|
||||||
double minv = (double)pSlot->range.i64MinVal;
|
|
||||||
double maxv = (double)pSlot->range.i64MaxVal;
|
|
||||||
|
|
||||||
if (*minVal > minv) {
|
|
||||||
*minVal = minv;
|
|
||||||
}
|
|
||||||
if (*maxVal < maxv) {
|
|
||||||
*maxVal = maxv;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* now, we need to find the minimum value of the next slot for
|
* now, we need to find the minimum value of the next slot for
|
||||||
|
@ -565,7 +362,6 @@ static MinMaxEntry getMinMaxEntryOfNextSlotWithData(tMemBucket *pMemBucket, int3
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isIdenticalData(tMemBucket *pMemBucket, int32_t index);
|
static bool isIdenticalData(tMemBucket *pMemBucket, int32_t index);
|
||||||
char *getFirstElemOfMemBuffer(tMemBucketSlot *pSeg, int32_t slotIdx, tFilePage *pPage);
|
|
||||||
|
|
||||||
static double getIdenticalDataVal(tMemBucket* pMemBucket, int32_t slotIndex) {
|
static double getIdenticalDataVal(tMemBucket* pMemBucket, int32_t slotIndex) {
|
||||||
assert(isIdenticalData(pMemBucket, slotIndex));
|
assert(isIdenticalData(pMemBucket, slotIndex));
|
||||||
|
@ -573,24 +369,12 @@ static double getIdenticalDataVal(tMemBucket* pMemBucket, int32_t slotIndex) {
|
||||||
tMemBucketSlot *pSlot = &pMemBucket->pSlots[slotIndex];
|
tMemBucketSlot *pSlot = &pMemBucket->pSlots[slotIndex];
|
||||||
|
|
||||||
double finalResult = 0.0;
|
double finalResult = 0.0;
|
||||||
switch (pMemBucket->type) {
|
if (IS_SIGNED_NUMERIC_TYPE(pMemBucket->type)) {
|
||||||
case TSDB_DATA_TYPE_SMALLINT:
|
finalResult = (double) pSlot->range.i64MinVal;
|
||||||
case TSDB_DATA_TYPE_TINYINT:
|
} else if (IS_UNSIGNED_NUMERIC_TYPE(pMemBucket->type)) {
|
||||||
case TSDB_DATA_TYPE_INT: {
|
finalResult = (double) pSlot->range.u64MinVal;
|
||||||
finalResult = pSlot->range.iMinVal;
|
} else {
|
||||||
break;
|
finalResult = (double) pSlot->range.dMinVal;
|
||||||
}
|
|
||||||
|
|
||||||
case TSDB_DATA_TYPE_FLOAT:
|
|
||||||
case TSDB_DATA_TYPE_DOUBLE: {
|
|
||||||
finalResult = pSlot->range.dMinVal;
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
|
|
||||||
case TSDB_DATA_TYPE_BIGINT: {
|
|
||||||
finalResult = (double)pSlot->range.i64MinVal;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return finalResult;
|
return finalResult;
|
||||||
|
@ -616,26 +400,16 @@ double getPercentileImpl(tMemBucket *pMemBucket, int32_t count, double fraction)
|
||||||
|
|
||||||
double maxOfThisSlot = 0;
|
double maxOfThisSlot = 0;
|
||||||
double minOfNextSlot = 0;
|
double minOfNextSlot = 0;
|
||||||
switch (pMemBucket->type) {
|
if (IS_SIGNED_NUMERIC_TYPE(pMemBucket->type)) {
|
||||||
case TSDB_DATA_TYPE_INT:
|
maxOfThisSlot = (double) pSlot->range.i64MaxVal;
|
||||||
case TSDB_DATA_TYPE_SMALLINT:
|
minOfNextSlot = (double) next.i64MinVal;
|
||||||
case TSDB_DATA_TYPE_TINYINT: {
|
} else if (IS_UNSIGNED_NUMERIC_TYPE(pMemBucket->type)) {
|
||||||
maxOfThisSlot = pSlot->range.iMaxVal;
|
maxOfThisSlot = (double) pSlot->range.u64MaxVal;
|
||||||
minOfNextSlot = next.iMinVal;
|
minOfNextSlot = (double) next.u64MinVal;
|
||||||
break;
|
} else {
|
||||||
};
|
maxOfThisSlot = (double) pSlot->range.dMaxVal;
|
||||||
case TSDB_DATA_TYPE_FLOAT:
|
minOfNextSlot = (double) next.dMinVal;
|
||||||
case TSDB_DATA_TYPE_DOUBLE: {
|
}
|
||||||
maxOfThisSlot = pSlot->range.dMaxVal;
|
|
||||||
minOfNextSlot = next.dMinVal;
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
case TSDB_DATA_TYPE_BIGINT: {
|
|
||||||
maxOfThisSlot = (double)pSlot->range.i64MaxVal;
|
|
||||||
minOfNextSlot = (double)next.i64MinVal;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
assert(minOfNextSlot > maxOfThisSlot);
|
assert(minOfNextSlot > maxOfThisSlot);
|
||||||
|
|
||||||
|
@ -652,38 +426,8 @@ double getPercentileImpl(tMemBucket *pMemBucket, int32_t count, double fraction)
|
||||||
char *nextVal = thisVal + pMemBucket->bytes;
|
char *nextVal = thisVal + pMemBucket->bytes;
|
||||||
|
|
||||||
double td = 1.0, nd = 1.0;
|
double td = 1.0, nd = 1.0;
|
||||||
switch (pMemBucket->type) {
|
GET_TYPED_DATA(td, double, pMemBucket->type, thisVal);
|
||||||
case TSDB_DATA_TYPE_SMALLINT: {
|
GET_TYPED_DATA(nd, double, pMemBucket->type, nextVal);
|
||||||
td = *(int16_t *)thisVal;
|
|
||||||
nd = *(int16_t *)nextVal;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case TSDB_DATA_TYPE_TINYINT: {
|
|
||||||
td = *(int8_t *)thisVal;
|
|
||||||
nd = *(int8_t *)nextVal;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case TSDB_DATA_TYPE_INT: {
|
|
||||||
td = *(int32_t *)thisVal;
|
|
||||||
nd = *(int32_t *)nextVal;
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
case TSDB_DATA_TYPE_FLOAT: {
|
|
||||||
td = GET_FLOAT_VAL(thisVal);
|
|
||||||
nd = GET_FLOAT_VAL(nextVal);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case TSDB_DATA_TYPE_DOUBLE: {
|
|
||||||
td = GET_DOUBLE_VAL(thisVal);
|
|
||||||
nd = GET_DOUBLE_VAL(nextVal);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case TSDB_DATA_TYPE_BIGINT: {
|
|
||||||
td = (double)*(int64_t *)thisVal;
|
|
||||||
nd = (double)*(int64_t *)nextVal;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
double val = (1 - fraction) * td + fraction * nd;
|
double val = (1 - fraction) * td + fraction * nd;
|
||||||
tfree(buffer);
|
tfree(buffer);
|
||||||
|
@ -696,7 +440,7 @@ double getPercentileImpl(tMemBucket *pMemBucket, int32_t count, double fraction)
|
||||||
|
|
||||||
// try next round
|
// try next round
|
||||||
pMemBucket->times += 1;
|
pMemBucket->times += 1;
|
||||||
uDebug("MemBucket:%p, start next round data bucketing, time:%d", pMemBucket, pMemBucket->times);
|
qDebug("MemBucket:%p, start next round data bucketing, time:%d", pMemBucket, pMemBucket->times);
|
||||||
|
|
||||||
pMemBucket->range = pSlot->range;
|
pMemBucket->range = pSlot->range;
|
||||||
pMemBucket->total = 0;
|
pMemBucket->total = 0;
|
||||||
|
@ -741,20 +485,14 @@ double getPercentile(tMemBucket *pMemBucket, double percent) {
|
||||||
if (fabs(percent - 100.0) < DBL_EPSILON || (percent < DBL_EPSILON)) {
|
if (fabs(percent - 100.0) < DBL_EPSILON || (percent < DBL_EPSILON)) {
|
||||||
MinMaxEntry* pRange = &pMemBucket->range;
|
MinMaxEntry* pRange = &pMemBucket->range;
|
||||||
|
|
||||||
switch(pMemBucket->type) {
|
if (IS_SIGNED_NUMERIC_TYPE(pMemBucket->type)) {
|
||||||
case TSDB_DATA_TYPE_TINYINT:
|
double v = (double)(fabs(percent - 100) < DBL_EPSILON ? pRange->i64MaxVal : pRange->i64MinVal);
|
||||||
case TSDB_DATA_TYPE_SMALLINT:
|
return v;
|
||||||
case TSDB_DATA_TYPE_INT:
|
} else if (IS_UNSIGNED_NUMERIC_TYPE(pMemBucket->type)) {
|
||||||
return fabs(percent - 100) < DBL_EPSILON? pRange->iMaxVal:pRange->iMinVal;
|
double v = (double)(fabs(percent - 100) < DBL_EPSILON ? pRange->u64MaxVal : pRange->u64MinVal);
|
||||||
case TSDB_DATA_TYPE_BIGINT: {
|
return v;
|
||||||
double v = (double)(fabs(percent - 100) < DBL_EPSILON ? pRange->i64MaxVal : pRange->i64MinVal);
|
} else {
|
||||||
return v;
|
return fabs(percent - 100) < DBL_EPSILON? pRange->dMaxVal:pRange->dMinVal;
|
||||||
}
|
|
||||||
case TSDB_DATA_TYPE_FLOAT:
|
|
||||||
case TSDB_DATA_TYPE_DOUBLE:
|
|
||||||
return fabs(percent - 100) < DBL_EPSILON? pRange->dMaxVal:pRange->dMinVal;
|
|
||||||
default:
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -771,40 +509,9 @@ double getPercentile(tMemBucket *pMemBucket, double percent) {
|
||||||
bool isIdenticalData(tMemBucket *pMemBucket, int32_t index) {
|
bool isIdenticalData(tMemBucket *pMemBucket, int32_t index) {
|
||||||
tMemBucketSlot *pSeg = &pMemBucket->pSlots[index];
|
tMemBucketSlot *pSeg = &pMemBucket->pSlots[index];
|
||||||
|
|
||||||
if (pMemBucket->type == TSDB_DATA_TYPE_INT || pMemBucket->type == TSDB_DATA_TYPE_BIGINT ||
|
if (IS_FLOAT_TYPE(pMemBucket->type)) {
|
||||||
pMemBucket->type == TSDB_DATA_TYPE_SMALLINT || pMemBucket->type == TSDB_DATA_TYPE_TINYINT) {
|
return fabs(pSeg->range.dMaxVal - pSeg->range.dMinVal) < DBL_EPSILON;
|
||||||
|
} else {
|
||||||
return pSeg->range.i64MinVal == pSeg->range.i64MaxVal;
|
return pSeg->range.i64MinVal == pSeg->range.i64MaxVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pMemBucket->type == TSDB_DATA_TYPE_FLOAT || pMemBucket->type == TSDB_DATA_TYPE_DOUBLE) {
|
|
||||||
return fabs(pSeg->range.dMaxVal - pSeg->range.dMinVal) < DBL_EPSILON;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* get the first element of one slot into memory.
|
|
||||||
* if no data of current slot in memory, load it from disk
|
|
||||||
*/
|
|
||||||
char *getFirstElemOfMemBuffer(tMemBucketSlot *pSeg, int32_t slotIdx, tFilePage *pPage) {
|
|
||||||
// STSBuf *pMemBuffer = pSeg->pBuffer[slotIdx];
|
|
||||||
char *thisVal = NULL;
|
|
||||||
|
|
||||||
// if (pSeg->pBuffer[slotIdx]->numOfTotal != 0) {
|
|
||||||
//// thisVal = pSeg->pBuffer[slotIdx]->pHead->item.data;
|
|
||||||
// } else {
|
|
||||||
// /*
|
|
||||||
// * no data in memory, load one page into memory
|
|
||||||
// */
|
|
||||||
// tFlushoutInfo *pFlushInfo = &pMemBuffer->fileMeta.flushoutData.pFlushoutInfo[0];
|
|
||||||
// assert(pFlushInfo->numOfPages == pMemBuffer->fileMeta.nFileSize);
|
|
||||||
// int32_t ret;
|
|
||||||
// ret = fseek(pMemBuffer->file, pFlushInfo->startPageId * pMemBuffer->pageSize, SEEK_SET);
|
|
||||||
// UNUSED(ret);
|
|
||||||
// size_t sz = fread(pPage, pMemBuffer->pageSize, 1, pMemBuffer->file);
|
|
||||||
// UNUSED(sz);
|
|
||||||
// thisVal = pPage->data;
|
|
||||||
// }
|
|
||||||
return thisVal;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,254 @@
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "qResultbuf.h"
|
||||||
|
#include "taos.h"
|
||||||
|
#include "taosdef.h"
|
||||||
|
|
||||||
|
#include "qPercentile.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
tMemBucket *createBigIntDataBucket(int32_t start, int32_t end) {
|
||||||
|
tMemBucket *pBucket = tMemBucketCreate(sizeof(int64_t), TSDB_DATA_TYPE_BIGINT, start, end);
|
||||||
|
for (int32_t i = start; i <= end; ++i) {
|
||||||
|
int64_t val = i;
|
||||||
|
tMemBucketPut(pBucket, &val, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pBucket;
|
||||||
|
}
|
||||||
|
|
||||||
|
tMemBucket *createIntDataBucket(int32_t start, int32_t end) {
|
||||||
|
tMemBucket *pBucket = tMemBucketCreate(sizeof(int32_t), TSDB_DATA_TYPE_INT, start, end);
|
||||||
|
|
||||||
|
for (int32_t i = start; i <= end; ++i) {
|
||||||
|
int32_t val = i;
|
||||||
|
tMemBucketPut(pBucket, &val, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pBucket;
|
||||||
|
}
|
||||||
|
|
||||||
|
tMemBucket *createDoubleDataBucket(int32_t start, int32_t end) {
|
||||||
|
tMemBucket *pBucket = tMemBucketCreate(sizeof(double), TSDB_DATA_TYPE_DOUBLE, start, end);
|
||||||
|
for (int32_t i = start; i <= end; ++i) {
|
||||||
|
double val = i;
|
||||||
|
int32_t ret = tMemBucketPut(pBucket, &val, 1);
|
||||||
|
if (ret != 0) {
|
||||||
|
printf("value out of range:%f", val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pBucket;
|
||||||
|
}
|
||||||
|
|
||||||
|
tMemBucket *createUnsignedDataBucket(int32_t start, int32_t end, int32_t type) {
|
||||||
|
tMemBucket *pBucket = tMemBucketCreate(tDataTypeDesc[type].nSize, type, start, end);
|
||||||
|
for (int32_t i = start; i <= end; ++i) {
|
||||||
|
uint64_t k = i;
|
||||||
|
int32_t ret = tMemBucketPut(pBucket, &k, 1);
|
||||||
|
if (ret != 0) {
|
||||||
|
printf("value out of range:%f", k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pBucket;
|
||||||
|
}
|
||||||
|
|
||||||
|
void intDataTest() {
|
||||||
|
printf("running %s\n", __FUNCTION__);
|
||||||
|
|
||||||
|
tMemBucket *pBucket = NULL;
|
||||||
|
double result = 0.;
|
||||||
|
|
||||||
|
pBucket = createIntDataBucket(0, 0);
|
||||||
|
result = getPercentile(pBucket, 0);
|
||||||
|
ASSERT_DOUBLE_EQ(result, 0);
|
||||||
|
tMemBucketDestroy(pBucket);
|
||||||
|
|
||||||
|
pBucket = createIntDataBucket(0, 1);
|
||||||
|
result = getPercentile(pBucket, 100);
|
||||||
|
ASSERT_DOUBLE_EQ(result, 1);
|
||||||
|
|
||||||
|
result = getPercentile(pBucket, 0);
|
||||||
|
ASSERT_DOUBLE_EQ(result, 0);
|
||||||
|
tMemBucketDestroy(pBucket);
|
||||||
|
|
||||||
|
pBucket = createIntDataBucket(-1, 1);
|
||||||
|
|
||||||
|
result = getPercentile(pBucket, 50);
|
||||||
|
ASSERT_DOUBLE_EQ(result, 0);
|
||||||
|
|
||||||
|
result = getPercentile(pBucket, 0);
|
||||||
|
ASSERT_DOUBLE_EQ(result, -1);
|
||||||
|
|
||||||
|
result = getPercentile(pBucket, 75);
|
||||||
|
ASSERT_DOUBLE_EQ(result, 0.5);
|
||||||
|
|
||||||
|
result = getPercentile(pBucket, 100);
|
||||||
|
ASSERT_DOUBLE_EQ(result, 1);
|
||||||
|
tMemBucketDestroy(pBucket);
|
||||||
|
|
||||||
|
pBucket = createIntDataBucket(0, 99999);
|
||||||
|
result = getPercentile(pBucket, 50);
|
||||||
|
ASSERT_DOUBLE_EQ(result, 49999.5);
|
||||||
|
|
||||||
|
tMemBucketDestroy(pBucket);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bigintDataTest() {
|
||||||
|
printf("running %s\n", __FUNCTION__);
|
||||||
|
|
||||||
|
tMemBucket *pBucket = NULL;
|
||||||
|
double result = 0.0;
|
||||||
|
|
||||||
|
pBucket = createBigIntDataBucket(-1000, 1000);
|
||||||
|
result = getPercentile(pBucket, 50);
|
||||||
|
ASSERT_DOUBLE_EQ(result, 0.);
|
||||||
|
tMemBucketDestroy(pBucket);
|
||||||
|
|
||||||
|
pBucket = createBigIntDataBucket(-10000, 10000);
|
||||||
|
result = getPercentile(pBucket, 100);
|
||||||
|
ASSERT_DOUBLE_EQ(result, 10000.0);
|
||||||
|
tMemBucketDestroy(pBucket);
|
||||||
|
|
||||||
|
pBucket = createBigIntDataBucket(-10000, 10000);
|
||||||
|
result = getPercentile(pBucket, 75);
|
||||||
|
ASSERT_DOUBLE_EQ(result, 5000.0);
|
||||||
|
|
||||||
|
tMemBucketDestroy(pBucket);
|
||||||
|
}
|
||||||
|
|
||||||
|
void doubleDataTest() {
|
||||||
|
printf("running %s\n", __FUNCTION__);
|
||||||
|
|
||||||
|
tMemBucket *pBucket = NULL;
|
||||||
|
double result = 0;
|
||||||
|
|
||||||
|
pBucket = createDoubleDataBucket(-10, 10);
|
||||||
|
result = getPercentile(pBucket, 0);
|
||||||
|
ASSERT_DOUBLE_EQ(result, -10.0);
|
||||||
|
|
||||||
|
printf("result is: %lf\n", result);
|
||||||
|
tMemBucketDestroy(pBucket);
|
||||||
|
|
||||||
|
pBucket = createDoubleDataBucket(-100000, 100000);
|
||||||
|
result = getPercentile(pBucket, 25);
|
||||||
|
ASSERT_DOUBLE_EQ(result, -50000);
|
||||||
|
|
||||||
|
printf("result is: %lf\n", result);
|
||||||
|
|
||||||
|
tMemBucketDestroy(pBucket);
|
||||||
|
|
||||||
|
pBucket = createDoubleDataBucket(-100000, 100000);
|
||||||
|
result = getPercentile(pBucket, 50);
|
||||||
|
ASSERT_DOUBLE_EQ(result, 0);
|
||||||
|
|
||||||
|
tMemBucketDestroy(pBucket);
|
||||||
|
|
||||||
|
pBucket = createDoubleDataBucket(-100000, 100000);
|
||||||
|
result = getPercentile(pBucket, 75);
|
||||||
|
ASSERT_DOUBLE_EQ(result, 50000);
|
||||||
|
tMemBucketDestroy(pBucket);
|
||||||
|
|
||||||
|
pBucket = createDoubleDataBucket(-100000, 100000);
|
||||||
|
|
||||||
|
result = getPercentile(pBucket, 100);
|
||||||
|
ASSERT_DOUBLE_EQ(result, 100000.0);
|
||||||
|
|
||||||
|
printf("result is: %lf\n", result);
|
||||||
|
tMemBucketDestroy(pBucket);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* large data test, we employ 0.1billion double data to calculated the percentile
|
||||||
|
* which is 800MB data
|
||||||
|
*/
|
||||||
|
void largeDataTest() {
|
||||||
|
printf("running : %s\n", __FUNCTION__);
|
||||||
|
|
||||||
|
tMemBucket *pBucket = NULL;
|
||||||
|
double result = 0;
|
||||||
|
|
||||||
|
struct timeval tv;
|
||||||
|
gettimeofday(&tv, NULL);
|
||||||
|
|
||||||
|
int64_t start = tv.tv_sec;
|
||||||
|
printf("start time: %" PRId64 "\n", tv.tv_sec);
|
||||||
|
pBucket = createDoubleDataBucket(0, 100000000);
|
||||||
|
result = getPercentile(pBucket, 50);
|
||||||
|
ASSERT_DOUBLE_EQ(result, 50000000);
|
||||||
|
|
||||||
|
gettimeofday(&tv, NULL);
|
||||||
|
|
||||||
|
printf("total elapsed time: %" PRId64 " sec.", -start + tv.tv_sec);
|
||||||
|
printf("the result of %d is: %lf\n", 50, result);
|
||||||
|
tMemBucketDestroy(pBucket);
|
||||||
|
}
|
||||||
|
|
||||||
|
void qsortTest() {
|
||||||
|
printf("running : %s\n", __FUNCTION__);
|
||||||
|
|
||||||
|
SSchema field[1] = {
|
||||||
|
{TSDB_DATA_TYPE_INT, "k", sizeof(int32_t)},
|
||||||
|
};
|
||||||
|
|
||||||
|
const int32_t num = 2000;
|
||||||
|
|
||||||
|
int32_t *d = (int32_t *)malloc(sizeof(int32_t) * num);
|
||||||
|
for (int32_t i = 0; i < num; ++i) {
|
||||||
|
d[i] = i % 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int32_t numOfOrderCols = 1;
|
||||||
|
int32_t orderColIdx = 0;
|
||||||
|
SColumnModel * pModel = createColumnModel(field, 1, 1000);
|
||||||
|
tOrderDescriptor *pDesc = tOrderDesCreate(&orderColIdx, numOfOrderCols, pModel, 1);
|
||||||
|
|
||||||
|
tColDataQSort(pDesc, num, 0, num - 1, (char *)d, 1);
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < num; ++i) {
|
||||||
|
printf("%d\t", d[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
destroyColumnModel(pModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void unsignedDataTest() {
|
||||||
|
printf("running %s\n", __FUNCTION__);
|
||||||
|
|
||||||
|
tMemBucket *pBucket = NULL;
|
||||||
|
double result = 0.0;
|
||||||
|
|
||||||
|
pBucket = createUnsignedDataBucket(0, 1000, TSDB_DATA_TYPE_UINT);
|
||||||
|
result = getPercentile(pBucket, 50);
|
||||||
|
ASSERT_DOUBLE_EQ(result, 500.0);
|
||||||
|
tMemBucketDestroy(pBucket);
|
||||||
|
|
||||||
|
pBucket = createUnsignedDataBucket(0, 10000, TSDB_DATA_TYPE_UBIGINT);
|
||||||
|
result = getPercentile(pBucket, 100);
|
||||||
|
ASSERT_DOUBLE_EQ(result, 10000.0);
|
||||||
|
|
||||||
|
result = getPercentile(pBucket, 0);
|
||||||
|
ASSERT_DOUBLE_EQ(result, 0.0);
|
||||||
|
|
||||||
|
result = getPercentile(pBucket, 50);
|
||||||
|
ASSERT_DOUBLE_EQ(result, 5000);
|
||||||
|
|
||||||
|
result = getPercentile(pBucket, 75);
|
||||||
|
ASSERT_DOUBLE_EQ(result, 7500);
|
||||||
|
tMemBucketDestroy(pBucket);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
TEST(testCase, percentileTest) {
|
||||||
|
// qsortTest();
|
||||||
|
intDataTest();
|
||||||
|
bigintDataTest();
|
||||||
|
doubleDataTest();
|
||||||
|
unsignedDataTest();
|
||||||
|
largeDataTest();
|
||||||
|
}
|
|
@ -30,24 +30,32 @@ int32_t compareInt8Val(const void *pLeft, const void *pRight) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t compareIntDoubleVal(const void *pLeft, const void *pRight) {
|
int32_t compareUint32Val(const void *pLeft, const void *pRight) {
|
||||||
int64_t lhs = GET_INT64_VAL(pLeft);
|
int32_t left = GET_UINT32_VAL(pLeft), right = GET_UINT32_VAL(pRight);
|
||||||
double rhs = GET_DOUBLE_VAL(pRight);
|
if (left > right) return 1;
|
||||||
if (fabs(lhs - rhs) < FLT_EPSILON) {
|
if (left < right) return -1;
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
|
||||||
return (lhs > rhs) ? 1 : -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t compareDoubleIntVal(const void *pLeft, const void *pRight) {
|
int32_t compareUint64Val(const void *pLeft, const void *pRight) {
|
||||||
double lhs = GET_DOUBLE_VAL(pLeft);
|
int64_t left = GET_UINT64_VAL(pLeft), right = GET_UINT64_VAL(pRight);
|
||||||
int64_t rhs = GET_INT64_VAL(pRight);
|
if (left > right) return 1;
|
||||||
if (fabs(lhs - rhs) < FLT_EPSILON) {
|
if (left < right) return -1;
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
}
|
||||||
return (lhs > rhs) ? 1 : -1;
|
|
||||||
}
|
int32_t compareUint16Val(const void *pLeft, const void *pRight) {
|
||||||
|
int16_t left = GET_UINT16_VAL(pLeft), right = GET_UINT16_VAL(pRight);
|
||||||
|
if (left > right) return 1;
|
||||||
|
if (left < right) return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t compareUint8Val(const void* pLeft, const void* pRight) {
|
||||||
|
uint8_t left = GET_UINT8_VAL(pLeft), right = GET_UINT8_VAL(pRight);
|
||||||
|
if (left > right) return 1;
|
||||||
|
if (left < right) return -1;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t compareFloatVal(const void *pLeft, const void *pRight) {
|
int32_t compareFloatVal(const void *pLeft, const void *pRight) {
|
||||||
|
@ -369,15 +377,24 @@ __compar_fn_t getKeyComparFunc(int32_t keyType) {
|
||||||
case TSDB_DATA_TYPE_DOUBLE:
|
case TSDB_DATA_TYPE_DOUBLE:
|
||||||
comparFn = compareDoubleVal;
|
comparFn = compareDoubleVal;
|
||||||
break;
|
break;
|
||||||
|
case TSDB_DATA_TYPE_UTINYINT:
|
||||||
|
comparFn = compareUint8Val;
|
||||||
|
break;
|
||||||
|
case TSDB_DATA_TYPE_USMALLINT:
|
||||||
|
comparFn = compareUint16Val;
|
||||||
|
break;
|
||||||
|
case TSDB_DATA_TYPE_UINT:
|
||||||
|
comparFn = compareUint32Val;
|
||||||
|
break;
|
||||||
|
case TSDB_DATA_TYPE_UBIGINT:
|
||||||
|
comparFn = compareUint64Val;
|
||||||
|
break;
|
||||||
case TSDB_DATA_TYPE_BINARY:
|
case TSDB_DATA_TYPE_BINARY:
|
||||||
comparFn = compareLenPrefixedStr;
|
comparFn = compareLenPrefixedStr;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TSDB_DATA_TYPE_NCHAR:
|
case TSDB_DATA_TYPE_NCHAR:
|
||||||
comparFn = compareLenPrefixedWStr;
|
comparFn = compareLenPrefixedWStr;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
comparFn = compareInt32Val;
|
comparFn = compareInt32Val;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -67,7 +67,7 @@ typedef struct {
|
||||||
void * qMgmt;
|
void * qMgmt;
|
||||||
char * rootDir;
|
char * rootDir;
|
||||||
tsem_t sem;
|
tsem_t sem;
|
||||||
char db[TSDB_ACCT_LEN + TSDB_DB_NAME_LEN];
|
char db[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN];
|
||||||
pthread_mutex_t statusMutex;
|
pthread_mutex_t statusMutex;
|
||||||
} SVnodeObj;
|
} SVnodeObj;
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ system sh/stop_dnodes.sh
|
||||||
|
|
||||||
system sh/deploy.sh -n dnode1 -i 1
|
system sh/deploy.sh -n dnode1 -i 1
|
||||||
system sh/cfg.sh -n dnode1 -c walLevel -v 0
|
system sh/cfg.sh -n dnode1 -c walLevel -v 0
|
||||||
system sh/cfg.sh -n dnode1 -c tableMetaKeepTimer -v 10
|
|
||||||
system sh/exec.sh -n dnode1 -s start
|
system sh/exec.sh -n dnode1 -s start
|
||||||
|
|
||||||
sleep 3000
|
sleep 3000
|
||||||
|
|
|
@ -3,7 +3,6 @@ system sh/stop_dnodes.sh
|
||||||
|
|
||||||
system sh/deploy.sh -n dnode1 -i 1
|
system sh/deploy.sh -n dnode1 -i 1
|
||||||
system sh/cfg.sh -n dnode1 -c walLevel -v 0
|
system sh/cfg.sh -n dnode1 -c walLevel -v 0
|
||||||
system sh/cfg.sh -n dnode1 -c tableMetaKeepTimer -v 10
|
|
||||||
system sh/exec.sh -n dnode1 -s start
|
system sh/exec.sh -n dnode1 -s start
|
||||||
|
|
||||||
sleep 3000
|
sleep 3000
|
||||||
|
@ -53,7 +52,6 @@ system sh/exec.sh -n dnode1 -s stop
|
||||||
sleep 5000
|
sleep 5000
|
||||||
system sh/deploy.sh -n dnode1 -i 1
|
system sh/deploy.sh -n dnode1 -i 1
|
||||||
system sh/cfg.sh -n dnode1 -c walLevel -v 0
|
system sh/cfg.sh -n dnode1 -c walLevel -v 0
|
||||||
system sh/cfg.sh -n dnode1 -c tableMetaKeepTimer -v 10
|
|
||||||
system sh/exec.sh -n dnode1 -s start
|
system sh/exec.sh -n dnode1 -s start
|
||||||
|
|
||||||
print =============== step3
|
print =============== step3
|
||||||
|
|
|
@ -3,7 +3,6 @@ system sh/stop_dnodes.sh
|
||||||
|
|
||||||
system sh/deploy.sh -n dnode1 -i 1
|
system sh/deploy.sh -n dnode1 -i 1
|
||||||
system sh/cfg.sh -n dnode1 -c walLevel -v 0
|
system sh/cfg.sh -n dnode1 -c walLevel -v 0
|
||||||
system sh/cfg.sh -n dnode1 -c tableMetaKeepTimer -v 10
|
|
||||||
system sh/exec.sh -n dnode1 -s start
|
system sh/exec.sh -n dnode1 -s start
|
||||||
|
|
||||||
sleep 3000
|
sleep 3000
|
||||||
|
@ -37,7 +36,6 @@ system sh/exec.sh -n dnode1 -s stop
|
||||||
sleep 5000
|
sleep 5000
|
||||||
system sh/deploy.sh -n dnode1 -i 1
|
system sh/deploy.sh -n dnode1 -i 1
|
||||||
system sh/cfg.sh -n dnode1 -c walLevel -v 0
|
system sh/cfg.sh -n dnode1 -c walLevel -v 0
|
||||||
system sh/cfg.sh -n dnode1 -c tableMetaKeepTimer -v 10
|
|
||||||
system sh/exec.sh -n dnode1 -s start
|
system sh/exec.sh -n dnode1 -s start
|
||||||
|
|
||||||
print =============== step3
|
print =============== step3
|
||||||
|
|
|
@ -2,7 +2,6 @@ system sh/stop_dnodes.sh
|
||||||
|
|
||||||
system sh/deploy.sh -n dnode1 -i 1
|
system sh/deploy.sh -n dnode1 -i 1
|
||||||
system sh/cfg.sh -n dnode1 -c walLevel -v 0
|
system sh/cfg.sh -n dnode1 -c walLevel -v 0
|
||||||
system sh/cfg.sh -n dnode1 -c tableMetaKeepTimer -v 3
|
|
||||||
system sh/exec.sh -n dnode1 -s start
|
system sh/exec.sh -n dnode1 -s start
|
||||||
sleep 100
|
sleep 100
|
||||||
sql connect
|
sql connect
|
||||||
|
|
|
@ -2,7 +2,6 @@ system sh/stop_dnodes.sh
|
||||||
|
|
||||||
system sh/deploy.sh -n dnode1 -i 1
|
system sh/deploy.sh -n dnode1 -i 1
|
||||||
system sh/cfg.sh -n dnode1 -c walLevel -v 0
|
system sh/cfg.sh -n dnode1 -c walLevel -v 0
|
||||||
system sh/cfg.sh -n dnode1 -c tableMetaKeepTimer -v 3
|
|
||||||
system sh/exec.sh -n dnode1 -s start
|
system sh/exec.sh -n dnode1 -s start
|
||||||
sleep 100
|
sleep 100
|
||||||
sql connect
|
sql connect
|
||||||
|
|
|
@ -2,7 +2,6 @@ system sh/stop_dnodes.sh
|
||||||
|
|
||||||
system sh/deploy.sh -n dnode1 -i 1
|
system sh/deploy.sh -n dnode1 -i 1
|
||||||
system sh/cfg.sh -n dnode1 -c walLevel -v 0
|
system sh/cfg.sh -n dnode1 -c walLevel -v 0
|
||||||
system sh/cfg.sh -n dnode1 -c tableMetaKeepTimer -v 3
|
|
||||||
system sh/exec.sh -n dnode1 -s start
|
system sh/exec.sh -n dnode1 -s start
|
||||||
sleep 100
|
sleep 100
|
||||||
sql connect
|
sql connect
|
||||||
|
|
|
@ -3,7 +3,6 @@ system sh/stop_dnodes.sh
|
||||||
|
|
||||||
system sh/deploy.sh -n dnode1 -i 1
|
system sh/deploy.sh -n dnode1 -i 1
|
||||||
system sh/cfg.sh -n dnode1 -c walLevel -v 0
|
system sh/cfg.sh -n dnode1 -c walLevel -v 0
|
||||||
system sh/cfg.sh -n dnode1 -c tableMetaKeepTimer -v 3
|
|
||||||
system sh/exec.sh -n dnode1 -s start
|
system sh/exec.sh -n dnode1 -s start
|
||||||
sleep 100
|
sleep 100
|
||||||
sql connect
|
sql connect
|
||||||
|
|
|
@ -106,4 +106,70 @@ if $data01 != 1 then
|
||||||
return -1
|
return -1
|
||||||
endi
|
endi
|
||||||
|
|
||||||
sql select a+b+c from mt_unsigned_1 where a is null;
|
sql select a+b+c from mt_unsigned_1 where a is null;
|
||||||
|
if $rows != 1 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
if $data00 != 6.000000000 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
sql select count(*), a from mt_unsigned_1 group by a;
|
||||||
|
if $rows != 1 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
if $data00 != 1 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
if $data01 != 1 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
sql select count(*), b from mt_unsigned_1 group by b;
|
||||||
|
if $rows != 1 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
if $data00 != 1 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
if $data01 != 2 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
sql select count(*), c from mt_unsigned_1 group by c;
|
||||||
|
if $rows != 1 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
if $data00 != 1 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
if $data01 != 3 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
sql select count(*), d from mt_unsigned_1 group by d;
|
||||||
|
if $rows != 1 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
if $data00 != 1 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
if $data01 != 4 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
// todo insert more rows and chec it
|
||||||
|
sql select first(a),count(b),last(c),sum(b),spread(d),avg(c),min(b),max(a),stddev(a) from mt_unsigned_1;
|
||||||
|
if $rows != 1 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ system sh/stop_dnodes.sh
|
||||||
|
|
||||||
system sh/deploy.sh -n dnode1 -i 1
|
system sh/deploy.sh -n dnode1 -i 1
|
||||||
system sh/cfg.sh -n dnode1 -c walLevel -v 0
|
system sh/cfg.sh -n dnode1 -c walLevel -v 0
|
||||||
system sh/cfg.sh -n dnode1 -c tableMetaKeepTimer -v 3
|
|
||||||
system sh/exec.sh -n dnode1 -s start
|
system sh/exec.sh -n dnode1 -s start
|
||||||
sleep 100
|
sleep 100
|
||||||
sql connect
|
sql connect
|
||||||
|
@ -228,7 +227,7 @@ sql select twa(k),avg(k),count(1) from t1 where ts>='2015-8-18 00:00:00' and ts<
|
||||||
sql select twa(k),avg(k),count(1) from t1 where ts>='2015-8-18 00:00:00' and ts<='2015-8-18 00:30:00' interval(10m) order by ts desc
|
sql select twa(k),avg(k),count(1) from t1 where ts>='2015-8-18 00:00:00' and ts<='2015-8-18 00:30:00' interval(10m) order by ts desc
|
||||||
|
|
||||||
|
|
||||||
#todo add test case while column filter exists.
|
#todo add test case while column filter exists for twa query
|
||||||
|
|
||||||
#sql select count(*),TWA(k) from tm0 where ts>='1970-1-1 13:43:00' and ts<='1970-1-1 13:44:10' interval(9s)
|
#sql select count(*),TWA(k) from tm0 where ts>='1970-1-1 13:43:00' and ts<='1970-1-1 13:44:10' interval(9s)
|
||||||
|
|
||||||
|
@ -373,3 +372,14 @@ sql select twa(k) from tm2 where ts='2020-12-29 18:46:19.109'
|
||||||
if $rows != 0 then
|
if $rows != 0 then
|
||||||
return -1
|
return -1
|
||||||
endi
|
endi
|
||||||
|
|
||||||
|
print ========================> TD-1787
|
||||||
|
sql create table cars(ts timestamp, c int) tags(id int);
|
||||||
|
sql create table car1 using cars tags(1);
|
||||||
|
sql create table car2 using cars tags(2);
|
||||||
|
sql insert into car1 (ts, c) values (now,1) car2(ts, c) values(now, 2);
|
||||||
|
sql drop table cars;
|
||||||
|
sql create table cars(ts timestamp, c int) tags(id int);
|
||||||
|
sql create table car1 using cars tags(1);
|
||||||
|
sql create table car2 using cars tags(2);
|
||||||
|
sql insert into car1 (ts, c) values (now,1) car2(ts, c) values(now, 2);
|
|
@ -3,7 +3,6 @@ system sh/stop_dnodes.sh
|
||||||
|
|
||||||
system sh/deploy.sh -n dnode1 -i 1
|
system sh/deploy.sh -n dnode1 -i 1
|
||||||
system sh/cfg.sh -n dnode1 -c walLevel -v 0
|
system sh/cfg.sh -n dnode1 -c walLevel -v 0
|
||||||
system sh/cfg.sh -n dnode1 -c tableMetaKeepTimer -v 3
|
|
||||||
system sh/exec.sh -n dnode1 -s start
|
system sh/exec.sh -n dnode1 -s start
|
||||||
|
|
||||||
sleep 100
|
sleep 100
|
||||||
|
|
|
@ -3,7 +3,6 @@ system sh/stop_dnodes.sh
|
||||||
|
|
||||||
system sh/deploy.sh -n dnode1 -i 1
|
system sh/deploy.sh -n dnode1 -i 1
|
||||||
system sh/cfg.sh -n dnode1 -c walLevel -v 0
|
system sh/cfg.sh -n dnode1 -c walLevel -v 0
|
||||||
system sh/cfg.sh -n dnode1 -c tableMetaKeepTimer -v 1
|
|
||||||
system sh/exec.sh -n dnode1 -s start
|
system sh/exec.sh -n dnode1 -s start
|
||||||
|
|
||||||
sleep 3000
|
sleep 3000
|
||||||
|
@ -98,7 +97,6 @@ print =============== step4
|
||||||
system sh/exec.sh -n dnode1 -s stop
|
system sh/exec.sh -n dnode1 -s stop
|
||||||
system sh/deploy.sh -n dnode1 -i 1
|
system sh/deploy.sh -n dnode1 -i 1
|
||||||
system sh/cfg.sh -n dnode1 -c walLevel -v 0
|
system sh/cfg.sh -n dnode1 -c walLevel -v 0
|
||||||
system sh/cfg.sh -n dnode1 -c tableMetaKeepTimer -v 1
|
|
||||||
system sh/exec.sh -n dnode1 -s start
|
system sh/exec.sh -n dnode1 -s start
|
||||||
|
|
||||||
print =============== step5
|
print =============== step5
|
||||||
|
|
|
@ -113,7 +113,6 @@ echo "rpcDebugFlag 143" >> $TAOS_CFG
|
||||||
echo "tmrDebugFlag 131" >> $TAOS_CFG
|
echo "tmrDebugFlag 131" >> $TAOS_CFG
|
||||||
echo "cDebugFlag 143" >> $TAOS_CFG
|
echo "cDebugFlag 143" >> $TAOS_CFG
|
||||||
echo "udebugFlag 143" >> $TAOS_CFG
|
echo "udebugFlag 143" >> $TAOS_CFG
|
||||||
echo "tablemetakeeptimer 5" >> $TAOS_CFG
|
|
||||||
echo "wal 0" >> $TAOS_CFG
|
echo "wal 0" >> $TAOS_CFG
|
||||||
echo "asyncLog 0" >> $TAOS_CFG
|
echo "asyncLog 0" >> $TAOS_CFG
|
||||||
echo "locale en_US.UTF-8" >> $TAOS_CFG
|
echo "locale en_US.UTF-8" >> $TAOS_CFG
|
||||||
|
|
|
@ -14,8 +14,6 @@ system sh/cfg.sh -n dnode1 -c mnodeEqualVnodeNum -v 0
|
||||||
system sh/cfg.sh -n dnode2 -c mnodeEqualVnodeNum -v 0
|
system sh/cfg.sh -n dnode2 -c mnodeEqualVnodeNum -v 0
|
||||||
system sh/cfg.sh -n dnode1 -c maxTablesPerVnode -v 4
|
system sh/cfg.sh -n dnode1 -c maxTablesPerVnode -v 4
|
||||||
system sh/cfg.sh -n dnode2 -c maxTablesPerVnode -v 4
|
system sh/cfg.sh -n dnode2 -c maxTablesPerVnode -v 4
|
||||||
system sh/cfg.sh -n dnode1 -c tableMetaKeepTimer -v 5
|
|
||||||
system sh/cfg.sh -n dnode2 -c tableMetaKeepTimer -v 5
|
|
||||||
system sh/cfg.sh -n dnode1 -c numOfMnodes -v 2
|
system sh/cfg.sh -n dnode1 -c numOfMnodes -v 2
|
||||||
system sh/cfg.sh -n dnode2 -c numOfMnodes -v 2
|
system sh/cfg.sh -n dnode2 -c numOfMnodes -v 2
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue