tdbBtree.c 6.0 KB
Newer Older
H
Hongze Cheng 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13
/*
 * 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/>.
H
refact  
Hongze Cheng 已提交
14 15
 */

H
Hongze Cheng 已提交
16 17
#include "tdbInt.h"

H
Hongze Cheng 已提交
18
struct SBTree {
H
more  
Hongze Cheng 已提交
19 20 21
  SPgno          root;
  int            keyLen;
  int            valLen;
H
refact  
Hongze Cheng 已提交
22
  SPager *       pPager;
H
more  
Hongze Cheng 已提交
23
  FKeyComparator kcmpr;
H
more  
Hongze Cheng 已提交
24 25 26 27 28 29
  u8             fanout;
  int            maxLocal;
  int            minLocal;
  int            maxLeaf;
  int            minLeaf;
  int            nPayload;
H
Hongze Cheng 已提交
30 31
};

H
Hongze Cheng 已提交
32
typedef struct SPgHdr {
H
more  
Hongze Cheng 已提交
33
  u8    flags;
H
more  
Hongze Cheng 已提交
34 35
  u8    fragmentTotalSize;
  u16   firstFreeCellOffset;
H
more  
Hongze Cheng 已提交
36 37 38 39 40
  u16   nCells;
  u16   pCell;
  i32   kLen;
  i32   vLen;
  SPgno rightChild;
H
Hongze Cheng 已提交
41 42
} SPgHdr;

H
Hongze Cheng 已提交
43
struct SBtPage {
H
Hongze Cheng 已提交
44 45
  SPgHdr *pHdr;
  u16 *   aCellIdx;
H
more  
Hongze Cheng 已提交
46
  u8 *    aData;
H
Hongze Cheng 已提交
47 48
};

H
more  
Hongze Cheng 已提交
49 50 51 52 53
typedef struct SFreeCell {
  u16 size;
  u16 next;
} SFreeCell;

H
Hongze Cheng 已提交
54
static int tdbBtCursorMoveTo(SBtCursor *pCur, const void *pKey, int kLen);
H
more  
Hongze Cheng 已提交
55
static int tdbEncodeLength(u8 *pBuf, uint32_t len);
H
more  
Hongze Cheng 已提交
56 57
static int tdbBtCursorMoveToRoot(SBtCursor *pCur);
static int tdbInitBtPage(SPage *pPage, SBtPage **ppBtPage);
H
more  
Hongze Cheng 已提交
58
static int tdbCompareKeyAndCell(const void *pKey, int kLen, const void *pCell);
H
Hongze Cheng 已提交
59 60
static int tdbDefaultKeyCmprFn(const void *pKey1, int keyLen1, const void *pKey2, int keyLen2);

H
refact  
Hongze Cheng 已提交
61
int tdbBtreeOpen(SPgno rtPgno, int keyLen, int valLen, SPager *pPager, FKeyComparator kcmpr, SBTree **ppBt) {
H
Hongze Cheng 已提交
62
  SBTree *pBt;
H
more  
Hongze Cheng 已提交
63

H
Hongze Cheng 已提交
64
  *ppBt = NULL;
H
Hongze Cheng 已提交
65 66 67 68 69 70 71 72 73 74 75 76

  pBt = (SBTree *)calloc(1, sizeof(*pBt));
  if (pBt == NULL) {
    return -1;
  }

  // pBt->root
  pBt->root = rtPgno;
  // pBt->keyLen
  pBt->keyLen = keyLen;
  // pBt->valLen
  pBt->valLen = valLen;
H
refact  
Hongze Cheng 已提交
77 78
  // pBt->pPager
  pBt->pPager = pPager;
H
Hongze Cheng 已提交
79 80
  // pBt->kcmpr
  pBt->kcmpr = kcmpr ? kcmpr : tdbDefaultKeyCmprFn;
H
more  
Hongze Cheng 已提交
81 82 83 84 85 86 87
  // pBt->fanout
  if (keyLen == TDB_VARIANT_LEN) {
    pBt->fanout = TDB_DEFAULT_FANOUT;
  } else {
    ASSERT(0);
    // TODO: pBt->fanout = 0;
  }
H
Hongze Cheng 已提交
88 89

  *ppBt = pBt;
H
Hongze Cheng 已提交
90 91 92 93 94 95 96 97
  return 0;
}

