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

#include "index_fst.h"
dengyihao's avatar
dengyihao 已提交
17
#include "tcoding.h"
dengyihao's avatar
dengyihao 已提交
18
#include "tchecksum.h"
dengyihao's avatar
dengyihao 已提交
19

dengyihao's avatar
dengyihao 已提交
20 21 22 23 24

static void fstPackDeltaIn(FstCountingWriter *wrt, CompiledAddr nodeAddr, CompiledAddr transAddr, uint8_t nBytes) {
  CompiledAddr deltaAddr = (transAddr == EMPTY_ADDRESS) ? EMPTY_ADDRESS : nodeAddr - transAddr;
  fstCountingWriterPackUintIn(wrt, deltaAddr, nBytes); 
}
dengyihao's avatar
dengyihao 已提交
25
static uint8_t fstPackDetla(FstCountingWriter *wrt, CompiledAddr nodeAddr, CompiledAddr transAddr) {
dengyihao's avatar
dengyihao 已提交
26 27
  uint8_t nBytes = packDeltaSize(nodeAddr, transAddr);
  fstPackDeltaIn(wrt, nodeAddr, transAddr, nBytes); 
dengyihao's avatar
dengyihao 已提交
28
  return nBytes;
dengyihao's avatar
dengyihao 已提交
29
}
dengyihao's avatar
dengyihao 已提交
30

dengyihao's avatar
dengyihao 已提交
31 32 33 34 35 36 37 38
FstUnFinishedNodes *fstUnFinishedNodesCreate() {
  FstUnFinishedNodes *nodes = malloc(sizeof(FstUnFinishedNodes));
  if (nodes == NULL) { return NULL; }

  nodes->stack = (SArray *)taosArrayInit(64, sizeof(FstBuilderNodeUnfinished));
  fstUnFinishedNodesPushEmpty(nodes, false);
  return nodes;
}
dengyihao's avatar
dengyihao 已提交
39 40 41 42
void unFinishedNodeDestroyElem(void* elem) {
  FstBuilderNodeUnfinished *b = (FstBuilderNodeUnfinished*)elem;
  fstBuilderNodeDestroy(b->node); 
  free(b->last); 
dengyihao's avatar
dengyihao 已提交
43
  b->last = NULL;
dengyihao's avatar
dengyihao 已提交
44
}  
dengyihao's avatar
dengyihao 已提交
45
void fstUnFinishedNodesDestroy(FstUnFinishedNodes *nodes) {
dengyihao's avatar
dengyihao 已提交
46 47 48 49 50 51
  if (nodes == NULL) { return; } 

  taosArrayDestroyEx(nodes->stack, unFinishedNodeDestroyElem); 
  free(nodes);
}

dengyihao's avatar
dengyihao 已提交
52 53 54 55
void fstUnFinishedNodesPushEmpty(FstUnFinishedNodes *nodes, bool isFinal) {
  FstBuilderNode *node = malloc(sizeof(FstBuilderNode));
  node->isFinal     = isFinal;
  node->finalOutput = 0;
dengyihao's avatar
dengyihao 已提交
56
  node->trans       = taosArrayInit(16, sizeof(FstTransition));
dengyihao's avatar
dengyihao 已提交
57 58 59 60 61 62 63 64 65

  FstBuilderNodeUnfinished un = {.node = node, .last = NULL}; 
  taosArrayPush(nodes->stack, &un);
  
}
FstBuilderNode *fstUnFinishedNodesPopRoot(FstUnFinishedNodes *nodes) {
  assert(taosArrayGetSize(nodes->stack) == 1);

  FstBuilderNodeUnfinished *un = taosArrayPop(nodes->stack);
dengyihao's avatar
dengyihao 已提交
66
  assert(un->last == NULL); 
dengyihao's avatar
dengyihao 已提交
67 68 69 70 71 72
  return un->node;  
}

FstBuilderNode *fstUnFinishedNodesPopFreeze(FstUnFinishedNodes *nodes, CompiledAddr addr) {
  FstBuilderNodeUnfinished *un = taosArrayPop(nodes->stack);
  fstBuilderNodeUnfinishedLastCompiled(un, addr);
dengyihao's avatar
dengyihao 已提交
73 74
  //free(un->last); // TODO add func FstLastTransitionFree()
  //un->last = NULL;
dengyihao's avatar
dengyihao 已提交
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
  return un->node; 
}

FstBuilderNode *fstUnFinishedNodesPopEmpty(FstUnFinishedNodes *nodes) {
  FstBuilderNodeUnfinished *un = taosArrayPop(nodes->stack);
  assert(un->last == NULL); 
  return un->node;  
  
}
void fstUnFinishedNodesSetRootOutput(FstUnFinishedNodes *nodes, Output out) {
  FstBuilderNodeUnfinished *un = taosArrayGet(nodes->stack, 0);
  un->node->isFinal     = true;
  un->node->finalOutput = out;
  //un->node->trans       = NULL;  
} 
void fstUnFinishedNodesTopLastFreeze(FstUnFinishedNodes *nodes, CompiledAddr addr) {
  size_t sz = taosArrayGetSize(nodes->stack) - 1; 
  FstBuilderNodeUnfinished *un = taosArrayGet(nodes->stack, sz);
  fstBuilderNodeUnfinishedLastCompiled(un, addr);
}
void fstUnFinishedNodesAddSuffix(FstUnFinishedNodes *nodes, FstSlice bs, Output out) {
  FstSlice *s = &bs;
dengyihao's avatar
dengyihao 已提交
97
  if (fstSliceIsEmpty(s)) {
dengyihao's avatar
dengyihao 已提交
98 99 100 101 102 103
    return;
  }
  size_t sz = taosArrayGetSize(nodes->stack) - 1; 
  FstBuilderNodeUnfinished *un = taosArrayGet(nodes->stack, sz);
  assert(un->last == NULL);

dengyihao's avatar
dengyihao 已提交
104 105 106
  //FstLastTransition *trn = malloc(sizeof(FstLastTransition)); 
  //trn->inp = s->data[s->start]; 
  //trn->out = out;
dengyihao's avatar
dengyihao 已提交
107 108 109
  int32_t len = 0;
  uint8_t *data = fstSliceData(s, &len);
  un->last = fstLastTransitionCreate(data[0], out); 
dengyihao's avatar
dengyihao 已提交
110

dengyihao's avatar
dengyihao 已提交
111
  for (uint64_t i = 1; i < len; i++) {
dengyihao's avatar
dengyihao 已提交
112 113 114
    FstBuilderNode *n = malloc(sizeof(FstBuilderNode));
    n->isFinal     = false;
    n->finalOutput = 0;
dengyihao's avatar
dengyihao 已提交
115
    n->trans       = taosArrayInit(16, sizeof(FstTransition));
dengyihao's avatar
dengyihao 已提交
116
    
dengyihao's avatar
dengyihao 已提交
117 118 119
    //FstLastTransition *trn = malloc(sizeof(FstLastTransition)); 
    //trn->inp = s->data[i];
    //trn->out = out; 
dengyihao's avatar
dengyihao 已提交
120
    FstLastTransition *trn = fstLastTransitionCreate(data[i], 0);
dengyihao's avatar
dengyihao 已提交
121 122 123 124 125 126 127 128 129 130 131 132 133

    FstBuilderNodeUnfinished un = {.node = n, .last = trn}; 
    taosArrayPush(nodes->stack, &un); 
  }
  fstUnFinishedNodesPushEmpty(nodes, true);  
}


uint64_t fstUnFinishedNodesFindCommPrefix(FstUnFinishedNodes *node, FstSlice bs) {
  FstSlice *s = &bs;

  size_t ssz = taosArrayGetSize(node->stack);  // stack size
  uint64_t count = 0;
dengyihao's avatar
dengyihao 已提交
134 135
  int32_t  lsz;          // data len 
  uint8_t  *data = fstSliceData(s, &lsz);
dengyihao's avatar
dengyihao 已提交
136 137
  for (size_t i = 0; i < ssz && i < lsz; i++) {
    FstBuilderNodeUnfinished *un = taosArrayGet(node->stack, i); 
dengyihao's avatar
dengyihao 已提交
138
    if (un->last->inp == data[i]) {
dengyihao's avatar
dengyihao 已提交
139 140 141 142 143 144 145
      count++;
    } else {
      break;
    } 
  }
  return count;
}
dengyihao's avatar
dengyihao 已提交
146
uint64_t fstUnFinishedNodesFindCommPrefixAndSetOutput(FstUnFinishedNodes *node, FstSlice bs, Output in, Output *out) {
dengyihao's avatar
dengyihao 已提交
147 148 149 150 151
  FstSlice *s = &bs;

  size_t lsz = (size_t)(s->end - s->start + 1);          // data len 
  size_t ssz = taosArrayGetSize(node->stack);  // stack size

dengyihao's avatar
dengyihao 已提交
152 153
  uint64_t i = 0;
  for (i = 0; i < lsz && i < ssz; i++) {
dengyihao's avatar
dengyihao 已提交
154 155
    FstBuilderNodeUnfinished *un = taosArrayGet(node->stack, i);

dengyihao's avatar
dengyihao 已提交
156 157
    FstLastTransition *t = un->last; 
    uint64_t addPrefix = 0;  
dengyihao's avatar
dengyihao 已提交
158 159
    uint8_t *data = fstSliceData(s, NULL);
    if (t && t->inp == data[i]) {
dengyihao's avatar
dengyihao 已提交
160 161 162 163 164
      uint64_t commPrefix = MIN(t->out, *out);      
      uint64_t tAddPrefix  = t->out - commPrefix; 
      (*out) = (*out) - commPrefix; 
      t->out = commPrefix;
      addPrefix = tAddPrefix; 
dengyihao's avatar
dengyihao 已提交
165
    } else {
dengyihao's avatar
dengyihao 已提交
166 167 168 169
       break;
    }
    if (addPrefix != 0) {
      fstBuilderNodeUnfinishedAddOutputPrefix(un, addPrefix);  
dengyihao's avatar
dengyihao 已提交
170 171
    }
  }   
dengyihao's avatar
dengyihao 已提交
172
  return i;
dengyihao's avatar
dengyihao 已提交
173 174 175
} 


