Changeset: 92776816068a for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/92776816068a
Modified Files:
gdk/gdk.h
gdk/gdk_align.c
gdk/gdk_bat.c
gdk/gdk_batop.c
gdk/gdk_bbp.c
gdk/gdk_hash.c
gdk/gdk_join.c
gdk/gdk_private.h
gdk/gdk_select.c
gdk/gdk_unique.c
gdk/gdk_utils.c
monetdb5/mal/mal_profiler.c
Branch: default
Log Message:
Move unique_estimate property into BAT structure.
diffs (280 lines):
diff --git a/gdk/gdk.h b/gdk/gdk.h
--- a/gdk/gdk.h
+++ b/gdk/gdk.h
@@ -725,6 +725,7 @@ typedef struct {
BUN nosorted; /* position that proves sorted==FALSE */
BUN norevsorted; /* position that proves revsorted==FALSE */
BUN minpos, maxpos; /* location of min/max value */
+ double unique_est; /* estimated number of unique values */
oid seq; /* start of dense sequence */
Heap *heap; /* space for the column. */
@@ -796,6 +797,7 @@ typedef struct BAT {
#define tnorevsorted T.norevsorted
#define tminpos T.minpos
#define tmaxpos T.maxpos
+#define tunique_est T.unique_est
#define theap T.heap
#define tbaseoff T.baseoff
#define tvheap T.vheap
@@ -2216,7 +2218,6 @@ gdk_export void VIEWbounds(BAT *b, BAT *
enum prop_t {
GDK_HASH_BUCKETS = 3, /* last used hash bucket size (oid) */
GDK_NUNIQUE, /* number of unique values (oid) */
- GDK_UNIQUE_ESTIMATE, /* estimate of number of distinct values (dbl)
*/
};
gdk_export ValPtr BATgetprop(BAT *b, enum prop_t idx);
diff --git a/gdk/gdk_align.c b/gdk/gdk_align.c
--- a/gdk/gdk_align.c
+++ b/gdk/gdk_align.c
@@ -255,7 +255,7 @@ BATmaterialize(BAT *b)
b->tbaseoff = 0;
b->theap->dirty = true;
BATsetprop_nolock(b, GDK_NUNIQUE, TYPE_oid, &(oid){is_oid_nil(t) ? 1 :
b->batCount});
- BATsetprop_nolock(b, GDK_UNIQUE_ESTIMATE, TYPE_dbl,
&(dbl){is_oid_nil(t) ? 1.0 : (dbl)b->batCount});
+ b->tunique_est = is_oid_nil(t) ? 1.0 : (double) b->batCount;
MT_lock_unset(&b->theaplock);
b->ttype = TYPE_oid;
BATsetdims(b);
diff --git a/gdk/gdk_bat.c b/gdk/gdk_bat.c
--- a/gdk/gdk_bat.c
+++ b/gdk/gdk_bat.c
@@ -92,6 +92,7 @@ BATcreatedesc(oid hseq, int tt, bool hea
.tseqbase = oid_nil,
.tminpos = BUN_NONE,
.tmaxpos = BUN_NONE,
+ .tunique_est = 0.0,
.batRole = role,
.batTransient = true,
@@ -590,6 +591,7 @@ BATclear(BAT *b, bool force)
PROPdestroy(b);
b->tminpos = BUN_NONE;
b->tmaxpos = BUN_NONE;
+ b->tunique_est = 0.0;
/* we must dispose of all inserted atoms */
MT_lock_set(&b->theaplock);
@@ -677,7 +679,7 @@ BATfree(BAT *b)
MT_lock_set(&b->theaplock);
if (nunique != BUN_NONE) {
BATsetprop_nolock(b, GDK_NUNIQUE, TYPE_oid, &(oid){nunique});
- BATsetprop_nolock(b, GDK_UNIQUE_ESTIMATE, TYPE_dbl,
&(dbl){(dbl)nunique});
+ b->tunique_est = (double) nunique;
BATsetprop_nolock(b, GDK_HASH_BUCKETS, TYPE_oid,
&(oid){nbucket});
}
if (b->theap) {
@@ -936,6 +938,7 @@ COLcopy(BAT *b, int tt, bool writable, r
bn->tnil = b->tnil;
bn->tminpos = b->tminpos;
bn->tmaxpos = b->tmaxpos;
+ bn->tunique_est = b->tunique_est;
} else if (ATOMstorage(tt) == ATOMstorage(b->ttype) &&
ATOMcompare(tt) == ATOMcompare(b->ttype)) {
BUN h = BUNlast(b);
@@ -963,6 +966,7 @@ COLcopy(BAT *b, int tt, bool writable, r
}
bn->tminpos = b->tminpos;
bn->tmaxpos = b->tmaxpos;
+ bn->tunique_est = b->tunique_est;
} else {
bn->tsorted = bn->trevsorted = false; /* set based on count
later */
bn->tnonil = bn->tnil = false;
@@ -1050,7 +1054,7 @@ BUNappendmulti(BAT *b, const void *value
}
if (count > BATcount(b) / GDK_UNIQUE_ESTIMATE_KEEP_FRACTION)
- BATrmprop(b, GDK_UNIQUE_ESTIMATE);
+ b->tunique_est = 0;
b->theap->dirty = true;
const void *t = b->ttype == TYPE_msk ? &(msk){false} :
ATOMnilptr(b->ttype);
if (b->ttype == TYPE_oid) {
@@ -1302,7 +1306,7 @@ BUNdelete(BAT *b, oid o)
MT_lock_set(&b->theaplock);
b->batCount--;
if (BATcount(b) < GDK_UNIQUE_ESTIMATE_KEEP_FRACTION)
- BATrmprop_nolock(b, GDK_UNIQUE_ESTIMATE);
+ b->tunique_est = 0;
MT_lock_unset(&b->theaplock);
if (b->batCount <= 1) {
/* some trivial properties */
@@ -1350,6 +1354,7 @@ BUNinplacemulti(BAT *b, const oid *posit
PROPdestroy(b);
b->tminpos = BUN_NONE;
b->tmaxpos = BUN_NONE;
+ b->tunique_est = 0.0;
}
MT_rwlock_wrlock(&b->thashlock);
for (BUN i = 0; i < count; i++) {
@@ -1423,7 +1428,7 @@ BUNinplacemulti(BAT *b, const oid *posit
}
}
if (count > BATcount(b) /
GDK_UNIQUE_ESTIMATE_KEEP_FRACTION)
- BATrmprop(b, GDK_UNIQUE_ESTIMATE);
+ b->tunique_est = 0;
}
HASHdelete_locked(b, p, val); /* first delete old
value from hash */
} else {
@@ -1437,6 +1442,7 @@ BUNinplacemulti(BAT *b, const oid *posit
}
b->tminpos = BUN_NONE;
b->tmaxpos = BUN_NONE;
+ b->tunique_est = 0.0;
}
OIDXdestroy(b);
IMPSdestroy(b);
diff --git a/gdk/gdk_batop.c b/gdk/gdk_batop.c
--- a/gdk/gdk_batop.c
+++ b/gdk/gdk_batop.c
@@ -723,7 +723,7 @@ BATappend2(BAT *b, BAT *n, BAT *s, bool
}
}
if (cnt > BATcount(b) / GDK_UNIQUE_ESTIMATE_KEEP_FRACTION)
- BATrmprop(b, GDK_UNIQUE_ESTIMATE);
+ b->tunique_est = 0;
/* load hash so that we can maintain it */
(void) BATcheckhash(b);
@@ -1042,6 +1042,7 @@ BATdel(BAT *b, BAT *d)
b->tnokey[0] = b->tnokey[1] = 0;
b->tminpos = BUN_NONE;
b->tmaxpos = BUN_NONE;
+ b->tunique_est = 0.0;
return GDK_SUCCEED;
}
@@ -1104,7 +1105,7 @@ BATappend_or_update(BAT *b, BAT *p, cons
OIDXdestroy(b);
IMPSdestroy(b);
if (ni.count > BATcount(b) / GDK_UNIQUE_ESTIMATE_KEEP_FRACTION)
- BATrmprop(b, GDK_UNIQUE_ESTIMATE);
+ b->tunique_est = 0;
/* load hash so that we can maintain it */
(void) BATcheckhash(b);
diff --git a/gdk/gdk_bbp.c b/gdk/gdk_bbp.c
--- a/gdk/gdk_bbp.c
+++ b/gdk/gdk_bbp.c
@@ -495,6 +495,7 @@ heapinit(BAT *b, const char *buf,
b->tnil = (properties & 0x0800) != 0;
b->tnosorted = (BUN) nosorted;
b->tnorevsorted = (BUN) norevsorted;
+ b->tunique_est = 0.0;
/* (properties & 0x0200) is the old tdense flag */
b->tseqbase = (properties & 0x0200) == 0 || base >= (uint64_t) oid_nil
? oid_nil : (oid) base;
b->theap->free = (size_t) free;
diff --git a/gdk/gdk_hash.c b/gdk/gdk_hash.c
--- a/gdk/gdk_hash.c
+++ b/gdk/gdk_hash.c
@@ -816,9 +816,8 @@ BAThash_impl(BAT *restrict b, struct can
maxmask = HASHmask(ci->ncand);
if (mask > maxmask)
mask = maxmask;
- } else if (!hascand && (prop = BATgetprop_try(b, GDK_UNIQUE_ESTIMATE))
!= NULL) {
- assert(prop->vtype == TYPE_dbl);
- mask = (BUN) (prop->val.dval * 8 / 7);
+ } else if (!hascand && b->tunique_est != 0) {
+ mask = (BUN) (b->tunique_est * 1.15); /* about 8/7 */
} else {
/* dynamic hash: we start with HASHmask(ci->ncand)/64, or,
* if ci->ncand large enough, HASHmask(ci->ncand)/256; if there
diff --git a/gdk/gdk_join.c b/gdk/gdk_join.c
--- a/gdk/gdk_join.c
+++ b/gdk/gdk_join.c
@@ -3220,11 +3220,10 @@ guess_uniques(BAT *b, struct canditer *c
if (ci->s == NULL ||
(ci->tpe == cand_dense && ci->ncand == BATcount(b))) {
- const ValRecord *p = BATgetprop(b, GDK_UNIQUE_ESTIMATE);
- if (p) {
+ if (b->tunique_est != 0) {
TRC_DEBUG(ALGO, "b=" ALGOBATFMT " use cached value\n",
ALGOBATPAR(b));
- return p->val.dval;
+ return b->tunique_est;
}
s1 = BATsample_with_seed(b, 1000, (uint64_t) GDKusec() *
(uint64_t) b->batCacheid);
} else {
@@ -3243,7 +3242,7 @@ guess_uniques(BAT *b, struct canditer *c
B += A * ci->ncand;
if (ci->s == NULL ||
(ci->tpe == cand_dense && ci->ncand == BATcount(b))) {
- BATsetprop(b, GDK_UNIQUE_ESTIMATE, TYPE_dbl, &B);
+ b->tunique_est = B;
}
return B;
}
diff --git a/gdk/gdk_private.h b/gdk/gdk_private.h
--- a/gdk/gdk_private.h
+++ b/gdk/gdk_private.h
@@ -464,7 +464,7 @@ extern MT_Lock GDKtmLock;
#define BBP_free(y) GDKbbpLock[y].free
/* when the number of updates to a BAT is less than 1 in this number, we
- * keep the GDK_UNIQUE_ESTIMATE property */
+ * keep the unique_est property */
extern BUN GDK_UNIQUE_ESTIMATE_KEEP_FRACTION; /* should become a define once */
/* if the number of unique values is less than 1 in this number, we
* destroy the hash rather than update it in HASH{append,insert,delete} */
diff --git a/gdk/gdk_select.c b/gdk/gdk_select.c
--- a/gdk/gdk_select.c
+++ b/gdk/gdk_select.c
@@ -1584,9 +1584,8 @@ BATselect(BAT *b, BAT *s, const void *tl
ATOMsize(b->ttype) >= sizeof(BUN) / 4 &&
BATcount(b) * (ATOMsize(b->ttype) + 2 * sizeof(BUN)) <
GDK_mem_maxsize / 2);
if (wanthash && !havehash) {
- const ValRecord *prop;
- if ((prop = BATgetprop(b, GDK_UNIQUE_ESTIMATE)) != NULL
&&
- prop->val.dval < BATcount(b) /
NO_HASH_SELECT_FRACTION) {
+ if (b->tunique_est != 0 &&
+ b->tunique_est < BATcount(b) /
NO_HASH_SELECT_FRACTION) {
/* too many duplicates: not worth it */
wanthash = false;
}
diff --git a/gdk/gdk_unique.c b/gdk/gdk_unique.c
--- a/gdk/gdk_unique.c
+++ b/gdk/gdk_unique.c
@@ -92,8 +92,8 @@ BATunique(BAT *b, BAT *s)
MT_lock_set(&b->theaplock);
if ((prop = BATgetprop_nolock(b, GDK_NUNIQUE)) != NULL)
initsize = prop->val.oval;
- else if ((prop = BATgetprop_nolock(b,
GDK_UNIQUE_ESTIMATE)) != NULL)
- initsize = (BUN) prop->val.dval;
+ else if (b->tunique_est != 0)
+ initsize = (BUN) b->tunique_est;
MT_lock_unset(&b->theaplock);
}
}
diff --git a/gdk/gdk_utils.c b/gdk/gdk_utils.c
--- a/gdk/gdk_utils.c
+++ b/gdk/gdk_utils.c
@@ -58,7 +58,7 @@ static void GDKunlockHome(int farmid);
#undef free
/* when the number of updates to a BAT is less than 1 in this number, we
- * keep the GDK_UNIQUE_ESTIMATE property */
+ * keep the unique_est property */
BUN GDK_UNIQUE_ESTIMATE_KEEP_FRACTION = 1000; /* should become a define once */
/* if the number of unique values is less than 1 in this number, we
* destroy the hash rather than update it in HASH{append,insert,delete} */
diff --git a/monetdb5/mal/mal_profiler.c b/monetdb5/mal/mal_profiler.c
--- a/monetdb5/mal/mal_profiler.c
+++ b/monetdb5/mal/mal_profiler.c
@@ -382,13 +382,14 @@ prepareProfilerEvent(Client cntxt, MalBl
if ((d->tminpos != BUN_NONE &&
!logadd(&logbuf,
",\"minpos\":\""BUNFMT"\"", d->tminpos)) ||
(d->tmaxpos != BUN_NONE &&
- !logadd(&logbuf,
",\"maxpos\":\""BUNFMT"\"", d->tmaxpos))) {
+ !logadd(&logbuf,
",\"maxpos\":\""BUNFMT"\"", d->tmaxpos)) ||
+ (d->tunique_est != 0 &&
+ !logadd(&logbuf,
",\"nestimate\":\"%g\"", d->tunique_est))) {
BBPunfix(d->batCacheid);
goto cleanup_and_exit;
}
keepprop(GDK_HASH_BUCKETS,"hbuckets");
keepprop(GDK_NUNIQUE,"nunique");
-
keepprop(GDK_UNIQUE_ESTIMATE,"nestimate");
cv =
VALformat(&stk->stk[getArg(pci,j)]);
c = strchr(cv, '>');
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list