indexCache.c 24.2 KB
Newer Older
dengyihao's avatar
dengyihao 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*
 * 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.
 *
 * 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/>.
 */

dengyihao's avatar
dengyihao 已提交
16 17 18
#include "indexCache.h"
#include "indexComm.h"
#include "indexUtil.h"
19
#include "tcompare.h"
dengyihao's avatar
dengyihao 已提交
20
#include "tsched.h"
dengyihao's avatar
dengyihao 已提交
21

22
#define MAX_INDEX_KEY_LEN 256  // test only, change later
dengyihao's avatar
dengyihao 已提交
23

dengyihao's avatar
dengyihao 已提交
24
#define MEM_TERM_LIMIT     10 * 10000
dengyihao's avatar
dengyihao 已提交
25
#define MEM_THRESHOLD      64 * 1024
dengyihao's avatar
dengyihao 已提交
26
#define MEM_SIGNAL_QUIT    MEM_THRESHOLD * 20
dengyihao's avatar
dengyihao 已提交
27
#define MEM_ESTIMATE_RADIO 1.5
dengyihao's avatar
dengyihao 已提交
28

dengyihao's avatar
dengyihao 已提交
29 30
static void idxMemRef(MemTable* tbl);
static void idxMemUnRef(MemTable* tbl);
31

dengyihao's avatar
dengyihao 已提交
32 33 34 35
static void    idxCacheTermDestroy(CacheTerm* ct);
static int32_t idxCacheTermCompare(const void* l, const void* r);
static int32_t idxCacheJsonTermCompare(const void* l, const void* r);
static char*   idxCacheTermGet(const void* pData);
36

dengyihao's avatar
dengyihao 已提交
37
static MemTable* idxInternalCacheCreate(int8_t type);
38

dengyihao's avatar
dengyihao 已提交
39 40 41 42 43 44 45 46 47
static int32_t cacheSearchTerm(void* cache, SIndexTerm* ct, SIdxTRslt* tr, STermValueType* s);
static int32_t cacheSearchPrefix(void* cache, SIndexTerm* ct, SIdxTRslt* tr, STermValueType* s);
static int32_t cacheSearchSuffix(void* cache, SIndexTerm* ct, SIdxTRslt* tr, STermValueType* s);
static int32_t cacheSearchRegex(void* cache, SIndexTerm* ct, SIdxTRslt* tr, STermValueType* s);
static int32_t cacheSearchLessThan(void* cache, SIndexTerm* ct, SIdxTRslt* tr, STermValueType* s);
static int32_t cacheSearchLessEqual(void* cache, SIndexTerm* ct, SIdxTRslt* tr, STermValueType* s);
static int32_t cacheSearchGreaterThan(void* cache, SIndexTerm* ct, SIdxTRslt* tr, STermValueType* s);
static int32_t cacheSearchGreaterEqual(void* cache, SIndexTerm* ct, SIdxTRslt* tr, STermValueType* s);
static int32_t cacheSearchRange(void* cache, SIndexTerm* ct, SIdxTRslt* tr, STermValueType* s);
dengyihao's avatar
dengyihao 已提交
48
/*comm func of compare, used in (LE/LT/GE/GT compare)*/
dengyihao's avatar
dengyihao 已提交
49 50
static int32_t cacheSearchCompareFunc(void* cache, SIndexTerm* ct, SIdxTRslt* tr, STermValueType* s, RangeType type);
static int32_t cacheSearchTerm_JSON(void* cache, SIndexTerm* ct, SIdxTRslt* tr, STermValueType* s);
dengyihao's avatar
dengyihao 已提交
51
static int32_t cacheSearchEqual_JSON(void* cache, SIndexTerm* ct, SIdxTRslt* tr, STermValueType* s);
dengyihao's avatar
dengyihao 已提交
52 53 54 55 56 57 58 59 60 61
static int32_t cacheSearchPrefix_JSON(void* cache, SIndexTerm* ct, SIdxTRslt* tr, STermValueType* s);
static int32_t cacheSearchSuffix_JSON(void* cache, SIndexTerm* ct, SIdxTRslt* tr, STermValueType* s);
static int32_t cacheSearchRegex_JSON(void* cache, SIndexTerm* ct, SIdxTRslt* tr, STermValueType* s);
static int32_t cacheSearchLessThan_JSON(void* cache, SIndexTerm* ct, SIdxTRslt* tr, STermValueType* s);
static int32_t cacheSearchLessEqual_JSON(void* cache, SIndexTerm* ct, SIdxTRslt* tr, STermValueType* s);
static int32_t cacheSearchGreaterThan_JSON(void* cache, SIndexTerm* ct, SIdxTRslt* tr, STermValueType* s);
static int32_t cacheSearchGreaterEqual_JSON(void* cache, SIndexTerm* ct, SIdxTRslt* tr, STermValueType* s);
static int32_t cacheSearchRange_JSON(void* cache, SIndexTerm* ct, SIdxTRslt* tr, STermValueType* s);

static int32_t cacheSearchCompareFunc_JSON(void* cache, SIndexTerm* term, SIdxTRslt* tr, STermValueType* s,
dengyihao's avatar
dengyihao 已提交
62
                                           RangeType type);
dengyihao's avatar
dengyihao 已提交
63

dengyihao's avatar
dengyihao 已提交
64
static int32_t (*cacheSearch[][QUERY_MAX])(void* cache, SIndexTerm* ct, SIdxTRslt* tr, STermValueType* s) = {
dengyihao's avatar
dengyihao 已提交
65 66
    {cacheSearchTerm, cacheSearchPrefix, cacheSearchSuffix, cacheSearchRegex, cacheSearchLessThan, cacheSearchLessEqual,
     cacheSearchGreaterThan, cacheSearchGreaterEqual, cacheSearchRange},
dengyihao's avatar
dengyihao 已提交
67
    {cacheSearchEqual_JSON, cacheSearchPrefix_JSON, cacheSearchSuffix_JSON, cacheSearchRegex_JSON,
dengyihao's avatar
dengyihao 已提交
68 69
     cacheSearchLessThan_JSON, cacheSearchLessEqual_JSON, cacheSearchGreaterThan_JSON, cacheSearchGreaterEqual_JSON,
     cacheSearchRange_JSON}};
dengyihao's avatar
dengyihao 已提交
70

dengyihao's avatar
dengyihao 已提交
71
static void idxDoMergeWork(SSchedMsg* msg);
dengyihao's avatar
dengyihao 已提交
72
static bool idxCacheIteratorNext(Iterate* itera);
dengyihao's avatar
dengyihao 已提交
73

