From f8203039efef9063151dfb2ade10a50ccb389e83 Mon Sep 17 00:00:00 2001 From: hzcheng Date: Fri, 21 Feb 2020 04:02:32 +0000 Subject: [PATCH 01/16] more --- src/vnode/common/inc/key.h | 10 +++++ src/vnode/common/inc/list.h | 20 +++++++++ src/vnode/common/inc/skiplist.c | 73 +++++++++++++++++++++++++++++++++ src/vnode/common/inc/skiplist.h | 38 +++++++++++++++++ 4 files changed, 141 insertions(+) create mode 100644 src/vnode/common/inc/key.h create mode 100644 src/vnode/common/inc/list.h create mode 100644 src/vnode/common/inc/skiplist.c create mode 100644 src/vnode/common/inc/skiplist.h diff --git a/src/vnode/common/inc/key.h b/src/vnode/common/inc/key.h new file mode 100644 index 0000000000..1f0478bda3 --- /dev/null +++ b/src/vnode/common/inc/key.h @@ -0,0 +1,10 @@ +#if !defined(_TD_KEY_H_) +#define _TD_KEY_H_ + +typedef struct { + +} key; + + + +#endif // _TD_KEY_H_ diff --git a/src/vnode/common/inc/list.h b/src/vnode/common/inc/list.h new file mode 100644 index 0000000000..489e39442b --- /dev/null +++ b/src/vnode/common/inc/list.h @@ -0,0 +1,20 @@ +#if !defined(_TD_LIST_H_) +#define _TD_LIST_H_ + +#include + +typedef enum { TD_LIST_ORDERED, TD_LIST_UNORDERED } TLIST_TYPE; + +typedef int32_t (* comparefn(void *key1, void *key2)); + +struct _list_type { + TLIST_TYPE type; +}; + +typedef struct _list_node { +} SListNode; + +typedef struct _list { +} SList; + +#endif // _TD_LIST_H_ diff --git a/src/vnode/common/inc/skiplist.c b/src/vnode/common/inc/skiplist.c new file mode 100644 index 0000000000..f2384bcbae --- /dev/null +++ b/src/vnode/common/inc/skiplist.c @@ -0,0 +1,73 @@ +#include + +#include "skiplist.h" + +#define IS_VALID_SKIPLIST_DUPLICATE_KEY_STRATEGY(strategy) \ + (((strategy) >= SKIPLIST_ALLOW_DUPLICATE_KEY) && ((strategy) <= SKIPLIST_DISCARD_DUPLICATE_KEY)) + +SSkipListNode *tdCreateSkiplistNode(int32_t nlevels) { + SSkipListNode *pNode = (SSkipListNode *)malloc(sizeof(SSkipListNode)); + if (pNode == NULL) return NULL; + + pNode->nexts = (struct _skiplist_node **)cmalloc(nlevels, sizeof(struct _skiplist_node *)); + if (pNode->nexts == NULL) { + free(pNode); + return NULL; + } + + pNode->prevs = (struct _skiplist_node **)cmalloc(nlevels, sizeof(struct _skiplist_node *)); + if (pNode->nexts == NULL) { + free(pNode->nexts); + free(pNode); + return NULL; + } + + return pNode; +} + +int32_t tdFreeSkiplistNode(SSkipListNode *pNode) { + if (pNode == NULL) return 0; + // TODO: free key and free value + + // Free the skip list + free(pNode->nexts); + free(pNode->prevs); + free(pNode); + return 0; +} + +SSkipList *tdCreateSkiplist(int16_t nMaxLevels, SKIPLIST_DUPLICATE_KEY_STATEGY strategy) { + // Check parameters + if (!IS_VALID_SKIPLIST_DUPLICATE_KEY_STRATEGY(strategy)) return NULL; + + SSkipList *pSkipList = (SSkipList *)malloc(sizeof(SSkipList)); + if (pSkipList == NULL) { + return NULL; + } + + pSkipList->strategy = strategy; + pSkipList->nMaxLevels = nMaxLevels; + + pSkipList->head = tdCreateSkiplistNode(nMaxLevels); + if (pSkipList->head == NULL) { + free(pSkipList); + return NULL; + } + + return pSkipList; +} + +int32_t tdFreeSkipList(SSkipList *pSkipList) { + if (pSkipList == NULL) return 0; + + SSkipListNode *pNode = pSkipList->head->nexts[0]; + while (pNode) { + SSkipListNode *pTemp = pNode->nexts[0]; + tdFreeSkiplistNode(pNode); + pNode = pTemp; + } + + free(pSkipList); + + return 0; +} \ No newline at end of file diff --git a/src/vnode/common/inc/skiplist.h b/src/vnode/common/inc/skiplist.h new file mode 100644 index 0000000000..5c395d289a --- /dev/null +++ b/src/vnode/common/inc/skiplist.h @@ -0,0 +1,38 @@ +#if !defined(_TD_SKIPLIST_H) +#define _TD_SKIPLIST_H + +#include + +typedef enum { + SKIPLIST_ALLOW_DUPLICATE_KEY, + SKIPLIST_REPLACE_DUPLICATE_KEY, + SKIPLIST_DISCARD_DUPLICATE_KEY +} SKIPLIST_DUPLICATE_KEY_STATEGY; + +typedef struct _skiplist_node { + void * key; + void * value; + struct _skiplist_node **nexts; + struct _skiplist_node **prevs; +} SSkipListNode; + +// To implement a general skip list +typedef struct _skiplist { + SKIPLIST_DUPLICATE_KEY_STATEGY strategy; + SSkipListNode * head; + SSkipListNode * tail; + int32_t nMaxLevels; + int32_t count; +} SSkipList; + +// -- Operations on SSkipListNode +SSkipListNode *tdCreateSkiplistNode(int32_t nlevels); +int32_t tdFreeSkiplistNode(SSkipListNode *pNode); + +// -- Operations on SSkipList +SSkipList *tdCreateSkiplist(int16_t nMaxLevels, SKIPLIST_DUPLICATE_KEY_STATEGY strategy); +int32_t tdFreeSkipList(SSkipList *pSkipList); +// int32_t tdAddItemToSkiplist(SSkipList *slist, void *key, void *value); +// int32_t tdAddNodeToSkiplist(SSkipList *slist, SSkipListNode *node); + +#endif // _TD_SKIPLIST_H From a6166565fb97e7241fd0a8f4643ef418d9e504b7 Mon Sep 17 00:00:00 2001 From: hzcheng Date: Mon, 2 Mar 2020 13:02:42 +0000 Subject: [PATCH 02/16] more --- src/vnode/tests/tsdb/tsdbTests.cpp | 2 +- src/vnode/tsdb/inc/tsdb.h | 34 +++++++---------- src/vnode/tsdb/inc/tsdbMeta.h | 4 +- src/vnode/tsdb/src/{tsdb.c => tsdbMain.c} | 46 +++++++++++------------ 4 files changed, 40 insertions(+), 46 deletions(-) rename src/vnode/tsdb/src/{tsdb.c => tsdbMain.c} (78%) diff --git a/src/vnode/tests/tsdb/tsdbTests.cpp b/src/vnode/tests/tsdb/tsdbTests.cpp index 580279e566..3d7f41df24 100644 --- a/src/vnode/tests/tsdb/tsdbTests.cpp +++ b/src/vnode/tests/tsdb/tsdbTests.cpp @@ -4,7 +4,7 @@ #include "tsdb.h" TEST(TsdbTest, createTsdbRepo) { - STSDBCfg *pCfg = (STSDBCfg *)malloc(sizeof(STSDBCfg)); + STsdbCfg *pCfg = (STsdbCfg *)malloc(sizeof(STsdbCfg)); free(pCfg); diff --git a/src/vnode/tsdb/inc/tsdb.h b/src/vnode/tsdb/inc/tsdb.h index b46f886b5d..57dbf6d180 100644 --- a/src/vnode/tsdb/inc/tsdb.h +++ b/src/vnode/tsdb/inc/tsdb.h @@ -8,17 +8,19 @@ #include #include -// #include "cache.h" #include "schema.h" #define TSDB_VERSION_MAJOR 1 #define TSDB_VERSION_MINOR 0 -typedef void tsdb_repo_t; // use void to hide implementation details from outside -typedef int32_t table_id_t; // table ID type in this repository -typedef int16_t tsdb_id_t; // TSDB repository ID +typedef void tsdb_repo_t; // use void to hide implementation details from outside -// Submit message +typedef struct { + int64_t uid; // the unique table ID + int32_t tableId; // the table ID in the repository. +} STableId; + +// Submit message for this TSDB typedef struct { int32_t numOfTables; int32_t compressed; @@ -27,10 +29,9 @@ typedef struct { // Submit message for one table typedef struct { - table_id_t tableId; // table ID to insert + STableId tid; int32_t sversion; // data schema version int32_t numOfRows; // number of rows data - int64_t uid; // table UID to insert char data[]; } SSubmitBlock; @@ -55,27 +56,20 @@ typedef struct { int32_t maxRowsPerFileBlock; } SBlockRowsPolicy; -// Applications trying to manipulate a table should provide both uid and tableId. -// tableId is used for table quick access and uid for verification. -typedef struct { - int64_t uid; // the unique table ID - table_id_t tableId; // the table ID in the repository. -} STableId; - // the TSDB repository configuration typedef struct { char * rootDir; // TSDB repository root directory, TODO: need to adjust here - tsdb_id_t tsdbId; + int32_t tsdbId; int32_t maxTables; // maximum number of tables this repository can have SDataShardPolicy dataShardPolicy; SBlockRowsPolicy blockRowsPolicy; SRetentionPolicy retentionPlicy; // retention configuration void * cachePool; // the cache pool the repository to use -} STSDBCfg; +} STsdbCfg; // the TSDB repository info typedef struct STSDBRepoInfo { - STSDBCfg tsdbCfg; + STsdbCfg tsdbCfg; int64_t version; // version of the repository int64_t tsdbTotalDataSize; // the original inserted data size int64_t tsdbTotalDiskSize; // the total disk size taken by this TSDB repository @@ -86,7 +80,7 @@ typedef struct STSDBRepoInfo { typedef struct { char * tableName; int64_t uid; // uid given by upper layer - table_id_t tableId; // table ID allocated from upper layer + int32_t tableId; // table ID allocated from upper layer char *stableName; // if not NULL, the table is created from a super table, need to make sure the super // table exists in this TSDB. @@ -115,7 +109,7 @@ typedef struct { * * @return a TSDB repository handle on success, NULL for failure and the error number is set */ -tsdb_repo_t *tsdbCreateRepo(STSDBCfg *pCfg); +tsdb_repo_t *tsdbCreateRepo(STsdbCfg *pCfg); /** * Close and free all resources taken by the repository @@ -149,7 +143,7 @@ int32_t tsdbCloseRepo(tsdb_repo_t *repo); * * @return 0 for success, -1 for failure and the error number is set */ -int32_t tsdbConfigRepo(tsdb_repo_t repo, STSDBCfg *pCfg); +int32_t tsdbConfigRepo(tsdb_repo_t repo, STsdbCfg *pCfg); /** * Get the TSDB repository information, including some statistics diff --git a/src/vnode/tsdb/inc/tsdbMeta.h b/src/vnode/tsdb/inc/tsdbMeta.h index 17d49ba38a..78d55e68ad 100644 --- a/src/vnode/tsdb/inc/tsdbMeta.h +++ b/src/vnode/tsdb/inc/tsdbMeta.h @@ -16,7 +16,7 @@ typedef enum { } TSDB_TABLE_TYPE; typedef struct STable { - tsdb_id_t tableId; + int32_t tableId; int64_t uid; char * tableName; TSDB_TABLE_TYPE type; @@ -24,7 +24,7 @@ typedef struct STable { int64_t createdTime; // super table UID - tsdb_id_t superTableId; + int32_t superTableId; // Schema for this table // For TSDB_SUPER_TABLE, it is the schema including tags diff --git a/src/vnode/tsdb/src/tsdb.c b/src/vnode/tsdb/src/tsdbMain.c similarity index 78% rename from src/vnode/tsdb/src/tsdb.c rename to src/vnode/tsdb/src/tsdbMain.c index dec46bea97..3ebef5498c 100644 --- a/src/vnode/tsdb/src/tsdb.c +++ b/src/vnode/tsdb/src/tsdbMain.c @@ -21,19 +21,19 @@ enum { typedef struct _tsdb_repo { // TSDB configuration - STSDBCfg *pCfg; + STsdbCfg *pCfg; // The meter meta handle of this TSDB repository - SMetaHandle *pMetaHandle; + SMetaHandle *tsdbMeta; // The cache Handle - SCacheHandle *pCacheHandle; + SCacheHandle *tsdbCache; // Disk tier handle for multi-tier storage - void *pDiskTier; + void *diskTier; // File Store - void *pFileStore; + void *tsdbFiles; pthread_mutex_t tsdbMutex; @@ -47,7 +47,7 @@ typedef struct _tsdb_repo { #define TSDB_IS_REPO_CLOSED(pRepo) ((pRepo)->state == TSDB_REPO_STATE_CLOSED) // Check the correctness of the TSDB configuration -static int32_t tsdbCheckCfg(STSDBCfg *pCfg) { +static int32_t tsdbCheckCfg(STsdbCfg *pCfg) { if (pCfg->rootDir == NULL) return -1; if (access(pCfg->rootDir, F_OK|R_OK|W_OK) == -1) { @@ -65,7 +65,7 @@ static int32_t tsdbClearFiles(STSDBRepo *pRepo) { // TODO } -tsdb_repo_t *tsdbCreateRepo(STSDBCfg *pCfg) { +tsdb_repo_t *tsdbCreateRepo(STsdbCfg *pCfg) { // Check the configuration if (tsdbCheckCfg(pCfg) < 0) { @@ -79,18 +79,18 @@ tsdb_repo_t *tsdbCreateRepo(STSDBCfg *pCfg) { } // TODO: Initailize pMetahandle - pRepo->pMetaHandle = tsdbCreateMetaHandle(pCfg->maxTables); - if (pRepo->pMetaHandle == NULL) { + pRepo->tsdbMeta = tsdbCreateMetaHandle(pCfg->maxTables); + if (pRepo->tsdbMeta == NULL) { // TODO: deal with error free(pRepo); return NULL; } // TODO: Initialize cache handle - pRepo->pCacheHandle = tsdbCreateCache(5); - if (pRepo->pCacheHandle == NULL) { + pRepo->tsdbCache = tsdbCreateCache(5); + if (pRepo->tsdbCache == NULL) { // TODO: free the object and return error - tsdbFreeMetaHandle(pRepo->pCacheHandle); + tsdbFreeMetaHandle(pRepo->tsdbCache); free(pRepo); return NULL; } @@ -101,7 +101,7 @@ tsdb_repo_t *tsdbCreateRepo(STSDBCfg *pCfg) { // Create the Meta data file and data directory if (tsdbCreateFiles(pRepo) < 0) { // Failed to create and save files - tsdbFreeMetaHandle(pRepo->pCacheHandle); + tsdbFreeMetaHandle(pRepo->tsdbCache); free(pRepo); return NULL; } @@ -117,10 +117,10 @@ int32_t tsdbDropRepo(tsdb_repo_t *repo) { pRepo->state = TSDB_REPO_STATE_CLOSED; // Free the metaHandle - tsdbFreeMetaHandle(pRepo->pMetaHandle); + tsdbFreeMetaHandle(pRepo->tsdbMeta); // Free the cache - tsdbFreeCache(pRepo->pCacheHandle); + tsdbFreeCache(pRepo->tsdbCache); tsdbClearFiles(pRepo); @@ -139,14 +139,14 @@ tsdb_repo_t *tsdbOpenRepo(char *tsdbDir) { } // TODO: Initialize configuration from the file - pRepo->pMetaHandle = tsdbOpenMetaHandle(); - if (pRepo->pMetaHandle == NULL) { + pRepo->tsdbMeta = tsdbOpenMetaHandle(); + if (pRepo->tsdbMeta == NULL) { free(pRepo); return NULL; } - pRepo->pCacheHandle = tsdbCreateCache(5); - if (pRepo->pCacheHandle == NULL) { + pRepo->tsdbCache = tsdbCreateCache(5); + if (pRepo->tsdbCache == NULL) { // TODO: deal with error return NULL; } @@ -167,14 +167,14 @@ int32_t tsdbCloseRepo(tsdb_repo_t *repo) { pRepo->state = TSDB_REPO_STATE_CLOSED; - tsdbFreeMetaHandle(pRepo->pMetaHandle); + tsdbFreeMetaHandle(pRepo->tsdbMeta); - tsdbFreeCache(pRepo->pMetaHandle); + tsdbFreeCache(pRepo->tsdbMeta); return 0; } -int32_t tsdbConfigRepo(tsdb_repo_t *repo, STSDBCfg *pCfg) { +int32_t tsdbConfigRepo(tsdb_repo_t *repo, STsdbCfg *pCfg) { STSDBRepo *pRepo = (STSDBRepo *)repo; pRepo->pCfg = pCfg; @@ -188,7 +188,7 @@ STSDBRepoInfo *tsdbGetStatus(tsdb_repo_t *pRepo) { int32_t tsdbCreateTable(tsdb_repo_t *repo, STableCfg *pCfg) { STSDBRepo *pRepo = (STSDBRepo *)repo; - return tsdbCreateTableImpl(pRepo->pMetaHandle, pCfg); + return tsdbCreateTableImpl(pRepo->tsdbMeta, pCfg); } int32_t tsdbAlterTable(tsdb_repo_t *pRepo, STableCfg *pCfg) { From 42fc4236844a75d37b819970d8d628cf0e66bb07 Mon Sep 17 00:00:00 2001 From: hzcheng Date: Mon, 2 Mar 2020 13:11:21 +0000 Subject: [PATCH 03/16] more --- src/vnode/tsdb/inc/tsdb.h | 44 +++++++++++++++++------------------ src/vnode/tsdb/src/tsdbMain.c | 20 ++++++++-------- 2 files changed, 31 insertions(+), 33 deletions(-) diff --git a/src/vnode/tsdb/inc/tsdb.h b/src/vnode/tsdb/inc/tsdb.h index 57dbf6d180..198618978e 100644 --- a/src/vnode/tsdb/inc/tsdb.h +++ b/src/vnode/tsdb/inc/tsdb.h @@ -16,8 +16,8 @@ typedef void tsdb_repo_t; // use void to hide implementation details from outside typedef struct { - int64_t uid; // the unique table ID - int32_t tableId; // the table ID in the repository. + int64_t uid; // the unique table ID + int32_t tid; // the table ID in the repository. } STableId; // Submit message for this TSDB @@ -29,10 +29,10 @@ typedef struct { // Submit message for one table typedef struct { - STableId tid; - int32_t sversion; // data schema version - int32_t numOfRows; // number of rows data - char data[]; + STableId tid; + int32_t sversion; // data schema version + int32_t numOfRows; // number of rows data + char data[]; } SSubmitBlock; // Retention policy. @@ -52,19 +52,18 @@ typedef struct { // Rows in file block policy typedef struct { // TODO: Need a more fancy description - int32_t minRowsPerFileBlock; - int32_t maxRowsPerFileBlock; } SBlockRowsPolicy; // the TSDB repository configuration typedef struct { - char * rootDir; // TSDB repository root directory, TODO: need to adjust here - int32_t tsdbId; - int32_t maxTables; // maximum number of tables this repository can have - SDataShardPolicy dataShardPolicy; - SBlockRowsPolicy blockRowsPolicy; - SRetentionPolicy retentionPlicy; // retention configuration - void * cachePool; // the cache pool the repository to use + char * rootDir; // TSDB repository root directory, TODO: need to adjust here + int32_t tsdbId; + int32_t maxTables; // maximum number of tables this repository can have + int32_t daysPerFile; // day per file sharding policy + int32_t minRowsPerFileBlock; // minimum rows per file block + int32_t maxRowsPerFileBlock; // maximum rows per file block + int32_t keep; // Day of data to keep + void * cachePool; // the cache pool the repository to use } STsdbCfg; // the TSDB repository info @@ -78,9 +77,8 @@ typedef struct STSDBRepoInfo { // the meter configuration typedef struct { - char * tableName; - int64_t uid; // uid given by upper layer - int32_t tableId; // table ID allocated from upper layer + char * tableName; + STableId tableId; char *stableName; // if not NULL, the table is created from a super table, need to make sure the super // table exists in this TSDB. @@ -99,8 +97,8 @@ typedef struct { typedef struct { STableCfg tableCfg; int64_t version; - int64_t tableTotalDataSize; // In bytes - int64_t tableTotalDiskSize; // In bytes + int64_t tableTotalDataSize; // In bytes + int64_t tableTotalDiskSize; // In bytes } STableInfo; /** @@ -201,7 +199,7 @@ int32_t tsdbInsertData(tsdb_repo_t *pRepo, STableId tid, char *pData, int32_t *e // -- FOR QUERY TIME SERIES DATA -typedef void tsdb_query_handle_t; // Use void to hide implementation details +typedef void tsdb_query_handle_t; // Use void to hide implementation details // time window typedef struct STimeWindow { @@ -245,7 +243,6 @@ typedef struct STableIDList { } STableIDList; typedef struct { - } SFields; /** @@ -269,7 +266,8 @@ tsdb_query_handle_t *tsdbQueryFromTableID(tsdb_repo_t *pRepo, STSDBQueryCond *pC * @param pTagFilterStr tag filter info * @return */ -tsdb_query_handle_t *tsdbQueryFromTagConds(tsdb_repo_t *pRepo, STSDBQueryCond *pCond, int16_t stableId, const char *pTagFilterStr); +tsdb_query_handle_t *tsdbQueryFromTagConds(tsdb_repo_t *pRepo, STSDBQueryCond *pCond, int16_t stableId, + const char *pTagFilterStr); /** * Reset to the start(end) position of current query, from which the iterator starts. diff --git a/src/vnode/tsdb/src/tsdbMain.c b/src/vnode/tsdb/src/tsdbMain.c index 3ebef5498c..0cc77c7b99 100644 --- a/src/vnode/tsdb/src/tsdbMain.c +++ b/src/vnode/tsdb/src/tsdbMain.c @@ -39,7 +39,7 @@ typedef struct _tsdb_repo { int8_t state; -} STSDBRepo; +} STsdbRepo; #define TSDB_GET_TABLE_BY_ID(pRepo, sid) (((STSDBRepo *)pRepo)->pTableList)[sid] #define TSDB_GET_TABLE_BY_NAME(pRepo, name) @@ -57,11 +57,11 @@ static int32_t tsdbCheckCfg(STsdbCfg *pCfg) { return 0; } -static int32_t tsdbCreateFiles(STSDBRepo *pRepo) { +static int32_t tsdbCreateFiles(STsdbRepo *pRepo) { // TODO } -static int32_t tsdbClearFiles(STSDBRepo *pRepo) { +static int32_t tsdbClearFiles(STsdbRepo *pRepo) { // TODO } @@ -72,7 +72,7 @@ tsdb_repo_t *tsdbCreateRepo(STsdbCfg *pCfg) { return NULL; } - STSDBRepo *pRepo = (STSDBRepo *)malloc(sizeof(STSDBRepo)); + STsdbRepo *pRepo = (STsdbRepo *)malloc(sizeof(STsdbRepo)); if (pRepo == NULL) { // TODO: deal with error return NULL; @@ -112,7 +112,7 @@ tsdb_repo_t *tsdbCreateRepo(STsdbCfg *pCfg) { } int32_t tsdbDropRepo(tsdb_repo_t *repo) { - STSDBRepo *pRepo = (STSDBRepo *)repo; + STsdbRepo *pRepo = (STsdbRepo *)repo; pRepo->state = TSDB_REPO_STATE_CLOSED; @@ -133,7 +133,7 @@ tsdb_repo_t *tsdbOpenRepo(char *tsdbDir) { return NULL; } - STSDBRepo *pRepo = (STSDBRepo *)malloc(sizeof(STSDBRepo)); + STsdbRepo *pRepo = (STsdbRepo *)malloc(sizeof(STsdbRepo)); if (pRepo == NULL) { return NULL; } @@ -156,12 +156,12 @@ tsdb_repo_t *tsdbOpenRepo(char *tsdbDir) { return (tsdb_repo_t *)pRepo; } -static int32_t tsdbFlushCache(STSDBRepo *pRepo) { +static int32_t tsdbFlushCache(STsdbRepo *pRepo) { // TODO } int32_t tsdbCloseRepo(tsdb_repo_t *repo) { - STSDBRepo *pRepo = (STSDBRepo *)repo; + STsdbRepo *pRepo = (STsdbRepo *)repo; tsdbFlushCache(pRepo); @@ -175,7 +175,7 @@ int32_t tsdbCloseRepo(tsdb_repo_t *repo) { } int32_t tsdbConfigRepo(tsdb_repo_t *repo, STsdbCfg *pCfg) { - STSDBRepo *pRepo = (STSDBRepo *)repo; + STsdbRepo *pRepo = (STsdbRepo *)repo; pRepo->pCfg = pCfg; // TODO @@ -187,7 +187,7 @@ STSDBRepoInfo *tsdbGetStatus(tsdb_repo_t *pRepo) { } int32_t tsdbCreateTable(tsdb_repo_t *repo, STableCfg *pCfg) { - STSDBRepo *pRepo = (STSDBRepo *)repo; + STsdbRepo *pRepo = (STsdbRepo *)repo; return tsdbCreateTableImpl(pRepo->tsdbMeta, pCfg); } From 9f0c01510e09b5c4bbdde3a83dbce31ee5d7a78c Mon Sep 17 00:00:00 2001 From: hzcheng Date: Mon, 2 Mar 2020 13:16:15 +0000 Subject: [PATCH 04/16] more --- src/vnode/tsdb/inc/tsdb.h | 22 ++------------------- src/vnode/tsdb/src/tsdbMain.c | 37 ++++++++++++++++++----------------- 2 files changed, 21 insertions(+), 38 deletions(-) diff --git a/src/vnode/tsdb/inc/tsdb.h b/src/vnode/tsdb/inc/tsdb.h index 198618978e..8478becaf2 100644 --- a/src/vnode/tsdb/inc/tsdb.h +++ b/src/vnode/tsdb/inc/tsdb.h @@ -35,25 +35,6 @@ typedef struct { char data[]; } SSubmitBlock; -// Retention policy. -typedef struct { - // TODO: Need a more fancy description - int32_t keep1; - int32_t keep2; - int32_t keep3; -} SRetentionPolicy; - -// Data sharding policy. -typedef struct { - // TODO: Need a more fancy description - int32_t daysPerFile; -} SDataShardPolicy; - -// Rows in file block policy -typedef struct { - // TODO: Need a more fancy description -} SBlockRowsPolicy; - // the TSDB repository configuration typedef struct { char * rootDir; // TSDB repository root directory, TODO: need to adjust here @@ -62,7 +43,8 @@ typedef struct { int32_t daysPerFile; // day per file sharding policy int32_t minRowsPerFileBlock; // minimum rows per file block int32_t maxRowsPerFileBlock; // maximum rows per file block - int32_t keep; // Day of data to keep + int32_t keep; // day of data to keep + int64_t maxCacheSize; // maximum cache size this TSDB can use void * cachePool; // the cache pool the repository to use } STsdbCfg; diff --git a/src/vnode/tsdb/src/tsdbMain.c b/src/vnode/tsdb/src/tsdbMain.c index 0cc77c7b99..826592bce6 100644 --- a/src/vnode/tsdb/src/tsdbMain.c +++ b/src/vnode/tsdb/src/tsdbMain.c @@ -46,24 +46,6 @@ typedef struct _tsdb_repo { #define TSDB_IS_REPO_ACTIVE(pRepo) ((pRepo)->state == TSDB_REPO_STATE_ACTIVE) #define TSDB_IS_REPO_CLOSED(pRepo) ((pRepo)->state == TSDB_REPO_STATE_CLOSED) -// Check the correctness of the TSDB configuration -static int32_t tsdbCheckCfg(STsdbCfg *pCfg) { - if (pCfg->rootDir == NULL) return -1; - - if (access(pCfg->rootDir, F_OK|R_OK|W_OK) == -1) { - return -1; - } - // TODO - return 0; -} - -static int32_t tsdbCreateFiles(STsdbRepo *pRepo) { - // TODO -} - -static int32_t tsdbClearFiles(STsdbRepo *pRepo) { - // TODO -} tsdb_repo_t *tsdbCreateRepo(STsdbCfg *pCfg) { @@ -201,4 +183,23 @@ STableInfo *tsdbGetTableInfo(tsdb_repo_t *pRepo, STableId tid, int32_t *error) { int32_t tsdbInsertData(tsdb_repo_t *pRepo, STableId tid, char *pData, int32_t *error) { // TODO +} + +// Check the correctness of the TSDB configuration +static int32_t tsdbCheckCfg(STsdbCfg *pCfg) { + if (pCfg->rootDir == NULL) return -1; + + if (access(pCfg->rootDir, F_OK|R_OK|W_OK) == -1) { + return -1; + } + // TODO + return 0; +} + +static int32_t tsdbCreateFiles(STsdbRepo *pRepo) { + // TODO +} + +static int32_t tsdbClearFiles(STsdbRepo *pRepo) { + // TODO } \ No newline at end of file From a4ee9d7c9c87d9d667b648ad818f51596d133345 Mon Sep 17 00:00:00 2001 From: hzcheng Date: Mon, 2 Mar 2020 13:37:03 +0000 Subject: [PATCH 05/16] refactor --- src/vnode/tsdb/inc/tsdb.h | 4 +-- src/vnode/tsdb/inc/tsdbMeta.h | 4 +-- src/vnode/tsdb/src/tsdbMain.c | 60 ++++++++++++++++------------------- src/vnode/tsdb/src/tsdbMeta.c | 32 +++++++++---------- 4 files changed, 47 insertions(+), 53 deletions(-) diff --git a/src/vnode/tsdb/inc/tsdb.h b/src/vnode/tsdb/inc/tsdb.h index 8478becaf2..f225fde093 100644 --- a/src/vnode/tsdb/inc/tsdb.h +++ b/src/vnode/tsdb/inc/tsdb.h @@ -37,7 +37,6 @@ typedef struct { // the TSDB repository configuration typedef struct { - char * rootDir; // TSDB repository root directory, TODO: need to adjust here int32_t tsdbId; int32_t maxTables; // maximum number of tables this repository can have int32_t daysPerFile; // day per file sharding policy @@ -45,7 +44,6 @@ typedef struct { int32_t maxRowsPerFileBlock; // maximum rows per file block int32_t keep; // day of data to keep int64_t maxCacheSize; // maximum cache size this TSDB can use - void * cachePool; // the cache pool the repository to use } STsdbCfg; // the TSDB repository info @@ -89,7 +87,7 @@ typedef struct { * * @return a TSDB repository handle on success, NULL for failure and the error number is set */ -tsdb_repo_t *tsdbCreateRepo(STsdbCfg *pCfg); +tsdb_repo_t *tsdbCreateRepo(char *rootDir, STsdbCfg *pCfg, void *limiter); /** * Close and free all resources taken by the repository diff --git a/src/vnode/tsdb/inc/tsdbMeta.h b/src/vnode/tsdb/inc/tsdbMeta.h index 78d55e68ad..81c3594952 100644 --- a/src/vnode/tsdb/inc/tsdbMeta.h +++ b/src/vnode/tsdb/inc/tsdbMeta.h @@ -62,7 +62,7 @@ typedef struct { // A map of tableName->tableId // TODO: May use hash table void *pNameTableMap; -} SMetaHandle; +} STsdbMeta; // ---- Operation on STable #define TSDB_TABLE_ID(pTable) ((pTable)->tableId) @@ -84,7 +84,7 @@ SSchema *tsdbGetTableSchema(STable *pTable); #define TSDB_GET_TABLE_OF_NAME(pHandle, name) /* TODO */ // Create a new meta handle with configuration -SMetaHandle * tsdbCreateMetaHandle (int32_t numOfTables); +SMetaHandle * tsdbCreateMeta (int32_t numOfTables); int32_t tsdbFreeMetaHandle(SMetaHandle *pMetaHandle); // Recover the meta handle from the file diff --git a/src/vnode/tsdb/src/tsdbMain.c b/src/vnode/tsdb/src/tsdbMain.c index 826592bce6..72761e834b 100644 --- a/src/vnode/tsdb/src/tsdbMain.c +++ b/src/vnode/tsdb/src/tsdbMain.c @@ -1,27 +1,23 @@ +#include #include #include #include -#include -#include #include -#include +#include +#include // #include "taosdef.h" // #include "disk.h" -#include "tsdbFile.h" #include "tsdb.h" #include "tsdbCache.h" +#include "tsdbFile.h" #include "tsdbMeta.h" -enum { - TSDB_REPO_STATE_ACTIVE, - TSDB_REPO_STATE_CLOSED, - TSDB_REPO_STATE_CONFIGURING -}; +enum { TSDB_REPO_STATE_ACTIVE, TSDB_REPO_STATE_CLOSED, TSDB_REPO_STATE_CONFIGURING }; typedef struct _tsdb_repo { // TSDB configuration - STsdbCfg *pCfg; + STsdbCfg config; // The meter meta handle of this TSDB repository SMetaHandle *tsdbMeta; @@ -37,31 +33,40 @@ typedef struct _tsdb_repo { pthread_mutex_t tsdbMutex; + // A limiter to monitor the resources used by tsdb + void *limiter; + int8_t state; } STsdbRepo; +static int32_t tsdbCheckAndSetDefaultCfg(STsdbCfg *pCfg); +static int32_t tsdbCreateRepoFiles(STsdbRepo *pRepo); + #define TSDB_GET_TABLE_BY_ID(pRepo, sid) (((STSDBRepo *)pRepo)->pTableList)[sid] #define TSDB_GET_TABLE_BY_NAME(pRepo, name) #define TSDB_IS_REPO_ACTIVE(pRepo) ((pRepo)->state == TSDB_REPO_STATE_ACTIVE) #define TSDB_IS_REPO_CLOSED(pRepo) ((pRepo)->state == TSDB_REPO_STATE_CLOSED) +tsdb_repo_t *tsdbCreateRepo(char *rootDir, STsdbCfg *pCfg, void *limiter) { -tsdb_repo_t *tsdbCreateRepo(STsdbCfg *pCfg) { + if (rootDir == NULL) return NULL; - // Check the configuration - if (tsdbCheckCfg(pCfg) < 0) { + if (access(rootDir, F_OK|R_OK|W_OK) == -1) return NULL; + + if (tsdbCheckAndSetDefaultCfg(pCfg) < 0) { return NULL; } STsdbRepo *pRepo = (STsdbRepo *)malloc(sizeof(STsdbRepo)); if (pRepo == NULL) { - // TODO: deal with error return NULL; } - // TODO: Initailize pMetahandle - pRepo->tsdbMeta = tsdbCreateMetaHandle(pCfg->maxTables); + pRepo->config = *pCfg; + pRepo->limiter = limiter; + + pRepo->tsdbMeta = tsdbCreateMeta(pCfg->maxTables); if (pRepo->tsdbMeta == NULL) { // TODO: deal with error free(pRepo); @@ -77,17 +82,14 @@ tsdb_repo_t *tsdbCreateRepo(STsdbCfg *pCfg) { return NULL; } - // Set configuration - pRepo->pCfg = pCfg; - // Create the Meta data file and data directory - if (tsdbCreateFiles(pRepo) < 0) { + if (tsdbCreateRepoFiles(pRepo) < 0) { // Failed to create and save files tsdbFreeMetaHandle(pRepo->tsdbCache); free(pRepo); return NULL; } - + pRepo->state = TSDB_REPO_STATE_ACTIVE; return (tsdb_repo_t *)pRepo; @@ -110,8 +112,7 @@ int32_t tsdbDropRepo(tsdb_repo_t *repo) { } tsdb_repo_t *tsdbOpenRepo(char *tsdbDir) { - - if (access(tsdbDir, F_OK|W_OK|R_OK) < 0) { + if (access(tsdbDir, F_OK | W_OK | R_OK) < 0) { return NULL; } @@ -159,7 +160,7 @@ int32_t tsdbCloseRepo(tsdb_repo_t *repo) { int32_t tsdbConfigRepo(tsdb_repo_t *repo, STsdbCfg *pCfg) { STsdbRepo *pRepo = (STsdbRepo *)repo; - pRepo->pCfg = pCfg; + pRepo->config = pCfg; // TODO return 0; } @@ -185,18 +186,13 @@ int32_t tsdbInsertData(tsdb_repo_t *pRepo, STableId tid, char *pData, int32_t *e // TODO } -// Check the correctness of the TSDB configuration -static int32_t tsdbCheckCfg(STsdbCfg *pCfg) { - if (pCfg->rootDir == NULL) return -1; - - if (access(pCfg->rootDir, F_OK|R_OK|W_OK) == -1) { - return -1; - } +// Check the configuration and set default options +static int32_t tsdbCheckAndSetDefaultCfg(STsdbCfg *pCfg) { // TODO return 0; } -static int32_t tsdbCreateFiles(STsdbRepo *pRepo) { +static int32_t tsdbCreateRepoFiles(STsdbRepo *pRepo) { // TODO } diff --git a/src/vnode/tsdb/src/tsdbMeta.c b/src/vnode/tsdb/src/tsdbMeta.c index a302498a24..f0abc2cd3c 100644 --- a/src/vnode/tsdb/src/tsdbMeta.c +++ b/src/vnode/tsdb/src/tsdbMeta.c @@ -4,39 +4,39 @@ #include "tsdb.h" #include "tsdbMeta.h" -SMetaHandle *tsdbCreateMetaHandle(int32_t numOfTables) { - SMetaHandle *pMetahandle = (SMetaHandle *)malloc(sizeof(SMetaHandle)); - if (pMetahandle == NULL) { +STsdbMeta *tsdbCreateMeta(int32_t maxNumOfTables) { + STsdbMeta *pMeta = (STsdbMeta *)malloc(sizeof(STsdbMeta)); + if (pMeta == NULL) { return NULL; } - pMetahandle->numOfTables = 0; - pMetahandle->numOfSuperTables = 0; - pMetahandle->pTables = calloc(sizeof(STable *), numOfTables); - if (pMetahandle->pTables == NULL) { - free(pMetahandle); + pMeta->numOfTables = 0; + pMeta->numOfSuperTables = 0; + pMeta->pTables = calloc(sizeof(STable *), numOfTables); + if (pMeta->pTables == NULL) { + free(pMeta); return NULL; } // TODO : initialize the map // pMetahandle->pNameTableMap = ; - if (pMetahandle->pNameTableMap == NULL) { - free(pMetahandle->pTables); - free(pMetahandle); + if (pMeta->pNameTableMap == NULL) { + free(pMeta->pTables); + free(pMeta); return NULL; } - return pMetahandle; + return pMeta; } -int32_t tsdbFreeMetaHandle(SMetaHandle *pMetaHandle) { +int32_t tsdbFreeMetaHandle(STsdbMeta *pMetaHandle) { // TODO } static int32_t tsdbCheckTableCfg(STableCfg *pCfg) { return 0; } -int32_t tsdbCreateTableImpl(SMetaHandle *pHandle, STableCfg *pCfg) { +int32_t tsdbCreateTableImpl(STsdbMeta *pHandle, STableCfg *pCfg) { if (tsdbCheckTableCfg(pCfg) < 0) { return -1; } @@ -53,10 +53,10 @@ int32_t tsdbCreateTableImpl(SMetaHandle *pHandle, STableCfg *pCfg) { return 0; } -SMetaHandle * tsdbOpenMetaHandle(char *tsdbDir) { +STsdbMeta * tsdbOpenMetaHandle(char *tsdbDir) { // Open meta file for reading - SMetaHandle *pHandle = (SMetaHandle *)malloc(sizeof(SMetaHandle)); + STsdbMeta *pHandle = (STsdbMeta *)malloc(sizeof(STsdbMeta)); if (pHandle == NULL) { return NULL; } From b2e189178d858e6af7e0ff37e54b2e70acca0286 Mon Sep 17 00:00:00 2001 From: hzcheng Date: Mon, 2 Mar 2020 15:09:33 +0000 Subject: [PATCH 06/16] more --- src/vnode/tsdb/inc/tsdb.h | 2 +- src/vnode/tsdb/inc/tsdbMeta.h | 8 +-- src/vnode/tsdb/src/tsdbMain.c | 99 ++++++++++++++++++++++++++++------- src/vnode/tsdb/src/tsdbMeta.c | 10 ++-- 4 files changed, 89 insertions(+), 30 deletions(-) diff --git a/src/vnode/tsdb/inc/tsdb.h b/src/vnode/tsdb/inc/tsdb.h index f225fde093..cc5d8ee5b6 100644 --- a/src/vnode/tsdb/inc/tsdb.h +++ b/src/vnode/tsdb/inc/tsdb.h @@ -121,7 +121,7 @@ int32_t tsdbCloseRepo(tsdb_repo_t *repo); * * @return 0 for success, -1 for failure and the error number is set */ -int32_t tsdbConfigRepo(tsdb_repo_t repo, STsdbCfg *pCfg); +int32_t tsdbConfigRepo(tsdb_repo_t *repo, STsdbCfg *pCfg); /** * Get the TSDB repository information, including some statistics diff --git a/src/vnode/tsdb/inc/tsdbMeta.h b/src/vnode/tsdb/inc/tsdbMeta.h index 81c3594952..30ac543391 100644 --- a/src/vnode/tsdb/inc/tsdbMeta.h +++ b/src/vnode/tsdb/inc/tsdbMeta.h @@ -84,10 +84,10 @@ SSchema *tsdbGetTableSchema(STable *pTable); #define TSDB_GET_TABLE_OF_NAME(pHandle, name) /* TODO */ // Create a new meta handle with configuration -SMetaHandle * tsdbCreateMeta (int32_t numOfTables); -int32_t tsdbFreeMetaHandle(SMetaHandle *pMetaHandle); +STsdbMeta * tsdbCreateMeta (int32_t maxTables); +int32_t tsdbFreeMeta(STsdbMeta *pMeta); // Recover the meta handle from the file -SMetaHandle * tsdbOpenMetaHandle(char *tsdbDir); +STsdbMeta * tsdbOpenMetaHandle(char *tsdbDir); -int32_t tsdbCreateTableImpl(SMetaHandle *pHandle, STableCfg *pCfg); +int32_t tsdbCreateTableImpl(STsdbMeta *pHandle, STableCfg *pCfg); diff --git a/src/vnode/tsdb/src/tsdbMain.c b/src/vnode/tsdb/src/tsdbMain.c index 72761e834b..1875471464 100644 --- a/src/vnode/tsdb/src/tsdbMain.c +++ b/src/vnode/tsdb/src/tsdbMain.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -5,6 +6,8 @@ #include #include #include +#include +#include // #include "taosdef.h" // #include "disk.h" @@ -16,11 +19,12 @@ enum { TSDB_REPO_STATE_ACTIVE, TSDB_REPO_STATE_CLOSED, TSDB_REPO_STATE_CONFIGURING }; typedef struct _tsdb_repo { + char *rootDir; // TSDB configuration STsdbCfg config; // The meter meta handle of this TSDB repository - SMetaHandle *tsdbMeta; + STsdbMeta *tsdbMeta; // The cache Handle SCacheHandle *tsdbCache; @@ -41,7 +45,8 @@ typedef struct _tsdb_repo { } STsdbRepo; static int32_t tsdbCheckAndSetDefaultCfg(STsdbCfg *pCfg); -static int32_t tsdbCreateRepoFiles(STsdbRepo *pRepo); +static int32_t tsdbSetRepoEnv(STsdbRepo *pRepo); +static int32_t tsdbDestroyRepoEnv(STsdbRepo *pRepo); #define TSDB_GET_TABLE_BY_ID(pRepo, sid) (((STSDBRepo *)pRepo)->pTableList)[sid] #define TSDB_GET_TABLE_BY_NAME(pRepo, name) @@ -63,29 +68,30 @@ tsdb_repo_t *tsdbCreateRepo(char *rootDir, STsdbCfg *pCfg, void *limiter) { return NULL; } + pRepo->rootDir = strdup(rootDir); pRepo->config = *pCfg; pRepo->limiter = limiter; pRepo->tsdbMeta = tsdbCreateMeta(pCfg->maxTables); if (pRepo->tsdbMeta == NULL) { - // TODO: deal with error + free(pRepo->rootDir); free(pRepo); return NULL; } - // TODO: Initialize cache handle pRepo->tsdbCache = tsdbCreateCache(5); if (pRepo->tsdbCache == NULL) { - // TODO: free the object and return error - tsdbFreeMetaHandle(pRepo->tsdbCache); + free(pRepo->rootDir); + tsdbFreeMeta(pRepo->tsdbMeta); free(pRepo); return NULL; } // Create the Meta data file and data directory - if (tsdbCreateRepoFiles(pRepo) < 0) { - // Failed to create and save files - tsdbFreeMetaHandle(pRepo->tsdbCache); + if (tsdbSetRepoEnv(pRepo) < 0) { + free(pRepo->rootDir); + tsdbFreeMeta(pRepo->tsdbMeta); + tsdbFreeCache(pRepo->tsdbCache); free(pRepo); return NULL; } @@ -101,12 +107,16 @@ int32_t tsdbDropRepo(tsdb_repo_t *repo) { pRepo->state = TSDB_REPO_STATE_CLOSED; // Free the metaHandle - tsdbFreeMetaHandle(pRepo->tsdbMeta); + tsdbFreeMeta(pRepo->tsdbMeta); // Free the cache tsdbFreeCache(pRepo->tsdbCache); - tsdbClearFiles(pRepo); + // Destroy the repository info + tsdbDestroyRepoEnv(pRepo); + + free(pRepo->rootDir); + free(pRepo); return 0; } @@ -122,7 +132,7 @@ tsdb_repo_t *tsdbOpenRepo(char *tsdbDir) { } // TODO: Initialize configuration from the file - pRepo->tsdbMeta = tsdbOpenMetaHandle(); + pRepo->tsdbMeta = tsdbCreateMeta(pRepo->config.maxTables); if (pRepo->tsdbMeta == NULL) { free(pRepo); return NULL; @@ -150,9 +160,9 @@ int32_t tsdbCloseRepo(tsdb_repo_t *repo) { pRepo->state = TSDB_REPO_STATE_CLOSED; - tsdbFreeMetaHandle(pRepo->tsdbMeta); + tsdbFreeMeta(pRepo->tsdbMeta); - tsdbFreeCache(pRepo->tsdbMeta); + tsdbFreeCache(pRepo->tsdbCache); return 0; } @@ -160,7 +170,7 @@ int32_t tsdbCloseRepo(tsdb_repo_t *repo) { int32_t tsdbConfigRepo(tsdb_repo_t *repo, STsdbCfg *pCfg) { STsdbRepo *pRepo = (STsdbRepo *)repo; - pRepo->config = pCfg; + pRepo->config = *pCfg; // TODO return 0; } @@ -192,10 +202,61 @@ static int32_t tsdbCheckAndSetDefaultCfg(STsdbCfg *pCfg) { return 0; } -static int32_t tsdbCreateRepoFiles(STsdbRepo *pRepo) { - // TODO +static int32_t tsdbSetRepoEnv(STsdbRepo *pRepo) { + char *metaFname = tsdbGetFileName(pRepo->rootDir, "tsdb", TSDB_FILE_TYPE_META); + + int fd = open(metaFname, O_WRONLY|O_CREAT); + if (fd < 0) { + return -1; + } + + if (write(fd, (void *)(&(pRepo->config)), sizeof(STsdbCfg)) < 0) { + return -1; + } + + // Create the data file + char *dirName = calloc(1, strlen(pRepo->rootDir) + strlen("tsdb") + 2); + if (dirName == NULL) { + return -1; + } + + sprintf(dirName, "%s/%s", pRepo->rootDir, dirName); + if (mkdir(dirName, 0755) < 0) { + free(dirName); + return -1; + } + + free(dirName); + + return 0; } -static int32_t tsdbClearFiles(STsdbRepo *pRepo) { - // TODO +static int32_t tsdbDestroyRepoEnv(STsdbRepo *pRepo) { + char fname[128]; + if (pRepo == NULL) return 0; + char *dirName = calloc(1, strlen(pRepo->rootDir) + strlen("tsdb") + 2); + if (dirName == NULL) { + return -1; + } + + sprintf(dirName, "%s/%s", pRepo->rootDir, "tsdb"); + + DIR *dir = opendir(dirName); + if (dir == NULL) return -1; + + struct dirent *dp; + while ((dp = readdir(dir)) != NULL) { + if ((strcmp(dp->d_name, ".") == 0) || (strcmp(dp->d_name, "..") == 0)) continue; + sprintf(fname, "%s/%s", pRepo->rootDir, dp->d_name); + remove(fname); + } + + closedir(dir); + + rmdir(dirName); + + char *metaFname = tsdbGetFileName(pRepo->rootDir, "tsdb", TSDB_FILE_TYPE_META); + remove(metaFname); + + return 0; } \ No newline at end of file diff --git a/src/vnode/tsdb/src/tsdbMeta.c b/src/vnode/tsdb/src/tsdbMeta.c index f0abc2cd3c..6752c6e4c5 100644 --- a/src/vnode/tsdb/src/tsdbMeta.c +++ b/src/vnode/tsdb/src/tsdbMeta.c @@ -4,7 +4,7 @@ #include "tsdb.h" #include "tsdbMeta.h" -STsdbMeta *tsdbCreateMeta(int32_t maxNumOfTables) { +STsdbMeta *tsdbCreateMeta(int32_t maxTables) { STsdbMeta *pMeta = (STsdbMeta *)malloc(sizeof(STsdbMeta)); if (pMeta == NULL) { return NULL; @@ -12,7 +12,7 @@ STsdbMeta *tsdbCreateMeta(int32_t maxNumOfTables) { pMeta->numOfTables = 0; pMeta->numOfSuperTables = 0; - pMeta->pTables = calloc(sizeof(STable *), numOfTables); + pMeta->pTables = calloc(sizeof(STable *), maxTables); if (pMeta->pTables == NULL) { free(pMeta); return NULL; @@ -29,9 +29,7 @@ STsdbMeta *tsdbCreateMeta(int32_t maxNumOfTables) { return pMeta; } -int32_t tsdbFreeMetaHandle(STsdbMeta *pMetaHandle) { - // TODO - +int32_t tsdbFreeMeta(STsdbMeta *pMeta) { } static int32_t tsdbCheckTableCfg(STableCfg *pCfg) { return 0; } @@ -47,7 +45,7 @@ int32_t tsdbCreateTableImpl(STsdbMeta *pHandle, STableCfg *pCfg) { return -1; } - pHandle->pTables[pCfg->tableId] = pTable; + pHandle->pTables[pCfg->tableId.tid] = pTable; // TODO: add name to it return 0; From 3b940a6beafa5360578df15a25cc290918eb7e0d Mon Sep 17 00:00:00 2001 From: hzcheng Date: Tue, 3 Mar 2020 02:29:14 +0000 Subject: [PATCH 07/16] more --- src/vnode/tsdb/inc/tsdb.h | 11 ++++--- src/vnode/tsdb/inc/tsdbMeta.h | 23 +++++++------- src/vnode/tsdb/src/tsdbMain.c | 2 +- src/vnode/tsdb/src/tsdbMeta.c | 59 +++++++++++++++++++++++++++-------- 4 files changed, 64 insertions(+), 31 deletions(-) diff --git a/src/vnode/tsdb/inc/tsdb.h b/src/vnode/tsdb/inc/tsdb.h index cc5d8ee5b6..4065533a1f 100644 --- a/src/vnode/tsdb/inc/tsdb.h +++ b/src/vnode/tsdb/inc/tsdb.h @@ -29,7 +29,7 @@ typedef struct { // Submit message for one table typedef struct { - STableId tid; + STableId tableId; int32_t sversion; // data schema version int32_t numOfRows; // number of rows data char data[]; @@ -47,20 +47,20 @@ typedef struct { } STsdbCfg; // the TSDB repository info -typedef struct STSDBRepoInfo { +typedef struct STsdbRepoInfo { STsdbCfg tsdbCfg; int64_t version; // version of the repository int64_t tsdbTotalDataSize; // the original inserted data size int64_t tsdbTotalDiskSize; // the total disk size taken by this TSDB repository // TODO: Other informations to add -} STSDBRepoInfo; +} STsdbRepoInfo; // the meter configuration typedef struct { char * tableName; STableId tableId; - char *stableName; // if not NULL, the table is created from a super table, need to make sure the super + char *superTable; // if not NULL, the table is created from a super table, need to make sure the super // table exists in this TSDB. int64_t stableUid; @@ -83,6 +83,7 @@ typedef struct { /** * Create a new TSDB repository + * @param rootDir the TSDB repository root directory * @param pCfg the TSDB repository configuration, upper layer to free the pointer * * @return a TSDB repository handle on success, NULL for failure and the error number is set @@ -131,7 +132,7 @@ int32_t tsdbConfigRepo(tsdb_repo_t *repo, STsdbCfg *pCfg); * @return a info struct handle on success, NULL for failure and the error number is set. The upper * layers should free the info handle themselves or memory leak will occur */ -STSDBRepoInfo *tsdbGetStatus(tsdb_repo_t *pRepo); +STsdbRepoInfo *tsdbGetStatus(tsdb_repo_t *pRepo); // -- For table manipulation diff --git a/src/vnode/tsdb/inc/tsdbMeta.h b/src/vnode/tsdb/inc/tsdbMeta.h index 30ac543391..56abb3b2e6 100644 --- a/src/vnode/tsdb/inc/tsdbMeta.h +++ b/src/vnode/tsdb/inc/tsdbMeta.h @@ -16,7 +16,7 @@ typedef enum { } TSDB_TABLE_TYPE; typedef struct STable { - int32_t tableId; + int32_t tableId; int64_t uid; char * tableName; TSDB_TABLE_TYPE type; @@ -51,17 +51,16 @@ typedef struct STable { // A handle to deal with stream void *streamHandle; + struct STable *next; + } STable; typedef struct { - int32_t numOfTables; // Number of tables not including TSDB_SUPER_TABLE (#TSDB_NTABLE + #TSDB_STABLE) - int32_t numOfSuperTables; // Number of super tables (#TSDB_SUPER_TABLE) - // An array of tables (TSDB_NTABLE and TSDB_STABLE) in this TSDB repository - STable **pTables; - - // A map of tableName->tableId - // TODO: May use hash table - void *pNameTableMap; + int32_t maxTables; + int32_t numOfSuperTables; // Number of super tables (#TSDB_SUPER_TABLE) + STable ** tables; // array of normal tables + STable * stables; // linked list of super tables + void * tableMap; // table map of name ==> table } STsdbMeta; // ---- Operation on STable @@ -84,10 +83,10 @@ SSchema *tsdbGetTableSchema(STable *pTable); #define TSDB_GET_TABLE_OF_NAME(pHandle, name) /* TODO */ // Create a new meta handle with configuration -STsdbMeta * tsdbCreateMeta (int32_t maxTables); -int32_t tsdbFreeMeta(STsdbMeta *pMeta); +STsdbMeta *tsdbCreateMeta(int32_t maxTables); +int32_t tsdbFreeMeta(STsdbMeta *pMeta); // Recover the meta handle from the file -STsdbMeta * tsdbOpenMetaHandle(char *tsdbDir); +STsdbMeta *tsdbOpenMetaHandle(char *tsdbDir); int32_t tsdbCreateTableImpl(STsdbMeta *pHandle, STableCfg *pCfg); diff --git a/src/vnode/tsdb/src/tsdbMain.c b/src/vnode/tsdb/src/tsdbMain.c index 1875471464..8cd926c7fd 100644 --- a/src/vnode/tsdb/src/tsdbMain.c +++ b/src/vnode/tsdb/src/tsdbMain.c @@ -175,7 +175,7 @@ int32_t tsdbConfigRepo(tsdb_repo_t *repo, STsdbCfg *pCfg) { return 0; } -STSDBRepoInfo *tsdbGetStatus(tsdb_repo_t *pRepo) { +STsdbRepoInfo *tsdbGetStatus(tsdb_repo_t *pRepo) { // TODO } diff --git a/src/vnode/tsdb/src/tsdbMeta.c b/src/vnode/tsdb/src/tsdbMeta.c index 6752c6e4c5..de15f8156c 100644 --- a/src/vnode/tsdb/src/tsdbMeta.c +++ b/src/vnode/tsdb/src/tsdbMeta.c @@ -4,24 +4,34 @@ #include "tsdb.h" #include "tsdbMeta.h" +#define TSDB_MIN_TABLES 10 +#define TSDB_MAX_TABLES 100000 +#define TSDB_DEFAULT_NSTABLES 10 + +#define IS_VALID_MAX_TABLES(maxTables) (((maxTables) >= TSDB_MIN_TABLES) && ((maxTables) >= TSDB_MAX_TABLES)) + +static int tsdbFreeTable(STable *pTable); + STsdbMeta *tsdbCreateMeta(int32_t maxTables) { + if (!IS_VALID_MAX_TABLES(maxTables)) return NULL; + STsdbMeta *pMeta = (STsdbMeta *)malloc(sizeof(STsdbMeta)); if (pMeta == NULL) { return NULL; } - pMeta->numOfTables = 0; + pMeta->maxTables = maxTables; pMeta->numOfSuperTables = 0; - pMeta->pTables = calloc(sizeof(STable *), maxTables); - if (pMeta->pTables == NULL) { + pMeta->stables = NULL; + pMeta->tables = (STable **)calloc(maxTables, sizeof(STable *)); + if (pMeta->tables == NULL) { free(pMeta); return NULL; } // TODO : initialize the map - // pMetahandle->pNameTableMap = ; - if (pMeta->pNameTableMap == NULL) { - free(pMeta->pTables); + if (pMeta->tableMap == NULL) { + free(pMeta->tables); free(pMeta); return NULL; } @@ -30,11 +40,32 @@ STsdbMeta *tsdbCreateMeta(int32_t maxTables) { } int32_t tsdbFreeMeta(STsdbMeta *pMeta) { + if (pMeta == NULL) return 0; + + for (int i = 0; i < pMeta->maxTables; i++) { + if (pMeta->tables[i] != NULL) { + tsdbFreeTable(pMeta->tables[i]); + } + } + + free(pMeta->tables); + + STable *pTable = pMeta->stables; + while (pTable != NULL) { + STable *pTemp = pTable; + pTable = pTemp->next; + tsdbFreeTable(pTemp); + } + // TODO close the map + + free(pMeta); + + return 0; } static int32_t tsdbCheckTableCfg(STableCfg *pCfg) { return 0; } -int32_t tsdbCreateTableImpl(STsdbMeta *pHandle, STableCfg *pCfg) { +int32_t tsdbCreateTableImpl(STsdbMeta *pMeta, STableCfg *pCfg) { if (tsdbCheckTableCfg(pCfg) < 0) { return -1; } @@ -45,19 +76,21 @@ int32_t tsdbCreateTableImpl(STsdbMeta *pHandle, STableCfg *pCfg) { return -1; } - pHandle->pTables[pCfg->tableId.tid] = pTable; + pMeta->tables[pCfg->tableId.tid] = pTable; // TODO: add name to it return 0; } -STsdbMeta * tsdbOpenMetaHandle(char *tsdbDir) { +STsdbMeta *tsdbOpenMetaHandle(char *tsdbDir) { // Open meta file for reading - STsdbMeta *pHandle = (STsdbMeta *)malloc(sizeof(STsdbMeta)); - if (pHandle == NULL) { + STsdbMeta *pMeta = (STsdbMeta *)malloc(sizeof(STsdbMeta)); + if (pMeta == NULL) { return NULL; } - return pHandle; -} \ No newline at end of file + return pMeta; +} + +static int tsdbFreeTable(STable *pTable) { return 0; } \ No newline at end of file From 5d746c9542b3720d6dfb85cf86dca3293211359d Mon Sep 17 00:00:00 2001 From: hzcheng Date: Tue, 3 Mar 2020 05:03:38 +0000 Subject: [PATCH 08/16] more --- src/vnode/tsdb/inc/tsdbMeta.h | 3 +-- src/vnode/tsdb/src/tsdbMain.c | 30 +++++++++++++++++++++++++----- src/vnode/tsdb/src/tsdbMeta.c | 8 ++++---- 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/vnode/tsdb/inc/tsdbMeta.h b/src/vnode/tsdb/inc/tsdbMeta.h index 56abb3b2e6..6fdc446dee 100644 --- a/src/vnode/tsdb/inc/tsdbMeta.h +++ b/src/vnode/tsdb/inc/tsdbMeta.h @@ -18,7 +18,6 @@ typedef enum { typedef struct STable { int32_t tableId; int64_t uid; - char * tableName; TSDB_TABLE_TYPE type; int64_t createdTime; @@ -60,7 +59,7 @@ typedef struct { int32_t numOfSuperTables; // Number of super tables (#TSDB_SUPER_TABLE) STable ** tables; // array of normal tables STable * stables; // linked list of super tables - void * tableMap; // table map of name ==> table + void * tableMap; // hash map of uid ==> STable * } STsdbMeta; // ---- Operation on STable diff --git a/src/vnode/tsdb/src/tsdbMain.c b/src/vnode/tsdb/src/tsdbMain.c index 8cd926c7fd..3999b88ef8 100644 --- a/src/vnode/tsdb/src/tsdbMain.c +++ b/src/vnode/tsdb/src/tsdbMain.c @@ -47,6 +47,8 @@ typedef struct _tsdb_repo { static int32_t tsdbCheckAndSetDefaultCfg(STsdbCfg *pCfg); static int32_t tsdbSetRepoEnv(STsdbRepo *pRepo); static int32_t tsdbDestroyRepoEnv(STsdbRepo *pRepo); +static int tsdbOpenMetaFile(char *tsdbDir); +static int tsdbRecoverRepo(int fd, STsdbCfg *pCfg); #define TSDB_GET_TABLE_BY_ID(pRepo, sid) (((STSDBRepo *)pRepo)->pTableList)[sid] #define TSDB_GET_TABLE_BY_NAME(pRepo, name) @@ -131,9 +133,14 @@ tsdb_repo_t *tsdbOpenRepo(char *tsdbDir) { return NULL; } - // TODO: Initialize configuration from the file - pRepo->tsdbMeta = tsdbCreateMeta(pRepo->config.maxTables); - if (pRepo->tsdbMeta == NULL) { + int fd = tsdbOpenMetaFile(tsdbDir); + if (fd < 0) { + free(pRepo); + return NULL; + } + + if (tsdbRecoverRepo(fd, &(pRepo->config)) < 0) { + close(fd); free(pRepo); return NULL; } @@ -144,6 +151,7 @@ tsdb_repo_t *tsdbOpenRepo(char *tsdbDir) { return NULL; } + pRepo->rootDir = strdup(tsdbDir); pRepo->state = TSDB_REPO_STATE_ACTIVE; return (tsdb_repo_t *)pRepo; @@ -155,11 +163,12 @@ static int32_t tsdbFlushCache(STsdbRepo *pRepo) { int32_t tsdbCloseRepo(tsdb_repo_t *repo) { STsdbRepo *pRepo = (STsdbRepo *)repo; - - tsdbFlushCache(pRepo); + if (pRepo == NULL) return 0; pRepo->state = TSDB_REPO_STATE_CLOSED; + tsdbFlushCache(pRepo); + tsdbFreeMeta(pRepo->tsdbMeta); tsdbFreeCache(pRepo->tsdbCache); @@ -258,5 +267,16 @@ static int32_t tsdbDestroyRepoEnv(STsdbRepo *pRepo) { char *metaFname = tsdbGetFileName(pRepo->rootDir, "tsdb", TSDB_FILE_TYPE_META); remove(metaFname); + return 0; +} + +static int tsdbOpenMetaFile(char *tsdbDir) { + // TODO + return 0 +} + +static int tsdbRecoverRepo(int fd, STsdbCfg *pCfg) { + // TODO: read tsdb configuration from file + // recover tsdb meta return 0; } \ No newline at end of file diff --git a/src/vnode/tsdb/src/tsdbMeta.c b/src/vnode/tsdb/src/tsdbMeta.c index de15f8156c..b149cf9795 100644 --- a/src/vnode/tsdb/src/tsdbMeta.c +++ b/src/vnode/tsdb/src/tsdbMeta.c @@ -3,6 +3,7 @@ // #include "taosdef.h" #include "tsdb.h" #include "tsdbMeta.h" +#include "hash.h" #define TSDB_MIN_TABLES 10 #define TSDB_MAX_TABLES 100000 @@ -29,7 +30,7 @@ STsdbMeta *tsdbCreateMeta(int32_t maxTables) { return NULL; } - // TODO : initialize the map + pMeta->tableMap = taosInitHashTable(maxTables + maxTables / 10, taosGetDefaultHashFunction, false); if (pMeta->tableMap == NULL) { free(pMeta->tables); free(pMeta); @@ -56,7 +57,8 @@ int32_t tsdbFreeMeta(STsdbMeta *pMeta) { pTable = pTemp->next; tsdbFreeTable(pTemp); } - // TODO close the map + + taosCleanUpHashTable(pMeta->tableMap); free(pMeta); @@ -70,7 +72,6 @@ int32_t tsdbCreateTableImpl(STsdbMeta *pMeta, STableCfg *pCfg) { return -1; } - // TODO: STable *pTable = (STable *)malloc(sizeof(STable)); if (pTable == NULL) { return -1; @@ -78,7 +79,6 @@ int32_t tsdbCreateTableImpl(STsdbMeta *pMeta, STableCfg *pCfg) { pMeta->tables[pCfg->tableId.tid] = pTable; - // TODO: add name to it return 0; } From e534caefff7f3866339110a7386d5080ac2eca0c Mon Sep 17 00:00:00 2001 From: hzcheng Date: Tue, 3 Mar 2020 05:54:05 +0000 Subject: [PATCH 09/16] more --- src/CMakeLists.txt | 2 +- src/vnode/tsdb/CMakeLists.txt | 9 +++++---- src/vnode/tsdb/src/tsdbCache.c | 3 +-- src/vnode/tsdb/src/tsdbMain.c | 7 ++++++- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a85df15776..34768b00df 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -9,6 +9,6 @@ ADD_SUBDIRECTORY(kit) ADD_SUBDIRECTORY(plugins) ADD_SUBDIRECTORY(sdb) ADD_SUBDIRECTORY(mnode) +ADD_SUBDIRECTORY(vnode) ADD_SUBDIRECTORY(dnode) -#ADD_SUBDIRECTORY(vnode) #ADD_SUBDIRECTORY(connector/jdbc) diff --git a/src/vnode/tsdb/CMakeLists.txt b/src/vnode/tsdb/CMakeLists.txt index 4a88fbd7d6..ed924109a7 100644 --- a/src/vnode/tsdb/CMakeLists.txt +++ b/src/vnode/tsdb/CMakeLists.txt @@ -1,9 +1,10 @@ aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/src SOURCE_LIST) -message(STATUS "tsdb source files: ${SOURCE_LIST}") - add_library(tsdb STATIC ${SOURCE_LIST}) - target_link_libraries(tsdb common) -target_include_directories(tsdb PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/inc") \ No newline at end of file +target_include_directories(tsdb + PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/inc" + PUBLIC "${CMAKE_SOURCE_DIR}/src/util/inc" + PUBLIC "${CMAKE_SOURCE_DIR}/src/os/linux/inc" + ) \ No newline at end of file diff --git a/src/vnode/tsdb/src/tsdbCache.c b/src/vnode/tsdb/src/tsdbCache.c index e957778eb6..25b649b73d 100644 --- a/src/vnode/tsdb/src/tsdbCache.c +++ b/src/vnode/tsdb/src/tsdbCache.c @@ -14,5 +14,4 @@ SCacheHandle *tsdbCreateCache(int32_t numOfBlocks) { } -int32_t tsdbFreeCache(SCacheHandle *pHandle) { -} \ No newline at end of file +int32_t tsdbFreeCache(SCacheHandle *pHandle) { return 0; } \ No newline at end of file diff --git a/src/vnode/tsdb/src/tsdbMain.c b/src/vnode/tsdb/src/tsdbMain.c index 3999b88ef8..793f67d176 100644 --- a/src/vnode/tsdb/src/tsdbMain.c +++ b/src/vnode/tsdb/src/tsdbMain.c @@ -159,6 +159,7 @@ tsdb_repo_t *tsdbOpenRepo(char *tsdbDir) { static int32_t tsdbFlushCache(STsdbRepo *pRepo) { // TODO + return 0; } int32_t tsdbCloseRepo(tsdb_repo_t *repo) { @@ -186,6 +187,7 @@ int32_t tsdbConfigRepo(tsdb_repo_t *repo, STsdbCfg *pCfg) { STsdbRepoInfo *tsdbGetStatus(tsdb_repo_t *pRepo) { // TODO + return NULL; } int32_t tsdbCreateTable(tsdb_repo_t *repo, STableCfg *pCfg) { @@ -195,14 +197,17 @@ int32_t tsdbCreateTable(tsdb_repo_t *repo, STableCfg *pCfg) { int32_t tsdbAlterTable(tsdb_repo_t *pRepo, STableCfg *pCfg) { // TODO + return 0; } STableInfo *tsdbGetTableInfo(tsdb_repo_t *pRepo, STableId tid, int32_t *error) { // TODO + return NULL; } int32_t tsdbInsertData(tsdb_repo_t *pRepo, STableId tid, char *pData, int32_t *error) { // TODO + return 0; } // Check the configuration and set default options @@ -272,7 +277,7 @@ static int32_t tsdbDestroyRepoEnv(STsdbRepo *pRepo) { static int tsdbOpenMetaFile(char *tsdbDir) { // TODO - return 0 + return 0; } static int tsdbRecoverRepo(int fd, STsdbCfg *pCfg) { From a92a1f12b30ba584add0c12b8f2323a5652f38cb Mon Sep 17 00:00:00 2001 From: hzcheng Date: Tue, 3 Mar 2020 08:05:46 +0000 Subject: [PATCH 10/16] more --- src/vnode/common/inc/dataformat.h | 2 + src/vnode/common/inc/schema.h | 1 + src/vnode/tsdb/inc/tsdb.h | 18 +++--- src/vnode/tsdb/inc/tsdbMeta.h | 20 +++--- src/vnode/tsdb/src/tsdbMain.c | 13 +++- src/vnode/tsdb/src/tsdbMeta.c | 100 +++++++++++++++++++++++++++--- 6 files changed, 128 insertions(+), 26 deletions(-) diff --git a/src/vnode/common/inc/dataformat.h b/src/vnode/common/inc/dataformat.h index b0389955fb..9e72ed5d6b 100644 --- a/src/vnode/common/inc/dataformat.h +++ b/src/vnode/common/inc/dataformat.h @@ -50,6 +50,8 @@ typedef char * SDataCols; #define TD_DATAROW_LEN(pDataRow) (*(int32_t *)(pDataRow)) #define TD_DATAROW_DATA(pDataRow) ((pDataRow) + sizeof(int32_t)) +SDataRow tdSDataRowDup(SDataRow rdata); + // ---- operation on SDataRows #define TD_DATAROWS_LEN(pDataRows) (*(int32_t *)(pDataRows)) #define TD_DATAROWS_ROWS(pDataRows) (*(int32_t *)(pDataRows + sizeof(int32_t))) diff --git a/src/vnode/common/inc/schema.h b/src/vnode/common/inc/schema.h index bda7e337c0..5387dbf99b 100644 --- a/src/vnode/common/inc/schema.h +++ b/src/vnode/common/inc/schema.h @@ -67,6 +67,7 @@ typedef char *SISchema; SISchema tdConvertSchemaToInline(SSchema *pSchema); int32_t tdGetColumnIdxByName(SSchema *pSchema, char *colName); int32_t tdGetColumnIdxById(SSchema *pSchema, int32_t colId); +SSchema *tdDupSchema(SSchema *pSchema); // ---- TODO: operations to modify schema diff --git a/src/vnode/tsdb/inc/tsdb.h b/src/vnode/tsdb/inc/tsdb.h index 4065533a1f..bf27d127d3 100644 --- a/src/vnode/tsdb/inc/tsdb.h +++ b/src/vnode/tsdb/inc/tsdb.h @@ -8,6 +8,7 @@ #include #include +#include "dataformat.h" #include "schema.h" #define TSDB_VERSION_MAJOR 1 @@ -35,8 +36,11 @@ typedef struct { char data[]; } SSubmitBlock; +enum { TSDB_PRECISION_MILLI, TSDB_PRECISION_MICRO, TSDB_PRECISION_NANO }; + // the TSDB repository configuration typedef struct { + int8_t precision; int32_t tsdbId; int32_t maxTables; // maximum number of tables this repository can have int32_t daysPerFile; // day per file sharding policy @@ -57,20 +61,18 @@ typedef struct STsdbRepoInfo { // the meter configuration typedef struct { - char * tableName; STableId tableId; - char *superTable; // if not NULL, the table is created from a super table, need to make sure the super - // table exists in this TSDB. int64_t stableUid; + int64_t createdTime; int32_t numOfCols; // number of columns. For table form super table, not includes the tag schema SSchema *schema; // If numOfCols == schema_->numOfCols, it is a normal table, stableName = NULL // If numOfCols < schema->numOfCols, it is a table created from super table // assert(numOfCols <= schema->numOfCols); - char *tagValues; // NULL if it is normal table - // otherwise, it contains the tag values. + SDataRow tagValues; // NULL if it is normal table + // otherwise, it contains the tag values. } STableCfg; // the meter information report structure @@ -154,7 +156,7 @@ int32_t tsdbAlterTable(tsdb_repo_t *repo, STableCfg *pCfg); * * @return 0 for success, -1 for failure and the error number is set */ -int32_t tsdbDropTable(tsdb_repo_t *pRepo, STableId tid, int32_t *error); +int32_t tsdbDropTable(tsdb_repo_t *pRepo, STableId tid); /** * Get the information of a table in the repository @@ -164,7 +166,7 @@ int32_t tsdbDropTable(tsdb_repo_t *pRepo, STableId tid, int32_t *error); * * @return a table information handle for success, NULL for failure and the error number is set */ -STableInfo *tsdbGetTableInfo(tsdb_repo_t *pRepo, STableId tid, int32_t *error); +STableInfo *tsdbGetTableInfo(tsdb_repo_t *pRepo, STableId tid); // -- FOR INSERT DATA /** @@ -176,7 +178,7 @@ STableInfo *tsdbGetTableInfo(tsdb_repo_t *pRepo, STableId tid, int32_t *error); * * @return the number of points inserted, -1 for failure and the error number is set */ -int32_t tsdbInsertData(tsdb_repo_t *pRepo, STableId tid, char *pData, int32_t *error); +int32_t tsdbInsertData(tsdb_repo_t *pRepo, STableId tid, char *pData); // -- FOR QUERY TIME SERIES DATA diff --git a/src/vnode/tsdb/inc/tsdbMeta.h b/src/vnode/tsdb/inc/tsdbMeta.h index 6fdc446dee..21c75212ca 100644 --- a/src/vnode/tsdb/inc/tsdbMeta.h +++ b/src/vnode/tsdb/inc/tsdbMeta.h @@ -4,6 +4,8 @@ #include +#include "dataformat.h" + // #include "taosdef.h" // Initially, there are 4 tables @@ -16,14 +18,15 @@ typedef enum { } TSDB_TABLE_TYPE; typedef struct STable { - int32_t tableId; - int64_t uid; + STableId tableId; TSDB_TABLE_TYPE type; int64_t createdTime; - // super table UID - int32_t superTableId; + // super table UID -1 for normal table + int32_t stableUid; + + int32_t numOfCols; // Schema for this table // For TSDB_SUPER_TABLE, it is the schema including tags @@ -34,7 +37,7 @@ typedef struct STable { // Tag value for this table // For TSDB_SUPER_TABLE and TSDB_NTABLE, it is NULL // For TSDB_STABLE, it is the tag value string - char *pTagVal; + SDataRow pTagVal; // Object content; // For TSDB_SUPER_TABLE, it is the index of tables created from it @@ -45,10 +48,10 @@ typedef struct STable { } content; // A handle to deal with event - void *eventHandle; + void *eventHandler; // A handle to deal with stream - void *streamHandle; + void *streamHandler; struct STable *next; @@ -56,7 +59,6 @@ typedef struct STable { typedef struct { int32_t maxTables; - int32_t numOfSuperTables; // Number of super tables (#TSDB_SUPER_TABLE) STable ** tables; // array of normal tables STable * stables; // linked list of super tables void * tableMap; // hash map of uid ==> STable * @@ -89,3 +91,5 @@ int32_t tsdbFreeMeta(STsdbMeta *pMeta); STsdbMeta *tsdbOpenMetaHandle(char *tsdbDir); int32_t tsdbCreateTableImpl(STsdbMeta *pHandle, STableCfg *pCfg); + +int32_t tsdbInsertDataImpl(STsdbMeta *pMeta, STableId tableId, char *pData); \ No newline at end of file diff --git a/src/vnode/tsdb/src/tsdbMain.c b/src/vnode/tsdb/src/tsdbMain.c index 793f67d176..f1a0701669 100644 --- a/src/vnode/tsdb/src/tsdbMain.c +++ b/src/vnode/tsdb/src/tsdbMain.c @@ -200,13 +200,20 @@ int32_t tsdbAlterTable(tsdb_repo_t *pRepo, STableCfg *pCfg) { return 0; } -STableInfo *tsdbGetTableInfo(tsdb_repo_t *pRepo, STableId tid, int32_t *error) { +int32_t tsdbDropTable(tsdb_repo_t *pRepo, STableId tid) { + return 0; +} + +STableInfo *tsdbGetTableInfo(tsdb_repo_t *pRepo, STableId tid) { // TODO return NULL; } -int32_t tsdbInsertData(tsdb_repo_t *pRepo, STableId tid, char *pData, int32_t *error) { - // TODO +int32_t tsdbInsertData(tsdb_repo_t *repo, STableId tableId, char *pData) { + STsdbRepo *pRepo = (STsdbRepo *)repo; + + tsdbInsertDataImpl(pRepo->tsdbMeta, tableId, pData); + return 0; } diff --git a/src/vnode/tsdb/src/tsdbMeta.c b/src/vnode/tsdb/src/tsdbMeta.c index b149cf9795..72781810e1 100644 --- a/src/vnode/tsdb/src/tsdbMeta.c +++ b/src/vnode/tsdb/src/tsdbMeta.c @@ -1,9 +1,10 @@ #include // #include "taosdef.h" +#include "hash.h" +#include "tskiplist.h" #include "tsdb.h" #include "tsdbMeta.h" -#include "hash.h" #define TSDB_MIN_TABLES 10 #define TSDB_MAX_TABLES 100000 @@ -11,7 +12,12 @@ #define IS_VALID_MAX_TABLES(maxTables) (((maxTables) >= TSDB_MIN_TABLES) && ((maxTables) >= TSDB_MAX_TABLES)) -static int tsdbFreeTable(STable *pTable); +static int tsdbFreeTable(STable *pTable); +static int32_t tsdbCheckTableCfg(STableCfg *pCfg); +static STable *tsdbGetTableByUid(int64_t uid); +static int tsdbAddTable(STsdbMeta *pMeta, STable *pTable); +static int tsdbAddTableIntoMap(STsdbMeta *pMeta, STable *pTable); +static int tsdbAddTableIntoIndex(pMeta, pTable); STsdbMeta *tsdbCreateMeta(int32_t maxTables) { if (!IS_VALID_MAX_TABLES(maxTables)) return NULL; @@ -22,7 +28,6 @@ STsdbMeta *tsdbCreateMeta(int32_t maxTables) { } pMeta->maxTables = maxTables; - pMeta->numOfSuperTables = 0; pMeta->stables = NULL; pMeta->tables = (STable **)calloc(maxTables, sizeof(STable *)); if (pMeta->tables == NULL) { @@ -65,19 +70,52 @@ int32_t tsdbFreeMeta(STsdbMeta *pMeta) { return 0; } -static int32_t tsdbCheckTableCfg(STableCfg *pCfg) { return 0; } - int32_t tsdbCreateTableImpl(STsdbMeta *pMeta, STableCfg *pCfg) { if (tsdbCheckTableCfg(pCfg) < 0) { return -1; } + STable *pSTable = NULL; + + if (pCfg->stableUid > 0) { // to create a TSDB_STABLE + pSTable = tsdbGetTableByUid(pCfg->stableUid); + if (pSTable == NULL) { // super table not exists, try to create it + pSTable = (STable *)calloc(1, sizeof(STable)); + if (pSTable == NULL) return -1; + + pSTable->tableId.uid = pCfg->stableUid; + pSTable->tableId.tid = -1; + pSTable->type = TSDB_SUPER_TABLE; + pSTable->createdTime = pCfg->createdTime; // The created time is not required + pSTable->stableUid = -1; + pSTable->numOfCols = pCfg->numOfCols; + pSTable->pSchema = tdDupSchema(pCfg->schema); + pSTable->content.pIndex = tSkipListCreate(5, 0, 10); // TODO: change here + tsdbAddTable(pMeta, pSTable); + } else { + if (pSTable->type != TSDB_SUPER_TABLE) return NULL; + } + } + STable *pTable = (STable *)malloc(sizeof(STable)); if (pTable == NULL) { return -1; } - pMeta->tables[pCfg->tableId.tid] = pTable; + pTable->tableId = pCfg->tableId; + pTable->createdTime = pCfg->createdTime; + if (1 /* */) { // TSDB_STABLE + pTable->type = TSDB_STABLE; + pTable->stableUid = pCfg->stableUid; + pTable->pTagVal = tdSDataRowDup(pCfg->tagValues); + } else { // TSDB_NTABLE + pTable->type = TSDB_NTABLE; + pTable->stableUid = -1; + pTable->pSchema = tdDupSchema(pCfg->schema); + } + pTable->content.pData = tSkipListCreate(5, 0, 10); // TODO: change here + + tsdbAddTable(pMeta, pTable); return 0; } @@ -93,4 +131,52 @@ STsdbMeta *tsdbOpenMetaHandle(char *tsdbDir) { return pMeta; } -static int tsdbFreeTable(STable *pTable) { return 0; } \ No newline at end of file +int32_t tsdbInsertDataImpl(STsdbMeta *pMeta, STableId tableId, char *pData) { + STable *pTable = pMeta->tables[tableId.tid]; + if (pTable == NULL) { + // TODO: deal with the error here + return 0; + } + + if (pTable->tableId.uid != tableId.uid) { + // TODO: deal with the error here + return 0; + } + + return 0; +} + +static int tsdbFreeTable(STable *pTable) { return 0; } + +static int32_t tsdbCheckTableCfg(STableCfg *pCfg) { return 0; } + +static STable *tsdbGetTableByUid(int64_t uid) { return NULL; } + +static int tsdbAddTable(STsdbMeta *pMeta, STable *pTable) { + if (pTable->type == TSDB_SUPER_TABLE) { + if (pMeta->stables == NULL) { + pMeta->stables = pTable; + pTable->next = NULL; + } else { + STable *pTemp = pMeta->stables; + pMeta->stables = pTable; + pTable->next = pTemp; + } + } else { + pMeta->tables[pTable->tableId.tid] = pTable; + if (pTable->type == TSDB_STABLE) { + tsdbAddTableIntoIndex(pMeta, pTable); + } + } + + return tsdbAddTableIntoMap(pMeta, pTable); +} + +static int tsdbAddTableIntoMap(STsdbMeta *pMeta, STable *pTable) { + // TODO: add the table to the map + return 0; +} +static int tsdbAddTableIntoIndex(pMeta, pTable) { + // TODO + return 0; +} \ No newline at end of file From 98be150f48fe60aa011b23ad94d7264941d87769 Mon Sep 17 00:00:00 2001 From: hzcheng Date: Tue, 3 Mar 2020 08:17:48 +0000 Subject: [PATCH 11/16] more --- src/dnode/CMakeLists.txt | 2 +- src/vnode/common/inc/dataformat.h | 21 +++++++++++++++++ src/vnode/tsdb/inc/tsdb.h | 25 +++++++++++++++++--- src/vnode/tsdb/inc/tsdbCache.h | 22 +++++++++++++++++ src/vnode/tsdb/inc/tsdbFile.h | 22 +++++++++++++++++ src/vnode/tsdb/inc/tsdbMeta.h | 39 ++++++++++++++++++++++++------- 6 files changed, 119 insertions(+), 12 deletions(-) diff --git a/src/dnode/CMakeLists.txt b/src/dnode/CMakeLists.txt index ef7d6e2981..af84071849 100644 --- a/src/dnode/CMakeLists.txt +++ b/src/dnode/CMakeLists.txt @@ -10,7 +10,7 @@ IF ((TD_LINUX_64) OR (TD_LINUX_32 AND TD_ARM)) AUX_SOURCE_DIRECTORY(src SRC) ADD_EXECUTABLE(taosd ${SRC}) - TARGET_LINK_LIBRARIES(taosd mnode sdb taos_static monitor http) + TARGET_LINK_LIBRARIES(taosd mnode sdb taos_static monitor http tsdb) #IF (TD_CLUSTER) # TARGET_LINK_LIBRARIES(taosd dcluster) diff --git a/src/vnode/common/inc/dataformat.h b/src/vnode/common/inc/dataformat.h index 9e72ed5d6b..9399d38023 100644 --- a/src/vnode/common/inc/dataformat.h +++ b/src/vnode/common/inc/dataformat.h @@ -1,3 +1,17 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ #if !defined(_TD_DATA_FORMAT_H_) #define _TD_DATA_FORMAT_H_ @@ -5,6 +19,9 @@ #include "schema.h" +#ifdef __cplusplus +extern "C" { +#endif // ----------------- Data row structure /* A data row, the format of it is like below: @@ -71,4 +88,8 @@ SDataRow tdSDataRowDup(SDataRow rdata); */ int32_t tdGetMaxDataRowSize(SSchema *pSchema); +#ifdef __cplusplus +} +#endif + #endif // _TD_DATA_FORMAT_H_ diff --git a/src/vnode/tsdb/inc/tsdb.h b/src/vnode/tsdb/inc/tsdb.h index bf27d127d3..655448ed16 100644 --- a/src/vnode/tsdb/inc/tsdb.h +++ b/src/vnode/tsdb/inc/tsdb.h @@ -1,6 +1,17 @@ -/************************************** - * FOR OUTSIDE USAGE - **************************************/ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ #if !defined(_TD_TSDB_H_) #define _TD_TSDB_H_ @@ -11,6 +22,10 @@ #include "dataformat.h" #include "schema.h" +#ifdef __cplusplus +extern "C" { +#endif + #define TSDB_VERSION_MAJOR 1 #define TSDB_VERSION_MINOR 0 @@ -324,4 +339,8 @@ STableIDList *tsdbGetTableList(tsdb_query_handle_t *pQueryHandle); */ STableIDList *tsdbQueryTableList(int16_t stableId, const char *pTagCond); +#ifdef __cplusplus +} +#endif + #endif // _TD_TSDB_H_ \ No newline at end of file diff --git a/src/vnode/tsdb/inc/tsdbCache.h b/src/vnode/tsdb/inc/tsdbCache.h index 6521b0fd9f..31d8221723 100644 --- a/src/vnode/tsdb/inc/tsdbCache.h +++ b/src/vnode/tsdb/inc/tsdbCache.h @@ -1,3 +1,17 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ #if !defined(_TD_TSDBCACHE_H_) #define _TD_TSDBCACHE_H_ @@ -5,6 +19,10 @@ // #include "cache.h" +#ifdef __cplusplus +extern "C" { +#endif + #define TSDB_DEFAULT_CACHE_BLOCK_SIZE 16*1024*1024 /* 16M */ typedef struct { @@ -38,4 +56,8 @@ typedef struct STSDBCache { SCacheHandle *tsdbCreateCache(int32_t numOfBlocks); int32_t tsdbFreeCache(SCacheHandle *pHandle); +#ifdef __cplusplus +} +#endif + #endif // _TD_TSDBCACHE_H_ diff --git a/src/vnode/tsdb/inc/tsdbFile.h b/src/vnode/tsdb/inc/tsdbFile.h index 8ea0a8b0f7..2dda323805 100644 --- a/src/vnode/tsdb/inc/tsdbFile.h +++ b/src/vnode/tsdb/inc/tsdbFile.h @@ -1,9 +1,27 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ #if !defined(_TD_TSDB_FILE_H_) #define _TD_TSDB_FILE_H_ #include // #include "tstring.h" +#ifdef __cplusplus +extern "C" { +#endif + typedef int32_t file_id_t; typedef enum { @@ -38,4 +56,8 @@ typedef struct { char *tsdbGetFileName(char *dirName, char *fname, TSDB_FILE_TYPE type); +#ifdef __cplusplus +} +#endif + #endif // _TD_TSDB_FILE_H_ diff --git a/src/vnode/tsdb/inc/tsdbMeta.h b/src/vnode/tsdb/inc/tsdbMeta.h index 21c75212ca..99930e9454 100644 --- a/src/vnode/tsdb/inc/tsdbMeta.h +++ b/src/vnode/tsdb/inc/tsdbMeta.h @@ -1,11 +1,28 @@ -/************************************ - * For internal usage - ************************************/ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ +#if !defined(_TSDB_META_H_) +#define _TSDB_META_H_ #include #include "dataformat.h" +#ifdef __cplusplus +extern "C" { +#endif + // #include "taosdef.h" // Initially, there are 4 tables @@ -58,10 +75,10 @@ typedef struct STable { } STable; typedef struct { - int32_t maxTables; - STable ** tables; // array of normal tables - STable * stables; // linked list of super tables - void * tableMap; // hash map of uid ==> STable * + int32_t maxTables; + STable **tables; // array of normal tables + STable * stables; // linked list of super tables + void * tableMap; // hash map of uid ==> STable * } STsdbMeta; // ---- Operation on STable @@ -92,4 +109,10 @@ STsdbMeta *tsdbOpenMetaHandle(char *tsdbDir); int32_t tsdbCreateTableImpl(STsdbMeta *pHandle, STableCfg *pCfg); -int32_t tsdbInsertDataImpl(STsdbMeta *pMeta, STableId tableId, char *pData); \ No newline at end of file +int32_t tsdbInsertDataImpl(STsdbMeta *pMeta, STableId tableId, char *pData); + +#ifdef __cplusplus +} +#endif + +#endif // _TSDB_META_H_ \ No newline at end of file From 532d4a26b798210598e615b3722aad33564ea948 Mon Sep 17 00:00:00 2001 From: hzcheng Date: Wed, 4 Mar 2020 02:54:56 +0000 Subject: [PATCH 12/16] more --- src/vnode/CMakeLists.txt | 2 -- src/vnode/common/inc/type.h | 13 +------------ src/vnode/common/src/dataformat.c | 4 ++++ src/vnode/common/src/schema.c | 16 ++++++++++++++++ src/vnode/tests/tsdb/tsdbTests.cpp | 16 +++++++++++++--- src/vnode/tsdb/CMakeLists.txt | 2 +- src/vnode/tsdb/inc/tsdbFile.h | 13 +++++++------ 7 files changed, 42 insertions(+), 24 deletions(-) diff --git a/src/vnode/CMakeLists.txt b/src/vnode/CMakeLists.txt index 5acf0483ec..22770e3799 100644 --- a/src/vnode/CMakeLists.txt +++ b/src/vnode/CMakeLists.txt @@ -1,7 +1,5 @@ cmake_minimum_required(VERSION 2.8) -project(tsdb) - add_subdirectory(common) add_subdirectory(tsdb) diff --git a/src/vnode/common/inc/type.h b/src/vnode/common/inc/type.h index 685fc2e240..1aaa95cb90 100644 --- a/src/vnode/common/inc/type.h +++ b/src/vnode/common/inc/type.h @@ -16,18 +16,7 @@ typedef enum { TD_DATATYPE_BINARY } td_datatype_t; -const int32_t rowDataLen[] = { - sizeof(int8_t), // TD_DATATYPE_BOOL, - sizeof(int8_t), // TD_DATATYPE_TINYINT, - sizeof(int16_t), // TD_DATATYPE_SMALLINT, - sizeof(int32_t), // TD_DATATYPE_INT, - sizeof(int64_t), // TD_DATATYPE_BIGINT, - sizeof(float), // TD_DATATYPE_FLOAT, - sizeof(double), // TD_DATATYPE_DOUBLE, - sizeof(int32_t), // TD_DATATYPE_VARCHAR, - sizeof(int32_t), // TD_DATATYPE_NCHAR, - sizeof(int32_t) // TD_DATATYPE_BINARY -}; +extern const int32_t rowDataLen[]; // TODO: finish below #define TD_DATATYPE_BOOL_NULL diff --git a/src/vnode/common/src/dataformat.c b/src/vnode/common/src/dataformat.c index f09ea1445b..18b78a4129 100644 --- a/src/vnode/common/src/dataformat.c +++ b/src/vnode/common/src/dataformat.c @@ -29,4 +29,8 @@ int32_t tdGetMaxDataRowSize(SSchema *pSchema) { nbytes += TD_DATA_ROW_HEADER_SIZE; return nbytes; +} + +SDataRow tdSDataRowDup(SDataRow rdata) { + return NULL; } \ No newline at end of file diff --git a/src/vnode/common/src/schema.c b/src/vnode/common/src/schema.c index 79b41533d2..eb1b4eb84b 100644 --- a/src/vnode/common/src/schema.c +++ b/src/vnode/common/src/schema.c @@ -1,6 +1,18 @@ #include #include "schema.h" +const int32_t rowDataLen[] = { + sizeof(int8_t), // TD_DATATYPE_BOOL, + sizeof(int8_t), // TD_DATATYPE_TINYINT, + sizeof(int16_t), // TD_DATATYPE_SMALLINT, + sizeof(int32_t), // TD_DATATYPE_INT, + sizeof(int64_t), // TD_DATATYPE_BIGINT, + sizeof(float), // TD_DATATYPE_FLOAT, + sizeof(double), // TD_DATATYPE_DOUBLE, + sizeof(int32_t), // TD_DATATYPE_VARCHAR, + sizeof(int32_t), // TD_DATATYPE_NCHAR, + sizeof(int32_t) // TD_DATATYPE_BINARY +}; static size_t tdGetEstimatedISchemaLen(SSchema *pSchema) { size_t colNameLen = 0; @@ -82,4 +94,8 @@ int32_t tdGetColumnIdxById(SSchema *pSchema, int32_t colId) { } } return -1; +} + +SSchema *tdDupSchema(SSchema *pSchema) { + return NULL; } \ No newline at end of file diff --git a/src/vnode/tests/tsdb/tsdbTests.cpp b/src/vnode/tests/tsdb/tsdbTests.cpp index 3d7f41df24..8e1b37b191 100644 --- a/src/vnode/tests/tsdb/tsdbTests.cpp +++ b/src/vnode/tests/tsdb/tsdbTests.cpp @@ -4,9 +4,19 @@ #include "tsdb.h" TEST(TsdbTest, createTsdbRepo) { - STsdbCfg *pCfg = (STsdbCfg *)malloc(sizeof(STsdbCfg)); + STsdbCfg config; - free(pCfg); + config.precision = TSDB_PRECISION_MILLI; + config.tsdbId = 0; + config.maxTables = 100; + config.daysPerFile = 10; + config.minRowsPerFileBlock = 100; + config.maxRowsPerFileBlock = 4096; + config.maxCacheSize = 4 * 1024 * 1024; - ASSERT_EQ(1, 2/2); + tsdb_repo_t *pRepo = tsdbCreateRepo("/root/mnt/test/vnode0", &config, NULL); + + ASSERT_NE(pRepo, nullptr); + + tsdbCloseRepo(pRepo); } \ No newline at end of file diff --git a/src/vnode/tsdb/CMakeLists.txt b/src/vnode/tsdb/CMakeLists.txt index ed924109a7..4e66b98528 100644 --- a/src/vnode/tsdb/CMakeLists.txt +++ b/src/vnode/tsdb/CMakeLists.txt @@ -1,7 +1,7 @@ aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/src SOURCE_LIST) add_library(tsdb STATIC ${SOURCE_LIST}) -target_link_libraries(tsdb common) +target_link_libraries(tsdb common tutil) target_include_directories(tsdb PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/inc" diff --git a/src/vnode/tsdb/inc/tsdbFile.h b/src/vnode/tsdb/inc/tsdbFile.h index 2dda323805..39d1b0b3c2 100644 --- a/src/vnode/tsdb/inc/tsdbFile.h +++ b/src/vnode/tsdb/inc/tsdbFile.h @@ -31,12 +31,13 @@ typedef enum { TSDB_FILE_TYPE_META // .meta file type } TSDB_FILE_TYPE; -const char *tsdbFileSuffix[] = { - ".head", // TSDB_FILE_TYPE_HEAD - ".data", // TSDB_FILE_TYPE_DATA - ".last", // TSDB_FILE_TYPE_LAST - ".meta" // TSDB_FILE_TYPE_META -}; +extern const char *tsdbFileSuffix[]; +// const char *tsdbFileSuffix[] = { +// ".head", // TSDB_FILE_TYPE_HEAD +// ".data", // TSDB_FILE_TYPE_DATA +// ".last", // TSDB_FILE_TYPE_LAST +// ".meta" // TSDB_FILE_TYPE_META +// }; typedef struct { int64_t fileSize; From 2b927cb78a832a2ff93c62ba11f2e26b95f7973e Mon Sep 17 00:00:00 2001 From: hzcheng Date: Wed, 4 Mar 2020 03:14:13 +0000 Subject: [PATCH 13/16] fix some error --- src/vnode/common/src/dataformat.c | 44 ++++++++++++++---------------- src/vnode/tsdb/src/tsdbFileStore.c | 8 ++++-- src/vnode/tsdb/src/tsdbMeta.c | 6 ++-- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/vnode/common/src/dataformat.c b/src/vnode/common/src/dataformat.c index 18b78a4129..1f2dfc7dad 100644 --- a/src/vnode/common/src/dataformat.c +++ b/src/vnode/common/src/dataformat.c @@ -3,34 +3,32 @@ #include "dataformat.h" int32_t tdGetMaxDataRowSize(SSchema *pSchema) { - int32_t nbytes = 0; + int32_t nbytes = 0; - for (int32_t i = 0; i < TD_SCHEMA_NCOLS(pSchema); i++) - { - SColumn *pCol = TD_SCHEMA_COLUMN_AT(pSchema, i); - td_datatype_t type = TD_COLUMN_TYPE(pCol); + for (int32_t i = 0; i < TD_SCHEMA_NCOLS(pSchema); i++) { + SColumn * pCol = TD_SCHEMA_COLUMN_AT(pSchema, i); + td_datatype_t type = TD_COLUMN_TYPE(pCol); - nbytes += rowDataLen[type]; + nbytes += rowDataLen[type]; - switch (type) - { - case TD_DATATYPE_VARCHAR: - nbytes += TD_COLUMN_BYTES(pCol); - break; - case TD_DATATYPE_NCHAR: - nbytes += 4 * TD_COLUMN_BYTES(pCol); - break; - case TD_DATATYPE_BINARY: - nbytes += TD_COLUMN_BYTES(pCol); - break; - } + switch (type) { + case TD_DATATYPE_VARCHAR: + nbytes += TD_COLUMN_BYTES(pCol); + break; + case TD_DATATYPE_NCHAR: + nbytes += 4 * TD_COLUMN_BYTES(pCol); + break; + case TD_DATATYPE_BINARY: + nbytes += TD_COLUMN_BYTES(pCol); + break; + default: + break; } + } - nbytes += TD_DATA_ROW_HEADER_SIZE; + nbytes += TD_DATA_ROW_HEADER_SIZE; - return nbytes; + return nbytes; } -SDataRow tdSDataRowDup(SDataRow rdata) { - return NULL; -} \ No newline at end of file +SDataRow tdSDataRowDup(SDataRow rdata) { return NULL; } \ No newline at end of file diff --git a/src/vnode/tsdb/src/tsdbFileStore.c b/src/vnode/tsdb/src/tsdbFileStore.c index a47f2eb1e4..79e6e6170a 100644 --- a/src/vnode/tsdb/src/tsdbFileStore.c +++ b/src/vnode/tsdb/src/tsdbFileStore.c @@ -1,6 +1,8 @@ +#include + #include "tsdbFile.h" -char *tsdbGetFileName(char *dirName, char *fname, TSDB_FILE_TYPE type){ - // char *suffix = tsdbFileSuffix[type]; - // TODO +char *tsdbGetFileName(char *dirName, char *fname, TSDB_FILE_TYPE type) { + // TODO + return NULL; } \ No newline at end of file diff --git a/src/vnode/tsdb/src/tsdbMeta.c b/src/vnode/tsdb/src/tsdbMeta.c index 72781810e1..eb348fafae 100644 --- a/src/vnode/tsdb/src/tsdbMeta.c +++ b/src/vnode/tsdb/src/tsdbMeta.c @@ -10,14 +10,14 @@ #define TSDB_MAX_TABLES 100000 #define TSDB_DEFAULT_NSTABLES 10 -#define IS_VALID_MAX_TABLES(maxTables) (((maxTables) >= TSDB_MIN_TABLES) && ((maxTables) >= TSDB_MAX_TABLES)) +#define IS_VALID_MAX_TABLES(maxTables) (((maxTables) >= TSDB_MIN_TABLES) && ((maxTables) <= TSDB_MAX_TABLES)) static int tsdbFreeTable(STable *pTable); static int32_t tsdbCheckTableCfg(STableCfg *pCfg); static STable *tsdbGetTableByUid(int64_t uid); static int tsdbAddTable(STsdbMeta *pMeta, STable *pTable); static int tsdbAddTableIntoMap(STsdbMeta *pMeta, STable *pTable); -static int tsdbAddTableIntoIndex(pMeta, pTable); +static int tsdbAddTableIntoIndex(STsdbMeta *pMeta, STable *pTable); STsdbMeta *tsdbCreateMeta(int32_t maxTables) { if (!IS_VALID_MAX_TABLES(maxTables)) return NULL; @@ -176,7 +176,7 @@ static int tsdbAddTableIntoMap(STsdbMeta *pMeta, STable *pTable) { // TODO: add the table to the map return 0; } -static int tsdbAddTableIntoIndex(pMeta, pTable) { +static int tsdbAddTableIntoIndex(STsdbMeta *pMeta, STable *pTable) { // TODO return 0; } \ No newline at end of file From 5ffd4207ae661960bcc30635ffae953c5e520ddd Mon Sep 17 00:00:00 2001 From: hzcheng Date: Wed, 4 Mar 2020 05:55:30 +0000 Subject: [PATCH 14/16] more --- src/vnode/common/inc/skiplist.c | 73 --------------------------------- src/vnode/common/inc/skiplist.h | 38 ----------------- 2 files changed, 111 deletions(-) delete mode 100644 src/vnode/common/inc/skiplist.c delete mode 100644 src/vnode/common/inc/skiplist.h diff --git a/src/vnode/common/inc/skiplist.c b/src/vnode/common/inc/skiplist.c deleted file mode 100644 index f2384bcbae..0000000000 --- a/src/vnode/common/inc/skiplist.c +++ /dev/null @@ -1,73 +0,0 @@ -#include - -#include "skiplist.h" - -#define IS_VALID_SKIPLIST_DUPLICATE_KEY_STRATEGY(strategy) \ - (((strategy) >= SKIPLIST_ALLOW_DUPLICATE_KEY) && ((strategy) <= SKIPLIST_DISCARD_DUPLICATE_KEY)) - -SSkipListNode *tdCreateSkiplistNode(int32_t nlevels) { - SSkipListNode *pNode = (SSkipListNode *)malloc(sizeof(SSkipListNode)); - if (pNode == NULL) return NULL; - - pNode->nexts = (struct _skiplist_node **)cmalloc(nlevels, sizeof(struct _skiplist_node *)); - if (pNode->nexts == NULL) { - free(pNode); - return NULL; - } - - pNode->prevs = (struct _skiplist_node **)cmalloc(nlevels, sizeof(struct _skiplist_node *)); - if (pNode->nexts == NULL) { - free(pNode->nexts); - free(pNode); - return NULL; - } - - return pNode; -} - -int32_t tdFreeSkiplistNode(SSkipListNode *pNode) { - if (pNode == NULL) return 0; - // TODO: free key and free value - - // Free the skip list - free(pNode->nexts); - free(pNode->prevs); - free(pNode); - return 0; -} - -SSkipList *tdCreateSkiplist(int16_t nMaxLevels, SKIPLIST_DUPLICATE_KEY_STATEGY strategy) { - // Check parameters - if (!IS_VALID_SKIPLIST_DUPLICATE_KEY_STRATEGY(strategy)) return NULL; - - SSkipList *pSkipList = (SSkipList *)malloc(sizeof(SSkipList)); - if (pSkipList == NULL) { - return NULL; - } - - pSkipList->strategy = strategy; - pSkipList->nMaxLevels = nMaxLevels; - - pSkipList->head = tdCreateSkiplistNode(nMaxLevels); - if (pSkipList->head == NULL) { - free(pSkipList); - return NULL; - } - - return pSkipList; -} - -int32_t tdFreeSkipList(SSkipList *pSkipList) { - if (pSkipList == NULL) return 0; - - SSkipListNode *pNode = pSkipList->head->nexts[0]; - while (pNode) { - SSkipListNode *pTemp = pNode->nexts[0]; - tdFreeSkiplistNode(pNode); - pNode = pTemp; - } - - free(pSkipList); - - return 0; -} \ No newline at end of file diff --git a/src/vnode/common/inc/skiplist.h b/src/vnode/common/inc/skiplist.h deleted file mode 100644 index 5c395d289a..0000000000 --- a/src/vnode/common/inc/skiplist.h +++ /dev/null @@ -1,38 +0,0 @@ -#if !defined(_TD_SKIPLIST_H) -#define _TD_SKIPLIST_H - -#include - -typedef enum { - SKIPLIST_ALLOW_DUPLICATE_KEY, - SKIPLIST_REPLACE_DUPLICATE_KEY, - SKIPLIST_DISCARD_DUPLICATE_KEY -} SKIPLIST_DUPLICATE_KEY_STATEGY; - -typedef struct _skiplist_node { - void * key; - void * value; - struct _skiplist_node **nexts; - struct _skiplist_node **prevs; -} SSkipListNode; - -// To implement a general skip list -typedef struct _skiplist { - SKIPLIST_DUPLICATE_KEY_STATEGY strategy; - SSkipListNode * head; - SSkipListNode * tail; - int32_t nMaxLevels; - int32_t count; -} SSkipList; - -// -- Operations on SSkipListNode -SSkipListNode *tdCreateSkiplistNode(int32_t nlevels); -int32_t tdFreeSkiplistNode(SSkipListNode *pNode); - -// -- Operations on SSkipList -SSkipList *tdCreateSkiplist(int16_t nMaxLevels, SKIPLIST_DUPLICATE_KEY_STATEGY strategy); -int32_t tdFreeSkipList(SSkipList *pSkipList); -// int32_t tdAddItemToSkiplist(SSkipList *slist, void *key, void *value); -// int32_t tdAddNodeToSkiplist(SSkipList *slist, SSkipListNode *node); - -#endif // _TD_SKIPLIST_H From 576f77031d0c84d14f564a5a822dfcc303371cb4 Mon Sep 17 00:00:00 2001 From: hzcheng Date: Wed, 4 Mar 2020 05:58:56 +0000 Subject: [PATCH 15/16] more --- src/util/inc/tarray.h | 91 +++ src/util/inc/tskiplist.h | 204 ++++--- src/util/src/tarray.c | 117 ++++ src/util/src/tskiplist.c | 1220 ++++++++++++++++++-------------------- 4 files changed, 907 insertions(+), 725 deletions(-) create mode 100644 src/util/inc/tarray.h create mode 100755 src/util/src/tarray.c diff --git a/src/util/inc/tarray.h b/src/util/inc/tarray.h new file mode 100644 index 0000000000..62cb1a23f8 --- /dev/null +++ b/src/util/inc/tarray.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#ifndef TDENGINE_TAOSARRAY_H +#define TDENGINE_TAOSARRAY_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "os.h" + +#define TARRAY_MIN_SIZE 8 +#define TARRAY_GET_ELEM(array, index) ((array)->pData + (index) * (array)->elemSize) + +typedef struct SArray { + size_t size; + size_t capacity; + size_t elemSize; + + void* pData; +} SArray; + +/** + * + * @param size + * @param elemSize + * @return + */ +void* taosArrayInit(size_t size, size_t elemSize); + +/** + * + * @param pArray + * @param pData + * @return + */ +void* taosArrayPush(SArray* pArray, void* pData); + +/** + * + * @param pArray + */ +void taosArrayPop(SArray* pArray); + +/** + * + * @param pArray + * @param index + * @return + */ +void* taosArrayGet(SArray* pArray, size_t index); + +/** + * + * @param pArray + * @return + */ +size_t taosArrayGetSize(SArray* pArray); + +/** + * + * @param pArray + * @param index + * @param pData + */ +void taosArrayInsert(SArray* pArray, int32_t index, void* pData); + +/** + * + * @param pArray + */ +void taosArrayDestory(SArray* pArray); + +#ifdef __cplusplus +} +#endif + +#endif // TDENGINE_TAOSARRAY_H diff --git a/src/util/inc/tskiplist.h b/src/util/inc/tskiplist.h index d6cdd77c11..ca9cc330c8 100644 --- a/src/util/inc/tskiplist.h +++ b/src/util/inc/tskiplist.h @@ -20,59 +20,62 @@ extern "C" { #endif -#define MAX_SKIP_LIST_LEVEL 20 - -#include -#include -#include - #include "os.h" #include "ttypes.h" +#include "tarray.h" /* * key of each node * todo move to as the global structure in all search codes... */ +#define MAX_SKIP_LIST_LEVEL 15 +#define SKIP_LIST_RECORD_PERFORMANCE 0 -const static size_t SKIP_LIST_STR_KEY_LENGTH_THRESHOLD = 15; -typedef tVariant tSkipListKey; +typedef char *SSkipListKey; +typedef char *(*__sl_key_fn_t)(const void *); -typedef enum tSkipListPointQueryType { - INCLUDE_POINT_QUERY, - EXCLUDE_POINT_QUERY, -} tSkipListPointQueryType; +/** + * the format of skip list node is as follows: + * +------------+-----------------------+------------------------+-----+------+ + * | node level | forward pointer array | backward pointer array | key | data | + * +------------+-----------------------+------------------------+-----+------+ + * the skiplist node is located in a consecutive memory area, key will not be copy to skip list + */ +typedef struct SSkipListNode { + uint8_t level; +} SSkipListNode; -typedef struct tSkipListNode { - uint16_t nLevel; - char * pData; +#define SL_NODE_HEADER_SIZE(_l) (sizeof(SSkipListNode) + ((_l) << 1u) * POINTER_BYTES) - struct tSkipListNode **pForward; - struct tSkipListNode **pBackward; +#define SL_GET_FORWARD_POINTER(n, _l) ((SSkipListNode **)((char *)(n) + sizeof(SSkipListNode)))[(_l)] +#define SL_GET_BACKWARD_POINTER(n, _l) \ + ((SSkipListNode **)((char *)(n) + sizeof(SSkipListNode) + ((n)->level) * POINTER_BYTES))[(_l)] - tSkipListKey key; -} tSkipListNode; +#define SL_GET_NODE_DATA(n) ((char*)(n) + SL_NODE_HEADER_SIZE((n)->level)) +#define SL_GET_NODE_KEY(s, n) ((s)->keyFn(SL_GET_NODE_DATA(n))) + +#define SL_GET_NODE_LEVEL(n) *(int32_t *)((n)) /* - * @version 0.2 + * @version 0.3 * @date 2017/11/12 - * the simple version of SkipList. + * the simple version of skip list. + * * for multi-thread safe purpose, we employ pthread_rwlock_t to guarantee to generate - * deterministic result. Later, we will remove the lock in SkipList to further - * enhance the performance. In this case, one should use the concurrent skip list (by - * using michael-scott algorithm) instead of this simple version in a multi-thread - * environment, to achieve higher performance of read/write operations. + * deterministic result. Later, we will remove the lock in SkipList to further enhance the performance. + * In this case, one should use the concurrent skip list (by using michael-scott algorithm) instead of + * this simple version in a multi-thread environment, to achieve higher performance of read/write operations. * * Note: Duplicated primary key situation. * In case of duplicated primary key, two ways can be employed to handle this situation: - * 1. add as normal insertion with out special process. - * 2. add an overflow pointer at each list node, all nodes with the same key will be added - * in the overflow pointer. In this case, the total steps of each search will be reduced significantly. + * 1. add as normal insertion without special process. + * 2. add an overflow pointer at each list node, all nodes with the same key will be added in the overflow pointer. + * In this case, the total steps of each search will be reduced significantly. * Currently, we implement the skip list in a line with the first means, maybe refactor it soon. * * Memory consumption: the memory alignment causes many memory wasted. So, employ a memory * pool will significantly reduce the total memory consumption, as well as the calloc/malloc operation costs. * - * 3. use the iterator pattern to refactor all routines to make it more clean */ // state struct, record following information: @@ -81,7 +84,7 @@ typedef struct tSkipListNode { // avg search rsp time, for latest 1000 queries // total memory size typedef struct tSkipListState { - // in bytes, sizeof(tSkipList)+sizeof(tSkipListNode)*tSkipList->nSize + // in bytes, sizeof(SSkipList)+sizeof(SSkipListNode)*SSkipList->nSize uint64_t nTotalMemSize; uint64_t nLevelNodeCnt[MAX_SKIP_LIST_LEVEL]; uint64_t queryCount; // total query count @@ -101,68 +104,95 @@ typedef struct tSkipListState { uint64_t nTotalElapsedTimeForInsert; } tSkipListState; -typedef struct tSkipList { - tSkipListNode pHead; - uint64_t nSize; - uint16_t nMaxLevel; - uint16_t nLevel; - uint16_t keyType; - uint16_t nMaxKeyLen; +typedef struct SSkipListKeyInfo { + uint8_t dupKey : 2; // if allow duplicated key in the skip list + uint8_t type : 6; // key type + uint8_t len; // maximum key length, used in case of string key +} SSkipListKeyInfo; - __compar_fn_t comparator; - pthread_rwlock_t lock; // will be removed soon - tSkipListState state; // skiplist state -} tSkipList; +typedef struct SSkipList { + __compar_fn_t comparFn; + __sl_key_fn_t keyFn; + uint32_t size; + uint8_t maxLevel; + uint8_t level; + SSkipListKeyInfo keyInfo; + + pthread_rwlock_t *lock; + SSkipListNode * pHead; + +#if SKIP_LIST_RECORD_PERFORMANCE + tSkipListState state; // skiplist state +#endif + +} SSkipList; /* * iterate the skiplist * this will cause the multi-thread problem, when the skiplist is destroyed, the iterate may * continue iterating the skiplist, so add the reference count for skiplist - * TODO add the ref for skiplist when one iterator is created + * TODO add the ref for skip list when one iterator is created */ typedef struct SSkipListIterator { - tSkipList * pSkipList; - tSkipListNode *cur; + SSkipList * pSkipList; + SSkipListNode *cur; int64_t num; } SSkipListIterator; -/* - * query condition structure to denote the range query - * todo merge the point query cond with range query condition +/** + * + * @param nMaxLevel maximum skip list level + * @param keyType type of key + * @param dupKey allow the duplicated key in the skip list + * @return */ -typedef struct tSKipListQueryCond { - // when the upper bounding == lower bounding, it is a point query - tSkipListKey lowerBnd; - tSkipListKey upperBnd; - int32_t lowerBndRelOptr; // relation operator to denote if lower bound is - int32_t upperBndRelOptr; // included or not -} tSKipListQueryCond; +SSkipList *tSkipListCreate(uint8_t nMaxLevel, uint8_t keyType, uint8_t keyLen, uint8_t dupKey, uint8_t threadsafe, + __sl_key_fn_t fn); -tSkipList *tSkipListCreate(int16_t nMaxLevel, int16_t keyType, int16_t nMaxKeyLen); - -void *tSkipListDestroy(tSkipList *pSkipList); - -// create skip list key -tSkipListKey tSkipListCreateKey(int32_t type, char *val, size_t keyLength); - -// destroy skip list key -void tSkipListDestroyKey(tSkipListKey *pKey); - -// put data into skiplist -tSkipListNode *tSkipListPut(tSkipList *pSkipList, void *pData, tSkipListKey *pKey, int32_t insertIdenticalKey); - -/* - * get only *one* node of which key is equalled to pKey, even there are more - * than one nodes are of the same key +/** + * + * @param pSkipList + * @return NULL will always be returned */ -tSkipListNode *tSkipListGetOne(tSkipList *pSkipList, tSkipListKey *pKey); +void *tSkipListDestroy(SSkipList *pSkipList); -/* - * get all data with the same keys +/** + * + * @param pSkipList + * @param level + * @param headSize */ -int32_t tSkipListGets(tSkipList *pSkipList, tSkipListKey *pKey, tSkipListNode ***pRes); +void tSkipListRandNodeInfo(SSkipList *pSkipList, int32_t *level, int32_t *headSize); -int32_t tSkipListIterateList(tSkipList *pSkipList, tSkipListNode ***pRes, bool (*fp)(tSkipListNode *, void *), +/** + * put the skip list node into the skip list. + * If failed, NULL will be returned, otherwise, the pNode will be returned. + * + * @param pSkipList + * @param pNode + * @return + */ +SSkipListNode *tSkipListPut(SSkipList *pSkipList, SSkipListNode *pNode); + +/** + * get only *one* node of which key is equalled to pKey, even there are more than one nodes are of the same key + * + * @param pSkipList + * @param pKey + * @param keyType + * @return + */ +SArray* tSkipListGet(SSkipList *pSkipList, SSkipListKey pKey, int16_t keyType); + +/** + * + * @param pSkipList + * @param pRes + * @param fp + * @param param + * @return + */ +int32_t tSkipListIterateList(SSkipList *pSkipList, SSkipListNode ***pRes, bool (*fp)(SSkipListNode *, void *), void *param); /* @@ -173,30 +203,16 @@ int32_t tSkipListIterateList(tSkipList *pSkipList, tSkipListNode ***pRes, bool ( * true: one node has been removed * false: no node has been removed */ -bool tSkipListRemove(tSkipList *pSkipList, tSkipListKey *pKey); +bool tSkipListRemove(SSkipList *pSkipList, SSkipListKey *pKey); /* * remove the specified node in parameters */ -void tSkipListRemoveNode(tSkipList *pSkipList, tSkipListNode *pNode); +void tSkipListRemoveNode(SSkipList *pSkipList, SSkipListNode *pNode); -// for debug purpose only -void tSkipListPrint(tSkipList *pSkipList, int16_t nlevel); - -/* - * range query & single point query function - */ -int32_t tSkipListQuery(tSkipList *pSkipList, tSKipListQueryCond *pQueryCond, tSkipListNode ***pResult); - -/* - * include/exclude point query - */ -int32_t tSkipListPointQuery(tSkipList *pSkipList, tSkipListKey *pKey, int32_t numOfKey, tSkipListPointQueryType type, - tSkipListNode ***pResult); - -int32_t tSkipListIteratorReset(tSkipList *pSkipList, SSkipListIterator *iter); -bool tSkipListIteratorNext(SSkipListIterator *iter); -tSkipListNode *tSkipListIteratorGet(SSkipListIterator *iter); +int32_t tSkipListIteratorReset(SSkipList *pSkipList, SSkipListIterator *iter); +bool tSkipListIteratorNext(SSkipListIterator *iter); +SSkipListNode *tSkipListIteratorGet(SSkipListIterator *iter); #ifdef __cplusplus } diff --git a/src/util/src/tarray.c b/src/util/src/tarray.c new file mode 100755 index 0000000000..017c5422c1 --- /dev/null +++ b/src/util/src/tarray.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#include "tarray.h" + +void* taosArrayInit(size_t size, size_t elemSize) { + assert(elemSize > 0); + + if (size < TARRAY_MIN_SIZE) { + size = TARRAY_MIN_SIZE; + } + + SArray* pArray = calloc(1, sizeof(SArray)); + if (pArray == NULL) { + return NULL; + } + + pArray->pData = calloc(size, elemSize * size); + if (pArray->pData == NULL) { + free(pArray); + return NULL; + } + + pArray->capacity = size; + pArray->elemSize = elemSize; + return pArray; +} + +static void taosArrayResize(SArray* pArray) { + assert(pArray->size >= pArray->capacity); + + size_t size = pArray->capacity; + size = (size << 1u); + + void* tmp = realloc(pArray->pData, size * pArray->elemSize); + if (tmp == NULL) { + // todo + } + + pArray->pData = tmp; + pArray->capacity = size; +} + +void* taosArrayPush(SArray* pArray, void* pData) { + if (pArray == NULL || pData == NULL) { + return NULL; + } + + if (pArray->size >= pArray->capacity) { + taosArrayResize(pArray); + } + + void* dst = TARRAY_GET_ELEM(pArray, pArray->size); + memcpy(dst, pData, pArray->elemSize); + + pArray->size += 1; + return dst; +} + +void taosArrayPop(SArray* pArray) { + if (pArray == NULL || pArray->size == 0) { + return; + } + + pArray->size -= 1; +} + +void* taosArrayGet(SArray* pArray, size_t index) { + assert(index < pArray->size); + return TARRAY_GET_ELEM(pArray, index); +} + +size_t taosArrayGetSize(SArray* pArray) { return pArray->size; } + +void taosArrayInsert(SArray* pArray, int32_t index, void* pData) { + if (pArray == NULL || pData == NULL) { + return; + } + + if (index >= pArray->size) { + taosArrayPush(pArray, pData); + return; + } + + if (pArray->size >= pArray->capacity) { + taosArrayResize(pArray); + } + + void* dst = TARRAY_GET_ELEM(pArray, index); + + int32_t remain = pArray->size - index; + memmove(dst + pArray->elemSize, dst, pArray->elemSize * remain); + memcpy(dst, pData, pArray->elemSize); + + pArray->size += 1; +} + +void taosArrayDestory(SArray* pArray) { + if (pArray == NULL) { + return; + } + + free(pArray->pData); + free(pArray); +} diff --git a/src/util/src/tskiplist.c b/src/util/src/tskiplist.c index 69a7144253..c4f0ccab03 100644 --- a/src/util/src/tskiplist.c +++ b/src/util/src/tskiplist.c @@ -15,49 +15,54 @@ #include "os.h" #include "tlog.h" -#include "taosdef.h" +// #include "tsdb.h" #include "tskiplist.h" #include "tutil.h" -static FORCE_INLINE void recordNodeEachLevel(tSkipList *pSkipList, int32_t nLevel) { // record link count in each level - for (int32_t i = 0; i < nLevel; ++i) { +static FORCE_INLINE void recordNodeEachLevel(SSkipList *pSkipList, int32_t level) { // record link count in each level +#if SKIP_LIST_RECORD_PERFORMANCE + for (int32_t i = 0; i < level; ++i) { pSkipList->state.nLevelNodeCnt[i]++; } +#endif } -static FORCE_INLINE void removeNodeEachLevel(tSkipList *pSkipList, int32_t nLevel) { - for (int32_t i = 0; i < nLevel; ++i) { +static FORCE_INLINE void removeNodeEachLevel(SSkipList *pSkipList, int32_t level) { +#if SKIP_LIST_RECORD_PERFORMANCE + for (int32_t i = 0; i < level; ++i) { pSkipList->state.nLevelNodeCnt[i]--; } +#endif } -static FORCE_INLINE int32_t getSkipListNodeRandomHeight(tSkipList *pSkipList) { +static FORCE_INLINE int32_t getSkipListNodeRandomHeight(SSkipList *pSkipList) { const uint32_t factor = 4; int32_t n = 1; - while ((rand() % factor) == 0 && n <= pSkipList->nMaxLevel) { + while ((rand() % factor) == 0 && n <= pSkipList->maxLevel) { n++; } return n; } -static FORCE_INLINE int32_t getSkipListNodeLevel(tSkipList *pSkipList) { - int32_t nLevel = getSkipListNodeRandomHeight(pSkipList); - if (pSkipList->nSize == 0) { - nLevel = 1; - pSkipList->nLevel = 1; +static FORCE_INLINE int32_t getSkipListRandLevel(SSkipList *pSkipList) { + int32_t level = getSkipListNodeRandomHeight(pSkipList); + if (pSkipList->size == 0) { + level = 1; + pSkipList->level = 1; } else { - if (nLevel > pSkipList->nLevel && pSkipList->nLevel < pSkipList->nMaxLevel) { - nLevel = (++pSkipList->nLevel); + if (level > pSkipList->level && pSkipList->level < pSkipList->maxLevel) { + level = (++pSkipList->level); } } - return nLevel; + return level; } -void tSkipListDoInsert(tSkipList *pSkipList, tSkipListNode **forward, int32_t nLevel, tSkipListNode *pNode); +static void tSkipListDoInsert(SSkipList *pSkipList, SSkipListNode **forward, int32_t level, SSkipListNode *pNode); -void tSkipListDoRecordPut(tSkipList *pSkipList) { +void tSkipListDoRecordPut(SSkipList *pSkipList) { +#if SKIP_LIST_RECORD_PERFORMANCE const int32_t MAX_RECORD_NUM = 1000; if (pSkipList->state.nInsertObjs == MAX_RECORD_NUM) { @@ -67,37 +72,69 @@ void tSkipListDoRecordPut(tSkipList *pSkipList) { } else { pSkipList->state.nInsertObjs++; } +#endif } -int32_t compareIntVal(const void *pLeft, const void *pRight) { - int64_t lhs = ((tSkipListKey *)pLeft)->i64Key; - int64_t rhs = ((tSkipListKey *)pRight)->i64Key; +int32_t compareInt32Val(const void *pLeft, const void *pRight) { + int32_t ret = GET_INT32_VAL(pLeft) - GET_INT32_VAL(pRight); + if (ret == 0) { + return 0; + } else { + return ret > 0 ? 1 : -1; + } +} - DEFAULT_COMP(lhs, rhs); +int32_t compareInt64Val(const void *pLeft, const void *pRight) { + int32_t ret = GET_INT64_VAL(pLeft) - GET_INT64_VAL(pRight); + if (ret == 0) { + return 0; + } else { + return ret > 0 ? 1 : -1; + } +} + +int32_t compareInt16Val(const void *pLeft, const void *pRight) { + int32_t ret = GET_INT16_VAL(pLeft) - GET_INT16_VAL(pRight); + if (ret == 0) { + return 0; + } else { + return ret > 0 ? 1 : -1; + } +} + +int32_t compareInt8Val(const void *pLeft, const void *pRight) { + int32_t ret = GET_INT8_VAL(pLeft) - GET_INT8_VAL(pRight); + if (ret == 0) { + return 0; + } else { + return ret > 0 ? 1 : -1; + } } int32_t compareIntDoubleVal(const void *pLeft, const void *pRight) { - int64_t lhs = ((tSkipListKey *)pLeft)->i64Key; - double rhs = ((tSkipListKey *)pRight)->dKey; - if (fabs(lhs - rhs) < FLT_EPSILON) { - return 0; - } else { - return (lhs > rhs) ? 1 : -1; - } + // int64_t lhs = ((SSkipListKey *)pLeft)->i64Key; + // double rhs = ((SSkipListKey *)pRight)->dKey; + // if (fabs(lhs - rhs) < FLT_EPSILON) { + // return 0; + // } else { + // return (lhs > rhs) ? 1 : -1; + // } + return 0; } int32_t compareDoubleIntVal(const void *pLeft, const void *pRight) { - double lhs = ((tSkipListKey *)pLeft)->dKey; - int64_t rhs = ((tSkipListKey *)pRight)->i64Key; - if (fabs(lhs - rhs) < FLT_EPSILON) { - return 0; - } else { - return (lhs > rhs) ? 1 : -1; - } + // double lhs = ((SSkipListKey *)pLeft)->dKey; + // int64_t rhs = ((SSkipListKey *)pRight)->i64Key; + // if (fabs(lhs - rhs) < FLT_EPSILON) { + // return 0; + // } else { + // return (lhs > rhs) ? 1 : -1; + // } + return 0; } int32_t compareDoubleVal(const void *pLeft, const void *pRight) { - double ret = (((tSkipListKey *)pLeft)->dKey - ((tSkipListKey *)pRight)->dKey); + double ret = GET_DOUBLE_VAL(pLeft) - GET_DOUBLE_VAL(pRight); if (fabs(ret) < FLT_EPSILON) { return 0; } else { @@ -106,739 +143,660 @@ int32_t compareDoubleVal(const void *pLeft, const void *pRight) { } int32_t compareStrVal(const void *pLeft, const void *pRight) { - tSkipListKey *pL = (tSkipListKey *)pLeft; - tSkipListKey *pR = (tSkipListKey *)pRight; - - if (pL->nLen == 0 && pR->nLen == 0) { - return 0; - } - - //handle only one-side bound compare situation, there is only lower bound or only upper bound - if (pL->nLen == -1) { - return 1; // no lower bound, lower bound is minimum, always return -1; - } else if (pR->nLen == -1) { - return -1; // no upper bound, upper bound is maximum situation, always return 1; - } - - int32_t ret = strcmp(((tSkipListKey *)pLeft)->pz, ((tSkipListKey *)pRight)->pz); - - if (ret == 0) { - return 0; - } else { - return ret > 0 ? 1 : -1; - } + // SSkipListKey *pL = (SSkipListKey *)pLeft; + // SSkipListKey *pR = (SSkipListKey *)pRight; + // + // if (pL->nLen == 0 && pR->nLen == 0) { + // return 0; + // } + // + // // handle only one-side bound compare situation, there is only lower bound or only upper bound + // if (pL->nLen == -1) { + // return 1; // no lower bound, lower bound is minimum, always return -1; + // } else if (pR->nLen == -1) { + // return -1; // no upper bound, upper bound is maximum situation, always return 1; + // } + // + // int32_t ret = strcmp(((SSkipListKey *)pLeft)->pz, ((SSkipListKey *)pRight)->pz); + // + // if (ret == 0) { + // return 0; + // } else { + // return ret > 0 ? 1 : -1; + // } + return 0; } int32_t compareWStrVal(const void *pLeft, const void *pRight) { - tSkipListKey *pL = (tSkipListKey *)pLeft; - tSkipListKey *pR = (tSkipListKey *)pRight; - - if (pL->nLen == 0 && pR->nLen == 0) { - return 0; - } - - //handle only one-side bound compare situation, there is only lower bound or only upper bound - if (pL->nLen == -1) { - return 1; // no lower bound, lower bound is minimum, always return -1; - } else if (pR->nLen == -1) { - return -1; // no upper bound, upper bound is maximum situation, always return 1; - } - - int32_t ret = wcscmp(((tSkipListKey *)pLeft)->wpz, ((tSkipListKey *)pRight)->wpz); - - if (ret == 0) { - return 0; - } else { - return ret > 0 ? 1 : -1; - } + // SSkipListKey *pL = (SSkipListKey *)pLeft; + // SSkipListKey *pR = (SSkipListKey *)pRight; + // + // if (pL->nLen == 0 && pR->nLen == 0) { + // return 0; + // } + // + // // handle only one-side bound compare situation, there is only lower bound or only upper bound + // if (pL->nLen == -1) { + // return 1; // no lower bound, lower bound is minimum, always return -1; + // } else if (pR->nLen == -1) { + // return -1; // no upper bound, upper bound is maximum situation, always return 1; + // } + // + // int32_t ret = wcscmp(((SSkipListKey *)pLeft)->wpz, ((SSkipListKey *)pRight)->wpz); + // + // if (ret == 0) { + // return 0; + // } else { + // return ret > 0 ? 1 : -1; + // } + return 0; } -static __compar_fn_t getKeyFilterComparator(tSkipList *pSkipList, int32_t filterDataType) { - __compar_fn_t comparator = NULL; +static __compar_fn_t getKeyFilterComparator(SSkipList *pSkipList, int32_t filterDataType) { + __compar_fn_t comparFn = NULL; - switch (pSkipList->keyType) { + switch (pSkipList->keyInfo.type) { case TSDB_DATA_TYPE_TINYINT: case TSDB_DATA_TYPE_SMALLINT: case TSDB_DATA_TYPE_INT: - case TSDB_DATA_TYPE_BIGINT: + case TSDB_DATA_TYPE_BIGINT: { + if (filterDataType == TSDB_DATA_TYPE_BIGINT) { + comparFn = compareInt64Val; + break; + } + } case TSDB_DATA_TYPE_BOOL: { if (filterDataType >= TSDB_DATA_TYPE_BOOL && filterDataType <= TSDB_DATA_TYPE_BIGINT) { - comparator = compareIntVal; + comparFn = compareInt32Val; } else if (filterDataType >= TSDB_DATA_TYPE_FLOAT && filterDataType <= TSDB_DATA_TYPE_DOUBLE) { - comparator = compareIntDoubleVal; + comparFn = compareIntDoubleVal; } break; } case TSDB_DATA_TYPE_FLOAT: case TSDB_DATA_TYPE_DOUBLE: { - if (filterDataType >= TSDB_DATA_TYPE_BOOL && filterDataType <= TSDB_DATA_TYPE_BIGINT) { - comparator = compareDoubleIntVal; - } else if (filterDataType >= TSDB_DATA_TYPE_FLOAT && filterDataType <= TSDB_DATA_TYPE_DOUBLE) { - comparator = compareDoubleVal; +// if (filterDataType >= TSDB_DATA_TYPE_BOOL && filterDataType <= TSDB_DATA_TYPE_BIGINT) { +// comparFn = compareDoubleIntVal; +// } else if (filterDataType >= TSDB_DATA_TYPE_FLOAT && filterDataType <= TSDB_DATA_TYPE_DOUBLE) { +// comparFn = compareDoubleVal; +// } + if (filterDataType == TSDB_DATA_TYPE_DOUBLE) { + comparFn = compareDoubleVal; } break; } case TSDB_DATA_TYPE_BINARY: - comparator = compareStrVal; + comparFn = compareStrVal; break; case TSDB_DATA_TYPE_NCHAR: - comparator = compareWStrVal; + comparFn = compareWStrVal; break; default: - comparator = compareIntVal; + comparFn = compareInt32Val; break; } - return comparator; + return comparFn; } static __compar_fn_t getKeyComparator(int32_t keyType) { - __compar_fn_t comparator = NULL; + __compar_fn_t comparFn = NULL; switch (keyType) { case TSDB_DATA_TYPE_TINYINT: + comparFn = compareInt8Val; + break; case TSDB_DATA_TYPE_SMALLINT: + comparFn = compareInt16Val; + break; case TSDB_DATA_TYPE_INT: + comparFn = compareInt32Val; + break; case TSDB_DATA_TYPE_BIGINT: + comparFn = compareInt64Val; + break; case TSDB_DATA_TYPE_BOOL: - comparator = compareIntVal; + comparFn = compareInt32Val; break; case TSDB_DATA_TYPE_FLOAT: case TSDB_DATA_TYPE_DOUBLE: - comparator = compareDoubleVal; + comparFn = compareDoubleVal; break; case TSDB_DATA_TYPE_BINARY: - comparator = compareStrVal; + comparFn = compareStrVal; break; case TSDB_DATA_TYPE_NCHAR: - comparator = compareWStrVal; + comparFn = compareWStrVal; break; default: - comparator = compareIntVal; + comparFn = compareInt32Val; break; } - return comparator; + return comparFn; } -tSkipList* tSkipListCreate(int16_t nMaxLevel, int16_t keyType, int16_t nMaxKeyLen) { - tSkipList *pSkipList = (tSkipList *)calloc(1, sizeof(tSkipList)); +SSkipList *tSkipListCreate(uint8_t maxLevel, uint8_t keyType, uint8_t keyLen, uint8_t dupKey, uint8_t lock, + __sl_key_fn_t fn) { + SSkipList *pSkipList = (SSkipList *)calloc(1, sizeof(SSkipList)); if (pSkipList == NULL) { return NULL; } - pSkipList->keyType = keyType; + if (maxLevel > MAX_SKIP_LIST_LEVEL) { + maxLevel = MAX_SKIP_LIST_LEVEL; + } - pSkipList->comparator = getKeyComparator(keyType); - pSkipList->pHead.pForward = (tSkipListNode **)calloc(1, POINTER_BYTES * MAX_SKIP_LIST_LEVEL); + pSkipList->keyInfo = (SSkipListKeyInfo){.type = keyType, .len = keyLen, .dupKey = dupKey}; + pSkipList->keyFn = fn; - pSkipList->nMaxLevel = MAX_SKIP_LIST_LEVEL; - pSkipList->nLevel = 1; + pSkipList->comparFn = getKeyComparator(keyType); + pSkipList->maxLevel = maxLevel; + pSkipList->level = 1; - pSkipList->nMaxKeyLen = nMaxKeyLen; - pSkipList->nMaxLevel = nMaxLevel; + pSkipList->pHead = (SSkipListNode *)calloc(1, SL_NODE_HEADER_SIZE(maxLevel)); + pSkipList->pHead->level = pSkipList->maxLevel; - if (pthread_rwlock_init(&pSkipList->lock, NULL) != 0) { - tfree(pSkipList->pHead.pForward); - tfree(pSkipList); - return NULL; + if (lock) { + pSkipList->lock = calloc(1, sizeof(pthread_rwlock_t)); + + if (pthread_rwlock_init(pSkipList->lock, NULL) != 0) { + tfree(pSkipList->pHead); + tfree(pSkipList); + return NULL; + } } srand(time(NULL)); - pSkipList->state.nTotalMemSize += sizeof(tSkipList); + +#if SKIP_LIST_RECORD_PERFORMANCE + pSkipList->state.nTotalMemSize += sizeof(SSkipList); +#endif + return pSkipList; } -static void doRemove(tSkipList *pSkipList, tSkipListNode *pNode, tSkipListNode *forward[]) { - int32_t level = pNode->nLevel; - for (int32_t j = level - 1; j >= 0; --j) { - if ((forward[j]->pForward[j] != NULL) && (forward[j]->pForward[j]->pForward[j])) { - forward[j]->pForward[j]->pForward[j]->pBackward[j] = forward[j]; - } +// static void doRemove(SSkipList *pSkipList, SSkipListNode *pNode, SSkipListNode *forward[]) { +// int32_t level = pNode->level; +// for (int32_t j = level - 1; j >= 0; --j) { +// if ((forward[j]->pForward[j] != NULL) && (forward[j]->pForward[j]->pForward[j])) { +// forward[j]->pForward[j]->pForward[j]->pBackward[j] = forward[j]; +// } +// +// if (forward[j]->pForward[j] != NULL) { +// forward[j]->pForward[j] = forward[j]->pForward[j]->pForward[j]; +// } +// } +// +// pSkipList->state.nTotalMemSize -= (sizeof(SSkipListNode) + POINTER_BYTES * pNode->level * 2); +// removeNodeEachLevel(pSkipList, pNode->level); +// +// tfree(pNode); +// --pSkipList->size; +//} - if (forward[j]->pForward[j] != NULL) { - forward[j]->pForward[j] = forward[j]->pForward[j]->pForward[j]; - } - } - - pSkipList->state.nTotalMemSize -= (sizeof(tSkipListNode) + POINTER_BYTES * pNode->nLevel * 2); - removeNodeEachLevel(pSkipList, pNode->nLevel); - - tfree(pNode); - --pSkipList->nSize; -} - -static size_t getOneNodeSize(const tSkipListKey *pKey, int32_t nLevel) { - size_t size = sizeof(tSkipListNode) + sizeof(intptr_t) * (nLevel << 1); - if (pKey->nType == TSDB_DATA_TYPE_BINARY) { - size += pKey->nLen + 1; - } else if (pKey->nType == TSDB_DATA_TYPE_NCHAR) { - size += (pKey->nLen + 1) * TSDB_NCHAR_SIZE; - } - - return size; -} - -static tSkipListNode *tSkipListCreateNode(void *pData, const tSkipListKey *pKey, int32_t nLevel) { - size_t nodeSize = getOneNodeSize(pKey, nLevel); - tSkipListNode *pNode = (tSkipListNode *)calloc(1, nodeSize); - - pNode->pForward = (tSkipListNode **)(&pNode[1]); - pNode->pBackward = (pNode->pForward + nLevel); - - pNode->pData = pData; - - pNode->key = *pKey; - if (pKey->nType == TSDB_DATA_TYPE_BINARY) { - pNode->key.pz = (char *)(pNode->pBackward + nLevel); - - strcpy(pNode->key.pz, pKey->pz); - pNode->key.pz[pKey->nLen] = 0; - } else if (pKey->nType == TSDB_DATA_TYPE_NCHAR) { - pNode->key.wpz = (wchar_t *)(pNode->pBackward + nLevel); - wcsncpy(pNode->key.wpz, pKey->wpz, pKey->nLen); - pNode->key.wpz[pKey->nLen] = 0; - } - - pNode->nLevel = nLevel; - return pNode; -} - -tSkipListKey tSkipListCreateKey(int32_t type, char *val, size_t keyLength) { - tSkipListKey k = {0}; - tVariantCreateFromBinary(&k, val, (uint32_t) keyLength, (uint32_t) type); - return k; -} - -void tSkipListDestroyKey(tSkipListKey *pKey) { tVariantDestroy(pKey); } - -void* tSkipListDestroy(tSkipList *pSkipList) { +void *tSkipListDestroy(SSkipList *pSkipList) { if (pSkipList == NULL) { return NULL; } - pthread_rwlock_wrlock(&pSkipList->lock); - tSkipListNode *pNode = pSkipList->pHead.pForward[0]; + if (pSkipList->lock) { + pthread_rwlock_wrlock(pSkipList->lock); + } + + SSkipListNode *pNode = SL_GET_FORWARD_POINTER(pSkipList->pHead, 0); // pSkipList->pHead.pForward[0]; + while (pNode) { - tSkipListNode *pTemp = pNode; - pNode = pNode->pForward[0]; + SSkipListNode *pTemp = pNode; + pNode = SL_GET_FORWARD_POINTER(pNode, 0); tfree(pTemp); } - tfree(pSkipList->pHead.pForward); - pthread_rwlock_unlock(&pSkipList->lock); + tfree(pSkipList->pHead); - pthread_rwlock_destroy(&pSkipList->lock); + if (pSkipList->lock) { + pthread_rwlock_unlock(pSkipList->lock); + pthread_rwlock_destroy(pSkipList->lock); + + tfree(pSkipList->lock); + } + + tfree(pSkipList->pHead); tfree(pSkipList); - return NULL; } -tSkipListNode *tSkipListPut(tSkipList *pSkipList, void *pData, tSkipListKey *pKey, int32_t insertIdenticalKey) { +void tSkipListRandNodeInfo(SSkipList *pSkipList, int32_t *level, int32_t *headSize) { + if (pSkipList == NULL) { + return; + } + + *level = getSkipListRandLevel(pSkipList); + *headSize = SL_NODE_HEADER_SIZE(*level); +} + +SSkipListNode *tSkipListPut(SSkipList *pSkipList, SSkipListNode *pNode) { if (pSkipList == NULL) { return NULL; } - pthread_rwlock_wrlock(&pSkipList->lock); + if (pSkipList->lock) { + pthread_rwlock_wrlock(pSkipList->lock); + } // record one node is put into skiplist tSkipListDoRecordPut(pSkipList); - tSkipListNode *px = &pSkipList->pHead; + SSkipListNode *px = pSkipList->pHead; + SSkipListNode *forward[MAX_SKIP_LIST_LEVEL] = {0}; - tSkipListNode *forward[MAX_SKIP_LIST_LEVEL] = {0}; - for (int32_t i = pSkipList->nLevel - 1; i >= 0; --i) { - while (px->pForward[i] != NULL && (pSkipList->comparator(&px->pForward[i]->key, pKey) < 0)) { - px = px->pForward[i]; - } + for (int32_t i = pSkipList->level - 1; i >= 0; --i) { + SSkipListNode *p = SL_GET_FORWARD_POINTER(px, i); + while (p != NULL) { + char *key = SL_GET_NODE_KEY(pSkipList, p); + char *newDatakey = SL_GET_NODE_KEY(pSkipList, pNode); - pSkipList->state.nTotalStepsForInsert++; - forward[i] = px; - } + // if the forward element is less than the specified key, forward one step + if (pSkipList->comparFn(key, newDatakey) < 0) { + px = p; - // if the skiplist does not allowed identical key inserted, the new data will be discarded. - if ((insertIdenticalKey == 0) && forward[0] != &pSkipList->pHead && - (pSkipList->comparator(&forward[0]->key, pKey) == 0)) { - pthread_rwlock_unlock(&pSkipList->lock); - return forward[0]; - } - - int32_t nLevel = getSkipListNodeLevel(pSkipList); - recordNodeEachLevel(pSkipList, nLevel); - - tSkipListNode *pNode = tSkipListCreateNode(pData, pKey, nLevel); - tSkipListDoInsert(pSkipList, forward, nLevel, pNode); - - pSkipList->nSize += 1; - - // char tmpstr[512] = {0}; - // tVariantToString(&pNode->key, tmpstr); - // pTrace("skiplist:%p, node added, key:%s, total list len:%d", pSkipList, - // tmpstr, pSkipList->nSize); - - pSkipList->state.nTotalMemSize += getOneNodeSize(pKey, nLevel); - pthread_rwlock_unlock(&pSkipList->lock); - - return pNode; -} - -void tSkipListDoInsert(tSkipList *pSkipList, tSkipListNode **forward, int32_t nLevel, tSkipListNode *pNode) { - for (int32_t i = 0; i < nLevel; ++i) { - tSkipListNode *x = forward[i]; - if (x != NULL) { - pNode->pBackward[i] = x; - if (x->pForward[i]) x->pForward[i]->pBackward[i] = pNode; - - pNode->pForward[i] = x->pForward[i]; - x->pForward[i] = pNode; - } else { - pSkipList->pHead.pForward[i] = pNode; - pNode->pBackward[i] = &(pSkipList->pHead); - } - } -} - -tSkipListNode *tSkipListGetOne(tSkipList *pSkipList, tSkipListKey *pKey) { - int32_t sLevel = pSkipList->nLevel - 1; - int32_t ret = -1; - - tSkipListNode *x = &pSkipList->pHead; - - pthread_rwlock_rdlock(&pSkipList->lock); - pSkipList->state.queryCount++; - - __compar_fn_t filterComparator = getKeyFilterComparator(pSkipList, pKey->nType); - - for (int32_t i = sLevel; i >= 0; --i) { - while (x->pForward[i] != NULL && (ret = filterComparator(&x->pForward[i]->key, pKey)) < 0) { - x = x->pForward[i]; - } - - if (ret == 0) { - pthread_rwlock_unlock(&pSkipList->lock); - return x->pForward[i]; - } - } - - pthread_rwlock_unlock(&pSkipList->lock); - return NULL; -} - -static int32_t tSkipListEndParQuery(tSkipList *pSkipList, tSkipListNode *pStartNode, tSkipListKey *pEndKey, - int32_t cond, tSkipListNode ***pRes) { - pthread_rwlock_rdlock(&pSkipList->lock); - tSkipListNode *p = pStartNode; - int32_t numOfRes = 0; - - __compar_fn_t filterComparator = getKeyFilterComparator(pSkipList, pEndKey->nType); - while (p != NULL) { - int32_t ret = filterComparator(&p->key, pEndKey); - if (ret > 0) { - break; - } - - if (ret < 0) { - numOfRes++; - p = p->pForward[0]; - } else if (ret == 0) { - if (cond == TSDB_RELATION_LESS_EQUAL) { - numOfRes++; - p = p->pForward[0]; + p = SL_GET_FORWARD_POINTER(px, i); } else { break; } } + +#if SKIP_LIST_RECORD_PERFORMANCE + pSkipList->state.nTotalStepsForInsert++; +#endif + forward[i] = px; } - (*pRes) = (tSkipListNode **)malloc(POINTER_BYTES * numOfRes); - for (int32_t i = 0; i < numOfRes; ++i) { - (*pRes)[i] = pStartNode; - pStartNode = pStartNode->pForward[0]; - } - pthread_rwlock_unlock(&pSkipList->lock); + // if the skip list does not allowed identical key inserted, the new data will be discarded. + if (pSkipList->keyInfo.dupKey == 0 && forward[0] != pSkipList->pHead) { + char *key = SL_GET_NODE_KEY(pSkipList, forward[0]); + char *pNewDataKey = SL_GET_NODE_KEY(pSkipList, pNode); - return numOfRes; + if (pSkipList->comparFn(key, pNewDataKey) == 0) { + if (pSkipList->lock) { + pthread_rwlock_unlock(pSkipList->lock); + } + + return forward[0]; + } + } + +#if SKIP_LIST_RECORD_PERFORMANCE + recordNodeEachLevel(pSkipList, level); +#endif + + int32_t level = SL_GET_NODE_LEVEL(pNode); + tSkipListDoInsert(pSkipList, forward, level, pNode); + + atomic_add_fetch_32(&pSkipList->size, 1); + +#if SKIP_LIST_RECORD_PERFORMANCE + pSkipList->state.nTotalMemSize += getOneNodeSize(pKey, level); +#endif + + if (pSkipList->lock) { + pthread_rwlock_unlock(pSkipList->lock); + } + + return pNode; } -/* - * maybe return the copy of tSkipListNode would be better - */ -int32_t tSkipListGets(tSkipList *pSkipList, tSkipListKey *pKey, tSkipListNode ***pRes) { - (*pRes) = NULL; +void tSkipListDoInsert(SSkipList *pSkipList, SSkipListNode **forward, int32_t level, SSkipListNode *pNode) { + for (int32_t i = 0; i < level; ++i) { + SSkipListNode *x = forward[i]; + if (x != NULL) { + SL_GET_BACKWARD_POINTER(pNode, i) = x; - tSkipListNode *pNode = tSkipListGetOne(pSkipList, pKey); - if (pNode == NULL) { - return 0; + SSkipListNode *pForward = SL_GET_FORWARD_POINTER(x, i); + if (pForward) { + SL_GET_BACKWARD_POINTER(pForward, i) = pNode; + } + + SL_GET_FORWARD_POINTER(pNode, i) = SL_GET_FORWARD_POINTER(x, i); + SL_GET_FORWARD_POINTER(x, i) = pNode; + } else { + SL_GET_FORWARD_POINTER(pSkipList->pHead, i) = pNode; + SL_GET_BACKWARD_POINTER(pSkipList->pHead, i) = (pSkipList->pHead); + } } - - __compar_fn_t filterComparator = getKeyFilterComparator(pSkipList, pKey->nType); - - // backward check if previous nodes are with the same value. - tSkipListNode *pPrev = pNode->pBackward[0]; - while ((pPrev != &pSkipList->pHead) && filterComparator(&pPrev->key, pKey) == 0) { - pPrev = pPrev->pBackward[0]; - } - - return tSkipListEndParQuery(pSkipList, pPrev->pForward[0], &pNode->key, TSDB_RELATION_LESS_EQUAL, pRes); } -static tSkipListNode *tSkipListParQuery(tSkipList *pSkipList, tSkipListKey *pKey, int32_t cond) { - int32_t sLevel = pSkipList->nLevel - 1; +SArray* tSkipListGet(SSkipList *pSkipList, SSkipListKey pKey, int16_t keyType) { + int32_t sLevel = pSkipList->level - 1; int32_t ret = -1; - tSkipListNode *x = &pSkipList->pHead; - __compar_fn_t filterComparator = getKeyFilterComparator(pSkipList, pKey->nType); - - pthread_rwlock_rdlock(&pSkipList->lock); - - if (cond == TSDB_RELATION_LARGE_EQUAL || cond == TSDB_RELATION_LARGE) { - for (int32_t i = sLevel; i >= 0; --i) { - while (x->pForward[i] != NULL && (ret = filterComparator(&x->pForward[i]->key, pKey)) < 0) { - x = x->pForward[i]; - } - } - - // backward check if previous nodes are with the same value. - if (cond == TSDB_RELATION_LARGE_EQUAL && ret == 0) { - tSkipListNode *pNode = x->pForward[0]; - while ((pNode->pBackward[0] != &pSkipList->pHead) && (filterComparator(&pNode->pBackward[0]->key, pKey) == 0)) { - pNode = pNode->pBackward[0]; - } - pthread_rwlock_unlock(&pSkipList->lock); - return pNode; - } - - if (ret > 0 || cond == TSDB_RELATION_LARGE_EQUAL) { - pthread_rwlock_unlock(&pSkipList->lock); - return x->pForward[0]; - } else { // cond == TSDB_RELATION_LARGE && ret == 0 - tSkipListNode *pn = x->pForward[0]; - while (pn != NULL && filterComparator(&pn->key, pKey) == 0) { - pn = pn->pForward[0]; - } - pthread_rwlock_unlock(&pSkipList->lock); - return pn; - } - } - - pthread_rwlock_unlock(&pSkipList->lock); - return NULL; -} - -int32_t tSkipListIterateList(tSkipList *pSkipList, tSkipListNode ***pRes, bool (*fp)(tSkipListNode *, void *), - void *param) { - (*pRes) = (tSkipListNode **)calloc(1, POINTER_BYTES * pSkipList->nSize); - if (NULL == *pRes) { - pError("error skiplist %p, malloc failed", pSkipList); - return -1; - } + // result list + SArray* sa = taosArrayInit(1, POINTER_BYTES); - pthread_rwlock_rdlock(&pSkipList->lock); - tSkipListNode *pStartNode = pSkipList->pHead.pForward[0]; - int32_t num = 0; - - for (int32_t i = 0; i < pSkipList->nSize; ++i) { - if (pStartNode == NULL) { - pError("error skiplist %p, required length:%d, actual length:%d", pSkipList, pSkipList->nSize, i - 1); -#ifdef _DEBUG_VIEW - tSkipListPrint(pSkipList, 1); -#endif - break; - } - - if (fp == NULL || (fp != NULL && fp(pStartNode, param) == true)) { - (*pRes)[num++] = pStartNode; - } - - pStartNode = pStartNode->pForward[0]; + SSkipListNode *pNode = pSkipList->pHead; + + if (pSkipList->lock) { + pthread_rwlock_rdlock(pSkipList->lock); } - pthread_rwlock_unlock(&pSkipList->lock); - - if (num == 0) { - free(*pRes); - *pRes = NULL; - } else if (num < pSkipList->nSize) { // free unused memory - char* tmp = realloc((*pRes), num * POINTER_BYTES); - assert(tmp != NULL); - - *pRes = (tSkipListNode**)tmp; - } - - return num; -} - -int32_t tSkipListIteratorReset(tSkipList *pSkipList, SSkipListIterator* iter) { - if (pSkipList == NULL) { - return -1; - } - - iter->pSkipList = pSkipList; - - pthread_rwlock_rdlock(&pSkipList->lock); - iter->cur = NULL;//pSkipList->pHead.pForward[0]; - iter->num = pSkipList->nSize; - pthread_rwlock_unlock(&pSkipList->lock); - - return 0; -} - -bool tSkipListIteratorNext(SSkipListIterator* iter) { - if (iter->num == 0 || iter->pSkipList == NULL) { - return false; - } - - tSkipList* pSkipList = iter->pSkipList; - - pthread_rwlock_rdlock(&pSkipList->lock); - if (iter->cur == NULL) { - iter->cur = pSkipList->pHead.pForward[0]; - } else { - iter->cur = iter->cur->pForward[0]; - } - - pthread_rwlock_unlock(&pSkipList->lock); - - return iter->cur != NULL; -} - -tSkipListNode* tSkipListIteratorGet(SSkipListIterator* iter) { - return iter->cur; -} - -int32_t tSkipListRangeQuery(tSkipList *pSkipList, tSKipListQueryCond *pCond, tSkipListNode ***pRes) { +#if SKIP_LIST_RECORD_PERFORMANCE pSkipList->state.queryCount++; - tSkipListNode *pStart = tSkipListParQuery(pSkipList, &pCond->lowerBnd, pCond->lowerBndRelOptr); - if (pStart == 0) { - *pRes = NULL; - return 0; - } +#endif - return tSkipListEndParQuery(pSkipList, pStart, &pCond->upperBnd, pCond->upperBndRelOptr, pRes); -} + __compar_fn_t filterComparFn = getKeyFilterComparator(pSkipList, keyType); -static bool removeSupport(tSkipList *pSkipList, tSkipListNode **forward, tSkipListKey *pKey) { - __compar_fn_t filterComparator = getKeyFilterComparator(pSkipList, pKey->nType); - - if (filterComparator(&forward[0]->pForward[0]->key, pKey) == 0) { - tSkipListNode *p = forward[0]->pForward[0]; - doRemove(pSkipList, p, forward); - } else { // failed to find the node of specified value,abort - return false; - } - - // compress the minimum level of skip list - while (pSkipList->nLevel > 0 && pSkipList->pHead.pForward[pSkipList->nLevel - 1] == NULL) { - pSkipList->nLevel -= 1; - } - - return true; -} - -void tSkipListRemoveNode(tSkipList *pSkipList, tSkipListNode *pNode) { - tSkipListNode *forward[MAX_SKIP_LIST_LEVEL] = {0}; - - pthread_rwlock_rdlock(&pSkipList->lock); - for (int32_t i = 0; i < pNode->nLevel; ++i) { - forward[i] = pNode->pBackward[i]; - } - - removeSupport(pSkipList, forward, &pNode->key); - pthread_rwlock_unlock(&pSkipList->lock); -} - -bool tSkipListRemove(tSkipList *pSkipList, tSkipListKey *pKey) { - tSkipListNode *forward[MAX_SKIP_LIST_LEVEL] = {0}; - __compar_fn_t filterComparator = getKeyFilterComparator(pSkipList, pKey->nType); - - pthread_rwlock_rdlock(&pSkipList->lock); - - tSkipListNode *x = &pSkipList->pHead; - for (int32_t i = pSkipList->nLevel - 1; i >= 0; --i) { - while (x->pForward[i] != NULL && (filterComparator(&x->pForward[i]->key, pKey) < 0)) { - x = x->pForward[i]; + for (int32_t i = sLevel; i >= 0; --i) { + SSkipListNode *pNext = SL_GET_FORWARD_POINTER(pNode, i); + while (pNext != NULL) { + char *key = SL_GET_NODE_KEY(pSkipList, pNext); + if ((ret = filterComparFn(key, pKey)) < 0) { + pNode = pNext; + pNext = SL_GET_FORWARD_POINTER(pNext, i); + } else { + break; + } + } + + // find the qualified key + if (ret == 0) { + if (pSkipList->lock) { + pthread_rwlock_unlock(pSkipList->lock); + } + + SSkipListNode* pResult = SL_GET_FORWARD_POINTER(pNode, i); + taosArrayPush(sa, &pResult); + + // skip list does not allowed duplicated key, abort further retrieve data + if (!pSkipList->keyInfo.dupKey) { + break; + } } - forward[i] = x; } - bool ret = removeSupport(pSkipList, forward, pKey); - pthread_rwlock_unlock(&pSkipList->lock); + if (pSkipList->lock) { + pthread_rwlock_unlock(pSkipList->lock); + } - return ret; + return sa; } -void tSkipListPrint(tSkipList *pSkipList, int16_t nlevel) { - if (pSkipList == NULL || pSkipList->nLevel < nlevel || nlevel <= 0) { +// static int32_t tSkipListEndParQuery(SSkipList *pSkipList, SSkipListNode *pStartNode, SSkipListKey *pEndKey, +// int32_t cond, SSkipListNode ***pRes) { +// pthread_rwlock_rdlock(&pSkipList->lock); +// SSkipListNode *p = pStartNode; +// int32_t numOfRes = 0; +// +// __compar_fn_t filterComparFn = getKeyFilterComparator(pSkipList, pEndKey->nType); +// while (p != NULL) { +// int32_t ret = filterComparFn(&p->key, pEndKey); +// if (ret > 0) { +// break; +// } +// +// if (ret < 0) { +// numOfRes++; +// p = p->pForward[0]; +// } else if (ret == 0) { +// if (cond == TSDB_RELATION_LESS_EQUAL) { +// numOfRes++; +// p = p->pForward[0]; +// } else { +// break; +// } +// } +// } +// +// (*pRes) = (SSkipListNode **)malloc(POINTER_BYTES * numOfRes); +// for (int32_t i = 0; i < numOfRes; ++i) { +// (*pRes)[i] = pStartNode; +// pStartNode = pStartNode->pForward[0]; +// } +// pthread_rwlock_unlock(&pSkipList->lock); +// +// return numOfRes; +//} +// +///* +// * maybe return the copy of SSkipListNode would be better +// */ +// int32_t tSkipListGets(SSkipList *pSkipList, SSkipListKey *pKey, SSkipListNode ***pRes) { +// (*pRes) = NULL; +// +// SSkipListNode *pNode = tSkipListGet(pSkipList, pKey); +// if (pNode == NULL) { +// return 0; +// } +// +// __compar_fn_t filterComparFn = getKeyFilterComparator(pSkipList, pKey->nType); +// +// // backward check if previous nodes are with the same value. +// SSkipListNode *pPrev = pNode->pBackward[0]; +// while ((pPrev != &pSkipList->pHead) && filterComparFn(&pPrev->key, pKey) == 0) { +// pPrev = pPrev->pBackward[0]; +// } +// +// return tSkipListEndParQuery(pSkipList, pPrev->pForward[0], &pNode->key, TSDB_RELATION_LESS_EQUAL, pRes); +//} +// +// static SSkipListNode *tSkipListParQuery(SSkipList *pSkipList, SSkipListKey *pKey, int32_t cond) { +// int32_t sLevel = pSkipList->level - 1; +// int32_t ret = -1; +// +// SSkipListNode *x = &pSkipList->pHead; +// __compar_fn_t filterComparFn = getKeyFilterComparator(pSkipList, pKey->nType); +// +// pthread_rwlock_rdlock(&pSkipList->lock); +// +// if (cond == TSDB_RELATION_LARGE_EQUAL || cond == TSDB_RELATION_LARGE) { +// for (int32_t i = sLevel; i >= 0; --i) { +// while (x->pForward[i] != NULL && (ret = filterComparFn(&x->pForward[i]->key, pKey)) < 0) { +// x = x->pForward[i]; +// } +// } +// +// // backward check if previous nodes are with the same value. +// if (cond == TSDB_RELATION_LARGE_EQUAL && ret == 0) { +// SSkipListNode *pNode = x->pForward[0]; +// while ((pNode->pBackward[0] != &pSkipList->pHead) && (filterComparFn(&pNode->pBackward[0]->key, pKey) == 0)) { +// pNode = pNode->pBackward[0]; +// } +// pthread_rwlock_unlock(&pSkipList->lock); +// return pNode; +// } +// +// if (ret > 0 || cond == TSDB_RELATION_LARGE_EQUAL) { +// pthread_rwlock_unlock(&pSkipList->lock); +// return x->pForward[0]; +// } else { // cond == TSDB_RELATION_LARGE && ret == 0 +// SSkipListNode *pn = x->pForward[0]; +// while (pn != NULL && filterComparFn(&pn->key, pKey) == 0) { +// pn = pn->pForward[0]; +// } +// pthread_rwlock_unlock(&pSkipList->lock); +// return pn; +// } +// } +// +// pthread_rwlock_unlock(&pSkipList->lock); +// return NULL; +//} +// +// int32_t tSkipListIterateList(SSkipList *pSkipList, SSkipListNode ***pRes, bool (*fp)(SSkipListNode *, void *), +// void *param) { +// (*pRes) = (SSkipListNode **)calloc(1, POINTER_BYTES * pSkipList->nSize); +// if (NULL == *pRes) { +// pError("error skiplist %p, malloc failed", pSkipList); +// return -1; +// } +// +// pthread_rwlock_rdlock(&pSkipList->lock); +// SSkipListNode *pStartNode = pSkipList->pHead.pForward[0]; +// int32_t num = 0; +// +// for (int32_t i = 0; i < pSkipList->nSize; ++i) { +// if (pStartNode == NULL) { +// pError("error skiplist %p, required length:%d, actual length:%d", pSkipList, pSkipList->nSize, i - 1); +//#ifdef _DEBUG_VIEW +// tSkipListPrint(pSkipList, 1); +//#endif +// break; +// } +// +// if (fp == NULL || (fp != NULL && fp(pStartNode, param) == true)) { +// (*pRes)[num++] = pStartNode; +// } +// +// pStartNode = pStartNode->pForward[0]; +// } +// +// pthread_rwlock_unlock(&pSkipList->lock); +// +// if (num == 0) { +// free(*pRes); +// *pRes = NULL; +// } else if (num < pSkipList->nSize) { // free unused memory +// char *tmp = realloc((*pRes), num * POINTER_BYTES); +// assert(tmp != NULL); +// +// *pRes = (SSkipListNode **)tmp; +// } +// +// return num; +//} +// +// int32_t tSkipListIteratorReset(SSkipList *pSkipList, SSkipListIterator *iter) { +// if (pSkipList == NULL) { +// return -1; +// } +// +// iter->pSkipList = pSkipList; +// if (pSkipList->lock) { +// pthread_rwlock_rdlock(&pSkipList->lock); +// } +// iter->cur = NULL; // pSkipList->pHead.pForward[0]; +// iter->num = pSkipList->size; +// +// if (pSkipList->lock) { +// pthread_rwlock_unlock(&pSkipList->lock); +// } +// +// return 0; +//} +// +// bool tSkipListIteratorNext(SSkipListIterator *iter) { +// if (iter->num == 0 || iter->pSkipList == NULL) { +// return false; +// } +// +// SSkipList *pSkipList = iter->pSkipList; +// +// pthread_rwlock_rdlock(&pSkipList->lock); +// if (iter->cur == NULL) { +// iter->cur = pSkipList->pHead.pForward[0]; +// } else { +// iter->cur = iter->cur->pForward[0]; +// } +// +// pthread_rwlock_unlock(&pSkipList->lock); +// +// return iter->cur != NULL; +//} +// +// SSkipListNode *tSkipListIteratorGet(SSkipListIterator *iter) { return iter->cur; } +// +// int32_t tSkipListRangeQuery(SSkipList *pSkipList, tSKipListQueryCond *pCond, SSkipListNode ***pRes) { +// pSkipList->state.queryCount++; +// SSkipListNode *pStart = tSkipListParQuery(pSkipList, &pCond->lowerBnd, pCond->lowerBndRelOptr); +// if (pStart == 0) { +// *pRes = NULL; +// return 0; +// } +// +// return tSkipListEndParQuery(pSkipList, pStart, &pCond->upperBnd, pCond->upperBndRelOptr, pRes); +//} +// +// static bool removeSupport(SSkipList *pSkipList, SSkipListNode **forward, SSkipListKey *pKey) { +// __compar_fn_t filterComparFn = getKeyFilterComparator(pSkipList, pKey->nType); +// +// if (filterComparFn(&forward[0]->pForward[0]->key, pKey) == 0) { +// SSkipListNode *p = forward[0]->pForward[0]; +// doRemove(pSkipList, p, forward); +// } else { // failed to find the node of specified value,abort +// return false; +// } +// +// // compress the minimum level of skip list +// while (pSkipList->level > 0 && pSkipList->pHead.pForward[pSkipList->level - 1] == NULL) { +// pSkipList->level -= 1; +// } +// +// return true; +//} +// +// void tSkipListRemoveNode(SSkipList *pSkipList, SSkipListNode *pNode) { +// SSkipListNode *forward[MAX_SKIP_LIST_LEVEL] = {0}; +// +// pthread_rwlock_rdlock(&pSkipList->lock); +// for (int32_t i = 0; i < pNode->level; ++i) { +// forward[i] = pNode->pBackward[i]; +// } +// +// removeSupport(pSkipList, forward, &pNode->key); +// pthread_rwlock_unlock(&pSkipList->lock); +//} +// +// bool tSkipListRemove(SSkipList *pSkipList, SSkipListKey *pKey) { +// SSkipListNode *forward[MAX_SKIP_LIST_LEVEL] = {0}; +// __compar_fn_t filterComparFn = getKeyFilterComparator(pSkipList, pKey->nType); +// +// pthread_rwlock_rdlock(&pSkipList->lock); +// +// SSkipListNode *x = &pSkipList->pHead; +// for (int32_t i = pSkipList->level - 1; i >= 0; --i) { +// while (x->pForward[i] != NULL && (filterComparFn(&x->pForward[i]->key, pKey) < 0)) { +// x = x->pForward[i]; +// } +// forward[i] = x; +// } +// +// bool ret = removeSupport(pSkipList, forward, pKey); +// pthread_rwlock_unlock(&pSkipList->lock); +// +// return ret; +//} + +void tSkipListPrint(SSkipList *pSkipList, int16_t nlevel) { + if (pSkipList == NULL || pSkipList->level < nlevel || nlevel <= 0) { return; } - tSkipListNode *p = pSkipList->pHead.pForward[nlevel - 1]; + SSkipListNode *p = SL_GET_FORWARD_POINTER(pSkipList->pHead, nlevel - 1); int32_t id = 1; + while (p) { - switch (pSkipList->keyType) { + char *key = SL_GET_NODE_KEY(pSkipList, p); + switch (pSkipList->keyInfo.type) { case TSDB_DATA_TYPE_INT: case TSDB_DATA_TYPE_SMALLINT: case TSDB_DATA_TYPE_TINYINT: case TSDB_DATA_TYPE_BIGINT: - fprintf(stdout, "%d: %" PRId64 " \n", id++, p->key.i64Key); + fprintf(stdout, "%d: %" PRId64 " \n", id++, *(int64_t *)key); break; case TSDB_DATA_TYPE_BINARY: - fprintf(stdout, "%d: %s \n", id++, p->key.pz); + fprintf(stdout, "%d: %s \n", id++, key); break; case TSDB_DATA_TYPE_DOUBLE: - fprintf(stdout, "%d: %lf \n", id++, p->key.dKey); + fprintf(stdout, "%d: %lf \n", id++, *(double *)key); break; default: fprintf(stdout, "\n"); } - p = p->pForward[nlevel - 1]; - } -} - -/* - * query processor based on query condition - */ -int32_t tSkipListQuery(tSkipList *pSkipList, tSKipListQueryCond *pQueryCond, tSkipListNode ***pResult) { - // query condition check - int32_t rel = 0; - __compar_fn_t comparator = getKeyComparator(pQueryCond->lowerBnd.nType); - - if (pSkipList == NULL || pQueryCond == NULL || pSkipList->nSize == 0 || - (((rel = comparator(&pQueryCond->lowerBnd, &pQueryCond->upperBnd)) > 0 && - pQueryCond->lowerBnd.nType != TSDB_DATA_TYPE_NCHAR && pQueryCond->lowerBnd.nType != TSDB_DATA_TYPE_BINARY))) { - (*pResult) = NULL; - return 0; - } - - if (rel == 0) { - /* - * 0 means: pQueryCond->lowerBnd == pQueryCond->upperBnd - * point query - */ - if (pQueryCond->lowerBndRelOptr == TSDB_RELATION_LARGE_EQUAL && - pQueryCond->upperBndRelOptr == TSDB_RELATION_LESS_EQUAL) { // point query - return tSkipListGets(pSkipList, &pQueryCond->lowerBnd, pResult); - } else { - (*pResult) = NULL; - return 0; - } - } else { - /* range query, query operation code check */ - return tSkipListRangeQuery(pSkipList, pQueryCond, pResult); - } -} - -typedef struct MultipleQueryResult { - int32_t len; - tSkipListNode **pData; -} MultipleQueryResult; - -static int32_t mergeQueryResult(MultipleQueryResult *pResults, int32_t numOfResSet, tSkipListNode ***pRes) { - int32_t total = 0; - for (int32_t i = 0; i < numOfResSet; ++i) { - total += pResults[i].len; - } - - (*pRes) = malloc(POINTER_BYTES * total); - int32_t idx = 0; - - for (int32_t i = 0; i < numOfResSet; ++i) { - MultipleQueryResult *pOneResult = &pResults[i]; - for (int32_t j = 0; j < pOneResult->len; ++j) { - (*pRes)[idx++] = pOneResult->pData[j]; - } - } - - return total; -} - -static void removeDuplicateKey(tSkipListKey *pKey, int32_t *numOfKey, __compar_fn_t comparator) { - if (*numOfKey == 1) { - return; - } - - qsort(pKey, *numOfKey, sizeof(pKey[0]), comparator); - int32_t i = 0, j = 1; - - while (i < (*numOfKey) && j < (*numOfKey)) { - int32_t ret = comparator(&pKey[i], &pKey[j]); - if (ret == 0) { - j++; - } else { - pKey[i + 1] = pKey[j]; - i++; - j++; - } - } - - (*numOfKey) = i + 1; -} - -int32_t mergeResult(const tSkipListKey *pKey, int32_t numOfKey, tSkipListNode ***pRes, __compar_fn_t comparator, - tSkipListNode *pNode) { - int32_t i = 0, j = 0; - // merge two sorted arrays in O(n) time - while (i < numOfKey && pNode != NULL) { - int32_t ret = comparator(&pNode->key, &pKey[i]); - if (ret < 0) { - (*pRes)[j++] = pNode; - pNode = pNode->pForward[0]; - } else if (ret == 0) { - pNode = pNode->pForward[0]; - } else { // pNode->key > pkey[i] - i++; - } - } - - while (pNode != NULL) { - (*pRes)[j++] = pNode; - pNode = pNode->pForward[0]; - } - return j; -} - -int32_t tSkipListPointQuery(tSkipList *pSkipList, tSkipListKey *pKey, int32_t numOfKey, tSkipListPointQueryType type, - tSkipListNode ***pRes) { - if (numOfKey == 0 || pKey == NULL || pSkipList == NULL || pSkipList->nSize == 0 || - (type != INCLUDE_POINT_QUERY && type != EXCLUDE_POINT_QUERY)) { - (*pRes) = NULL; - return 0; - } - - __compar_fn_t comparator = getKeyComparator(pKey->nType); - removeDuplicateKey(pKey, &numOfKey, comparator); - - if (type == INCLUDE_POINT_QUERY) { - if (numOfKey == 1) { - return tSkipListGets(pSkipList, &pKey[0], pRes); - } else { - MultipleQueryResult *pTempResult = (MultipleQueryResult *)malloc(sizeof(MultipleQueryResult) * numOfKey); - for (int32_t i = 0; i < numOfKey; ++i) { - pTempResult[i].len = tSkipListGets(pSkipList, &pKey[i], &pTempResult[i].pData); - } - int32_t num = mergeQueryResult(pTempResult, numOfKey, pRes); - - for (int32_t i = 0; i < numOfKey; ++i) { - free(pTempResult[i].pData); - } - free(pTempResult); - return num; - } - } else { // exclude query - *pRes = malloc(POINTER_BYTES * pSkipList->nSize); - - __compar_fn_t filterComparator = getKeyFilterComparator(pSkipList, pKey->nType); - - tSkipListNode *pNode = pSkipList->pHead.pForward[0]; - int32_t retLen = mergeResult(pKey, numOfKey, pRes, filterComparator, pNode); - - if (retLen < pSkipList->nSize) { - (*pRes) = realloc(*pRes, POINTER_BYTES * retLen); - } - return retLen; + + p = SL_GET_FORWARD_POINTER(p, nlevel - 1); + // p = p->pForward[nlevel - 1]; } } From 9fa0685bbf43edc137476c575d0b11c0f8f1e438 Mon Sep 17 00:00:00 2001 From: hzcheng Date: Wed, 4 Mar 2020 06:20:26 +0000 Subject: [PATCH 16/16] correct some error --- src/CMakeLists.txt | 12 ++++++------ src/vnode/tests/tsdb/tsdbTests.cpp | 1 + src/vnode/tsdb/inc/tsdbFile.h | 8 ++------ src/vnode/tsdb/src/tsdbFileStore.c | 18 ++++++++++++++++-- src/vnode/tsdb/src/tsdbMain.c | 2 +- src/vnode/tsdb/src/tsdbMeta.c | 4 ++-- 6 files changed, 28 insertions(+), 17 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 34768b00df..91670d3e7a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -4,11 +4,11 @@ PROJECT(TDengine) ADD_SUBDIRECTORY(os) ADD_SUBDIRECTORY(util) ADD_SUBDIRECTORY(rpc) -ADD_SUBDIRECTORY(client) -ADD_SUBDIRECTORY(kit) -ADD_SUBDIRECTORY(plugins) -ADD_SUBDIRECTORY(sdb) -ADD_SUBDIRECTORY(mnode) +# ADD_SUBDIRECTORY(client) +# ADD_SUBDIRECTORY(kit) +# ADD_SUBDIRECTORY(plugins) +# ADD_SUBDIRECTORY(sdb) +# ADD_SUBDIRECTORY(mnode) ADD_SUBDIRECTORY(vnode) -ADD_SUBDIRECTORY(dnode) +# ADD_SUBDIRECTORY(dnode) #ADD_SUBDIRECTORY(connector/jdbc) diff --git a/src/vnode/tests/tsdb/tsdbTests.cpp b/src/vnode/tests/tsdb/tsdbTests.cpp index 8e1b37b191..3e7a7cca5f 100644 --- a/src/vnode/tests/tsdb/tsdbTests.cpp +++ b/src/vnode/tests/tsdb/tsdbTests.cpp @@ -10,6 +10,7 @@ TEST(TsdbTest, createTsdbRepo) { config.tsdbId = 0; config.maxTables = 100; config.daysPerFile = 10; + config.keep = 3650; config.minRowsPerFileBlock = 100; config.maxRowsPerFileBlock = 4096; config.maxCacheSize = 4 * 1024 * 1024; diff --git a/src/vnode/tsdb/inc/tsdbFile.h b/src/vnode/tsdb/inc/tsdbFile.h index 39d1b0b3c2..dbcec49651 100644 --- a/src/vnode/tsdb/inc/tsdbFile.h +++ b/src/vnode/tsdb/inc/tsdbFile.h @@ -32,12 +32,6 @@ typedef enum { } TSDB_FILE_TYPE; extern const char *tsdbFileSuffix[]; -// const char *tsdbFileSuffix[] = { -// ".head", // TSDB_FILE_TYPE_HEAD -// ".data", // TSDB_FILE_TYPE_DATA -// ".last", // TSDB_FILE_TYPE_LAST -// ".meta" // TSDB_FILE_TYPE_META -// }; typedef struct { int64_t fileSize; @@ -55,6 +49,8 @@ typedef struct { // int16_t numOfBlocks; // } SDataBlock; +#define IS_VALID_TSDB_FILE_TYPE(type) ((type) >= TSDB_FILE_TYPE_HEAD && (type) <= TSDB_FILE_TYPE_META) + char *tsdbGetFileName(char *dirName, char *fname, TSDB_FILE_TYPE type); #ifdef __cplusplus diff --git a/src/vnode/tsdb/src/tsdbFileStore.c b/src/vnode/tsdb/src/tsdbFileStore.c index 79e6e6170a..5c0702e296 100644 --- a/src/vnode/tsdb/src/tsdbFileStore.c +++ b/src/vnode/tsdb/src/tsdbFileStore.c @@ -1,8 +1,22 @@ +#include #include +#include #include "tsdbFile.h" +const char *tsdbFileSuffix[] = { + ".head", // TSDB_FILE_TYPE_HEAD + ".data", // TSDB_FILE_TYPE_DATA + ".last", // TSDB_FILE_TYPE_LAST + ".meta" // TSDB_FILE_TYPE_META +}; + char *tsdbGetFileName(char *dirName, char *fname, TSDB_FILE_TYPE type) { - // TODO - return NULL; + if (!IS_VALID_TSDB_FILE_TYPE(type)) return NULL; + + char *fileName = (char *)malloc(strlen(dirName) + strlen(fname) + strlen(tsdbFileSuffix[type]) + 5); + if (fileName == NULL) return NULL; + + sprintf(fileName, "%s/%s%s", dirName, fname, tsdbFileSuffix[type]); + return fileName; } \ No newline at end of file diff --git a/src/vnode/tsdb/src/tsdbMain.c b/src/vnode/tsdb/src/tsdbMain.c index f1a0701669..cf217f0771 100644 --- a/src/vnode/tsdb/src/tsdbMain.c +++ b/src/vnode/tsdb/src/tsdbMain.c @@ -241,7 +241,7 @@ static int32_t tsdbSetRepoEnv(STsdbRepo *pRepo) { return -1; } - sprintf(dirName, "%s/%s", pRepo->rootDir, dirName); + sprintf(dirName, "%s/%s", pRepo->rootDir, "tsdb"); if (mkdir(dirName, 0755) < 0) { free(dirName); return -1; diff --git a/src/vnode/tsdb/src/tsdbMeta.c b/src/vnode/tsdb/src/tsdbMeta.c index eb348fafae..76801b1ddc 100644 --- a/src/vnode/tsdb/src/tsdbMeta.c +++ b/src/vnode/tsdb/src/tsdbMeta.c @@ -90,7 +90,7 @@ int32_t tsdbCreateTableImpl(STsdbMeta *pMeta, STableCfg *pCfg) { pSTable->stableUid = -1; pSTable->numOfCols = pCfg->numOfCols; pSTable->pSchema = tdDupSchema(pCfg->schema); - pSTable->content.pIndex = tSkipListCreate(5, 0, 10); // TODO: change here + // pSTable->content.pIndex = tSkipListCreate(5, 0, 10); // TODO: change here tsdbAddTable(pMeta, pSTable); } else { if (pSTable->type != TSDB_SUPER_TABLE) return NULL; @@ -113,7 +113,7 @@ int32_t tsdbCreateTableImpl(STsdbMeta *pMeta, STableCfg *pCfg) { pTable->stableUid = -1; pTable->pSchema = tdDupSchema(pCfg->schema); } - pTable->content.pData = tSkipListCreate(5, 0, 10); // TODO: change here + // pTable->content.pData = tSkipListCreate(5, 0, 10); // TODO: change here tsdbAddTable(pMeta, pTable);