~vcs-imports/mammoth-replicator/trunk

« back to all changes in this revision

Viewing changes to contrib/btree_gist/btree_interval.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
 
 
4
typedef struct
 
5
{
 
6
        Interval        lower,
 
7
                                upper;
 
8
}       intvKEY;
 
9
 
 
10
 
 
11
/*
 
12
** Interval ops
 
13
*/
 
14
PG_FUNCTION_INFO_V1(gbt_intv_compress);
 
15
PG_FUNCTION_INFO_V1(gbt_intv_decompress);
 
16
PG_FUNCTION_INFO_V1(gbt_intv_union);
 
17
PG_FUNCTION_INFO_V1(gbt_intv_picksplit);
 
18
PG_FUNCTION_INFO_V1(gbt_intv_consistent);
 
19
PG_FUNCTION_INFO_V1(gbt_intv_penalty);
 
20
PG_FUNCTION_INFO_V1(gbt_intv_same);
 
21
 
 
22
Datum           gbt_intv_compress(PG_FUNCTION_ARGS);
 
23
Datum           gbt_intv_decompress(PG_FUNCTION_ARGS);
 
24
Datum           gbt_intv_union(PG_FUNCTION_ARGS);
 
25
Datum           gbt_intv_picksplit(PG_FUNCTION_ARGS);
 
26
Datum           gbt_intv_consistent(PG_FUNCTION_ARGS);
 
27
Datum           gbt_intv_penalty(PG_FUNCTION_ARGS);
 
28
Datum           gbt_intv_same(PG_FUNCTION_ARGS);
 
29
 
 
30
 
 
31
static bool
 
32
gbt_intvgt(const void *a, const void *b)
 
33
{
 
34
        return DatumGetBool(DirectFunctionCall2(interval_gt, IntervalPGetDatum(a), IntervalPGetDatum(b)));
 
35
}
 
36
 
 
37
static bool
 
38
gbt_intvge(const void *a, const void *b)
 
39
{
 
40
        return DatumGetBool(DirectFunctionCall2(interval_ge, IntervalPGetDatum(a), IntervalPGetDatum(b)));
 
41
}
 
42
 
 
43
static bool
 
44
gbt_intveq(const void *a, const void *b)
 
45
{
 
46
        return DatumGetBool(DirectFunctionCall2(interval_eq, IntervalPGetDatum(a), IntervalPGetDatum(b)));
 
47
}
 
48
 
 
49
static bool
 
50
gbt_intvle(const void *a, const void *b)
 
51
{
 
52
        return DatumGetBool(DirectFunctionCall2(interval_le, IntervalPGetDatum(a), IntervalPGetDatum(b)));
 
53
}
 
54
 
 
55
static bool
 
56
gbt_intvlt(const void *a, const void *b)
 
57
{
 
58
        return DatumGetBool(DirectFunctionCall2(interval_lt, IntervalPGetDatum(a), IntervalPGetDatum(b)));
 
59
}
 
60
 
 
61
static int
 
62
gbt_intvkey_cmp(const void *a, const void *b)
 
63
{
 
64
        return DatumGetInt32(
 
65
                                                 DirectFunctionCall2(interval_cmp,
 
66
                                                                          IntervalPGetDatum(((Nsrt *) a)->t),
 
67
                                                                           IntervalPGetDatum(((Nsrt *) b)->t)
 
68
                                                                                         )
 
69
                );
 
70
}
 
71
 
 
72
 
 
73
static double
 
74
intr2num(const Interval *i)
 
75
{
 
76
        double          ret = 0.0;
 
77
        struct pg_tm tm;
 
78
        fsec_t          fsec;
 
79
 
 
80
        interval2tm(*i, &tm, &fsec);
 
81
        ret += (tm.tm_year * 360.0 * 86400.0);
 
82
        ret += (tm.tm_mon * 12.0 * 86400.0);
 
83
        ret += (tm.tm_mday * 86400.0);
 
84
        ret += (tm.tm_hour * 3600.0);
 
85
        ret += (tm.tm_min * 60.0);
 
86
        ret += (tm.tm_sec);
 
87
        ret += (fsec / 1000000.0);
 
88
 
 
89
        return (ret);
 
90
}
 
91
 
 
92
#define INTERVALSIZE 12
 
93
 
 
94
static const gbtree_ninfo tinfo =
 
95
{
 
96
        gbt_t_intv,
 
97
        sizeof(Interval),
 
98
        gbt_intvgt,
 
99
        gbt_intvge,
 
100
        gbt_intveq,
 
101
        gbt_intvle,
 
102
        gbt_intvlt,
 
103
        gbt_intvkey_cmp
 
104
};
 
105
 
 
106
 
 
107
/**************************************************
 
108
 * interval ops
 
109
 **************************************************/
 
110
 
 
111
 
 
112
Datum
 
113
gbt_intv_compress(PG_FUNCTION_ARGS)
 
