gist.h 5.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/*-------------------------------------------------------------------------
 *
 * gist.h--
 *    common declarations for the GiST access method code.
 *
 *
 *
 * 
 *
 *-------------------------------------------------------------------------
 */
#ifndef GIST_H
#define GIST_H

15 16 17 18
#include <access/funcindex.h>
#include <access/itup.h>
#include <access/relscan.h>
#include <access/sdir.h>
M
Marc G. Fournier 已提交
19 20 21 22
#include <storage/page.h>
#include <storage/block.h>
#include <utils/rel.h>
#include <storage/off.h>
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148

/* 
** You can have as many strategies as you please in GiSTs, as
** long as your consistent method can handle them
*/
#define GISTNStrategies			100

/*
** Helper routines
*/
#define GISTNProcs			8
#define GIST_CONSISTENT_PROC		1
#define GIST_UNION_PROC			2
#define GIST_COMPRESS_PROC		3
#define GIST_DECOMPRESS_PROC		4
#define GIST_PENALTY_PROC		5
#define GIST_PICKSPLIT_PROC		6
#define GIST_EQUAL_PROC 		7
#define GIST_INFO_PROC			8

#define F_LEAF		(1 << 0)

typedef struct GISTPageOpaqueData {
	uint32		flags;
} GISTPageOpaqueData;

typedef GISTPageOpaqueData	*GISTPageOpaque;

#define GIST_LEAF(entry) (((GISTPageOpaque) PageGetSpecialPointer((entry)->page))->flags & F_LEAF)

/*
 *  When we descend a tree, we keep a stack of parent pointers.
 */

typedef struct GISTSTACK {
	struct GISTSTACK *gs_parent;
	OffsetNumber	gs_child;
	BlockNumber	gs_blk;
} GISTSTACK;

typedef struct GISTSTATE {
    func_ptr consistentFn;
    func_ptr unionFn;
    func_ptr compressFn;
    func_ptr decompressFn;
    func_ptr penaltyFn;
    func_ptr picksplitFn;
    func_ptr equalFn;
    bool     haskeytype;
    bool     keytypbyval;
} GISTSTATE;


/*
**  When we're doing a scan, we need to keep track of the parent stack
**  for the marked and current items.  
*/

typedef struct GISTScanOpaqueData {
	struct GISTSTACK	*s_stack;
	struct GISTSTACK	*s_markstk;
	uint16		s_flags;
	struct GISTSTATE        *giststate;
} GISTScanOpaqueData;

typedef GISTScanOpaqueData	*GISTScanOpaque;

/*
**  When we're doing a scan and updating a tree at the same time, the
**  updates may affect the scan.  We use the flags entry of the scan's
**  opaque space to record our actual position in response to updates
**  that we can't handle simply by adjusting pointers.
*/

#define GS_CURBEFORE	((uint16) (1 << 0))
#define GS_MRKBEFORE	((uint16) (1 << 1))

/* root page of a gist */
#define GISTP_ROOT		0

/*
**  When we update a relation on which we're doing a scan, we need to
**  check the scan and fix it if the update affected any of the pages it
**  touches.  Otherwise, we can miss records that we should see.  The only
**  times we need to do this are for deletions and splits.  See the code in
**  gistscan.c for how the scan is fixed. These two constants tell us what sort
**  of operation changed the index.
*/

#define	GISTOP_DEL	0
#define	GISTOP_SPLIT	1

/*
** This is the Split Vector to be returned by the PickSplit method.
*/
typedef struct GIST_SPLITVEC {
    OffsetNumber	*spl_left;    /* array of entries that go left */
    int			spl_nleft;    /* size of this array */
    char		*spl_ldatum;  /* Union of keys in spl_left */
    OffsetNumber	*spl_right;   /* array of entries that go right */
    int			spl_nright;   /* size of the array */
    char		*spl_rdatum;  /* Union of keys in spl_right */
} GIST_SPLITVEC;

/*
** An entry on a GiST node.  Contains the key (pred), as well as 
** its own location (rel,page,offset) which can supply the matching
** pointer.  The size of the pred is in bytes, and leafkey is a flag to
** tell us if the entry is in a leaf node.
*/
typedef struct GISTENTRY {
    char *pred;
    Relation rel;
    Page page;
    OffsetNumber offset;
    int bytes;
    bool leafkey;
} GISTENTRY;

/*
** macro to initialize a GISTENTRY
*/
#define gistentryinit(e, pr, r, pg, o, b, l)\
   {(e).pred = pr; (e).rel = r; (e).page = pg; (e).offset = o; (e).bytes = b; (e).leafkey = l;}

/* defined in gist.c */
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
#define TRLOWER(tr) (((tr)->bytes))
#define TRUPPER(tr) (&((tr)->bytes[MAXALIGN(VARSIZE(TRLOWER(tr)))]))

typedef struct txtrange {
    /* flag: NINF means that lower is negative infinity; PINF means that
    ** upper is positive infinity.  0 means that both are numbers.
    */
    int32 vl_len;
    int32 flag;  
    char bytes[2];
} TXTRANGE;

typedef struct intrange {
    int lower;
    int upper;
    /* flag: NINF means that lower is negative infinity; PINF means that
    ** upper is positive infinity.  0 means that both are numbers.
    */
    int flag;  
} INTRANGE;

extern void gistbuild(Relation heap,
	  Relation index, int natts,
	  AttrNumber *attnum, IndexStrategy istrat,
	  uint16 pint, Datum *params,
	  FuncIndexInfo *finfo,
	  PredInfo *predInfo);
extern InsertIndexResult gistinsert(Relation r, Datum *datum,
177
			char *nulls,ItemPointer ht_ctid, bool is_update);
178 179 180
extern void _gistdump(Relation r);
extern char *text_range_out(TXTRANGE *r);
extern char *int_range_out(INTRANGE *r);
181 182 183 184 185 186
extern void gistfreestack(GISTSTACK *s);
extern void initGISTstate(GISTSTATE *giststate, Relation index);
extern void gistdentryinit(GISTSTATE *giststate, GISTENTRY *e, char *pr, 
			   Relation r, Page pg, OffsetNumber o, int b, bool l) ;
extern void gistcentryinit(GISTSTATE *giststate, GISTENTRY *e, char *pr, 
			   Relation r, Page pg, OffsetNumber o, int b, bool l) ;
187
extern StrategyNumber RelationGetGISTStrategy(Relation, AttrNumber, RegProcedure);
188 189 190 191 192 193 194 195 196 197 198

/* gistget.c */
extern RetrieveIndexResult gistgettuple(IndexScanDesc s, ScanDirection dir);
extern bool gistindex_keytest(IndexTuple tuple, TupleDesc tupdesc,
		  int scanKeySize, ScanKey key, GISTSTATE *giststate,
		  Relation r, Page p, OffsetNumber offset);

/* giststrat.c */
extern bool RelationInvokeGISTStrategy(Relation r, AttrNumber attnum,
			 StrategyNumber s, Datum left, Datum right);

199
#endif /* GIST_H */