int tdbBtreeClose(SBTree *pBt) {
  // TODO
  return 0;
}

H
more  
Hongze Cheng 已提交
98
int tdbBtreeCursor(SBtCursor *pCur, SBTree *pBt) {
H
more  
Hongze Cheng 已提交
99 100
  pCur->pBt = pBt;
  pCur->iPage = -1;
H
more  
Hongze Cheng 已提交
101 102 103
  pCur->pPage = NULL;
  pCur->idx = 0;

H
more  
Hongze Cheng 已提交
104 105 106
  return 0;
}

H
Hongze Cheng 已提交
107
int tdbBtCursorInsert(SBtCursor *pCur, const void *pKey, int kLen, const void *pVal, int vLen) {
H
more  
Hongze Cheng 已提交
108
  int      ret;
H
refact  
Hongze Cheng 已提交
109
  SPager * pPager;
H
more  
Hongze Cheng 已提交
110
  SBtPage *pPage;
H
Hongze Cheng 已提交
111 112 113 114 115 116 117

  ret = tdbBtCursorMoveTo(pCur, pKey, kLen);
  if (ret < 0) {
    // TODO: handle error
    return -1;
  }

H
more  
Hongze Cheng 已提交
118
  pPage = pCur->pPage;
H
Hongze Cheng 已提交
119

H
more  
Hongze Cheng 已提交
120 121 122
  return 0;
}

H
Hongze Cheng 已提交
123
static int tdbBtCursorMoveTo(SBtCursor *pCur, const void *pKey, int kLen) {
H
more  
Hongze Cheng 已提交
124 125 126
  int      ret;
  SBtPage *pBtPage;
  void *   pCell;
H
more  
Hongze Cheng 已提交
127 128

  ret = tdbBtCursorMoveToRoot(pCur);
H
more  
Hongze Cheng 已提交
129 130 131 132
  if (ret < 0) {
    return -1;
  }

H
refact  
Hongze Cheng 已提交
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
  if (pCur->pPage->pHdr->nCells == 0) {
    // Tree is empty
  } else {
    for (;;) {
      int lidx, ridx, midx, c;

      pBtPage = pCur->pPage;
      lidx = 0;
      ridx = pBtPage->pHdr->nCells - 1;
      while (lidx <= ridx) {
        midx = (lidx + ridx) >> 1;
        pCell = (void *)(pBtPage->aData + pBtPage->aCellIdx[midx]);

        c = tdbCompareKeyAndCell(pKey, kLen, pCell);
        if (c == 0) {
          break;
        } else if (c < 0) {
          lidx = lidx + 1;
        } else {
          ridx = ridx - 1;
        }
H
more  
Hongze Cheng 已提交
154 155 156 157 158 159
      }
    }

    /* code */
  }

H
Hongze Cheng 已提交
160 161
  return 0;
}
H
more  
Hongze Cheng 已提交
162

H
Hongze Cheng 已提交
163 164 165
static int tdbEncodeKeyValue(const void *pKey, int kLen, int kLenG, const void *pVal, int vLen, int vLenG, void *pBuf,
                             int *bLen) {
  u8 *pPtr;
H
more  
Hongze Cheng 已提交
166

H
Hongze Cheng 已提交
167 168 169 170 171 172 173 174 175 176 177
  ASSERT(kLen > 0 && vLen > 0);
  ASSERT(kLenG == TDB_VARIANT_LEN || kLenG == kLen);
  ASSERT(vLenG == TDB_VARIANT_LEN || vLenG == vLen);

  pPtr = (u8 *)pBuf;
  if (kLenG == TDB_VARIANT_LEN) {
    pPtr += tdbEncodeLength(pPtr, kLen);
  }

  if (vLenG == TDB_VARIANT_LEN) {
    pPtr += tdbEncodeLength(pPtr, vLen);
H
more  
Hongze Cheng 已提交
178
  }
H
more  
Hongze Cheng 已提交
179

H
Hongze Cheng 已提交
180 181 182 183 184 185 186
  memcpy(pPtr, pKey, kLen);
  pPtr += kLen;

  memcpy(pPtr, pVal, vLen);
  pPtr += vLen;

  *bLen = pPtr - (u8 *)pBuf;
H
more  
Hongze Cheng 已提交
187
  return 0;
H
Hongze Cheng 已提交
188 189 190
}

