|
| 1 | +/*------------------------------------------------------------------------- |
| 2 | + * |
| 3 | + * gist.h-- |
| 4 | + * common declarations for the GiST access method code. |
| 5 | + * |
| 6 | + * |
| 7 | + * |
| 8 | + * |
| 9 | + * |
| 10 | + *------------------------------------------------------------------------- |
| 11 | + */ |
| 12 | +#ifndef GIST_H |
| 13 | +#define GIST_H |
| 14 | + |
| 15 | +#include "utils/rel.h" |
| 16 | +#include "storage/off.h" |
| 17 | +#include "storage/block.h" |
| 18 | +#include "storage/bufpage.h" |
| 19 | +#include "access/skey.h" |
| 20 | + |
| 21 | +/* |
| 22 | +** You can have as many strategies as you please in GiSTs, as |
| 23 | +** long as your consistent method can handle them |
| 24 | +*/ |
| 25 | +#define GISTNStrategies 100 |
| 26 | + |
| 27 | +/* |
| 28 | +** Helper routines |
| 29 | +*/ |
| 30 | +#define GISTNProcs 8 |
| 31 | +#define GIST_CONSISTENT_PROC 1 |
| 32 | +#define GIST_UNION_PROC 2 |
| 33 | +#define GIST_COMPRESS_PROC 3 |
| 34 | +#define GIST_DECOMPRESS_PROC 4 |
| 35 | +#define GIST_PENALTY_PROC 5 |
| 36 | +#define GIST_PICKSPLIT_PROC 6 |
| 37 | +#define GIST_EQUAL_PROC 7 |
| 38 | +#define GIST_INFO_PROC 8 |
| 39 | + |
| 40 | +#define F_LEAF (1 << 0) |
| 41 | + |
| 42 | +typedef struct GISTPageOpaqueData { |
| 43 | + uint32 flags; |
| 44 | +} GISTPageOpaqueData; |
| 45 | + |
| 46 | +typedef GISTPageOpaqueData *GISTPageOpaque; |
| 47 | + |
| 48 | +#define GIST_LEAF(entry) (((GISTPageOpaque) PageGetSpecialPointer((entry)->page))->flags & F_LEAF) |
| 49 | + |
| 50 | +/* |
| 51 | + * When we descend a tree, we keep a stack of parent pointers. |
| 52 | + */ |
| 53 | + |
| 54 | +typedef struct GISTSTACK { |
| 55 | + struct GISTSTACK *gs_parent; |
| 56 | + OffsetNumber gs_child; |
| 57 | + BlockNumber gs_blk; |
| 58 | +} GISTSTACK; |
| 59 | + |
| 60 | +typedef struct GISTSTATE { |
| 61 | + func_ptr consistentFn; |
| 62 | + func_ptr unionFn; |
| 63 | + func_ptr compressFn; |
| 64 | + func_ptr decompressFn; |
| 65 | + func_ptr penaltyFn; |
| 66 | + func_ptr picksplitFn; |
| 67 | + func_ptr equalFn; |
| 68 | + bool haskeytype; |
| 69 | + bool keytypbyval; |
| 70 | +} GISTSTATE; |
| 71 | + |
| 72 | + |
| 73 | +/* |
| 74 | +** When we're doing a scan, we need to keep track of the parent stack |
| 75 | +** for the marked and current items. |
| 76 | +*/ |
| 77 | + |
| 78 | +typedef struct GISTScanOpaqueData { |
| 79 | + struct GISTSTACK *s_stack; |
| 80 | + struct GISTSTACK *s_markstk; |
| 81 | + uint16 s_flags; |
| 82 | + struct GISTSTATE *giststate; |
| 83 | +} GISTScanOpaqueData; |
| 84 | + |
| 85 | +typedef GISTScanOpaqueData *GISTScanOpaque; |
| 86 | + |
| 87 | +/* |
| 88 | +** When we're doing a scan and updating a tree at the same time, the |
| 89 | +** updates may affect the scan. We use the flags entry of the scan's |
| 90 | +** opaque space to record our actual position in response to updates |
| 91 | +** that we can't handle simply by adjusting pointers. |
| 92 | +*/ |
| 93 | + |
| 94 | +#define GS_CURBEFORE ((uint16) (1 << 0)) |
| 95 | +#define GS_MRKBEFORE ((uint16) (1 << 1)) |
| 96 | + |
| 97 | +/* root page of a gist */ |
| 98 | +#define GISTP_ROOT 0 |
| 99 | + |
| 100 | +/* |
| 101 | +** When we update a relation on which we're doing a scan, we need to |
| 102 | +** check the scan and fix it if the update affected any of the pages it |
| 103 | +** touches. Otherwise, we can miss records that we should see. The only |
| 104 | +** times we need to do this are for deletions and splits. See the code in |
| 105 | +** gistscan.c for how the scan is fixed. These two constants tell us what sort |
| 106 | +** of operation changed the index. |
| 107 | +*/ |
| 108 | + |
| 109 | +#define GISTOP_DEL 0 |
| 110 | +#define GISTOP_SPLIT 1 |
| 111 | + |
| 112 | +/* |
| 113 | +** This is the Split Vector to be returned by the PickSplit method. |
| 114 | +*/ |
| 115 | +typedef struct GIST_SPLITVEC { |
| 116 | + OffsetNumber *spl_left; /* array of entries that go left */ |
| 117 | + int spl_nleft; /* size of this array */ |
| 118 | + char *spl_ldatum; /* Union of keys in spl_left */ |
| 119 | + OffsetNumber *spl_right; /* array of entries that go right */ |
| 120 | + int spl_nright; /* size of the array */ |
| 121 | + char *spl_rdatum; /* Union of keys in spl_right */ |
| 122 | +} GIST_SPLITVEC; |
| 123 | + |
| 124 | +/* |
| 125 | +** An entry on a GiST node. Contains the key (pred), as well as |
| 126 | +** its own location (rel,page,offset) which can supply the matching |
| 127 | +** pointer. The size of the pred is in bytes, and leafkey is a flag to |
| 128 | +** tell us if the entry is in a leaf node. |
| 129 | +*/ |
| 130 | +typedef struct GISTENTRY { |
| 131 | + char *pred; |
| 132 | + Relation rel; |
| 133 | + Page page; |
| 134 | + OffsetNumber offset; |
| 135 | + int bytes; |
| 136 | + bool leafkey; |
| 137 | +} GISTENTRY; |
| 138 | + |
| 139 | +/* |
| 140 | +** macro to initialize a GISTENTRY |
| 141 | +*/ |
| 142 | +#define gistentryinit(e, pr, r, pg, o, b, l)\ |
| 143 | + {(e).pred = pr; (e).rel = r; (e).page = pg; (e).offset = o; (e).bytes = b; (e).leafkey = l;} |
| 144 | + |
| 145 | +/* defined in gist.c */ |
| 146 | +extern void gistfreestack(GISTSTACK *s); |
| 147 | +extern void initGISTstate(GISTSTATE *giststate, Relation index); |
| 148 | +extern void gistdentryinit(GISTSTATE *giststate, GISTENTRY *e, char *pr, |
| 149 | + Relation r, Page pg, OffsetNumber o, int b, bool l) ; |
| 150 | +extern void gistcentryinit(GISTSTATE *giststate, GISTENTRY *e, char *pr, |
| 151 | + Relation r, Page pg, OffsetNumber o, int b, bool l) ; |
| 152 | +#endif /* GIST_H */ |
0 commit comments