diff options
author | Teodor Sigaev <teodor@sigaev.ru> | 2004-05-28 10:43:32 +0000 |
---|---|---|
committer | Teodor Sigaev <teodor@sigaev.ru> | 2004-05-28 10:43:32 +0000 |
commit | 42d069886f38687839388c615af608706508b557 (patch) | |
tree | 0409615407a17d22e2511ac14745277467853453 /contrib/btree_gist/btree_utils_num.c | |
parent | 1a321f26d88e5c64bccba9d36920aede1e201729 (diff) | |
download | postgresql-42d069886f38687839388c615af608706508b557.tar.gz postgresql-42d069886f38687839388c615af608706508b557.zip |
New version. Add support for int2, int8, float4, float8, timestamp with/without time zone, time with/without time zone, date, interval, oid, money and macaddr, char, varchar/text, bytea, numeric, bit, varbit, inet/cidr types for GiST
Diffstat (limited to 'contrib/btree_gist/btree_utils_num.c')
-rw-r--r-- | contrib/btree_gist/btree_utils_num.c | 255 |
1 files changed, 255 insertions, 0 deletions
diff --git a/contrib/btree_gist/btree_utils_num.c b/contrib/btree_gist/btree_utils_num.c new file mode 100644 index 00000000000..80fccbaef05 --- /dev/null +++ b/contrib/btree_gist/btree_utils_num.c @@ -0,0 +1,255 @@ +#include "btree_gist.h" +#include "btree_utils_num.h" +#include "utils/date.h" + +extern GISTENTRY * +gbt_num_compress( GISTENTRY *retval , GISTENTRY *entry , const gbtree_ninfo * tinfo ) +{ + + if (entry->leafkey) + { + + union { + int16 i2; + int32 i4; + TimeADT ts; + DateADT dt; + } v ; + + GBT_NUMKEY *r = ( GBT_NUMKEY * ) palloc(2 * tinfo->size); + void *leaf = NULL; + + switch ( tinfo->t ) + { + case gbt_t_int2 : + v.i2 = DatumGetInt16(entry->key); + leaf = &v.i2; + break; + case gbt_t_int4 : + v.i4 = DatumGetInt32(entry->key); + leaf = &v.i4; + break; + case gbt_t_oid : + v.i4 = DatumGetObjectId(entry->key); + leaf = &v.i4; + break; + case gbt_t_time : + v.ts = DatumGetTimeADT(entry->key); + leaf = &v.ts; + break; + case gbt_t_date : + v.dt = DatumGetDateADT(entry->key); + leaf = &v.dt; + break; + default : + leaf = DatumGetPointer(entry->key); + } + + memcpy ( (void*) &r[0] , leaf, tinfo->size ); + memcpy ( (void*) &r[tinfo->size] , leaf, tinfo->size ); + + retval = palloc(sizeof(GISTENTRY)); + gistentryinit(*retval, PointerGetDatum(r), entry->rel, entry->page, + entry->offset,( 2 * tinfo->size), FALSE); + } else + retval = entry; + + return retval; +} + + + + +/* +** The GiST union method for numerical values +*/ + +extern void * +gbt_num_union( GBT_NUMKEY * out, const GistEntryVector * entryvec, const gbtree_ninfo * tinfo ) +{ + int i, + numranges; + GBT_NUMKEY * cur ; + GBT_NUMKEY_R o, c; + + numranges = entryvec->n; + cur = (GBT_NUMKEY *) DatumGetPointer((entryvec->vector[0].key)); + + + o.lower = &((GBT_NUMKEY *)out)[0]; + o.upper = &((GBT_NUMKEY *)out)[tinfo->size]; + + memcpy( (void*)out, (void*) cur, 2*tinfo->size ); + + for (i = 1; i < numranges; i++) + { + cur = (GBT_NUMKEY *) DatumGetPointer((entryvec->vector[i].key)); + c.lower = &cur[0]; + c.upper = &cur[tinfo->size]; + + if ( (*tinfo->f_gt)(o.lower, c.lower) ) /* out->lower > cur->lower */ + memcpy( (void* ) o.lower, (void*) c.lower, tinfo->size ); + if ( (*tinfo->f_lt)(o.upper, c.upper) ) /* out->upper < cur->upper */ + memcpy( (void*) o.upper, (void*) c.upper, tinfo->size ); + } + + return out; +} + + + +/* +** The GiST same method for numerical values +*/ + +extern bool gbt_num_same ( const GBT_NUMKEY * a, const GBT_NUMKEY * b, const gbtree_ninfo * tinfo ) +{ + + GBT_NUMKEY_R b1, b2 ; + + b1.lower = &(((GBT_NUMKEY *)a)[0]); + b1.upper = &(((GBT_NUMKEY *)a)[tinfo->size]); + b2.lower = &(((GBT_NUMKEY *)b)[0]); + b2.upper = &(((GBT_NUMKEY *)b)[tinfo->size]); + + if ( + (*tinfo->f_eq)( b1.lower, b2.lower) && + (*tinfo->f_eq)( b1.upper, b2.upper) + ) + return TRUE; + return FALSE; + +} + + +extern void +gbt_num_bin_union(Datum * u , GBT_NUMKEY * e , const gbtree_ninfo * tinfo ) +{ + + GBT_NUMKEY_R rd; + rd.lower = &e[0]; + rd.upper = &e[tinfo->size]; + + if (!DatumGetPointer(*u)) + { + *u = PointerGetDatum(palloc(2 * tinfo->size)); + memcpy( (void* ) &( ( (GBT_NUMKEY *) DatumGetPointer(*u) )[0] ) , (void*)rd.lower , tinfo->size ); + memcpy( (void* ) &( ( (GBT_NUMKEY *) DatumGetPointer(*u) )[tinfo->size]) , (void*)rd.upper , tinfo->size ); + } + else + { + GBT_NUMKEY_R ur ; + ur.lower = &( ( (GBT_NUMKEY *) DatumGetPointer(*u) )[0] ) ; + ur.upper = &( ( (GBT_NUMKEY *) DatumGetPointer(*u) )[tinfo->size]) ; + if ( (*tinfo->f_gt)((void*)ur.lower, (void*)rd.lower) ) + memcpy( (void*) ur.lower, (void*) rd.lower, tinfo->size ); + if ( (*tinfo->f_lt)((void*)ur.upper, (void*)rd.upper) ) + memcpy( (void*) ur.upper, (void*) rd.upper, tinfo->size ); + } + +} + + + +/* +** The GiST consistent method +*/ + +extern bool +gbt_num_consistent( + const GBT_NUMKEY_R * key, + const void * query, + const StrategyNumber * strategy, + bool is_leaf, + const gbtree_ninfo * tinfo +) +{ + + bool retval = FALSE; + + switch (*strategy) + { + case BTLessEqualStrategyNumber: + retval = (*tinfo->f_ge)(query, key->lower); + break; + case BTLessStrategyNumber: + if ( is_leaf ) + retval = (*tinfo->f_gt)(query, key->lower); + else + retval = (*tinfo->f_ge)(query, key->lower); + break; + case BTEqualStrategyNumber: + if ( is_leaf ) + retval = (*tinfo->f_eq)(query, key->lower); + else + retval = (*tinfo->f_le)(key->lower, query) && (*tinfo->f_le)(query, key->upper ); + break; + case BTGreaterStrategyNumber: + if ( is_leaf ) + retval = (*tinfo->f_lt)(query, key->upper); + else + retval = (*tinfo->f_le)(query, key->upper); + break; + case BTGreaterEqualStrategyNumber: + retval = (*tinfo->f_le)(query, key->upper); + break; + default: + retval = FALSE; + } + + return (retval); +} + + + + +GIST_SPLITVEC * +gbt_num_picksplit( const GistEntryVector *entryvec, GIST_SPLITVEC *v, const gbtree_ninfo * tinfo ) +{ + + OffsetNumber i , + + maxoff = entryvec->n - 1; + + Nsrt arr[maxoff+1] ; + int nbytes ; + + nbytes = (maxoff + 2) * sizeof(OffsetNumber); + v->spl_left = (OffsetNumber *) palloc(nbytes); + v->spl_right = (OffsetNumber *) palloc(nbytes); + v->spl_ldatum = PointerGetDatum(0); + v->spl_rdatum = PointerGetDatum(0); + v->spl_nleft = 0; + v->spl_nright = 0; + + /* Sort entries */ + + for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) + { + arr[i].t = (GBT_NUMKEY *) DatumGetPointer((entryvec->vector[i].key)); + arr[i].i = i; + } + qsort ( (void*) &arr[FirstOffsetNumber], maxoff-FirstOffsetNumber+1,sizeof(Nsrt), tinfo->f_cmp ); + + /* We do simply create two parts */ + + for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) + { + if (i <= (maxoff - FirstOffsetNumber + 1) / 2) + { + gbt_num_bin_union(&v->spl_ldatum, arr[i].t, tinfo); + v->spl_left[v->spl_nleft] = arr[i].i; + v->spl_nleft++; + } + else + { + gbt_num_bin_union(&v->spl_rdatum, arr[i].t, tinfo); + v->spl_right[v->spl_nright] = arr[i].i; + v->spl_nright++; + } + } + + return v; + +} + |