1 /*-------------------------------------------------------------------------
4 * private declarations for GiST -- declarations related to the
5 * internal implementation of GiST, not the public API
7 * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
8 * Portions Copyright (c) 1994, Regents of the University of California
10 * $PostgreSQL: pgsql/src/include/access/gist_private.h,v 1.4 2005/06/20 10:29:36 teodor Exp $
12 *-------------------------------------------------------------------------
14 #ifndef GIST_PRIVATE_H
15 #define GIST_PRIVATE_H
17 #include "access/itup.h"
18 #include "access/gist.h"
19 #include "access/xlog.h"
20 #include "access/xlogdefs.h"
24 * When we descend a tree, we keep a stack of parent pointers. This
25 * allows us to follow a chain of internal node points until we reach
26 * a leaf node, and then back up the stack to re-examine the internal
29 * 'parent' is the previous stack entry -- i.e. the node we arrived
30 * from. 'block' is the node's block number. 'offset' is the offset in
31 * the node's page that we stopped at (i.e. we followed the child
32 * pointer located at the specified offset).
34 typedef struct GISTSTACK
36 struct GISTSTACK *parent;
41 typedef struct GISTSTATE
43 FmgrInfo consistentFn[INDEX_MAX_KEYS];
44 FmgrInfo unionFn[INDEX_MAX_KEYS];
45 FmgrInfo compressFn[INDEX_MAX_KEYS];
46 FmgrInfo decompressFn[INDEX_MAX_KEYS];
47 FmgrInfo penaltyFn[INDEX_MAX_KEYS];
48 FmgrInfo picksplitFn[INDEX_MAX_KEYS];
49 FmgrInfo equalFn[INDEX_MAX_KEYS];
55 * When we're doing a scan, we need to keep track of the parent stack
56 * for the marked and current items.
58 typedef struct GISTScanOpaqueData
64 MemoryContext tempCxt;
69 typedef GISTScanOpaqueData *GISTScanOpaque;
72 * GISTInsertStack used for locking buffers and transfer arguments during
76 typedef struct GISTInsertStack {
83 OffsetNumber childoffnum;
85 /* pointer to parent */
86 struct GISTInsertStack *parent;
93 IndexTuple *itup; /* in/out, points to compressed entry */
94 int ituplen; /* length of itup */
95 GISTInsertStack *stack;
96 bool needInsertComplete;
98 /* pointer to heap tuple */
101 /* path to stroe in XLog */
107 * When we're doing a scan and updating a tree at the same time, the
108 * updates may affect the scan. We use the flags entry of the scan's
109 * opaque space to record our actual position in response to updates
110 * that we can't handle simply by adjusting pointers.
112 #define GS_CURBEFORE ((uint16) (1 << 0))
113 #define GS_MRKBEFORE ((uint16) (1 << 1))
115 /* root page of a gist index */
116 #define GIST_ROOT_BLKNO 0
119 * When we update a relation on which we're doing a scan, we need to
120 * check the scan and fix it if the update affected any of the pages
121 * it touches. Otherwise, we can miss records that we should see.
122 * The only times we need to do this are for deletions and splits. See
123 * the code in gistscan.c for how the scan is fixed. These two
124 * constants tell us what sort of operation changed the index.
127 #define GISTOP_SPLIT 1
129 #define ATTSIZE(datum, tupdesc, i, isnull) \
132 att_addlength(0, (tupdesc)->attrs[(i)-1]->attlen, (datum)) \
136 #define XLOG_GIST_ENTRY_UPDATE 0x00
137 #define XLOG_GIST_ENTRY_DELETE 0x10
138 #define XLOG_GIST_NEW_ROOT 0x20
140 typedef struct gistxlogEntryUpdate {
149 * It used to identify completeness of insert.
155 * 1. path to root (BlockNumber)
156 * 2. todelete OffsetNumbers
157 * 3. tuples to insert
159 } gistxlogEntryUpdate;
161 #define XLOG_GIST_PAGE_SPLIT 0x30
163 typedef struct gistxlogPageSplit {
165 BlockNumber origblkno; /*splitted page*/
171 /* see comments on gistxlogEntryUpdate */
175 * 1. path to root (BlockNumber)
176 * 2. todelete OffsetNumbers
177 * 3. tuples to insert
178 * 4. gistxlogPage and array of OffsetNumber per page
182 typedef struct gistxlogPage {
188 #define XLOG_GIST_INSERT_COMPLETE 0x40
190 typedef struct gistxlogInsertComplete {
192 /* follows ItemPointerData key to clean */
193 } gistxlogInsertComplete;
195 #define XLOG_GIST_CREATE_INDEX 0x50
198 * mark tuples on inner pages during recovery
200 #define TUPLE_IS_VALID 0xffff
201 #define TUPLE_IS_INVALID 0xfffe
203 #define GistTupleIsInvalid(itup) ( ItemPointerGetOffsetNumber( &((itup)->t_tid) ) == TUPLE_IS_INVALID )
204 #define GistTupleSetValid(itup) ItemPointerSetOffsetNumber( &((itup)->t_tid), TUPLE_IS_VALID )
205 #define GistTupleSetInvalid(itup) ItemPointerSetOffsetNumber( &((itup)->t_tid), TUPLE_IS_INVALID )
208 extern Datum gistbuild(PG_FUNCTION_ARGS);
209 extern Datum gistinsert(PG_FUNCTION_ARGS);
210 extern MemoryContext createTempGistContext(void);
211 extern void initGISTstate(GISTSTATE *giststate, Relation index);
212 extern void freeGISTstate(GISTSTATE *giststate);
213 extern void gistnewroot(Relation r, IndexTuple *itup, int len, ItemPointer key);
214 extern void gistmakedeal(GISTInsertState *state, GISTSTATE *giststate);
216 typedef struct SplitedPageLayout {
219 Buffer buffer; /* to write after all proceed */
221 struct SplitedPageLayout *next;
224 IndexTuple * gistSplit(Relation r, Buffer buffer, IndexTuple *itup,
225 int *len, SplitedPageLayout **dist, GISTSTATE *giststate);
227 extern void gist_redo(XLogRecPtr lsn, XLogRecord *record);
228 extern void gist_desc(char *buf, uint8 xl_info, char *rec);
229 extern void gist_xlog_startup(void);
230 extern void gist_xlog_cleanup(void);
231 extern IndexTuple gist_form_invalid_tuple(BlockNumber blkno);
233 extern XLogRecData* formUpdateRdata(RelFileNode node, BlockNumber blkno,
234 OffsetNumber *todelete, int ntodelete, bool emptypage,
235 IndexTuple *itup, int ituplen, ItemPointer key,
236 BlockNumber *path, int pathlen);
238 extern XLogRecData* formSplitRdata(RelFileNode node, BlockNumber blkno,
239 OffsetNumber *todelete, int ntodelete,
240 IndexTuple *itup, int ituplen, ItemPointer key,
241 BlockNumber *path, int pathlen, SplitedPageLayout *dist );
243 extern XLogRecPtr gistxlogInsertCompletion(RelFileNode node, ItemPointerData *keys, int len);
246 extern Datum gistgettuple(PG_FUNCTION_ARGS);
247 extern Datum gistgetmulti(PG_FUNCTION_ARGS);
250 extern Buffer gistReadBuffer(Relation r, BlockNumber blkno);
251 extern OffsetNumber gistfillbuffer(Relation r, Page page, IndexTuple *itup,
252 int len, OffsetNumber off);
253 extern bool gistnospace(Page page, IndexTuple *itvec, int len);
254 extern IndexTuple * gistextractbuffer(Buffer buffer, int *len /* out */ );
255 extern IndexTuple * gistjoinvector(
256 IndexTuple *itvec, int *len,
257 IndexTuple *additvec, int addlen);
258 extern IndexTuple gistunion(Relation r, IndexTuple *itvec,
259 int len, GISTSTATE *giststate);
260 extern IndexTuple gistgetadjusted(Relation r,
263 GISTSTATE *giststate);
264 extern int gistfindgroup(GISTSTATE *giststate,
265 GISTENTRY *valvec, GIST_SPLITVEC *spl);
266 extern void gistadjsubkey(Relation r,
267 IndexTuple *itup, int len,
269 GISTSTATE *giststate);
270 extern IndexTuple gistFormTuple(GISTSTATE *giststate,
271 Relation r, Datum *attdata, int *datumsize, bool *isnull);
273 extern OffsetNumber gistchoose(Relation r, Page p,
275 GISTSTATE *giststate);
276 extern void gistcentryinit(GISTSTATE *giststate, int nkey,
277 GISTENTRY *e, Datum k,
279 OffsetNumber o, int b, bool l, bool isNull);
280 extern void gistDeCompressAtt(GISTSTATE *giststate, Relation r,
281 IndexTuple tuple, Page p, OffsetNumber o,
282 GISTENTRY *attdata, bool *isnull);
283 extern void gistunionsubkey(Relation r, GISTSTATE *giststate,
284 IndexTuple *itvec, GIST_SPLITVEC *spl, bool isall);
285 extern void GISTInitBuffer(Buffer b, uint32 f);
286 extern void gistdentryinit(GISTSTATE *giststate, int nkey, GISTENTRY *e,
287 Datum k, Relation r, Page pg, OffsetNumber o,
288 int b, bool l, bool isNull);
289 void gistUserPicksplit(Relation r, GistEntryVector *entryvec, GIST_SPLITVEC *v,
290 IndexTuple *itup, int len, GISTSTATE *giststate);
293 extern Datum gistbulkdelete(PG_FUNCTION_ARGS);
294 extern Datum gistvacuumcleanup(PG_FUNCTION_ARGS);
296 #endif /* GIST_PRIVATE_H */