dengyihao's avatar
dengyihao 已提交
176
FstState fstStateCreateFrom(FstSlice* slice, CompiledAddr addr) {
dengyihao's avatar
dengyihao 已提交
177
  FstState fs = {.state = EmptyFinal, .val = 0};
dengyihao's avatar
dengyihao 已提交
178 179 180
  if (addr == EMPTY_ADDRESS) {
    return fs; 
  }
dengyihao's avatar
dengyihao 已提交
181 182 183
  
  uint8_t *data = fstSliceData(slice, NULL);
  uint8_t v = data[addr]; 
dengyihao's avatar
dengyihao 已提交
184 185 186 187
  uint8_t t = (v & 0b11000000) >> 6;
  if (t == 0b11) {
    fs.state = OneTransNext;
  } else if (t == 0b10) {
dengyihao's avatar
dengyihao 已提交
188
    fs.state = OneTrans; 
dengyihao's avatar
dengyihao 已提交
189
  } else {
dengyihao's avatar
dengyihao 已提交
190
    fs.state = AnyTrans;  
dengyihao's avatar
dengyihao 已提交
191
  }
dengyihao's avatar
dengyihao 已提交
192
  fs.val = v;
dengyihao's avatar
dengyihao 已提交
193 194
  return fs;
}
dengyihao's avatar
dengyihao 已提交
195

dengyihao's avatar
dengyihao 已提交
196
static FstState fstStateDict[] = {
dengyihao's avatar
dengyihao 已提交
197 198 199 200 201
  {.state = OneTransNext, .val = 0b11000000},
  {.state = OneTrans,     .val = 0b10000000},
  {.state = AnyTrans,     .val = 0b00000000},
  {.state = EmptyFinal,   .val = 0b00000000}
};
dengyihao's avatar
dengyihao 已提交
202
// debug 
dengyihao's avatar
dengyihao 已提交
203
static const char *fstStateStr[] = {"ONE_TRANS_NEXT", "ONE_TRANS", "ANY_TRANS", "EMPTY_FINAL"}; 
dengyihao's avatar
dengyihao 已提交
204 205 206

FstState fstStateCreate(State state){
  uint8_t idx = (uint8_t)state;
dengyihao's avatar
dengyihao 已提交
207
  return fstStateDict[idx];
dengyihao's avatar
dengyihao 已提交
208 209
}
//compile
dengyihao's avatar
dengyihao 已提交
210 211 212 213 214 215 216 217
void fstStateCompileForOneTransNext(FstCountingWriter *w, CompiledAddr addr, uint8_t inp) {
  FstState s = fstStateCreate(OneTransNext);  
  fstStateSetCommInput(&s, inp);

  bool null = false;
  uint8_t v = fstStateCommInput(&s, &null);
  if (null) {
    // w->write_all(&[inp])
dengyihao's avatar
dengyihao 已提交
218 219 220
    fstCountingWriterWrite(w, &inp, 1);
  }     
  fstCountingWriterWrite(w, &(s.val), 1);
dengyihao's avatar
dengyihao 已提交
221
  // w->write_all(&[s.val])
dengyihao's avatar
dengyihao 已提交
222
  return;
dengyihao's avatar
dengyihao 已提交
223
}
dengyihao's avatar
dengyihao 已提交
224
void fstStateCompileForOneTrans(FstCountingWriter *w, CompiledAddr addr, FstTransition* trn) {
dengyihao's avatar
dengyihao 已提交
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
  Output out = trn->out;   
  uint8_t outPackSize = (out == 0 ? 0 : fstCountingWriterPackUint(w, out));        
  uint8_t transPackSize = fstPackDetla(w, addr, trn->addr);      
  PackSizes packSizes = 0;

  FST_SET_OUTPUT_PACK_SIZE(packSizes, outPackSize);
  FST_SET_TRANSITION_PACK_SIZE(packSizes, transPackSize);
  fstCountingWriterWrite(w, (char *)&packSizes, sizeof(packSizes)); 

  FstState st = fstStateCreate(OneTrans); 
  
  fstStateSetCommInput(&st, trn->inp);
  bool null = false;
  uint8_t inp = fstStateCommInput(&st, &null);   
  if (null == true) {
    fstCountingWriterWrite(w, (char *)&trn->inp, sizeof(trn->inp));
  }
  fstCountingWriterWrite(w, (char *)(&(st.val)), sizeof(st.val));
dengyihao's avatar
dengyihao 已提交
243 244 245
  return ;

}
dengyihao's avatar
dengyihao 已提交
246
void fstStateCompileForAnyTrans(FstCountingWriter *w, CompiledAddr addr, FstBuilderNode *node) {
dengyihao's avatar
dengyihao 已提交
247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294
  size_t sz = taosArrayGetSize(node->trans);  
  assert(sz <= 256);

  uint8_t tSize = 0;
  uint8_t oSize = packSize(node->finalOutput) ;  
  
  // finalOutput.is_zero()
  bool anyOuts = (node->finalOutput != 0) ;
  for (size_t i = 0; i < sz; i++) {
    FstTransition *t = taosArrayGet(node->trans, i); 
    tSize = MAX(tSize, packDeltaSize(addr, t->addr)); 
    oSize = MAX(oSize, packSize(t->out));
    anyOuts = anyOuts || (t->out != 0); 
  }

  PackSizes packSizes = 0; 
  if (anyOuts) { FST_SET_OUTPUT_PACK_SIZE(packSizes, oSize); }
  else { FST_SET_OUTPUT_PACK_SIZE(packSizes, 0); }

  FST_SET_TRANSITION_PACK_SIZE(packSizes, tSize);
  
  FstState st = fstStateCreate(AnyTrans);
  fstStateSetFinalState(&st, node->isFinal); 
  fstStateSetStateNtrans(&st, (uint8_t)sz);
   
  if (anyOuts) {
    if (FST_BUILDER_NODE_IS_FINAL(node)) {
      fstCountingWriterPackUintIn(w, node->finalOutput, oSize);
    }
    for (size_t i = 0; i < sz; i++) {
      FstTransition *t = taosArrayGet(node->trans, i);
      fstCountingWriterPackUintIn(w, t->out, oSize);
    }
  } 
  for (size_t i = 0; i < sz; i++) {
      FstTransition *t = taosArrayGet(node->trans, i);
      fstPackDeltaIn(w, addr, t->addr, tSize);
  }
  for (size_t i = 0; i < sz; i++) {
     FstTransition *t = taosArrayGet(node->trans, i);
     fstCountingWriterWrite(w, (char *)&t->inp, 1);
      //fstPackDeltaIn(w, addr, t->addr, tSize);
  }
  if (sz > TRANS_INDEX_THRESHOLD) {
    // A value of 255 indicates that no transition exists for the byte
    // at that index. (Except when there are 256 transitions.) Namely,
    // any value greater than or equal to the number of transitions in
    // this node indicates an absent transition.
dengyihao's avatar
dengyihao 已提交
295
    uint8_t *index = (uint8_t *)malloc(sizeof(uint8_t) * 256); 
dengyihao's avatar
dengyihao 已提交
296 297 298 299 300 301 302 303 304
    for (uint8_t i = 0; i < 256; i++) {
      index[i] = 255;
    }
    for (size_t i = 0; i < sz; i++) {
      FstTransition *t = taosArrayGet(node->trans, i);
      index[t->inp] = i;
      fstCountingWriterWrite(w, (char *)index, sizeof(index)); 
      //fstPackDeltaIn(w, addr, t->addr, tSize);
    }
dengyihao's avatar
dengyihao 已提交
305
    free(index);
dengyihao's avatar
dengyihao 已提交
306 307 308 309 310 311 312 313 314 315 316 317 318
  }
  fstCountingWriterWrite(w, (char *)&packSizes, 1);
  bool null = false;
  fstStateStateNtrans(&st, &null);
  if (null == true) {
     // 256 can't be represented in a u8, so we abuse the fact that
     // the # of transitions can never be 1 here, since 1 is always
     // encoded in the state byte.
    uint8_t v = 1;
    if (sz == 256) { fstCountingWriterWrite(w, (char *)&v, 1); }
    else { fstCountingWriterWrite(w, (char *)&sz, 1); }
  }
  fstCountingWriterWrite(w, (char *)(&(st.val)), 1);
dengyihao's avatar
dengyihao 已提交
319 320 321 322 323 324 325 326 327
  return;
}

