indexTfile.c 23.5 KB
Newer Older
dengyihao's avatar
dengyihao 已提交
1 2
/*
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
dengyihao's avatar
dengyihao 已提交
3
p *
dengyihao's avatar
dengyihao 已提交
4 5 6 7 8 9 10 11 12 13 14 15
 * 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
#include "indexTfile.h"
17
#include "index.h"
dengyihao's avatar
dengyihao 已提交
18 19 20 21
#include "indexComm.h"
#include "indexFst.h"
#include "indexFstCountingWriter.h"
#include "indexUtil.h"
dengyihao's avatar
dengyihao 已提交
22
#include "taosdef.h"
dengyihao's avatar
dengyihao 已提交
23
#include "tcoding.h"
dengyihao's avatar
dengyihao 已提交
24
#include "tcompare.h"
dengyihao's avatar
dengyihao 已提交
25

dengyihao's avatar
dengyihao 已提交
26 27
const static uint64_t tfileMagicNumber = 0xdb4775248b80fb57ull;

dengyihao's avatar
dengyihao 已提交
28 29 30 31 32 33 34
typedef struct TFileFstIter {
  FstStreamBuilder* fb;
  StreamWithState*  st;
  AutomationCtx*    ctx;
  TFileReader*      rdr;
} TFileFstIter;

dengyihao's avatar
dengyihao 已提交
35 36
#define TF_TABLE_TATOAL_SIZE(sz) (sizeof(sz) + sz * sizeof(uint64_t))

dengyihao's avatar
dengyihao 已提交
37
static int  tfileUidCompare(const void* a, const void* b);
dengyihao's avatar
dengyihao 已提交
38
static int  tfileStrCompare(const void* a, const void* b);
dengyihao's avatar
dengyihao 已提交
39 40
static int  tfileValueCompare(const void* a, const void* b, const void* param);
static void tfileSerialTableIdsToBuf(char* buf, SArray* tableIds);
dengyihao's avatar
dengyihao 已提交
41

dengyihao's avatar
dengyihao 已提交
42
static int tfileWriteHeader(TFileWriter* writer);
dengyihao's avatar
dengyihao 已提交
43
static int tfileWriteFstOffset(TFileWriter* tw, int32_t offset);
dengyihao's avatar
dengyihao 已提交
44
static int tfileWriteData(TFileWriter* write, TFileValue* tval);
dengyihao's avatar
dengyihao 已提交
45
static int tfileWriteFooter(TFileWriter* write);
dengyihao's avatar
dengyihao 已提交
46

dengyihao's avatar
dengyihao 已提交
47
// handle file corrupt later
dengyihao's avatar
dengyihao 已提交
48 49
static int tfileReaderLoadHeader(TFileReader* reader);
static int tfileReaderLoadFst(TFileReader* reader);
dengyihao's avatar
dengyihao 已提交
50
static int tfileReaderVerify(TFileReader* reader);
dengyihao's avatar
dengyihao 已提交
51
static int tfileReaderLoadTableIds(TFileReader* reader, int32_t offset, SArray* result);
dengyihao's avatar
dengyihao 已提交
52

dengyihao's avatar
dengyihao 已提交
53 54 55 56 57 58 59
static SArray* tfileGetFileList(const char* path);
static int     tfileRmExpireFile(SArray* result);
static void    tfileDestroyFileName(void* elem);
static int     tfileCompare(const void* a, const void* b);
static int     tfileParseFileName(const char* filename, uint64_t* suid, char* col, int* version);
static void    tfileGenFileName(char* filename, uint64_t suid, const char* col, int version);
static void    tfileGenFileFullName(char* fullname, const char* path, uint64_t suid, const char* col, int32_t version);
dengyihao's avatar
dengyihao 已提交
60

dengyihao's avatar
dengyihao 已提交
61
TFileCache* tfileCacheCreate(const char* path) {
wafwerar's avatar
wafwerar 已提交
62
  TFileCache* tcache = taosMemoryCalloc(1, sizeof(TFileCache));
dengyihao's avatar
dengyihao 已提交
63 64 65
  if (tcache == NULL) {
    return NULL;
  }
66 67 68 69

  tcache->tableCache = taosHashInit(8, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
  tcache->capacity = 64;

dengyihao's avatar
dengyihao 已提交
70
  SArray* files = tfileGetFileList(path);
dengyihao's avatar
dengyihao 已提交
71
  for (size_t i = 0; i < taosArrayGetSize(files); i++) {
dengyihao's avatar
dengyihao 已提交
72
    char* file = taosArrayGetP(files, i);
dengyihao's avatar
dengyihao 已提交
73

dengyihao's avatar
dengyihao 已提交
74
    WriterCtx* wc = writerCtxCreate(TFile, file, true, 1024 * 1024 * 64);
75
    if (wc == NULL) {
dengyihao's avatar
dengyihao 已提交
76
      indexError("failed to open index:%s", file);
77
      goto End;
dengyihao's avatar
dengyihao 已提交
78
    }
dengyihao's avatar
dengyihao 已提交
79

dengyihao's avatar
dengyihao 已提交
80
    TFileReader* reader = tfileReaderCreate(wc);
dengyihao's avatar
dengyihao 已提交
81 82 83 84
    if (reader == NULL) {
      indexInfo("skip invalid file: %s", file);
      continue;
    }
dengyihao's avatar
dengyihao 已提交
85
    TFileHeader* header = &reader->header;
dengyihao's avatar
dengyihao 已提交
86
    ICacheKey    key = {.suid = header->suid, .colName = header->colName, .nColName = strlen(header->colName)};
dengyihao's avatar
dengyihao 已提交
87

dengyihao's avatar
dengyihao 已提交
88
    char    buf[128] = {0};
dengyihao's avatar
dengyihao 已提交
89 90 91
    int32_t sz = indexSerialCacheKey(&key, buf);
    assert(sz < sizeof(buf));
    taosHashPut(tcache->tableCache, buf, sz, &reader, sizeof(void*));
dengyihao's avatar
dengyihao 已提交
92
    tfileReaderRef(reader);
dengyihao's avatar
dengyihao 已提交
93
  }
dengyihao's avatar
dengyihao 已提交
94
  taosArrayDestroyEx(files, tfileDestroyFileName);
dengyihao's avatar
dengyihao 已提交
95
  return tcache;
dengyihao's avatar
dengyihao 已提交
96
End:
97
  tfileCacheDestroy(tcache);
dengyihao's avatar
dengyihao 已提交
98
  taosArrayDestroyEx(files, tfileDestroyFileName);
99
  return NULL;
dengyihao's avatar
dengyihao 已提交
100
}
dengyihao's avatar
dengyihao 已提交
101
void tfileCacheDestroy(TFileCache* tcache) {
dengyihao's avatar
dengyihao 已提交
102 103 104
  if (tcache == NULL) {
    return;
  }
105
  // free table cache
dengyihao's avatar
dengyihao 已提交
106
  TFileReader** reader = taosHashIterate(tcache->tableCache, NULL);
107
  while (reader) {
dengyihao's avatar
dengyihao 已提交
108
    TFileReader* p = *reader;
109 110
    indexInfo("drop table cache suid: %" PRIu64 ", colName: %s, colType: %d", p->header.suid, p->header.colName,
              p->header.colType);
dengyihao's avatar
dengyihao 已提交
111

dengyihao's avatar
dengyihao 已提交
112
    tfileReaderUnRef(p);
113 114 115
    reader = taosHashIterate(tcache->tableCache, reader);
  }
  taosHashCleanup(tcache->tableCache);
wafwerar's avatar
wafwerar 已提交
116
  taosMemoryFree(tcache);
dengyihao's avatar
dengyihao 已提交
117 118
}

dengyihao's avatar
dengyihao 已提交
119 120 121 122 123
TFileReader* tfileCacheGet(TFileCache* tcache, ICacheKey* key) {
  char    buf[128] = {0};
  int32_t sz = indexSerialCacheKey(key, buf);
  assert(sz < sizeof(buf));
  TFileReader** reader = taosHashGet(tcache->tableCache, buf, sz);
dengyihao's avatar
dengyihao 已提交
124 125 126
  if (reader == NULL) {
    return NULL;
  }
127
  tfileReaderRef(*reader);
dengyihao's avatar
dengyihao 已提交
128

129
  return *reader;
dengyihao's avatar
dengyihao 已提交
130
}
dengyihao's avatar
dengyihao 已提交
131 132 133
void tfileCachePut(TFileCache* tcache, ICacheKey* key, TFileReader* reader) {
  char    buf[128] = {0};
  int32_t sz = indexSerialCacheKey(key, buf);
dengyihao's avatar
dengyihao 已提交
134
  // remove last version index reader
dengyihao's avatar
dengyihao 已提交
135
  TFileReader** p = taosHashGet(tcache->tableCache, buf, sz);
dengyihao's avatar
dengyihao 已提交
136
  if (p != NULL) {
dengyihao's avatar
dengyihao 已提交
137
    TFileReader* oldReader = *p;
dengyihao's avatar
dengyihao 已提交
138
    taosHashRemove(tcache->tableCache, buf, sz);
dengyihao's avatar
dengyihao 已提交
139
    oldReader->remove = true;
dengyihao's avatar
dengyihao 已提交
140
    tfileReaderUnRef(oldReader);
dengyihao's avatar
dengyihao 已提交
141
  }
dengyihao's avatar
dengyihao 已提交
142

dengyihao's avatar
dengyihao 已提交
143
  taosHashPut(tcache->tableCache, buf, sz, &reader, sizeof(void*));
dengyihao's avatar
dengyihao 已提交
144
  tfileReaderRef(reader);
dengyihao's avatar
dengyihao 已提交
145
  return;
146
}
dengyihao's avatar
dengyihao 已提交
147
TFileReader* tfileReaderCreate(WriterCtx* ctx) {
wafwerar's avatar
wafwerar 已提交
148
  TFileReader* reader = taosMemoryCalloc(1, sizeof(TFileReader));
dengyihao's avatar
dengyihao 已提交
149 150 151
  if (reader == NULL) {
    return NULL;
  }
dengyihao's avatar
dengyihao 已提交
152 153

  reader->ctx = ctx;
dengyihao's avatar
dengyihao 已提交
154 155

  if (0 != tfileReaderVerify(reader)) {
dengyihao's avatar
dengyihao 已提交
156
    indexError("invalid tfile, suid: %" PRIu64 ", colName: %s", reader->header.suid, reader->header.colName);
dengyihao's avatar
dengyihao 已提交
157
    tfileReaderDestroy(reader);
dengyihao's avatar
dengyihao 已提交
158 159 160
    return NULL;
  }
  // T_REF_INC(reader);
dengyihao's avatar
dengyihao 已提交
161
  if (0 != tfileReaderLoadHeader(reader)) {
162 163
    indexError("failed to load index header, suid: %" PRIu64 ", colName: %s", reader->header.suid,
               reader->header.colName);
dengyihao's avatar
dengyihao 已提交
164
    tfileReaderDestroy(reader);
dengyihao's avatar
dengyihao 已提交
165 166 167 168
    return NULL;
  }

  if (0 != tfileReaderLoadFst(reader)) {
dengyihao's avatar
dengyihao 已提交
169 170
    indexError("failed to load index fst, suid: %" PRIu64 ", colName: %s, errno: %d", reader->header.suid,
               reader->header.colName, errno);
dengyihao's avatar
dengyihao 已提交
171 172 173 174
    tfileReaderDestroy(reader);
    return NULL;
  }

175
  return reader;
dengyihao's avatar
dengyihao 已提交
176
}
dengyihao's avatar
dengyihao 已提交
177
void tfileReaderDestroy(TFileReader* reader) {
dengyihao's avatar
dengyihao 已提交
178 179 180
  if (reader == NULL) {
    return;
  }
181
  // T_REF_INC(reader);
dengyihao's avatar
dengyihao 已提交
182
  fstDestroy(reader->fst);
dengyihao's avatar
dengyihao 已提交
183
  writerCtxDestroy(reader->ctx, reader->remove);
wafwerar's avatar
wafwerar 已提交
184
  taosMemoryFree(reader);
dengyihao's avatar
dengyihao 已提交
185 186
}

dengyihao's avatar
dengyihao 已提交
187
int tfileReaderSearch(TFileReader* reader, SIndexTermQuery* query, SIdxTempResult* tr) {
dengyihao's avatar
dengyihao 已提交
188
  SIndexTerm*     term = query->term;
dengyihao's avatar
add UT  
dengyihao 已提交
189
  bool            hasJson = INDEX_TYPE_CONTAIN_EXTERN_TYPE(term->colType, TSDB_DATA_TYPE_JSON);
dengyihao's avatar
dengyihao 已提交
190
  EIndexQueryType qtype = query->qType;
dengyihao's avatar
dengyihao 已提交
191

dengyihao's avatar
add UT  
dengyihao 已提交
192 193
  // SArray* result = taosArrayInit(16, sizeof(uint64_t));
  int ret = -1;
dengyihao's avatar
dengyihao 已提交
194
  // refactor to callback later
dengyihao's avatar
dengyihao 已提交
195
  if (qtype == QUERY_TERM) {
dengyihao's avatar
dengyihao 已提交
196
    uint64_t offset;
dengyihao's avatar
add UT  
dengyihao 已提交
197 198 199 200 201 202
    char*    p = term->colVal;
    uint64_t sz = term->nColVal;
    if (hasJson) {
      p = indexPackJsonData(term);
      sz = strlen(p);
    }
dengyihao's avatar
add UT  
dengyihao 已提交
203
    int64_t  st = taosGetTimestampUs();
dengyihao's avatar
add UT  
dengyihao 已提交
204
    FstSlice key = fstSliceCreate(p, sz);
dengyihao's avatar
dengyihao 已提交
205
    if (fstGet(reader->fst, &key, &offset)) {
dengyihao's avatar
add UT  
dengyihao 已提交
206 207 208 209 210 211 212 213 214
      int64_t et = taosGetTimestampUs();
      int64_t cost = et - st;
      indexInfo("index: %" PRIu64 ", col: %s, colVal: %s, found table info in tindex, time cost: %" PRIu64 "us",
                term->suid, term->colName, term->colVal, cost);

      ret = tfileReaderLoadTableIds(reader, offset, tr->total);
      cost = taosGetTimestampUs() - et;
      indexInfo("index: %" PRIu64 ", col: %s, colVal: %s, load all table info, time cost: %" PRIu64 "us", term->suid,
                term->colName, term->colVal, cost);
dengyihao's avatar
dengyihao 已提交
215
    } else {
216 217
      indexInfo("index: %" PRIu64 ", col: %s, colVal: %s, not found table info in tindex", term->suid, term->colName,
                term->colVal);
dengyihao's avatar
dengyihao 已提交
218
    }
dengyihao's avatar
dengyihao 已提交
219
    fstSliceDestroy(&key);
dengyihao's avatar
add UT  
dengyihao 已提交
220
    if (hasJson) {
wafwerar's avatar
wafwerar 已提交
221
      taosMemoryFree(p);
dengyihao's avatar
add UT  
dengyihao 已提交
222
    }
dengyihao's avatar
dengyihao 已提交
223
  } else if (qtype == QUERY_PREFIX) {
dengyihao's avatar
dengyihao 已提交
224
    // handle later
dengyihao's avatar
dengyihao 已提交
225
    //
dengyihao's avatar
dengyihao 已提交
226 227 228 229 230
  } else if (qtype == QUERY_SUFFIX) {
    // handle later
  } else if (qtype == QUERY_REGEX) {
    // handle later
  } else if (qtype == QUERY_RANGE) {
dengyihao's avatar
dengyihao 已提交
231
    // handle later
dengyihao's avatar
dengyihao 已提交
232
  }
dengyihao's avatar
dengyihao 已提交
233
  tfileReaderUnRef(reader);
dengyihao's avatar
dengyihao 已提交
234

dengyihao's avatar
add UT  
dengyihao 已提交
235 236
  // taosArrayAddAll(tr->total, result);
  // taosArrayDestroy(result);
dengyihao's avatar
dengyihao 已提交
237

dengyihao's avatar
dengyihao 已提交
238
  return ret;
dengyihao's avatar
dengyihao 已提交
239 240
}

dengyihao's avatar
dengyihao 已提交
241 242
TFileWriter* tfileWriterOpen(char* path, uint64_t suid, int32_t version, const char* colName, uint8_t colType) {
  char fullname[256] = {0};
dengyihao's avatar
dengyihao 已提交
243
  tfileGenFileFullName(fullname, path, suid, colName, version);
dengyihao's avatar
dengyihao 已提交
244
  // indexInfo("open write file name %s", fullname);
dengyihao's avatar
dengyihao 已提交
245
  WriterCtx* wcx = writerCtxCreate(TFile, fullname, false, 1024 * 1024 * 64);
dengyihao's avatar
dengyihao 已提交
246 247 248
  if (wcx == NULL) {
    return NULL;
  }
dengyihao's avatar
dengyihao 已提交
249 250 251 252 253 254 255 256 257

  TFileHeader tfh = {0};
  tfh.suid = suid;
  tfh.version = version;
  memcpy(tfh.colName, colName, strlen(colName));
  tfh.colType = colType;

  return tfileWriterCreate(wcx, &tfh);
}
dengyihao's avatar
dengyihao 已提交
258 259
TFileReader* tfileReaderOpen(char* path, uint64_t suid, int32_t version, const char* colName) {
  char fullname[256] = {0};
dengyihao's avatar
dengyihao 已提交
260 261
  tfileGenFileFullName(fullname, path, suid, colName, version);

dengyihao's avatar
dengyihao 已提交
262
  WriterCtx* wc = writerCtxCreate(TFile, fullname, true, 1024 * 1024 * 1024);
dengyihao's avatar
dengyihao 已提交
263
  indexInfo("open read file name:%s, file size: %d", wc->file.buf, wc->file.size);
dengyihao's avatar
dengyihao 已提交
264 265 266
  if (wc == NULL) {
    return NULL;
  }
dengyihao's avatar
dengyihao 已提交
267

dengyihao's avatar
dengyihao 已提交
268
  TFileReader* reader = tfileReaderCreate(wc);
dengyihao's avatar
dengyihao 已提交
269 270
  return reader;
}
dengyihao's avatar
dengyihao 已提交
271
TFileWriter* tfileWriterCreate(WriterCtx* ctx, TFileHeader* header) {
wafwerar's avatar
wafwerar 已提交
272
  TFileWriter* tw = taosMemoryCalloc(1, sizeof(TFileWriter));
dengyihao's avatar
dengyihao 已提交
273
  if (tw == NULL) {
dengyihao's avatar
dengyihao 已提交
274
    indexError("index: %" PRIu64 " failed to alloc TFilerWriter", header->suid);
dengyihao's avatar
dengyihao 已提交
275 276
    return NULL;
  }
dengyihao's avatar
dengyihao 已提交
277 278
  tw->ctx = ctx;
  tw->header = *header;
dengyihao's avatar
dengyihao 已提交
279
  tfileWriteHeader(tw);
dengyihao's avatar
dengyihao 已提交
280 281
  return tw;
}
dengyihao's avatar
dengyihao 已提交
282

dengyihao's avatar
dengyihao 已提交
283
int tfileWriterPut(TFileWriter* tw, void* data, bool order) {
dengyihao's avatar
dengyihao 已提交
284
  // sort by coltype and write to tindex
dengyihao's avatar
dengyihao 已提交
285 286
  if (order == false) {
    __compar_fn_t fn;
dengyihao's avatar
dengyihao 已提交
287 288

    int8_t colType = tw->header.colType;
dengyihao's avatar
add UT  
dengyihao 已提交
289
    colType = INDEX_TYPE_GET_TYPE(colType);
dengyihao's avatar
dengyihao 已提交
290 291 292 293 294 295
    if (colType == TSDB_DATA_TYPE_BINARY || colType == TSDB_DATA_TYPE_NCHAR) {
      fn = tfileStrCompare;
    } else {
      fn = getComparFunc(colType, 0);
    }
    taosArraySortPWithExt((SArray*)(data), tfileValueCompare, &fn);
dengyihao's avatar
dengyihao 已提交
296
  }
dengyihao's avatar
dengyihao 已提交
297

dengyihao's avatar
dengyihao 已提交
298
  int32_t bufLimit = 64 * 4096, offset = 0;
wafwerar's avatar
wafwerar 已提交
299
  // char*   buf = taosMemoryCalloc(1, sizeof(char) * bufLimit);
dengyihao's avatar
dengyihao 已提交
300
  // char*   p = buf;
dengyihao's avatar
dengyihao 已提交
301
  int32_t sz = taosArrayGetSize((SArray*)data);
dengyihao's avatar
dengyihao 已提交
302 303 304 305 306
  int32_t fstOffset = tw->offset;

  // ugly code, refactor later
  for (size_t i = 0; i < sz; i++) {
    TFileValue* v = taosArrayGetP((SArray*)data, i);
dengyihao's avatar
dengyihao 已提交
307 308
    taosArraySort(v->tableId, tfileUidCompare);
    taosArrayRemoveDuplicate(v->tableId, tfileUidCompare, NULL);
dengyihao's avatar
dengyihao 已提交
309
    int32_t tbsz = taosArrayGetSize(v->tableId);
dengyihao's avatar
dengyihao 已提交
310
    fstOffset += TF_TABLE_TATOAL_SIZE(tbsz);
dengyihao's avatar
dengyihao 已提交
311 312 313
  }
  tfileWriteFstOffset(tw, fstOffset);

dengyihao's avatar
dengyihao 已提交
314 315 316 317 318 319 320
  for (size_t i = 0; i < sz; i++) {
    TFileValue* v = taosArrayGetP((SArray*)data, i);

    int32_t tbsz = taosArrayGetSize(v->tableId);
    // check buf has enough space or not
    int32_t ttsz = TF_TABLE_TATOAL_SIZE(tbsz);

wafwerar's avatar
wafwerar 已提交
321
    char* buf = taosMemoryCalloc(1, ttsz * sizeof(char));
dengyihao's avatar
dengyihao 已提交
322
    char* p = buf;
dengyihao's avatar
dengyihao 已提交
323
    tfileSerialTableIdsToBuf(p, v->tableId);
dengyihao's avatar
dengyihao 已提交
324
    tw->ctx->write(tw->ctx, buf, ttsz);
dengyihao's avatar
dengyihao 已提交
325 326
    v->offset = tw->offset;
    tw->offset += ttsz;
wafwerar's avatar
wafwerar 已提交
327
    taosMemoryFree(buf);
dengyihao's avatar
dengyihao 已提交
328
  }
dengyihao's avatar
dengyihao 已提交
329

dengyihao's avatar
dengyihao 已提交
330 331
  tw->fb = fstBuilderCreate(tw->ctx, 0);
  if (tw->fb == NULL) {
dengyihao's avatar
dengyihao 已提交
332
    tfileWriterClose(tw);
dengyihao's avatar
dengyihao 已提交
333 334
    return -1;
  }
dengyihao's avatar
dengyihao 已提交
335 336

  // write data
dengyihao's avatar
dengyihao 已提交
337 338 339
  for (size_t i = 0; i < sz; i++) {
    // TODO, fst batch write later
    TFileValue* v = taosArrayGetP((SArray*)data, i);
dengyihao's avatar
dengyihao 已提交
340 341 342 343
    if (tfileWriteData(tw, v) != 0) {
      indexError("failed to write data: %s, offset: %d len: %d", v->colVal, v->offset,
                 (int)taosArrayGetSize(v->tableId));
    } else {
dengyihao's avatar
dengyihao 已提交
344 345
      // indexInfo("success to write data: %s, offset: %d len: %d", v->colVal, v->offset,
      //          (int)taosArrayGetSize(v->tableId));
dengyihao's avatar
dengyihao 已提交
346 347

      // indexInfo("tfile write data size: %d", tw->ctx->size(tw->ctx));
dengyihao's avatar
dengyihao 已提交
348 349
    }
  }
dengyihao's avatar
dengyihao 已提交
350 351 352
  fstBuilderFinish(tw->fb);
  fstBuilderDestroy(tw->fb);
  tw->fb = NULL;
dengyihao's avatar
dengyihao 已提交
353 354

  tfileWriteFooter(tw);
dengyihao's avatar
dengyihao 已提交
355 356
  return 0;
}
dengyihao's avatar
dengyihao 已提交
357
void tfileWriterClose(TFileWriter* tw) {
dengyihao's avatar
dengyihao 已提交
358 359 360
  if (tw == NULL) {
    return;
  }
dengyihao's avatar
dengyihao 已提交
361
  writerCtxDestroy(tw->ctx, false);
wafwerar's avatar
wafwerar 已提交
362
  taosMemoryFree(tw);
dengyihao's avatar
dengyihao 已提交
363
}
dengyihao's avatar
dengyihao 已提交
364
void tfileWriterDestroy(TFileWriter* tw) {
dengyihao's avatar
dengyihao 已提交
365 366 367
  if (tw == NULL) {
    return;
  }
dengyihao's avatar
dengyihao 已提交
368
  writerCtxDestroy(tw->ctx, false);
wafwerar's avatar
wafwerar 已提交
369
  taosMemoryFree(tw);
dengyihao's avatar
dengyihao 已提交
370
}
dengyihao's avatar
dengyihao 已提交
371

dengyihao's avatar
dengyihao 已提交
372
IndexTFile* indexTFileCreate(const char* path) {
dengyihao's avatar
dengyihao 已提交
373
  TFileCache* cache = tfileCacheCreate(path);
dengyihao's avatar
dengyihao 已提交
374 375 376
  if (cache == NULL) {
    return NULL;
  }
dengyihao's avatar
dengyihao 已提交
377

wafwerar's avatar
wafwerar 已提交
378
  IndexTFile* tfile = taosMemoryCalloc(1, sizeof(IndexTFile));
dengyihao's avatar
dengyihao 已提交
379 380 381 382
  if (tfile == NULL) {
    tfileCacheDestroy(cache);
    return NULL;
  }
383

dengyihao's avatar
dengyihao 已提交
384
  tfile->cache = cache;
dengyihao's avatar
dengyihao 已提交
385 386
  return tfile;
}
387
void indexTFileDestroy(IndexTFile* tfile) {
dengyihao's avatar
dengyihao 已提交
388 389 390
  if (tfile == NULL) {
    return;
  }
dengyihao's avatar
dengyihao 已提交
391
  tfileCacheDestroy(tfile->cache);
wafwerar's avatar
wafwerar 已提交
392
  taosMemoryFree(tfile);
dengyihao's avatar
dengyihao 已提交
393
}
dengyihao's avatar
dengyihao 已提交
394

dengyihao's avatar
dengyihao 已提交
395
int indexTFileSearch(void* tfile, SIndexTermQuery* query, SIdxTempResult* result) {
dengyihao's avatar
dengyihao 已提交
396
  int ret = -1;
dengyihao's avatar
dengyihao 已提交
397 398 399
  if (tfile == NULL) {
    return ret;
  }
dengyihao's avatar
dengyihao 已提交
400

dengyihao's avatar
add UT  
dengyihao 已提交
401
  int64_t     st = taosGetTimestampUs();
dengyihao's avatar
dengyihao 已提交
402
  IndexTFile* pTfile = tfile;
403

dengyihao's avatar
dengyihao 已提交
404 405
  SIndexTerm* term = query->term;
  ICacheKey key = {.suid = term->suid, .colType = term->colType, .colName = term->colName, .nColName = term->nColName};
406
  TFileReader* reader = tfileCacheGet(pTfile->cache, &key);
dengyihao's avatar
dengyihao 已提交
407 408 409
  if (reader == NULL) {
    return 0;
  }
dengyihao's avatar
add UT  
dengyihao 已提交
410 411
  int64_t cost = taosGetTimestampUs() - st;
  indexInfo("index tfile stage 1 cost: %" PRId64 "", cost);
dengyihao's avatar
dengyihao 已提交
412

dengyihao's avatar
dengyihao 已提交
413
  return tfileReaderSearch(reader, query, result);
dengyihao's avatar
dengyihao 已提交
414
}
dengyihao's avatar
dengyihao 已提交
415
int indexTFilePut(void* tfile, SIndexTerm* term, uint64_t uid) {
416 417
  // TFileWriterOpt wOpt = {.suid = term->suid, .colType = term->colType, .colName = term->colName, .nColName =
  // term->nColName, .version = 1};
dengyihao's avatar
dengyihao 已提交
418

419 420
  return 0;
}
dengyihao's avatar
dengyihao 已提交
421 422 423 424 425 426 427 428 429
static bool tfileIteratorNext(Iterate* iiter) {
  IterateValue* iv = &iiter->val;
  iterateValueDestroy(iv, false);

  char*    colVal = NULL;
  uint64_t offset = 0;

  TFileFstIter*          tIter = iiter->iter;
  StreamWithStateResult* rt = streamWithStateNextWith(tIter->st, NULL);
dengyihao's avatar
dengyihao 已提交
430 431 432
  if (rt == NULL) {
    return false;
  }
dengyihao's avatar
dengyihao 已提交
433 434 435

  int32_t sz = 0;
  char*   ch = (char*)fstSliceData(&rt->data, &sz);
wafwerar's avatar
wafwerar 已提交
436
  colVal = taosMemoryCalloc(1, sz + 1);
dengyihao's avatar
dengyihao 已提交
437 438 439 440 441
  memcpy(colVal, ch, sz);

  offset = (uint64_t)(rt->out.out);
  swsResultDestroy(rt);
  // set up iterate value
dengyihao's avatar
dengyihao 已提交
442 443 444
  if (tfileReaderLoadTableIds(tIter->rdr, offset, iv->val) != 0) {
    return false;
  }
dengyihao's avatar
dengyihao 已提交
445

dengyihao's avatar
dengyihao 已提交
446
  iv->ver = 0;
447
  iv->type = ADD_VALUE;  // value in tfile always ADD_VALUE
dengyihao's avatar
dengyihao 已提交
448
  iv->colVal = colVal;
dengyihao's avatar
dengyihao 已提交
449
  return true;
dengyihao's avatar
dengyihao 已提交
450 451 452
  // std::string key(ch, sz);
}

453
static IterateValue* tifileIterateGetValue(Iterate* iter) { return &iter->val; }
dengyihao's avatar
dengyihao 已提交
454 455

static TFileFstIter* tfileFstIteratorCreate(TFileReader* reader) {
wafwerar's avatar
wafwerar 已提交
456
  TFileFstIter* tIter = taosMemoryCalloc(1, sizeof(TFileFstIter));
dengyihao's avatar
dengyihao 已提交
457 458 459
  if (tIter == NULL) {
    return NULL;
  }
dengyihao's avatar
dengyihao 已提交
460

dengyihao's avatar
dengyihao 已提交
461 462 463 464 465 466 467 468
  tIter->ctx = automCtxCreate(NULL, AUTOMATION_ALWAYS);
  tIter->fb = fstSearch(reader->fst, tIter->ctx);
  tIter->st = streamBuilderIntoStream(tIter->fb);
  tIter->rdr = reader;
  return tIter;
}

Iterate* tfileIteratorCreate(TFileReader* reader) {
dengyihao's avatar
dengyihao 已提交
469 470 471
  if (reader == NULL) {
    return NULL;
  }
dengyihao's avatar
dengyihao 已提交
472

wafwerar's avatar
wafwerar 已提交
473
  Iterate* iter = taosMemoryCalloc(1, sizeof(Iterate));
dengyihao's avatar
dengyihao 已提交
474
  iter->iter = tfileFstIteratorCreate(reader);
475
  if (iter->iter == NULL) {
wafwerar's avatar
wafwerar 已提交
476
    taosMemoryFree(iter);
477 478
    return NULL;
  }
dengyihao's avatar
dengyihao 已提交
479 480
  iter->next = tfileIteratorNext;
  iter->getValue = tifileIterateGetValue;
dengyihao's avatar
dengyihao 已提交
481
  iter->val.val = taosArrayInit(1, sizeof(uint64_t));
482
  iter->val.colVal = NULL;
dengyihao's avatar
dengyihao 已提交
483 484 485
  return iter;
}
void tfileIteratorDestroy(Iterate* iter) {
dengyihao's avatar
dengyihao 已提交
486 487 488
  if (iter == NULL) {
    return;
  }
dengyihao's avatar
dengyihao 已提交
489

dengyihao's avatar
dengyihao 已提交
490 491 492 493 494 495 496
  IterateValue* iv = &iter->val;
  iterateValueDestroy(iv, true);

  TFileFstIter* tIter = iter->iter;
  streamWithStateDestroy(tIter->st);
  fstStreamBuilderDestroy(tIter->fb);
  automCtxDestroy(tIter->ctx);
wafwerar's avatar
wafwerar 已提交
497
  taosMemoryFree(tIter);
dengyihao's avatar
dengyihao 已提交
498

wafwerar's avatar
wafwerar 已提交
499
  taosMemoryFree(iter);
dengyihao's avatar
dengyihao 已提交
500 501
}

dengyihao's avatar
dengyihao 已提交
502
TFileReader* tfileGetReaderByCol(IndexTFile* tf, uint64_t suid, char* colName) {
dengyihao's avatar
dengyihao 已提交
503 504 505
  if (tf == NULL) {
    return NULL;
  }
dengyihao's avatar
dengyihao 已提交
506
  ICacheKey key = {.suid = suid, .colType = TSDB_DATA_TYPE_BINARY, .colName = colName, .nColName = strlen(colName)};
dengyihao's avatar
dengyihao 已提交
507 508
  return tfileCacheGet(tf->cache, &key);
}
dengyihao's avatar
dengyihao 已提交
509

dengyihao's avatar
dengyihao 已提交
510 511 512 513 514
static int tfileUidCompare(const void* a, const void* b) {
  uint64_t l = *(uint64_t*)a;
  uint64_t r = *(uint64_t*)b;
  return l - r;
}
dengyihao's avatar
dengyihao 已提交
515 516
static int tfileStrCompare(const void* a, const void* b) {
  int ret = strcmp((char*)a, (char*)b);
dengyihao's avatar
dengyihao 已提交
517 518 519
  if (ret == 0) {
    return ret;
  }
dengyihao's avatar
dengyihao 已提交
520 521 522
  return ret < 0 ? -1 : 1;
}

dengyihao's avatar
dengyihao 已提交
523 524 525 526 527 528 529 530
static int tfileValueCompare(const void* a, const void* b, const void* param) {
  __compar_fn_t fn = *(__compar_fn_t*)param;

  TFileValue* av = (TFileValue*)a;
  TFileValue* bv = (TFileValue*)b;

  return fn(av->colVal, bv->colVal);
}
dengyihao's avatar
dengyihao 已提交
531 532

TFileValue* tfileValueCreate(char* val) {
wafwerar's avatar
wafwerar 已提交
533
  TFileValue* tf = taosMemoryCalloc(1, sizeof(TFileValue));
dengyihao's avatar
dengyihao 已提交
534 535 536
  if (tf == NULL) {
    return NULL;
  }
537
  tf->colVal = tstrdup(val);
dengyihao's avatar
dengyihao 已提交
538 539 540 541
  tf->tableId = taosArrayInit(32, sizeof(uint64_t));
  return tf;
}
int tfileValuePush(TFileValue* tf, uint64_t val) {
dengyihao's avatar
dengyihao 已提交
542 543 544
  if (tf == NULL) {
    return -1;
  }
dengyihao's avatar
dengyihao 已提交
545 546 547 548 549
  taosArrayPush(tf->tableId, &val);
  return 0;
}
void tfileValueDestroy(TFileValue* tf) {
  taosArrayDestroy(tf->tableId);
wafwerar's avatar
wafwerar 已提交
550 551
  taosMemoryFree(tf->colVal);
  taosMemoryFree(tf);
dengyihao's avatar
dengyihao 已提交
552
}
dengyihao's avatar
dengyihao 已提交
553 554 555 556 557
static void tfileSerialTableIdsToBuf(char* buf, SArray* ids) {
  int sz = taosArrayGetSize(ids);
  SERIALIZE_VAR_TO_BUF(buf, sz, int32_t);
  for (size_t i = 0; i < sz; i++) {
    uint64_t* v = taosArrayGet(ids, i);
dengyihao's avatar
dengyihao 已提交
558 559 560 561 562 563 564
    SERIALIZE_VAR_TO_BUF(buf, *v, uint64_t);
  }
}

static int tfileWriteFstOffset(TFileWriter* tw, int32_t offset) {
  int32_t fstOffset = offset + sizeof(tw->header.fstOffset);
  tw->header.fstOffset = fstOffset;
dengyihao's avatar
dengyihao 已提交
565

dengyihao's avatar
dengyihao 已提交
566 567 568
  if (sizeof(fstOffset) != tw->ctx->write(tw->ctx, (char*)&fstOffset, sizeof(fstOffset))) {
    return -1;
  }
dengyihao's avatar
dengyihao 已提交
569
  indexInfo("tfile write fst offset: %d", tw->ctx->size(tw->ctx));
dengyihao's avatar
dengyihao 已提交
570
  tw->offset += sizeof(fstOffset);
dengyihao's avatar
dengyihao 已提交
571 572 573
  return 0;
}
static int tfileWriteHeader(TFileWriter* writer) {
dengyihao's avatar
dengyihao 已提交
574
  char buf[TFILE_HEADER_NO_FST] = {0};
dengyihao's avatar
dengyihao 已提交
575 576 577 578

  TFileHeader* header = &writer->header;
  memcpy(buf, (char*)header, sizeof(buf));

dengyihao's avatar
dengyihao 已提交
579
  indexInfo("tfile pre write header size: %d", writer->ctx->size(writer->ctx));
dengyihao's avatar
dengyihao 已提交
580
  int nwrite = writer->ctx->write(writer->ctx, buf, sizeof(buf));
dengyihao's avatar
dengyihao 已提交
581 582 583
  if (sizeof(buf) != nwrite) {
    return -1;
  }
dengyihao's avatar
dengyihao 已提交
584 585

  indexInfo("tfile after write header size: %d", writer->ctx->size(writer->ctx));
dengyihao's avatar
dengyihao 已提交
586 587 588 589 590 591
  writer->offset = nwrite;
  return 0;
}
static int tfileWriteData(TFileWriter* write, TFileValue* tval) {
  TFileHeader* header = &write->header;
  uint8_t      colType = header->colType;
dengyihao's avatar
add UT  
dengyihao 已提交
592 593

  colType = INDEX_TYPE_GET_TYPE(colType);
dengyihao's avatar
dengyihao 已提交
594 595 596 597 598 599 600 601 602 603 604
  if (colType == TSDB_DATA_TYPE_BINARY || colType == TSDB_DATA_TYPE_NCHAR) {
    FstSlice key = fstSliceCreate((uint8_t*)(tval->colVal), (size_t)strlen(tval->colVal));
    if (fstBuilderInsert(write->fb, key, tval->offset)) {
      fstSliceDestroy(&key);
      return 0;
    }
    fstSliceDestroy(&key);
    return -1;
  } else {
    // handle other type later
  }
dengyihao's avatar
dengyihao 已提交
605
  return 0;
dengyihao's avatar
dengyihao 已提交
606
}
dengyihao's avatar
dengyihao 已提交
607 608 609 610 611
static int tfileWriteFooter(TFileWriter* write) {
  char  buf[sizeof(tfileMagicNumber) + 1] = {0};
  void* pBuf = (void*)buf;
  taosEncodeFixedU64((void**)(void*)&pBuf, tfileMagicNumber);
  int nwrite = write->ctx->write(write->ctx, buf, strlen(buf));
dengyihao's avatar
dengyihao 已提交
612 613

  indexInfo("tfile write footer size: %d", write->ctx->size(write->ctx));
dengyihao's avatar
dengyihao 已提交
614 615 616
  assert(nwrite == sizeof(tfileMagicNumber));
  return nwrite;
}
dengyihao's avatar
dengyihao 已提交
617
static int tfileReaderLoadHeader(TFileReader* reader) {
dengyihao's avatar
dengyihao 已提交
618
  // TODO simple tfile header later
dengyihao's avatar
dengyihao 已提交
619
  char buf[TFILE_HEADER_SIZE] = {0};
dengyihao's avatar
dengyihao 已提交
620

dengyihao's avatar
dengyihao 已提交
621
  int64_t nread = reader->ctx->readFrom(reader->ctx, buf, sizeof(buf), 0);
dengyihao's avatar
dengyihao 已提交
622
  if (nread == -1) {
dengyihao's avatar
dengyihao 已提交
623 624
    indexError("actual Read: %d, to read: %d, errno: %d, filename: %s", (int)(nread), (int)sizeof(buf), errno,
               reader->ctx->file.buf);
dengyihao's avatar
dengyihao 已提交
625
  } else {
dengyihao's avatar
dengyihao 已提交
626
    indexInfo("actual Read: %d, to read: %d, filename: %s", (int)(nread), (int)sizeof(buf), reader->ctx->file.buf);
dengyihao's avatar
dengyihao 已提交
627 628
  }
  // assert(nread == sizeof(buf));
dengyihao's avatar
dengyihao 已提交
629
  memcpy(&reader->header, buf, sizeof(buf));
dengyihao's avatar
dengyihao 已提交
630

dengyihao's avatar
dengyihao 已提交
631 632
  return 0;
}
dengyihao's avatar
dengyihao 已提交
633
static int tfileReaderLoadFst(TFileReader* reader) {
dengyihao's avatar
dengyihao 已提交
634 635
  WriterCtx* ctx = reader->ctx;
  int        size = ctx->size(ctx);
dengyihao's avatar
dengyihao 已提交
636

dengyihao's avatar
dengyihao 已提交
637 638
  // current load fst into memory, refactor it later
  int   fstSize = size - reader->header.fstOffset - sizeof(tfileMagicNumber);
wafwerar's avatar
wafwerar 已提交
639
  char* buf = taosMemoryCalloc(1, fstSize);
dengyihao's avatar
dengyihao 已提交
640 641 642
  if (buf == NULL) {
    return -1;
  }
dengyihao's avatar
dengyihao 已提交
643

dengyihao's avatar
dengyihao 已提交
644
  int64_t ts = taosGetTimestampUs();
dengyihao's avatar
dengyihao 已提交
645
  int32_t nread = ctx->readFrom(ctx, buf, fstSize, reader->header.fstOffset);
dengyihao's avatar
dengyihao 已提交
646
  int64_t cost = taosGetTimestampUs() - ts;
dengyihao's avatar
dengyihao 已提交
647
  indexInfo("nread = %d, and fst offset=%d, fst size: %d, filename: %s, file size: %d, time cost: %" PRId64 "us", nread,
dengyihao's avatar
dengyihao 已提交
648
            reader->header.fstOffset, fstSize, ctx->file.buf, ctx->file.size, cost);
dengyihao's avatar
dengyihao 已提交
649
  // we assuse fst size less than FST_MAX_SIZE
dengyihao's avatar
dengyihao 已提交
650
  assert(nread > 0 && nread <= fstSize);
dengyihao's avatar
dengyihao 已提交
651 652 653

  FstSlice st = fstSliceCreate((uint8_t*)buf, nread);
  reader->fst = fstCreate(&st);
wafwerar's avatar
wafwerar 已提交
654
  taosMemoryFree(buf);
dengyihao's avatar
dengyihao 已提交
655 656
  fstSliceDestroy(&st);

dengyihao's avatar
dengyihao 已提交
657
  return reader->fst != NULL ? 0 : -1;
dengyihao's avatar
dengyihao 已提交
658
}
dengyihao's avatar
dengyihao 已提交
659
static int tfileReaderLoadTableIds(TFileReader* reader, int32_t offset, SArray* result) {
dengyihao's avatar
dengyihao 已提交
660
  // TODO(yihao): opt later
dengyihao's avatar
dengyihao 已提交
661
  WriterCtx* ctx = reader->ctx;
dengyihao's avatar
dengyihao 已提交
662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677
  char       block[1024] = {0};
  int32_t    nread = ctx->readFrom(ctx, block, sizeof(block), offset);
  assert(nread >= sizeof(uint32_t));

  char*   p = block;
  int32_t nid = *(int32_t*)p;
  p += sizeof(nid);

  while (nid > 0) {
    int32_t left = block + sizeof(block) - p;
    if (left >= sizeof(uint64_t)) {
      taosArrayPush(result, (uint64_t*)p);
      p += sizeof(uint64_t);
    } else {
      char buf[sizeof(uint64_t)] = {0};
      memcpy(buf, p, left);
dengyihao's avatar
dengyihao 已提交
678

dengyihao's avatar
dengyihao 已提交
679 680 681 682
      memset(block, 0, sizeof(block));
      offset += sizeof(block);
      nread = ctx->readFrom(ctx, block, sizeof(block), offset);
      memcpy(buf + left, block, sizeof(uint64_t) - left);
dengyihao's avatar
dengyihao 已提交
683

dengyihao's avatar
dengyihao 已提交
684 685 686 687
      taosArrayPush(result, (uint64_t*)buf);
      p = block + sizeof(uint64_t) - left;
    }
    nid -= 1;
dengyihao's avatar
dengyihao 已提交
688
  }
dengyihao's avatar
dengyihao 已提交
689 690
  return 0;
}
dengyihao's avatar
dengyihao 已提交
691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709
static int tfileReaderVerify(TFileReader* reader) {
  // just validate header and Footer, file corrupted also shuild be verified later
  WriterCtx* ctx = reader->ctx;

  uint64_t tMagicNumber = 0;

  char buf[sizeof(tMagicNumber) + 1] = {0};
  int  size = ctx->size(ctx);

  if (size < sizeof(tMagicNumber) || size <= sizeof(reader->header)) {
    return -1;
  } else if (ctx->readFrom(ctx, buf, sizeof(tMagicNumber), size - sizeof(tMagicNumber)) != sizeof(tMagicNumber)) {
    return -1;
  }

  taosDecodeFixedU64(buf, &tMagicNumber);
  return tMagicNumber == tfileMagicNumber ? 0 : -1;
}

dengyihao's avatar
dengyihao 已提交
710
void tfileReaderRef(TFileReader* reader) {
dengyihao's avatar
dengyihao 已提交
711 712 713
  if (reader == NULL) {
    return;
  }
dengyihao's avatar
dengyihao 已提交
714 715 716 717
  int ref = T_REF_INC(reader);
  UNUSED(ref);
}

dengyihao's avatar
dengyihao 已提交
718
void tfileReaderUnRef(TFileReader* reader) {
dengyihao's avatar
dengyihao 已提交
719 720 721
  if (reader == NULL) {
    return;
  }
dengyihao's avatar
dengyihao 已提交
722
  int ref = T_REF_DEC(reader);
723
  if (ref == 0) {
dengyihao's avatar
dengyihao 已提交
724
    // do nothing
725 726
    tfileReaderDestroy(reader);
  }
dengyihao's avatar
dengyihao 已提交
727
}
dengyihao's avatar
dengyihao 已提交
728

dengyihao's avatar
dengyihao 已提交
729
static SArray* tfileGetFileList(const char* path) {
dengyihao's avatar
dengyihao 已提交
730 731 732
  char     buf[128] = {0};
  uint64_t suid;
  uint32_t version;
dengyihao's avatar
dengyihao 已提交
733
  SArray*  files = taosArrayInit(4, sizeof(void*));
dengyihao's avatar
dengyihao 已提交
734

wafwerar's avatar
wafwerar 已提交
735 736
  TdDirPtr pDir = taosOpenDir(path);
  if (NULL == pDir) {
dengyihao's avatar
dengyihao 已提交
737 738
    return NULL;
  }
wafwerar's avatar
wafwerar 已提交
739 740 741
  TdDirEntryPtr pDirEntry;
  while ((pDirEntry = taosReadDir(pDir)) != NULL) {
    char* file = taosGetDirEntryName(pDirEntry);
dengyihao's avatar
dengyihao 已提交
742 743 744
    if (0 != tfileParseFileName(file, &suid, buf, &version)) {
      continue;
    }
dengyihao's avatar
dengyihao 已提交
745 746

    size_t len = strlen(path) + 1 + strlen(file) + 1;
wafwerar's avatar
wafwerar 已提交
747
    char*  buf = taosMemoryCalloc(1, len);
dengyihao's avatar
dengyihao 已提交
748
    sprintf(buf, "%s/%s", path, file);
dengyihao's avatar
dengyihao 已提交
749
    taosArrayPush(files, &buf);
dengyihao's avatar
dengyihao 已提交
750
  }
wafwerar's avatar
wafwerar 已提交
751
  taosCloseDir(&pDir);
dengyihao's avatar
dengyihao 已提交
752 753 754 755 756

  taosArraySort(files, tfileCompare);
  tfileRmExpireFile(files);

  return files;
dengyihao's avatar
dengyihao 已提交
757
}
dengyihao's avatar
dengyihao 已提交
758 759 760 761
static int tfileRmExpireFile(SArray* result) {
  // TODO(yihao): remove expire tindex after restart
  return 0;
}
dengyihao's avatar
dengyihao 已提交
762 763
static void tfileDestroyFileName(void* elem) {
  char* p = *(char**)elem;
wafwerar's avatar
wafwerar 已提交
764
  taosMemoryFree(p);
dengyihao's avatar
dengyihao 已提交
765 766
}
static int tfileCompare(const void* a, const void* b) {
dengyihao's avatar
dengyihao 已提交
767 768 769
  const char* as = *(char**)a;
  const char* bs = *(char**)b;
  return strcmp(as, bs);
dengyihao's avatar
dengyihao 已提交
770
}
dengyihao's avatar
dengyihao 已提交
771 772 773

static int tfileParseFileName(const char* filename, uint64_t* suid, char* col, int* version) {
  if (3 == sscanf(filename, "%" PRIu64 "-%[^-]-%d.tindex", suid, col, version)) {
dengyihao's avatar
dengyihao 已提交
774 775 776 777 778
    // read suid & colid & version  success
    return 0;
  }
  return -1;
}
dengyihao's avatar
dengyihao 已提交
779 780 781 782 783 784 785 786 787 788
// tfile name suid-colId-version.tindex
static void tfileGenFileName(char* filename, uint64_t suid, const char* col, int version) {
  sprintf(filename, "%" PRIu64 "-%s-%d.tindex", suid, col, version);
  return;
}
static void tfileGenFileFullName(char* fullname, const char* path, uint64_t suid, const char* col, int32_t version) {
  char filename[128] = {0};
  tfileGenFileName(filename, suid, col, version);
  sprintf(fullname, "%s/%s", path, filename);
}