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

dengyihao's avatar
dengyihao 已提交
16 17
#include "indexFstCountingWriter.h"
#include "indexFstUtil.h"
dengyihao's avatar
dengyihao 已提交
18
#include "indexInt.h"
dengyihao's avatar
dengyihao 已提交
19
#include "os.h"
20
#include "tutil.h"
dengyihao's avatar
dengyihao 已提交
21

dengyihao's avatar
dengyihao 已提交
22
static int writeCtxDoWrite(WriterCtx* ctx, uint8_t* buf, int len) {
dengyihao's avatar
dengyihao 已提交
23
  if (ctx->type == TFile) {
24
    assert(len == taosWriteFile(ctx->file.pFile, buf, len));
dengyihao's avatar
dengyihao 已提交
25
  } else {
26 27
    memcpy(ctx->mem.buf + ctx->offset, buf, len);
  }
dengyihao's avatar
dengyihao 已提交
28 29 30
  ctx->offset += len;
  return len;
}
dengyihao's avatar
dengyihao 已提交
31
static int writeCtxDoRead(WriterCtx* ctx, uint8_t* buf, int len) {
32
  int nRead = 0;
dengyihao's avatar
dengyihao 已提交
33
  if (ctx->type == TFile) {
dengyihao's avatar
dengyihao 已提交
34 35 36 37
#ifdef USE_MMAP
    nRead = len < ctx->file.size ? len : ctx->file.size;
    memcpy(buf, ctx->file.ptr, nRead);
#else
38
    nRead = taosReadFile(ctx->file.pFile, buf, len);
dengyihao's avatar
dengyihao 已提交
39
#endif
dengyihao's avatar
dengyihao 已提交
40
  } else {
dengyihao's avatar
dengyihao 已提交
41
    memcpy(buf, ctx->mem.buf + ctx->offset, len);
dengyihao's avatar
dengyihao 已提交
42
  }
dengyihao's avatar
dengyihao 已提交
43
  ctx->offset += nRead;
dengyihao's avatar
dengyihao 已提交
44

dengyihao's avatar
dengyihao 已提交
45
  return nRead;
46
}
dengyihao's avatar
dengyihao 已提交
47 48 49
static int writeCtxDoReadFrom(WriterCtx* ctx, uint8_t* buf, int len, int32_t offset) {
  int nRead = 0;
  if (ctx->type == TFile) {
50
    // tfLseek(ctx->file.pFile, offset, 0);
dengyihao's avatar
dengyihao 已提交
51 52 53 54 55
#ifdef USE_MMAP
    int32_t last = ctx->file.size - offset;
    nRead = last >= len ? len : last;
    memcpy(buf, ctx->file.ptr + offset, nRead);
#else
56
    nRead = taosPReadFile(ctx->file.pFile, buf, len, offset);
dengyihao's avatar
dengyihao 已提交
57
#endif
dengyihao's avatar
dengyihao 已提交
58 59 60 61 62 63
  } else {
    // refactor later
    assert(0);
  }
  return nRead;
}
dengyihao's avatar
dengyihao 已提交
64
static int writeCtxGetSize(WriterCtx* ctx) {
dengyihao's avatar
dengyihao 已提交
65
  if (ctx->type == TFile) {
66 67 68
    int64_t file_size = 0;
    taosStatFile(ctx->file.buf, &file_size, NULL);
    return (int)file_size;
dengyihao's avatar
dengyihao 已提交
69 70 71
  }
  return 0;
}
dengyihao's avatar
dengyihao 已提交
72
static int writeCtxDoFlush(WriterCtx* ctx) {
dengyihao's avatar
dengyihao 已提交
73
  if (ctx->type == TFile) {
74 75 76
    // taosFsyncFile(ctx->file.pFile);
    taosFsyncFile(ctx->file.pFile);
    // tfFlush(ctx->file.pFile);
dengyihao's avatar
dengyihao 已提交
77 78 79 80 81 82
  } else {
    // do nothing
  }
  return 1;
}