// set_comm_input
void fstStateSetCommInput(FstState* s, uint8_t inp) {
  assert(s->state == OneTransNext || s->state == OneTrans);

  uint8_t val;
  COMMON_INDEX(inp, 0x111111, val); 
dengyihao's avatar
dengyihao 已提交
328
  s->val = (s->val & fstStateDict[s->state].val) | val;    
dengyihao's avatar
dengyihao 已提交
329 330 331
}

// comm_input
dengyihao's avatar
dengyihao 已提交
332
uint8_t fstStateCommInput(FstState* s, bool *null) {
dengyihao's avatar
dengyihao 已提交
333 334
  assert(s->state == OneTransNext || s->state == OneTrans);
  uint8_t v = s->val & 0b00111111;
dengyihao's avatar
dengyihao 已提交
335 336 337 338
  if (v == 0) { 
    *null = true; 
    return v;
  } 
dengyihao's avatar
dengyihao 已提交
339 340 341 342 343 344 345 346
  //v = 0 indicate that common_input is None
  return v == 0 ? 0 : COMMON_INPUT(v);  
}

// input_len

uint64_t fstStateInputLen(FstState* s) {
  assert(s->state == OneTransNext || s->state == OneTrans);
dengyihao's avatar
dengyihao 已提交
347 348 349
  bool null = false;
  fstStateCommInput(s, &null); 
  return null ? 1 : 0 ;
dengyihao's avatar
dengyihao 已提交
350
} 
dengyihao's avatar
dengyihao 已提交
351
  
dengyihao's avatar
dengyihao 已提交
352 353
// end_addr 
uint64_t fstStateEndAddrForOneTransNext(FstState* s, FstSlice *data) {
dengyihao's avatar
dengyihao 已提交
354
  assert(s->state == OneTransNext);
dengyihao's avatar
dengyihao 已提交
355 356 357
  return FST_SLICE_LEN(data) - 1 - fstStateInputLen(s);
}
uint64_t fstStateEndAddrForOneTrans(FstState *s, FstSlice *data, PackSizes sizes) {
dengyihao's avatar
dengyihao 已提交
358
  assert(s->state == OneTrans);
dengyihao's avatar
dengyihao 已提交
359 360 361 362 363 364
  return FST_SLICE_LEN(data) 
                - 1 
                - fstStateInputLen(s) 
                - 1 // pack size 
                - FST_GET_TRANSITION_PACK_SIZE(sizes) 
                - FST_GET_OUTPUT_PACK_SIZE(sizes); 
dengyihao's avatar
dengyihao 已提交
365 366
}
uint64_t fstStateEndAddrForAnyTrans(FstState *state, uint64_t version, FstSlice *date, PackSizes sizes, uint64_t nTrans) {
dengyihao's avatar
dengyihao 已提交
367 368 369 370 371 372 373 374 375
  uint8_t oSizes = FST_GET_OUTPUT_PACK_SIZE(sizes); 
  uint8_t finalOsize = !fstStateIsFinalState(state) ? 0 : oSizes;    
  return FST_SLICE_LEN(date)  
               - 1 
               - fstStateNtransLen(state) 
               - 1 //pack size 
               - fstStateTotalTransSize(state, version, sizes, nTrans) 
               - nTrans * oSizes  // output values
               - finalOsize;     // final output 
dengyihao's avatar
dengyihao 已提交
376 377
}
// input  
dengyihao's avatar
dengyihao 已提交
378 379 380
uint8_t  fstStateInput(FstState *s, FstNode *node) {
  assert(s->state == OneTransNext || s->state == OneTrans);
  FstSlice *slice = &node->data;
dengyihao's avatar
dengyihao 已提交
381 382
  bool null = false;
  uint8_t inp = fstStateCommInput(s, &null);
dengyihao's avatar
dengyihao 已提交
383 384
  uint8_t *data = fstSliceData(slice, NULL); 
  return null == false ? inp : data[-1];
dengyihao's avatar
dengyihao 已提交
385
}
dengyihao's avatar
dengyihao 已提交
386 387 388 389 390 391 392 393 394 395
uint8_t  fstStateInputForAnyTrans(FstState *s, FstNode *node, uint64_t i) {
  assert(s->state == AnyTrans);
  FstSlice *slice = &node->data; 

  uint64_t at = node->start 
            - fstStateNtransLen(s) 
            - 1  // pack size
            - fstStateTransIndexSize(s, node->version, node->nTrans) 
            - i 
            - 1; // the output size 
dengyihao's avatar
dengyihao 已提交
396 397 398

  uint8_t *data = fstSliceData(slice, NULL);
  return data[at];
dengyihao's avatar
dengyihao 已提交
399 400 401
}

// trans_addr
dengyihao's avatar
dengyihao 已提交
402 403 404 405 406 407 408 409 410 411 412 413 414 415
CompiledAddr fstStateTransAddr(FstState *s, FstNode *node) {
  assert(s->state == OneTransNext || s->state == OneTrans);
  FstSlice *slice = &node->data;
  if (s->state == OneTransNext) {
    return (CompiledAddr)(node->end);      
  } else {
    PackSizes sizes = node->sizes; 
    uint8_t tSizes = FST_GET_TRANSITION_PACK_SIZE(sizes);  
    uint64_t i = node->start 
                - fstStateInputLen(s)
                - 1 // PackSizes
                - tSizes;

    // refactor error logic 
dengyihao's avatar
dengyihao 已提交
416 417
    uint8_t *data = fstSliceData(slice, NULL);
    return unpackDelta(data +i, tSizes, node->end);      
dengyihao's avatar
dengyihao 已提交
418 419 420 421 422 423 424 425 426 427 428 429 430 431
  }  
}
CompiledAddr fstStateTransAddrForAnyTrans(FstState *s, FstNode *node, uint64_t i) {
  assert(s->state == AnyTrans);

  FstSlice *slice = &node->data;
  uint8_t tSizes = FST_GET_TRANSITION_PACK_SIZE(node->sizes);
  uint64_t at = node->start  
               - fstStateNtransLen(s)
               - 1
               - fstStateTransIndexSize(s, node->version, node->nTrans)
               - node->nTrans
               - (i * tSizes)
               - tSizes;
dengyihao's avatar
dengyihao 已提交
432 433
  uint8_t *data = fstSliceData(slice, NULL);
  return unpackDelta(data + at, tSizes, node->end); 
dengyihao's avatar
dengyihao 已提交
434 435
}

dengyihao's avatar
dengyihao 已提交
436
// sizes 
dengyihao's avatar
dengyihao 已提交
437 438 439 440 441 442 443 444 445
PackSizes fstStateSizes(FstState *s, FstSlice *slice) {
  assert(s->state == OneTrans || s->state == AnyTrans) ;
  uint64_t i; 
  if (s->state == OneTrans) {
    i = FST_SLICE_LEN(slice) - 1 - fstStateInputLen(s) - 1;  
  } else {
    i = FST_SLICE_LEN(slice) - 1 - fstStateNtransLen(s) - 1;
  }

dengyihao's avatar
dengyihao 已提交
446 447
  uint8_t *data = fstSliceData(slice, NULL);
  return (PackSizes)(*(data +i));
dengyihao's avatar
dengyihao 已提交
448 449
}
// Output 
dengyihao's avatar
dengyihao 已提交
450 451 452 453 454 455 456 457 458 459 460 461 462 463 464
Output fstStateOutput(FstState *s, FstNode *node) {
  assert(s->state == OneTrans);  
  
  uint8_t oSizes = FST_GET_OUTPUT_PACK_SIZE(node->sizes);
  if (oSizes == 0) {
    return 0;
  }
  FstSlice *slice = &node->data;
  uint8_t tSizes = FST_GET_TRANSITION_PACK_SIZE(node->sizes);

  uint64_t i = node->start 
                - fstStateInputLen(s);
                - 1
                - tSizes 
                - oSizes;
dengyihao's avatar
dengyihao 已提交
465 466
  uint8_t *data = fstSliceData(slice, NULL);              
  return unpackUint64(data + i, oSizes);
dengyihao's avatar
dengyihao 已提交
467
  
dengyihao's avatar
dengyihao 已提交
468
}
dengyihao's avatar
dengyihao 已提交
469 470 471 472 473 474 475 476 477 478 479 480 481 482
Output fstStateOutputForAnyTrans(FstState *s, FstNode *node, uint64_t i) {
  assert(s->state == AnyTrans);

  uint8_t oSizes = FST_GET_OUTPUT_PACK_SIZE(node->sizes); 
  if (oSizes == 0) {
    return 0;    
  }  
  FstSlice *slice = &node->data;
  uint64_t at = node->start
                - fstStateNtransLen(s)
                - 1 // pack size
                - fstStateTotalTransSize(s, node->version, node->sizes, node->nTrans)
                - (i * oSizes)
                - oSizes;
dengyihao's avatar
dengyihao 已提交
483 484 485

  uint8_t *data = fstSliceData(slice, NULL);              
  return unpackUint64(data + at, oSizes);
dengyihao's avatar
dengyihao 已提交
486 487 488 489
}

// anyTrans specify function

dengyihao's avatar
dengyihao 已提交
490 491 492
void fstStateSetFinalState(FstState *s, bool yes) {
  assert(s->state == AnyTrans); 
  if (yes) { s->val |= 0b01000000; } 
dengyihao's avatar
dengyihao 已提交
493 494
  return;
}
dengyihao's avatar
dengyihao 已提交
495 496 497
bool fstStateIsFinalState(FstState *s) {
  assert(s->state == AnyTrans); 
  return (s->val & 0b01000000) == 0b01000000; 
dengyihao's avatar
dengyihao 已提交
498
} 
dengyihao's avatar
dengyihao 已提交
499 500 501 502 503 504