dengyihao's avatar
dengyihao 已提交
74
static int32_t cacheSearchTerm(void* cache, SIndexTerm* term, SIdxTRslt* tr, STermValueType* s) {
dengyihao's avatar
dengyihao 已提交
75 76 77
  if (cache == NULL) {
    return 0;
  }
dengyihao's avatar
dengyihao 已提交
78 79
  MemTable*   mem = cache;
  IndexCache* pCache = mem->pCache;
dengyihao's avatar
dengyihao 已提交
80

dengyihao's avatar
dengyihao 已提交
81 82
  CacheTerm* pCt = taosMemoryCalloc(1, sizeof(CacheTerm));
  pCt->colVal = term->colVal;
dengyihao's avatar
dengyihao 已提交
83
  pCt->version = atomic_load_64(&pCache->version);
dengyihao's avatar
dengyihao 已提交
84

dengyihao's avatar
dengyihao 已提交
85
  char* key = idxCacheTermGet(pCt);
dengyihao's avatar
dengyihao 已提交
86 87 88 89 90 91 92 93

  SSkipListIterator* iter = tSkipListCreateIterFromVal(mem->mem, key, TSDB_DATA_TYPE_BINARY, TSDB_ORDER_ASC);
  while (tSkipListIterNext(iter)) {
    SSkipListNode* node = tSkipListIterGet(iter);
    if (node == NULL) {
      break;
    }
    CacheTerm* c = (CacheTerm*)SL_GET_NODE_DATA(node);
dengyihao's avatar
dengyihao 已提交
94
    if (0 == strcmp(c->colVal, pCt->colVal) && strlen(pCt->colVal) == strlen(c->colVal)) {
dengyihao's avatar
dengyihao 已提交
95
      if (c->operaType == ADD_VALUE) {
dengyihao's avatar
dengyihao 已提交
96
        INDEX_MERGE_ADD_DEL(tr->del, tr->add, c->uid)
dengyihao's avatar
dengyihao 已提交
97 98 99
        // taosArrayPush(result, &c->uid);
        *s = kTypeValue;
      } else if (c->operaType == DEL_VALUE) {
dengyihao's avatar
dengyihao 已提交
100
        INDEX_MERGE_ADD_DEL(tr->add, tr->del, c->uid)
dengyihao's avatar
dengyihao 已提交
101 102 103 104 105
      }
    } else {
      break;
    }
  }
dengyihao's avatar
dengyihao 已提交
106 107

  taosMemoryFree(pCt);
dengyihao's avatar
dengyihao 已提交
108
  tSkipListDestroyIter(iter);
dengyihao's avatar
dengyihao 已提交
109 110
  return 0;
}
dengyihao's avatar
dengyihao 已提交
111
static int32_t cacheSearchPrefix(void* cache, SIndexTerm* term, SIdxTRslt* tr, STermValueType* s) {
dengyihao's avatar
dengyihao 已提交
112 113 114
  // impl later
  return 0;
}
dengyihao's avatar
dengyihao 已提交
115
static int32_t cacheSearchSuffix(void* cache, SIndexTerm* term, SIdxTRslt* tr, STermValueType* s) {
dengyihao's avatar
dengyihao 已提交
116 117 118
  // impl later
  return 0;
}
dengyihao's avatar
dengyihao 已提交
119
static int32_t cacheSearchRegex(void* cache, SIndexTerm* term, SIdxTRslt* tr, STermValueType* s) {
dengyihao's avatar
dengyihao 已提交
120 121 122
  // impl later
  return 0;
}
dengyihao's avatar
dengyihao 已提交
123
static int32_t cacheSearchCompareFunc(void* cache, SIndexTerm* term, SIdxTRslt* tr, STermValueType* s, RangeType type) {
dengyihao's avatar
dengyihao 已提交
124 125 126
  if (cache == NULL) {
    return 0;
  }
dengyihao's avatar
dengyihao 已提交
127 128 129
  MemTable*   mem = cache;
  IndexCache* pCache = mem->pCache;

dengyihao's avatar
dengyihao 已提交
130
  _cache_range_compare cmpFn = idxGetCompare(type);
dengyihao's avatar
dengyihao 已提交
131

dengyihao's avatar
dengyihao 已提交
132 133
  CacheTerm* pCt = taosMemoryCalloc(1, sizeof(CacheTerm));
  pCt->colVal = term->colVal;
dengyihao's avatar
dengyihao 已提交
134
  pCt->colType = term->colType;
dengyihao's avatar
dengyihao 已提交
135
  pCt->version = atomic_load_64(&pCache->version);
dengyihao's avatar
dengyihao 已提交
136

dengyihao's avatar
dengyihao 已提交
137
  char* key = idxCacheTermGet(pCt);
dengyihao's avatar
dengyihao 已提交
138 139 140 141 142 143 144 145

  SSkipListIterator* iter = tSkipListCreateIter(mem->mem);
  while (tSkipListIterNext(iter)) {
    SSkipListNode* node = tSkipListIterGet(iter);
    if (node == NULL) {
      break;
    }
    CacheTerm* c = (CacheTerm*)SL_GET_NODE_DATA(node);
dengyihao's avatar
dengyihao 已提交
146
    TExeCond   cond = cmpFn(c->colVal, pCt->colVal, pCt->colType);
dengyihao's avatar
dengyihao 已提交
147 148
    if (cond == MATCH) {
      if (c->operaType == ADD_VALUE) {
dengyihao's avatar
dengyihao 已提交
149
        INDEX_MERGE_ADD_DEL(tr->del, tr->add, c->uid)
dengyihao's avatar
dengyihao 已提交
150 151 152
        // taosArrayPush(result, &c->uid);
        *s = kTypeValue;
      } else if (c->operaType == DEL_VALUE) {
dengyihao's avatar
dengyihao 已提交
153
        INDEX_MERGE_ADD_DEL(tr->add, tr->del, c->uid)
dengyihao's avatar
dengyihao 已提交
154 155
      }
    } else if (cond == CONTINUE) {
dengyihao's avatar
dengyihao 已提交
156
      continue;
dengyihao's avatar
dengyihao 已提交
157 158 159 160
    } else if (cond == BREAK) {
      break;
    }
  }
dengyihao's avatar
dengyihao 已提交
161
  taosMemoryFree(pCt);
dengyihao's avatar
dengyihao 已提交
162 163 164
  tSkipListDestroyIter(iter);
  return TSDB_CODE_SUCCESS;
}
dengyihao's avatar
dengyihao 已提交
165
static int32_t cacheSearchLessThan(void* cache, SIndexTerm* term, SIdxTRslt* tr, STermValueType* s) {
dengyihao's avatar
dengyihao 已提交
166 167
  return cacheSearchCompareFunc(cache, term, tr, s, LT);
}
dengyihao's avatar
dengyihao 已提交
168
static int32_t cacheSearchLessEqual(void* cache, SIndexTerm* term, SIdxTRslt* tr, STermValueType* s) {
dengyihao's avatar
dengyihao 已提交
169
  return cacheSearchCompareFunc(cache, term, tr, s, LE);
dengyihao's avatar
dengyihao 已提交
170
}
dengyihao's avatar
dengyihao 已提交
171
static int32_t cacheSearchGreaterThan(void* cache, SIndexTerm* term, SIdxTRslt* tr, STermValueType* s) {
dengyihao's avatar
dengyihao 已提交
172 173
  return cacheSearchCompareFunc(cache, term, tr, s, GT);
}
dengyihao's avatar
dengyihao 已提交
174
static int32_t cacheSearchGreaterEqual(void* cache, SIndexTerm* term, SIdxTRslt* tr, STermValueType* s) {
dengyihao's avatar
dengyihao 已提交
175 176 177
  return cacheSearchCompareFunc(cache, term, tr, s, GE);
}