dengyihao's avatar
dengyihao 已提交
83
WriterCtx* writerCtxCreate(WriterType type, const char* path, bool readOnly, int32_t capacity) {
wafwerar's avatar
wafwerar 已提交
84
  WriterCtx* ctx = taosMemoryCalloc(1, sizeof(WriterCtx));
dengyihao's avatar
dengyihao 已提交
85 86 87
  if (ctx == NULL) {
    return NULL;
  }
dengyihao's avatar
dengyihao 已提交
88

dengyihao's avatar
dengyihao 已提交
89
  ctx->type = type;
dengyihao's avatar
dengyihao 已提交
90
  if (ctx->type == TFile) {
dengyihao's avatar
dengyihao 已提交
91
    // ugly code, refactor later
dengyihao's avatar
dengyihao 已提交
92
    ctx->file.readOnly = readOnly;
dengyihao's avatar
dengyihao 已提交
93
    if (readOnly == false) {
94 95 96 97 98 99
      // ctx->file.pFile = open(path, O_WRONLY | O_CREAT | O_APPEND, S_IRWXU | S_IRWXG | S_IRWXO);
      ctx->file.pFile = taosOpenFile(path, TD_FILE_CTEATE | TD_FILE_WRITE | TD_FILE_APPEND);
      taosFtruncateFile(ctx->file.pFile, 0);
      int64_t file_size;
      taosStatFile(path, &file_size, NULL);
      ctx->file.size = (int)file_size;
dengyihao's avatar
dengyihao 已提交
100
    } else {
101 102
      // ctx->file.pFile = open(path, O_RDONLY, S_IRWXU | S_IRWXG | S_IRWXO);
      ctx->file.pFile = taosOpenFile(path, TD_FILE_READ);
dengyihao's avatar
dengyihao 已提交
103

104 105 106
      int64_t file_size = 0;
      taosFStatFile(ctx->file.pFile, &file_size, NULL);
      ctx->file.size = (int)file_size;
dengyihao's avatar
dengyihao 已提交
107
#ifdef USE_MMAP
108
      ctx->file.ptr = (char*)tfMmapReadOnly(ctx->file.pFile, ctx->file.size);
dengyihao's avatar
dengyihao 已提交
109
#endif
110
    }
dengyihao's avatar
dengyihao 已提交
111
    memcpy(ctx->file.buf, path, strlen(path));
112
    if (ctx->file.pFile == NULL) {
dengyihao's avatar
dengyihao 已提交
113
      indexError("failed to open file, error %d", errno);
dengyihao's avatar
dengyihao 已提交
114
      goto END;
dengyihao's avatar
dengyihao 已提交
115
    }
dengyihao's avatar
dengyihao 已提交
116
  } else if (ctx->type == TMemory) {
wafwerar's avatar
wafwerar 已提交
117
    ctx->mem.buf = taosMemoryCalloc(1, sizeof(char) * capacity);
118 119
    ctx->mem.capa = capacity;
  }
dengyihao's avatar
dengyihao 已提交
120
  ctx->write = writeCtxDoWrite;
121
  ctx->read = writeCtxDoRead;
dengyihao's avatar
dengyihao 已提交
122
  ctx->flush = writeCtxDoFlush;
dengyihao's avatar
dengyihao 已提交
123
  ctx->readFrom = writeCtxDoReadFrom;
dengyihao's avatar
dengyihao 已提交
124
  ctx->size = writeCtxGetSize;
dengyihao's avatar
dengyihao 已提交
125 126

  ctx->offset = 0;
127
  ctx->limit = capacity;
dengyihao's avatar
dengyihao 已提交
128 129

  return ctx;
dengyihao's avatar
dengyihao 已提交
130
END:
dengyihao's avatar
dengyihao 已提交
131 132 133
  if (ctx->type == TMemory) {
    taosMemoryFree(ctx->mem.buf);
  }
wafwerar's avatar
wafwerar 已提交
134
  taosMemoryFree(ctx);
dengyihao's avatar
dengyihao 已提交
135
  return NULL;
dengyihao's avatar
dengyihao 已提交
136
}
dengyihao's avatar
dengyihao 已提交
137
void writerCtxDestroy(WriterCtx* ctx, bool remove) {
dengyihao's avatar
dengyihao 已提交
138
  if (ctx->type == TMemory) {
wafwerar's avatar
wafwerar 已提交
139
    taosMemoryFree(ctx->mem.buf);
dengyihao's avatar
dengyihao 已提交
140
  } else {
dengyihao's avatar
dengyihao 已提交
141
    ctx->flush(ctx);
142
    taosCloseFile(&ctx->file.pFile);
dengyihao's avatar
dengyihao 已提交
143 144 145 146 147
    if (ctx->file.readOnly) {
#ifdef USE_MMAP
      munmap(ctx->file.ptr, ctx->file.size);
#endif
    }
dengyihao's avatar
dengyihao 已提交
148
    if (ctx->file.readOnly == false) {
149 150 151 152
      int64_t file_size = 0;
      taosStatFile(ctx->file.buf, &file_size, NULL);
      // struct stat fstat;
      // stat(ctx->file.buf, &fstat);
dengyihao's avatar
dengyihao 已提交
153 154
      // indexError("write file size: %d", (int)(fstat.st_size));
    }
dengyihao's avatar
dengyihao 已提交
155 156 157
    if (remove) {
      unlink(ctx->file.buf);
    }
dengyihao's avatar
dengyihao 已提交
158
  }
wafwerar's avatar
wafwerar 已提交
159
  taosMemoryFree(ctx);
dengyihao's avatar
dengyihao 已提交
160 161
}