void fstStateSetStateNtrans(FstState *s, uint8_t n) {
  assert(s->state == AnyTrans); 
  if (n <= 0b00111111) {
    s->val = (s->val & 0b11000000) | n;  
  } 
dengyihao's avatar
dengyihao 已提交
505 506 507
  return;
}
// state_ntrans
dengyihao's avatar
dengyihao 已提交
508 509 510 511 512 513 514 515 516
uint8_t fstStateStateNtrans(FstState *s, bool *null) {
  assert(s->state == AnyTrans); 
  *null = false;
  uint8_t n = s->val & 0b00111111; 

  if (n == 0) {
    *null = true; // None
  }  
  return n;
dengyihao's avatar
dengyihao 已提交
517
}
dengyihao's avatar
dengyihao 已提交
518 519 520 521
uint64_t fstStateTotalTransSize(FstState *s, uint64_t version, PackSizes sizes, uint64_t nTrans) {
  assert(s->state == AnyTrans); 
  uint64_t idxSize = fstStateTransIndexSize(s, version, nTrans); 
  return nTrans + (nTrans * FST_GET_TRANSITION_PACK_SIZE(sizes)) + idxSize;
dengyihao's avatar
dengyihao 已提交
522
}
dengyihao's avatar
dengyihao 已提交
523 524 525
uint64_t fstStateTransIndexSize(FstState *s, uint64_t version, uint64_t nTrans) {
  assert(s->state == AnyTrans); 
  return (version >= 2 &&nTrans > TRANS_INDEX_THRESHOLD) ?  256 : 0;
dengyihao's avatar
dengyihao 已提交
526
}
dengyihao's avatar
dengyihao 已提交
527 528 529 530 531 532 533 534 535 536 537 538
uint64_t fstStateNtransLen(FstState *s) {
  assert(s->state == AnyTrans);
  bool null = false;
  fstStateStateNtrans(s, &null);
  return null == true ?  1 : 0; 
}
uint64_t fstStateNtrans(FstState *s, FstSlice *slice) {
  bool null = false; 
  uint8_t n = fstStateStateNtrans(s, &null);
  if (null != true) {
    return n;   
  }  
dengyihao's avatar
dengyihao 已提交
539 540 541 542
  int32_t len;
  uint8_t *data = fstSliceData(slice, &len);
  n = data[len - 2];
  //n = data[slice->end - 1]; // data[data.len() - 2]
dengyihao's avatar
dengyihao 已提交
543 544 545 546 547 548 549 550 551 552 553 554 555 556
  return n == 1 ? 256: n; // // "1" is never a normal legal value here, because if there, // is only 1 transition, then it is encoded in the state byte  
}
Output  fstStateFinalOutput(FstState *s, uint64_t version, FstSlice *slice, PackSizes sizes, uint64_t nTrans) {
   uint8_t oSizes = FST_GET_OUTPUT_PACK_SIZE(sizes);
   if (oSizes == 0 || !fstStateIsFinalState(s)) {
      return 0;
   }
   
   uint64_t at = FST_SLICE_LEN(slice) 
                 - 1 
                 - fstStateNtransLen(s)
                 - fstStateTotalTransSize(s, version, sizes, nTrans)
                 - (nTrans * oSizes)
                 - oSizes;
dengyihao's avatar
dengyihao 已提交
557 558
  uint8_t *data = fstSliceData(slice, NULL);
  return unpackUint64(data + at, (uint8_t)oSizes);    
dengyihao's avatar
dengyihao 已提交
559 560 561 562 563 564 565 566 567 568

}
uint64_t fstStateFindInput(FstState *s, FstNode *node, uint8_t b, bool *null) {
  assert(s->state == AnyTrans);
  FstSlice *slice = &node->data;
  if (node->version >= 2 && node->nTrans > TRANS_INDEX_THRESHOLD) {
    uint64_t at = node->start
                  - fstStateNtransLen(s)
                  - 1 // pack size 
                  - fstStateTransIndexSize(s, node->version, node->nTrans);
dengyihao's avatar
dengyihao 已提交
569 570 571 572
    int32_t dlen = 0; 
    uint8_t *data = fstSliceData(slice, &dlen);
    uint64_t i = data[at + b];
    //uint64_t i = slice->data[slice->start + at + b];  
dengyihao's avatar
dengyihao 已提交
573 574 575 576 577 578 579 580 581 582 583
    if (i >= node->nTrans) {
      *null = true;
    } 
    return i;
  } else {
    uint64_t start = node->start 
                    - fstStateNtransLen(s)
                    - 1 // pack size
                    - node->nTrans;
    uint64_t end =  start + node->nTrans;
    uint64_t len = end - start; 
dengyihao's avatar
dengyihao 已提交
584 585
    int32_t dlen = 0; 
    uint8_t *data = fstSliceData(slice, &dlen);
dengyihao's avatar
dengyihao 已提交
586
    for(int i = 0; i < len; i++) {
dengyihao's avatar
dengyihao 已提交
587 588 589 590
      //uint8_t v = slice->data[slice->start + i];
      ////slice->data[slice->start + i];
      uint8_t v = data[i]; 
      
dengyihao's avatar
dengyihao 已提交
591 592 593 594 595
      if (v == b) {
        return node->nTrans - i - 1; // bug  
      }
    } 
  } 
dengyihao's avatar
dengyihao 已提交
596 597 598
}


dengyihao's avatar
dengyihao 已提交
599
// fst node function 
dengyihao's avatar
dengyihao 已提交
600 601

FstNode *fstNodeCreate(int64_t version, CompiledAddr addr, FstSlice *slice) {
dengyihao's avatar
dengyihao 已提交
602 603 604
  FstNode *n = (FstNode *)malloc(sizeof(FstNode)); 
  if (n == NULL) { return NULL; }

dengyihao's avatar
dengyihao 已提交
605
  FstState st = fstStateCreateFrom(slice, addr);  
dengyihao's avatar
dengyihao 已提交
606 607

  if (st.state == EmptyFinal) {
dengyihao's avatar
dengyihao 已提交
608
     n->data    = fstSliceCreate(NULL, 0);   
dengyihao's avatar
dengyihao 已提交
609
     n->version = version;
dengyihao's avatar
dengyihao 已提交
610
     n->state   = st;  
dengyihao's avatar
dengyihao 已提交
611 612 613 614 615
     n->start   = EMPTY_ADDRESS;
     n->end     = EMPTY_ADDRESS;  
     n->isFinal = true; 
     n->nTrans  = 0;
     n->sizes   = 0;  
dengyihao's avatar
dengyihao 已提交
616
     n->finalOutput = 0;  
dengyihao's avatar
dengyihao 已提交
617
  } else if (st.state == OneTransNext) {
dengyihao's avatar
dengyihao 已提交
618 619
     n->data    = fstSliceCopy(slice, 0, addr);     
     n->version = version;
dengyihao's avatar
dengyihao 已提交
620
     n->state   = st;  
dengyihao's avatar
dengyihao 已提交
621
     n->start   = addr;
dengyihao's avatar
dengyihao 已提交
622
     n->end     = fstStateEndAddrForOneTransNext(&st, slice); //? s.end_addr(data); 
dengyihao's avatar
dengyihao 已提交
623 624
     n->isFinal = false;
     n->sizes   = 0;
dengyihao's avatar
dengyihao 已提交
625
     n->nTrans  = 1;
dengyihao's avatar
dengyihao 已提交
626
     n->finalOutput = 0;
dengyihao's avatar
dengyihao 已提交
627
  } else if (st.state == OneTrans) {
dengyihao's avatar
dengyihao 已提交
628 629 630
     FstSlice data = fstSliceCopy(slice, 0, addr); 
     PackSizes sz = fstStateSizes(&st, &data);
     n->data    =   fstSliceCopy(slice, 0, addr); 
dengyihao's avatar
dengyihao 已提交
631
     n->version = version; 
dengyihao's avatar
dengyihao 已提交
632
     n->state   = st; 
dengyihao's avatar
dengyihao 已提交
633
     n->start   = addr;
dengyihao's avatar
dengyihao 已提交
634
     n->end     = fstStateEndAddrForOneTrans(&st, slice, sz); // s.end_addr(data, sz);
dengyihao's avatar
dengyihao 已提交
635 636 637 638
     n->isFinal = false; 
     n->nTrans  = 1; 
     n->sizes   = sz;   
     n->finalOutput = 0; 
dengyihao's avatar
dengyihao 已提交
639
  } else {
dengyihao's avatar
dengyihao 已提交
640 641
     uint64_t sz = fstStateSizes(&st, slice);    // s.sizes(data)
     uint32_t nTrans = fstStateNtrans(&st, slice); // s.ntrans(data)  
dengyihao's avatar
dengyihao 已提交
642 643
     n->data    = *slice; 
     n->version = version;
dengyihao's avatar
dengyihao 已提交
644
     n->state   = st;
dengyihao's avatar
dengyihao 已提交
645
     n->start   = addr;
dengyihao's avatar
dengyihao 已提交
646 647
     n->end     = fstStateEndAddrForAnyTrans(&st, version, slice, sz, nTrans); // s.end_addr(version, data, sz, ntrans);
     n->isFinal = fstStateIsFinalState(&st); // s.is_final_state();
dengyihao's avatar
dengyihao 已提交
648 649
     n->nTrans  = nTrans;
     n->sizes   = sz;
dengyihao's avatar
dengyihao 已提交
650
     n->finalOutput = fstStateFinalOutput(&st, version, slice, sz, nTrans); // s.final_output(version, data, sz, ntrans);
dengyihao's avatar
dengyihao 已提交
651
  }
dengyihao's avatar
dengyihao 已提交
652 653
   return n; 
}
dengyihao's avatar
dengyihao 已提交
654 655 656 657 658 659 660 661

