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

dengyihao's avatar
dengyihao 已提交
16
#include "indexFstRegistry.h"
S
Shengliang Guan 已提交
17
#include "os.h"
dengyihao's avatar
dengyihao 已提交
18

dengyihao's avatar
dengyihao 已提交
19
uint64_t fstRegistryHash(FstRegistry* registry, FstBuilderNode* bNode) {
20
  // TODO(yihaoDeng): refactor later
dengyihao's avatar
dengyihao 已提交
21
  const uint64_t FNV_PRIME = 1099511628211;
22
  uint64_t       h = 14695981039346656037u;
dengyihao's avatar
dengyihao 已提交
23

24
  h = (h ^ (uint64_t)bNode->isFinal) * FNV_PRIME;
dengyihao's avatar
dengyihao 已提交
25 26
  h = (h ^ (bNode)->finalOutput) * FNV_PRIME;

27
  uint32_t sz = (uint32_t)taosArrayGetSize(bNode->trans);
dengyihao's avatar
dengyihao 已提交
28
  for (uint32_t i = 0; i < sz; i++) {
dengyihao's avatar
dengyihao 已提交
29
    FstTransition* trn = taosArrayGet(bNode->trans, i);
30 31 32 33 34
    h = (h ^ (uint64_t)(trn->inp)) * FNV_PRIME;
    h = (h ^ (uint64_t)(trn->out)) * FNV_PRIME;
    h = (h ^ (uint64_t)(trn->addr)) * FNV_PRIME;
  }
  return h % (registry->tableSize);
dengyihao's avatar
dengyihao 已提交
35
}
dengyihao's avatar
dengyihao 已提交
36
static void fstRegistryCellSwap(SArray* arr, uint32_t a, uint32_t b) {
dengyihao's avatar
dengyihao 已提交
37
  size_t sz = taosArrayGetSize(arr);
dengyihao's avatar
dengyihao 已提交
38 39 40
  if (a >= sz || b >= sz) {
    return;
  }
dengyihao's avatar
dengyihao 已提交
41

dengyihao's avatar
dengyihao 已提交
42 43
  FstRegistryCell* cell1 = (FstRegistryCell*)taosArrayGet(arr, a);
  FstRegistryCell* cell2 = (FstRegistryCell*)taosArrayGet(arr, b);
dengyihao's avatar
dengyihao 已提交
44

45
  FstRegistryCell t = {.addr = cell1->addr, .node = cell1->node};
dengyihao's avatar
dengyihao 已提交
46 47 48 49 50 51 52 53 54

  cell1->addr = cell2->addr;
  cell1->node = cell2->node;

  cell2->addr = t.addr;
  cell2->node = t.node;
  return;
}

dengyihao's avatar
dengyihao 已提交
55
static void fstRegistryCellPromote(SArray* arr, uint32_t start, uint32_t end) {
56
  size_t sz = taosArrayGetSize(arr);
dengyihao's avatar
dengyihao 已提交
57 58 59
  if (start >= sz && end >= sz) {
    return;
  }
60

dengyihao's avatar
dengyihao 已提交
61 62 63 64
  assert(start >= end);

  int32_t s = (int32_t)start;
  int32_t e = (int32_t)end;
65
  while (s > e) {
dengyihao's avatar
dengyihao 已提交
66 67 68 69
    fstRegistryCellSwap(arr, s - 1, s);
    s -= 1;
  }
}
dengyihao's avatar
dengyihao 已提交
70

dengyihao's avatar
dengyihao 已提交
71
FstRegistry* fstRegistryCreate(uint64_t tableSize, uint64_t mruSize) {
wafwerar's avatar
wafwerar 已提交
72
  FstRegistry* registry = taosMemoryMalloc(sizeof(FstRegistry));
dengyihao's avatar
dengyihao 已提交
73 74 75
  if (registry == NULL) {
    return NULL;
  }
dengyihao's avatar
dengyihao 已提交
76

77
  uint64_t nCells = tableSize * mruSize;
dengyihao's avatar
dengyihao 已提交
78
  SArray*  tb = (SArray*)taosArrayInit(nCells, sizeof(FstRegistryCell));
79
  if (NULL == tb) {
wafwerar's avatar
wafwerar 已提交
80
    taosMemoryFree(registry);
81
    return NULL;
dengyihao's avatar
dengyihao 已提交
82 83
  }

dengyihao's avatar
dengyihao 已提交
84
  for (uint64_t i = 0; i < nCells; i++) {
85 86
    FstRegistryCell cell = {.addr = NONE_ADDRESS, .node = fstBuilderNodeDefault()};
    taosArrayPush(tb, &cell);
dengyihao's avatar
dengyihao 已提交
87
  }
88 89 90 91 92

  registry->table = tb;
  registry->tableSize = tableSize;
  registry->mruSize = mruSize;
  return registry;
dengyihao's avatar
dengyihao 已提交
93 94
}

dengyihao's avatar
dengyihao 已提交
95
void fstRegistryDestroy(FstRegistry* registry) {
dengyihao's avatar
dengyihao 已提交
96 97 98
  if (registry == NULL) {
    return;
  }
dengyihao's avatar
dengyihao 已提交
99

dengyihao's avatar
dengyihao 已提交
100
  SArray* tb = registry->table;
101
  size_t  sz = taosArrayGetSize(tb);
dengyihao's avatar
dengyihao 已提交
102
  for (size_t i = 0; i < sz; i++) {
dengyihao's avatar
dengyihao 已提交
103
    FstRegistryCell* cell = taosArrayGet(tb, i);
104
    fstBuilderNodeDestroy(cell->node);
dengyihao's avatar
dengyihao 已提交
105 106
  }
  taosArrayDestroy(tb);
wafwerar's avatar
wafwerar 已提交
107
  taosMemoryFree(registry);
dengyihao's avatar
dengyihao 已提交
108 109
}

