~vcs-imports/mammoth-replicator/trunk

« back to all changes in this revision

Viewing changes to contrib/btree_gist/btree_utils_num.c

  • Committer: alvherre
  • Date: 2005-12-16 21:24:52 UTC
  • Revision ID: svn-v4:db760fc0-0f08-0410-9d63-cc6633f64896:trunk:1
Initial import of the REL8_0_3 sources from the Pgsql CVS repository.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "btree_gist.h"
 
2
#include "btree_utils_num.h"
 
3
#include "utils/date.h"
 
4
 
 
5
extern GISTENTRY *
 
6
gbt_num_compress(GISTENTRY *retval, GISTENTRY *entry, const gbtree_ninfo * tinfo)
 
7
{
 
8
 
 
9
        if (entry->leafkey)
 
10
        {
 
11
 
 
12
                union
 
13
                {
 
14
                        int16           i2;
 
15
                        int32           i4;
 
16
                        DateADT         dt;
 
17
                }                       v;
 
18
 
 
19
                GBT_NUMKEY *r = (GBT_NUMKEY *) palloc(2 * tinfo->size);
 
20
                void       *leaf = NULL;
 
21
 
 
22
                switch (tinfo->t)
 
23
                {
 
24
                        case gbt_t_int2:
 
25
                                v.i2 = DatumGetInt16(entry->key);
 
26
                                leaf = &v.i2;
 
27
                                break;
 
28
                        case gbt_t_int4:
 
29
                                v.i4 = DatumGetInt32(entry->key);
 
30
                                leaf = &v.i4;
 
31
                                break;
 
32
                        case gbt_t_oid:
 
33
                                v.i4 = DatumGetObjectId(entry->key);
 
34
                                leaf = &v.i4;
 
35
                                break;
 
36
                        case gbt_t_date:
 
37
                                v.dt = DatumGetDateADT(entry->key);
 
38
                                leaf = &v.dt;
 
39
                                break;
 
40
                        default:
 
41
                                leaf = DatumGetPointer(entry->key);
 
42
                }
 
43
 
 
44
                memset((void *) &r[0], 0, 2 * tinfo->size);
 
45
                memcpy((void *) &r[0], leaf, tinfo->size);
 
46
                memcpy((void *) &r[tinfo->size], leaf, tinfo->size);
 
47
                retval = palloc(sizeof(GISTENTRY));
 
48
                gistentryinit(*retval, PointerGetDatum(r), entry->rel, entry->page,
 
49
                                          entry->offset, (2 * tinfo->size), FALSE);
 
50
        }
 
51
        else
 
52
                retval = entry;
 
53
 
 
54
        return retval;
 
55
}
 
56
 
 
57
 
 
58
 
 
59
 
 
60
/*
 
61
** The GiST union method for numerical values
 
62
*/
 
63
 
 
64
extern void *
 
65
gbt_num_union(GBT_NUMKEY * out, const GistEntryVector *entryvec, const gbtree_ninfo * tinfo)
 
66
{
 
67
        int                     i,
 
68
                                numranges;
 
69
        GBT_NUMKEY *cur;
 
70
        GBT_NUMKEY_R o,
 
71
                                c;
 
72
 
 
73
        numranges = entryvec->n;
 
74
        cur = (GBT_NUMKEY *) DatumGetPointer((entryvec->vector[0].key));
 
75
 
 
76
 
 
77
        o.lower = &((GBT_NUMKEY *) out)[0];
 
78
        o.upper = &((GBT_NUMKEY *) out)[tinfo->size];
 
79
 
 
80
        memcpy((void *) out, (void *) cur, 2 * tinfo->size);
 
81
 
 
82
        for (i = 1; i < numranges; i++)
 
83
        {
 
84
                cur = (GBT_NUMKEY *) DatumGetPointer((entryvec->vector[i].key));
 
85
                c.lower = &cur[0];
 
86
                c.upper = &cur[tinfo->size];
 
87
                if ((*tinfo->f_gt) (o.lower, c.lower))  /* out->lower > cur->lower */
 
88
                        memcpy((void *) o.lower, (void *) c.lower, tinfo->size);
 
89
                if ((*tinfo->f_lt) (o.upper, c.upper))  /* out->upper < cur->upper */
 
90
                        memcpy((void *) o.upper, (void *) c.upper, tinfo->size);
 
91
        }
 
92
 
 
93
        return out;
 
94
}
 
95
 
 
96
 
 
97
 
 
98
/*
 
99
** The GiST same method for numerical values
 
100
*/
 
101
 
 
102
extern bool
 
103
gbt_num_same(const GBT_NUMKEY * a, const GBT_NUMKEY * b, const gbtree_ninfo * tinfo)
 
104
{
 
105
 
 
106
        GBT_NUMKEY_R b1,
 
107
                                b2;
 
108
 
 
109
        b1.lower = &(((GBT_NUMKEY *) a)[0]);
 
110
        b1.upper = &(((GBT_NUMKEY *) a)[tinfo->size]);
 
111
        b2.lower = &(((GBT_NUMKEY *) b)[0]);
 
112
        b2.upper = &(((GBT_NUMKEY *) b)[tinfo->size]);
 
113
 
 
114
        if (
 
115
                (*tinfo->f_eq) (b1.lower, b2.lower) &&
 
116
                (*tinfo->f_eq) (b1.upper, b2.upper)
 
117
                )
 
118
                return TRUE;
 
119
        return FALSE;
 
120
 
 
121
}
 
122
 
 
123
 
 
124
extern void
 
125
gbt_num_bin_union(Datum *u, GBT_NUMKEY * e, const gbtree_ninfo * tinfo)
 
