OSDN Git Service

rebuid:
[eos/hostdependX86MAC64.git] / util / X86MAC64 / include / postgresql / server / access / gist.h
1 /*-------------------------------------------------------------------------
2  *
3  * gist.h
4  *        The public API for GiST indexes. This API is exposed to
5  *        individuals implementing GiST indexes, so backward-incompatible
6  *        changes should be made with care.
7  *
8  *
9  * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
10  * Portions Copyright (c) 1994, Regents of the University of California
11  *
12  * src/include/access/gist.h
13  *
14  *-------------------------------------------------------------------------
15  */
16 #ifndef GIST_H
17 #define GIST_H
18
19 #include "access/xlog.h"
20 #include "access/xlogdefs.h"
21 #include "storage/block.h"
22 #include "storage/bufpage.h"
23 #include "utils/relcache.h"
24
25 /*
26  * amproc indexes for GiST indexes.
27  */
28 #define GIST_CONSISTENT_PROC                    1
29 #define GIST_UNION_PROC                                 2
30 #define GIST_COMPRESS_PROC                              3
31 #define GIST_DECOMPRESS_PROC                    4
32 #define GIST_PENALTY_PROC                               5
33 #define GIST_PICKSPLIT_PROC                             6
34 #define GIST_EQUAL_PROC                                 7
35 #define GIST_DISTANCE_PROC                              8
36 #define GISTNProcs                                              8
37
38 /*
39  * strategy numbers for GiST opclasses that want to implement the old
40  * RTREE behavior.
41  */
42 #define RTLeftStrategyNumber                    1
43 #define RTOverLeftStrategyNumber                2
44 #define RTOverlapStrategyNumber                 3
45 #define RTOverRightStrategyNumber               4
46 #define RTRightStrategyNumber                   5
47 #define RTSameStrategyNumber                    6
48 #define RTContainsStrategyNumber                7               /* for @> */
49 #define RTContainedByStrategyNumber             8               /* for <@ */
50 #define RTOverBelowStrategyNumber               9
51 #define RTBelowStrategyNumber                   10
52 #define RTAboveStrategyNumber                   11
53 #define RTOverAboveStrategyNumber               12
54 #define RTOldContainsStrategyNumber             13              /* for old spelling of @> */
55 #define RTOldContainedByStrategyNumber  14              /* for old spelling of <@ */
56 #define RTKNNSearchStrategyNumber               15
57
58 /*
59  * Page opaque data in a GiST index page.
60  */
61 #define F_LEAF                          (1 << 0)        /* leaf page */
62 #define F_DELETED                       (1 << 1)        /* the page has been deleted */
63 #define F_TUPLES_DELETED        (1 << 2)        /* some tuples on the page are dead */
64 #define F_FOLLOW_RIGHT          (1 << 3)        /* page to the right has no downlink */
65
66 typedef XLogRecPtr GistNSN;
67
68 /*
69  * For on-disk compatibility with pre-9.3 servers, NSN is stored as two
70  * 32-bit fields on disk, same as LSNs.
71  */
72 typedef PageXLogRecPtr PageGistNSN;
73
74 typedef struct GISTPageOpaqueData
75 {
76         PageGistNSN nsn;                        /* this value must change on page split */
77         BlockNumber rightlink;          /* next page if any */
78         uint16          flags;                  /* see bit definitions above */
79         uint16          gist_page_id;   /* for identification of GiST indexes */
80 } GISTPageOpaqueData;
81
82 typedef GISTPageOpaqueData *GISTPageOpaque;
83
84 /*
85  * The page ID is for the convenience of pg_filedump and similar utilities,
86  * which otherwise would have a hard time telling pages of different index
87  * types apart.  It should be the last 2 bytes on the page.  This is more or
88  * less "free" due to alignment considerations.
89  */
90 #define GIST_PAGE_ID            0xFF81
91
92 /*
93  * This is the Split Vector to be returned by the PickSplit method.
94  * PickSplit should fill the indexes of tuples to go to the left side into
95  * spl_left[], and those to go to the right into spl_right[] (note the method
96  * is responsible for palloc'ing both of these arrays!).  The tuple counts
97  * go into spl_nleft/spl_nright, and spl_ldatum/spl_rdatum must be set to
98  * the union keys for each side.
99  *
100  * If spl_ldatum_exists and spl_rdatum_exists are true, then we are performing
101  * a "secondary split" using a non-first index column.  In this case some
102  * decisions have already been made about a page split, and the set of tuples
103  * being passed to PickSplit is just the tuples about which we are undecided.
104  * spl_ldatum/spl_rdatum then contain the union keys for the tuples already
105  * chosen to go left or right.  Ideally the PickSplit method should take those
106  * keys into account while deciding what to do with the remaining tuples, ie
107  * it should try to "build out" from those unions so as to minimally expand
108  * them.  If it does so, it should union the given tuples' keys into the
109  * existing spl_ldatum/spl_rdatum values rather than just setting those values
110  * from scratch, and then set spl_ldatum_exists/spl_rdatum_exists to false to
111  * show it has done this.
112  *
113  * If the PickSplit method fails to clear spl_ldatum_exists/spl_rdatum_exists,
114  * the core GiST code will make its own decision about how to merge the
115  * secondary-split results with the previously-chosen tuples, and will then
116  * recompute the union keys from scratch.  This is a workable though often not
117  * optimal approach.
118  */
119 typedef struct GIST_SPLITVEC
120 {
121         OffsetNumber *spl_left;         /* array of entries that go left */
122         int                     spl_nleft;              /* size of this array */
123         Datum           spl_ldatum;             /* Union of keys in spl_left */
124         bool            spl_ldatum_exists;              /* true, if spl_ldatum already exists. */
125
126         OffsetNumber *spl_right;        /* array of entries that go right */
127         int                     spl_nright;             /* size of the array */
128         Datum           spl_rdatum;             /* Union of keys in spl_right */
129         bool            spl_rdatum_exists;              /* true, if spl_rdatum already exists. */
130 } GIST_SPLITVEC;
131
132 /*
133  * An entry on a GiST node.  Contains the key, as well as its own
134  * location (rel,page,offset) which can supply the matching pointer.
135  * leafkey is a flag to tell us if the entry is in a leaf node.
136  */
137 typedef struct GISTENTRY
138 {
139         Datum           key;
140         Relation        rel;
141         Page            page;
142         OffsetNumber offset;
143         bool            leafkey;
144 } GISTENTRY;
145
146 #define GistPageGetOpaque(page) ( (GISTPageOpaque) PageGetSpecialPointer(page) )
147
148 #define GistPageIsLeaf(page)    ( GistPageGetOpaque(page)->flags & F_LEAF)
149 #define GIST_LEAF(entry) (GistPageIsLeaf((entry)->page))
150 #define GistPageSetLeaf(page)   ( GistPageGetOpaque(page)->flags |= F_LEAF)
151 #define GistPageSetNonLeaf(page)        ( GistPageGetOpaque(page)->flags &= ~F_LEAF)
152
153 #define GistPageIsDeleted(page) ( GistPageGetOpaque(page)->flags & F_DELETED)
154 #define GistPageSetDeleted(page)        ( GistPageGetOpaque(page)->flags |= F_DELETED)
155 #define GistPageSetNonDeleted(page) ( GistPageGetOpaque(page)->flags &= ~F_DELETED)
156
157 #define GistTuplesDeleted(page) ( GistPageGetOpaque(page)->flags & F_TUPLES_DELETED)
158 #define GistMarkTuplesDeleted(page) ( GistPageGetOpaque(page)->flags |= F_TUPLES_DELETED)
159 #define GistClearTuplesDeleted(page)    ( GistPageGetOpaque(page)->flags &= ~F_TUPLES_DELETED)
160
161 #define GistFollowRight(page) ( GistPageGetOpaque(page)->flags & F_FOLLOW_RIGHT)
162 #define GistMarkFollowRight(page) ( GistPageGetOpaque(page)->flags |= F_FOLLOW_RIGHT)
163 #define GistClearFollowRight(page)      ( GistPageGetOpaque(page)->flags &= ~F_FOLLOW_RIGHT)
164
165 #define GistPageGetNSN(page) ( PageXLogRecPtrGet(GistPageGetOpaque(page)->nsn))
166 #define GistPageSetNSN(page, val) ( PageXLogRecPtrSet(GistPageGetOpaque(page)->nsn, val))
167
168 /*
169  * Vector of GISTENTRY structs; user-defined methods union and picksplit
170  * take it as one of their arguments
171  */
172 typedef struct
173 {
174         int32           n;                              /* number of elements */
175         GISTENTRY       vector[FLEXIBLE_ARRAY_MEMBER];
176 } GistEntryVector;
177
178 #define GEVHDRSZ        (offsetof(GistEntryVector, vector))
179
180 /*
181  * macro to initialize a GISTENTRY
182  */
183 #define gistentryinit(e, k, r, pg, o, l) \
184         do { (e).key = (k); (e).rel = (r); (e).page = (pg); \
185                  (e).offset = (o); (e).leafkey = (l); } while (0)
186
187 #endif   /* GIST_H */