Header And Logo

PostgreSQL
| The world's most advanced open source database.

btree_float4.c

Go to the documentation of this file.
00001 /*
00002  * contrib/btree_gist/btree_float4.c
00003  */
00004 #include "postgres.h"
00005 
00006 #include "btree_gist.h"
00007 #include "btree_utils_num.h"
00008 
00009 typedef struct float4key
00010 {
00011     float4      lower;
00012     float4      upper;
00013 } float4KEY;
00014 
00015 /*
00016 ** float4 ops
00017 */
00018 PG_FUNCTION_INFO_V1(gbt_float4_compress);
00019 PG_FUNCTION_INFO_V1(gbt_float4_union);
00020 PG_FUNCTION_INFO_V1(gbt_float4_picksplit);
00021 PG_FUNCTION_INFO_V1(gbt_float4_consistent);
00022 PG_FUNCTION_INFO_V1(gbt_float4_distance);
00023 PG_FUNCTION_INFO_V1(gbt_float4_penalty);
00024 PG_FUNCTION_INFO_V1(gbt_float4_same);
00025 
00026 Datum       gbt_float4_compress(PG_FUNCTION_ARGS);
00027 Datum       gbt_float4_union(PG_FUNCTION_ARGS);
00028 Datum       gbt_float4_picksplit(PG_FUNCTION_ARGS);
00029 Datum       gbt_float4_consistent(PG_FUNCTION_ARGS);
00030 Datum       gbt_float4_distance(PG_FUNCTION_ARGS);
00031 Datum       gbt_float4_penalty(PG_FUNCTION_ARGS);
00032 Datum       gbt_float4_same(PG_FUNCTION_ARGS);
00033 
00034 static bool
00035 gbt_float4gt(const void *a, const void *b)
00036 {
00037     return (*((const float4 *) a) > *((const float4 *) b));
00038 }
00039 static bool
00040 gbt_float4ge(const void *a, const void *b)
00041 {
00042     return (*((const float4 *) a) >= *((const float4 *) b));
00043 }
00044 static bool
00045 gbt_float4eq(const void *a, const void *b)
00046 {
00047     return (*((const float4 *) a) == *((const float4 *) b));
00048 }
00049 static bool
00050 gbt_float4le(const void *a, const void *b)
00051 {
00052     return (*((const float4 *) a) <= *((const float4 *) b));
00053 }
00054 static bool
00055 gbt_float4lt(const void *a, const void *b)
00056 {
00057     return (*((const float4 *) a) < *((const float4 *) b));
00058 }
00059 
00060 static int
00061 gbt_float4key_cmp(const void *a, const void *b)
00062 {
00063     float4KEY  *ia = (float4KEY *) (((const Nsrt *) a)->t);
00064     float4KEY  *ib = (float4KEY *) (((const Nsrt *) b)->t);
00065 
00066     if (ia->lower == ib->lower)
00067     {
00068         if (ia->upper == ib->upper)
00069             return 0;
00070 
00071         return (ia->upper > ib->upper) ? 1 : -1;
00072     }
00073 
00074     return (ia->lower > ib->lower) ? 1 : -1;
00075 }
00076 
00077 static float8
00078 gbt_float4_dist(const void *a, const void *b)
00079 {
00080     return GET_FLOAT_DISTANCE(float4, a, b);
00081 }
00082 
00083 
00084 static const gbtree_ninfo tinfo =
00085 {
00086     gbt_t_float4,
00087     sizeof(float4),
00088     gbt_float4gt,
00089     gbt_float4ge,
00090     gbt_float4eq,
00091     gbt_float4le,
00092     gbt_float4lt,
00093     gbt_float4key_cmp,
00094     gbt_float4_dist
00095 };
00096 
00097 
00098 PG_FUNCTION_INFO_V1(float4_dist);
00099 Datum       float4_dist(PG_FUNCTION_ARGS);
00100 Datum
00101 float4_dist(PG_FUNCTION_ARGS)
00102 {
00103     float4      a = PG_GETARG_FLOAT4(0);
00104     float4      b = PG_GETARG_FLOAT4(1);
00105     float4      r;
00106 
00107     r = a - b;
00108     CHECKFLOATVAL(r, isinf(a) || isinf(b), true);
00109 
00110     PG_RETURN_FLOAT4(Abs(r));
00111 }
00112 
00113 
00114 /**************************************************
00115  * float4 ops
00116  **************************************************/
00117 
00118 
00119 Datum
00120 gbt_float4_compress(PG_FUNCTION_ARGS)
00121 {
00122     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
00123     GISTENTRY  *retval = NULL;
00124 
00125     PG_RETURN_POINTER(gbt_num_compress(retval, entry, &tinfo));
00126 }
00127 
00128 
00129 Datum
00130 gbt_float4_consistent(PG_FUNCTION_ARGS)
00131 {
00132     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
00133     float4      query = PG_GETARG_FLOAT4(1);
00134     StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
00135 
00136     /* Oid      subtype = PG_GETARG_OID(3); */
00137     bool       *recheck = (bool *) PG_GETARG_POINTER(4);
00138     float4KEY  *kkk = (float4KEY *) DatumGetPointer(entry->key);
00139     GBT_NUMKEY_R key;
00140 
00141     /* All cases served by this function are exact */
00142     *recheck = false;
00143 
00144     key.lower = (GBT_NUMKEY *) &kkk->lower;
00145     key.upper = (GBT_NUMKEY *) &kkk->upper;
00146 
00147     PG_RETURN_BOOL(
00148                    gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo)
00149         );
00150 }
00151 
00152 
00153 Datum
00154 gbt_float4_distance(PG_FUNCTION_ARGS)
00155 {
00156     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
00157     float4      query = PG_GETARG_FLOAT4(1);
00158 
00159     /* Oid      subtype = PG_GETARG_OID(3); */
00160     float4KEY  *kkk = (float4KEY *) DatumGetPointer(entry->key);
00161     GBT_NUMKEY_R key;
00162 
00163     key.lower = (GBT_NUMKEY *) &kkk->lower;
00164     key.upper = (GBT_NUMKEY *) &kkk->upper;
00165 
00166     PG_RETURN_FLOAT8(
00167             gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo)
00168         );
00169 }
00170 
00171 
00172 Datum
00173 gbt_float4_union(PG_FUNCTION_ARGS)
00174 {
00175     GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
00176     void       *out = palloc(sizeof(float4KEY));
00177 
00178     *(int *) PG_GETARG_POINTER(1) = sizeof(float4KEY);
00179     PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
00180 }
00181 
00182 
00183 Datum
00184 gbt_float4_penalty(PG_FUNCTION_ARGS)
00185 {
00186     float4KEY  *origentry = (float4KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
00187     float4KEY  *newentry = (float4KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
00188     float      *result = (float *) PG_GETARG_POINTER(2);
00189 
00190     penalty_num(result, origentry->lower, origentry->upper, newentry->lower, newentry->upper);
00191 
00192     PG_RETURN_POINTER(result);
00193 
00194 }
00195 
00196 Datum
00197 gbt_float4_picksplit(PG_FUNCTION_ARGS)
00198 {
00199     PG_RETURN_POINTER(gbt_num_picksplit(
00200                                     (GistEntryVector *) PG_GETARG_POINTER(0),
00201                                       (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
00202                                         &tinfo
00203                                         ));
00204 }
00205 
00206 Datum
00207 gbt_float4_same(PG_FUNCTION_ARGS)
00208 {
00209     float4KEY  *b1 = (float4KEY *) PG_GETARG_POINTER(0);
00210     float4KEY  *b2 = (float4KEY *) PG_GETARG_POINTER(1);
00211     bool       *result = (bool *) PG_GETARG_POINTER(2);
00212 
00213     *result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
00214     PG_RETURN_POINTER(result);
00215 }