From 05f06e04c1403a2e8889cfc8795ddb5a1507d2d2 Mon Sep 17 00:00:00 2001 From: Hongze Cheng Date: Mon, 2 May 2022 15:17:43 +0000 Subject: [PATCH] refact sl --- include/util/tskiplist2.h | 159 +++++++++++++++++++++++++++++++ source/libs/tdb/test/tdbTest.cpp | 4 +- source/util/src/tskiplist2.c | 139 +++++++++++++++++++++++++++ 3 files changed, 301 insertions(+), 1 deletion(-) create mode 100644 include/util/tskiplist2.h create mode 100644 source/util/src/tskiplist2.c diff --git a/include/util/tskiplist2.h b/include/util/tskiplist2.h new file mode 100644 index 0000000000..ce44ff96eb --- /dev/null +++ b/include/util/tskiplist2.h @@ -0,0 +1,159 @@ +/* + * 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 _TD_UTIL_SKIPLIST2_H_ +#define _TD_UTIL_SKIPLIST2_H_ + +#include "os.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define SL_MAX_LEVEL 15 + +typedef struct SSkipList2 SSkipList2; +typedef struct SSLCursor SSLCursor; +typedef struct SSLCfg SSLCfg; + +typedef int32_t (*tslCmprFn)(const void *pKey1, int32_t nKey1, const void *pKey2, int32_t nKey2); + +// SSkipList2 +int32_t slOpen(const SSLCfg *pCfg, SSkipList2 **ppSl); +int32_t slClose(SSkipList2 *pSl); + +// SSLCursor +int32_t slcOpen(SSkipList2 *pSl, SSLCursor *pSlc); +int32_t slcClose(SSLCursor *pSlc); +int32_t slcMoveTo(SSLCursor *pSlc, const void *pKey, int32_t nKey); +int32_t slcMoveToNext(SSLCursor *pSlc); +int32_t slcMoveToPrev(SSLCursor *pSlc); +int32_t slcMoveToFirst(SSLCursor *pSlc); +int32_t slcMoveToLast(SSLCursor *pSlc); +int32_t slcPut(SSLCursor *pSlc, const void *pKey, int32_t nKey, const void *pData, int32_t nData); +int32_t slcGet(SSLCursor *pSlc, const void **ppKey, int32_t *nKey, const void **ppData, int32_t *nData); +int32_t slcDrop(SSLCursor *pSlc); + +// struct +struct SSLCfg { + int8_t maxLevel; + int32_t nKey; + int32_t nData; + tslCmprFn cmprFn; + void *pPool; + void *(*xMalloc)(void *, int32_t size); + void (*xFree)(void *, void *); +}; + +#ifdef __cplusplus +} +#endif + +#endif /*_TD_UTIL_SKIPLIST2_H_*/ + +#if 0 +#ifndef _TD_UTIL_SKILIST_H +#define _TD_UTIL_SKILIST_H + +#include "os.h" +#include "taos.h" +#include "tarray.h" +#include "tfunctional.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MAX_SKIP_LIST_LEVEL 15 +#define SKIP_LIST_RECORD_PERFORMANCE 0 + +// For key property setting +#define SL_ALLOW_DUP_KEY (uint8_t)0x0 // Allow duplicate key exists (for tag index usage) +#define SL_DISCARD_DUP_KEY (uint8_t)0x1 // Discard duplicate key (for data update=0 case) +#define SL_UPDATE_DUP_KEY (uint8_t)0x2 // Update duplicate key by remove/insert (for data update!=0 case) + +// For thread safety setting +#define SL_THREAD_SAFE (uint8_t)0x4 + +typedef char *SSkipListKey; +typedef char *(*__sl_key_fn_t)(const void *); + +typedef void (*sl_patch_row_fn_t)(void *pDst, const void *pSrc); +typedef void *(*iter_next_fn_t)(void *iter); + +typedef struct SSkipListNode { + uint8_t level; + void *pData; + struct SSkipListNode *forwards[]; +} SSkipListNode; + +#define SL_GET_NODE_DATA(n) (n)->pData +#define SL_NODE_GET_FORWARD_POINTER(n, l) (n)->forwards[(l)] +#define SL_NODE_GET_BACKWARD_POINTER(n, l) (n)->forwards[(n)->level + (l)] + +typedef enum { SSkipListPutSuccess = 0, SSkipListPutEarlyStop = 1, SSkipListPutSkipOne = 2 } SSkipListPutStatus; + +typedef struct SSkipList { + uint32_t seed; + __compar_fn_t comparFn; + __sl_key_fn_t keyFn; + TdThreadRwlock *lock; + uint16_t len; + uint8_t maxLevel; + uint8_t flags; + uint8_t type; // static info above + uint8_t level; + uint32_t size; + SSkipListNode *pHead; // point to the first element + SSkipListNode *pTail; // point to the last element + tGenericSavedFunc *insertHandleFn; +} SSkipList; + +typedef struct SSkipListIterator { + SSkipList *pSkipList; + SSkipListNode *cur; + int32_t step; // the number of nodes that have been checked already + int32_t order; // order of the iterator + SSkipListNode *next; // next points to the true qualified node in skiplist +} SSkipListIterator; + +#define SL_IS_THREAD_SAFE(s) (((s)->flags) & SL_THREAD_SAFE) +#define SL_DUP_MODE(s) (((s)->flags) & ((((uint8_t)1) << 2) - 1)) +#define SL_GET_NODE_KEY(s, n) ((s)->keyFn((n)->pData)) +#define SL_GET_MIN_KEY(s) SL_GET_NODE_KEY(s, SL_NODE_GET_FORWARD_POINTER((s)->pHead, 0)) +#define SL_GET_MAX_KEY(s) SL_GET_NODE_KEY((s), SL_NODE_GET_BACKWARD_POINTER((s)->pTail, 0)) +#define SL_SIZE(s) (s)->size + +SSkipList *tSkipListCreate(uint8_t maxLevel, uint8_t keyType, uint16_t keyLen, __compar_fn_t comparFn, uint8_t flags, + __sl_key_fn_t fn); +void tSkipListDestroy(SSkipList *pSkipList); +SSkipListNode *tSkipListPut(SSkipList *pSkipList, void *pData); +void tSkipListPutBatchByIter(SSkipList *pSkipList, void *iter, iter_next_fn_t iterate); +SArray *tSkipListGet(SSkipList *pSkipList, SSkipListKey pKey); +void tSkipListPrint(SSkipList *pSkipList, int16_t nlevel); +SSkipListIterator *tSkipListCreateIter(SSkipList *pSkipList); +SSkipListIterator *tSkipListCreateIterFromVal(SSkipList *pSkipList, const char *val, int32_t type, int32_t order); +bool tSkipListIterNext(SSkipListIterator *iter); +SSkipListNode *tSkipListIterGet(SSkipListIterator *iter); +void *tSkipListDestroyIter(SSkipListIterator *iter); +uint32_t tSkipListRemove(SSkipList *pSkipList, SSkipListKey key); +void tSkipListRemoveNode(SSkipList *pSkipList, SSkipListNode *pNode); + +#ifdef __cplusplus +} +#endif + +#endif /*_TD_UTIL_SKILIST_H*/ + +#endif \ No newline at end of file diff --git a/source/libs/tdb/test/tdbTest.cpp b/source/libs/tdb/test/tdbTest.cpp index 9b4bc46ea9..4f20efd904 100644 --- a/source/libs/tdb/test/tdbTest.cpp +++ b/source/libs/tdb/test/tdbTest.cpp @@ -316,4 +316,6 @@ TEST(tdb_test, simple_test2) { // Close Env ret = tdbEnvClose(pEnv); GTEST_ASSERT_EQ(ret, 0); -} \ No newline at end of file +} + +TEST(tdb_test, simple_delete1) { taosRemoveDir("tdb"); } \ No newline at end of file diff --git a/source/util/src/tskiplist2.c b/source/util/src/tskiplist2.c new file mode 100644 index 0000000000..6657896131 --- /dev/null +++ b/source/util/src/tskiplist2.c @@ -0,0 +1,139 @@ +/* + * 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 "tskiplist2.h" + +typedef struct SSLNode SSLNode; +struct SSLNode { + int8_t level; + SSLNode *forwards[]; +}; + +struct SSkipList2 { + int8_t level; + uint32_t seed; + int32_t size; + const SSLCfg *pCfg; +}; + +struct SSLCursor { + SSkipList2 *pSl; + SSLNode *forwards[SL_MAX_LEVEL]; +}; + +static void *slMalloc(void *pPool, int32_t size); +static void slFree(void *pPool, void *p); +static int32_t slCmprFn(const void *pKey, int32_t nKey, const void *pData, int32_t nData); + +const SSLCfg slDefaultCfg = {.maxLevel = SL_MAX_LEVEL, + .nKey = -1, + .nData = -1, + .cmprFn = slCmprFn, + .pPool = NULL, + .xMalloc = slMalloc, + .xFree = slFree}; + +int32_t slOpen(const SSLCfg *pCfg, SSkipList2 **ppSl) { + SSkipList2 *pSl = NULL; + + *ppSl = NULL; + if (pCfg == NULL) pCfg = &slDefaultCfg; + + // check cfg (TODO) + + // create handle + pSl = pCfg->xMalloc(pCfg->pPool, sizeof(*pSl)); + // (TODO) + *ppSl = pSl; + return 0; +} + +int32_t slClose(SSkipList2 *pSl) { + // TODO + return 0; +} + +int32_t slcOpen(SSkipList2 *pSl, SSLCursor *pSlc) { + // TODO + return 0; +} + +int32_t slcClose(SSLCursor *pSlc) { + // TODO + return 0; +} + +int32_t slcMoveTo(SSLCursor *pSlc, const void *pKey, int32_t nKey) { + // TODO + return 0; +} + +int32_t slcMoveToNext(SSLCursor *pSlc) { + // TODO + return 0; +} + +int32_t slcMoveToPrev(SSLCursor *pSlc) { + // TODO + return 0; +} + +int32_t slcMoveToFirst(SSLCursor *pSlc) { + // TODO + return 0; +} + +int32_t slcMoveToLast(SSLCursor *pSlc) { + // TODO + return 0; +} + +int32_t slcPut(SSLCursor *pSlc, const void *pKey, int32_t nKey, const void *pData, int32_t nData) { + // TODO + return 0; +} + +int32_t slcGet(SSLCursor *pSlc, const void **ppKey, int32_t *nKey, const void **ppData, int32_t *nData) { + // TODO + return 0; +} + +int32_t slcDrop(SSLCursor *pSlc) { + // TODO + return 0; +} + +static FORCE_INLINE void *slMalloc(void *pPool, int32_t size) { return taosMemoryMalloc(size); } + +static FORCE_INLINE void slFree(void *pPool, void *p) { taosMemoryFree(p); } + +static int32_t slCmprFn(const void *pKey1, int32_t nKey1, const void *pKey2, int32_t nKey2) { + ASSERT(nKey1 >= 0 && nKey2 >= 0); + + int32_t nKey = nKey1 > nKey2 ? nKey2 : nKey1; + int32_t c; + + c = memcmp(pKey1, pKey2, nKey); + if (c == 0) { + if (nKey1 > nKey2) { + c = 1; + } else if (nKey1 < nKey2) { + c = -1; + } + } + + return c; +} \ No newline at end of file