// debug state transition
static const char *fstNodeState(FstNode *node) {
  FstState *st = &node->state; 
  return fstStateStr[st->state]; 
}


dengyihao's avatar
dengyihao 已提交
662
void fstNodeDestroy(FstNode *node) {
dengyihao's avatar
dengyihao 已提交
663
  fstSliceDestroy(&node->data); 
dengyihao's avatar
dengyihao 已提交
664 665
  free(node);
}
dengyihao's avatar
dengyihao 已提交
666 667 668 669 670 671 672
FstTransitions* fstNodeTransitions(FstNode *node) {
  FstTransitions *t = malloc(sizeof(FstTransitions));
  if (NULL == t) {
    return NULL; 
  }
  FstRange range = {.start = 0, .end = FST_NODE_LEN(node)};
  t->range = range;
dengyihao's avatar
dengyihao 已提交
673
  t->node  = node;
dengyihao's avatar
dengyihao 已提交
674 675
  return t; 
} 
dengyihao's avatar
dengyihao 已提交
676

dengyihao's avatar
dengyihao 已提交
677 678 679
// Returns the transition at index `i`. 
bool fstNodeGetTransitionAt(FstNode *node, uint64_t i, FstTransition *trn) {
  bool s = true;
dengyihao's avatar
dengyihao 已提交
680 681 682
  FstState *st = &node->state;
  if (st->state == OneTransNext) {
    trn->inp  = fstStateInput(st, node); 
dengyihao's avatar
dengyihao 已提交
683
    trn->out  = 0;
dengyihao's avatar
dengyihao 已提交
684 685 686 687 688 689 690 691 692
    trn->addr = fstStateTransAddr(st, node); 
  } else if (st->state == OneTrans) {
    trn->inp  = fstStateInput(st, node);    
    trn->out  = fstStateOutput(st, node);
    trn->addr = fstStateTransAddr(st, node); 
  } else if (st->state == AnyTrans) {
    trn->inp  = fstStateInputForAnyTrans(st, node, i);
    trn->out  = fstStateOutputForAnyTrans(st, node, i);
    trn->addr = fstStateTransAddrForAnyTrans(st, node, i); 
dengyihao's avatar
dengyihao 已提交
693 694 695 696 697 698
  } else {
    s = false;
  }
  return s;
} 

dengyihao's avatar
dengyihao 已提交
699
// Returns the transition address of the `i`th transition
dengyihao's avatar
dengyihao 已提交
700 701
bool fstNodeGetTransitionAddrAt(FstNode *node, uint64_t i, CompiledAddr *res) {
  bool s = true;
dengyihao's avatar
dengyihao 已提交
702 703 704 705 706 707 708 709 710
  FstState *st = &node->state;
  if (st->state == OneTransNext) {
    assert(i == 0);
    fstStateTransAddr(st, node);
  } else if (st->state == OneTrans) {
    assert(i == 0); 
    fstStateTransAddr(st, node);
  } else if (st->state == AnyTrans) {
    fstStateTransAddrForAnyTrans(st, node, i);
dengyihao's avatar
dengyihao 已提交
711
  } else if (FST_STATE_EMPTY_FINAL(node)){
dengyihao's avatar
dengyihao 已提交
712
    s = false;
dengyihao's avatar
dengyihao 已提交
713 714
  } else {
    assert(0);
dengyihao's avatar
dengyihao 已提交
715 716
  }
  return s;
dengyihao's avatar
dengyihao 已提交
717 718
}

dengyihao's avatar
dengyihao 已提交
719 720
//  Finds the `i`th transition corresponding to the given input byte.
//  If no transition for this byte exists, then `false` is returned. 
dengyihao's avatar
dengyihao 已提交
721 722
bool fstNodeFindInput(FstNode *node, uint8_t b, uint64_t *res) {
  bool s = true;
dengyihao's avatar
dengyihao 已提交
723 724 725 726 727 728 729 730 731 732 733 734 735
  FstState *st = &node->state;
  if (st->state == OneTransNext) {
    if (fstStateInput(st,node) == b) { *res = 0; } 
    else { s = false; } } 
  else if (st->state == OneTrans) {
    if (fstStateInput(st, node) == b) { *res = 0 ;}
    else {  s = false; }
  } else if (st->state == AnyTrans) {
    bool null = false;
    uint64_t out = fstStateFindInput(st, node, b, &null); 
    if (null == false) { *res = out; } 
    else { s = false;}
  }
dengyihao's avatar
dengyihao 已提交
736 737 738 739 740 741 742 743 744
  return s;
} 

bool fstNodeCompile(FstNode *node, void *w, CompiledAddr lastAddr, CompiledAddr addr, FstBuilderNode *builderNode) {
  size_t sz = taosArrayGetSize(builderNode->trans);  
  assert(sz < 256);
  if (sz == 0 && builderNode->isFinal && builderNode->finalOutput == 0) {
    return true; 
  } else if (sz != 1 || builderNode->isFinal) {
dengyihao's avatar
dengyihao 已提交
745
     fstStateCompileForAnyTrans(w, addr, builderNode); 
dengyihao's avatar
dengyihao 已提交
746 747 748 749
    // AnyTrans->Compile(w, addr, node);
  } else {
    FstTransition *tran = taosArrayGet(builderNode->trans, 0);   
    if (tran->addr == lastAddr && tran->out == 0) {
dengyihao's avatar
dengyihao 已提交
750
       fstStateCompileForOneTransNext(w, addr, tran->inp);
dengyihao's avatar
dengyihao 已提交
751 752 753
       //OneTransNext::compile(w, lastAddr, tran->inp);
       return true;
    } else {
dengyihao's avatar
dengyihao 已提交
754
       fstStateCompileForOneTrans(w, addr, tran);
dengyihao's avatar
dengyihao 已提交
755 756 757 758 759 760 761
      //OneTrans::Compile(w, lastAddr, *tran);
       return true;
    } 
  } 
  return true; 
} 

dengyihao's avatar
dengyihao 已提交
762 763 764 765 766
bool fstBuilderNodeCompileTo(FstBuilderNode *b, FstCountingWriter *wrt, CompiledAddr lastAddr, CompiledAddr startAddr) {
  return fstNodeCompile(NULL, wrt, lastAddr, startAddr, b);
}


dengyihao's avatar
dengyihao 已提交
767 768 769 770 771

FstBuilder *fstBuilderCreate(void *w, FstType ty) {
  FstBuilder *b = malloc(sizeof(FstBuilder));  
  if (NULL == b) { return b; }

dengyihao's avatar
dengyihao 已提交
772 773 774 775
   
  b->wrt = fstCountingWriterCreate(w);
  b->unfinished = fstUnFinishedNodesCreate();   
  b->registry   = fstRegistryCreate(10000, 2) ;
dengyihao's avatar
dengyihao 已提交
776
  b->last       = fstSliceCreate(NULL, 0);
dengyihao's avatar
dengyihao 已提交
777 778
  b->lastAddr   = NONE_ADDRESS; 
  b->len        = 0;
dengyihao's avatar
dengyihao 已提交
779 780
  return b;
}
dengyihao's avatar
dengyihao 已提交
781 782
void fstBuilderDestroy(FstBuilder *b) {
  if (b == NULL) { return; }
dengyihao's avatar
dengyihao 已提交
783

dengyihao's avatar
dengyihao 已提交
784 785 786 787 788
  fstCountingWriterDestroy(b->wrt); 
  fstUnFinishedNodesDestroy(b->unfinished); 
  fstRegistryDestroy(b->registry);
  free(b);
}
dengyihao's avatar
dengyihao 已提交
789 790 791 792 793 794 795 796 797 798 799 800


bool fstBuilderInsert(FstBuilder *b, FstSlice bs, Output in) {
  OrderType t = fstBuilderCheckLastKey(b, bs, true);  
  if (t == Ordered) {
    // add log info
    fstBuilderInsertOutput(b, bs, in); 
    return true; 
  } 
  return false;
}

