Changeset: ac637e0e0709 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=ac637e0e0709
Modified Files:
gdk/gdk_bbp.c
gdk/gdk_sample.c
Branch: default
Log Message:
Use a global pseudo random number state for BATsample.
The global state is protected by a lock. BATsample_with_seed does not
use this state but uses its own and therefore doesn't need or use a
lock.
Also some cleanup of the code.
diffs (125 lines):
diff --git a/gdk/gdk_bbp.c b/gdk/gdk_bbp.c
--- a/gdk/gdk_bbp.c
+++ b/gdk/gdk_bbp.c
@@ -1318,6 +1318,7 @@ BBPinit(void)
#ifdef NEED_MT_LOCK_INIT
MT_lock_init(&GDKunloadLock, "GDKunloadLock");
ATOMIC_INIT(BBPsizeLock);
+ BATsample(NULL, 0); /* initializes the lock */
#endif
if (BBPfarms[0].dirname == NULL) {
diff --git a/gdk/gdk_sample.c b/gdk/gdk_sample.c
--- a/gdk/gdk_sample.c
+++ b/gdk/gdk_sample.c
@@ -28,23 +28,6 @@
#include "gdk_private.h"
#include "xoshiro256starstar.h"
-#undef BATsample
-
-#ifdef STATIC_CODE_ANALYSIS
-#define DRAND (0.5)
-#else
-/* the range of rand() is [0..RAND_MAX], i.e. inclusive;
- * cast first, add later: on Linux RAND_MAX == INT_MAX, so adding 1
- * will overflow, but INT_MAX does fit in a double */
-#if RAND_MAX < 46340 /* 46340*46340 = 2147395600 < INT_MAX */
-/* random range is too small, double it */
-#define DRAND ((double)(rand() * (RAND_MAX + 1) + rand()) / ((double)
((RAND_MAX + 1) * (RAND_MAX + 1))))
-#else
-#define DRAND ((double)rand() / ((double)RAND_MAX + 1))
-#endif
-#endif
-
-
/* this is a straightforward implementation of a binary tree */
struct oidtreenode {
oid o;
@@ -107,9 +90,8 @@ OIDTreeToBATAntiset(struct oidtreenode *
((oid *) bat->theap.base)[bat->batCount++] = noid;
}
-/* BATsample implements sampling for void headed BATs */
-BAT *
-BATsample_with_seed(BAT *b, BUN n, unsigned seed)
+static BAT *
+do_batsample(BAT *b, BUN n, random_state_engine rse, MT_Lock *lock)
{
BAT *bn;
BUN cnt, slen;
@@ -129,9 +111,7 @@ BATsample_with_seed(BAT *b, BUN n, unsig
} else {
oid minoid = b->hseqbase;
oid maxoid = b->hseqbase + cnt;
- random_state_engine rse;
-
-
+
/* if someone samples more than half of our tree, we
* do the antiset */
bool antiset = n > cnt / 2;
@@ -149,20 +129,19 @@ BATsample_with_seed(BAT *b, BUN n, unsig
return NULL;
}
- init_random_state_engine(&rse, seed);
-
/* while we do not have enough sample OIDs yet */
+ if (lock) /* serialize access to random state engine */
+ MT_lock_set(lock);
for (rescnt = 0; rescnt < n; rescnt++) {
oid candoid;
do {
- double random_double = next_double(rse);
-
- /* generate a new random OID */
- candoid = (oid) (minoid + random_double *
(maxoid - minoid));
+ candoid = minoid + next(rse) % cnt;
/* if that candidate OID was already
* generated, try again */
} while (!OIDTreeMaybeInsert(tree, candoid, rescnt));
}
+ if (lock)
+ MT_lock_unset(lock);
if (!antiset) {
OIDTreeToBAT(tree, bn);
} else {
@@ -182,10 +161,35 @@ BATsample_with_seed(BAT *b, BUN n, unsig
return bn;
}
+/* BATsample implements sampling for BATs */
+BAT *
+BATsample_with_seed(BAT *b, BUN n, unsigned seed)
+{
+ random_state_engine rse;
+
+ init_random_state_engine(rse, (uint64_t) seed);
+
+ return do_batsample(b, n, rse, NULL);
+}
+
BAT *
BATsample(BAT *b, BUN n)
{
- unsigned some_random_seed = (unsigned) rand();
+ static random_state_engine rse;
+ static MT_Lock rse_lock MT_LOCK_INITIALIZER("rse_lock");
- return BATsample_with_seed(b, n,some_random_seed);
+#ifdef NEED_MT_LOCK_INIT
+ static bool rse_lock_initialized = false;
+ if (!rse_lock_initialized) {
+ MT_lock_init(&rse_lock, "rse_lock");
+ rse_lock_initialized = true;
+ if (b == NULL && n == 0)
+ return NULL;
+ }
+#endif
+ MT_lock_set(&rse_lock);
+ if (rse[0] == 0 && rse[1] == 0 && rse[2] == 0 && rse[3] == 0)
+ init_random_state_engine(rse, (uint64_t) GDKusec());
+ MT_lock_unset(&rse_lock);
+ return do_batsample(b, n, rse, &rse_lock);
}
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list