dengyihao's avatar
dengyihao 已提交
178
static int32_t cacheSearchTerm_JSON(void* cache, SIndexTerm* term, SIdxTRslt* tr, STermValueType* s) {
dengyihao's avatar
dengyihao 已提交
179 180 181 182 183 184 185 186
  if (cache == NULL) {
    return 0;
  }
  MemTable*   mem = cache;
  IndexCache* pCache = mem->pCache;

  CacheTerm* pCt = taosMemoryCalloc(1, sizeof(CacheTerm));
  pCt->colVal = term->colVal;
dengyihao's avatar
dengyihao 已提交
187
  pCt->version = atomic_load_64(&pCache->version);
dengyihao's avatar
dengyihao 已提交
188 189

  char* exBuf = NULL;
dengyihao's avatar
dengyihao 已提交
190
  if (IDX_TYPE_CONTAIN_EXTERN_TYPE(term->colType, TSDB_DATA_TYPE_JSON)) {
dengyihao's avatar
dengyihao 已提交
191
    exBuf = idxPackJsonData(term);
dengyihao's avatar
dengyihao 已提交
192 193
    pCt->colVal = exBuf;
  }
dengyihao's avatar
dengyihao 已提交
194
  char* key = idxCacheTermGet(pCt);
dengyihao's avatar
dengyihao 已提交
195 196 197 198 199 200 201 202

  SSkipListIterator* iter = tSkipListCreateIterFromVal(mem->mem, key, TSDB_DATA_TYPE_BINARY, TSDB_ORDER_ASC);
  while (tSkipListIterNext(iter)) {
    SSkipListNode* node = tSkipListIterGet(iter);
    if (node == NULL) {
      break;
    }
    CacheTerm* c = (CacheTerm*)SL_GET_NODE_DATA(node);
203

dengyihao's avatar
dengyihao 已提交
204 205
    if (0 == strcmp(c->colVal, pCt->colVal)) {
      if (c->operaType == ADD_VALUE) {
dengyihao's avatar
dengyihao 已提交
206
        INDEX_MERGE_ADD_DEL(tr->del, tr->add, c->uid)
dengyihao's avatar
dengyihao 已提交
207 208 209
        // taosArrayPush(result, &c->uid);
        *s = kTypeValue;
      } else if (c->operaType == DEL_VALUE) {
dengyihao's avatar
dengyihao 已提交
210
        INDEX_MERGE_ADD_DEL(tr->add, tr->del, c->uid)
dengyihao's avatar
dengyihao 已提交
211 212 213 214 215 216 217 218 219 220 221
      }
    } else {
      break;
    }
  }

  taosMemoryFree(pCt);
  taosMemoryFree(exBuf);
  tSkipListDestroyIter(iter);
  return 0;

dengyihao's avatar
dengyihao 已提交
222 223
  return TSDB_CODE_SUCCESS;
}
dengyihao's avatar
dengyihao 已提交
224
static int32_t cacheSearchSuffix_JSON(void* cache, SIndexTerm* term, SIdxTRslt* tr, STermValueType* s) {
dengyihao's avatar
dengyihao 已提交
225 226
  return TSDB_CODE_SUCCESS;
}
dengyihao's avatar
dengyihao 已提交
227
static int32_t cacheSearchRegex_JSON(void* cache, SIndexTerm* term, SIdxTRslt* tr, STermValueType* s) {
dengyihao's avatar
dengyihao 已提交
228
  return TSDB_CODE_SUCCESS;
dengyihao's avatar
dengyihao 已提交
229
}
dengyihao's avatar
dengyihao 已提交
230 231 232 233 234 235
static int32_t cacheSearchEqual_JSON(void* cache, SIndexTerm* term, SIdxTRslt* tr, STermValueType* s) {
  return cacheSearchCompareFunc_JSON(cache, term, tr, s, EQ);
}
static int32_t cacheSearchPrefix_JSON(void* cache, SIndexTerm* term, SIdxTRslt* tr, STermValueType* s) {
  return cacheSearchCompareFunc_JSON(cache, term, tr, s, CONTAINS);
}
dengyihao's avatar
dengyihao 已提交
236
static int32_t cacheSearchLessThan_JSON(void* cache, SIndexTerm* term, SIdxTRslt* tr, STermValueType* s) {
dengyihao's avatar
dengyihao 已提交
237
  return cacheSearchCompareFunc_JSON(cache, term, tr, s, LT);
dengyihao's avatar
dengyihao 已提交
238
}
dengyihao's avatar
dengyihao 已提交
239
static int32_t cacheSearchLessEqual_JSON(void* cache, SIndexTerm* term, SIdxTRslt* tr, STermValueType* s) {
dengyihao's avatar
dengyihao 已提交
240
  return cacheSearchCompareFunc_JSON(cache, term, tr, s, LE);
dengyihao's avatar
dengyihao 已提交
241
}
dengyihao's avatar
dengyihao 已提交
242
static int32_t cacheSearchGreaterThan_JSON(void* cache, SIndexTerm* term, SIdxTRslt* tr, STermValueType* s) {
dengyihao's avatar
dengyihao 已提交
243 244
  return cacheSearchCompareFunc_JSON(cache, term, tr, s, GT);
}
dengyihao's avatar
dengyihao 已提交
245
static int32_t cacheSearchGreaterEqual_JSON(void* cache, SIndexTerm* term, SIdxTRslt* tr, STermValueType* s) {
dengyihao's avatar
dengyihao 已提交
246 247
  return cacheSearchCompareFunc_JSON(cache, term, tr, s, GE);
}
dengyihao's avatar
dengyihao 已提交
248 249 250
static int32_t cacheSearchContain_JSON(void* cache, SIndexTerm* term, SIdxTRslt* tr, STermValueType* s) {
  return cacheSearchCompareFunc_JSON(cache, term, tr, s, CONTAINS);
}
dengyihao's avatar
dengyihao 已提交
251
static int32_t cacheSearchRange_JSON(void* cache, SIndexTerm* term, SIdxTRslt* tr, STermValueType* s) {
dengyihao's avatar
dengyihao 已提交
252 253 254
  return TSDB_CODE_SUCCESS;
}