static int tdbDecodeKeyValue(const void *pBuf, void *pKey, int *kLen, void *pVal, int *vLen) {
H
more  
Hongze Cheng 已提交
191 192 193 194 195 196 197 198 199 200
  if (*kLen == TDB_VARIANT_LEN) {
    // Decode the key length
  }

  if (*vLen == TDB_VARIANT_LEN) {
    // Decode the value length
  }

  // TODO: decode the key and value

H
Hongze Cheng 已提交
201 202 203
  return 0;
}

H
more  
Hongze Cheng 已提交
204
static int tdbEncodeLength(u8 *pBuf, uint32_t len) {
H
Hongze Cheng 已提交
205 206 207 208 209 210 211 212 213 214
  int iCount = 0;

  while (len > 127) {
    pBuf[iCount++] = (u8)((len & 0xff) | 128);
    len >>= 7;
  }

  pBuf[iCount++] = (u8)len;

  return iCount;
H
more  
Hongze Cheng 已提交
215 216 217 218
}

static int tdbBtCursorMoveToRoot(SBtCursor *pCur) {
  SBTree * pBt;
H
refact  
Hongze Cheng 已提交
219
  SPager * pPager;
H
more  
Hongze Cheng 已提交
220 221 222 223 224
  SPage *  pPage;
  SBtPage *pBtPage;
  int      ret;

  pBt = pCur->pBt;
H
refact  
Hongze Cheng 已提交
225
  pPager = pBt->pPager;
H
more  
Hongze Cheng 已提交
226

H
Hongze Cheng 已提交
227
  pPage = tdbPagerGet(pPager, pBt->root, true);
H
more  
Hongze Cheng 已提交
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244
  if (pPage == NULL) {
    // TODO: handle error
  }

  ret = tdbInitBtPage(pPage, &pBtPage);
  if (ret < 0) {
    // TODO
    return 0;
  }

  pCur->pPage = pBtPage;
  pCur->iPage = 0;

  return 0;
}

static int tdbInitBtPage(SPage *pPage, SBtPage **ppBtPage) {
H
more  
Hongze Cheng 已提交
245 246 247 248 249 250 251 252 253 254 255 256
  SBtPage *pBtPage;

  pBtPage = (SBtPage *)pPage->pExtra;
  pBtPage->pHdr = (SPgHdr *)pPage->pData;
  pBtPage->aCellIdx = (u16 *)(&((pBtPage->pHdr)[1]));
  pBtPage->aData = (u8 *)pPage->pData;

  *ppBtPage = pBtPage;
  return 0;
}
static int tdbCompareKeyAndCell(const void *pKey, int kLen, const void *pCell) {
  /* TODO */
H
more  
Hongze Cheng 已提交
257
  return 0;
H
Hongze Cheng 已提交
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277
}

static int tdbDefaultKeyCmprFn(const void *pKey1, int keyLen1, const void *pKey2, int keyLen2) {
  int mlen;
  int cret;

  ASSERT(keyLen1 > 0 && keyLen2 > 0 && pKey1 != NULL && pKey2 != NULL);

  mlen = keyLen1 < keyLen2 ? keyLen1 : keyLen2;
  cret = memcmp(pKey1, pKey2, mlen);
  if (cret == 0) {
    if (keyLen1 < keyLen2) {
      cret = -1;
    } else if (keyLen1 > keyLen2) {
      cret = 1;
    } else {
      cret = 0;
    }
  }
  return cret;
H
more  
Hongze Cheng 已提交
278 279 280 281 282 283 284 285 286
}

static void tdbBtreeZeroPage(SPageHandle *pPage, int flags) {
  // TODO
}

static int tdbBtreeInitPage(SPageHandle *pPage) {
  // TODO
  return 0;
H
more  
Hongze Cheng 已提交
287
}