#include "fmgr.h"
#include "access/gist.h"
#include "access/skey.h"
-#include "access/tuptoaster.h"
+#include "access/heaptoast.h"
#include "utils/memutils.h"
typedef struct SmlSign {
#define HASHVAL(val) (((unsigned int)(val)) % SIGLENBIT)
#define HASH(sign, val) SETBIT((sign), HASHVAL(val))
-#define ARRKEY 0x01
-#define SIGNKEY 0x02
-#define ALLISTRUE 0x04
+#define ARRKEY 0x01
+#define SIGNKEY 0x02
+#define ALLISTRUE 0x04
-#define ISARRKEY(x) ( ((SmlSign*)x)->flag & ARRKEY )
-#define ISSIGNKEY(x) ( ((SmlSign*)x)->flag & SIGNKEY )
-#define ISALLTRUE(x) ( ((SmlSign*)x)->flag & ALLISTRUE )
+#define ISARRKEY(x) ( ((SmlSign*)x)->flag & ARRKEY )
+#define ISSIGNKEY(x) ( ((SmlSign*)x)->flag & SIGNKEY )
+#define ISALLTRUE(x) ( ((SmlSign*)x)->flag & ALLISTRUE )
-#define CALCGTSIZE(flag, len) ( SMLSIGNHDRSZ + ( ( (flag) & ARRKEY ) ? ((len)*sizeof(uint32)) : (((flag) & ALLISTRUE) ? 0 : SIGLEN) ) )
-#define GETSIGN(x) ( (BITVECP)( (char*)x+SMLSIGNHDRSZ ) )
-#define GETARR(x) ( (uint32*)( (char*)x+SMLSIGNHDRSZ ) )
+#define CALCGTSIZE(flag, len) ( SMLSIGNHDRSZ + ( ( (flag) & ARRKEY ) ? ((len)*sizeof(uint32)) : (((flag) & ALLISTRUE) ? 0 : SIGLEN) ) )
+#define GETSIGN(x) ( (BITVECP)( (char*)x+SMLSIGNHDRSZ ) )
+#define GETARR(x) ( (uint32*)( (char*)x+SMLSIGNHDRSZ ) )
#define GETENTRY(vec,pos) ((SmlSign *) DatumGetPointer((vec)->vector[(pos)].key))
* Fake IO
*/
PG_FUNCTION_INFO_V1(gsmlsign_in);
-Datum gsmlsign_in(PG_FUNCTION_ARGS);
+Datum gsmlsign_in(PG_FUNCTION_ARGS);
Datum
gsmlsign_in(PG_FUNCTION_ARGS)
{
}
PG_FUNCTION_INFO_V1(gsmlsign_out);
-Datum gsmlsign_out(PG_FUNCTION_ARGS);
+Datum gsmlsign_out(PG_FUNCTION_ARGS);
Datum
gsmlsign_out(PG_FUNCTION_ARGS)
{
/* Number of one-bits in an unsigned byte */
static const uint8 number_of_ones[256] = {
- 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
+ 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
static int
compareint(const void *va, const void *vb)
{
- uint32 a = *((uint32 *) va);
- uint32 b = *((uint32 *) vb);
-
+ uint32 a = *((uint32 *) va);
+ uint32 b = *((uint32 *) vb);
+
if (a == b)
return 0;
return (a > b) ? 1 : -1;
}
/*
- * Removes duplicates from an array of int4. 'l' is
+ * Removes duplicates from an array of int32. 'l' is
* size of the input array. Returns the new size of the array.
*/
static int
-uniqueint(uint32 *a, int4 l, int4 *max)
+uniqueint(uint32 *a, int32 l, int32 *max)
{
- uint32 *ptr,
- *res;
- int4 cnt = 0;
+ uint32 *ptr,
+ *res;
+ int32 cnt = 0;
*max = 1;
{
SimpleArray *s = Array2SimpleArray(info, a);
SmlSign *sign;
- int4 len, i;
+ int32 len, i;
uint32 *ptr;
len = CALCGTSIZE( ARRKEY, s->nelems );
ptr = GETARR(sign);
for(i=0;i<s->nelems;i++)
- ptr[i] = DatumGetUInt32( FunctionCall1( &s->info->hashFunc, s->elems[i] ) );
-
+ ptr[i] = DatumGetUInt32(FunctionCall1Coll(&s->info->hashFunc,
+ DEFAULT_COLLATION_OID,
+ s->elems[i]));
+
/*
* there is a collision of hash-function; len is always equal or less than
* s->nelems
static int
HashedElemCmp(const void *va, const void *vb)
{
- uint32 a = ((HashedElem *) va)->hash;
- uint32 b = ((HashedElem *) vb)->hash;
-
+ uint32 a = ((HashedElem *) va)->hash;
+ uint32 b = ((HashedElem *) vb)->hash;
+
if (a == b)
{
double ma = ((HashedElem *) va)->idfMin;
}
static int
-uniqueHashedElem(HashedElem *a, int4 l)
+uniqueHashedElem(HashedElem *a, int32 l)
{
- HashedElem *ptr,
- *res;
+ HashedElem *ptr,
+ *res;
if (l <= 1)
return l;
getFmgrInfoHash(stat->info);
for(i=0;i<stat->nelems;i++)
{
- uint32 hash = DatumGetUInt32( FunctionCall1( &stat->info->hashFunc, stat->elems[i].datum ) );
- int index = HASHVAL(hash);
+ uint32 hash;
+
+ hash = DatumGetUInt32(FunctionCall1Coll(&stat->info->hashFunc,
+ DEFAULT_COLLATION_OID,
+ stat->elems[i].datum));
+ int index = HASHVAL(hash);
stat->helems[i].hash = hash;
stat->helems[i].idfMin = stat->helems[i].idfMax = stat->elems[i].idf;
stat->selems[index].idfMax = stat->elems[i].idf;
}
- stat->nhelems = uniqueHashedElem( stat->helems, stat->nelems);
+ stat->nhelems = uniqueHashedElem( stat->helems, stat->nelems);
}
return stat;
getFmgrInfoHash(a->info);
for(i=0;i<a->nelems;i++)
- a->hash[i] = DatumGetUInt32( FunctionCall1( &a->info->hashFunc, a->elems[i] ) );
+ a->hash[i] = DatumGetUInt32(FunctionCall1Coll(&a->info->hashFunc,
+ DEFAULT_COLLATION_OID,
+ a->elems[i]));
}
while (StopLow < StopHigh) {
StopMiddle = StopLow + ((StopHigh - StopLow) >> 1);
-
+
if ( *StopMiddle == h )
return true;
else if ( *StopMiddle < h )
static void
makesign(BITVECP sign, SmlSign *a)
{
- int4 i;
+ int32 i;
uint32 *ptr = GETARR(a);
MemSet((void *) sign, 0, sizeof(BITVEC));
- SETBIT(sign, SIGLENBIT); /* set last unused bit */
+ SETBIT(sign, SIGLENBIT); /* set last unused bit */
for (i = 0; i < a->size; i++)
HASH(sign, ptr[i]);
}
-static int4
+static int32
sizebitvec(BITVECP sign)
{
- int4 size = 0,
+ int32 size = 0,
i;
LOOPBYTE
sign = Array2HashedArray(NULL, a);
if ( VARSIZE(sign) > TOAST_INDEX_TARGET )
- { /* make signature due to its big size */
+ { /* make signature due to its big size */
SmlSign *tmpsign;
int len;
makesign(GETSIGN(tmpsign), sign);
tmpsign->size = sizebitvec(GETSIGN(tmpsign));
- tmpsign->maxrepeat = sign->maxrepeat;
+ tmpsign->maxrepeat = sign->maxrepeat;
sign = tmpsign;
}
retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
gistentryinit(*retval, PointerGetDatum(sign),
entry->rel, entry->page,
- entry->offset, FALSE);
+ entry->offset, false);
}
else if ( ISSIGNKEY(DatumGetPointer(entry->key)) &&
!ISALLTRUE(DatumGetPointer(entry->key)) )
if ( sign->size == SIGLENBIT )
{
- int4 len = CALCGTSIZE(SIGNKEY | ALLISTRUE, 0);
- int4 maxrepeat = sign->maxrepeat;
+ int32 len = CALCGTSIZE(SIGNKEY | ALLISTRUE, 0);
+ int32 maxrepeat = sign->maxrepeat;
sign = (SmlSign *) palloc(len);
SET_VARSIZE(sign, len);
gistentryinit(*retval, PointerGetDatum(sign),
entry->rel, entry->page,
- entry->offset, FALSE);
+ entry->offset, false);
}
}
-
+
PG_RETURN_POINTER(retval);
}
Datum
gsmlsign_decompress(PG_FUNCTION_ARGS)
{
- GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
- SmlSign *key = (SmlSign*)DatumGetPointer(PG_DETOAST_DATUM(entry->key));
+ GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+ SmlSign *key = (SmlSign*)DatumGetPointer(PG_DETOAST_DATUM(entry->key));
if (key != (SmlSign *) DatumGetPointer(entry->key))
{
gistentryinit(*retval, PointerGetDatum(key),
entry->rel, entry->page,
- entry->offset, FALSE);
+ entry->offset, false);
PG_RETURN_POINTER(retval);
}
static bool
unionkey(BITVECP sbase, SmlSign *add)
{
- int4 i;
+ int32 i;
if (ISSIGNKEY(add))
{
- BITVECP sadd = GETSIGN(add);
+ BITVECP sadd = GETSIGN(add);
if (ISALLTRUE(add))
return true;
}
else
{
- uint32 *ptr = GETARR(add);
+ uint32 *ptr = GETARR(add);
for (i = 0; i < add->size; i++)
HASH(sbase, ptr[i]);
gsmlsign_union(PG_FUNCTION_ARGS)
{
GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
- int *size = (int *) PG_GETARG_POINTER(1);
- BITVEC base;
- int4 i,
+ int *size = (int *) PG_GETARG_POINTER(1);
+ BITVEC base;
+ int32 i,
len,
maxrepeat = 1;
- int4 flag = 0;
+ int32 flag = 0;
SmlSign *result;
MemSet((void *) base, 0, sizeof(BITVEC));
result->flag = flag;
result->maxrepeat = maxrepeat;
- if (!ISALLTRUE(result))
+ if (!ISALLTRUE(result))
{
memcpy((void *) GETSIGN(result), (void *) base, sizeof(BITVEC));
result->size = sizebitvec(GETSIGN(result));
}
else
- result->size = SIGLENBIT;
+ result->size = SIGLENBIT;
PG_RETURN_POINTER(result);
}
}
else
{
- int4 i;
+ int32 i;
BITVECP sa = GETSIGN(a),
sb = GETSIGN(b);
{
uint32 *ptra = GETARR(a),
*ptrb = GETARR(b);
- int4 i;
+ int32 i;
*result = true;
for (i = 0; i < a->size; i++)
static int
hemdistsign(BITVECP a, BITVECP b)
{
- int i,
- diff,
- dist = 0;
+ int i,
+ diff,
+ dist = 0;
LOOPBYTE
{
}
return dist;
}
-
+
static int
hemdist(SmlSign *a, SmlSign *b)
{
Datum
gsmlsign_penalty(PG_FUNCTION_ARGS)
{
- GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0); /* always ISSIGNKEY */
- GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1);
- float *penalty = (float *) PG_GETARG_POINTER(2);
- SmlSign *origval = (SmlSign *) DatumGetPointer(origentry->key);
- SmlSign *newval = (SmlSign *) DatumGetPointer(newentry->key);
- BITVECP orig = GETSIGN(origval);
+ GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0); /* always ISSIGNKEY */
+ GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1);
+ float *penalty = (float *) PG_GETARG_POINTER(2);
+ SmlSign *origval = (SmlSign *) DatumGetPointer(origentry->key);
+ SmlSign *newval = (SmlSign *) DatumGetPointer(newentry->key);
+ BITVECP orig = GETSIGN(origval);
*penalty = 0.0;
if (ISARRKEY(newval))
{
- BITVEC sign;
+ BITVEC sign;
makesign(sign, newval);
typedef struct
{
- bool allistrue;
- int32 size;
- BITVEC sign;
+ bool allistrue;
+ int32 size;
+ BITVEC sign;
} CACHESIGN;
static void
fillcache(CACHESIGN *item, SmlSign *key)
{
- item->allistrue = false;
+ item->allistrue = false;
item->size = key->size;
- if (ISARRKEY(key))
+ if (ISARRKEY(key))
{
makesign(item->sign, key);
- item->size = sizebitvec( item->sign );
- }
+ item->size = sizebitvec( item->sign );
+ }
else if (ISALLTRUE(key))
item->allistrue = true;
else
typedef struct
{
OffsetNumber pos;
- int4 cost;
+ int32 cost;
} SPLITCOST;
static int
GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
OffsetNumber k,
j;
- SmlSign *datum_l,
+ SmlSign *datum_l,
*datum_r;
- BITVECP union_l,
+ BITVECP union_l,
union_r;
- int4 size_alpha,
+ int32 size_alpha,
size_beta;
- int4 size_waste,
+ int32 size_waste,
waste = -1;
- int4 nbytes;
+ int32 nbytes;
OffsetNumber seed_1 = 0,
seed_2 = 0;
OffsetNumber *left,
*right;
OffsetNumber maxoff;
- BITVECP ptr;
- int i;
+ BITVECP ptr;
+ int i;
CACHESIGN *cache;
SPLITCOST *costvector;
cache = (CACHESIGN *) palloc(sizeof(CACHESIGN) * (maxoff + 2));
fillcache(&cache[FirstOffsetNumber], GETENTRY(entryvec, FirstOffsetNumber));
- for (k = FirstOffsetNumber; k < maxoff; k = OffsetNumberNext(k))
+ for (k = FirstOffsetNumber; k < maxoff; k = OffsetNumberNext(k))
{
for (j = OffsetNumberNext(k); j <= maxoff; j = OffsetNumberNext(j))
{
datum_l = (SmlSign *) palloc(CALCGTSIZE(SIGNKEY | ALLISTRUE, 0));
SET_VARSIZE(datum_l, CALCGTSIZE(SIGNKEY | ALLISTRUE, 0));
datum_l->flag = SIGNKEY | ALLISTRUE;
- datum_l->size = SIGLENBIT;
+ datum_l->size = SIGLENBIT;
}
else
{
gsmlsign_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
- StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
- bool *recheck = (bool *) PG_GETARG_POINTER(4);
+ StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
+ bool *recheck = (bool *) PG_GETARG_POINTER(4);
ArrayType *a;
SmlSign *key = (SmlSign*)DatumGetPointer(entry->key);
int res = false;
SmlSign *query;
SimpleArray *s;
- int4 i;
+ int32 i;
fcinfo->flinfo->fn_extra = SearchArrayCache(
fcinfo->flinfo->fn_extra,
}
else if (ISARRKEY(key))
{
- uint32 *kptr = GETARR(key),
- *qptr = GETARR(query);
+ uint32 *kptr = GETARR(key),
+ *qptr = GETARR(query);
while( kptr - GETARR(key) < key->size && qptr - GETARR(query) < query->size )
{
}
else if (ISARRKEY(key))
{
- uint32 *kptr = GETARR(key),
- *qptr = GETARR(query);
+ uint32 *kptr = GETARR(key),
+ *qptr = GETARR(query);
Assert( GIST_LEAF(entry) );
if ( ((double)Min(key->size, s->nelems)) / power >= GetSmlarLimit() )
{
- int cnt = 0;
+ int cnt = 0;
while( kptr - GETARR(key) < key->size && qptr - GETARR(query) < query->size )
{
qptr++;
}
}
-
+
if ( ((double)cnt) / power >= GetSmlarLimit() )
res = true;
}
else
{ /* signature */
BITVECP sign = GETSIGN(key);
- int4 count = 0;
+ int32 count = 0;
fillHashVal(fcinfo->flinfo->fn_extra, s);
sumQ = 0.0,
sumK = 0.0;
double maxKTF = getIdfMaxLimit(key);
-
+
Assert( s->df );
if ( stat->info != s->info )
elog(ERROR,"Statistic and actual argument have different type");
break;
case ST_COSINE:
{
- double power;
+ double power;
power = sqrt( ((double)(key->size)) * ((double)(s->nelems)) );
for(i=0; i<s->nelems; i++)
count += GETBIT(sign, HASHVAL(s->hash[i]));
-
+
if ( ((double)count) / power >= GetSmlarLimit() )
res = true;
}
sumQ = 0.0,
minK = -1.0;
double maxKTF = getIdfMaxLimit(key);
-
+
Assert( s->df );
if ( stat->info != s->info )
elog(ERROR,"Statistic and actual argument have different type");
{
for(i=0; i<s->nelems; i++)
count += GETBIT(sign, HASHVAL(s->hash[i]));
-
- if ( s->nelems == count || ((double)count) / ((double)(s->nelems)) >= GetSmlarLimit() )
+
+ if ( s->nelems == count || sqrt(((double)count) / ((double)(s->nelems))) >= GetSmlarLimit() )
res = true;
}
break;