dengyihao's avatar
dengyihao 已提交
255
static int32_t cacheSearchCompareFunc_JSON(void* cache, SIndexTerm* term, SIdxTRslt* tr, STermValueType* s,
dengyihao's avatar
dengyihao 已提交
256
                                           RangeType type) {
dengyihao's avatar
dengyihao 已提交
257 258 259
  if (cache == NULL) {
    return 0;
  }
dengyihao's avatar
dengyihao 已提交
260
  _cache_range_compare cmpFn = idxGetCompare(type);
dengyihao's avatar
dengyihao 已提交
261 262 263 264 265 266

  MemTable*   mem = cache;
  IndexCache* pCache = mem->pCache;

  CacheTerm* pCt = taosMemoryCalloc(1, sizeof(CacheTerm));
  pCt->colVal = term->colVal;
dengyihao's avatar
dengyihao 已提交
267
  pCt->version = atomic_load_64(&pCache->version);
dengyihao's avatar
dengyihao 已提交
268

dengyihao's avatar
dengyihao 已提交
269
  int8_t dType = IDX_TYPE_GET_TYPE(term->colType);
dengyihao's avatar
dengyihao 已提交
270 271
  int    skip = 0;
  char*  exBuf = NULL;
dengyihao's avatar
dengyihao 已提交
272 273 274 275 276 277
  if (type == CONTAINS) {
    SIndexTerm tm = {.suid = term->suid,
                     .operType = term->operType,
                     .colType = term->colType,
                     .colName = term->colVal,
                     .nColName = term->nColVal};
dengyihao's avatar
dengyihao 已提交
278
    exBuf = idxPackJsonDataPrefixNoType(&tm, &skip);
dengyihao's avatar
dengyihao 已提交
279 280
    pCt->colVal = exBuf;
  } else {
dengyihao's avatar
dengyihao 已提交
281
    exBuf = idxPackJsonDataPrefix(term, &skip);
dengyihao's avatar
dengyihao 已提交
282 283
    pCt->colVal = exBuf;
  }
dengyihao's avatar
dengyihao 已提交
284
  char* key = idxCacheTermGet(pCt);
dengyihao's avatar
dengyihao 已提交
285 286 287 288 289 290 291 292

  SSkipListIterator* iter = tSkipListCreateIterFromVal(mem->mem, key, TSDB_DATA_TYPE_BINARY, TSDB_ORDER_ASC);
  while (tSkipListIterNext(iter)) {
    SSkipListNode* node = tSkipListIterGet(iter);
    if (node == NULL) {
      break;
    }
    CacheTerm* c = (CacheTerm*)SL_GET_NODE_DATA(node);
dengyihao's avatar
dengyihao 已提交
293 294 295 296 297 298
    TExeCond   cond = CONTINUE;
    if (type == CONTAINS) {
      if (0 == strncmp(c->colVal, pCt->colVal, skip)) {
        cond = MATCH;
      }
    } else {
dengyihao's avatar
dengyihao 已提交
299
      if (0 != strncmp(c->colVal, pCt->colVal, skip - 1)) {
dengyihao's avatar
dengyihao 已提交
300
        break;
dengyihao's avatar
dengyihao 已提交
301 302 303 304 305 306
      } else if (0 != strncmp(c->colVal, pCt->colVal, skip)) {
        continue;
      } else {
        char* p = taosMemoryCalloc(1, strlen(c->colVal) + 1);
        memcpy(p, c->colVal, strlen(c->colVal));
        cond = cmpFn(p + skip, term->colVal, dType);
dengyihao's avatar
dengyihao 已提交
307
      }
308
    }
dengyihao's avatar
dengyihao 已提交
309 310
    if (cond == MATCH) {
      if (c->operaType == ADD_VALUE) {
dengyihao's avatar
dengyihao 已提交
311
        INDEX_MERGE_ADD_DEL(tr->del, tr->add, c->uid)
dengyihao's avatar
dengyihao 已提交
312 313 314
        // taosArrayPush(result, &c->uid);
        *s = kTypeValue;
      } else if (c->operaType == DEL_VALUE) {
dengyihao's avatar
dengyihao 已提交
315
        INDEX_MERGE_ADD_DEL(tr->add, tr->del, c->uid)
dengyihao's avatar
dengyihao 已提交
316 317 318 319 320 321 322 323 324 325 326 327
      }
    } else if (cond == CONTINUE) {
      continue;
    } else if (cond == BREAK) {
      break;
    }
  }

  taosMemoryFree(pCt);
  taosMemoryFree(exBuf);
  tSkipListDestroyIter(iter);

dengyihao's avatar
dengyihao 已提交
328 329
  return TSDB_CODE_SUCCESS;
}
dengyihao's avatar
dengyihao 已提交
330
static int32_t cacheSearchRange(void* cache, SIndexTerm* term, SIdxTRslt* tr, STermValueType* s) {
dengyihao's avatar
dengyihao 已提交
331 332 333
  // impl later
  return 0;
}
dengyihao's avatar
dengyihao 已提交
334
static IterateValue* idxCacheIteratorGetValue(Iterate* iter);
dengyihao's avatar
dengyihao 已提交
335

