1 /*
2  * contrib/intarray/_int.h
3  */
4 #ifndef ___INT_H__
5 #define ___INT_H__
6 
7 #include "utils/array.h"
8 #include "utils/memutils.h"
9 
10 /* number ranges for compression */
11 #define G_INT_NUMRANGES_DEFAULT		100
12 #define G_INT_NUMRANGES_MAX			((GISTMaxIndexKeySize - VARHDRSZ) / \
13 									 (2 * sizeof(int32)))
14 #define G_INT_GET_NUMRANGES()		(PG_HAS_OPCLASS_OPTIONS() ? \
15 									 ((GISTIntArrayOptions *) PG_GET_OPCLASS_OPTIONS())->num_ranges : \
16 									 G_INT_NUMRANGES_DEFAULT)
17 
18 /* gist_int_ops opclass options */
19 typedef struct
20 {
21 	int32		vl_len_;		/* varlena header (do not touch directly!) */
22 	int			num_ranges;		/* number of ranges */
23 } GISTIntArrayOptions;
24 
25 /* useful macros for accessing int4 arrays */
26 #define ARRPTR(x)  ( (int32 *) ARR_DATA_PTR(x) )
27 #define ARRNELEMS(x)  ArrayGetNItems(ARR_NDIM(x), ARR_DIMS(x))
28 
29 /* reject arrays we can't handle; to wit, those containing nulls */
30 #define CHECKARRVALID(x) \
31 	do { \
32 		if (ARR_HASNULL(x) && array_contains_nulls(x)) \
33 			ereport(ERROR, \
34 					(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), \
35 					 errmsg("array must not contain nulls"))); \
36 	} while(0)
37 
38 #define ARRISEMPTY(x)  (ARRNELEMS(x) == 0)
39 
40 /* sort the elements of the array */
41 #define SORT(x) \
42 	do { \
43 		int		_nelems_ = ARRNELEMS(x); \
44 		if (_nelems_ > 1) \
45 			isort(ARRPTR(x), _nelems_); \
46 	} while(0)
47 
48 /* sort the elements of the array and remove duplicates */
49 #define PREPAREARR(x) \
50 	do { \
51 		int		_nelems_ = ARRNELEMS(x); \
52 		if (_nelems_ > 1) \
53 			if (isort(ARRPTR(x), _nelems_)) \
54 				(x) = _int_unique(x); \
55 	} while(0)
56 
57 /* "wish" function */
58 #define WISH_F(a,b,c) (double)( -(double)(((a)-(b))*((a)-(b))*((a)-(b)))*(c) )
59 
60 
61 /* bigint defines */
62 #define SIGLEN_DEFAULT		(63 * 4)
63 #define SIGLEN_MAX			GISTMaxIndexKeySize
64 #define SIGLENBIT(siglen)	((siglen) * BITS_PER_BYTE)
65 #define GET_SIGLEN()		(PG_HAS_OPCLASS_OPTIONS() ? \
66 							 ((GISTIntArrayBigOptions *) PG_GET_OPCLASS_OPTIONS())->siglen : \
67 							 SIGLEN_DEFAULT)
68 
69 typedef char *BITVECP;
70 
71 #define LOOPBYTE(siglen) \
72 			for (i = 0; i < siglen; i++)
73 
74 /* beware of multiple evaluation of arguments to these macros! */
75 #define GETBYTE(x,i) ( *( (BITVECP)(x) + (int)( (i) / BITS_PER_BYTE ) ) )
76 #define GETBITBYTE(x,i) ( (*((char*)(x)) >> (i)) & 0x01 )
77 #define CLRBIT(x,i)   GETBYTE(x,i) &= ~( 0x01 << ( (i) % BITS_PER_BYTE ) )
78 #define SETBIT(x,i)   GETBYTE(x,i) |=  ( 0x01 << ( (i) % BITS_PER_BYTE ) )
79 #define GETBIT(x,i) ( (GETBYTE(x,i) >> ( (i) % BITS_PER_BYTE )) & 0x01 )
80 #define HASHVAL(val, siglen) (((unsigned int)(val)) % SIGLENBIT(siglen))
81 #define HASH(sign, val, siglen) SETBIT((sign), HASHVAL(val, siglen))
82 
83 /* gist_intbig_ops opclass options */
84 typedef struct
85 {
86 	int32		vl_len_;		/* varlena header (do not touch directly!) */
87 	int			siglen;			/* signature length in bytes */
88 } GISTIntArrayBigOptions;
89 
90 /*
91  * type of index key
92  */
93 typedef struct
94 {
95 	int32		vl_len_;		/* varlena header (do not touch directly!) */
96 	int32		flag;
97 	char		data[FLEXIBLE_ARRAY_MEMBER];
98 } GISTTYPE;
99 
100 #define ALLISTRUE		0x04
101 
102 #define ISALLTRUE(x)	( ((GISTTYPE*)x)->flag & ALLISTRUE )
103 
104 #define GTHDRSIZE		(VARHDRSZ + sizeof(int32))
105 #define CALCGTSIZE(flag, siglen) ( GTHDRSIZE+(((flag) & ALLISTRUE) ? 0 : (siglen)) )
106 
107 #define GETSIGN(x)		( (BITVECP)( (char*)x+GTHDRSIZE ) )
108 
109 /*
110  * useful functions
111  */
112 bool		isort(int32 *a, int len);
113 ArrayType  *new_intArrayType(int num);
114 ArrayType  *copy_intArrayType(ArrayType *a);
115 ArrayType  *resize_intArrayType(ArrayType *a, int num);
116 int			internal_size(int *a, int len);
117 ArrayType  *_int_unique(ArrayType *a);
118 int32		intarray_match_first(ArrayType *a, int32 elem);
119 ArrayType  *intarray_add_elem(ArrayType *a, int32 elem);
120 ArrayType  *intarray_concat_arrays(ArrayType *a, ArrayType *b);
121 ArrayType  *int_to_intset(int32 elem);
122 bool		inner_int_overlap(ArrayType *a, ArrayType *b);
123 bool		inner_int_contains(ArrayType *a, ArrayType *b);
124 ArrayType  *inner_int_union(ArrayType *a, ArrayType *b);
125 ArrayType  *inner_int_inter(ArrayType *a, ArrayType *b);
126 void		rt__int_size(ArrayType *a, float *size);
127 void		gensign(BITVECP sign, int *a, int len, int siglen);
128 
129 
130 /*****************************************************************************
131  *			Boolean Search
132  *****************************************************************************/
133 
134 #define BooleanSearchStrategy	20
135 
136 /*
137  * item in polish notation with back link
138  * to left operand
139  */
140 typedef struct ITEM
141 {
142 	int16		type;
143 	int16		left;
144 	int32		val;
145 } ITEM;
146 
147 typedef struct QUERYTYPE
148 {
149 	int32		vl_len_;		/* varlena header (do not touch directly!) */
150 	int32		size;			/* number of ITEMs */
151 	ITEM		items[FLEXIBLE_ARRAY_MEMBER];
152 } QUERYTYPE;
153 
154 #define HDRSIZEQT	offsetof(QUERYTYPE, items)
155 #define COMPUTESIZE(size)	( HDRSIZEQT + (size) * sizeof(ITEM) )
156 #define QUERYTYPEMAXITEMS	((MaxAllocSize - HDRSIZEQT) / sizeof(ITEM))
157 #define GETQUERY(x)  ( (x)->items )
158 
159 /* "type" codes for ITEM */
160 #define END		0
161 #define ERR		1
162 #define VAL		2
163 #define OPR		3
164 #define OPEN	4
165 #define CLOSE	5
166 
167 /* fmgr macros for QUERYTYPE objects */
168 #define DatumGetQueryTypeP(X)		  ((QUERYTYPE *) PG_DETOAST_DATUM(X))
169 #define DatumGetQueryTypePCopy(X)	  ((QUERYTYPE *) PG_DETOAST_DATUM_COPY(X))
170 #define PG_GETARG_QUERYTYPE_P(n)	  DatumGetQueryTypeP(PG_GETARG_DATUM(n))
171 #define PG_GETARG_QUERYTYPE_P_COPY(n) DatumGetQueryTypePCopy(PG_GETARG_DATUM(n))
172 
173 bool		signconsistent(QUERYTYPE *query, BITVECP sign, int siglen, bool calcnot);
174 bool		execconsistent(QUERYTYPE *query, ArrayType *array, bool calcnot);
175 
176 bool		gin_bool_consistent(QUERYTYPE *query, bool *check);
177 bool		query_has_required_values(QUERYTYPE *query);
178 
179 int			compASC(const void *a, const void *b);
180 int			compDESC(const void *a, const void *b);
181 
182 /* sort, either ascending or descending */
183 #define QSORT(a, direction) \
184 	do { \
185 		int		_nelems_ = ARRNELEMS(a); \
186 		if (_nelems_ > 1) \
187 			qsort((void*) ARRPTR(a), _nelems_, sizeof(int32), \
188 				  (direction) ? compASC : compDESC ); \
189 	} while(0)
190 
191 #endif							/* ___INT_H__ */
192