00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifndef GIST_PRIVATE_H
00015 #define GIST_PRIVATE_H
00016
00017 #include "access/gist.h"
00018 #include "access/itup.h"
00019 #include "fmgr.h"
00020 #include "storage/bufmgr.h"
00021 #include "storage/buffile.h"
00022 #include "utils/rbtree.h"
00023 #include "utils/hsearch.h"
00024
00025
00026 #define GIST_SHARE BUFFER_LOCK_SHARE
00027 #define GIST_EXCLUSIVE BUFFER_LOCK_EXCLUSIVE
00028 #define GIST_UNLOCK BUFFER_LOCK_UNLOCK
00029
00030 typedef struct
00031 {
00032 BlockNumber prev;
00033 uint32 freespace;
00034 char tupledata[1];
00035 } GISTNodeBufferPage;
00036
00037 #define BUFFER_PAGE_DATA_OFFSET MAXALIGN(offsetof(GISTNodeBufferPage, tupledata))
00038
00039 #define PAGE_FREE_SPACE(nbp) (nbp->freespace)
00040
00041 #define PAGE_IS_EMPTY(nbp) (nbp->freespace == BLCKSZ - BUFFER_PAGE_DATA_OFFSET)
00042
00043 #define PAGE_NO_SPACE(nbp, itup) (PAGE_FREE_SPACE(nbp) < \
00044 MAXALIGN(IndexTupleSize(itup)))
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 typedef struct GISTSTATE
00060 {
00061 MemoryContext scanCxt;
00062 MemoryContext tempCxt;
00063
00064 TupleDesc tupdesc;
00065
00066 FmgrInfo consistentFn[INDEX_MAX_KEYS];
00067 FmgrInfo unionFn[INDEX_MAX_KEYS];
00068 FmgrInfo compressFn[INDEX_MAX_KEYS];
00069 FmgrInfo decompressFn[INDEX_MAX_KEYS];
00070 FmgrInfo penaltyFn[INDEX_MAX_KEYS];
00071 FmgrInfo picksplitFn[INDEX_MAX_KEYS];
00072 FmgrInfo equalFn[INDEX_MAX_KEYS];
00073 FmgrInfo distanceFn[INDEX_MAX_KEYS];
00074
00075
00076 Oid supportCollation[INDEX_MAX_KEYS];
00077 } GISTSTATE;
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 typedef struct GISTSearchHeapItem
00102 {
00103 ItemPointerData heapPtr;
00104 bool recheck;
00105 } GISTSearchHeapItem;
00106
00107
00108 typedef struct GISTSearchItem
00109 {
00110 struct GISTSearchItem *next;
00111 BlockNumber blkno;
00112 union
00113 {
00114 GistNSN parentlsn;
00115
00116 GISTSearchHeapItem heap;
00117 } data;
00118 } GISTSearchItem;
00119
00120 #define GISTSearchItemIsHeap(item) ((item).blkno == InvalidBlockNumber)
00121
00122
00123
00124
00125
00126
00127 typedef struct GISTSearchTreeItem
00128 {
00129 RBNode rbnode;
00130 GISTSearchItem *head;
00131 GISTSearchItem *lastHeap;
00132 double distances[1];
00133 } GISTSearchTreeItem;
00134
00135 #define GSTIHDRSZ offsetof(GISTSearchTreeItem, distances)
00136
00137
00138
00139
00140 typedef struct GISTScanOpaqueData
00141 {
00142 GISTSTATE *giststate;
00143 RBTree *queue;
00144 MemoryContext queueCxt;
00145 bool qual_ok;
00146 bool firstCall;
00147
00148 GISTSearchTreeItem *curTreeItem;
00149
00150
00151 GISTSearchTreeItem *tmpTreeItem;
00152 double *distances;
00153
00154
00155 GISTSearchHeapItem pageData[BLCKSZ / sizeof(IndexTupleData)];
00156 OffsetNumber nPageData;
00157 OffsetNumber curPageData;
00158 } GISTScanOpaqueData;
00159
00160 typedef GISTScanOpaqueData *GISTScanOpaque;
00161
00162
00163
00164
00165 #define XLOG_GIST_PAGE_UPDATE 0x00
00166
00167 #define XLOG_GIST_PAGE_SPLIT 0x30
00168
00169 #define XLOG_GIST_CREATE_INDEX 0x50
00170
00171
00172 typedef struct gistxlogPageUpdate
00173 {
00174 RelFileNode node;
00175 BlockNumber blkno;
00176
00177
00178
00179
00180
00181 BlockNumber leftchild;
00182
00183
00184 uint16 ntodelete;
00185
00186
00187
00188
00189 } gistxlogPageUpdate;
00190
00191 typedef struct gistxlogPageSplit
00192 {
00193 RelFileNode node;
00194 BlockNumber origblkno;
00195 BlockNumber origrlink;
00196 GistNSN orignsn;
00197 bool origleaf;
00198
00199 BlockNumber leftchild;
00200 uint16 npage;
00201 bool markfollowright;
00202
00203
00204
00205
00206 } gistxlogPageSplit;
00207
00208 typedef struct gistxlogPage
00209 {
00210 BlockNumber blkno;
00211 int num;
00212 } gistxlogPage;
00213
00214
00215 typedef struct SplitedPageLayout
00216 {
00217 gistxlogPage block;
00218 IndexTupleData *list;
00219 int lenlist;
00220 IndexTuple itup;
00221 Page page;
00222 Buffer buffer;
00223
00224 struct SplitedPageLayout *next;
00225 } SplitedPageLayout;
00226
00227
00228
00229
00230
00231 typedef struct GISTInsertStack
00232 {
00233
00234 BlockNumber blkno;
00235 Buffer buffer;
00236 Page page;
00237
00238
00239
00240
00241
00242 GistNSN lsn;
00243
00244
00245 OffsetNumber downlinkoffnum;
00246
00247
00248 struct GISTInsertStack *parent;
00249 } GISTInsertStack;
00250
00251
00252 typedef struct GistSplitVector
00253 {
00254 GIST_SPLITVEC splitVector;
00255
00256 Datum spl_lattr[INDEX_MAX_KEYS];
00257
00258 bool spl_lisnull[INDEX_MAX_KEYS];
00259
00260 Datum spl_rattr[INDEX_MAX_KEYS];
00261
00262 bool spl_risnull[INDEX_MAX_KEYS];
00263
00264 bool *spl_dontcare;
00265
00266 } GistSplitVector;
00267
00268 typedef struct
00269 {
00270 Relation r;
00271 Size freespace;
00272
00273 GISTInsertStack *stack;
00274 } GISTInsertState;
00275
00276
00277 #define GIST_ROOT_BLKNO 0
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300 #define TUPLE_IS_VALID 0xffff
00301 #define TUPLE_IS_INVALID 0xfffe
00302
00303 #define GistTupleIsInvalid(itup) ( ItemPointerGetOffsetNumber( &((itup)->t_tid) ) == TUPLE_IS_INVALID )
00304 #define GistTupleSetValid(itup) ItemPointerSetOffsetNumber( &((itup)->t_tid), TUPLE_IS_VALID )
00305
00306
00307
00308
00309
00310
00311
00312
00313 typedef struct
00314 {
00315 BlockNumber nodeBlocknum;
00316 int32 blocksCount;
00317
00318 BlockNumber pageBlocknum;
00319 GISTNodeBufferPage *pageBuffer;
00320
00321
00322 bool queuedForEmptying;
00323
00324
00325 bool isTemp;
00326
00327 int level;
00328 } GISTNodeBuffer;
00329
00330
00331
00332
00333
00334 #define LEVEL_HAS_BUFFERS(nlevel, gfbb) \
00335 ((nlevel) != 0 && (nlevel) % (gfbb)->levelStep == 0 && \
00336 (nlevel) != (gfbb)->rootlevel)
00337
00338
00339 #define BUFFER_HALF_FILLED(nodeBuffer, gfbb) \
00340 ((nodeBuffer)->blocksCount > (gfbb)->pagesPerBuffer / 2)
00341
00342
00343
00344
00345
00346
00347 #define BUFFER_OVERFLOWED(nodeBuffer, gfbb) \
00348 ((nodeBuffer)->blocksCount > (gfbb)->pagesPerBuffer)
00349
00350
00351
00352
00353 typedef struct GISTBuildBuffers
00354 {
00355
00356 MemoryContext context;
00357
00358 BufFile *pfile;
00359 long nFileBlocks;
00360
00361
00362
00363
00364 long *freeBlocks;
00365 int nFreeBlocks;
00366 int freeBlocksLen;
00367
00368
00369 HTAB *nodeBuffersTab;
00370
00371
00372 List *bufferEmptyingQueue;
00373
00374
00375
00376
00377
00378
00379 int levelStep;
00380 int pagesPerBuffer;
00381
00382
00383 List **buffersOnLevels;
00384 int buffersOnLevelsLen;
00385
00386
00387
00388
00389
00390 GISTNodeBuffer **loadedBuffers;
00391 int loadedBuffersCount;
00392 int loadedBuffersLen;
00393
00394
00395 int rootlevel;
00396 } GISTBuildBuffers;
00397
00398
00399
00400
00401 typedef struct GiSTOptions
00402 {
00403 int32 vl_len_;
00404 int fillfactor;
00405 int bufferingModeOffset;
00406 } GiSTOptions;
00407
00408
00409 extern Datum gistbuildempty(PG_FUNCTION_ARGS);
00410 extern Datum gistinsert(PG_FUNCTION_ARGS);
00411 extern MemoryContext createTempGistContext(void);
00412 extern GISTSTATE *initGISTstate(Relation index);
00413 extern void freeGISTstate(GISTSTATE *giststate);
00414 extern void gistdoinsert(Relation r,
00415 IndexTuple itup,
00416 Size freespace,
00417 GISTSTATE *GISTstate);
00418
00419
00420 typedef struct
00421 {
00422 Buffer buf;
00423 IndexTuple downlink;
00424 } GISTPageSplitInfo;
00425
00426 extern bool gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate,
00427 Buffer buffer,
00428 IndexTuple *itup, int ntup,
00429 OffsetNumber oldoffnum, BlockNumber *newblkno,
00430 Buffer leftchildbuf,
00431 List **splitinfo,
00432 bool markleftchild);
00433
00434 extern SplitedPageLayout *gistSplit(Relation r, Page page, IndexTuple *itup,
00435 int len, GISTSTATE *giststate);
00436
00437
00438 extern void gist_redo(XLogRecPtr lsn, XLogRecord *record);
00439 extern void gist_desc(StringInfo buf, uint8 xl_info, char *rec);
00440 extern void gist_xlog_startup(void);
00441 extern void gist_xlog_cleanup(void);
00442
00443 extern XLogRecPtr gistXLogUpdate(RelFileNode node, Buffer buffer,
00444 OffsetNumber *todelete, int ntodelete,
00445 IndexTuple *itup, int ntup,
00446 Buffer leftchild);
00447
00448 extern XLogRecPtr gistXLogSplit(RelFileNode node,
00449 BlockNumber blkno, bool page_is_leaf,
00450 SplitedPageLayout *dist,
00451 BlockNumber origrlink, GistNSN oldnsn,
00452 Buffer leftchild, bool markfollowright);
00453
00454
00455 extern Datum gistgettuple(PG_FUNCTION_ARGS);
00456 extern Datum gistgetbitmap(PG_FUNCTION_ARGS);
00457
00458
00459
00460 #define GiSTPageSize \
00461 ( BLCKSZ - SizeOfPageHeaderData - MAXALIGN(sizeof(GISTPageOpaqueData)) )
00462
00463 #define GIST_MIN_FILLFACTOR 10
00464 #define GIST_DEFAULT_FILLFACTOR 90
00465
00466 extern Datum gistoptions(PG_FUNCTION_ARGS);
00467 extern bool gistfitpage(IndexTuple *itvec, int len);
00468 extern bool gistnospace(Page page, IndexTuple *itvec, int len, OffsetNumber todelete, Size freespace);
00469 extern void gistcheckpage(Relation rel, Buffer buf);
00470 extern Buffer gistNewBuffer(Relation r);
00471 extern void gistfillbuffer(Page page, IndexTuple *itup, int len,
00472 OffsetNumber off);
00473 extern IndexTuple *gistextractpage(Page page, int *len );
00474 extern IndexTuple *gistjoinvector(
00475 IndexTuple *itvec, int *len,
00476 IndexTuple *additvec, int addlen);
00477 extern IndexTupleData *gistfillitupvec(IndexTuple *vec, int veclen, int *memlen);
00478
00479 extern IndexTuple gistunion(Relation r, IndexTuple *itvec,
00480 int len, GISTSTATE *giststate);
00481 extern IndexTuple gistgetadjusted(Relation r,
00482 IndexTuple oldtup,
00483 IndexTuple addtup,
00484 GISTSTATE *giststate);
00485 extern IndexTuple gistFormTuple(GISTSTATE *giststate,
00486 Relation r, Datum *attdata, bool *isnull, bool newValues);
00487
00488 extern OffsetNumber gistchoose(Relation r, Page p,
00489 IndexTuple it,
00490 GISTSTATE *giststate);
00491 extern void gistcentryinit(GISTSTATE *giststate, int nkey,
00492 GISTENTRY *e, Datum k,
00493 Relation r, Page pg,
00494 OffsetNumber o, bool l, bool isNull);
00495
00496 extern void GISTInitBuffer(Buffer b, uint32 f);
00497 extern void gistdentryinit(GISTSTATE *giststate, int nkey, GISTENTRY *e,
00498 Datum k, Relation r, Page pg, OffsetNumber o,
00499 bool l, bool isNull);
00500
00501 extern float gistpenalty(GISTSTATE *giststate, int attno,
00502 GISTENTRY *key1, bool isNull1,
00503 GISTENTRY *key2, bool isNull2);
00504 extern void gistMakeUnionItVec(GISTSTATE *giststate, IndexTuple *itvec, int len,
00505 Datum *attr, bool *isnull);
00506 extern bool gistKeyIsEQ(GISTSTATE *giststate, int attno, Datum a, Datum b);
00507 extern void gistDeCompressAtt(GISTSTATE *giststate, Relation r, IndexTuple tuple, Page p,
00508 OffsetNumber o, GISTENTRY *attdata, bool *isnull);
00509
00510 extern void gistMakeUnionKey(GISTSTATE *giststate, int attno,
00511 GISTENTRY *entry1, bool isnull1,
00512 GISTENTRY *entry2, bool isnull2,
00513 Datum *dst, bool *dstisnull);
00514
00515 extern XLogRecPtr gistGetFakeLSN(Relation rel);
00516
00517
00518 extern Datum gistbulkdelete(PG_FUNCTION_ARGS);
00519 extern Datum gistvacuumcleanup(PG_FUNCTION_ARGS);
00520
00521
00522 extern void gistSplitByKey(Relation r, Page page, IndexTuple *itup,
00523 int len, GISTSTATE *giststate,
00524 GistSplitVector *v,
00525 int attno);
00526
00527
00528 extern Datum gistbuild(PG_FUNCTION_ARGS);
00529 extern void gistValidateBufferingOption(char *value);
00530
00531
00532 extern GISTBuildBuffers *gistInitBuildBuffers(int pagesPerBuffer, int levelStep,
00533 int maxLevel);
00534 extern GISTNodeBuffer *gistGetNodeBuffer(GISTBuildBuffers *gfbb,
00535 GISTSTATE *giststate,
00536 BlockNumber blkno, int level);
00537 extern void gistPushItupToNodeBuffer(GISTBuildBuffers *gfbb,
00538 GISTNodeBuffer *nodeBuffer, IndexTuple item);
00539 extern bool gistPopItupFromNodeBuffer(GISTBuildBuffers *gfbb,
00540 GISTNodeBuffer *nodeBuffer, IndexTuple *item);
00541 extern void gistFreeBuildBuffers(GISTBuildBuffers *gfbb);
00542 extern void gistRelocateBuildBuffersOnSplit(GISTBuildBuffers *gfbb,
00543 GISTSTATE *giststate, Relation r,
00544 int level, Buffer buffer,
00545 List *splitinfo);
00546 extern void gistUnloadNodeBuffers(GISTBuildBuffers *gfbb);
00547
00548 #endif