dengyihao's avatar
dengyihao 已提交
336
IndexCache* idxCacheCreate(SIndex* idx, uint64_t suid, const char* colName, int8_t type) {
wafwerar's avatar
wafwerar 已提交
337
  IndexCache* cache = taosMemoryCalloc(1, sizeof(IndexCache));
dengyihao's avatar
dengyihao 已提交
338 339 340
  if (cache == NULL) {
    indexError("failed to create index cache");
    return NULL;
dengyihao's avatar
dengyihao 已提交
341
  };
dengyihao's avatar
dengyihao 已提交
342

dengyihao's avatar
dengyihao 已提交
343
  cache->mem = idxInternalCacheCreate(type);
dengyihao's avatar
dengyihao 已提交
344
  cache->mem->pCache = cache;
dengyihao's avatar
dengyihao 已提交
345
  cache->colName = IDX_TYPE_CONTAIN_EXTERN_TYPE(type, TSDB_DATA_TYPE_JSON) ? tstrdup(JSON_COLUMN) : tstrdup(colName);
dengyihao's avatar
dengyihao 已提交
346 347 348
  cache->type = type;
  cache->index = idx;
  cache->version = 0;
dengyihao's avatar
dengyihao 已提交
349
  cache->suid = suid;
dengyihao's avatar
dengyihao 已提交
350
  cache->occupiedMem = 0;
dengyihao's avatar
dengyihao 已提交
351

wafwerar's avatar
wafwerar 已提交
352 353
  taosThreadMutexInit(&cache->mtx, NULL);
  taosThreadCondInit(&cache->finished, NULL);
dengyihao's avatar
dengyihao 已提交
354

dengyihao's avatar
dengyihao 已提交
355
  idxCacheRef(cache);
356
  if (idx != NULL) {
dengyihao's avatar
dengyihao 已提交
357
    idxAcquireRef(idx->refId);
358
  }
dengyihao's avatar
dengyihao 已提交
359 360
  return cache;
}
dengyihao's avatar
dengyihao 已提交
361
void idxCacheDebug(IndexCache* cache) {
362 363
  MemTable* tbl = NULL;

wafwerar's avatar
wafwerar 已提交
364
  taosThreadMutexLock(&cache->mtx);
365
  tbl = cache->mem;
dengyihao's avatar
dengyihao 已提交
366
  idxMemRef(tbl);
wafwerar's avatar
wafwerar 已提交
367
  taosThreadMutexUnlock(&cache->mtx);
368

dengyihao's avatar
dengyihao 已提交
369 370 371 372 373 374 375 376
  {
    SSkipList*         slt = tbl->mem;
    SSkipListIterator* iter = tSkipListCreateIter(slt);
    while (tSkipListIterNext(iter)) {
      SSkipListNode* node = tSkipListIterGet(iter);
      CacheTerm*     ct = (CacheTerm*)SL_GET_NODE_DATA(node);
      if (ct != NULL) {
        // TODO, add more debug info
dengyihao's avatar
dengyihao 已提交
377
        indexInfo("{colVal: %s, version: %" PRId64 "} \t", ct->colVal, ct->version);
dengyihao's avatar
dengyihao 已提交
378
      }
379
    }
dengyihao's avatar
dengyihao 已提交
380 381
    tSkipListDestroyIter(iter);

dengyihao's avatar
dengyihao 已提交
382
    idxMemUnRef(tbl);
383
  }
384

dengyihao's avatar
dengyihao 已提交
385
  {
wafwerar's avatar
wafwerar 已提交
386
    taosThreadMutexLock(&cache->mtx);
dengyihao's avatar
dengyihao 已提交
387
    tbl = cache->imm;
dengyihao's avatar
dengyihao 已提交
388
    idxMemRef(tbl);
wafwerar's avatar
wafwerar 已提交
389
    taosThreadMutexUnlock(&cache->mtx);
dengyihao's avatar
dengyihao 已提交
390 391 392 393 394 395 396 397
    if (tbl != NULL) {
      SSkipList*         slt = tbl->mem;
      SSkipListIterator* iter = tSkipListCreateIter(slt);
      while (tSkipListIterNext(iter)) {
        SSkipListNode* node = tSkipListIterGet(iter);
        CacheTerm*     ct = (CacheTerm*)SL_GET_NODE_DATA(node);
        if (ct != NULL) {
          // TODO, add more debug info
dengyihao's avatar
dengyihao 已提交
398
          indexInfo("{colVal: %s, version: %" PRId64 "} \t", ct->colVal, ct->version);
dengyihao's avatar
dengyihao 已提交
399 400 401 402 403
        }
      }
      tSkipListDestroyIter(iter);
    }

dengyihao's avatar
dengyihao 已提交
404
    idxMemUnRef(tbl);
dengyihao's avatar
dengyihao 已提交
405
  }
406
}
dengyihao's avatar
dengyihao 已提交
407

dengyihao's avatar
dengyihao 已提交
408
void idxCacheDestroySkiplist(SSkipList* slt) {
dengyihao's avatar
dengyihao 已提交
409
  SSkipListIterator* iter = tSkipListCreateIter(slt);
dengyihao's avatar
dengyihao 已提交
410
  while (iter != NULL && tSkipListIterNext(iter)) {
dengyihao's avatar
dengyihao 已提交
411 412
    SSkipListNode* node = tSkipListIterGet(iter);
    CacheTerm*     ct = (CacheTerm*)SL_GET_NODE_DATA(node);
dengyihao's avatar
dengyihao 已提交
413
    if (ct != NULL) {
wafwerar's avatar
wafwerar 已提交
414 415
      taosMemoryFree(ct->colVal);
      taosMemoryFree(ct);
dengyihao's avatar
dengyihao 已提交
416
    }
dengyihao's avatar
dengyihao 已提交
417 418
  }
  tSkipListDestroyIter(iter);
419
  tSkipListDestroy(slt);
dengyihao's avatar
dengyihao 已提交
420
}
dengyihao's avatar
dengyihao 已提交
421
void idxCacheBroadcast(void* cache) {
dengyihao's avatar
dengyihao 已提交
422 423 424
  IndexCache* pCache = cache;
  taosThreadCondBroadcast(&pCache->finished);
}
dengyihao's avatar
dengyihao 已提交
425
void idxCacheWait(void* cache) {
dengyihao's avatar
dengyihao 已提交
426 427 428
  IndexCache* pCache = cache;
  taosThreadCondWait(&pCache->finished, &pCache->mtx);
}
dengyihao's avatar
dengyihao 已提交
429
void idxCacheDestroyImm(IndexCache* cache) {
dengyihao's avatar
dengyihao 已提交
430 431 432
  if (cache == NULL) {
    return;
  }
433
  MemTable* tbl = NULL;
wafwerar's avatar
wafwerar 已提交
434
  taosThreadMutexLock(&cache->mtx);
dengyihao's avatar
dengyihao 已提交
435

436
  tbl = cache->imm;
dengyihao's avatar
dengyihao 已提交
437
  cache->imm = NULL;  // or throw int bg thread
dengyihao's avatar
dengyihao 已提交
438
  idxCacheBroadcast(cache);
dengyihao's avatar
dengyihao 已提交
439

wafwerar's avatar
wafwerar 已提交
440
  taosThreadMutexUnlock(&cache->mtx);
dengyihao's avatar
dengyihao 已提交
441

dengyihao's avatar
dengyihao 已提交
442 443
  idxMemUnRef(tbl);
  idxMemUnRef(tbl);
dengyihao's avatar
dengyihao 已提交
444
}
dengyihao's avatar
dengyihao 已提交
445
void idxCacheDestroy(void* cache) {
dengyihao's avatar
dengyihao 已提交
446
  IndexCache* pCache = cache;
dengyihao's avatar
dengyihao 已提交
447 448 449
  if (pCache == NULL) {
    return;
  }
450

dengyihao's avatar
dengyihao 已提交
451 452
  idxMemUnRef(pCache->mem);
  idxMemUnRef(pCache->imm);
wafwerar's avatar
wafwerar 已提交
453
  taosMemoryFree(pCache->colName);
dengyihao's avatar
dengyihao 已提交
454

wafwerar's avatar
wafwerar 已提交
455 456
  taosThreadMutexDestroy(&pCache->mtx);
  taosThreadCondDestroy(&pCache->finished);
457
  if (pCache->index != NULL) {
dengyihao's avatar
dengyihao 已提交
458
    idxReleaseRef(((SIndex*)pCache->index)->refId);
459
  }
wafwerar's avatar
wafwerar 已提交
460
  taosMemoryFree(pCache);
dengyihao's avatar
dengyihao 已提交
461 462
}

