tdbPage.h 8.6 KB
Newer Older
H
Hongze Cheng 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
/*
 * 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/>.
 */

#ifndef _TDB_PAGE_H_
#define _TDB_PAGE_H_

#ifdef __cplusplus
extern "C" {
#endif

H
Hongze Cheng 已提交
23 24
typedef u8 SCell;

H
Hongze Cheng 已提交
25
// Page header (pageSize < 65536 (64K))
H
Hongze Cheng 已提交
26
typedef struct __attribute__((__packed__)) {
H
Hongze Cheng 已提交
27 28
  u16 flags;
  u16 nCells;
H
refact  
Hongze Cheng 已提交
29 30
  u16 cCells;
  u16 fCell;
H
Hongze Cheng 已提交
31
  u16 nFree;
H
Hongze Cheng 已提交
32 33
} SPageHdr;

H
Hongze Cheng 已提交
34
// Large page header (pageSize >= 65536 (64K))
H
Hongze Cheng 已提交
35 36 37
typedef struct __attribute__((__packed__)) {
  u16 flags;
  u8  nCells[3];
H
refact  
Hongze Cheng 已提交
38 39
  u8  cCells[3];
  u8  fCell[3];
H
Hongze Cheng 已提交
40
  u8  nFree[3];
H
Hongze Cheng 已提交
41
} SLPageHdr;
H
Hongze Cheng 已提交
42

H
Hongze Cheng 已提交
43
// Page footer
H
Hongze Cheng 已提交
44 45 46 47
typedef struct __attribute__((__packed__)) {
  u8 cksm[4];
} SPageFtr;

H
refact  
Hongze Cheng 已提交
48
struct SPage {
H
Hongze Cheng 已提交
49
  u8                *pData;
H
Hongze Cheng 已提交
50
  int                pageSize;
H
Hongze Cheng 已提交
51
  u8                 szOffset;
H
Hongze Cheng 已提交
52
  u8                 szPageHdr;
H
Hongze Cheng 已提交
53
  pthread_spinlock_t lock;
H
refact  
Hongze Cheng 已提交
54
  // Fields below used by pager and am
H
Hongze Cheng 已提交
55
  u8       *pPageHdr;
H
Hongze Cheng 已提交
56
  SPageFtr *pPageFtr;
H
Hongze Cheng 已提交
57
  u8       *aCellIdx;
H
Hongze Cheng 已提交
58 59
  u8       *pFreeStart;
  u8       *pFreeEnd;
H
Hongze Cheng 已提交
60 61
  int       kLen;
  int       vLen;
H
Hongze Cheng 已提交
62
  int       nFree;
H
Hongze Cheng 已提交
63 64 65
  int       maxLocal;
  int       minLocal;
  int       nOverflow;
H
Hongze Cheng 已提交
66
  SCell    *apOvfl[4];
H
Hongze Cheng 已提交
67
  int       aiOvfl[4];
H
Hongze Cheng 已提交
68 69
  // Fields used by SPCache
  TDB_PCACHE_PAGE
H
refact  
Hongze Cheng 已提交
70
};
H
Hongze Cheng 已提交
71

H
Hongze Cheng 已提交
72
// Macros
H
Hongze Cheng 已提交
73 74
#define TDB_IS_LARGE_PAGE(pPage) ((pPage)->szOffset == 3)

H
Hongze Cheng 已提交
75
/* For small page */
H
Hongze Cheng 已提交
76 77 78 79 80 81
#define TDB_SPAGE_FLAGS(pPage)               (((SPageHdr *)(pPage)->pPageHdr)->flags)
#define TDB_SPAGE_NCELLS(pPage)              (((SPageHdr *)(pPage)->pPageHdr)->nCells)
#define TDB_SPAGE_CCELLS(pPage)              (((SPageHdr *)(pPage)->pPageHdr)->cCells)
#define TDB_SPAGE_FCELL(pPage)               (((SPageHdr *)(pPage)->pPageHdr)->fCell)
#define TDB_SPAGE_NFREE(pPage)               (((SPageHdr *)(pPage)->pPageHdr)->nFree)
#define TDB_SPAGE_CELL_OFFSET_AT(pPage, idx) ((u16 *)((pPage)->aCellIdx))[idx]
H
Hongze Cheng 已提交
82

H
Hongze Cheng 已提交
83 84 85 86 87 88 89
#define TDB_SPAGE_FLAGS_SET(pPage, FLAGS)                TDB_SPAGE_FLAGS(pPage) = (FLAGS)
#define TDB_SPAGE_NCELLS_SET(pPage, NCELLS)              TDB_SPAGE_NCELLS(pPage) = (NCELLS)
#define TDB_SPAGE_CCELLS_SET(pPage, CCELLS)              TDB_SPAGE_CCELLS(pPage) = (CCELLS)
#define TDB_SPAGE_FCELL_SET(pPage, FCELL)                TDB_SPAGE_FCELL(pPage) = (FCELL)
#define TDB_SPAGE_NFREE_SET(pPage, NFREE)                TDB_SPAGE_NFREE(pPage) = (NFREE)
#define TDB_SPAGE_CELL_OFFSET_AT_SET(pPage, idx, OFFSET) TDB_SPAGE_CELL_OFFSET_AT(pPage, idx) = (OFFSET)

H
Hongze Cheng 已提交
90
/* For large page */
H
Hongze Cheng 已提交
91 92 93 94 95 96 97 98 99 100 101 102 103
#define TDB_LPAGE_FLAGS(pPage)               (((SLPageHdr *)(pPage)->pPageHdr)->flags)
#define TDB_LPAGE_NCELLS(pPage)              TDB_GET_U24(((SLPageHdr *)(pPage)->pPageHdr)->nCells)
#define TDB_LPAGE_CCELLS(pPage)              TDB_GET_U24(((SLPageHdr *)(pPage)->pPageHdr)->cCells)
#define TDB_LPAGE_FCELL(pPage)               TDB_GET_U24(((SLPageHdr *)(pPage)->pPageHdr)->fCell)
#define TDB_LPAGE_NFREE(pPage)               TDB_GET_U24(((SLPageHdr *)(pPage)->pPageHdr)->nFree)
#define TDB_LPAGE_CELL_OFFSET_AT(pPage, idx) TDB_GET_U24((pPage)->aCellIdx + idx * 3)

#define TDB_LPAGE_FLAGS_SET(pPage, FLAGS)                TDB_LPAGE_FLAGS(pPage) = (flags)
#define TDB_LPAGE_NCELLS_SET(pPage, NCELLS)              TDB_PUT_U24(((SLPageHdr *)(pPage)->pPageHdr)->nCells, NCELLS)
#define TDB_LPAGE_CCELLS_SET(pPage, CCELLS)              TDB_PUT_U24(((SLPageHdr *)(pPage)->pPageHdr)->cCells, CCELLS)
#define TDB_LPAGE_FCELL_SET(pPage, FCELL)                TDB_PUT_U24(((SLPageHdr *)(pPage)->pPageHdr)->fCell, FCELL)
#define TDB_LPAGE_NFREE_SET(pPage, NFREE)                TDB_PUT_U24(((SLPageHdr *)(pPage)->pPageHdr)->nFree, NFREE)
#define TDB_LPAGE_CELL_OFFSET_AT_SET(pPage, idx, OFFSET) TDB_PUT_U24((pPage)->aCellIdx + idx * 3, OFFSET)
H
Hongze Cheng 已提交
104 105

/* For page */
H
Hongze Cheng 已提交
106 107 108 109 110
#define TDB_PAGE_FLAGS(pPage)  (TDB_IS_LARGE_PAGE(pPage) ? TDB_LPAGE_FLAGS(pPage) : TDB_SPAGE_FLAGS(pPage))
#define TDB_PAGE_NCELLS(pPage) (TDB_IS_LARGE_PAGE(pPage) ? TDB_LPAGE_NCELLS(pPage) : TDB_SPAGE_NCELLS(pPage))
#define TDB_PAGE_CCELLS(pPage) (TDB_IS_LARGE_PAGE(pPage) ? TDB_LPAGE_CCELLS(pPage) : TDB_SPAGE_CCELLS(pPage))
#define TDB_PAGE_FCELL(pPage)  (TDB_IS_LARGE_PAGE(pPage) ? TDB_LPAGE_FCELL(pPage) : TDB_SPAGE_FCELL(pPage))
#define TDB_PAGE_NFREE(pPage)  (TDB_IS_LARGE_PAGE(pPage) ? TDB_LPAGE_NFREE(pPage) : TDB_SPAGE_NFREE(pPage))
H
Hongze Cheng 已提交
111 112
#define TDB_PAGE_CELL_OFFSET_AT(pPage, idx) \
  (TDB_IS_LARGE_PAGE(pPage) ? TDB_LPAGE_CELL_OFFSET_AT(pPage, idx) : TDB_SPAGE_CELL_OFFSET_AT(pPage, idx))
H
Hongze Cheng 已提交
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167

#define TDB_PAGE_FLAGS_SET(pPage, FLAGS) \
  do {                                   \
    if (TDB_IS_LARGE_PAGE(pPage)) {      \
      TDB_LPAGE_FLAGS_SET(pPage, FLAGS); \
    } else {                             \
      TDB_SPAGE_FLAGS_SET(pPage, FLAGS); \
    }                                    \
  } while (0)

#define TDB_PAGE_NCELLS_SET(pPage, NCELLS) \
  do {                                     \
    if (TDB_IS_LARGE_PAGE(pPage)) {        \
      TDB_LPAGE_NCELLS_SET(pPage, NCELLS); \
    } else {                               \
      TDB_SPAGE_NCELLS_SET(pPage, NCELLS); \
    }                                      \
  } while (0)

#define TDB_PAGE_CCELLS_SET(pPage, CCELLS) \
  do {                                     \
    if (TDB_IS_LARGE_PAGE(pPage)) {        \
      TDB_LPAGE_CCELLS_SET(pPage, CCELLS); \
    } else {                               \
      TDB_SPAGE_CCELLS_SET(pPage, CCELLS); \
    }                                      \
  } while (0)

#define TDB_PAGE_FCELL_SET(pPage, FCELL) \
  do {                                   \
    if (TDB_IS_LARGE_PAGE(pPage)) {      \
      TDB_LPAGE_FCELL_SET(pPage, FCELL); \
    } else {                             \
      TDB_SPAGE_FCELL_SET(pPage, FCELL); \
    }                                    \
  } while (0)

#define TDB_PAGE_NFREE_SET(pPage, NFREE) \
  do {                                   \
    if (TDB_IS_LARGE_PAGE(pPage)) {      \
      TDB_LPAGE_NFREE_SET(pPage, NFREE); \
    } else {                             \
      TDB_SPAGE_NFREE_SET(pPage, NFREE); \
    }                                    \
  } while (0)

#define TDB_PAGE_CELL_OFFSET_AT_SET(pPage, idx, OFFSET) \
  do {                                                  \
    if (TDB_IS_LARGE_PAGE(pPage)) {                     \
      TDB_LPAGE_CELL_OFFSET_AT_SET(pPage, idx, OFFSET); \
    } else {                                            \
      TDB_SPAGE_CELL_OFFSET_AT_SET(pPage, idx, OFFSET); \
    }                                                   \
  } while (0)

H
Hongze Cheng 已提交
168
#define TDB_PAGE_CELL_AT(pPage, idx) ((pPage)->pData + TDB_PAGE_CELL_OFFSET_AT(pPage, idx))
H
Hongze Cheng 已提交
169

H
Hongze Cheng 已提交
170
// For page lock
H
Hongze Cheng 已提交
171 172 173 174
#define P_LOCK_SUCC 0
#define P_LOCK_BUSY 1
#define P_LOCK_FAIL -1

H
Hongze Cheng 已提交
175
#define TDB_INIT_PAGE_LOCK(pPage)    pthread_spin_init(&((pPage)->lock), 0)
H
Hongze Cheng 已提交
176 177 178
#define TDB_DESTROY_PAGE_LOCK(pPage) pthread_spin_destroy(&((pPage)->lock))
#define TDB_LOCK_PAGE(pPage)         pthread_spin_lock(&((pPage)->lock))
#define TDB_UNLOCK_PAGE(pPage)       pthread_spin_unlock(&((pPage)->lock))
H
Hongze Cheng 已提交
179 180 181 182 183 184 185 186 187 188 189 190
#define TDB_TRY_LOCK_PAGE(pPage)                       \
  ({                                                   \
    int ret;                                           \
    if (pthread_spin_trylock(&((pPage)->lock)) == 0) { \
      ret = P_LOCK_SUCC;                               \
    } else if (errno == EBUSY) {                       \
      ret = P_LOCK_BUSY;                               \
    } else {                                           \
      ret = P_LOCK_FAIL;                               \
    }                                                  \
    ret;                                               \
  })
H
Hongze Cheng 已提交
191

H
Hongze Cheng 已提交
192
// For page ref
H
Hongze Cheng 已提交
193
#define TDB_INIT_PAGE_REF(pPage) ((pPage)->nRef = 0)
H
Hongze Cheng 已提交
194
#if 0
H
Hongze Cheng 已提交
195 196 197
#define TDB_REF_PAGE(pPage)     (++(pPage)->nRef)
#define TDB_UNREF_PAGE(pPage)   (--(pPage)->nRef)
#define TDB_GET_PAGE_REF(pPage) ((pPage)->nRef)
H
Hongze Cheng 已提交
198
#else
H
Hongze Cheng 已提交
199 200 201
#define TDB_REF_PAGE(pPage)     atomic_add_fetch_32(&((pPage)->nRef), 1)
#define TDB_UNREF_PAGE(pPage)   atomic_sub_fetch_32(&((pPage)->nRef), 1)
#define TDB_GET_PAGE_REF(pPage) atomic_load_32(&((pPage)->nRef))
H
Hongze Cheng 已提交
202
#endif
H
Hongze Cheng 已提交
203

H
Hongze Cheng 已提交
204
// APIs
H
Hongze Cheng 已提交
205
int tdbPageCreate(int pageSize, SPage **ppPage, void *(*xMalloc)(void *, size_t), void *arg);
H
Hongze Cheng 已提交
206
int tdbPageDestroy(SPage *pPage, void (*xFree)(void *arg, void *ptr), void *arg);
H
Hongze Cheng 已提交
207
int tdbPageInsertCell(SPage *pPage, int idx, SCell *pCell, int szCell);
H
Hongze Cheng 已提交
208 209
int tdbPageDropCell(SPage *pPage, int idx);

H
Hongze Cheng 已提交
210 211 212 213 214
#ifdef __cplusplus
}
#endif

#endif /*_TDB_PAGE_H_*/