-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathfrugal-uuid-random.lisp
51 lines (43 loc) · 2.04 KB
/
frugal-uuid-random.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
;;;; frugal-uuid-random.lisp
(in-package #:frugal-uuid)
(defvar *random-number-generator* nil)
(defvar *random-number-generator-init-function*
(lambda () (make-random-state t)))
(defvar *random-number-function* #'random)
(defun initialize-random (random-fn &optional init-fn)
"Sets up alternate source of randomness for generating UUIDs.
The provided RANDOM-FN is expected to take two arguments: the first is
a limit below which a non-negative random number should be generated
and the second is the value returned by the INIT-FN function
argument. When no random INIT-FN is provided, RANDOM-FN is called with
a single LIMIT argument."
(setf *random-number-generator* nil
*random-number-generator-init-function* init-fn
*random-number-function* random-fn)
nil)
(defmacro with-random-number-generator (random-number-generator &body body)
"Dynamically bind random number generator for creating uuid values."
`(let ((*random-number-generator* ,random-number-generator))
,@body))
(defmacro with-random ((random-number-function
&optional random-number-generator) &body body)
"Dynamically bind source of randomness for creating uuid values."
`(let ((*random-number-generator* ,random-number-generator)
(*random-number-function* ,random-number-function))
,@body))
(declaim (ftype (function (integer) (values integer &optional))
random-integer))
(defun random-integer (limit)
"Generate a non-negative random number below LIMIT.
When no alternative source of randomness is provided via
INITIALIZE-RANDOM, then sets up its own random number generator via
*RANDOM-NUMBER-GENERATOR-INIT-FUNCTION* when first invoked."
(when (and (not *random-number-generator*)
*random-number-generator-init-function*)
(setf *random-number-generator*
(funcall *random-number-generator-init-function*)))
(if *random-number-generator*
(funcall *random-number-function*
limit
*random-number-generator*)
(funcall *random-number-function* limit)))