dengyihao's avatar
dengyihao 已提交
463
Iterate* idxCacheIteratorCreate(IndexCache* cache) {
dengyihao's avatar
dengyihao 已提交
464 465 466
  if (cache->imm == NULL) {
    return NULL;
  }
wafwerar's avatar
wafwerar 已提交
467
  Iterate* iiter = taosMemoryCalloc(1, sizeof(Iterate));
dengyihao's avatar
dengyihao 已提交
468 469 470
  if (iiter == NULL) {
    return NULL;
  }
wafwerar's avatar
wafwerar 已提交
471
  taosThreadMutexLock(&cache->mtx);
dengyihao's avatar
dengyihao 已提交
472

dengyihao's avatar
dengyihao 已提交
473
  idxMemRef(cache->imm);
dengyihao's avatar
dengyihao 已提交
474

475
  MemTable* tbl = cache->imm;
dengyihao's avatar
dengyihao 已提交
476
  iiter->val.val = taosArrayInit(1, sizeof(uint64_t));
477
  iiter->val.colVal = NULL;
478
  iiter->iter = tbl != NULL ? tSkipListCreateIter(tbl->mem) : NULL;
dengyihao's avatar
dengyihao 已提交
479
  iiter->next = idxCacheIteratorNext;
dengyihao's avatar
dengyihao 已提交
480
  iiter->getValue = idxCacheIteratorGetValue;
dengyihao's avatar
dengyihao 已提交
481

wafwerar's avatar
wafwerar 已提交
482
  taosThreadMutexUnlock(&cache->mtx);
dengyihao's avatar
dengyihao 已提交
483

dengyihao's avatar
dengyihao 已提交
484 485
  return iiter;
}
dengyihao's avatar
dengyihao 已提交
486
void idxCacheIteratorDestroy(Iterate* iter) {
dengyihao's avatar
dengyihao 已提交
487 488 489
  if (iter == NULL) {
    return;
  }
dengyihao's avatar
dengyihao 已提交
490 491
  tSkipListDestroyIter(iter->iter);
  iterateValueDestroy(&iter->val, true);
wafwerar's avatar
wafwerar 已提交
492
  taosMemoryFree(iter);
dengyihao's avatar
dengyihao 已提交
493
}
dengyihao's avatar
dengyihao 已提交
494

dengyihao's avatar
dengyihao 已提交
495
int idxCacheSchedToMerge(IndexCache* pCache, bool notify) {
dengyihao's avatar
dengyihao 已提交
496
  SSchedMsg schedMsg = {0};
dengyihao's avatar
dengyihao 已提交
497
  schedMsg.fp = idxDoMergeWork;
dengyihao's avatar
dengyihao 已提交
498
  schedMsg.ahandle = pCache;
dengyihao's avatar
dengyihao 已提交
499 500 501
  if (notify) {
    schedMsg.thandle = taosMemoryMalloc(1);
  }
dengyihao's avatar
dengyihao 已提交
502
  schedMsg.msg = NULL;
dengyihao's avatar
dengyihao 已提交
503
  idxAcquireRef(pCache->index->refId);
dengyihao's avatar
dengyihao 已提交
504
  taosScheduleTask(indexQhandle, &schedMsg);
505
  return 0;
dengyihao's avatar
dengyihao 已提交
506
}
507

dengyihao's avatar
dengyihao 已提交
508
static void idxCacheMakeRoomForWrite(IndexCache* cache) {
dengyihao's avatar
dengyihao 已提交
509
  while (true) {
dengyihao's avatar
dengyihao 已提交
510
    if (cache->occupiedMem * MEM_ESTIMATE_RADIO < MEM_THRESHOLD) {
dengyihao's avatar
dengyihao 已提交
511 512 513
      break;
    } else if (cache->imm != NULL) {
      // TODO: wake up by condition variable
dengyihao's avatar
dengyihao 已提交
514
      idxCacheWait(cache);
dengyihao's avatar
dengyihao 已提交
515
    } else {
dengyihao's avatar
dengyihao 已提交
516
      bool quit = cache->occupiedMem >= MEM_SIGNAL_QUIT ? true : false;
dengyihao's avatar
dengyihao 已提交
517

dengyihao's avatar
dengyihao 已提交
518
      idxCacheRef(cache);
dengyihao's avatar
dengyihao 已提交
519
      cache->imm = cache->mem;
dengyihao's avatar
dengyihao 已提交
520
      cache->mem = idxInternalCacheCreate(cache->type);
dengyihao's avatar
dengyihao 已提交
521
      cache->mem->pCache = cache;
dengyihao's avatar
dengyihao 已提交
522
      cache->occupiedMem = 0;
dengyihao's avatar
dengyihao 已提交
523 524 525
      if (quit == false) {
        atomic_store_32(&cache->merging, 1);
      }
dengyihao's avatar
dengyihao 已提交
526 527
      // sched to merge
      // unref cache in bgwork
dengyihao's avatar
dengyihao 已提交
528
      idxCacheSchedToMerge(cache, quit);
dengyihao's avatar
dengyihao 已提交
529 530 531
    }
  }
}
dengyihao's avatar
dengyihao 已提交
532
int idxCachePut(void* cache, SIndexTerm* term, uint64_t uid) {
dengyihao's avatar
dengyihao 已提交
533 534 535
  if (cache == NULL) {
    return -1;
  }
dengyihao's avatar
dengyihao 已提交
536
  bool hasJson = IDX_TYPE_CONTAIN_EXTERN_TYPE(term->colType, TSDB_DATA_TYPE_JSON);
dengyihao's avatar
dengyihao 已提交
537

dengyihao's avatar
dengyihao 已提交
538
  IndexCache* pCache = cache;
dengyihao's avatar
dengyihao 已提交
539
  idxCacheRef(pCache);
dengyihao's avatar
dengyihao 已提交
540
  // encode data
wafwerar's avatar
wafwerar 已提交
541
  CacheTerm* ct = taosMemoryCalloc(1, sizeof(CacheTerm));
dengyihao's avatar
dengyihao 已提交
542 543 544
  if (cache == NULL) {
    return -1;
  }
545 546
  // set up key
  ct->colType = term->colType;
dengyihao's avatar
dengyihao 已提交
547
  if (hasJson) {
dengyihao's avatar
dengyihao 已提交
548
    ct->colVal = idxPackJsonData(term);
dengyihao's avatar
dengyihao 已提交
549
  } else {
wafwerar's avatar
wafwerar 已提交
550
    ct->colVal = (char*)taosMemoryCalloc(1, sizeof(char) * (term->nColVal + 1));
dengyihao's avatar
dengyihao 已提交
551 552
    memcpy(ct->colVal, term->colVal, term->nColVal);
  }
dengyihao's avatar
dengyihao 已提交
553
  ct->version = atomic_add_fetch_64(&pCache->version, 1);
dengyihao's avatar
dengyihao 已提交
554
  // set value
555 556
  ct->uid = uid;
  ct->operaType = term->operType;
dengyihao's avatar
dengyihao 已提交
557
  // ugly code, refactor later
dengyihao's avatar
dengyihao 已提交
558
  int64_t estimate = sizeof(ct) + strlen(ct->colVal);
dengyihao's avatar
dengyihao 已提交
559

wafwerar's avatar
wafwerar 已提交
560
  taosThreadMutexLock(&pCache->mtx);
dengyihao's avatar
dengyihao 已提交
561
  pCache->occupiedMem += estimate;
dengyihao's avatar
dengyihao 已提交
562
  idxCacheMakeRoomForWrite(pCache);
563
  MemTable* tbl = pCache->mem;
dengyihao's avatar
dengyihao 已提交
564
  idxMemRef(tbl);
565
  tSkipListPut(tbl->mem, (char*)ct);
dengyihao's avatar
dengyihao 已提交
566
  idxMemUnRef(tbl);
567

wafwerar's avatar
wafwerar 已提交
568
  taosThreadMutexUnlock(&pCache->mtx);
dengyihao's avatar
dengyihao 已提交
569

dengyihao's avatar
dengyihao 已提交
570
  idxCacheUnRef(pCache);
dengyihao's avatar
dengyihao 已提交
571
  return 0;
dengyihao's avatar
dengyihao 已提交
572
  // encode end
dengyihao's avatar
dengyihao 已提交
573
}
dengyihao's avatar
dengyihao 已提交
574
void idxCacheForceToMerge(void* cache) {
dengyihao's avatar
dengyihao 已提交
575
  IndexCache* pCache = cache;
dengyihao's avatar
dengyihao 已提交
576
  idxCacheRef(pCache);
dengyihao's avatar
dengyihao 已提交
577 578 579
  taosThreadMutexLock(&pCache->mtx);

  indexInfo("%p is forced to merge into tfile", pCache);
dengyihao's avatar
dengyihao 已提交
580
  pCache->occupiedMem += MEM_SIGNAL_QUIT;
dengyihao's avatar
dengyihao 已提交
581
  idxCacheMakeRoomForWrite(pCache);
dengyihao's avatar
dengyihao 已提交
582 583

  taosThreadMutexUnlock(&pCache->mtx);
dengyihao's avatar
dengyihao 已提交
584
  idxCacheUnRef(pCache);
dengyihao's avatar
dengyihao 已提交
585 586
  return;
}
dengyihao's avatar
dengyihao 已提交
587
int idxCacheDel(void* cache, const char* fieldValue, int32_t fvlen, uint64_t uid, int8_t operType) {
dengyihao's avatar
dengyihao 已提交
588
  IndexCache* pCache = cache;
dengyihao's avatar
dengyihao 已提交
589
  return 0;
dengyihao's avatar
dengyihao 已提交
590
}
591