dengyihao's avatar
dengyihao 已提交
801 802
void fstBuilderInsertOutput(FstBuilder *b, FstSlice bs, Output in) {
   FstSlice *s = &bs;
dengyihao's avatar
dengyihao 已提交
803
   if (fstSliceIsEmpty(s)) {
dengyihao's avatar
dengyihao 已提交
804 805 806 807
     b->len = 1; 
     fstUnFinishedNodesSetRootOutput(b->unfinished, in);
     return;
   }
dengyihao's avatar
dengyihao 已提交
808 809 810 811 812 813
   //if (in != 0) { //if let Some(in) = in 
   //   prefixLen = fstUnFinishedNodesFindCommPrefixAndSetOutput(b->unfinished, bs, in, &out);  
   //} else {
   //   prefixLen = fstUnFinishedNodesFindCommPrefix(b->unfinished, bs);
   //   out = 0;
   //}
dengyihao's avatar
dengyihao 已提交
814
   Output out; 
dengyihao's avatar
dengyihao 已提交
815 816
   uint64_t prefixLen = fstUnFinishedNodesFindCommPrefixAndSetOutput(b->unfinished, bs, in, &out);
  
dengyihao's avatar
dengyihao 已提交
817
   if (prefixLen == FST_SLICE_LEN(s)) {
dengyihao's avatar
dengyihao 已提交
818
      assert(out == 0);
dengyihao's avatar
dengyihao 已提交
819 820 821 822 823 824 825 826
      return;
   }

   b->len += 1;
   fstBuilderCompileFrom(b, prefixLen); 
   
   FstSlice sub = fstSliceCopy(s, prefixLen, s->end);
   fstUnFinishedNodesAddSuffix(b->unfinished, sub, out);
dengyihao's avatar
dengyihao 已提交
827
   fstSliceDestroy(&sub);
dengyihao's avatar
dengyihao 已提交
828 829
   return;
 }
dengyihao's avatar
dengyihao 已提交
830

dengyihao's avatar
dengyihao 已提交
831 832
OrderType fstBuilderCheckLastKey(FstBuilder *b, FstSlice bs, bool ckDup) {
  FstSlice *input = &bs;
dengyihao's avatar
dengyihao 已提交
833
  if (fstSliceIsEmpty(&b->last)) {
dengyihao's avatar
dengyihao 已提交
834 835 836 837 838 839 840 841 842 843 844 845 846
    // deep copy or not
    b->last = fstSliceCopy(&bs, input->start, input->end);
  } else {
    int comp = fstSliceCompare(&b->last, &bs);
    if (comp == 0 && ckDup) {
      return DuplicateKey;  
    } else if (comp == 1) {
      return OutOfOrdered;
    }
    // deep copy or not
    b->last = fstSliceCopy(&bs, input->start, input->end); 
  }       
  return Ordered;
dengyihao's avatar
dengyihao 已提交
847
} 
dengyihao's avatar
dengyihao 已提交
848 849 850 851 852 853 854 855 856
void fstBuilderCompileFrom(FstBuilder *b, uint64_t istate) {
  CompiledAddr addr = NONE_ADDRESS;
  while (istate + 1 < FST_UNFINISHED_NODES_LEN(b->unfinished)) {
    FstBuilderNode *n = NULL;
    if (addr == NONE_ADDRESS) {
      n = fstUnFinishedNodesPopEmpty(b->unfinished);
    } else {
      n = fstUnFinishedNodesPopFreeze(b->unfinished, addr);
    }
dengyihao's avatar
dengyihao 已提交
857
    addr = fstBuilderCompile(b, n);
dengyihao's avatar
dengyihao 已提交
858
    assert(addr != NONE_ADDRESS);      
dengyihao's avatar
dengyihao 已提交
859
    //fstBuilderNodeDestroy(n);
dengyihao's avatar
dengyihao 已提交
860 861 862 863
  }
  fstUnFinishedNodesTopLastFreeze(b->unfinished, addr);
  return; 
}
dengyihao's avatar
dengyihao 已提交
864 865 866 867 868 869 870 871 872
CompiledAddr fstBuilderCompile(FstBuilder *b, FstBuilderNode *bn) {
  if (FST_BUILDER_NODE_IS_FINAL(bn) 
      && FST_BUILDER_NODE_TRANS_ISEMPTY(bn) 
      && FST_BUILDER_NODE_FINALOUTPUT_ISZERO(bn)) {
    return EMPTY_ADDRESS; 
  }
  FstRegistryEntry *entry = fstRegistryGetEntry(b->registry, bn); 
  if (entry->state == FOUND) { 
    CompiledAddr ret = entry->addr;
dengyihao's avatar
dengyihao 已提交
873
    fstRegistryEntryDestroy(entry);
dengyihao's avatar
dengyihao 已提交
874 875 876 877 878
    return ret;
  } 
  CompiledAddr startAddr = (CompiledAddr)(FST_WRITER_COUNT(b->wrt));

  fstBuilderNodeCompileTo(bn, b->wrt, b->lastAddr, startAddr);  
dengyihao's avatar
dengyihao 已提交
879
  b->lastAddr =  (CompiledAddr)(FST_WRITER_COUNT(b->wrt) - 1);  
dengyihao's avatar
dengyihao 已提交
880 881 882
  if (entry->state == NOTFOUND) {
    FST_REGISTRY_CELL_INSERT(entry->cell, b->lastAddr);    
  }
dengyihao's avatar
dengyihao 已提交
883 884
  fstRegistryEntryDestroy(entry);
  
dengyihao's avatar
dengyihao 已提交
885 886 887
  return b->lastAddr;  
}

dengyihao's avatar
dengyihao 已提交
888 889 890 891 892
void* fstBuilderInsertInner(FstBuilder *b) {
  fstBuilderCompileFrom(b, 0);  
  FstBuilderNode *rootNode = fstUnFinishedNodesPopRoot(b->unfinished); 
  CompiledAddr  rootAddr = fstBuilderCompile(b, rootNode);

dengyihao's avatar
dengyihao 已提交
893
  char  buf64[8] = {0}; 
dengyihao's avatar
dengyihao 已提交
894

dengyihao's avatar
dengyihao 已提交
895 896
  void  *pBuf64 = buf64; 
  taosEncodeFixedU64(&pBuf64, b->len); 
dengyihao's avatar
dengyihao 已提交
897 898
  fstCountingWriterWrite(b->wrt, buf64, sizeof(buf64));  
    
dengyihao's avatar
dengyihao 已提交
899 900
  pBuf64 = buf64;
  taosEncodeFixedU64(&pBuf64, rootAddr);  
dengyihao's avatar
dengyihao 已提交
901 902
  fstCountingWriterWrite(b->wrt, buf64, sizeof(buf64));  

dengyihao's avatar
dengyihao 已提交
903 904
  char buf32[4] = {0};
  void *pBuf32  = buf32; 
dengyihao's avatar
dengyihao 已提交
905
  uint32_t sum = fstCountingWriterMaskedCheckSum(b->wrt);
dengyihao's avatar
dengyihao 已提交
906
  taosEncodeFixedU32(&pBuf32, sum); 
dengyihao's avatar
dengyihao 已提交
907 908 909
  fstCountingWriterWrite(b->wrt, buf32, sizeof(buf32));  
  
  fstCountingWriterFlush(b->wrt);
dengyihao's avatar
dengyihao 已提交
910 911
  //fstCountingWriterDestroy(b->wrt);  
  //b->wrt = NULL;
dengyihao's avatar
dengyihao 已提交
912 913 914 915 916
  return b->wrt;
}
void fstBuilderFinish(FstBuilder *b) {
  fstBuilderInsertInner(b);
}
dengyihao's avatar
dengyihao 已提交
917

dengyihao's avatar
dengyihao 已提交
918 919


dengyihao's avatar
dengyihao 已提交
920 921
FstSlice fstNodeAsSlice(FstNode *node) {
  FstSlice *slice = &node->data; 
dengyihao's avatar
dengyihao 已提交
922
  FstSlice s = fstSliceCopy(slice, slice->end, FST_SLICE_LEN(slice) - 1);   
dengyihao's avatar
dengyihao 已提交
923 924
  return s; 
}
dengyihao's avatar
dengyihao 已提交
925

dengyihao's avatar
dengyihao 已提交
926 927 928 929 930 931 932 933 934 935 936 937
FstLastTransition *fstLastTransitionCreate(uint8_t inp, Output out) {
  FstLastTransition *trn = malloc(sizeof(FstLastTransition));
  if (trn == NULL) { return NULL; }

  trn->inp = inp;
  trn->out = out;
  return trn;
}

void fstLastTransitionDestroy(FstLastTransition *trn) {
  free(trn);
}
dengyihao's avatar
dengyihao 已提交
938 939
void fstBuilderNodeUnfinishedLastCompiled(FstBuilderNodeUnfinished *unNode, CompiledAddr addr) {
  FstLastTransition *trn = unNode->last;       
dengyihao's avatar
dengyihao 已提交
940
  if (trn == NULL) { return; }  
dengyihao's avatar
dengyihao 已提交
941 942
  FstTransition t = {.inp = trn->inp, .out = trn->out, .addr = addr};      
  taosArrayPush(unNode->node->trans, &t); 
dengyihao's avatar
dengyihao 已提交
943 944
  fstLastTransitionDestroy(trn); 
  unNode->last = NULL;
dengyihao's avatar
dengyihao 已提交
945 946 947
  return;
}

dengyihao's avatar
dengyihao 已提交
948 949 950 951 952 953 954 955 956 957 958 959
void fstBuilderNodeUnfinishedAddOutputPrefix(FstBuilderNodeUnfinished *unNode, Output out) {
  if (FST_BUILDER_NODE_IS_FINAL(unNode->node)) {
    unNode->node->finalOutput += out;  
  }
  size_t sz = taosArrayGetSize(unNode->node->trans);
  for (size_t i = 0; i < sz; i++) {
    FstTransition *trn = taosArrayGet(unNode->node->trans, i); 
    trn->out += out;
  }
  if (unNode->last) {
    unNode->last->out += out;  
  }
dengyihao's avatar
dengyihao 已提交
960 961 962
  return;
}