dengyihao's avatar
dengyihao 已提交
110
FstRegistryEntry* fstRegistryGetEntry(FstRegistry* registry, FstBuilderNode* bNode) {
dengyihao's avatar
dengyihao 已提交
111 112 113
  if (taosArrayGetSize(registry->table) <= 0) {
    return NULL;
  }
dengyihao's avatar
dengyihao 已提交
114
  uint64_t bucket = fstRegistryHash(registry, bNode);
115 116 117
  uint64_t start = registry->mruSize * bucket;
  uint64_t end = start + registry->mruSize;

wafwerar's avatar
wafwerar 已提交
118
  FstRegistryEntry* entry = taosMemoryMalloc(sizeof(FstRegistryEntry));
dengyihao's avatar
dengyihao 已提交
119
  if (end - start == 1) {
dengyihao's avatar
dengyihao 已提交
120
    FstRegistryCell* cell = taosArrayGet(registry->table, start);
121
    // cell->isNode &&
dengyihao's avatar
dengyihao 已提交
122
    if (cell->addr != NONE_ADDRESS && fstBuilderNodeEqual(cell->node, bNode)) {
123 124 125
      entry->state = FOUND;
      entry->addr = cell->addr;
      return entry;
dengyihao's avatar
dengyihao 已提交
126
    } else {
127 128 129
      fstBuilderNodeCloneFrom(cell->node, bNode);
      entry->state = NOTFOUND;
      entry->cell = cell;  // copy or not
dengyihao's avatar
dengyihao 已提交
130 131
    }
  } else if (end - start == 2) {
dengyihao's avatar
dengyihao 已提交
132
    FstRegistryCell* cell1 = taosArrayGet(registry->table, start);
dengyihao's avatar
dengyihao 已提交
133
    if (cell1->addr != NONE_ADDRESS && fstBuilderNodeEqual(cell1->node, bNode)) {
134 135
      entry->state = FOUND;
      entry->addr = cell1->addr;
dengyihao's avatar
dengyihao 已提交
136
      return entry;
137
    }
dengyihao's avatar
dengyihao 已提交
138
    FstRegistryCell* cell2 = taosArrayGet(registry->table, start + 1);
dengyihao's avatar
dengyihao 已提交
139
    if (cell2->addr != NONE_ADDRESS && fstBuilderNodeEqual(cell2->node, bNode)) {
140 141
      entry->state = FOUND;
      entry->addr = cell2->addr;
dengyihao's avatar
dengyihao 已提交
142
      // must swap here
143 144
      fstRegistryCellSwap(registry->table, start, start + 1);
      return entry;
dengyihao's avatar
dengyihao 已提交
145
    }
146
    // clone from bNode, refactor later
dengyihao's avatar
dengyihao 已提交
147
    fstBuilderNodeCloneFrom(cell2->node, bNode);
dengyihao's avatar
dengyihao 已提交
148 149

    fstRegistryCellSwap(registry->table, start, start + 1);
dengyihao's avatar
dengyihao 已提交
150
    FstRegistryCell* cCell = taosArrayGet(registry->table, start);
151 152
    entry->state = NOTFOUND;
    entry->cell = cCell;
dengyihao's avatar
dengyihao 已提交
153
  } else {
154
    uint32_t i = start;
dengyihao's avatar
dengyihao 已提交
155
    for (; i < end; i++) {
dengyihao's avatar
dengyihao 已提交
156
      FstRegistryCell* cell = (FstRegistryCell*)taosArrayGet(registry->table, i);
dengyihao's avatar
dengyihao 已提交
157
      if (cell->addr != NONE_ADDRESS && fstBuilderNodeEqual(cell->node, bNode)) {
158 159
        entry->state = FOUND;
        entry->addr = cell->addr;
dengyihao's avatar
dengyihao 已提交
160 161 162
        fstRegistryCellPromote(registry->table, i, start);
        break;
      }
163
    }
dengyihao's avatar
dengyihao 已提交
164
    if (i >= end) {
165
      uint64_t         last = end - 1;
dengyihao's avatar
dengyihao 已提交
166
      FstRegistryCell* cell = (FstRegistryCell*)taosArrayGet(registry->table, last);
167 168
      // clone from bNode, refactor later
      fstBuilderNodeCloneFrom(cell->node, bNode);
dengyihao's avatar
dengyihao 已提交
169 170

      fstRegistryCellPromote(registry->table, last, start);
dengyihao's avatar
dengyihao 已提交
171
      FstRegistryCell* cCell = taosArrayGet(registry->table, start);
172 173
      entry->state = NOTFOUND;
      entry->cell = cCell;
dengyihao's avatar
dengyihao 已提交
174
    }
175
  }
dengyihao's avatar
dengyihao 已提交
176 177
  return entry;
}
dengyihao's avatar
dengyihao 已提交
178
void fstRegistryEntryDestroy(FstRegistryEntry* entry) { taosMemoryFree(entry); }