dengyihao's avatar
dengyihao 已提交
592
static int32_t idxQueryMem(MemTable* mem, SIndexTermQuery* query, SIdxTRslt* tr, STermValueType* s) {
dengyihao's avatar
dengyihao 已提交
593 594 595
  if (mem == NULL) {
    return 0;
  }
dengyihao's avatar
dengyihao 已提交
596 597 598 599

  SIndexTerm*     term = query->term;
  EIndexQueryType qtype = query->qType;

dengyihao's avatar
dengyihao 已提交
600
  if (IDX_TYPE_CONTAIN_EXTERN_TYPE(term->colType, TSDB_DATA_TYPE_JSON)) {
dengyihao's avatar
dengyihao 已提交
601 602 603 604
    return cacheSearch[1][qtype](mem, term, tr, s);
  } else {
    return cacheSearch[0][qtype](mem, term, tr, s);
  }
dengyihao's avatar
dengyihao 已提交
605
}
dengyihao's avatar
dengyihao 已提交
606
int idxCacheSearch(void* cache, SIndexTermQuery* query, SIdxTRslt* result, STermValueType* s) {
dengyihao's avatar
add UT  
dengyihao 已提交
607
  int64_t st = taosGetTimestampUs();
dengyihao's avatar
dengyihao 已提交
608 609 610
  if (cache == NULL) {
    return 0;
  }
dengyihao's avatar
dengyihao 已提交
611 612 613
  IndexCache* pCache = cache;

  MemTable *mem = NULL, *imm = NULL;
wafwerar's avatar
wafwerar 已提交
614
  taosThreadMutexLock(&pCache->mtx);
dengyihao's avatar
dengyihao 已提交
615 616
  mem = pCache->mem;
  imm = pCache->imm;
dengyihao's avatar
dengyihao 已提交
617 618
  idxMemRef(mem);
  idxMemRef(imm);
wafwerar's avatar
wafwerar 已提交
619
  taosThreadMutexUnlock(&pCache->mtx);
dengyihao's avatar
dengyihao 已提交
620

dengyihao's avatar
dengyihao 已提交
621
  int ret = (mem && mem->mem) ? idxQueryMem(mem, query, result, s) : 0;
dengyihao's avatar
dengyihao 已提交
622 623
  if (ret == 0 && *s != kTypeDeletion) {
    // continue search in imm
dengyihao's avatar
dengyihao 已提交
624
    ret = (imm && imm->mem) ? idxQueryMem(imm, query, result, s) : 0;
dengyihao's avatar
dengyihao 已提交
625
  }
dengyihao's avatar
dengyihao 已提交
626

dengyihao's avatar
dengyihao 已提交
627 628
  idxMemUnRef(mem);
  idxMemUnRef(imm);
dengyihao's avatar
add UT  
dengyihao 已提交
629
  indexInfo("cache search, time cost %" PRIu64 "us", taosGetTimestampUs() - st);
dengyihao's avatar
dengyihao 已提交
630 631

  return ret;
dengyihao's avatar
dengyihao 已提交
632
}
dengyihao's avatar
dengyihao 已提交
633

dengyihao's avatar
dengyihao 已提交
634
void idxCacheRef(IndexCache* cache) {
dengyihao's avatar
dengyihao 已提交
635 636 637
  if (cache == NULL) {
    return;
  }
dengyihao's avatar
dengyihao 已提交
638 639 640
  int ref = T_REF_INC(cache);
  UNUSED(ref);
}
dengyihao's avatar
dengyihao 已提交
641
void idxCacheUnRef(IndexCache* cache) {
dengyihao's avatar
dengyihao 已提交
642 643 644
  if (cache == NULL) {
    return;
  }
dengyihao's avatar
dengyihao 已提交
645
  int ref = T_REF_DEC(cache);
dengyihao's avatar
dengyihao 已提交
646
  if (ref == 0) {
dengyihao's avatar
dengyihao 已提交
647
    idxCacheDestroy(cache);
dengyihao's avatar
dengyihao 已提交
648
  }
dengyihao's avatar
dengyihao 已提交
649
}
650