dengyihao's avatar
dengyihao 已提交
963
Fst* fstCreate(FstSlice *slice) {
dengyihao's avatar
dengyihao 已提交
964 965 966
  int32_t slen;
  char *buf = fstSliceData(slice, &slen);
  if (slen < 36) { 
dengyihao's avatar
dengyihao 已提交
967 968
    return NULL; 
  }
dengyihao's avatar
dengyihao 已提交
969 970
  uint64_t len = slen;
  uint64_t skip = 0;  
dengyihao's avatar
dengyihao 已提交
971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008

  uint64_t version; 
  taosDecodeFixedU64(buf, &version); 
  skip += sizeof(version); 
  if (version == 0 || version > VERSION) {
    return NULL; 
  }  

  uint64_t type;
  taosDecodeFixedU64(buf + skip, &type);
  skip += sizeof(type); 

  uint32_t checkSum = 0;
  len -= sizeof(checkSum);
  taosDecodeFixedU32(buf + len, &checkSum); 

  CompiledAddr rootAddr;
  len -= sizeof(rootAddr); 
  taosDecodeFixedU64(buf + len, &rootAddr); 

  uint64_t fstLen; 
  len -= sizeof(fstLen); 
  taosDecodeFixedU64(buf + len, &fstLen);
  //TODO(validat root addr)
  // 
  Fst *fst= (Fst *)calloc(1, sizeof(Fst)); 
  if (fst == NULL) { return NULL; }  
  
  fst->meta = (FstMeta *)malloc(sizeof(FstMeta));
  if (NULL == fst->meta) { 
    goto FST_CREAT_FAILED; 
  }

  fst->meta->version   = version;  
  fst->meta->rootAddr = rootAddr; 
  fst->meta->ty       = type;
  fst->meta->len      = fstLen;
  fst->meta->checkSum = checkSum;
dengyihao's avatar
dengyihao 已提交
1009
  fst->data = slice; 
dengyihao's avatar
dengyihao 已提交
1010 1011 1012 1013 1014 1015 1016 1017
  return fst;

FST_CREAT_FAILED: 
  free(fst->meta); 
  free(fst);

}
void fstDestroy(Fst *fst) {
dengyihao's avatar
dengyihao 已提交
1018 1019 1020 1021 1022 1023 1024 1025
  if (fst) { 
    free(fst->meta); 
    fstNodeDestroy(fst->root);  
  } 
  free(fst); 
}

bool fstGet(Fst *fst, FstSlice *b, Output *out) {
dengyihao's avatar
dengyihao 已提交
1026 1027
  FstNode *root = fstGetRoot(fst);    
  Output tOut = 0; 
dengyihao's avatar
dengyihao 已提交
1028 1029 1030 1031
  int32_t len;
  uint8_t *data = fstSliceData(b, &len);
  for (uint32_t i = 0; i < len; i++) {
    uint8_t inp = data[i];
dengyihao's avatar
dengyihao 已提交
1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047
    Output  res = 0;
    bool null = fstNodeFindInput(root, inp, &res);    
    if (null) { return false; }    

    FstTransition trn; 
    fstNodeGetTransitionAt(root, res, &trn);
    tOut += trn.out; 
    root = fstGetNode(fst, trn.addr);
  }
  if (!FST_NODE_IS_FINAL(root)) {
    return false;
  } else {
    tOut = tOut + FST_NODE_FINAL_OUTPUT(root); 
  }
  *out = tOut;
  
dengyihao's avatar
dengyihao 已提交
1048 1049
  return false; 
}
dengyihao's avatar
dengyihao 已提交
1050

dengyihao's avatar
dengyihao 已提交
1051
FstNode *fstGetRoot(Fst *fst) {
dengyihao's avatar
dengyihao 已提交
1052 1053 1054
  if (fst->root != NULL) {
    return fst->root;
  }
dengyihao's avatar
dengyihao 已提交
1055 1056
  CompiledAddr rAddr = fstGetRootAddr(fst); 
  fst->root =  fstGetNode(fst, rAddr);
dengyihao's avatar
dengyihao 已提交
1057
  return fst->root;
dengyihao's avatar
dengyihao 已提交
1058 1059 1060
}
FstNode* fstGetNode(Fst *fst, CompiledAddr addr) {
  return fstNodeCreate(fst->meta->version, addr, fst->data); 
dengyihao's avatar
dengyihao 已提交
1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083
  
}
FstType fstGetType(Fst *fst) {
  return fst->meta->ty;
}
CompiledAddr fstGetRootAddr(Fst *fst) {
  return fst->meta->rootAddr;
} 

Output fstEmptyFinalOutput(Fst *fst, bool *null) {
  Output res = 0;
  FstNode *node = fst->root;
  if (FST_NODE_IS_FINAL(node)) {
    *null = false;
    res = FST_NODE_FINAL_OUTPUT(node); 
  } else {
    *null = true;
  }
  return res;
}

bool fstVerify(Fst *fst) {
  uint32_t checkSum = fst->meta->checkSum;
dengyihao's avatar
dengyihao 已提交
1084 1085
  int32_t len;
  uint8_t *data = fstSliceData(fst->data, &len);
dengyihao's avatar
dengyihao 已提交
1086
  TSCKSUM initSum  = 0;  
dengyihao's avatar
dengyihao 已提交
1087
  if (!taosCheckChecksumWhole(data, len)) {
dengyihao's avatar
dengyihao 已提交
1088 1089
    return false;
  }
dengyihao's avatar
dengyihao 已提交
1090
  return true;
dengyihao's avatar
dengyihao 已提交
1091 1092
}

dengyihao's avatar
dengyihao 已提交
1093 1094 1095 1096
// data bound function
FstBoundWithData* fstBoundStateCreate(FstBound type, FstSlice *data) {
  FstBoundWithData *b = calloc(1, sizeof(FstBoundWithData));
  if (b == NULL) { return NULL; }
dengyihao's avatar
dengyihao 已提交
1097 1098 1099 1100 1101 1102

  if (data != NULL) {
    b->data = fstSliceCopy(data, data->start, data->end);
  } else {
    b->data = fstSliceCreate(NULL, 0);
  }
dengyihao's avatar
dengyihao 已提交
1103
  b->type = type;
dengyihao's avatar
dengyihao 已提交
1104

dengyihao's avatar
dengyihao 已提交
1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121
  return b; 
}

bool fstBoundWithDataExceededBy(FstBoundWithData *bound, FstSlice *slice) {
  int comp = fstSliceCompare(slice, &bound->data);
  if (bound->type == Included) {
    return comp > 0 ? true : false;
  } else if (bound->type == Excluded) {
    return comp >= 0 ? true : false;
  } else {
    return true;
  }
}
bool fstBoundWithDataIsEmpty(FstBoundWithData *bound) {
  if (bound->type == Unbounded) {
    return true;
  } else { 
dengyihao's avatar
dengyihao 已提交
1122
    return fstSliceIsEmpty(&bound->data);  
dengyihao's avatar
dengyihao 已提交
1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155
  }     
}


bool fstBoundWithDataIsIncluded(FstBoundWithData *bound) {
  return bound->type == Included ? true : false;
}

void fstBoundDestroy(FstBoundWithData *bound) {
  free(bound);
}

StreamWithState *streamWithStateCreate(Fst *fst, Automation *automation, FstBoundWithData *min, FstBoundWithData *max) {
  StreamWithState *sws = calloc(1, sizeof(StreamWithState));
  if (sws == NULL) { return NULL; } 

  sws->fst  = fst;
  sws->aut  = automation; 
  sws->inp  = (SArray *)taosArrayInit(256, sizeof(uint8_t));  
  
  sws->emptyOutput.null = false;
  sws->emptyOutput.out  = 0;

  sws->stack = (SArray *)taosArrayInit(256, sizeof(StreamState)); 
  sws->endAt = max; 
  streamWithStateSeekMin(sws, min);

  return sws;
}
void streamWithStateDestroy(StreamWithState *sws) {
  if (sws == NULL) { return; }

  taosArrayDestroy(sws->inp);
dengyihao's avatar
dengyihao 已提交
1156
  taosArrayDestroyEx(sws->stack, streamStateDestroy);
dengyihao's avatar
dengyihao 已提交
1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188

  free(sws); 
}

