|
| 1 | +/*------------------------------------------------------------------------- |
| 2 | + * |
| 3 | + * gist.h-- |
| 4 | + * common declarations for the GiST access method code. |
| 5 | + * |
| 6 | + * |
| 7 | + * |
| 8 | + * |
| 9 | + * |
| 10 | + *------------------------------------------------------------------------- |
| 11 | + */ |
| 12 | +#ifndefGIST_H |
| 13 | +#defineGIST_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 | +#defineGISTNStrategies100 |
| 26 | + |
| 27 | +/* |
| 28 | +** Helper routines |
| 29 | +*/ |
| 30 | +#defineGISTNProcs8 |
| 31 | +#defineGIST_CONSISTENT_PROC1 |
| 32 | +#defineGIST_UNION_PROC2 |
| 33 | +#defineGIST_COMPRESS_PROC3 |
| 34 | +#defineGIST_DECOMPRESS_PROC4 |
| 35 | +#defineGIST_PENALTY_PROC5 |
| 36 | +#defineGIST_PICKSPLIT_PROC6 |
| 37 | +#defineGIST_EQUAL_PROC 7 |
| 38 | +#defineGIST_INFO_PROC8 |
| 39 | + |
| 40 | +#defineF_LEAF(1 << 0) |
| 41 | + |
| 42 | +typedefstructGISTPageOpaqueData { |
| 43 | +uint32flags; |
| 44 | +}GISTPageOpaqueData; |
| 45 | + |
| 46 | +typedefGISTPageOpaqueData*GISTPageOpaque; |
| 47 | + |
| 48 | +#defineGIST_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 | +typedefstructGISTSTACK { |
| 55 | +structGISTSTACK*gs_parent; |
| 56 | +OffsetNumbergs_child; |
| 57 | +BlockNumbergs_blk; |
| 58 | +}GISTSTACK; |
| 59 | + |
| 60 | +typedefstructGISTSTATE { |
| 61 | +func_ptrconsistentFn; |
| 62 | +func_ptrunionFn; |
| 63 | +func_ptrcompressFn; |
| 64 | +func_ptrdecompressFn; |
| 65 | +func_ptrpenaltyFn; |
| 66 | +func_ptrpicksplitFn; |
| 67 | +func_ptrequalFn; |
| 68 | +boolhaskeytype; |
| 69 | +boolkeytypbyval; |
| 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 | +typedefstructGISTScanOpaqueData { |
| 79 | +structGISTSTACK*s_stack; |
| 80 | +structGISTSTACK*s_markstk; |
| 81 | +uint16s_flags; |
| 82 | +structGISTSTATE*giststate; |
| 83 | +}GISTScanOpaqueData; |
| 84 | + |
| 85 | +typedefGISTScanOpaqueData*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 | +#defineGS_CURBEFORE((uint16) (1 << 0)) |
| 95 | +#defineGS_MRKBEFORE((uint16) (1 << 1)) |
| 96 | + |
| 97 | +/* root page of a gist */ |
| 98 | +#defineGISTP_ROOT0 |
| 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 | +#defineGISTOP_DEL0 |
| 110 | +#defineGISTOP_SPLIT1 |
| 111 | + |
| 112 | +/* |
| 113 | +** This is the Split Vector to be returned by the PickSplit method. |
| 114 | +*/ |
| 115 | +typedefstructGIST_SPLITVEC { |
| 116 | +OffsetNumber*spl_left;/* array of entries that go left */ |
| 117 | +intspl_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 | +intspl_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 | +typedefstructGISTENTRY { |
| 131 | +char*pred; |
| 132 | +Relationrel; |
| 133 | +Pagepage; |
| 134 | +OffsetNumberoffset; |
| 135 | +intbytes; |
| 136 | +boolleafkey; |
| 137 | +}GISTENTRY; |
| 138 | + |
| 139 | +/* |
| 140 | +** macro to initialize a GISTENTRY |
| 141 | +*/ |
| 142 | +#definegistentryinit(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 | +externvoidgistfreestack(GISTSTACK*s); |
| 147 | +externvoidinitGISTstate(GISTSTATE*giststate,Relationindex); |
| 148 | +externvoidgistdentryinit(GISTSTATE*giststate,GISTENTRY*e,char*pr, |
| 149 | +Relationr,Pagepg,OffsetNumbero,intb,booll) ; |
| 150 | +externvoidgistcentryinit(GISTSTATE*giststate,GISTENTRY*e,char*pr, |
| 151 | +Relationr,Pagepg,OffsetNumbero,intb,booll) ; |
| 152 | +#endif/* GIST_H */ |