From 5f741122fa3313bf02f6e1320866b56ed1d87444 Mon Sep 17 00:00:00 2001 From: Vitor Santos Costa Date: Mon, 5 Aug 2013 15:07:51 -0500 Subject: [PATCH] more user udi fixes --- C/exo.c | 30 ++++-- C/exo_udi.c | 279 ++++++++++++++++++++++++++++++++-------------------- H/clause.h | 1 + 3 files changed, 193 insertions(+), 117 deletions(-) diff --git a/C/exo.c b/C/exo.c index cc23dee78..8bcd92091 100644 --- a/C/exo.c +++ b/C/exo.c @@ -186,13 +186,13 @@ HASH_FVN_1A(UInt arity, CELL *cl, UInt bnds[], UInt sz); spread over j quadrants. */ extern inline BITS32 -HASH_FVN_1A(UInt ar, CELL *cl, UInt bnds[], UInt sz) +HASH_FVN_1A(UInt arity, CELL *cl, UInt bnds[], UInt sz) { UInt hash; UInt j=0; hash = FNV32_OFFSET; - while (j < ar) { + while (j < arity) { if (bnds[j]) { unsigned char *i=(unsigned char*)(cl+j); unsigned char *m=(unsigned char*)(cl+(j+1)); @@ -219,12 +219,18 @@ HASH_FVN_1A(UInt ar, CELL *cl, UInt bnds[], UInt sz) #else /* Default: TEST_HASH_FVN */ # define HASH(...) HASH_FVN_1A(__VA_ARGS__) +# define HASH1(...) HASH_MURMUR3_32(__VA_ARGS__) #endif static BITS32 -NEXT(UInt hash) +NEXT(UInt arity, CELL *cl, UInt bnds[], UInt sz, BITS32 hash) { - return (hash*997); + int i = 0; + BITS32 hash1; + + while (bnds[i]==0) i++; + hash1 = HASH1(arity, cl, bnds, sz); + return (hash + hash1 +cl[i]); } /* search for matching elements */ @@ -289,6 +295,8 @@ INSERT(CELL *cl, struct index_t *it, UInt arity, UInt base, UInt bnds[]) /* simple case, new entry */ it->nentries++; it->key[hash % it->hsize ] = EXO_ADDRESS_TO_OFFSET(it, cl); + if (coll_count > it -> max_col_count) + it->max_col_count = coll_count; return TRUE; } else if (MATCH(kvp, cl, arity, bnds)) { it->ntrys++; @@ -296,11 +304,9 @@ INSERT(CELL *cl, struct index_t *it, UInt arity, UInt base, UInt bnds[]) return TRUE; } else { coll_count++; - if (coll_count == 32) - return FALSE; it->ncollisions++; // printf("#"); - hash = NEXT(hash); + hash = NEXT(arity, cl, bnds, it->hsize, hash); //if (exo_write) printf("N=%ld\n", hash); goto next; } @@ -330,7 +336,7 @@ LOOKUP(struct index_t *it, UInt arity, UInt j, UInt bnds[]) return NEXTOP(NEXTOP(it->code,lp),lp); } else { /* collision */ - hash = NEXT(hash); + hash = NEXT(arity, XREGS+1, bnds, it->hsize, hash); goto next; } } @@ -409,6 +415,9 @@ add_index(struct index_t **ip, UInt bmap, PredEntry *ap, UInt count) i->ncollisions = i->nentries = i->ntrys = 0; i->cls = (CELL *)((ADDR)ap->cs.p_code.FirstClause+2*sizeof(struct index_t *)); i->bcls= i->cls-i->arity; + i->udi_free_args = 0; + i->is_udi = FALSE; + i->udi_arg = 0; *ip = i; while (count) { if (!fill_hash(bmap, i, bnds)) { @@ -428,7 +437,7 @@ add_index(struct index_t **ip, UInt bmap, PredEntry *ap, UInt count) continue; } #if DEBUG - fprintf(stderr, "entries=%ld collisions=%ld trys=%ld\n", i->nentries, i->ncollisions, i->ntrys); + fprintf(stderr, "entries=%ld collisions=%ld (max=%ld) trys=%ld\n", i->nentries, i->ncollisions, i->max_col_count, i->ntrys); #endif if (!i->ntrys && !i->is_key) { i->is_key = TRUE; @@ -533,7 +542,8 @@ Yap_ExoLookup(PredEntry *ap USES_REGS) return code; if (i->is_udi) return ((CEnterExoIndex)i->udi_first)(i PASS_REGS); - else return code; + else + return code; } else if(i->is_udi) { return ((CEnterExoIndex)i->udi_first)(i PASS_REGS); } else { diff --git a/C/exo_udi.c b/C/exo_udi.c index 9ceb47a53..d0fde83a3 100644 --- a/C/exo_udi.c +++ b/C/exo_udi.c @@ -47,30 +47,47 @@ compar(const void *ip0, const void *jp0) { return IntOfTerm(i)-IntOfTerm(j); } +static Int +cmp_extra_args(CELL *si, CELL *sj, struct index_t *it) +{ + UInt m = it->udi_free_args; + UInt m0 = 1, x; + + for (x=0; x< it->arity; x++) { + if (m0 & m) { + if (si[x] != sj[x]) { + if (IsIntTerm(si[x])) + return IntOfTerm(si[x])-IntOfTerm(sj[x]); + return AtomOfTerm(si[x])-AtomOfTerm(sj[x]); + } + m -= m0; + if (m == 0) + return 0; + } + m0 <<= 1; + } + return 0; +} + +static int +compar2(const void *ip0, const void *jp0) { + CACHE_REGS + BITS32 *ip = (BITS32 *)ip0, *jp = (BITS32 *)jp0; + struct index_t *it = LOCAL_exo_it; + Term* si = EXO_OFFSET_TO_ADDRESS(it, *ip); + Term* sj = EXO_OFFSET_TO_ADDRESS(it, *jp); + int cmp = cmp_extra_args(si, sj, it); + if (cmp) + return cmp; + return IntOfTerm(si[LOCAL_exo_arg])-IntOfTerm(sj[LOCAL_exo_arg]); +} + static int compare(const BITS32 *ip, Int j USES_REGS) { Term i = EXO_OFFSET_TO_ADDRESS(LOCAL_exo_it, *ip)[LOCAL_exo_arg]; //fprintf(stderr, "%ld-%ld\n", IntOfTerm(i), j); return IntOfTerm(i)-j; - } - -static int -same_free(BITS32 i, BITS32 j, struct index_t *it) { - CELL *ip = EXO_OFFSET_TO_ADDRESS(it, i); - CELL *jp = EXO_OFFSET_TO_ADDRESS(it, j); - UInt m = it->udi_free_args, m0 = 1, x; - for (x=0; x< it->arity; x++) { - if (m0 & m) { - if (ip[x] != jp[x]) - return FALSE; - m -= m0; - if (!m) - return TRUE; - } - m0 <<= 1; - } - return TRUE; - } +} static UInt free_args(UInt b[], UInt arity, UInt i) { UInt j; @@ -83,46 +100,94 @@ static UInt free_args(UInt b[], UInt arity, UInt i) { return rc; } -static void -chain(BITS32 *p0, BITS32 *el, BITS32 n, struct index_t *it) { - UInt i; +static BITS32* +NEXT_DIFFERENT(BITS32 *pt0, BITS32 *pte, struct index_t *it) +{ + Term* si = EXO_OFFSET_TO_ADDRESS(it, pt0[0]); + Term* sj; - for (i=0; i= x) - return x; - } - return x; + Term* si = EXO_OFFSET_TO_ADDRESS(it, pt0[0]); + Term* sj; + + do { + pt0--; + if (pt0 == pte) + return NULL; + sj = EXO_OFFSET_TO_ADDRESS(it, *pt0); + } while (!cmp_extra_args(si, sj, it)); + return pt0; } -static Int -BIGGEST_EL(Int x0, BITS32 *p, Int xe) +static BITS32* +NEXT_MIN(BITS32 *pt0, BITS32 *pte, Term tmin, Term tmax, struct index_t *it) { - Int x = x0; + Term* si = EXO_OFFSET_TO_ADDRESS(it, pt0[0]); + int do_min, do_max; + Int min = 0, max = 0; - while (x <= xe) { - if (p[x] == x0) - x0 = x; - x++; + if (IsVarTerm(tmin)) { + do_min = FALSE; + } else { + do_min = TRUE; + min = IntOfTerm(tmin); } - return x0; + if (IsVarTerm(tmax)) { + do_max = FALSE; + } else { + do_max = TRUE; + max = IntOfTerm(tmax); + } + + while ((do_min && IntOfTerm(si[it->udi_arg]) < min) || + (do_max && IntOfTerm(si[it->udi_arg]) > max)) { + pt0++; + if (pt0 == pte) + return NULL; + si = EXO_OFFSET_TO_ADDRESS(it, *pt0); + } + return pt0; +} + +static BITS32* +NEXT_MAX(BITS32 *pt0, BITS32 *pte, Term tmin, Term tmax, struct index_t *it) +{ + Term* si = EXO_OFFSET_TO_ADDRESS(it, pt0[0]); + int do_min, do_max; + Int min = 0, max = 0; + + if (IsVarTerm(tmin)) { + do_min = FALSE; + } else { + do_min = TRUE; + min = IntOfTerm(tmin); + } + if (IsVarTerm(tmax)) { + do_max = FALSE; + } else { + do_max = TRUE; + max = IntOfTerm(tmax); + } + + while ((do_min && IntOfTerm(si[it->udi_arg]) < min) || + (do_max && IntOfTerm(si[it->udi_arg]) > max)) { + pt0--; + if (pt0 == pte) + return NULL; + si = EXO_OFFSET_TO_ADDRESS(it, *pt0); + } + return pt0; } static void @@ -161,11 +226,11 @@ IntervalUDIRefitIndex(struct index_t **ip, UInt b[] USES_REGS) /* be conservative */ if (it->udi_free_args) - sz = sizeof(BITS32)*(3*it->ntrys+3*it->nentries); + sz = sizeof(BITS32)*(2*it->ntrys+3*it->nentries); else - sz = sizeof(BITS32)*(2*it->ntrys+2*it->nentries); + sz = sizeof(BITS32)*(it->ntrys+2*it->nentries); /* allocate space */ - if (!(it->udi_data = (BITS32*)Yap_AllocCodeSpace(sz))) + if (!(it->udi_data = (BITS32*)malloc(sz))) return; sorted0 = sorted = (BITS32 *)it->udi_data; sorted++; /* leave an initial hole */ @@ -189,18 +254,16 @@ IntervalUDIRefitIndex(struct index_t **ip, UInt b[] USES_REGS) *s0 = sorted - (s0+1); qsort(s0+1, (size_t)*s0, sizeof(BITS32), compar); it->links[offset0] = s0-sorted0; - // fprintf(stderr," %d links %d=%d \n", offset0, s0-sorted0, s0[0]); if (it->udi_free_args) { - bzero(sorted, sizeof(BITS32)*(*s0)); - /* chain elements with same unbound vars together */ - chain(sorted, s0+1, *s0, it); + memcpy(sorted, s0+1, sizeof(BITS32)*(*s0)); + qsort(sorted, (size_t)*s0, sizeof(BITS32), compar2); sorted += *s0; } } } } sz = sizeof(BITS32)*(sorted-sorted0); - it->udi_data = (BITS32 *)Yap_ReallocCodeSpace((char *)it->udi_data, sz); + it->udi_data = (BITS32 *)realloc((char *)it->udi_data, sz); } it->is_udi = i+1; code = it->code; @@ -362,43 +425,48 @@ Interval(struct index_t *it, Term min, Term max, Term op, BITS32 off USES_REGS) return FAILCODE; S = EXO_OFFSET_TO_ADDRESS(it, pt[0]); } else if (at == AtomMin) { - Int x0, xe, x; - - if (!(it->udi_free_args)) { + S = EXO_OFFSET_TO_ADDRESS(it, pt[0]); + if (it->udi_free_args) { + BITS32 *ptn; + pt = c+(it->links[off]+n+1); + end = pt+n; + pt = NEXT_MIN(pt, end, min, max, it); + if (!pt) + return FAILCODE; S = EXO_OFFSET_TO_ADDRESS(it, pt[0]); - } else { - x0 = pt-pt0; - xe = end-pt0; - S = EXO_OFFSET_TO_ADDRESS(it, pt[0]); - x = NEXT_DIFFERENT(x0, x0, end0, xe); - if (x < xe ) { - YENV[-5] = (CELL)( pt0 ); // base for array of pointed pointers - YENV[-4] = MkIntegerTerm( x ); // where we are in pt0 array - YENV[-3] = MkIntegerTerm( xe ); // our visit will end here - YENV[-2] = MkIntegerTerm( x0 ); // our visit started here - YENV[-1] = (CELL)( end0 ); // base for array into pt + ptn = NEXT_DIFFERENT(pt, end, it); + if (ptn) + ptn = NEXT_MIN(ptn, end, min, max, it); + if ( ptn ) { + YENV[-1] = min; // what we are doing + YENV[-2] = max; // what we are doing + YENV[-3] = (CELL) end; // what we are doing + YENV[-4] = MkAtomTerm(AtomMin); // what we are doing + YENV[-5] = (CELL)( ptn ); // where we are in pt0 array YENV -= 5; return it->code; } } return NEXTOP(NEXTOP(it->code,lp),lp); } else if (at == AtomMax) { - Int x0, xe, x, y; - - if (!(it->udi_free_args)) { - S = EXO_OFFSET_TO_ADDRESS(it, end[0]); - } else { - x0 = pt-pt0; - xe = end-pt0; - y = BIGGEST_EL( x0, end0, xe ); + S = EXO_OFFSET_TO_ADDRESS(it, pt[0]); + if (it->udi_free_args) { + BITS32 *ptn; + end = c+(it->links[off]+n); + pt = end+n; + pt = NEXT_MAX(pt, end, min, max, it); + if (!pt) + return FAILCODE; S = EXO_OFFSET_TO_ADDRESS(it, pt[0]); - x = NEXT_DIFFERENT(x0, x0, end0, xe); - if (x < xe ) { - YENV[-5] = (CELL)( pt0 ); // base for array of pointed pointers - YENV[-4] = MkIntegerTerm( -x ); // where we are in pt0 array - YENV[-3] = MkIntegerTerm( xe ); // our visit will end here - YENV[-2] = MkIntegerTerm( x0 ); // our visit started here - YENV[-1] = (CELL)( end0 ); // base for array into pt + ptn = PREV_DIFFERENT(pt, end, it); + if (ptn) + ptn = NEXT_MAX(ptn, end, min, max, it); + if ( ptn ) { + YENV[-1] = min; // what we are doing + YENV[-2] = max; // what we are doing + YENV[-3] = (CELL) end; // what we are doing + YENV[-4] = MkAtomTerm(AtomMax); // what we are doing + YENV[-5] = (CELL)( ptn ); // where we are in pt0 array YENV -= 5; return it->code; } @@ -450,28 +518,25 @@ IntervalRetryUDIIndex(struct index_t *it USES_REGS) w[1] = (CELL)pt; } else { BITS32 *pt0 = (BITS32 *)w[1]; - Int x = IntegerOfTerm( w[2] ); - Int xe = IntegerOfTerm( w[3] ); - Int x0 = IntegerOfTerm( w[4] ); - BITS32 *base = (BITS32 *)w[5]; - if ( x > 0) { - //Yap_DebugPlWrite( EXO_OFFSET_TO_ADDRESS(it, el[i])[1] ); fprintf(stderr,"\n"); - S = EXO_OFFSET_TO_ADDRESS(it, pt0[x]); - //fprintf(stderr,"S=%p x=%d/%d %d %d %p %p \n", S, x, base[x], x0, xe, pt0, base); - x = NEXT_DIFFERENT(x0, x, base, xe); - if (x > xe) return FALSE; - w[2] = MkIntegerTerm(x); + BITS32 *pte = (BITS32 *)w[3]; + Atom what = AtomOfTerm(w[2]); + Term min = w[5]; + Term max = w[4]; + + S = EXO_OFFSET_TO_ADDRESS(it, pt0[0]); + if ( what == AtomMin ) { + pt0 = NEXT_DIFFERENT(pt0, pte, it); + if (pt0) + pt0 = NEXT_MIN(pt0, pte, min, max, it); } else { - x = -x; - //Yap_DebugPlWrite( EXO_OFFSET_TO_ADDRESS(it, el[i])[1] ); fprintf(stderr,"\n"); - S = EXO_OFFSET_TO_ADDRESS(it, pt0[BIGGEST_EL(x, base, xe) ]); - x = NEXT_DIFFERENT(x0, x, base, xe); - // fprintf(stderr,"S=%p x=%d/%d %d %d %p %p \n", S, x, base[x], x0, xe, pt0, base); - if (x > xe) { - return FALSE; - } - w[2] = MkIntegerTerm(-x); + pt0 = PREV_DIFFERENT(pt0, pte, it); + if (pt0) + pt0 = NEXT_MAX(pt0, pte, min, max, it); } + if (!pt0) { + return FALSE; + } + w[1] = (CELL)pt0; } return TRUE; } diff --git a/H/clause.h b/H/clause.h index f8c6a0ad0..64e0e13ef 100644 --- a/H/clause.h +++ b/H/clause.h @@ -168,6 +168,7 @@ typedef struct index_t { int is_key; int is_udi; UInt ncollisions; + UInt max_col_count; UInt ntrys; UInt nentries; UInt hsize;