tdbPager.c 4.6 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
refact  
Hongze Cheng 已提交
18
struct SPager {
H
more  
Hongze Cheng 已提交
19 20
  char *   dbFileName;
  char *   jFileName;
H
Hongze Cheng 已提交
21
  int      pageSize;
H
more  
Hongze Cheng 已提交
22 23 24 25 26 27
  uint8_t  fid[TDB_FILE_ID_LEN];
  int      fd;
  int      jfd;
  SPCache *pCache;
  SPgno    dbFileSize;
  SPgno    dbOrigSize;
H
more  
Hongze Cheng 已提交
28 29 30
  int      nDirty;
  SPage *  pDirty;
  SPage *  pDirtyTail;
H
more  
Hongze Cheng 已提交
31
  u8       inTran;
H
more  
Hongze Cheng 已提交
32 33
};

H
Hongze Cheng 已提交
34 35 36 37 38 39
typedef struct __attribute__((__packed__)) {
  u8    hdrString[16];
  u16   pageSize;
  SPgno freePage;
  u32   nFreePages;
  u8    reserved[102];
H
Hongze Cheng 已提交
40 41
} SFileHdr;

H
Hongze Cheng 已提交
42 43
TDB_STATIC_ASSERT(sizeof(SFileHdr) == 128, "Size of file header is not correct");

H
refact  
Hongze Cheng 已提交
44
static int tdbPagerReadPage(SPager *pPager, SPage *pPage);
H
Hongze Cheng 已提交
45

H
refact  
Hongze Cheng 已提交
46
int tdbPagerOpen(SPCache *pCache, const char *fileName, SPager **ppPager) {
H
more  
Hongze Cheng 已提交
47
  uint8_t *pPtr;
H
refact  
Hongze Cheng 已提交
48
  SPager * pPager;
H
more  
Hongze Cheng 已提交
49 50
  int      fsize;
  int      zsize;
H
Hongze Cheng 已提交
51
  int      ret;
H
more  
Hongze Cheng 已提交
52

H
refact  
Hongze Cheng 已提交
53
  *ppPager = NULL;
H
more  
Hongze Cheng 已提交
54 55

  fsize = strlen(fileName);
H
refact  
Hongze Cheng 已提交
56
  zsize = sizeof(*pPager)  /* SPager */
H
more  
Hongze Cheng 已提交
57 58 59 60 61 62 63
          + fsize + 1      /* dbFileName */
          + fsize + 8 + 1; /* jFileName */
  pPtr = (uint8_t *)calloc(1, zsize);
  if (pPtr == NULL) {
    return -1;
  }

H
refact  
Hongze Cheng 已提交
64 65 66 67 68 69
  pPager = (SPager *)pPtr;
  pPtr += sizeof(*pPager);
  // pPager->dbFileName
  pPager->dbFileName = (char *)pPtr;
  memcpy(pPager->dbFileName, fileName, fsize);
  pPager->dbFileName[fsize] = '\0';
H
more  
Hongze Cheng 已提交
70
  pPtr += fsize + 1;
H
refact  
Hongze Cheng 已提交
71 72 73 74 75 76 77 78 79 80
  // pPager->jFileName
  pPager->jFileName = (char *)pPtr;
  memcpy(pPager->jFileName, fileName, fsize);
  memcpy(pPager->jFileName + fsize, "-journal", 8);
  pPager->jFileName[fsize + 8] = '\0';
  // pPager->pCache
  pPager->pCache = pCache;

  pPager->fd = open(pPager->dbFileName, O_RDWR | O_CREAT, 0755);
  if (pPager->fd < 0) {
H
more  
Hongze Cheng 已提交
81 82 83
    return -1;
  }

H
refact  
Hongze Cheng 已提交
84
  ret = tdbGnrtFileID(pPager->dbFileName, pPager->fid, false);
H
Hongze Cheng 已提交
85 86 87 88
  if (ret < 0) {
    return -1;
  }

H
refact  
Hongze Cheng 已提交
89
  pPager->jfd = -1;
H
more  
Hongze Cheng 已提交
90

H
refact  
Hongze Cheng 已提交
91
  *ppPager = pPager;
H
more  
Hongze Cheng 已提交
92 93 94
  return 0;
}

H
refact  
Hongze Cheng 已提交
95
int tdbPagerClose(SPager *pPager) {
H
more  
Hongze Cheng 已提交
96 97 98 99
  // TODO
  return 0;
}

H
refact  
Hongze Cheng 已提交
100
int tdbPagerOpenDB(SPager *pPager, SPgno *ppgno, bool toCreate) {
H
Hongze Cheng 已提交
101 102 103 104 105 106 107 108 109 110
  SPgno  pgno;
  SPage *pPage;
  int    ret;

  {
    // TODO: try to search the main DB to get the page number
    pgno = 0;
  }

  if (pgno == 0 && toCreate) {
H
refact  
Hongze Cheng 已提交
111
    ret = tdbPagerAllocPage(pPager, &pPage, &pgno);
H
Hongze Cheng 已提交
112 113 114 115
    if (ret < 0) {
      return -1;
    }

H
refact  
Hongze Cheng 已提交
116 117
    // tdbpPagerZeroPage(pPage);
    ret = tdbPagerWrite(pPager, pPage);
H
Hongze Cheng 已提交
118 119 120 121 122 123 124 125 126
    if (ret < 0) {
      return -1;
    }
  }

  *ppgno = pgno;
  return 0;
}

