tskiplist.c 20.5 KB
Newer Older
H
hzcheng 已提交
1 2 3 4 5 6 7
/*
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
 *
 * This program is free software: you can use, redistribute, and/or modify
 * it under the terms of the GNU Affero General Public License, version 3
 * or later ("AGPL"), as published by the Free Software Foundation.
 *
H
Haojun Liao 已提交
8
 *
H
hzcheng 已提交
9 10 11 12 13 14 15
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
16

S
Shengliang Guan 已提交
17
#define _DEFAULT_SOURCE
18
#include "tskiplist.h"
S
Shengliang Guan 已提交
19
#include "tcompare.h"
S
log  
Shengliang Guan 已提交
20
#include "tlog.h"
S
Shengliang Guan 已提交
21
#include "tutil.h"
H
hzcheng 已提交
22

S
Shengliang Guan 已提交
23 24
static int32_t            initForwardBackwardPtr(SSkipList *pSkipList);
static SSkipListNode     *getPriorNode(SSkipList *pSkipList, const char *val, int32_t order, SSkipListNode **pCur);
H
TD-1194  
Hongze Cheng 已提交
25 26
static void               tSkipListRemoveNodeImpl(SSkipList *pSkipList, SSkipListNode *pNode);
static void               tSkipListCorrectLevel(SSkipList *pSkipList);
H
TD-1437  
Hongze Cheng 已提交
27
static SSkipListIterator *doCreateSkipListIterator(SSkipList *pSkipList, int32_t order);
H
Hongze Cheng 已提交
28 29 30
static void tSkipListDoInsert(SSkipList *pSkipList, SSkipListNode **direction, SSkipListNode *pNode, bool isForward);
static bool tSkipListGetPosToPut(SSkipList *pSkipList, SSkipListNode **backward, void *pData);
static SSkipListNode *tSkipListNewNode(uint8_t level);
S
TD-1848  
Shengliang Guan 已提交
31
#define tSkipListFreeNode(n) tfree((n))
H
Hongze Cheng 已提交
32 33
static SSkipListNode *tSkipListPutImpl(SSkipList *pSkipList, void *pData, SSkipListNode **direction, bool isForward,
                                       bool hasDup);
H
TD-1437  
Hongze Cheng 已提交
34

S
Shengliang Guan 已提交
35 36 37
static FORCE_INLINE int32_t tSkipListWLock(SSkipList *pSkipList);
static FORCE_INLINE int32_t tSkipListRLock(SSkipList *pSkipList);
static FORCE_INLINE int32_t tSkipListUnlock(SSkipList *pSkipList);
H
TD-1437  
Hongze Cheng 已提交
38 39
static FORCE_INLINE int32_t getSkipListRandLevel(SSkipList *pSkipList);

H
TD-1548  
Hongze Cheng 已提交
40 41
SSkipList *tSkipListCreate(uint8_t maxLevel, uint8_t keyType, uint16_t keyLen, __compar_fn_t comparFn, uint8_t flags,
                           __sl_key_fn_t fn) {
H
TD-1437  
Hongze Cheng 已提交
42
  SSkipList *pSkipList = (SSkipList *)calloc(1, sizeof(SSkipList));
H
TD-1194  
Hongze Cheng 已提交
43
  if (pSkipList == NULL) return NULL;
H
TD-1437  
Hongze Cheng 已提交
44 45 46 47 48 49 50 51 52 53

  if (maxLevel > MAX_SKIP_LIST_LEVEL) {
    maxLevel = MAX_SKIP_LIST_LEVEL;
  }

  pSkipList->maxLevel = maxLevel;
  pSkipList->type = keyType;
  pSkipList->len = keyLen;
  pSkipList->flags = flags;
  pSkipList->keyFn = fn;
wafwerar's avatar
wafwerar 已提交
54
  pSkipList->seed = taosRand();
55 56 57

#if 0 
  // the function getkeycomparfunc is defined in common
H
TD-1548  
Hongze Cheng 已提交
58
  if (comparFn == NULL) {
59
    pSkipList->comparFn = getKeyComparFunc(keyType, TSDB_ORDER_ASC);
H
TD-1548  
Hongze Cheng 已提交
60 61 62
  } else {
    pSkipList->comparFn = comparFn;
  }
63 64 65
#else
  pSkipList->comparFn = comparFn;
#endif
H
TD-1437  
Hongze Cheng 已提交
66 67

  if (initForwardBackwardPtr(pSkipList) < 0) {
H
TD-1194  
Hongze Cheng 已提交
68
    tSkipListDestroy(pSkipList);
H
TD-1437  
Hongze Cheng 已提交
69
    return NULL;
S
slguan 已提交
70
  }
H
TD-1437  
Hongze Cheng 已提交
71

H
TD-1194  
Hongze Cheng 已提交
72
  if (SL_IS_THREAD_SAFE(pSkipList)) {
H
TD-1437  
Hongze Cheng 已提交
73
    pSkipList->lock = (pthread_rwlock_t *)calloc(1, sizeof(pthread_rwlock_t));
H
TD-1194  
Hongze Cheng 已提交
74 75 76 77
    if (pSkipList->lock == NULL) {
      tSkipListDestroy(pSkipList);
      return NULL;
    }
H
TD-1437  
Hongze Cheng 已提交
78 79

    if (pthread_rwlock_init(pSkipList->lock, NULL) != 0) {
H
TD-1194  
Hongze Cheng 已提交
80
      tSkipListDestroy(pSkipList);
H
TD-1437  
Hongze Cheng 已提交
81 82 83 84
      return NULL;
    }
  }

wafwerar's avatar
wafwerar 已提交
85
  taosSeedRand((uint32_t)time(NULL));
H
TD-1437  
Hongze Cheng 已提交
86 87 88

#if SKIP_LIST_RECORD_PERFORMANCE
  pSkipList->state.nTotalMemSize += sizeof(SSkipList);
H
more  
hzcheng 已提交
89
#endif
90
  pSkipList->insertHandleFn = NULL;
H
TD-1437  
Hongze Cheng 已提交
91 92

  return pSkipList;
S
slguan 已提交
93
}
H
hzcheng 已提交
94

H
TD-1194  
Hongze Cheng 已提交
95 96
void tSkipListDestroy(SSkipList *pSkipList) {
  if (pSkipList == NULL) return;
H
TD-1437  
Hongze Cheng 已提交
97 98 99

  tSkipListWLock(pSkipList);

H
TD-1194  
Hongze Cheng 已提交
100
  SSkipListNode *pNode = SL_NODE_GET_FORWARD_POINTER(pSkipList->pHead, 0);
H
TD-1437  
Hongze Cheng 已提交
101 102 103

  while (pNode != pSkipList->pTail) {
    SSkipListNode *pTemp = pNode;
H
TD-1194  
Hongze Cheng 已提交
104 105
    pNode = SL_NODE_GET_FORWARD_POINTER(pNode, 0);
    tSkipListFreeNode(pTemp);
S
slguan 已提交
106
  }
H
TD-1437  
Hongze Cheng 已提交
107

108 109
  tfree(pSkipList->insertHandleFn);

H
TD-1437  
Hongze Cheng 已提交
110 111 112
  tSkipListUnlock(pSkipList);
  if (pSkipList->lock != NULL) {
    pthread_rwlock_destroy(pSkipList->lock);
S
TD-1848  
Shengliang Guan 已提交
113
    tfree(pSkipList->lock);
H
TD-1437  
Hongze Cheng 已提交
114 115
  }

H
TD-1194  
Hongze Cheng 已提交
116 117
  tSkipListFreeNode(pSkipList->pHead);
  tSkipListFreeNode(pSkipList->pTail);
S
TD-1848  
Shengliang Guan 已提交
118
  tfree(pSkipList);
H
TD-1437  
Hongze Cheng 已提交
119 120
}

H
TD-1194  
Hongze Cheng 已提交
121
SSkipListNode *tSkipListPut(SSkipList *pSkipList, void *pData) {
H
TD-1437  
Hongze Cheng 已提交
122 123
  if (pSkipList == NULL || pData == NULL) return NULL;

H
Hongze Cheng 已提交
124
  SSkipListNode *backward[MAX_SKIP_LIST_LEVEL] = {0};
H
TD-1194  
Hongze Cheng 已提交
125 126
  SSkipListNode *pNode = NULL;

H
TD-1437  
Hongze Cheng 已提交
127 128
  tSkipListWLock(pSkipList);

H
Hongze Cheng 已提交
129
  bool hasDup = tSkipListGetPosToPut(pSkipList, backward, pData);
H
Hongze Cheng 已提交
130
  pNode = tSkipListPutImpl(pSkipList, pData, backward, false, hasDup);
H
TD-1437  
Hongze Cheng 已提交
131

H
Hongze Cheng 已提交
132 133 134 135 136
  tSkipListUnlock(pSkipList);

  return pNode;
}

137
void tSkipListPutBatchByIter(SSkipList *pSkipList, void *iter, iter_next_fn_t iterate) {
H
Hongze Cheng 已提交
138 139 140
  SSkipListNode *backward[MAX_SKIP_LIST_LEVEL] = {0};
  SSkipListNode *forward[MAX_SKIP_LIST_LEVEL] = {0};
  bool           hasDup = false;
S
Shengliang Guan 已提交
141 142 143
  char          *pKey = NULL;
  char          *pDataKey = NULL;
  int32_t        compare = 0;
H
Hongze Cheng 已提交
144 145

  tSkipListWLock(pSkipList);
H
TD-1437  
Hongze Cheng 已提交
146

S
Shengliang Guan 已提交
147 148
  void *pData = iterate(iter);
  if (pData == NULL) return;
149

H
Hongze Cheng 已提交
150
  // backward to put the first data
151 152 153
  hasDup = tSkipListGetPosToPut(pSkipList, backward, pData);

  tSkipListPutImpl(pSkipList, pData, backward, false, hasDup);
H
Hongze Cheng 已提交
154

S
Shengliang Guan 已提交
155
  for (int32_t level = 0; level < pSkipList->maxLevel; level++) {
H
Hongze Cheng 已提交
156 157 158 159
    forward[level] = SL_NODE_GET_BACKWARD_POINTER(backward[level], level);
  }

  // forward to put the rest of data
160 161
  while ((pData = iterate(iter)) != NULL) {
    pDataKey = pSkipList->keyFn(pData);
H
Hongze Cheng 已提交
162
    hasDup = false;
H
Hongze Cheng 已提交
163 164 165 166 167

    // Compare max key
    pKey = SL_GET_MAX_KEY(pSkipList);
    compare = pSkipList->comparFn(pDataKey, pKey);
    if (compare > 0) {
S
Shengliang Guan 已提交
168
      for (int32_t i = 0; i < pSkipList->maxLevel; i++) {
H
Hongze Cheng 已提交
169 170 171 172
        forward[i] = SL_NODE_GET_BACKWARD_POINTER(pSkipList->pTail, i);
      }
    } else {
      SSkipListNode *px = pSkipList->pHead;
S
Shengliang Guan 已提交
173
      for (int32_t i = pSkipList->maxLevel - 1; i >= 0; --i) {
H
Hongze Cheng 已提交
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
        if (i < pSkipList->level) {
          // set new px
          if (forward[i] != pSkipList->pHead) {
            if (px == pSkipList->pHead ||
                pSkipList->comparFn(SL_GET_NODE_KEY(pSkipList, forward[i]), SL_GET_NODE_KEY(pSkipList, px)) > 0) {
              px = forward[i];
            }
          }

          SSkipListNode *p = SL_NODE_GET_FORWARD_POINTER(px, i);
          while (p != pSkipList->pTail) {
            pKey = SL_GET_NODE_KEY(pSkipList, p);

            compare = pSkipList->comparFn(pKey, pDataKey);
            if (compare >= 0) {
H
Hongze Cheng 已提交
189
              if (compare == 0 && !hasDup) hasDup = true;
H
Hongze Cheng 已提交
190 191 192 193 194 195 196 197 198 199
              break;
            } else {
              px = p;
              p = SL_NODE_GET_FORWARD_POINTER(px, i);
            }
          }
        }

        forward[i] = px;
      }
H
TD-1194  
Hongze Cheng 已提交
200
    }
H
Hongze Cheng 已提交
201

202
    tSkipListPutImpl(pSkipList, pData, forward, true, hasDup);
H
TD-1437  
Hongze Cheng 已提交
203 204
  }
  tSkipListUnlock(pSkipList);
H
hzcheng 已提交
205 206
}

H
TD-1194  
Hongze Cheng 已提交
207 208
uint32_t tSkipListRemove(SSkipList *pSkipList, SSkipListKey key) {
  uint32_t count = 0;
H
TD-1437  
Hongze Cheng 已提交
209 210 211

  tSkipListWLock(pSkipList);

H
Hongze Cheng 已提交
212
  SSkipListNode *pNode = getPriorNode(pSkipList, key, TSDB_ORDER_ASC, NULL);
H
TD-1437  
Hongze Cheng 已提交
213
  while (1) {
H
TD-1194  
Hongze Cheng 已提交
214
    SSkipListNode *p = SL_NODE_GET_FORWARD_POINTER(pNode, 0);
H
TD-1437  
Hongze Cheng 已提交
215 216 217 218 219
    if (p == pSkipList->pTail) {
      break;
    }
    if (pSkipList->comparFn(key, SL_GET_NODE_KEY(pSkipList, p)) != 0) {
      break;
S
slguan 已提交
220
    }
H
TD-1194  
Hongze Cheng 已提交
221 222 223 224

    tSkipListRemoveNodeImpl(pSkipList, p);

    ++count;
S
slguan 已提交
225
  }
H
TD-1437  
Hongze Cheng 已提交
226

H
TD-1194  
Hongze Cheng 已提交
227 228
  tSkipListCorrectLevel(pSkipList);

H
TD-1437  
Hongze Cheng 已提交
229 230
  tSkipListUnlock(pSkipList);

H
TD-1194  
Hongze Cheng 已提交
231
  return count;
S
slguan 已提交
232 233
}

H
TD-1194  
Hongze Cheng 已提交
234 235
SArray *tSkipListGet(SSkipList *pSkipList, SSkipListKey key) {
  SArray *sa = taosArrayInit(1, POINTER_BYTES);
S
slguan 已提交
236

H
TD-1194  
Hongze Cheng 已提交
237
  tSkipListRLock(pSkipList);
238

H
Hongze Cheng 已提交
239
  SSkipListNode *pNode = getPriorNode(pSkipList, key, TSDB_ORDER_ASC, NULL);
H
TD-1437  
Hongze Cheng 已提交
240
  while (1) {
H
TD-1194  
Hongze Cheng 已提交
241
    SSkipListNode *p = SL_NODE_GET_FORWARD_POINTER(pNode, 0);
H
TD-1437  
Hongze Cheng 已提交
242 243 244 245 246 247
    if (p == pSkipList->pTail) {
      break;
    }
    if (pSkipList->comparFn(key, SL_GET_NODE_KEY(pSkipList, p)) != 0) {
      break;
    }
H
TD-1548  
Hongze Cheng 已提交
248
    taosArrayPush(sa, &p);
H
TD-1194  
Hongze Cheng 已提交
249
    pNode = p;
H
TD-1437  
Hongze Cheng 已提交
250 251 252 253
  }

  tSkipListUnlock(pSkipList);

H
TD-1194  
Hongze Cheng 已提交
254
  return sa;
H
TD-1437  
Hongze Cheng 已提交
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270
}

void tSkipListRemoveNode(SSkipList *pSkipList, SSkipListNode *pNode) {
  tSkipListWLock(pSkipList);
  tSkipListRemoveNodeImpl(pSkipList, pNode);
  tSkipListCorrectLevel(pSkipList);
  tSkipListUnlock(pSkipList);
}

SSkipListIterator *tSkipListCreateIter(SSkipList *pSkipList) {
  if (pSkipList == NULL) return NULL;

  return doCreateSkipListIterator(pSkipList, TSDB_ORDER_ASC);
}

SSkipListIterator *tSkipListCreateIterFromVal(SSkipList *pSkipList, const char *val, int32_t type, int32_t order) {
H
TD-1194  
Hongze Cheng 已提交
271 272
  ASSERT(order == TSDB_ORDER_ASC || order == TSDB_ORDER_DESC);
  ASSERT(pSkipList != NULL);
H
TD-1437  
Hongze Cheng 已提交
273 274 275 276 277 278 279 280

  SSkipListIterator *iter = doCreateSkipListIterator(pSkipList, order);
  if (val == NULL) {
    return iter;
  }

  tSkipListRLock(pSkipList);

H
Hongze Cheng 已提交
281
  iter->cur = getPriorNode(pSkipList, val, order, &(iter->next));
H
TD-1437  
Hongze Cheng 已提交
282 283 284 285 286 287 288 289 290 291 292 293 294

  tSkipListUnlock(pSkipList);

  return iter;
}

bool tSkipListIterNext(SSkipListIterator *iter) {
  if (iter->pSkipList == NULL) return false;

  SSkipList *pSkipList = iter->pSkipList;

  tSkipListRLock(pSkipList);

H
TD-1194  
Hongze Cheng 已提交
295
  if (iter->order == TSDB_ORDER_ASC) {
296 297 298 299 300 301 302
    // no data in the skip list
    if (iter->cur == pSkipList->pTail || iter->next == NULL) {
      iter->cur = pSkipList->pTail;
      tSkipListUnlock(pSkipList);
      return false;
    }

H
TD-1548  
Hongze Cheng 已提交
303
    iter->cur = SL_NODE_GET_FORWARD_POINTER(iter->cur, 0);
H
Hongze Cheng 已提交
304 305 306 307 308 309 310

    // a new node is inserted into between iter->cur and iter->next, ignore it
    if (iter->cur != iter->next && (iter->next != NULL)) {
      iter->cur = iter->next;
    }

    iter->next = SL_NODE_GET_FORWARD_POINTER(iter->cur, 0);
H
TD-1548  
Hongze Cheng 已提交
311
    iter->step++;
H
TD-1194  
Hongze Cheng 已提交
312
  } else {
H
Hongze Cheng 已提交
313
    if (iter->cur == pSkipList->pHead) {
314
      iter->cur = pSkipList->pHead;
H
Hongze Cheng 已提交
315 316 317
      tSkipListUnlock(pSkipList);
      return false;
    }
318

H
TD-1548  
Hongze Cheng 已提交
319
    iter->cur = SL_NODE_GET_BACKWARD_POINTER(iter->cur, 0);
H
Hongze Cheng 已提交
320 321 322 323 324 325 326

    // a new node is inserted into between iter->cur and iter->next, ignore it
    if (iter->cur != iter->next && (iter->next != NULL)) {
      iter->cur = iter->next;
    }

    iter->next = SL_NODE_GET_BACKWARD_POINTER(iter->cur, 0);
H
TD-1548  
Hongze Cheng 已提交
327
    iter->step++;
328 329
  }

H
TD-1437  
Hongze Cheng 已提交
330
  tSkipListUnlock(pSkipList);
331

H
TD-1437  
Hongze Cheng 已提交
332 333
  return (iter->order == TSDB_ORDER_ASC) ? (iter->cur != pSkipList->pTail) : (iter->cur != pSkipList->pHead);
}
334

H
TD-1437  
Hongze Cheng 已提交
335 336 337 338 339
SSkipListNode *tSkipListIterGet(SSkipListIterator *iter) {
  if (iter == NULL || iter->cur == iter->pSkipList->pTail || iter->cur == iter->pSkipList->pHead) {
    return NULL;
  } else {
    return iter->cur;
340 341
  }
}
342

H
TD-1437  
Hongze Cheng 已提交
343 344
void *tSkipListDestroyIter(SSkipListIterator *iter) {
  if (iter == NULL) {
345
    return NULL;
H
hzcheng 已提交
346 347
  }

S
TD-1848  
Shengliang Guan 已提交
348
  tfree(iter);
H
TD-1437  
Hongze Cheng 已提交
349 350
  return NULL;
}
H
hzcheng 已提交
351

H
TD-1437  
Hongze Cheng 已提交
352 353 354
void tSkipListPrint(SSkipList *pSkipList, int16_t nlevel) {
  if (pSkipList == NULL || pSkipList->level < nlevel || nlevel <= 0) {
    return;
355
  }
H
hzcheng 已提交
356

H
TD-1194  
Hongze Cheng 已提交
357
  SSkipListNode *p = SL_NODE_GET_FORWARD_POINTER(pSkipList->pHead, nlevel - 1);
H
TD-1437  
Hongze Cheng 已提交
358 359

  int32_t id = 1;
S
Shengliang Guan 已提交
360
  char   *prev = NULL;
H
TD-1437  
Hongze Cheng 已提交
361 362 363 364

  while (p != pSkipList->pTail) {
    char *key = SL_GET_NODE_KEY(pSkipList, p);
    if (prev != NULL) {
H
TD-1194  
Hongze Cheng 已提交
365
      ASSERT(pSkipList->comparFn(prev, key) < 0);
H
TD-1437  
Hongze Cheng 已提交
366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384
    }

    switch (pSkipList->type) {
      case TSDB_DATA_TYPE_INT:
        fprintf(stdout, "%d: %d\n", id++, *(int32_t *)key);
        break;
      case TSDB_DATA_TYPE_SMALLINT:
      case TSDB_DATA_TYPE_TINYINT:
      case TSDB_DATA_TYPE_BIGINT:
        fprintf(stdout, "%d: %" PRId64 " \n", id++, *(int64_t *)key);
        break;
      case TSDB_DATA_TYPE_BINARY:
        fprintf(stdout, "%d: %s \n", id++, key);
        break;
      case TSDB_DATA_TYPE_DOUBLE:
        fprintf(stdout, "%d: %lf \n", id++, *(double *)key);
        break;
      default:
        fprintf(stdout, "\n");
H
hzcheng 已提交
385
    }
H
TD-1437  
Hongze Cheng 已提交
386 387 388

    prev = SL_GET_NODE_KEY(pSkipList, p);

H
TD-1194  
Hongze Cheng 已提交
389
    p = SL_NODE_GET_FORWARD_POINTER(p, nlevel - 1);
H
hzcheng 已提交
390
  }
H
TD-1437  
Hongze Cheng 已提交
391
}
H
hzcheng 已提交
392

H
Hongze Cheng 已提交
393
static void tSkipListDoInsert(SSkipList *pSkipList, SSkipListNode **direction, SSkipListNode *pNode, bool isForward) {
H
TD-1437  
Hongze Cheng 已提交
394
  for (int32_t i = 0; i < pNode->level; ++i) {
H
Hongze Cheng 已提交
395 396 397 398 399 400 401 402 403
    SSkipListNode *x = direction[i];
    if (isForward) {
      SL_NODE_GET_BACKWARD_POINTER(pNode, i) = x;

      SSkipListNode *next = SL_NODE_GET_FORWARD_POINTER(x, i);
      SL_NODE_GET_BACKWARD_POINTER(next, i) = pNode;

      SL_NODE_GET_FORWARD_POINTER(pNode, i) = next;
      SL_NODE_GET_FORWARD_POINTER(x, i) = pNode;
H
TD-1194  
Hongze Cheng 已提交
404
    } else {
H
Hongze Cheng 已提交
405
      SL_NODE_GET_FORWARD_POINTER(pNode, i) = x;
H
TD-1437  
Hongze Cheng 已提交
406

H
Hongze Cheng 已提交
407 408
      SSkipListNode *prev = SL_NODE_GET_BACKWARD_POINTER(x, i);
      SL_NODE_GET_FORWARD_POINTER(prev, i) = pNode;
H
TD-1437  
Hongze Cheng 已提交
409

H
Hongze Cheng 已提交
410
      SL_NODE_GET_BACKWARD_POINTER(pNode, i) = prev;
H
Hongze Cheng 已提交
411
      SL_NODE_GET_BACKWARD_POINTER(x, i) = pNode;
H
TD-1194  
Hongze Cheng 已提交
412
    }
H
TD-1437  
Hongze Cheng 已提交
413 414
  }

H
TD-1194  
Hongze Cheng 已提交
415 416 417
  if (pSkipList->level < pNode->level) pSkipList->level = pNode->level;

  pSkipList->size += 1;
H
hzcheng 已提交
418 419
}

H
TD-1437  
Hongze Cheng 已提交
420 421 422 423 424 425 426
static SSkipListIterator *doCreateSkipListIterator(SSkipList *pSkipList, int32_t order) {
  SSkipListIterator *iter = calloc(1, sizeof(SSkipListIterator));

  iter->pSkipList = pSkipList;
  iter->order = order;
  if (order == TSDB_ORDER_ASC) {
    iter->cur = pSkipList->pHead;
H
Hongze Cheng 已提交
427
    iter->next = SL_NODE_GET_FORWARD_POINTER(iter->cur, 0);
H
TD-1437  
Hongze Cheng 已提交
428 429
  } else {
    iter->cur = pSkipList->pTail;
H
Hongze Cheng 已提交
430
    iter->next = SL_NODE_GET_BACKWARD_POINTER(iter->cur, 0);
H
hzcheng 已提交
431 432
  }

H
TD-1437  
Hongze Cheng 已提交
433 434 435
  return iter;
}

S
Shengliang Guan 已提交
436
static FORCE_INLINE int32_t tSkipListWLock(SSkipList *pSkipList) {
H
TD-1194  
Hongze Cheng 已提交
437
  if (pSkipList->lock) {
H
TD-1437  
Hongze Cheng 已提交
438
    return pthread_rwlock_wrlock(pSkipList->lock);
H
more  
hzcheng 已提交
439
  }
H
TD-1437  
Hongze Cheng 已提交
440 441
  return 0;
}
H
hzcheng 已提交
442

S
Shengliang Guan 已提交
443
static FORCE_INLINE int32_t tSkipListRLock(SSkipList *pSkipList) {
H
TD-1194  
Hongze Cheng 已提交
444
  if (pSkipList->lock) {
H
TD-1437  
Hongze Cheng 已提交
445 446 447 448
    return pthread_rwlock_rdlock(pSkipList->lock);
  }
  return 0;
}
H
hzcheng 已提交
449

S
Shengliang Guan 已提交
450
static FORCE_INLINE int32_t tSkipListUnlock(SSkipList *pSkipList) {
H
TD-1194  
Hongze Cheng 已提交
451
  if (pSkipList->lock) {
H
TD-1437  
Hongze Cheng 已提交
452
    return pthread_rwlock_unlock(pSkipList->lock);
H
more  
hzcheng 已提交
453
  }
H
TD-1437  
Hongze Cheng 已提交
454 455
  return 0;
}
H
hzcheng 已提交
456

H
Hongze Cheng 已提交
457
static bool tSkipListGetPosToPut(SSkipList *pSkipList, SSkipListNode **backward, void *pData) {
S
Shengliang Guan 已提交
458
  int32_t compare = 0;
H
TD-1437  
Hongze Cheng 已提交
459
  bool    hasDupKey = false;
S
Shengliang Guan 已提交
460
  char   *pDataKey = pSkipList->keyFn(pData);
H
hzcheng 已提交
461

H
TD-1437  
Hongze Cheng 已提交
462
  if (pSkipList->size == 0) {
S
Shengliang Guan 已提交
463
    for (int32_t i = 0; i < pSkipList->maxLevel; i++) {
H
Hongze Cheng 已提交
464
      backward[i] = pSkipList->pTail;
H
TD-1437  
Hongze Cheng 已提交
465 466 467 468
    }
  } else {
    char *pKey = NULL;

H
Hongze Cheng 已提交
469 470
    // Compare max key
    pKey = SL_GET_MAX_KEY(pSkipList);
H
TD-1194  
Hongze Cheng 已提交
471
    compare = pSkipList->comparFn(pDataKey, pKey);
H
Hongze Cheng 已提交
472
    if (compare >= 0) {
S
Shengliang Guan 已提交
473
      for (int32_t i = 0; i < pSkipList->maxLevel; i++) {
H
Hongze Cheng 已提交
474
        backward[i] = pSkipList->pTail;
H
TD-1437  
Hongze Cheng 已提交
475
      }
H
TD-1194  
Hongze Cheng 已提交
476

H
TD-1437  
Hongze Cheng 已提交
477 478 479
      return (compare == 0);
    }

H
Hongze Cheng 已提交
480 481
    // Compare min key
    pKey = SL_GET_MIN_KEY(pSkipList);
H
TD-1194  
Hongze Cheng 已提交
482
    compare = pSkipList->comparFn(pDataKey, pKey);
H
Hongze Cheng 已提交
483
    if (compare < 0) {
S
Shengliang Guan 已提交
484
      for (int32_t i = 0; i < pSkipList->maxLevel; i++) {
H
Hongze Cheng 已提交
485
        backward[i] = SL_NODE_GET_FORWARD_POINTER(pSkipList->pHead, i);
H
TD-1437  
Hongze Cheng 已提交
486 487 488 489 490
      }

      return (compare == 0);
    }

H
Hongze Cheng 已提交
491
    SSkipListNode *px = pSkipList->pTail;
S
Shengliang Guan 已提交
492
    for (int32_t i = pSkipList->maxLevel - 1; i >= 0; --i) {
H
Hongze Cheng 已提交
493 494 495 496 497 498 499 500 501 502 503 504 505
      if (i < pSkipList->level) {
        SSkipListNode *p = SL_NODE_GET_BACKWARD_POINTER(px, i);
        while (p != pSkipList->pHead) {
          pKey = SL_GET_NODE_KEY(pSkipList, p);

          compare = pSkipList->comparFn(pKey, pDataKey);
          if (compare <= 0) {
            if (compare == 0 && !hasDupKey) hasDupKey = true;
            break;
          } else {
            px = p;
            p = SL_NODE_GET_BACKWARD_POINTER(px, i);
          }
H
TD-1437  
Hongze Cheng 已提交
506 507 508
        }
      }

H
Hongze Cheng 已提交
509
      backward[i] = px;
H
TD-1437  
Hongze Cheng 已提交
510
    }
H
hzcheng 已提交
511 512
  }

H
TD-1437  
Hongze Cheng 已提交
513
  return hasDupKey;
H
hzcheng 已提交
514 515
}

H
TD-1437  
Hongze Cheng 已提交
516 517
static void tSkipListRemoveNodeImpl(SSkipList *pSkipList, SSkipListNode *pNode) {
  int32_t level = pNode->level;
H
TD-1194  
Hongze Cheng 已提交
518
  uint8_t dupMode = SL_DUP_MODE(pSkipList);
H
TD-1548  
Hongze Cheng 已提交
519
  ASSERT(dupMode != SL_DISCARD_DUP_KEY && dupMode != SL_UPDATE_DUP_KEY);
H
TD-1437  
Hongze Cheng 已提交
520

H
TD-1548  
Hongze Cheng 已提交
521 522 523
  for (int32_t j = level - 1; j >= 0; --j) {
    SSkipListNode *prev = SL_NODE_GET_BACKWARD_POINTER(pNode, j);
    SSkipListNode *next = SL_NODE_GET_FORWARD_POINTER(pNode, j);
H
TD-1437  
Hongze Cheng 已提交
524

H
TD-1548  
Hongze Cheng 已提交
525 526
    SL_NODE_GET_FORWARD_POINTER(prev, j) = next;
    SL_NODE_GET_BACKWARD_POINTER(next, j) = prev;
H
hzcheng 已提交
527
  }
H
TD-1548  
Hongze Cheng 已提交
528 529 530

  tSkipListFreeNode(pNode);
  pSkipList->size--;
H
hzcheng 已提交
531 532
}

H
TD-1437  
Hongze Cheng 已提交
533 534
// Function must be called after calling tSkipListRemoveNodeImpl() function
static void tSkipListCorrectLevel(SSkipList *pSkipList) {
S
Shengliang Guan 已提交
535 536
  while (pSkipList->level > 0 &&
         SL_NODE_GET_FORWARD_POINTER(pSkipList->pHead, pSkipList->level - 1) == pSkipList->pTail) {
H
TD-1437  
Hongze Cheng 已提交
537
    pSkipList->level -= 1;
H
hzcheng 已提交
538
  }
H
TD-1437  
Hongze Cheng 已提交
539
}
H
hzcheng 已提交
540

H
TD-1437  
Hongze Cheng 已提交
541 542 543 544 545
UNUSED_FUNC 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]++;
H
more  
hzcheng 已提交
546
  }
H
TD-1437  
Hongze Cheng 已提交
547 548 549 550 551 552 553
#endif
}

UNUSED_FUNC 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]--;
554
  }
H
TD-1437  
Hongze Cheng 已提交
555 556 557 558 559 560 561
#endif
}

static FORCE_INLINE int32_t getSkipListNodeRandomHeight(SSkipList *pSkipList) {
  const uint32_t factor = 4;

  int32_t n = 1;
S
Shengliang Guan 已提交
562
#if defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32)
wafwerar's avatar
wafwerar 已提交
563
  while ((taosRand() % factor) == 0 && n <= pSkipList->maxLevel) {
S
Shengliang Guan 已提交
564
#else
wafwerar's avatar
wafwerar 已提交
565
  while ((taosRandR(&(pSkipList->seed)) % factor) == 0 && n <= pSkipList->maxLevel) {
S
Shengliang Guan 已提交
566
#endif
H
TD-1437  
Hongze Cheng 已提交
567
    n++;
568
  }
H
hzcheng 已提交
569

H
TD-1437  
Hongze Cheng 已提交
570 571 572 573 574 575 576 577 578 579 580 581
  return n;
}

static FORCE_INLINE int32_t getSkipListRandLevel(SSkipList *pSkipList) {
  int32_t level = 0;
  if (pSkipList->size == 0) {
    level = 1;
  } else {
    level = getSkipListNodeRandomHeight(pSkipList);
    if (level > pSkipList->level) {
      if (pSkipList->level < pSkipList->maxLevel) {
        level = pSkipList->level + 1;
H
more  
hzcheng 已提交
582
      } else {
H
TD-1437  
Hongze Cheng 已提交
583
        level = pSkipList->level;
H
more  
hzcheng 已提交
584
      }
H
hzcheng 已提交
585 586 587
    }
  }

H
TD-1194  
Hongze Cheng 已提交
588
  ASSERT(level <= pSkipList->maxLevel);
H
TD-1437  
Hongze Cheng 已提交
589 590
  return level;
}
591

H
TD-1437  
Hongze Cheng 已提交
592 593
// when order is TSDB_ORDER_ASC, return the last node with key less than val
// when order is TSDB_ORDER_DESC, return the first node with key large than val
H
Hongze Cheng 已提交
594
static SSkipListNode *getPriorNode(SSkipList *pSkipList, const char *val, int32_t order, SSkipListNode **pCur) {
H
TD-1437  
Hongze Cheng 已提交
595 596
  __compar_fn_t  comparFn = pSkipList->comparFn;
  SSkipListNode *pNode = NULL;
H
Hongze Cheng 已提交
597 598 599
  if (pCur != NULL) {
    *pCur = NULL;
  }
H
TD-1437  
Hongze Cheng 已提交
600 601 602 603

  if (order == TSDB_ORDER_ASC) {
    pNode = pSkipList->pHead;
    for (int32_t i = pSkipList->level - 1; i >= 0; --i) {
H
TD-1194  
Hongze Cheng 已提交
604
      SSkipListNode *p = SL_NODE_GET_FORWARD_POINTER(pNode, i);
H
TD-1437  
Hongze Cheng 已提交
605 606 607 608
      while (p != pSkipList->pTail) {
        char *key = SL_GET_NODE_KEY(pSkipList, p);
        if (comparFn(key, val) < 0) {
          pNode = p;
H
TD-1194  
Hongze Cheng 已提交
609
          p = SL_NODE_GET_FORWARD_POINTER(p, i);
H
TD-1437  
Hongze Cheng 已提交
610
        } else {
H
Hongze Cheng 已提交
611 612 613
          if (pCur != NULL) {
            *pCur = p;
          }
H
TD-1437  
Hongze Cheng 已提交
614 615 616 617 618 619 620
          break;
        }
      }
    }
  } else {
    pNode = pSkipList->pTail;
    for (int32_t i = pSkipList->level - 1; i >= 0; --i) {
H
TD-1194  
Hongze Cheng 已提交
621
      SSkipListNode *p = SL_NODE_GET_BACKWARD_POINTER(pNode, i);
H
TD-1437  
Hongze Cheng 已提交
622 623 624 625
      while (p != pSkipList->pHead) {
        char *key = SL_GET_NODE_KEY(pSkipList, p);
        if (comparFn(key, val) > 0) {
          pNode = p;
H
TD-1194  
Hongze Cheng 已提交
626
          p = SL_NODE_GET_BACKWARD_POINTER(p, i);
H
TD-1437  
Hongze Cheng 已提交
627
        } else {
H
Hongze Cheng 已提交
628 629 630
          if (pCur != NULL) {
            *pCur = p;
          }
H
TD-1437  
Hongze Cheng 已提交
631 632 633 634
          break;
        }
      }
    }
H
hzcheng 已提交
635
  }
H
TD-1437  
Hongze Cheng 已提交
636

H
hzcheng 已提交
637 638 639
  return pNode;
}

S
Shengliang Guan 已提交
640
static int32_t initForwardBackwardPtr(SSkipList *pSkipList) {
H
TD-1437  
Hongze Cheng 已提交
641
  uint32_t maxLevel = pSkipList->maxLevel;
642

H
TD-1437  
Hongze Cheng 已提交
643
  // head info
H
TD-1194  
Hongze Cheng 已提交
644 645
  pSkipList->pHead = tSkipListNewNode(maxLevel);
  if (pSkipList->pHead == NULL) return -1;
646

H
TD-1437  
Hongze Cheng 已提交
647
  // tail info
H
TD-1194  
Hongze Cheng 已提交
648 649 650 651 652
  pSkipList->pTail = tSkipListNewNode(maxLevel);
  if (pSkipList->pTail == NULL) {
    tSkipListFreeNode(pSkipList->pHead);
    return -1;
  }
H
TD-1437  
Hongze Cheng 已提交
653 654

  for (uint32_t i = 0; i < maxLevel; ++i) {
H
TD-1194  
Hongze Cheng 已提交
655 656
    SL_NODE_GET_FORWARD_POINTER(pSkipList->pHead, i) = pSkipList->pTail;
    SL_NODE_GET_BACKWARD_POINTER(pSkipList->pTail, i) = pSkipList->pHead;
657 658
  }

H
TD-1437  
Hongze Cheng 已提交
659
  return 0;
H
more  
hzcheng 已提交
660 661
}

H
TD-1194  
Hongze Cheng 已提交
662 663
static SSkipListNode *tSkipListNewNode(uint8_t level) {
  int32_t tsize = sizeof(SSkipListNode) + sizeof(SSkipListNode *) * level * 2;
664

H
TD-1194  
Hongze Cheng 已提交
665 666
  SSkipListNode *pNode = (SSkipListNode *)calloc(1, tsize);
  if (pNode == NULL) return NULL;
H
TD-1437  
Hongze Cheng 已提交
667

H
TD-1194  
Hongze Cheng 已提交
668 669
  pNode->level = level;
  return pNode;
H
hjxilinx 已提交
670 671
}

H
Hongze Cheng 已提交
672 673 674 675 676
static SSkipListNode *tSkipListPutImpl(SSkipList *pSkipList, void *pData, SSkipListNode **direction, bool isForward,
                                       bool hasDup) {
  uint8_t        dupMode = SL_DUP_MODE(pSkipList);
  SSkipListNode *pNode = NULL;

677
  if (hasDup && (dupMode != SL_ALLOW_DUP_KEY)) {
H
Hongze Cheng 已提交
678 679 680 681 682 683
    if (dupMode == SL_UPDATE_DUP_KEY) {
      if (isForward) {
        pNode = SL_NODE_GET_FORWARD_POINTER(direction[0], 0);
      } else {
        pNode = SL_NODE_GET_BACKWARD_POINTER(direction[0], 0);
      }
684 685 686 687 688
      if (pSkipList->insertHandleFn) {
        pSkipList->insertHandleFn->args[0] = pData;
        pSkipList->insertHandleFn->args[1] = pNode->pData;
        pData = genericInvoke(pSkipList->insertHandleFn);
      }
S
Shengliang Guan 已提交
689
      if (pData) {
690 691 692
        atomic_store_ptr(&(pNode->pData), pData);
      }
    } else {
S
Shengliang Guan 已提交
693 694
      // for compatiblity, duplicate key inserted when update=0 should be also calculated as affected rows!
      if (pSkipList->insertHandleFn) {
695 696 697 698
        pSkipList->insertHandleFn->args[0] = NULL;
        pSkipList->insertHandleFn->args[1] = NULL;
        genericInvoke(pSkipList->insertHandleFn);
      }
H
Hongze Cheng 已提交
699 700 701 702
    }
  } else {
    pNode = tSkipListNewNode(getSkipListRandLevel(pSkipList));
    if (pNode != NULL) {
703 704 705 706 707 708 709 710
      // insertHandleFn will be assigned only for timeseries data,
      // in which case, pData is pointed to an memory to be freed later;
      // while for metadata, the mem alloc will not be called.
      if (pSkipList->insertHandleFn) {
        pSkipList->insertHandleFn->args[0] = pData;
        pSkipList->insertHandleFn->args[1] = NULL;
        pData = genericInvoke(pSkipList->insertHandleFn);
      }
H
Hongze Cheng 已提交
711 712 713 714 715 716 717 718
      pNode->pData = pData;

      tSkipListDoInsert(pSkipList, direction, pNode, isForward);
    }
  }

  return pNode;
}