126
{
 
127
 
 
128
        GBT_NUMKEY_R rd;
 
129
 
 
130
        rd.lower = &e[0];
 
131
        rd.upper = &e[tinfo->size];
 
132
 
 
133
        if (!DatumGetPointer(*u))
 
134
        {
 
135
                *u = PointerGetDatum(palloc(2 * tinfo->size));
 
136
                memcpy((void *) &(((GBT_NUMKEY *) DatumGetPointer(*u))[0]), (void *) rd.lower, tinfo->size);
 
137
                memcpy((void *) &(((GBT_NUMKEY *) DatumGetPointer(*u))[tinfo->size]), (void *) rd.upper, tinfo->size);
 
138
        }
 
139
        else
 
140
        {
 
141
                GBT_NUMKEY_R ur;
 
142
 
 
143
                ur.lower = &(((GBT_NUMKEY *) DatumGetPointer(*u))[0]);
 
144
                ur.upper = &(((GBT_NUMKEY *) DatumGetPointer(*u))[tinfo->size]);
 
145
                if ((*tinfo->f_gt) ((void *) ur.lower, (void *) rd.lower))
 
146
                        memcpy((void *) ur.lower, (void *) rd.lower, tinfo->size);
 
147
                if ((*tinfo->f_lt) ((void *) ur.upper, (void *) rd.upper))
 
148
                        memcpy((void *) ur.upper, (void *) rd.upper, tinfo->size);
 
149
        }
 
150
}
 
151
 
 
152
 
 
153
 
 
154
/*
 
155
** The GiST consistent method
 
156
*/
 
157
 
 
158
extern bool
 
159
gbt_num_consistent(
 
160
                                   const GBT_NUMKEY_R * key,
 
161
                                   const void *query,
 
162
                                   const StrategyNumber *strategy,
 
163
                                   bool is_leaf,
 
164
                                   const gbtree_ninfo * tinfo
 
165
)
 
166
{
 
167
 
 
168
        bool            retval = FALSE;
 
169
 
 
170
        switch (*strategy)
 
171
        {
 
172
                case BTLessEqualStrategyNumber:
 
173
                        retval = (*tinfo->f_ge) (query, key->lower);
 
174
                        break;
 
175
                case BTLessStrategyNumber:
 
176
                        if (is_leaf)
 
177
                                retval = (*tinfo->f_gt) (query, key->lower);
 
178
                        else
 
179
                                retval = (*tinfo->f_ge) (query, key->lower);
 
180
                        break;
 
181
                case BTEqualStrategyNumber:
 
182
                        if (is_leaf)
 
183
                                retval = (*tinfo->f_eq) (query, key->lower);
 
184
                        else
 
185
                                retval = (*tinfo->f_le) (key->lower, query) && (*tinfo->f_le) (query, key->upper);
 
186
                        break;
 
187
                case BTGreaterStrategyNumber:
 
188
                        if (is_leaf)
 
189
                                retval = (*tinfo->f_lt) (query, key->upper);
 
190
                        else
 
191
                                retval = (*tinfo->f_le) (query, key->upper);
 
192
                        break;
 
193
                case BTGreaterEqualStrategyNumber:
 
194
                        retval = (*tinfo->f_le) (query, key->upper);
 
195
                        break;
 
196
                default:
 
197
                        retval = FALSE;
 
198
        }
 
199
 
 
200
        return (retval);
 
201
}
 
202
 
 
203
 
 
204
GIST_SPLITVEC *
 
205
gbt_num_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v,
 
206
                                  const gbtree_ninfo * tinfo)
 
207
{
 
208
        OffsetNumber i,
 
209
                                maxoff = entryvec->n - 1;
 
210
        Nsrt       *arr;
 
211
        int                     nbytes;
 
212
 
 
213
        arr = (Nsrt *) palloc((maxoff + 1) * sizeof(Nsrt));
 
214
        nbytes = (maxoff + 2) * sizeof(OffsetNumber);
 
215
        v->spl_left = (OffsetNumber *) palloc(nbytes);
 
216
        v->spl_right = (OffsetNumber *) palloc(nbytes);
 
217
        v->spl_ldatum = PointerGetDatum(0);
 
218
        v->spl_rdatum = PointerGetDatum(0);
 
219
        v->spl_nleft = 0;
 
220
        v->spl_nright = 0;
 
221
 
 
222
        /* Sort entries */
 
223
 
 
224
        for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
 
225
        {
 
226
                arr[i].t = (GBT_NUMKEY *) DatumGetPointer((entryvec->vector[i].key));
 
227
                arr[i].i = i;
 
228
        }
 
229
        qsort((void *) &arr[FirstOffsetNumber], maxoff - FirstOffsetNumber + 1, sizeof(Nsrt), tinfo->f_cmp);
 
230
 
 
231
        /* We do simply create two parts */
 
232
 
 
233
        for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
 
234
        {
 
235
                if (i <= (maxoff - FirstOffsetNumber + 1) / 2)
 
236
                {
 
237
                        gbt_num_bin_union(&v->spl_ldatum, arr[i].t, tinfo);
 
238
                        v->spl_left[v->spl_nleft] = arr[i].i;
 
239
                        v->spl_nleft++;
 
240
                }
 
241
                else
 
242
                {
 
243
                        gbt_num_bin_union(&v->spl_rdatum, arr[i].t, tinfo);
 
244
                        v->spl_right[v->spl_nright] = arr[i].i;
 
245
                        v->spl_nright++;
 
246
                }
 
247
        }
 
248
 
 
249
        pfree(arr);
 
250
 
 
251
        return v;
 
252
}