dengyihao's avatar
dengyihao 已提交
651
void idxMemRef(MemTable* tbl) {
dengyihao's avatar
dengyihao 已提交
652 653 654
  if (tbl == NULL) {
    return;
  }
655 656 657
  int ref = T_REF_INC(tbl);
  UNUSED(ref);
}
dengyihao's avatar
dengyihao 已提交
658
void idxMemUnRef(MemTable* tbl) {
dengyihao's avatar
dengyihao 已提交
659 660 661
  if (tbl == NULL) {
    return;
  }
662 663 664
  int ref = T_REF_DEC(tbl);
  if (ref == 0) {
    SSkipList* slt = tbl->mem;
dengyihao's avatar
dengyihao 已提交
665
    idxCacheDestroySkiplist(slt);
wafwerar's avatar
wafwerar 已提交
666
    taosMemoryFree(tbl);
667 668 669
  }
}

dengyihao's avatar
dengyihao 已提交
670
static void idxCacheTermDestroy(CacheTerm* ct) {
dengyihao's avatar
dengyihao 已提交
671 672 673
  if (ct == NULL) {
    return;
  }
wafwerar's avatar
wafwerar 已提交
674 675
  taosMemoryFree(ct->colVal);
  taosMemoryFree(ct);
676
}
dengyihao's avatar
dengyihao 已提交
677
static char* idxCacheTermGet(const void* pData) {
678 679 680
  CacheTerm* p = (CacheTerm*)pData;
  return (char*)p;
}
dengyihao's avatar
dengyihao 已提交
681
static int32_t idxCacheTermCompare(const void* l, const void* r) {
682 683 684
  CacheTerm* lt = (CacheTerm*)l;
  CacheTerm* rt = (CacheTerm*)r;
  // compare colVal
dengyihao's avatar
dengyihao 已提交
685
  int32_t cmp = strcmp(lt->colVal, rt->colVal);
dengyihao's avatar
dengyihao 已提交
686
  if (cmp == 0) {
dengyihao's avatar
dengyihao 已提交
687 688 689 690 691
    if (rt->version == lt->version) {
      cmp = 0;
    } else {
      cmp = rt->version < lt->version ? -1 : 1;
    }
dengyihao's avatar
dengyihao 已提交
692
  }
dengyihao's avatar
dengyihao 已提交
693
  return cmp;
694 695
}

dengyihao's avatar
dengyihao 已提交
696
static int idxFindCh(char* a, char c) {
697 698 699 700 701
  char* p = a;
  while (*p != 0 && *p++ != c) {
  }
  return p - a;
}
dengyihao's avatar
dengyihao 已提交
702
static int idxCacheJsonTermCompareImpl(char* a, char* b) {
dengyihao's avatar
dengyihao 已提交
703 704
  // int alen = idxFindCh(a, '&');
  // int blen = idxFindCh(b, '&');
705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720

  // int cmp = strncmp(a, b, MIN(alen, blen));
  // if (cmp == 0) {
  //  cmp = alen - blen;
  //  if (cmp != 0) {
  //    return cmp;
  //  }
  //  cmp = *(a + alen) - *(b + blen);
  //  if (cmp != 0) {
  //    return cmp;
  //  }
  //  alen += 2;
  //  blen += 2;
  //  cmp = strcmp(a + alen, b + blen);
  //}
  return 0;
721
}
dengyihao's avatar
dengyihao 已提交
722
static int32_t idxCacheJsonTermCompare(const void* l, const void* r) {
723 724 725
  CacheTerm* lt = (CacheTerm*)l;
  CacheTerm* rt = (CacheTerm*)r;
  // compare colVal
726
  int32_t cmp = strcmp(lt->colVal, rt->colVal);
727 728 729 730 731
  if (cmp == 0) {
    return rt->version - lt->version;
  }
  return cmp;
}
dengyihao's avatar
dengyihao 已提交
732
static MemTable* idxInternalCacheCreate(int8_t type) {
dengyihao's avatar
dengyihao 已提交
733
  int ttype = IDX_TYPE_CONTAIN_EXTERN_TYPE(type, TSDB_DATA_TYPE_JSON) ? TSDB_DATA_TYPE_BINARY : TSDB_DATA_TYPE_BINARY;
734
  int32_t (*cmpFn)(const void* l, const void* r) =
dengyihao's avatar
dengyihao 已提交
735
      IDX_TYPE_CONTAIN_EXTERN_TYPE(type, TSDB_DATA_TYPE_JSON) ? idxCacheJsonTermCompare : idxCacheTermCompare;
dengyihao's avatar
dengyihao 已提交
736

wafwerar's avatar
wafwerar 已提交
737
  MemTable* tbl = taosMemoryCalloc(1, sizeof(MemTable));
dengyihao's avatar
dengyihao 已提交
738
  idxMemRef(tbl);
739
  if (ttype == TSDB_DATA_TYPE_BINARY || ttype == TSDB_DATA_TYPE_NCHAR) {
dengyihao's avatar
dengyihao 已提交
740
    tbl->mem = tSkipListCreate(MAX_SKIP_LIST_LEVEL, ttype, MAX_INDEX_KEY_LEN, cmpFn, SL_ALLOW_DUP_KEY, idxCacheTermGet);
741 742 743 744
  }
  return tbl;
}

dengyihao's avatar
dengyihao 已提交
745
static void idxDoMergeWork(SSchedMsg* msg) {
746 747
  IndexCache* pCache = msg->ahandle;
  SIndex*     sidx = (SIndex*)pCache->index;
dengyihao's avatar
dengyihao 已提交
748

dengyihao's avatar
dengyihao 已提交
749
  int quit = msg->thandle ? true : false;
dengyihao's avatar
dengyihao 已提交
750
  taosMemoryFree(msg->thandle);
dengyihao's avatar
dengyihao 已提交
751
  idxFlushCacheToTFile(sidx, pCache, quit);
752
}
dengyihao's avatar
dengyihao 已提交
753
static bool idxCacheIteratorNext(Iterate* itera) {
754
  SSkipListIterator* iter = itera->iter;
dengyihao's avatar
dengyihao 已提交
755 756 757
  if (iter == NULL) {
    return false;
  }
dengyihao's avatar
dengyihao 已提交
758
  IterateValue* iv = &itera->val;
759 760 761 762 763 764 765 766
  iterateValueDestroy(iv, false);

  bool next = tSkipListIterNext(iter);
  if (next) {
    SSkipListNode* node = tSkipListIterGet(iter);
    CacheTerm*     ct = (CacheTerm*)SL_GET_NODE_DATA(node);

    iv->type = ct->operaType;
dengyihao's avatar
dengyihao 已提交
767
    iv->ver = ct->version;
dengyihao's avatar
dengyihao 已提交
768
    iv->colVal = tstrdup(ct->colVal);
769 770 771 772 773
    taosArrayPush(iv->val, &ct->uid);
  }
  return next;
}

dengyihao's avatar
dengyihao 已提交
774
static IterateValue* idxCacheIteratorGetValue(Iterate* iter) {
dengyihao's avatar
dengyihao 已提交
775 776 777
  // opt later
  return &iter->val;
}