void gbt_var_bin_union(Datum *u, GBT_VARKEY *e, Oid collation, const gbtree_vinfo *tinfo) { GBT_VARKEY_R eo = gbt_var_key_readable(e); GBT_VARKEY_R nr; if (eo.lower == eo.upper) /* leaf */ { GBT_VARKEY *tmp; tmp = gbt_var_leaf2node(e, tinfo); if (tmp != e) eo = gbt_var_key_readable(tmp); } if (DatumGetPointer(*u)) { GBT_VARKEY_R ro = gbt_var_key_readable((GBT_VARKEY *) DatumGetPointer(*u)); bool update = false; nr.lower = ro.lower; nr.upper = ro.upper; if ((*tinfo->f_cmp) (ro.lower, eo.lower, collation) > 0) { nr.lower = eo.lower; update = true; } if ((*tinfo->f_cmp) (ro.upper, eo.upper, collation) < 0) { nr.upper = eo.upper; update = true; } if (update) *u = PointerGetDatum(gbt_var_key_copy(&nr)); } else { nr.lower = eo.lower; nr.upper = eo.upper; *u = PointerGetDatum(gbt_var_key_copy(&nr)); } }
void gbt_var_bin_union(Datum *u, GBT_VARKEY *e, Oid collation, const gbtree_vinfo *tinfo) { GBT_VARKEY *nk = NULL; GBT_VARKEY *tmp = NULL; GBT_VARKEY_R nr; GBT_VARKEY_R eo = gbt_var_key_readable(e); if (eo.lower == eo.upper) /* leaf */ { tmp = gbt_var_leaf2node(e, tinfo); if (tmp != e) eo = gbt_var_key_readable(tmp); } if (DatumGetPointer(*u)) { GBT_VARKEY_R ro = gbt_var_key_readable((GBT_VARKEY *) DatumGetPointer(*u)); if ((*tinfo->f_cmp) (ro.lower, eo.lower, collation) > 0) { nr.lower = eo.lower; nr.upper = ro.upper; nk = gbt_var_key_copy(&nr, TRUE); } if ((*tinfo->f_cmp) (ro.upper, eo.upper, collation) < 0) { nr.upper = eo.upper; nr.lower = ro.lower; nk = gbt_var_key_copy(&nr, TRUE); } if (nk) *u = PointerGetDatum(nk); } else { nr.lower = eo.lower; nr.upper = eo.upper; *u = PointerGetDatum(gbt_var_key_copy(&nr, TRUE)); } }
GIST_SPLITVEC * gbt_var_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v, Oid collation, const gbtree_vinfo *tinfo) { OffsetNumber i, maxoff = entryvec->n - 1; Vsrt *arr; int svcntr = 0, nbytes; char *cur; GBT_VARKEY **sv = NULL; gbt_vsrt_arg varg; arr = (Vsrt *) palloc((maxoff + 1) * sizeof(Vsrt)); 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; sv = palloc(sizeof(bytea *) * (maxoff + 1)); /* Sort entries */ for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) { GBT_VARKEY_R ro; cur = (char *) DatumGetPointer(entryvec->vector[i].key); ro = gbt_var_key_readable((GBT_VARKEY *) cur); if (ro.lower == ro.upper) /* leaf */ { sv[svcntr] = gbt_var_leaf2node((GBT_VARKEY *) cur, tinfo); arr[i].t = sv[svcntr]; if (sv[svcntr] != (GBT_VARKEY *) cur) svcntr++; } else arr[i].t = (GBT_VARKEY *) cur; arr[i].i = i; } /* sort */ varg.tinfo = tinfo; varg.collation = collation; qsort_arg((void *) &arr[FirstOffsetNumber], maxoff - FirstOffsetNumber + 1, sizeof(Vsrt), gbt_vsrt_cmp, (void *) &varg); /* We do simply create two parts */ for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) { if (i <= (maxoff - FirstOffsetNumber + 1) / 2) { gbt_var_bin_union(&v->spl_ldatum, arr[i].t, collation, tinfo); v->spl_left[v->spl_nleft] = arr[i].i; v->spl_nleft++; } else { gbt_var_bin_union(&v->spl_rdatum, arr[i].t, collation, tinfo); v->spl_right[v->spl_nright] = arr[i].i; v->spl_nright++; } } /* Truncate (=compress) key */ if (tinfo->trnc) { int32 ll = gbt_var_node_cp_len((GBT_VARKEY *) DatumGetPointer(v->spl_ldatum), tinfo); int32 lr = gbt_var_node_cp_len((GBT_VARKEY *) DatumGetPointer(v->spl_rdatum), tinfo); GBT_VARKEY *dl; GBT_VARKEY *dr; ll = Max(ll, lr); ll++; dl = gbt_var_node_truncate((GBT_VARKEY *) DatumGetPointer(v->spl_ldatum), ll, tinfo); dr = gbt_var_node_truncate((GBT_VARKEY *) DatumGetPointer(v->spl_rdatum), ll, tinfo); v->spl_ldatum = PointerGetDatum(dl); v->spl_rdatum = PointerGetDatum(dr); } return v; }
float * gbt_var_penalty(float *res, const GISTENTRY *o, const GISTENTRY *n, Oid collation, const gbtree_vinfo *tinfo) { GBT_VARKEY *orge = (GBT_VARKEY *) DatumGetPointer(o->key); GBT_VARKEY *newe = (GBT_VARKEY *) DatumGetPointer(n->key); GBT_VARKEY_R ok, nk; GBT_VARKEY *tmp = NULL; *res = 0.0; nk = gbt_var_key_readable(newe); if (nk.lower == nk.upper) /* leaf */ { tmp = gbt_var_leaf2node(newe, tinfo); if (tmp != newe) nk = gbt_var_key_readable(tmp); } ok = gbt_var_key_readable(orge); if ((VARSIZE(ok.lower) - VARHDRSZ) == 0 && (VARSIZE(ok.upper) - VARHDRSZ) == 0) *res = 0.0; else if (!(((*tinfo->f_cmp) (nk.lower, ok.lower, collation) >= 0 || gbt_bytea_pf_match(ok.lower, nk.lower, tinfo)) && ((*tinfo->f_cmp) (nk.upper, ok.upper, collation) <= 0 || gbt_bytea_pf_match(ok.upper, nk.upper, tinfo)))) { Datum d = PointerGetDatum(0); double dres = 0.0; int32 ol, ul; gbt_var_bin_union(&d, orge, collation, tinfo); ol = gbt_var_node_cp_len((GBT_VARKEY *) DatumGetPointer(d), tinfo); gbt_var_bin_union(&d, newe, collation, tinfo); ul = gbt_var_node_cp_len((GBT_VARKEY *) DatumGetPointer(d), tinfo); if (ul < ol) { dres = (ol - ul); /* lost of common prefix len */ } else { GBT_VARKEY_R uk = gbt_var_key_readable((GBT_VARKEY *) DatumGetPointer(d)); char tmp[4]; tmp[0] = ((VARSIZE(ok.lower) - VARHDRSZ) == ul) ? (CHAR_MIN) : (VARDATA(ok.lower)[ul]); tmp[1] = ((VARSIZE(uk.lower) - VARHDRSZ) == ul) ? (CHAR_MIN) : (VARDATA(uk.lower)[ul]); tmp[2] = ((VARSIZE(ok.upper) - VARHDRSZ) == ul) ? (CHAR_MIN) : (VARDATA(ok.upper)[ul]); tmp[3] = ((VARSIZE(uk.upper) - VARHDRSZ) == ul) ? (CHAR_MIN) : (VARDATA(uk.upper)[ul]); dres = (tmp[0] - tmp[1]) + (tmp[3] - tmp[2]); dres /= 256.0; } *res += FLT_MIN; *res += (float) (dres / ((double) (ol + 1))); *res *= (FLT_MAX / (o->rel->rd_att->natts + 1)); } return res; }