[td-98] add bi-direction iterator for skiplist
This commit is contained in:
parent
1da0f92d84
commit
66d6800315
|
@ -13,8 +13,8 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TBASE_TSKIPLIST_H
|
||||
#define TBASE_TSKIPLIST_H
|
||||
#ifndef TDENGINE_TSKIPLIST_H
|
||||
#define TDENGINE_TSKIPLIST_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -24,10 +24,6 @@ extern "C" {
|
|||
#include "taosdef.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
|
||||
|
||||
|
@ -35,11 +31,11 @@ typedef char *SSkipListKey;
|
|||
typedef char *(*__sl_key_fn_t)(const void *);
|
||||
|
||||
/**
|
||||
* the skip list node is located in a consecutive memory area,
|
||||
* 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;
|
||||
|
@ -136,7 +132,8 @@ typedef struct SSkipList {
|
|||
typedef struct SSkipListIterator {
|
||||
SSkipList * pSkipList;
|
||||
SSkipListNode *cur;
|
||||
int64_t num;
|
||||
int32_t step; // the number of nodes that have been checked already
|
||||
int32_t order; // order of the iterator
|
||||
} SSkipListIterator;
|
||||
|
||||
/**
|
||||
|
@ -205,6 +202,15 @@ void tSkipListPrint(SSkipList *pSkipList, int16_t nlevel);
|
|||
*/
|
||||
SSkipListIterator *tSkipListCreateIter(SSkipList *pSkipList);
|
||||
|
||||
/**
|
||||
* create skip list iterator from the given node and specified the order
|
||||
* @param pSkipList
|
||||
* @param pNode start position, instead of the first node in skip list
|
||||
* @param order traverse order of the iterator
|
||||
* @return
|
||||
*/
|
||||
SSkipListIterator *tSkipListCreateIterFromVal(SSkipList* pSkipList, const char* val, int32_t type, int32_t order);
|
||||
|
||||
/**
|
||||
* forward the skip list iterator
|
||||
* @param iter
|
||||
|
@ -245,4 +251,4 @@ void tSkipListRemoveNode(SSkipList *pSkipList, SSkipListNode *pNode);
|
|||
}
|
||||
#endif
|
||||
|
||||
#endif // TBASE_TSKIPLIST_H
|
||||
#endif // TDENGINE_TSKIPLIST_H
|
||||
|
|
|
@ -125,7 +125,7 @@ char* strreplace(const char* str, const char* pattern, const char* rep);
|
|||
|
||||
int32_t strdequote(char *src);
|
||||
|
||||
char *paGetToken(char *src, char **token, int32_t *tokenLen);
|
||||
char *paGetToken(char *src, size_t maxLen, char **token, int32_t *tokenLen);
|
||||
|
||||
void taosMsleep(int32_t mseconds);
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "tlog.h"
|
||||
#include "tskiplist.h"
|
||||
#include "tutil.h"
|
||||
#include "tcompare.h"
|
||||
|
||||
static FORCE_INLINE void recordNodeEachLevel(SSkipList *pSkipList, int32_t level) { // record link count in each level
|
||||
#if SKIP_LIST_RECORD_PERFORMANCE
|
||||
|
@ -72,196 +73,54 @@ memset(pNode, 0, SL_NODE_HEADER_SIZE(_l));\
|
|||
|
||||
static void tSkipListDoInsert(SSkipList *pSkipList, SSkipListNode **forward, SSkipListNode *pNode);
|
||||
static SSkipListNode* tSkipListDoAppend(SSkipList *pSkipList, SSkipListNode *pNode);
|
||||
static SSkipListIterator* doCreateSkipListIterator(SSkipList *pSkipList, int32_t order);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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 = ((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 = ((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 = GET_DOUBLE_VAL(pLeft) - GET_DOUBLE_VAL(pRight);
|
||||
if (fabs(ret) < FLT_EPSILON) {
|
||||
return 0;
|
||||
} else {
|
||||
return ret > 0 ? 1 : -1;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t compareStrVal(const void *pLeft, const void *pRight) {
|
||||
int32_t ret = strcmp(pLeft, pRight);
|
||||
if (ret == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return ret > 0 ? 1 : -1;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t compareWStrVal(const void *pLeft, const void *pRight) {
|
||||
// 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(SSkipList *pSkipList, int32_t filterDataType) {
|
||||
__compar_fn_t comparFn = NULL;
|
||||
|
||||
switch (pSkipList->keyInfo.type) {
|
||||
case TSDB_DATA_TYPE_TINYINT:
|
||||
case TSDB_DATA_TYPE_SMALLINT:
|
||||
case TSDB_DATA_TYPE_INT:
|
||||
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) {
|
||||
comparFn = compareInt32Val;
|
||||
} else if (filterDataType >= TSDB_DATA_TYPE_FLOAT && filterDataType <= TSDB_DATA_TYPE_DOUBLE) {
|
||||
comparFn = compareIntDoubleVal;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_FLOAT:
|
||||
case TSDB_DATA_TYPE_DOUBLE: {
|
||||
//static __compar_fn_t getComparFunc(SSkipList *pSkipList, int32_t filterDataType) {
|
||||
// __compar_fn_t comparFn = NULL;
|
||||
//
|
||||
// switch (pSkipList->keyInfo.type) {
|
||||
// case TSDB_DATA_TYPE_TINYINT:
|
||||
// case TSDB_DATA_TYPE_SMALLINT:
|
||||
// case TSDB_DATA_TYPE_INT:
|
||||
// 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) {
|
||||
// comparFn = compareDoubleIntVal;
|
||||
// comparFn = compareInt32Val;
|
||||
// } else if (filterDataType >= TSDB_DATA_TYPE_FLOAT && filterDataType <= TSDB_DATA_TYPE_DOUBLE) {
|
||||
// comparFn = compareIntDoubleVal;
|
||||
// }
|
||||
// break;
|
||||
// }
|
||||
// case TSDB_DATA_TYPE_FLOAT:
|
||||
// case TSDB_DATA_TYPE_DOUBLE: {
|
||||
//// 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;
|
||||
// }
|
||||
if (filterDataType == TSDB_DATA_TYPE_DOUBLE) {
|
||||
comparFn = compareDoubleVal;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_BINARY:
|
||||
comparFn = compareStrVal;
|
||||
break;
|
||||
case TSDB_DATA_TYPE_NCHAR:
|
||||
comparFn = compareWStrVal;
|
||||
break;
|
||||
default:
|
||||
comparFn = compareInt32Val;
|
||||
break;
|
||||
}
|
||||
|
||||
return comparFn;
|
||||
}
|
||||
|
||||
static __compar_fn_t getKeyComparator(int32_t keyType) {
|
||||
__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:
|
||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||
comparFn = compareInt64Val;
|
||||
break;
|
||||
case TSDB_DATA_TYPE_BOOL:
|
||||
comparFn = compareInt32Val;
|
||||
break;
|
||||
|
||||
case TSDB_DATA_TYPE_FLOAT:
|
||||
case TSDB_DATA_TYPE_DOUBLE:
|
||||
comparFn = compareDoubleVal;
|
||||
break;
|
||||
|
||||
case TSDB_DATA_TYPE_BINARY:
|
||||
comparFn = compareStrVal;
|
||||
break;
|
||||
|
||||
case TSDB_DATA_TYPE_NCHAR:
|
||||
comparFn = compareWStrVal;
|
||||
break;
|
||||
|
||||
default:
|
||||
comparFn = compareInt32Val;
|
||||
break;
|
||||
}
|
||||
|
||||
return comparFn;
|
||||
}
|
||||
// break;
|
||||
// }
|
||||
// case TSDB_DATA_TYPE_BINARY:
|
||||
// comparFn = compareStrVal;
|
||||
// break;
|
||||
// case TSDB_DATA_TYPE_NCHAR:
|
||||
// comparFn = compareWStrVal;
|
||||
// break;
|
||||
// default:
|
||||
// comparFn = compareInt32Val;
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// return comparFn;
|
||||
//}
|
||||
|
||||
static bool initForwardBackwardPtr(SSkipList* pSkipList) {
|
||||
uint32_t maxLevel = pSkipList->maxLevel;
|
||||
|
@ -298,7 +157,7 @@ SSkipList *tSkipListCreate(uint8_t maxLevel, uint8_t keyType, uint8_t keyLen, ui
|
|||
|
||||
pSkipList->keyInfo = (SSkipListKeyInfo){.type = keyType, .len = keyLen, .dupKey = dupKey, .freeNode = freeNode};
|
||||
pSkipList->keyFn = fn;
|
||||
pSkipList->comparFn = getKeyComparator(keyType);
|
||||
pSkipList->comparFn = getKeyComparFunc(keyType);
|
||||
pSkipList->maxLevel = maxLevel;
|
||||
pSkipList->level = 1;
|
||||
|
||||
|
@ -406,22 +265,18 @@ SSkipListNode *tSkipListPut(SSkipList *pSkipList, SSkipListNode *pNode) {
|
|||
SSkipListNode *px = pSkipList->pHead;
|
||||
SSkipListNode *forward[MAX_SKIP_LIST_LEVEL] = {0};
|
||||
|
||||
bool identical = false;
|
||||
int32_t ret = -1;
|
||||
for (int32_t i = pSkipList->level - 1; i >= 0; --i) {
|
||||
SSkipListNode *p = SL_GET_FORWARD_POINTER(px, i);
|
||||
while (p != pSkipList->pTail) {
|
||||
char *key = SL_GET_NODE_KEY(pSkipList, p);
|
||||
|
||||
// if the forward element is less than the specified key, forward one step
|
||||
int32_t ret = pSkipList->comparFn(key, newDatakey);
|
||||
ret = pSkipList->comparFn(key, newDatakey);
|
||||
if (ret < 0) {
|
||||
px = p;
|
||||
p = SL_GET_FORWARD_POINTER(px, i);
|
||||
} else {
|
||||
if (identical == false) {
|
||||
identical = (ret == 0);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -430,7 +285,7 @@ SSkipListNode *tSkipListPut(SSkipList *pSkipList, SSkipListNode *pNode) {
|
|||
}
|
||||
|
||||
// if the skip list does not allowed identical key inserted, the new data will be discarded.
|
||||
if (pSkipList->keyInfo.dupKey == 0 && identical) {
|
||||
if (pSkipList->keyInfo.dupKey == 0 && ret == 0) {
|
||||
if (pSkipList->lock) {
|
||||
pthread_rwlock_unlock(pSkipList->lock);
|
||||
}
|
||||
|
@ -447,20 +302,13 @@ void tSkipListDoInsert(SSkipList *pSkipList, SSkipListNode **forward, SSkipListN
|
|||
|
||||
for (int32_t i = 0; i < pNode->level; ++i) {
|
||||
SSkipListNode *x = forward[i];
|
||||
|
||||
// if (x != pSkipList->pTail) {
|
||||
SL_GET_BACKWARD_POINTER(pNode, i) = x;
|
||||
SL_GET_BACKWARD_POINTER(pNode, i) = x;
|
||||
|
||||
SSkipListNode *next = SL_GET_FORWARD_POINTER(x, i);
|
||||
// if (next) {
|
||||
SL_GET_BACKWARD_POINTER(next, i) = pNode;
|
||||
// }
|
||||
SSkipListNode *next = SL_GET_FORWARD_POINTER(x, i);
|
||||
SL_GET_BACKWARD_POINTER(next, i) = pNode;
|
||||
|
||||
SL_GET_FORWARD_POINTER(pNode, i) = next;
|
||||
SL_GET_FORWARD_POINTER(x, i) = pNode;
|
||||
// } else {
|
||||
// SL_GET_FORWARD_POINTER(pSkipList->pHead, i) = pNode;
|
||||
// }
|
||||
SL_GET_FORWARD_POINTER(pNode, i) = next;
|
||||
SL_GET_FORWARD_POINTER(x, i) = pNode;
|
||||
}
|
||||
|
||||
atomic_add_fetch_32(&pSkipList->size, 1);
|
||||
|
@ -494,11 +342,9 @@ SSkipListNode* tSkipListDoAppend(SSkipList *pSkipList, SSkipListNode *pNode) {
|
|||
|
||||
SArray* tSkipListGet(SSkipList *pSkipList, SSkipListKey pKey, int16_t keyType) {
|
||||
int32_t sLevel = pSkipList->level - 1;
|
||||
int32_t ret = -1;
|
||||
|
||||
|
||||
// result list
|
||||
SArray* sa = taosArrayInit(1, POINTER_BYTES);
|
||||
|
||||
SSkipListNode *pNode = pSkipList->pHead;
|
||||
|
||||
if (pSkipList->lock) {
|
||||
|
@ -509,15 +355,16 @@ SArray* tSkipListGet(SSkipList *pSkipList, SSkipListKey pKey, int16_t keyType) {
|
|||
pSkipList->state.queryCount++;
|
||||
#endif
|
||||
|
||||
__compar_fn_t filterComparFn = getKeyFilterComparator(pSkipList, keyType);
|
||||
|
||||
__compar_fn_t filterComparFn = getComparFunc(pSkipList->keyInfo.type, keyType);
|
||||
int32_t ret = -1;
|
||||
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);
|
||||
SSkipListNode *p = SL_GET_FORWARD_POINTER(pNode, i);
|
||||
while (p != pSkipList->pTail) {
|
||||
char *key = SL_GET_NODE_KEY(pSkipList, p);
|
||||
|
||||
if ((ret = filterComparFn(key, pKey)) < 0) {
|
||||
pNode = pNext;
|
||||
pNext = SL_GET_FORWARD_POINTER(pNext, i);
|
||||
pNode = p;
|
||||
p = SL_GET_FORWARD_POINTER(p, i);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
@ -525,10 +372,6 @@ SArray* tSkipListGet(SSkipList *pSkipList, SSkipListKey pKey, int16_t keyType) {
|
|||
|
||||
// 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);
|
||||
|
||||
|
@ -559,25 +402,57 @@ SSkipListIterator* tSkipListCreateIter(SSkipList *pSkipList) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
SSkipListIterator* iter = calloc(1, sizeof(SSkipListIterator));
|
||||
|
||||
iter->pSkipList = pSkipList;
|
||||
if (pSkipList->lock) {
|
||||
pthread_rwlock_rdlock(pSkipList->lock);
|
||||
return doCreateSkipListIterator(pSkipList, TSDB_ORDER_ASC);
|
||||
}
|
||||
|
||||
SSkipListIterator *tSkipListCreateIterFromVal(SSkipList* pSkipList, const char* val, int32_t type, int32_t order) {
|
||||
if (pSkipList == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
iter->cur = NULL;
|
||||
iter->num = pSkipList->size;
|
||||
assert(order == TSDB_ORDER_ASC || order == TSDB_ORDER_DESC);
|
||||
|
||||
if (pSkipList->lock) {
|
||||
pthread_rwlock_unlock(pSkipList->lock);
|
||||
if (val == NULL) {
|
||||
return doCreateSkipListIterator(pSkipList, order);
|
||||
} else {
|
||||
|
||||
SSkipListNode *forward[MAX_SKIP_LIST_LEVEL] = {0};
|
||||
|
||||
int32_t ret = -1;
|
||||
__compar_fn_t filterComparFn = getComparFunc(pSkipList->keyInfo.type, type);
|
||||
SSkipListNode* pNode = pSkipList->pHead;
|
||||
|
||||
for (int32_t i = pSkipList->level - 1; i >= 0; --i) {
|
||||
SSkipListNode *p = SL_GET_FORWARD_POINTER(pNode, i);
|
||||
while (p != pSkipList->pTail) {
|
||||
char *key = SL_GET_NODE_KEY(pSkipList, p);
|
||||
|
||||
if ((ret = filterComparFn(key, val)) < 0) {
|
||||
pNode = p;
|
||||
p = SL_GET_FORWARD_POINTER(p, i);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
forward[i] = pNode;
|
||||
}
|
||||
|
||||
SSkipListIterator* iter = doCreateSkipListIterator(pSkipList, order);
|
||||
|
||||
// set the initial position
|
||||
if (order == TSDB_ORDER_ASC) {
|
||||
iter->cur = forward[0]; // greater equals than the value
|
||||
} else {
|
||||
iter->cur = SL_GET_FORWARD_POINTER(forward[0], 0);
|
||||
}
|
||||
|
||||
return iter;
|
||||
}
|
||||
|
||||
return iter;
|
||||
}
|
||||
|
||||
bool tSkipListIterNext(SSkipListIterator *iter) {
|
||||
if (iter->num == 0 || iter->pSkipList == NULL) {
|
||||
if (iter->pSkipList == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -587,26 +462,35 @@ bool tSkipListIterNext(SSkipListIterator *iter) {
|
|||
pthread_rwlock_rdlock(pSkipList->lock);
|
||||
}
|
||||
|
||||
if (iter->cur == NULL) {
|
||||
iter->cur = SL_GET_FORWARD_POINTER(pSkipList->pHead, 0);
|
||||
} else {
|
||||
iter->cur = SL_GET_FORWARD_POINTER(iter->cur, 0);
|
||||
if (iter->order == TSDB_ORDER_ASC) { // ascending order iterate
|
||||
if (iter->cur == NULL) {
|
||||
iter->cur = SL_GET_FORWARD_POINTER(pSkipList->pHead, 0);
|
||||
} else {
|
||||
iter->cur = SL_GET_FORWARD_POINTER(iter->cur, 0);
|
||||
}
|
||||
} else { // descending order iterate
|
||||
if (iter->cur == NULL) {
|
||||
iter->cur = SL_GET_BACKWARD_POINTER(pSkipList->pTail, 0);
|
||||
} else {
|
||||
iter->cur = SL_GET_BACKWARD_POINTER(iter->cur, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (pSkipList->lock) {
|
||||
pthread_rwlock_unlock(pSkipList->lock);
|
||||
}
|
||||
|
||||
return iter->cur != pSkipList->pTail;
|
||||
return (iter->order == TSDB_ORDER_ASC)? (iter->cur != pSkipList->pTail) : (iter->cur != pSkipList->pHead);
|
||||
}
|
||||
|
||||
SSkipListNode *tSkipListIterGet(SSkipListIterator *iter) {
|
||||
if (iter == NULL || iter->cur == iter->pSkipList->pTail) {
|
||||
if (iter == NULL || iter->cur == iter->pSkipList->pTail || iter->cur == iter->pSkipList->pHead) {
|
||||
return NULL;
|
||||
} else {
|
||||
return iter->cur;
|
||||
}
|
||||
}
|
||||
|
||||
void* tSkipListDestroyIter(SSkipListIterator* iter) {
|
||||
if (iter == NULL) {
|
||||
return NULL;
|
||||
|
@ -622,7 +506,7 @@ void* tSkipListDestroyIter(SSkipListIterator* iter) {
|
|||
// SSkipListNode *p = pStartNode;
|
||||
// int32_t numOfRes = 0;
|
||||
//
|
||||
// __compar_fn_t filterComparFn = getKeyFilterComparator(pSkipList, pEndKey->nType);
|
||||
// __compar_fn_t filterComparFn = getComparFunc(pSkipList, pEndKey->nType);
|
||||
// while (p != NULL) {
|
||||
// int32_t ret = filterComparFn(&p->key, pEndKey);
|
||||
// if (ret > 0) {
|
||||
|
@ -663,7 +547,7 @@ void* tSkipListDestroyIter(SSkipListIterator* iter) {
|
|||
// return 0;
|
||||
// }
|
||||
//
|
||||
// __compar_fn_t filterComparFn = getKeyFilterComparator(pSkipList, pKey->nType);
|
||||
// __compar_fn_t filterComparFn = getComparFunc(pSkipList, pKey->nType);
|
||||
//
|
||||
// // backward check if previous nodes are with the same value.
|
||||
// SSkipListNode *pPrev = pNode->pBackward[0];
|
||||
|
@ -679,11 +563,11 @@ void* tSkipListDestroyIter(SSkipListIterator* iter) {
|
|||
// int32_t ret = -1;
|
||||
//
|
||||
// SSkipListNode *x = &pSkipList->pHead;
|
||||
// __compar_fn_t filterComparFn = getKeyFilterComparator(pSkipList, pKey->nType);
|
||||
// __compar_fn_t filterComparFn = getComparFunc(pSkipList, pKey->nType);
|
||||
//
|
||||
// pthread_rwlock_rdlock(&pSkipList->lock);
|
||||
//
|
||||
// if (cond == TSDB_RELATION_LARGE_EQUAL || cond == TSDB_RELATION_LARGE) {
|
||||
// if (cond == TSDB_RELATION_GREATER_EQUAL || cond == TSDB_RELATION_GREATER) {
|
||||
// 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];
|
||||
|
@ -691,7 +575,7 @@ void* tSkipListDestroyIter(SSkipListIterator* iter) {
|
|||
// }
|
||||
//
|
||||
// // backward check if previous nodes are with the same value.
|
||||
// if (cond == TSDB_RELATION_LARGE_EQUAL && ret == 0) {
|
||||
// if (cond == TSDB_RELATION_GREATER_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];
|
||||
|
@ -700,10 +584,10 @@ void* tSkipListDestroyIter(SSkipListIterator* iter) {
|
|||
// return pNode;
|
||||
// }
|
||||
//
|
||||
// if (ret > 0 || cond == TSDB_RELATION_LARGE_EQUAL) {
|
||||
// if (ret > 0 || cond == TSDB_RELATION_GREATER_EQUAL) {
|
||||
// pthread_rwlock_unlock(&pSkipList->lock);
|
||||
// return x->pForward[0];
|
||||
// } else { // cond == TSDB_RELATION_LARGE && ret == 0
|
||||
// } else { // cond == TSDB_RELATION_GREATER && ret == 0
|
||||
// SSkipListNode *pn = x->pForward[0];
|
||||
// while (pn != NULL && filterComparFn(&pn->key, pKey) == 0) {
|
||||
// pn = pn->pForward[0];
|
||||
|
@ -717,19 +601,9 @@ void* tSkipListDestroyIter(SSkipListIterator* iter) {
|
|||
// return NULL;
|
||||
//}
|
||||
//
|
||||
// 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);
|
||||
// __compar_fn_t filterComparFn = getComparFunc(pSkipList, pKey->nType);
|
||||
//
|
||||
// if (filterComparFn(&forward[0]->pForward[0]->key, pKey) == 0) {
|
||||
// SSkipListNode *p = forward[0]->pForward[0];
|
||||
|
@ -760,7 +634,7 @@ void* tSkipListDestroyIter(SSkipListIterator* iter) {
|
|||
//
|
||||
// bool tSkipListRemove(SSkipList *pSkipList, SSkipListKey *pKey) {
|
||||
// SSkipListNode *forward[MAX_SKIP_LIST_LEVEL] = {0};
|
||||
// __compar_fn_t filterComparFn = getKeyFilterComparator(pSkipList, pKey->nType);
|
||||
// __compar_fn_t filterComparFn = getComparFunc(pSkipList, pKey->nType);
|
||||
//
|
||||
// pthread_rwlock_rdlock(&pSkipList->lock);
|
||||
//
|
||||
|
@ -818,3 +692,12 @@ void tSkipListPrint(SSkipList *pSkipList, int16_t nlevel) {
|
|||
p = SL_GET_FORWARD_POINTER(p, nlevel - 1);
|
||||
}
|
||||
}
|
||||
|
||||
SSkipListIterator* doCreateSkipListIterator(SSkipList *pSkipList, int32_t order) {
|
||||
SSkipListIterator* iter = calloc(1, sizeof(SSkipListIterator));
|
||||
|
||||
iter->pSkipList = pSkipList;
|
||||
iter->order = order;
|
||||
|
||||
return iter;
|
||||
}
|
||||
|
|
|
@ -164,9 +164,10 @@ char* strtolower(char *dst, const char *src) {
|
|||
return dst;
|
||||
}
|
||||
|
||||
char *paGetToken(char *string, char **token, int32_t *tokenLen) {
|
||||
char *paGetToken(char *string, size_t maxLen, char **token, int32_t *tokenLen) {
|
||||
char quote = 0;
|
||||
|
||||
char* start = string;
|
||||
|
||||
while (*string != 0) {
|
||||
if (*string == ' ' || *string == '\t') {
|
||||
++string;
|
||||
|
@ -182,7 +183,7 @@ char *paGetToken(char *string, char **token, int32_t *tokenLen) {
|
|||
|
||||
*token = string;
|
||||
|
||||
while (*string != 0) {
|
||||
while (*string != 0 && *string != '\n' && (string - start < maxLen)) {
|
||||
if (*string == '@' && quote) {
|
||||
//*string = 0;
|
||||
++string;
|
||||
|
|
|
@ -104,6 +104,7 @@ void randKeyTest() {
|
|||
|
||||
tSkipListDestroy(pSkipList);
|
||||
}
|
||||
|
||||
void stringKeySkiplistTest() {
|
||||
const int32_t max_key_size = 12;
|
||||
|
||||
|
|
Loading…
Reference in New Issue