bool streamWithStateSeekMin(StreamWithState *sws, FstBoundWithData *min) {
  if (fstBoundWithDataIsEmpty(min)) {
    if (fstBoundWithDataIsIncluded(min)) {
       sws->emptyOutput.out = fstEmptyFinalOutput(sws->fst, &(sws->emptyOutput.null));
    } 
    StreamState s = {.node     = fstGetRoot(sws->fst),
                     .trans    = 0,
                     .out      = {.null = false, .out = 0},
                     .autState = sws->aut->start()}; // auto.start callback 
    taosArrayPush(sws->stack, &s);
    return true;
  } 
  FstSlice *key = NULL;
  bool inclusize = false;;

  if (min->type == Included) {
    key = &min->data;
    inclusize = true;
  } else if (min->type == Excluded) {
    key = &min->data;
  } else {
    return false;
  }

  FstNode *node = fstGetRoot(sws->fst); 
  Output  out = 0;
  void*   autState = sws->aut->start();  

dengyihao's avatar
dengyihao 已提交
1189 1190 1191 1192
  int32_t len; 
  uint8_t *data = fstSliceData(key, &len);  
  for (uint32_t i = 0; i < len; i++) {
    uint8_t b = data[i];
dengyihao's avatar
dengyihao 已提交
1193 1194 1195 1196 1197 1198
    uint64_t res = 0;
    bool null = fstNodeFindInput(node, b, &res); 
    if (null == false) {
      FstTransition trn;
      fstNodeGetTransitionAt(node, res, &trn);   
      void *preState = autState;
dengyihao's avatar
dengyihao 已提交
1199
      autState = sws->aut->accept(preState, b);
dengyihao's avatar
dengyihao 已提交
1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253
      taosArrayPush(sws->inp, &b);
      StreamState s = {.node     = node, 
                       .trans    = res + 1, 
                       .out      = {.null = false, .out = out}, 
                       .autState = preState}; 
      taosArrayPush(sws->stack, &s);
      out += trn.out;
      node = fstGetNode(sws->fst, trn.addr);  
    } else {

      // This is a little tricky. We're in this case if the
      // given bound is not a prefix of any key in the FST.
      // Since this is a minimum bound, we need to find the
      // first transition in this node that proceeds the current
      // input byte. 
      FstTransitions *trans = fstNodeTransitions(node);
      uint64_t i = 0; 
      for (i = trans->range.start; i < trans->range.end; i++) {
        FstTransition trn;
        if (fstNodeGetTransitionAt(node, i, &trn) && trn.inp > b) {
          break;   
        }  
      }
      
      StreamState s = {.node     = node, 
                       .trans    = i, 
                       .out      = {.null = false, .out = out}, 
                       .autState = autState}; 
      taosArrayPush(sws->stack, &s);  
       return true;  
    }
  }
  uint32_t sz = taosArrayGetSize(sws->stack); 
  if (sz != 0) {
    StreamState *s = taosArrayGet(sws->stack, sz - 1); 
    if (inclusize) {
      s->trans -= 1;
      taosArrayPop(sws->inp);
    } else {
      FstNode *n = s->node;  
      uint64_t trans = s->trans; 
      FstTransition trn;  
      fstNodeGetTransitionAt(n, trans - 1, &trn);
      StreamState s = {.node = fstGetNode(sws->fst, trn.addr),
                       .trans= 0,
                       .out  = {.null = false, .out = out},
                       .autState = autState}; 
      taosArrayPush(sws->stack, &s);
      return true; 
   }
   return false;
  } 
}          

dengyihao's avatar
dengyihao 已提交
1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307
StreamWithStateResult *streamWithStateNextWith(StreamWithState *sws, StreamCallback callback) {
  FstOutput output = sws->emptyOutput; 
  if (output.null == false) {
    FstSlice emptySlice = fstSliceCreate(NULL, 0);   
    if (fstBoundWithDataExceededBy(sws->endAt, &emptySlice)) {
      taosArrayDestroyEx(sws->stack, streamStateDestroy);
      sws->stack = (SArray *)taosArrayInit(256, sizeof(StreamState)); 
      return NULL;
    }
    void* start = sws->aut->start();
    if (sws->aut->isMatch(start)) { 
      FstSlice s = fstSliceCreate(NULL, 0);
      return swsResultCreate(&s, output, callback(start));
    }
  }
  while (taosArrayGetSize(sws->stack) > 0) {
    StreamState *p = (StreamState *)taosArrayPop(sws->stack);     
    if (p->trans >= FST_NODE_LEN(p->node) || !sws->aut->canMatch(p->autState)) {
      if (FST_NODE_ADDR(p->node) != fstGetRootAddr(sws->fst)) {
        taosArrayPop(sws->inp);
      }
      streamStateDestroy(p);    
      continue;
    }
    FstTransition trn; 
    fstNodeGetTransitionAt(p->node, p->trans, &trn);
    Output out = p->out.out + trn.out;
    void* nextState = sws->aut->accept(p->autState, trn.inp);
    void* tState = callback(nextState);
    bool isMatch = sws->aut->isMatch(nextState);
    FstNode *nextNode = fstGetNode(sws->fst, trn.addr); 
    taosArrayPush(sws->inp, &(trn.inp)); 

    if (FST_NODE_IS_FINAL(nextNode)) {
      void *eofState = sws->aut->acceptEof(nextState); 
      if (eofState != NULL) {
        isMatch = sws->aut->isMatch(eofState); 
      }
    } 
    StreamState s1 = { .node = p->node, .trans = p->trans + 1, .out = p->out, .autState = p->autState};  
    taosArrayPush(sws->stack, &s1);

    StreamState s2 = {.node = nextNode, .trans = 0, .out = {.null = false, .out = out}, .autState = nextState};
    taosArrayPush(sws->stack, &s2);
    
    uint8_t *buf = (uint8_t *)malloc(taosArrayGetSize(sws->inp) * sizeof(uint8_t)); 
    for (uint32_t i = 0; i < taosArrayGetSize(sws->inp); i++) {
      uint8_t *t = (uint8_t *)taosArrayGet(sws->inp, i);
      buf[i] = *t; 
    }
    FstSlice slice = fstSliceCreate(buf, taosArrayGetSize(sws->inp));
    if (fstBoundWithDataExceededBy(sws->endAt, &slice)) {
      taosArrayDestroyEx(sws->stack, streamStateDestroy);
      sws->stack = (SArray *)taosArrayInit(256, sizeof(StreamState)); 
dengyihao's avatar
dengyihao 已提交
1308
      fstSliceDestroy(&slice);
dengyihao's avatar
dengyihao 已提交
1309 1310 1311
      return NULL;
    }
    if (FST_NODE_IS_FINAL(nextNode) && isMatch) {
dengyihao's avatar
dengyihao 已提交
1312
      FstOutput fOutput = {.null = false, .out = out + FST_NODE_FINAL_OUTPUT(nextNode)};
dengyihao's avatar
dengyihao 已提交
1313 1314 1315
      StreamWithStateResult *result =  swsResultCreate(&slice, fOutput , tState);     
      fstSliceDestroy(&slice);
      return result; 
dengyihao's avatar
dengyihao 已提交
1316
    }
dengyihao's avatar
dengyihao 已提交
1317
    fstSliceDestroy(&slice);
dengyihao's avatar
dengyihao 已提交
1318 1319 1320 1321 1322 1323 1324 1325 1326
  }
  return NULL; 
  
}

StreamWithStateResult *swsResultCreate(FstSlice *data, FstOutput fOut, void *state) {
  StreamWithStateResult *result = calloc(1, sizeof(StreamWithStateResult));  
  if (result == NULL) { return NULL; }
  
dengyihao's avatar
dengyihao 已提交
1327
  result->data   = fstSliceCopy(data, 0, FST_SLICE_LEN(data) - 1);
dengyihao's avatar
dengyihao 已提交
1328 1329 1330 1331 1332
  result->out   = fOut;
  result->state = state; 

  return result;
}
dengyihao's avatar
dengyihao 已提交
1333 1334 1335 1336 1337 1338 1339
void swsResultDestroy(StreamWithStateResult *result) {
  if (NULL == result) { return; }
  
  fstSliceDestroy(&result->data);
  free(result);
}

dengyihao's avatar
dengyihao 已提交
1340 1341 1342 1343 1344 1345 1346 1347
void streamStateDestroy(void *s) {
  if (NULL == s) { return; }
  StreamState *ss = (StreamState *)s;

  fstNodeDestroy(ss->node);
  //free(s->autoState);
}

dengyihao's avatar
dengyihao 已提交
1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358
FstStreamBuilder *fstStreamBuilderCreate(Fst *fst, Automation *aut) {
  FstStreamBuilder *b = calloc(1, sizeof(FstStreamBuilder));
  if (NULL == b) { return NULL; }

  b->fst = fst;
  b->aut = aut;
  b->min = fstBoundStateCreate(Unbounded, NULL);
  b->max = fstBoundStateCreate(Unbounded, NULL);  
  return b;
}
void fstStreamBuilderDestroy(FstStreamBuilder *b) {
dengyihao's avatar
dengyihao 已提交
1359 1360
  fstSliceDestroy(&b->min->data);
  fstSliceDestroy(&b->max->data);
dengyihao's avatar
dengyihao 已提交
1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386
  free(b);
}
FstStreamBuilder *fstStreamBuilderRange(FstStreamBuilder *b, FstSlice *val, RangeType type) {
  if (b == NULL) { return NULL; }

  if (type == GE) {
    b->min->type = Included;
    fstSliceDestroy(&(b->min->data));
    b->min->data = fstSliceDeepCopy(val, 0, FST_SLICE_LEN(val) - 1);
  } else if (type == GT) {
    b->min->type = Excluded;
    fstSliceDestroy(&(b->min->data));
    b->min->data = fstSliceDeepCopy(val, 0, FST_SLICE_LEN(val) - 1);
  } else if (type == LE) {
    b->max->type = Included;
    fstSliceDestroy(&(b->max->data));
    b->max->data = fstSliceDeepCopy(val, 0, FST_SLICE_LEN(val) - 1);
  } else if (type == LT) {
    b->max->type = Excluded;
    fstSliceDestroy(&(b->max->data));
    b->max->data = fstSliceDeepCopy(val, 0, FST_SLICE_LEN(val) - 1);
  }
  return b;
}


dengyihao's avatar
dengyihao 已提交
1387

dengyihao's avatar
dengyihao 已提交
1388