00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifndef SPGIST_PRIVATE_H
00015 #define SPGIST_PRIVATE_H
00016
00017 #include "access/itup.h"
00018 #include "access/spgist.h"
00019 #include "nodes/tidbitmap.h"
00020 #include "storage/relfilenode.h"
00021 #include "utils/relcache.h"
00022
00023
00024
00025 #define SPGIST_METAPAGE_BLKNO (0)
00026 #define SPGIST_ROOT_BLKNO (1)
00027 #define SPGIST_NULL_BLKNO (2)
00028 #define SPGIST_LAST_FIXED_BLKNO SPGIST_NULL_BLKNO
00029
00030 #define SpGistBlockIsRoot(blkno) \
00031 ((blkno) == SPGIST_ROOT_BLKNO || (blkno) == SPGIST_NULL_BLKNO)
00032 #define SpGistBlockIsFixed(blkno) \
00033 ((BlockNumber) (blkno) <= (BlockNumber) SPGIST_LAST_FIXED_BLKNO)
00034
00035
00036
00037
00038 typedef struct SpGistPageOpaqueData
00039 {
00040 uint16 flags;
00041 uint16 nRedirection;
00042 uint16 nPlaceholder;
00043
00044 uint16 spgist_page_id;
00045 } SpGistPageOpaqueData;
00046
00047 typedef SpGistPageOpaqueData *SpGistPageOpaque;
00048
00049
00050 #define SPGIST_META (1<<0)
00051 #define SPGIST_DELETED (1<<1)
00052 #define SPGIST_LEAF (1<<2)
00053 #define SPGIST_NULLS (1<<3)
00054
00055 #define SpGistPageGetOpaque(page) ((SpGistPageOpaque) PageGetSpecialPointer(page))
00056 #define SpGistPageIsMeta(page) (SpGistPageGetOpaque(page)->flags & SPGIST_META)
00057 #define SpGistPageIsDeleted(page) (SpGistPageGetOpaque(page)->flags & SPGIST_DELETED)
00058 #define SpGistPageSetDeleted(page) (SpGistPageGetOpaque(page)->flags |= SPGIST_DELETED)
00059 #define SpGistPageIsLeaf(page) (SpGistPageGetOpaque(page)->flags & SPGIST_LEAF)
00060 #define SpGistPageStoresNulls(page) (SpGistPageGetOpaque(page)->flags & SPGIST_NULLS)
00061
00062
00063
00064
00065
00066
00067
00068 #define SPGIST_PAGE_ID 0xFF82
00069
00070
00071
00072
00073
00074
00075 typedef struct SpGistLastUsedPage
00076 {
00077 BlockNumber blkno;
00078 int freeSpace;
00079 } SpGistLastUsedPage;
00080
00081
00082 #define SPGIST_CACHED_PAGES 8
00083
00084 typedef struct SpGistLUPCache
00085 {
00086 SpGistLastUsedPage cachedPage[SPGIST_CACHED_PAGES];
00087 } SpGistLUPCache;
00088
00089
00090
00091
00092 typedef struct SpGistMetaPageData
00093 {
00094 uint32 magicNumber;
00095 SpGistLUPCache lastUsedPages;
00096 } SpGistMetaPageData;
00097
00098 #define SPGIST_MAGIC_NUMBER (0xBA0BABEE)
00099
00100 #define SpGistPageGetMeta(p) \
00101 ((SpGistMetaPageData *) PageGetContents(p))
00102
00103
00104
00105
00106
00107
00108
00109 typedef struct SpGistTypeDesc
00110 {
00111 Oid type;
00112 bool attbyval;
00113 int16 attlen;
00114 } SpGistTypeDesc;
00115
00116 typedef struct SpGistState
00117 {
00118 spgConfigOut config;
00119
00120 SpGistTypeDesc attType;
00121 SpGistTypeDesc attPrefixType;
00122 SpGistTypeDesc attLabelType;
00123
00124 char *deadTupleStorage;
00125
00126 TransactionId myXid;
00127 bool isBuild;
00128 } SpGistState;
00129
00130
00131
00132
00133 typedef struct SpGistScanOpaqueData
00134 {
00135 SpGistState state;
00136 MemoryContext tempCxt;
00137
00138
00139 bool searchNulls;
00140 bool searchNonNulls;
00141
00142
00143 int numberOfKeys;
00144 ScanKey keyData;
00145
00146
00147 List *scanStack;
00148
00149
00150 TIDBitmap *tbm;
00151 int64 ntids;
00152
00153
00154 bool want_itup;
00155 TupleDesc indexTupDesc;
00156 int nPtrs;
00157 int iPtr;
00158 ItemPointerData heapPtrs[MaxIndexTuplesPerPage];
00159 bool recheck[MaxIndexTuplesPerPage];
00160 IndexTuple indexTups[MaxIndexTuplesPerPage];
00161
00162
00163
00164
00165
00166
00167 } SpGistScanOpaqueData;
00168
00169 typedef SpGistScanOpaqueData *SpGistScanOpaque;
00170
00171
00172
00173
00174
00175 typedef struct SpGistCache
00176 {
00177 spgConfigOut config;
00178
00179 SpGistTypeDesc attType;
00180 SpGistTypeDesc attPrefixType;
00181 SpGistTypeDesc attLabelType;
00182
00183 SpGistLUPCache lastUsedPages;
00184 } SpGistCache;
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 #define SPGIST_LIVE 0
00196 #define SPGIST_REDIRECT 1
00197 #define SPGIST_DEAD 2
00198 #define SPGIST_PLACEHOLDER 3
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208 typedef struct SpGistInnerTupleData
00209 {
00210 unsigned int tupstate:2,
00211 allTheSame:1,
00212 nNodes:13,
00213 prefixSize:16;
00214 uint16 size;
00215
00216
00217 } SpGistInnerTupleData;
00218
00219 typedef SpGistInnerTupleData *SpGistInnerTuple;
00220
00221
00222 #define SGITMAXNNODES 0x1FFF
00223 #define SGITMAXPREFIXSIZE 0xFFFF
00224 #define SGITMAXSIZE 0xFFFF
00225
00226 #define SGITHDRSZ MAXALIGN(sizeof(SpGistInnerTupleData))
00227 #define _SGITDATA(x) (((char *) (x)) + SGITHDRSZ)
00228 #define SGITDATAPTR(x) ((x)->prefixSize ? _SGITDATA(x) : NULL)
00229 #define SGITDATUM(x, s) ((x)->prefixSize ? \
00230 ((s)->attPrefixType.attbyval ? \
00231 *(Datum *) _SGITDATA(x) : \
00232 PointerGetDatum(_SGITDATA(x))) \
00233 : (Datum) 0)
00234 #define SGITNODEPTR(x) ((SpGistNodeTuple) (_SGITDATA(x) + (x)->prefixSize))
00235
00236
00237 #define SGITITERATE(x, i, nt) \
00238 for ((i) = 0, (nt) = SGITNODEPTR(x); \
00239 (i) < (x)->nNodes; \
00240 (i)++, (nt) = (SpGistNodeTuple) (((char *) (nt)) + IndexTupleSize(nt)))
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252 typedef IndexTupleData SpGistNodeTupleData;
00253
00254 typedef SpGistNodeTupleData *SpGistNodeTuple;
00255
00256 #define SGNTHDRSZ MAXALIGN(sizeof(SpGistNodeTupleData))
00257 #define SGNTDATAPTR(x) (((char *) (x)) + SGNTHDRSZ)
00258 #define SGNTDATUM(x, s) ((s)->attLabelType.attbyval ? \
00259 *(Datum *) SGNTDATAPTR(x) : \
00260 PointerGetDatum(SGNTDATAPTR(x)))
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288 typedef struct SpGistLeafTupleData
00289 {
00290 unsigned int tupstate:2,
00291 size:30;
00292 OffsetNumber nextOffset;
00293 ItemPointerData heapPtr;
00294
00295 } SpGistLeafTupleData;
00296
00297 typedef SpGistLeafTupleData *SpGistLeafTuple;
00298
00299 #define SGLTHDRSZ MAXALIGN(sizeof(SpGistLeafTupleData))
00300 #define SGLTDATAPTR(x) (((char *) (x)) + SGLTHDRSZ)
00301 #define SGLTDATUM(x, s) ((s)->attType.attbyval ? \
00302 *(Datum *) SGLTDATAPTR(x) : \
00303 PointerGetDatum(SGLTDATAPTR(x)))
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316 typedef struct SpGistDeadTupleData
00317 {
00318 unsigned int tupstate:2,
00319 size:30;
00320 OffsetNumber nextOffset;
00321 ItemPointerData pointer;
00322 TransactionId xid;
00323 } SpGistDeadTupleData;
00324
00325 typedef SpGistDeadTupleData *SpGistDeadTuple;
00326
00327 #define SGDTSIZE MAXALIGN(sizeof(SpGistDeadTupleData))
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337 #define SPGIST_PAGE_CAPACITY \
00338 MAXALIGN_DOWN(BLCKSZ - \
00339 SizeOfPageHeaderData - \
00340 MAXALIGN(sizeof(SpGistPageOpaqueData)))
00341
00342
00343
00344
00345
00346 #define SpGistPageGetFreeSpace(p, n) \
00347 (PageGetExactFreeSpace(p) + \
00348 Min(SpGistPageGetOpaque(p)->nPlaceholder, n) * \
00349 (SGDTSIZE + sizeof(ItemIdData)))
00350
00351
00352
00353
00354
00355
00356
00357 #define ACCEPT_RDATA_DATA(p, s, i) \
00358 do { \
00359 Assert((i) < lengthof(rdata)); \
00360 rdata[i].data = (char *) (p); \
00361 rdata[i].len = (s); \
00362 rdata[i].buffer = InvalidBuffer; \
00363 rdata[i].buffer_std = true; \
00364 rdata[i].next = NULL; \
00365 if ((i) > 0) \
00366 rdata[(i) - 1].next = rdata + (i); \
00367 } while(0)
00368
00369 #define ACCEPT_RDATA_BUFFER(b, i) \
00370 do { \
00371 Assert((i) < lengthof(rdata)); \
00372 rdata[i].data = NULL; \
00373 rdata[i].len = 0; \
00374 rdata[i].buffer = (b); \
00375 rdata[i].buffer_std = true; \
00376 rdata[i].next = NULL; \
00377 if ((i) > 0) \
00378 rdata[(i) - 1].next = rdata + (i); \
00379 } while(0)
00380
00381
00382
00383 #define XLOG_SPGIST_CREATE_INDEX 0x00
00384 #define XLOG_SPGIST_ADD_LEAF 0x10
00385 #define XLOG_SPGIST_MOVE_LEAFS 0x20
00386 #define XLOG_SPGIST_ADD_NODE 0x30
00387 #define XLOG_SPGIST_SPLIT_TUPLE 0x40
00388 #define XLOG_SPGIST_PICKSPLIT 0x50
00389 #define XLOG_SPGIST_VACUUM_LEAF 0x60
00390 #define XLOG_SPGIST_VACUUM_ROOT 0x70
00391 #define XLOG_SPGIST_VACUUM_REDIRECT 0x80
00392
00393
00394
00395
00396
00397
00398 typedef struct spgxlogState
00399 {
00400 TransactionId myXid;
00401 bool isBuild;
00402 } spgxlogState;
00403
00404 #define STORE_STATE(s, d) \
00405 do { \
00406 (d).myXid = (s)->myXid; \
00407 (d).isBuild = (s)->isBuild; \
00408 } while(0)
00409
00410
00411 typedef struct spgxlogAddLeaf
00412 {
00413 RelFileNode node;
00414
00415 BlockNumber blknoLeaf;
00416 bool newPage;
00417 bool storesNulls;
00418 OffsetNumber offnumLeaf;
00419 OffsetNumber offnumHeadLeaf;
00420
00421 BlockNumber blknoParent;
00422 OffsetNumber offnumParent;
00423 uint16 nodeI;
00424
00425
00426
00427
00428
00429 } spgxlogAddLeaf;
00430
00431 typedef struct spgxlogMoveLeafs
00432 {
00433 RelFileNode node;
00434
00435 BlockNumber blknoSrc;
00436 BlockNumber blknoDst;
00437 uint16 nMoves;
00438 bool newPage;
00439 bool replaceDead;
00440 bool storesNulls;
00441
00442 BlockNumber blknoParent;
00443 OffsetNumber offnumParent;
00444 uint16 nodeI;
00445
00446 spgxlogState stateSrc;
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466 } spgxlogMoveLeafs;
00467
00468 typedef struct spgxlogAddNode
00469 {
00470 RelFileNode node;
00471
00472 BlockNumber blkno;
00473 OffsetNumber offnum;
00474
00475 BlockNumber blknoParent;
00476 OffsetNumber offnumParent;
00477 uint16 nodeI;
00478
00479 BlockNumber blknoNew;
00480 OffsetNumber offnumNew;
00481 bool newPage;
00482
00483 spgxlogState stateSrc;
00484
00485
00486
00487
00488
00489 } spgxlogAddNode;
00490
00491 typedef struct spgxlogSplitTuple
00492 {
00493 RelFileNode node;
00494
00495 BlockNumber blknoPrefix;
00496 OffsetNumber offnumPrefix;
00497
00498 BlockNumber blknoPostfix;
00499 OffsetNumber offnumPostfix;
00500 bool newPage;
00501
00502
00503
00504
00505
00506
00507 } spgxlogSplitTuple;
00508
00509 typedef struct spgxlogPickSplit
00510 {
00511 RelFileNode node;
00512
00513 BlockNumber blknoSrc;
00514 BlockNumber blknoDest;
00515 uint16 nDelete;
00516 uint16 nInsert;
00517 bool initSrc;
00518 bool initDest;
00519
00520 BlockNumber blknoInner;
00521 OffsetNumber offnumInner;
00522 bool initInner;
00523
00524 bool storesNulls;
00525
00526 BlockNumber blknoParent;
00527 OffsetNumber offnumParent;
00528 uint16 nodeI;
00529
00530 spgxlogState stateSrc;
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549 } spgxlogPickSplit;
00550
00551 typedef struct spgxlogVacuumLeaf
00552 {
00553 RelFileNode node;
00554
00555 BlockNumber blkno;
00556 uint16 nDead;
00557 uint16 nPlaceholder;
00558 uint16 nMove;
00559 uint16 nChain;
00560
00561 spgxlogState stateSrc;
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573 } spgxlogVacuumLeaf;
00574
00575 typedef struct spgxlogVacuumRoot
00576 {
00577
00578 RelFileNode node;
00579
00580 BlockNumber blkno;
00581 uint16 nDelete;
00582
00583 spgxlogState stateSrc;
00584
00585
00586 } spgxlogVacuumRoot;
00587
00588 typedef struct spgxlogVacuumRedirect
00589 {
00590 RelFileNode node;
00591
00592 BlockNumber blkno;
00593 uint16 nToPlaceholder;
00594 OffsetNumber firstPlaceholder;
00595 TransactionId newestRedirectXid;
00596
00597
00598 } spgxlogVacuumRedirect;
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611 #define GBUF_LEAF 0x03
00612 #define GBUF_INNER_PARITY(x) ((x) % 3)
00613 #define GBUF_NULLS 0x04
00614
00615 #define GBUF_PARITY_MASK 0x03
00616 #define GBUF_REQ_LEAF(flags) (((flags) & GBUF_PARITY_MASK) == GBUF_LEAF)
00617 #define GBUF_REQ_NULLS(flags) ((flags) & GBUF_NULLS)
00618
00619
00620 extern SpGistCache *spgGetCache(Relation index);
00621 extern void initSpGistState(SpGistState *state, Relation index);
00622 extern Buffer SpGistNewBuffer(Relation index);
00623 extern void SpGistUpdateMetaPage(Relation index);
00624 extern Buffer SpGistGetBuffer(Relation index, int flags,
00625 int needSpace, bool *isNew);
00626 extern void SpGistSetLastUsedPage(Relation index, Buffer buffer);
00627 extern void SpGistInitPage(Page page, uint16 f);
00628 extern void SpGistInitBuffer(Buffer b, uint16 f);
00629 extern void SpGistInitMetapage(Page page);
00630 extern unsigned int SpGistGetTypeSize(SpGistTypeDesc *att, Datum datum);
00631 extern SpGistLeafTuple spgFormLeafTuple(SpGistState *state,
00632 ItemPointer heapPtr,
00633 Datum datum, bool isnull);
00634 extern SpGistNodeTuple spgFormNodeTuple(SpGistState *state,
00635 Datum label, bool isnull);
00636 extern SpGistInnerTuple spgFormInnerTuple(SpGistState *state,
00637 bool hasPrefix, Datum prefix,
00638 int nNodes, SpGistNodeTuple *nodes);
00639 extern SpGistDeadTuple spgFormDeadTuple(SpGistState *state, int tupstate,
00640 BlockNumber blkno, OffsetNumber offnum);
00641 extern Datum *spgExtractNodeLabels(SpGistState *state,
00642 SpGistInnerTuple innerTuple);
00643 extern OffsetNumber SpGistPageAddNewItem(SpGistState *state, Page page,
00644 Item item, Size size,
00645 OffsetNumber *startOffset,
00646 bool errorOK);
00647
00648
00649 extern void spgUpdateNodeLink(SpGistInnerTuple tup, int nodeN,
00650 BlockNumber blkno, OffsetNumber offset);
00651 extern void spgPageIndexMultiDelete(SpGistState *state, Page page,
00652 OffsetNumber *itemnos, int nitems,
00653 int firststate, int reststate,
00654 BlockNumber blkno, OffsetNumber offnum);
00655 extern void spgdoinsert(Relation index, SpGistState *state,
00656 ItemPointer heapPtr, Datum datum, bool isnull);
00657
00658 #endif