114
{
 
115
        GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
 
116
        GISTENTRY  *retval = entry;
 
117
 
 
118
        if (entry->leafkey || INTERVALSIZE != sizeof(Interval))
 
119
        {
 
120
                char       *r = (char *) palloc(2 * INTERVALSIZE);
 
121
 
 
122
                retval = palloc(sizeof(GISTENTRY));
 
123
 
 
124
                if (entry->leafkey)
 
125
                {
 
126
                        Interval   *key = DatumGetIntervalP(entry->key);
 
127
 
 
128
                        memcpy((void *) r, (void *) key, INTERVALSIZE);
 
129
                        memcpy((void *) (r + INTERVALSIZE), (void *) key, INTERVALSIZE);
 
130
                }
 
131
                else
 
132
                {
 
133
                        intvKEY    *key = (intvKEY *) DatumGetPointer(entry->key);
 
134
 
 
135
                        memcpy(r, &key->lower, INTERVALSIZE);
 
136
                        memcpy(r + INTERVALSIZE, &key->upper, INTERVALSIZE);
 
137
                }
 
138
                gistentryinit(*retval, PointerGetDatum(r),
 
139
                                          entry->rel, entry->page,
 
140
                                          entry->offset, 2 * INTERVALSIZE, FALSE);
 
141
        }
 
142
 
 
143
        PG_RETURN_POINTER(retval);
 
144
 
 
145
}
 
146
 
 
147
Datum
 
148
gbt_intv_decompress(PG_FUNCTION_ARGS)
 
149
{
 
150
        GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
 
151
        GISTENTRY  *retval = entry;
 
152
 
 
153
        if (INTERVALSIZE != sizeof(Interval))
 
154
        {
 
155
                intvKEY    *r = palloc(sizeof(intvKEY));
 
156
                char       *key = DatumGetPointer(entry->key);
 
157
 
 
158
                retval = palloc(sizeof(GISTENTRY));
 
159
                memcpy(&r->lower, key, INTERVALSIZE);
 
160
                memcpy(&r->upper, key + INTERVALSIZE, INTERVALSIZE);
 
161
 
 
162
                gistentryinit(*retval, PointerGetDatum(r),
 
163
                                          entry->rel, entry->page,
 
164
                                          entry->offset, sizeof(intvKEY), FALSE);
 
165
        }
 
166
        PG_RETURN_POINTER(retval);
 
167
}
 
168
 
 
169
 
 
170
Datum
 
171
gbt_intv_consistent(PG_FUNCTION_ARGS)
 
172
{
 
173
        GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
 
174
        Interval   *query = PG_GETARG_INTERVAL_P(1);
 
175
        intvKEY    *kkk = (intvKEY *) DatumGetPointer(entry->key);
 
176
        GBT_NUMKEY_R key;
 
177
        StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
 
178
 
 
179
        key.lower = (GBT_NUMKEY *) & kkk->lower;
 
180
        key.upper = (GBT_NUMKEY *) & kkk->upper;
 
181
 
 
182
        PG_RETURN_BOOL(
 
183
                                   gbt_num_consistent(&key, (void *) query, &strategy, GIST_LEAF(entry), &tinfo)
 
184
                );
 
185
}
 
186
 
 
187
 
 
188
Datum
 
189
gbt_intv_union(PG_FUNCTION_ARGS)
 
190
{
 
191
        GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
 
192
        void       *out = palloc(sizeof(intvKEY));
 
193
 
 
194
        *(int *) PG_GETARG_POINTER(1) = sizeof(intvKEY);
 
195
        PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
 
196
}
 
197
 
 
198
 
 
199
Datum
 
200
gbt_intv_penalty(PG_FUNCTION_ARGS)
 
201
{
 
202
        intvKEY    *origentry = (intvKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
 
203
        intvKEY    *newentry = (intvKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
 
204
        float      *result = (float *) PG_GETARG_POINTER(2);
 
205
        double          iorg[2],
 
206
                                inew[2],
 
207
                                res;
 
208
 
 
209
        iorg[0] = intr2num(&origentry->lower);
 
210
        iorg[1] = intr2num(&origentry->upper);
 
211
        inew[0] = intr2num(&newentry->lower);
 
212
        inew[1] = intr2num(&newentry->upper);
 
213
 
 
214
        penalty_range_enlarge(iorg[0], iorg[1], inew[0], inew[1]);
 
215
 
 
216
        *result = 0.0;
 
217
 
 
218
        if (res > 0)
 
219
        {
 
220
                *result += FLT_MIN;
 
221
                *result += (float) (res / (res + iorg[1] - iorg[0]));
 
222
                *result *= (FLT_MAX / (((GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1));
 
223
        }
 
224
 
 
225
        PG_RETURN_POINTER(result);
 
226
 
 
227
}
 
228
 
 
229
Datum
 
230
gbt_intv_picksplit(PG_FUNCTION_ARGS)
 
231
{
 
232
        PG_RETURN_POINTER(gbt_num_picksplit(
 
233
                                                                (GistEntryVector *) PG_GETARG_POINTER(0),
 
234
                                                                  (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
 
235
                                                                                &tinfo
 
236
                                                                                ));
 
237
}
 
238
 
 
239
Datum
 
240
gbt_intv_same(PG_FUNCTION_ARGS)
 
241
{
 
242
        intvKEY    *b1 = (intvKEY *) PG_GETARG_POINTER(0);
 
243
        intvKEY    *b2 = (intvKEY *) PG_GETARG_POINTER(1);
 
244
        bool       *result = (bool *) PG_GETARG_POINTER(2);
 
245
 
 
246
        *result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
 
247
        PG_RETURN_POINTER(result);
 
248
}