Properly access a buffer's LSN using existing access macros instead of abusing
[PostgreSQL.git] / src / backend / utils / adt / tsgistidx.c
blobcb56f0feb34a2e597544d4eb627b2f937cfa0ae1
1 /*-------------------------------------------------------------------------
3 * tsgistidx.c
4 * GiST support functions for tsvector_ops
6 * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
9 * IDENTIFICATION
10 * $PostgreSQL$
12 *-------------------------------------------------------------------------
15 #include "postgres.h"
17 #include "access/gist.h"
18 #include "access/tuptoaster.h"
19 #include "tsearch/ts_type.h"
20 #include "tsearch/ts_utils.h"
21 #include "utils/pg_crc.h"
24 #define SIGLENINT 31 /* >121 => key will toast, so it will not work
25 * !!! */
27 #define SIGLEN ( sizeof(int4) * SIGLENINT )
28 #define SIGLENBIT (SIGLEN * BITS_PER_BYTE)
30 typedef char BITVEC[SIGLEN];
31 typedef char *BITVECP;
33 #define LOOPBYTE \
34 for(i=0;i<SIGLEN;i++)
36 #define GETBYTE(x,i) ( *( (BITVECP)(x) + (int)( (i) / BITS_PER_BYTE ) ) )
37 #define GETBITBYTE(x,i) ( ((char)(x)) >> (i) & 0x01 )
38 #define CLRBIT(x,i) GETBYTE(x,i) &= ~( 0x01 << ( (i) % BITS_PER_BYTE ) )
39 #define SETBIT(x,i) GETBYTE(x,i) |= ( 0x01 << ( (i) % BITS_PER_BYTE ) )
40 #define GETBIT(x,i) ( (GETBYTE(x,i) >> ( (i) % BITS_PER_BYTE )) & 0x01 )
42 #define HASHVAL(val) (((unsigned int)(val)) % SIGLENBIT)
43 #define HASH(sign, val) SETBIT((sign), HASHVAL(val))
45 #define GETENTRY(vec,pos) ((SignTSVector *) DatumGetPointer((vec)->vector[(pos)].key))
48 * type of GiST index key
51 typedef struct
53 int32 vl_len_; /* varlena header (do not touch directly!) */
54 int4 flag;
55 char data[1];
56 } SignTSVector;
58 #define ARRKEY 0x01
59 #define SIGNKEY 0x02
60 #define ALLISTRUE 0x04
62 #define ISARRKEY(x) ( ((SignTSVector*)(x))->flag & ARRKEY )
63 #define ISSIGNKEY(x) ( ((SignTSVector*)(x))->flag & SIGNKEY )
64 #define ISALLTRUE(x) ( ((SignTSVector*)(x))->flag & ALLISTRUE )
66 #define GTHDRSIZE ( VARHDRSZ + sizeof(int4) )
67 #define CALCGTSIZE(flag, len) ( GTHDRSIZE + ( ( (flag) & ARRKEY ) ? ((len)*sizeof(int4)) : (((flag) & ALLISTRUE) ? 0 : SIGLEN) ) )
69 #define GETSIGN(x) ( (BITVECP)( (char*)(x)+GTHDRSIZE ) )
70 #define GETARR(x) ( (int4*)( (char*)(x)+GTHDRSIZE ) )
71 #define ARRNELEM(x) ( ( VARSIZE(x) - GTHDRSIZE )/sizeof(int4) )
73 /* Number of one-bits in an unsigned byte */
74 static const uint8 number_of_ones[256] = {
75 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
76 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
77 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
78 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
79 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
80 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
81 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
82 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
83 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
84 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
85 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
86 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
87 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
88 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
89 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
90 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
93 static int4 sizebitvec(BITVECP sign);
95 Datum
96 gtsvectorin(PG_FUNCTION_ARGS)
98 ereport(ERROR,
99 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
100 errmsg("gtsvector_in not implemented")));
101 PG_RETURN_DATUM(0);
104 #define SINGOUTSTR "%d true bits, %d false bits"
105 #define ARROUTSTR "%d unique words"
106 #define EXTRALEN ( 2*13 )
108 static int outbuf_maxlen = 0;
110 Datum
111 gtsvectorout(PG_FUNCTION_ARGS)
113 SignTSVector *key = (SignTSVector *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_POINTER(0)));
114 char *outbuf;
116 if (outbuf_maxlen == 0)
117 outbuf_maxlen = 2 * EXTRALEN + Max(strlen(SINGOUTSTR), strlen(ARROUTSTR)) + 1;
118 outbuf = palloc(outbuf_maxlen);
120 if (ISARRKEY(key))
121 sprintf(outbuf, ARROUTSTR, (int) ARRNELEM(key));
122 else
124 int cnttrue = (ISALLTRUE(key)) ? SIGLENBIT : sizebitvec(GETSIGN(key));
126 sprintf(outbuf, SINGOUTSTR, cnttrue, (int) SIGLENBIT - cnttrue);
129 PG_FREE_IF_COPY(key, 0);
130 PG_RETURN_POINTER(outbuf);
133 static int
134 compareint(const void *va, const void *vb)
136 int4 a = *((int4 *) va);
137 int4 b = *((int4 *) vb);
139 if (a == b)
140 return 0;
141 return (a > b) ? 1 : -1;
145 * Removes duplicates from an array of int4. 'l' is
146 * size of the input array. Returns the new size of the array.
148 static int
149 uniqueint(int4 *a, int4 l)
151 int4 *ptr,
152 *res;
154 if (l <= 1)
155 return l;
157 ptr = res = a;
159 qsort((void *) a, l, sizeof(int4), compareint);
161 while (ptr - a < l)
162 if (*ptr != *res)
163 *(++res) = *ptr++;
164 else
165 ptr++;
166 return res + 1 - a;
169 static void
170 makesign(BITVECP sign, SignTSVector *a)
172 int4 k,
173 len = ARRNELEM(a);
174 int4 *ptr = GETARR(a);
176 MemSet((void *) sign, 0, sizeof(BITVEC));
177 for (k = 0; k < len; k++)
178 HASH(sign, ptr[k]);
181 Datum
182 gtsvector_compress(PG_FUNCTION_ARGS)
184 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
185 GISTENTRY *retval = entry;
187 if (entry->leafkey)
188 { /* tsvector */
189 SignTSVector *res;
190 TSVector val = DatumGetTSVector(entry->key);
191 int4 len;
192 int4 *arr;
193 WordEntry *ptr = ARRPTR(val);
194 char *words = STRPTR(val);
196 len = CALCGTSIZE(ARRKEY, val->size);
197 res = (SignTSVector *) palloc(len);
198 SET_VARSIZE(res, len);
199 res->flag = ARRKEY;
200 arr = GETARR(res);
201 len = val->size;
202 while (len--)
204 pg_crc32 c;
206 INIT_CRC32(c);
207 COMP_CRC32(c, words + ptr->pos, ptr->len);
208 FIN_CRC32(c);
210 *arr = *(int4 *) &c;
211 arr++;
212 ptr++;
215 len = uniqueint(GETARR(res), val->size);
216 if (len != val->size)
219 * there is a collision of hash-function; len is always less than
220 * val->size
222 len = CALCGTSIZE(ARRKEY, len);
223 res = (SignTSVector *) repalloc((void *) res, len);
224 SET_VARSIZE(res, len);
227 /* make signature, if array is too long */
228 if (VARSIZE(res) > TOAST_INDEX_TARGET)
230 SignTSVector *ressign;
232 len = CALCGTSIZE(SIGNKEY, 0);
233 ressign = (SignTSVector *) palloc(len);
234 SET_VARSIZE(ressign, len);
235 ressign->flag = SIGNKEY;
236 makesign(GETSIGN(ressign), res);
237 res = ressign;
240 retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
241 gistentryinit(*retval, PointerGetDatum(res),
242 entry->rel, entry->page,
243 entry->offset, FALSE);
245 else if (ISSIGNKEY(DatumGetPointer(entry->key)) &&
246 !ISALLTRUE(DatumGetPointer(entry->key)))
248 int4 i,
249 len;
250 SignTSVector *res;
251 BITVECP sign = GETSIGN(DatumGetPointer(entry->key));
253 LOOPBYTE
255 if ((sign[i] & 0xff) != 0xff)
256 PG_RETURN_POINTER(retval);
259 len = CALCGTSIZE(SIGNKEY | ALLISTRUE, 0);
260 res = (SignTSVector *) palloc(len);
261 SET_VARSIZE(res, len);
262 res->flag = SIGNKEY | ALLISTRUE;
264 retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
265 gistentryinit(*retval, PointerGetDatum(res),
266 entry->rel, entry->page,
267 entry->offset, FALSE);
269 PG_RETURN_POINTER(retval);
272 Datum
273 gtsvector_decompress(PG_FUNCTION_ARGS)
275 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
276 SignTSVector *key = (SignTSVector *) DatumGetPointer(PG_DETOAST_DATUM(entry->key));
278 if (key != (SignTSVector *) DatumGetPointer(entry->key))
280 GISTENTRY *retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
282 gistentryinit(*retval, PointerGetDatum(key),
283 entry->rel, entry->page,
284 entry->offset, FALSE);
286 PG_RETURN_POINTER(retval);
289 PG_RETURN_POINTER(entry);
292 typedef struct
294 int4 *arrb;
295 int4 *arre;
296 } CHKVAL;
299 * is there value 'val' in array or not ?
301 static bool
302 checkcondition_arr(void *checkval, QueryOperand *val)
304 int4 *StopLow = ((CHKVAL *) checkval)->arrb;
305 int4 *StopHigh = ((CHKVAL *) checkval)->arre;
306 int4 *StopMiddle;
308 /* Loop invariant: StopLow <= val < StopHigh */
311 * we are not able to find a a prefix by hash value
313 if ( val->prefix )
314 return true;
316 while (StopLow < StopHigh)
318 StopMiddle = StopLow + (StopHigh - StopLow) / 2;
319 if (*StopMiddle == val->valcrc)
320 return (true);
321 else if (*StopMiddle < val->valcrc)
322 StopLow = StopMiddle + 1;
323 else
324 StopHigh = StopMiddle;
327 return (false);
330 static bool
331 checkcondition_bit(void *checkval, QueryOperand *val)
334 * we are not able to find a a prefix in signature tree
336 if ( val->prefix )
337 return true;
338 return GETBIT(checkval, HASHVAL(val->valcrc));
341 Datum
342 gtsvector_consistent(PG_FUNCTION_ARGS)
344 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
345 TSQuery query = PG_GETARG_TSQUERY(1);
346 /* StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); */
347 /* Oid subtype = PG_GETARG_OID(3); */
348 bool *recheck = (bool *) PG_GETARG_POINTER(4);
349 SignTSVector *key = (SignTSVector *) DatumGetPointer(entry->key);
351 /* All cases served by this function are inexact */
352 *recheck = true;
354 if (!query->size)
355 PG_RETURN_BOOL(false);
357 if (ISSIGNKEY(key))
359 if (ISALLTRUE(key))
360 PG_RETURN_BOOL(true);
362 PG_RETURN_BOOL(TS_execute(
363 GETQUERY(query),
364 (void *) GETSIGN(key), false,
365 checkcondition_bit
368 else
369 { /* only leaf pages */
370 CHKVAL chkval;
372 chkval.arrb = GETARR(key);
373 chkval.arre = chkval.arrb + ARRNELEM(key);
374 PG_RETURN_BOOL(TS_execute(
375 GETQUERY(query),
376 (void *) &chkval, true,
377 checkcondition_arr
382 static int4
383 unionkey(BITVECP sbase, SignTSVector *add)
385 int4 i;
387 if (ISSIGNKEY(add))
389 BITVECP sadd = GETSIGN(add);
391 if (ISALLTRUE(add))
392 return 1;
394 LOOPBYTE
395 sbase[i] |= sadd[i];
397 else
399 int4 *ptr = GETARR(add);
401 for (i = 0; i < ARRNELEM(add); i++)
402 HASH(sbase, ptr[i]);
404 return 0;
408 Datum
409 gtsvector_union(PG_FUNCTION_ARGS)
411 GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
412 int *size = (int *) PG_GETARG_POINTER(1);
413 BITVEC base;
414 int4 i,
415 len;
416 int4 flag = 0;
417 SignTSVector *result;
419 MemSet((void *) base, 0, sizeof(BITVEC));
420 for (i = 0; i < entryvec->n; i++)
422 if (unionkey(base, GETENTRY(entryvec, i)))
424 flag = ALLISTRUE;
425 break;
429 flag |= SIGNKEY;
430 len = CALCGTSIZE(flag, 0);
431 result = (SignTSVector *) palloc(len);
432 *size = len;
433 SET_VARSIZE(result, len);
434 result->flag = flag;
435 if (!ISALLTRUE(result))
436 memcpy((void *) GETSIGN(result), (void *) base, sizeof(BITVEC));
438 PG_RETURN_POINTER(result);
441 Datum
442 gtsvector_same(PG_FUNCTION_ARGS)
444 SignTSVector *a = (SignTSVector *) PG_GETARG_POINTER(0);
445 SignTSVector *b = (SignTSVector *) PG_GETARG_POINTER(1);
446 bool *result = (bool *) PG_GETARG_POINTER(2);
448 if (ISSIGNKEY(a))
449 { /* then b also ISSIGNKEY */
450 if (ISALLTRUE(a) && ISALLTRUE(b))
451 *result = true;
452 else if (ISALLTRUE(a))
453 *result = false;
454 else if (ISALLTRUE(b))
455 *result = false;
456 else
458 int4 i;
459 BITVECP sa = GETSIGN(a),
460 sb = GETSIGN(b);
462 *result = true;
463 LOOPBYTE
465 if (sa[i] != sb[i])
467 *result = false;
468 break;
473 else
474 { /* a and b ISARRKEY */
475 int4 lena = ARRNELEM(a),
476 lenb = ARRNELEM(b);
478 if (lena != lenb)
479 *result = false;
480 else
482 int4 *ptra = GETARR(a),
483 *ptrb = GETARR(b);
484 int4 i;
486 *result = true;
487 for (i = 0; i < lena; i++)
488 if (ptra[i] != ptrb[i])
490 *result = false;
491 break;
496 PG_RETURN_POINTER(result);
499 static int4
500 sizebitvec(BITVECP sign)
502 int4 size = 0,
505 LOOPBYTE
506 size += number_of_ones[(unsigned char) sign[i]];
507 return size;
510 static int
511 hemdistsign(BITVECP a, BITVECP b)
513 int i,
514 diff,
515 dist = 0;
517 LOOPBYTE
519 diff = (unsigned char) (a[i] ^ b[i]);
520 dist += number_of_ones[diff];
522 return dist;
525 static int
526 hemdist(SignTSVector *a, SignTSVector *b)
528 if (ISALLTRUE(a))
530 if (ISALLTRUE(b))
531 return 0;
532 else
533 return SIGLENBIT - sizebitvec(GETSIGN(b));
535 else if (ISALLTRUE(b))
536 return SIGLENBIT - sizebitvec(GETSIGN(a));
538 return hemdistsign(GETSIGN(a), GETSIGN(b));
541 Datum
542 gtsvector_penalty(PG_FUNCTION_ARGS)
544 GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0); /* always ISSIGNKEY */
545 GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1);
546 float *penalty = (float *) PG_GETARG_POINTER(2);
547 SignTSVector *origval = (SignTSVector *) DatumGetPointer(origentry->key);
548 SignTSVector *newval = (SignTSVector *) DatumGetPointer(newentry->key);
549 BITVECP orig = GETSIGN(origval);
551 *penalty = 0.0;
553 if (ISARRKEY(newval))
555 BITVEC sign;
557 makesign(sign, newval);
559 if (ISALLTRUE(origval))
560 *penalty = ((float) (SIGLENBIT - sizebitvec(sign))) / (float) (SIGLENBIT + 1);
561 else
562 *penalty = hemdistsign(sign, orig);
564 else
565 *penalty = hemdist(origval, newval);
566 PG_RETURN_POINTER(penalty);
569 typedef struct
571 bool allistrue;
572 BITVEC sign;
573 } CACHESIGN;
575 static void
576 fillcache(CACHESIGN *item, SignTSVector *key)
578 item->allistrue = false;
579 if (ISARRKEY(key))
580 makesign(item->sign, key);
581 else if (ISALLTRUE(key))
582 item->allistrue = true;
583 else
584 memcpy((void *) item->sign, (void *) GETSIGN(key), sizeof(BITVEC));
587 #define WISH_F(a,b,c) (double)( -(double)(((a)-(b))*((a)-(b))*((a)-(b)))*(c) )
588 typedef struct
590 OffsetNumber pos;
591 int4 cost;
592 } SPLITCOST;
594 static int
595 comparecost(const void *va, const void *vb)
597 SPLITCOST *a = (SPLITCOST *) va;
598 SPLITCOST *b = (SPLITCOST *) vb;
600 if (a->cost == b->cost)
601 return 0;
602 else
603 return (a->cost > b->cost) ? 1 : -1;
607 static int
608 hemdistcache(CACHESIGN *a, CACHESIGN *b)
610 if (a->allistrue)
612 if (b->allistrue)
613 return 0;
614 else
615 return SIGLENBIT - sizebitvec(b->sign);
617 else if (b->allistrue)
618 return SIGLENBIT - sizebitvec(a->sign);
620 return hemdistsign(a->sign, b->sign);
623 Datum
624 gtsvector_picksplit(PG_FUNCTION_ARGS)
626 GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
627 GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
628 OffsetNumber k,
630 SignTSVector *datum_l,
631 *datum_r;
632 BITVECP union_l,
633 union_r;
634 int4 size_alpha,
635 size_beta;
636 int4 size_waste,
637 waste = -1;
638 int4 nbytes;
639 OffsetNumber seed_1 = 0,
640 seed_2 = 0;
641 OffsetNumber *left,
642 *right;
643 OffsetNumber maxoff;
644 BITVECP ptr;
645 int i;
646 CACHESIGN *cache;
647 SPLITCOST *costvector;
649 maxoff = entryvec->n - 2;
650 nbytes = (maxoff + 2) * sizeof(OffsetNumber);
651 v->spl_left = (OffsetNumber *) palloc(nbytes);
652 v->spl_right = (OffsetNumber *) palloc(nbytes);
654 cache = (CACHESIGN *) palloc(sizeof(CACHESIGN) * (maxoff + 2));
655 fillcache(&cache[FirstOffsetNumber], GETENTRY(entryvec, FirstOffsetNumber));
657 for (k = FirstOffsetNumber; k < maxoff; k = OffsetNumberNext(k))
659 for (j = OffsetNumberNext(k); j <= maxoff; j = OffsetNumberNext(j))
661 if (k == FirstOffsetNumber)
662 fillcache(&cache[j], GETENTRY(entryvec, j));
664 size_waste = hemdistcache(&(cache[j]), &(cache[k]));
665 if (size_waste > waste)
667 waste = size_waste;
668 seed_1 = k;
669 seed_2 = j;
674 left = v->spl_left;
675 v->spl_nleft = 0;
676 right = v->spl_right;
677 v->spl_nright = 0;
679 if (seed_1 == 0 || seed_2 == 0)
681 seed_1 = 1;
682 seed_2 = 2;
685 /* form initial .. */
686 if (cache[seed_1].allistrue)
688 datum_l = (SignTSVector *) palloc(CALCGTSIZE(SIGNKEY | ALLISTRUE, 0));
689 SET_VARSIZE(datum_l, CALCGTSIZE(SIGNKEY | ALLISTRUE, 0));
690 datum_l->flag = SIGNKEY | ALLISTRUE;
692 else
694 datum_l = (SignTSVector *) palloc(CALCGTSIZE(SIGNKEY, 0));
695 SET_VARSIZE(datum_l, CALCGTSIZE(SIGNKEY, 0));
696 datum_l->flag = SIGNKEY;
697 memcpy((void *) GETSIGN(datum_l), (void *) cache[seed_1].sign, sizeof(BITVEC));
699 if (cache[seed_2].allistrue)
701 datum_r = (SignTSVector *) palloc(CALCGTSIZE(SIGNKEY | ALLISTRUE, 0));
702 SET_VARSIZE(datum_r, CALCGTSIZE(SIGNKEY | ALLISTRUE, 0));
703 datum_r->flag = SIGNKEY | ALLISTRUE;
705 else
707 datum_r = (SignTSVector *) palloc(CALCGTSIZE(SIGNKEY, 0));
708 SET_VARSIZE(datum_r, CALCGTSIZE(SIGNKEY, 0));
709 datum_r->flag = SIGNKEY;
710 memcpy((void *) GETSIGN(datum_r), (void *) cache[seed_2].sign, sizeof(BITVEC));
713 union_l = GETSIGN(datum_l);
714 union_r = GETSIGN(datum_r);
715 maxoff = OffsetNumberNext(maxoff);
716 fillcache(&cache[maxoff], GETENTRY(entryvec, maxoff));
717 /* sort before ... */
718 costvector = (SPLITCOST *) palloc(sizeof(SPLITCOST) * maxoff);
719 for (j = FirstOffsetNumber; j <= maxoff; j = OffsetNumberNext(j))
721 costvector[j - 1].pos = j;
722 size_alpha = hemdistcache(&(cache[seed_1]), &(cache[j]));
723 size_beta = hemdistcache(&(cache[seed_2]), &(cache[j]));
724 costvector[j - 1].cost = Abs(size_alpha - size_beta);
726 qsort((void *) costvector, maxoff, sizeof(SPLITCOST), comparecost);
728 for (k = 0; k < maxoff; k++)
730 j = costvector[k].pos;
731 if (j == seed_1)
733 *left++ = j;
734 v->spl_nleft++;
735 continue;
737 else if (j == seed_2)
739 *right++ = j;
740 v->spl_nright++;
741 continue;
744 if (ISALLTRUE(datum_l) || cache[j].allistrue)
746 if (ISALLTRUE(datum_l) && cache[j].allistrue)
747 size_alpha = 0;
748 else
749 size_alpha = SIGLENBIT - sizebitvec(
750 (cache[j].allistrue) ? GETSIGN(datum_l) : GETSIGN(cache[j].sign)
753 else
754 size_alpha = hemdistsign(cache[j].sign, GETSIGN(datum_l));
756 if (ISALLTRUE(datum_r) || cache[j].allistrue)
758 if (ISALLTRUE(datum_r) && cache[j].allistrue)
759 size_beta = 0;
760 else
761 size_beta = SIGLENBIT - sizebitvec(
762 (cache[j].allistrue) ? GETSIGN(datum_r) : GETSIGN(cache[j].sign)
765 else
766 size_beta = hemdistsign(cache[j].sign, GETSIGN(datum_r));
768 if (size_alpha < size_beta + WISH_F(v->spl_nleft, v->spl_nright, 0.1))
770 if (ISALLTRUE(datum_l) || cache[j].allistrue)
772 if (!ISALLTRUE(datum_l))
773 MemSet((void *) GETSIGN(datum_l), 0xff, sizeof(BITVEC));
775 else
777 ptr = cache[j].sign;
778 LOOPBYTE
779 union_l[i] |= ptr[i];
781 *left++ = j;
782 v->spl_nleft++;
784 else
786 if (ISALLTRUE(datum_r) || cache[j].allistrue)
788 if (!ISALLTRUE(datum_r))
789 MemSet((void *) GETSIGN(datum_r), 0xff, sizeof(BITVEC));
791 else
793 ptr = cache[j].sign;
794 LOOPBYTE
795 union_r[i] |= ptr[i];
797 *right++ = j;
798 v->spl_nright++;
802 *right = *left = FirstOffsetNumber;
803 v->spl_ldatum = PointerGetDatum(datum_l);
804 v->spl_rdatum = PointerGetDatum(datum_r);
806 PG_RETURN_POINTER(v);