H
refact  
Hongze Cheng 已提交
127
SPage *tdbPagerGet(SPager *pPager, SPgno pgno) {
H
refact  
Hongze Cheng 已提交
128 129
  SPgid  pgid;
  SPage *pPage;
H
more  
Hongze Cheng 已提交
130

H
refact  
Hongze Cheng 已提交
131
  memcpy(pgid.fileid, pPager->fid, TDB_FILE_ID_LEN);
H
more  
Hongze Cheng 已提交
132 133
  pgid.pgno = pgno;

H
refact  
Hongze Cheng 已提交
134
  pPage = tdbPCacheFetch(pPager->pCache, &pgid, 1);
H
more  
Hongze Cheng 已提交
135
  if (pPage == NULL) {
H
more  
Hongze Cheng 已提交
136 137
    // TODO: handle error
    return NULL;
H
more  
Hongze Cheng 已提交
138
  }
H
refact  
Hongze Cheng 已提交
139
  tdbPCacheFetchFinish(pPager->pCache, pPage);
H
more  
Hongze Cheng 已提交
140 141

  return pPage;
H
more  
Hongze Cheng 已提交
142
}
H
Hongze Cheng 已提交
143

H
refact  
Hongze Cheng 已提交
144
int tdbPagerWrite(SPager *pPager, SPage *pPage) {
H
more  
Hongze Cheng 已提交
145 146
  int ret;

H
refact  
Hongze Cheng 已提交
147 148
  if (pPager->inTran == 0) {
    ret = tdbPagerBegin(pPager);
H
more  
Hongze Cheng 已提交
149 150 151 152 153 154 155 156 157 158
    if (ret < 0) {
      return -1;
    }
  }

  if (pPage->isDirty == 0) {
    pPage->isDirty = 1;
    // TODO: add the page to the dirty list

    // TODO: write the page to the journal
H
Hongze Cheng 已提交
159 160
    if (1 /*actually load from the file*/) {
    }
H
more  
Hongze Cheng 已提交
161
  }
H
Hongze Cheng 已提交
162 163 164
  return 0;
}

H
refact  
Hongze Cheng 已提交
165
int tdbPagerAllocPage(SPager *pPager, SPage **ppPage, SPgno *ppgno) {
H
Hongze Cheng 已提交
166 167 168 169
  SPage *pPage;
  SPgno  pgno;

  if (1 /*TODO: no free page*/) {
H
refact  
Hongze Cheng 已提交
170 171
    pgno = ++pPager->dbFileSize;
    pPage = tdbPagerGet(pPager, pgno);
H
Hongze Cheng 已提交
172 173
    ASSERT(pPage != NULL);
  } else {
H
Hongze Cheng 已提交
174
    /* TODO: allocate from the free list */
H
Hongze Cheng 已提交
175 176 177 178
    ASSERT(0);
  }

  *ppPage = pPage;
H
Hongze Cheng 已提交
179
  *ppgno = pgno;
H
Hongze Cheng 已提交
180 181 182
  return 0;
}

H
refact  
Hongze Cheng 已提交
183 184
int tdbPagerBegin(SPager *pPager) {
  if (pPager->inTran) {
H
more  
Hongze Cheng 已提交
185 186
    return 0;
  }
H
Hongze Cheng 已提交
187 188

  // Open the journal
H
refact  
Hongze Cheng 已提交
189 190
  pPager->jfd = open(pPager->jFileName, O_RDWR | O_CREAT, 0755);
  if (pPager->jfd < 0) {
H
Hongze Cheng 已提交
191 192 193 194 195
    return -1;
  }

  // TODO: write the size of the file

H
refact  
Hongze Cheng 已提交
196
  pPager->inTran = 1;
H
Hongze Cheng 已提交
197

H
more  
Hongze Cheng 已提交
198 199 200
  return 0;
}

H
refact  
Hongze Cheng 已提交
201
int tdbPagerCommit(SPager *pPager) {
H
more  
Hongze Cheng 已提交
202 203 204 205
  // TODO
  return 0;
}

H
refact  
Hongze Cheng 已提交
206
static int tdbPagerReadPage(SPager *pPager, SPage *pPage) {
H
Hongze Cheng 已提交
207 208 209
  i64 offset;
  int ret;

H
refact  
Hongze Cheng 已提交
210
  ASSERT(memcmp(pPager->fid, pPage->pgid.fileid, TDB_FILE_ID_LEN) == 0);
H
Hongze Cheng 已提交
211

H
refact  
Hongze Cheng 已提交
212 213
  offset = (pPage->pgid.pgno - 1) * (i64)(pPager->pageSize);
  ret = tdbPRead(pPager->fd, pPage->pData, pPager->pageSize, offset);
H
Hongze Cheng 已提交
214 215 216 217 218
  if (ret < 0) {
    // TODO: handle error
    return -1;
  }
  return 0;
H
more  
Hongze Cheng 已提交
219
}