dengyihao's avatar
dengyihao 已提交
162
FstCountingWriter* fstCountingWriterCreate(void* wrt) {
wafwerar's avatar
wafwerar 已提交
163
  FstCountingWriter* cw = taosMemoryCalloc(1, sizeof(FstCountingWriter));
dengyihao's avatar
dengyihao 已提交
164 165 166
  if (cw == NULL) {
    return NULL;
  }
167

dengyihao's avatar
dengyihao 已提交
168
  cw->wrt = wrt;
169 170
  //(void *)(writerCtxCreate(TFile, readOnly));
  return cw;
dengyihao's avatar
dengyihao 已提交
171
}
dengyihao's avatar
dengyihao 已提交
172
void fstCountingWriterDestroy(FstCountingWriter* cw) {
173
  // free wrt object: close fd or free mem
dengyihao's avatar
dengyihao 已提交
174
  fstCountingWriterFlush(cw);
175
  // writerCtxDestroy((WriterCtx *)(cw->wrt));
wafwerar's avatar
wafwerar 已提交
176
  taosMemoryFree(cw);
dengyihao's avatar
dengyihao 已提交
177 178
}

dengyihao's avatar
dengyihao 已提交
179
int fstCountingWriterWrite(FstCountingWriter* write, uint8_t* buf, uint32_t len) {
dengyihao's avatar
dengyihao 已提交
180 181 182
  if (write == NULL) {
    return 0;
  }
183
  // update checksum
dengyihao's avatar
dengyihao 已提交
184
  // write data to file/socket or mem
dengyihao's avatar
dengyihao 已提交
185
  WriterCtx* ctx = write->wrt;
dengyihao's avatar
dengyihao 已提交
186

187
  int nWrite = ctx->write(ctx, buf, len);
dengyihao's avatar
dengyihao 已提交
188 189
  assert(nWrite == len);
  write->count += len;
dengyihao's avatar
dengyihao 已提交
190 191

  write->summer = taosCalcChecksum(write->summer, buf, len);
192 193
  return len;
}
dengyihao's avatar
dengyihao 已提交
194
int fstCountingWriterRead(FstCountingWriter* write, uint8_t* buf, uint32_t len) {
dengyihao's avatar
dengyihao 已提交
195 196 197
  if (write == NULL) {
    return 0;
  }
dengyihao's avatar
dengyihao 已提交
198
  WriterCtx* ctx = write->wrt;
199 200 201
  int        nRead = ctx->read(ctx, buf, len);
  // assert(nRead == len);
  return nRead;
dengyihao's avatar
dengyihao 已提交
202
}
203

dengyihao's avatar
dengyihao 已提交
204 205 206 207
uint32_t fstCountingWriterMaskedCheckSum(FstCountingWriter* write) {
  // opt
  return write->summer;
}
dengyihao's avatar
dengyihao 已提交
208 209

int fstCountingWriterFlush(FstCountingWriter* write) {
dengyihao's avatar
dengyihao 已提交
210
  WriterCtx* ctx = write->wrt;
dengyihao's avatar
dengyihao 已提交
211
  ctx->flush(ctx);
212
  // write->wtr->flush
dengyihao's avatar
dengyihao 已提交
213 214 215
  return 1;
}

dengyihao's avatar
dengyihao 已提交
216
void fstCountingWriterPackUintIn(FstCountingWriter* writer, uint64_t n, uint8_t nBytes) {
dengyihao's avatar
dengyihao 已提交
217
  assert(1 <= nBytes && nBytes <= 8);
wafwerar's avatar
wafwerar 已提交
218
  uint8_t* buf = taosMemoryCalloc(8, sizeof(uint8_t));
dengyihao's avatar
dengyihao 已提交
219
  for (uint8_t i = 0; i < nBytes; i++) {
220
    buf[i] = (uint8_t)n;
dengyihao's avatar
dengyihao 已提交
221 222 223
    n = n >> 8;
  }
  fstCountingWriterWrite(writer, buf, nBytes);
wafwerar's avatar
wafwerar 已提交
224
  taosMemoryFree(buf);
dengyihao's avatar
dengyihao 已提交
225 226
  return;
}
dengyihao's avatar
dengyihao 已提交
227

dengyihao's avatar
dengyihao 已提交
228
uint8_t fstCountingWriterPackUint(FstCountingWriter* writer, uint64_t n) {
dengyihao's avatar
dengyihao 已提交
229 230
  uint8_t nBytes = packSize(n);
  fstCountingWriterPackUintIn(writer, n, nBytes);
231 232
  return nBytes;
}