pcg_random 0.1.3 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/benchmarks/new_seed.md +17 -0
- data/benchmarks/new_seed_bench.rb +4 -21
- data/benchmarks/raw_seed.md +17 -0
- data/benchmarks/raw_seed_bench.rb +5 -21
- data/ext/pcg_random/depend +3 -0
- data/ext/pcg_random/extconf.rb +2 -2
- data/ext/pcg_random/pcg_random.c +179 -10
- data/ext/pcg_random/pcg_random.h +14 -1
- data/ext/pcg_random/pcg_seed.c +43 -86
- data/ext/pcg_random/pcg_seed.h +13 -1
- data/lib/pcg_random/version.rb +1 -1
- metadata +5 -4
- data/ext/pcg_random/rb_constants.c +0 -26
- data/ext/pcg_random/rb_constants.h +0 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e26f09fa3ea5290710f41975fcf1a22e4265e794
|
4
|
+
data.tar.gz: 792f5b3ffddb3c984d58aa93c8146443e7837682
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8bf992989aa751a8cd99dc153f78469dc3da4c16b6e2ec3e8dc8a8589aaa1407d0f78b42b9b1a33123ef6b0b83b3b700853afbac5bb23ccc9151e799cd8d7b92
|
7
|
+
data.tar.gz: 8addc87f54888e50b8bdeb08f6959da746054f5d8014c498842121596b6b0c64c314d1b5cd841fd650a97924cc6a69778cd2f36633428b1a352fd0f801ac73b4
|
@@ -0,0 +1,17 @@
|
|
1
|
+
```bash
|
2
|
+
Benchmark of Random.new_seed vs PCGRandom.new_seed
|
3
|
+
==================================================
|
4
|
+
|
5
|
+
Benchmark created around: 2016-03-25 18:27:27 +0000
|
6
|
+
|
7
|
+
Running for: 100000 iterations
|
8
|
+
|
9
|
+
Rehearsal ------------------------------------------------------
|
10
|
+
Random.new_seed 0.120000 1.060000 1.180000 ( 1.173928)
|
11
|
+
PCGRandom.new_seed 0.070000 1.020000 1.090000 ( 1.096108)
|
12
|
+
--------------------------------------------- total: 2.270000sec
|
13
|
+
|
14
|
+
user system total real
|
15
|
+
Random.new_seed 0.100000 1.090000 1.190000 ( 1.188864)
|
16
|
+
PCGRandom.new_seed 0.110000 1.090000 1.200000 ( 1.197528)
|
17
|
+
```
|
@@ -1,26 +1,8 @@
|
|
1
1
|
require 'benchmark'
|
2
2
|
require 'pcg_random'
|
3
3
|
|
4
|
-
|
5
|
-
# Benchmark of Random.new_seed vs PCGRandom.new_seed
|
6
|
-
# ==================================================
|
7
|
-
#
|
8
|
-
# Benchmark created around: 2016-03-20 14:28:07 +0000
|
9
|
-
#
|
10
|
-
# Running for: 100000 iterations
|
11
|
-
#
|
12
|
-
# Rehearsal ------------------------------------------------------
|
13
|
-
# Random.new_seed 0.110000 1.030000 1.140000 ( 1.135205)
|
14
|
-
# PCGRandom.new_seed 0.090000 1.060000 1.150000 ( 1.157619)
|
15
|
-
# --------------------------------------------- total: 2.290000sec
|
16
|
-
#
|
17
|
-
# user system total real
|
18
|
-
# Random.new_seed 0.090000 1.250000 1.340000 ( 1.348947)
|
19
|
-
# PCGRandom.new_seed 0.150000 1.000000 1.150000 ( 1.146167)
|
20
|
-
|
21
|
-
|
22
4
|
Iterations = 100_000
|
23
|
-
|
5
|
+
puts "```bash"
|
24
6
|
puts "Benchmark of Random.new_seed vs PCGRandom.new_seed"
|
25
7
|
puts "=================================================="
|
26
8
|
puts ""
|
@@ -32,8 +14,9 @@ Benchmark.bmbm do |bench|
|
|
32
14
|
bench.report("Random.new_seed") do
|
33
15
|
Iterations.times {Random.new_seed}
|
34
16
|
end
|
35
|
-
|
17
|
+
|
36
18
|
bench.report("PCGRandom.new_seed") do
|
37
19
|
Iterations.times {PCGRandom.new_seed}
|
38
20
|
end
|
39
|
-
end
|
21
|
+
end
|
22
|
+
puts "```"
|
@@ -0,0 +1,17 @@
|
|
1
|
+
```bash
|
2
|
+
Benchmark of Random.raw_seed(16) vs PCGRandom.raw_seed(16)
|
3
|
+
==================================================
|
4
|
+
|
5
|
+
Benchmark created around: 2016-03-25 18:27:35 +0000
|
6
|
+
|
7
|
+
Running for: 100000 iterations
|
8
|
+
|
9
|
+
Rehearsal ----------------------------------------------------------
|
10
|
+
Random.raw_seed(16) 0.040000 0.980000 1.020000 ( 1.031410)
|
11
|
+
PCGRandom.raw_seed(16) 0.050000 0.970000 1.020000 ( 1.021024)
|
12
|
+
------------------------------------------------- total: 2.040000sec
|
13
|
+
|
14
|
+
user system total real
|
15
|
+
Random.raw_seed(16) 0.090000 0.990000 1.080000 ( 1.076778)
|
16
|
+
PCGRandom.raw_seed(16) 0.060000 1.000000 1.060000 ( 1.067268)
|
17
|
+
```
|
@@ -1,27 +1,10 @@
|
|
1
1
|
require 'benchmark'
|
2
2
|
require 'pcg_random'
|
3
3
|
|
4
|
-
|
5
|
-
# Benchmark of Random.raw_seed(16) vs PCGRandom.raw_seed(16)
|
6
|
-
# ==================================================
|
7
|
-
#
|
8
|
-
# Benchmark created around: 2016-03-20 14:34:40 +0000
|
9
|
-
#
|
10
|
-
# Running for: 100000 iterations
|
11
|
-
#
|
12
|
-
# Rehearsal ----------------------------------------------------------
|
13
|
-
# Random.raw_seed(16) 0.060000 1.110000 1.170000 ( 1.173924)
|
14
|
-
# PCGRandom.raw_seed(16) 0.060000 1.110000 1.170000 ( 1.175782)
|
15
|
-
# ------------------------------------------------- total: 2.340000sec
|
16
|
-
#
|
17
|
-
# user system total real
|
18
|
-
# Random.raw_seed(16) 0.060000 1.230000 1.290000 ( 1.292141)
|
19
|
-
# PCGRandom.raw_seed(16) 0.080000 1.100000 1.180000 ( 1.189046)
|
20
|
-
|
21
|
-
|
22
|
-
|
23
4
|
Iterations = 100_000
|
24
5
|
SeedSize = 16
|
6
|
+
|
7
|
+
puts "```bash"
|
25
8
|
puts "Benchmark of Random.raw_seed(#{SeedSize}) vs PCGRandom.raw_seed(#{SeedSize})"
|
26
9
|
puts "=================================================="
|
27
10
|
puts ""
|
@@ -33,8 +16,9 @@ Benchmark.bmbm do |bench|
|
|
33
16
|
bench.report("Random.raw_seed(#{SeedSize})") do
|
34
17
|
Iterations.times {Random.raw_seed SeedSize}
|
35
18
|
end
|
36
|
-
|
19
|
+
|
37
20
|
bench.report("PCGRandom.raw_seed(#{SeedSize})") do
|
38
21
|
Iterations.times {PCGRandom.raw_seed SeedSize}
|
39
22
|
end
|
40
|
-
end
|
23
|
+
end
|
24
|
+
puts "```"
|
data/ext/pcg_random/extconf.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
require
|
1
|
+
require 'mkmf'
|
2
2
|
|
3
3
|
RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC'] if ENV['CC']
|
4
4
|
|
5
|
-
$CFLAGS = " -Wall -pedantic -
|
5
|
+
$CFLAGS = " -ggdb -Wall -pedantic -std=c99"
|
6
6
|
|
7
7
|
LIBDIR = RbConfig::CONFIG['libdir']
|
8
8
|
INCLUDEDIR = RbConfig::CONFIG['includedir']
|
data/ext/pcg_random/pcg_random.c
CHANGED
@@ -1,24 +1,193 @@
|
|
1
1
|
#include <ruby.h>
|
2
|
+
#include <stdbool.h>
|
3
|
+
#include <stdint.h>
|
4
|
+
#include <math.h>
|
2
5
|
#include <pcg_variants.h>
|
3
|
-
#include <inttypes.h>
|
4
|
-
#include <string.h>
|
5
6
|
|
6
|
-
#include "rb_constants.h"
|
7
7
|
#include "pcg_random.h"
|
8
8
|
#include "pcg_seed.h"
|
9
9
|
|
10
10
|
VALUE rb_cPCGRandom;
|
11
11
|
|
12
|
+
static void pcg_random_mark(void *ptr);
|
13
|
+
static void pcg_random_free(void *rand_data);
|
14
|
+
static size_t pcg_random_memsize(const void *ptr);
|
15
|
+
static pcg_rb_rand_t *pcg_get_rand_type(VALUE obj);
|
16
|
+
static VALUE pcg_random_alloc(VALUE klass);
|
17
|
+
static VALUE pcg_func_init(int argc, VALUE *argv, VALUE self);
|
18
|
+
static VALUE pcg_func_get_state(VALUE self);
|
19
|
+
static VALUE pcg_func_get_seq(VALUE self);
|
20
|
+
|
21
|
+
/*
|
22
|
+
* Structure wrapping our rng's data type's GC related functions
|
23
|
+
*/
|
24
|
+
static const rb_data_type_t pcg_rand_data_t = {
|
25
|
+
"pcg_random",
|
26
|
+
{
|
27
|
+
pcg_random_mark,
|
28
|
+
pcg_random_free,
|
29
|
+
pcg_random_memsize,
|
30
|
+
},
|
31
|
+
};
|
32
|
+
|
33
|
+
/*
|
34
|
+
* Internal - Mark the internal seed value for garbage collection since a VALUE
|
35
|
+
* inside a C struct is not marked by the GC automatically, and isn't freed
|
36
|
+
* correctly either.
|
37
|
+
*/
|
38
|
+
static void
|
39
|
+
pcg_random_mark(void *ptr)
|
40
|
+
{
|
41
|
+
rb_gc_mark(((pcg_rb_rand_t *) ptr)->seed.val);
|
42
|
+
}
|
43
|
+
|
44
|
+
/*
|
45
|
+
* Internal - Free internal C-types in the `pcg_rb_rand_t` struct
|
46
|
+
*/
|
47
|
+
static void
|
48
|
+
pcg_random_free(void *rand_data)
|
49
|
+
{
|
50
|
+
xfree(((pcg_rb_rand_t *) rand_data)->rng);
|
51
|
+
xfree((pcg_rb_rand_t *)(rand_data));
|
52
|
+
}
|
53
|
+
|
54
|
+
/*
|
55
|
+
* Internal - Get the size of a valid pcg_rb_rand_t pointer
|
56
|
+
*
|
57
|
+
* @return the size of `pcg_rb_rand_t` struct if it is initialized correctly.
|
58
|
+
* 0 if given a NULL pointer
|
59
|
+
*/
|
60
|
+
static size_t
|
61
|
+
pcg_random_memsize(const void *ptr)
|
62
|
+
{
|
63
|
+
return ptr ? sizeof(pcg_rb_rand_t) : 0;
|
64
|
+
}
|
65
|
+
|
66
|
+
/*
|
67
|
+
* Internal - Helper function to get a pointer to a pcg_rb_rand_t struct given
|
68
|
+
* an instance of the `PCGRandom` class
|
69
|
+
*
|
70
|
+
* Returns an object wrapping a C struct, with default initializations
|
71
|
+
*/
|
72
|
+
static pcg_rb_rand_t *
|
73
|
+
pcg_get_rand_type(VALUE obj)
|
74
|
+
{
|
75
|
+
pcg_rb_rand_t *ptr;
|
76
|
+
TypedData_Get_Struct(obj, pcg_rb_rand_t, &pcg_rand_data_t, ptr);
|
77
|
+
return ptr;
|
78
|
+
}
|
79
|
+
|
80
|
+
/*
|
81
|
+
* Memory allocation function that is called by new before `initialize` is
|
82
|
+
* The chain is similar to: `new -> allocate -> initialize`
|
83
|
+
*
|
84
|
+
* Returns an object wrapping a C struct, with default initializations
|
85
|
+
*/
|
86
|
+
static VALUE
|
87
|
+
pcg_random_alloc(VALUE klass)
|
88
|
+
{
|
89
|
+
pcg_rb_rand_t *rand_data;
|
90
|
+
VALUE obj;
|
91
|
+
/*
|
92
|
+
* ISO C forbids braced-groups within expressions
|
93
|
+
* See: http://stackoverflow.com/questions/1238016/
|
94
|
+
*/
|
95
|
+
obj = __extension__ TypedData_Make_Struct(klass, pcg_rb_rand_t, &pcg_rand_data_t, rand_data);
|
96
|
+
|
97
|
+
rand_data->seed.val = INT2FIX(0);
|
98
|
+
rand_data->seed.state = 0;
|
99
|
+
rand_data->seed.seq = 0;
|
100
|
+
rand_data->rng = ALLOC(pcg32_random_t);
|
101
|
+
|
102
|
+
return obj;
|
103
|
+
}
|
104
|
+
|
105
|
+
/*
|
106
|
+
* Internal - Initialize the requested instance using a pre-allocated ruby
|
107
|
+
* object (TypedStruct). Sets the instance variables and relevant accessor
|
108
|
+
* methods where applicable.
|
109
|
+
*/
|
110
|
+
static VALUE
|
111
|
+
pcg_func_init(int argc, VALUE *argv, VALUE self)
|
112
|
+
{
|
113
|
+
VALUE seed;
|
114
|
+
uint64_t cseeds[2];
|
115
|
+
pcg_rb_rand_t* rand_data = pcg_get_rand_type(self);
|
116
|
+
|
117
|
+
if(argc == 0)
|
118
|
+
{
|
119
|
+
seed = DEFAULT_SEED_VALUE;
|
120
|
+
}
|
121
|
+
else
|
122
|
+
{
|
123
|
+
rb_scan_args(argc, argv, "01", &seed);
|
124
|
+
}
|
125
|
+
|
126
|
+
rb_integer_pack(seed, (void *) cseeds, 2, sizeof(uint64_t), 0,
|
127
|
+
INTEGER_PACK_MSWORD_FIRST|INTEGER_PACK_NATIVE_BYTE_ORDER);
|
128
|
+
|
129
|
+
rand_data->seed.val = seed;
|
130
|
+
rand_data->seed.state = cseeds[0];
|
131
|
+
rand_data->seed.seq = cseeds[1];
|
132
|
+
pcg32_srandom_r(rand_data->rng, cseeds[0], cseeds[1]);
|
133
|
+
|
134
|
+
/* Add & set private instance variables */
|
135
|
+
rb_iv_set(self, "@seed", seed);
|
136
|
+
rb_iv_set(self, "state", LONG2NUM(rand_data->seed.state));
|
137
|
+
rb_iv_set(self, "sequence", LONG2NUM(rand_data->seed.seq));
|
138
|
+
return self;
|
139
|
+
}
|
140
|
+
|
141
|
+
/*
|
142
|
+
* Internal - Private method to access internal rng state parameter
|
143
|
+
* (Most significant word of seed)
|
144
|
+
*/
|
145
|
+
static VALUE
|
146
|
+
pcg_func_get_state(VALUE self)
|
147
|
+
{
|
148
|
+
VALUE state;
|
149
|
+
state = rb_iv_get(self, "state");
|
150
|
+
return state;
|
151
|
+
}
|
152
|
+
|
153
|
+
/*
|
154
|
+
* Internal - Private method to access internal rng state parameter
|
155
|
+
* (Most significant word of seed)
|
156
|
+
*/
|
157
|
+
static VALUE
|
158
|
+
pcg_func_get_seq(VALUE self)
|
159
|
+
{
|
160
|
+
VALUE seq;
|
161
|
+
seq = rb_iv_get(self, "sequence");
|
162
|
+
return seq;
|
163
|
+
}
|
164
|
+
|
12
165
|
void
|
13
166
|
Init_pcg_random(void)
|
14
167
|
{
|
15
|
-
/*
|
16
|
-
|
17
|
-
|
18
|
-
/* Define encapsulating module */
|
168
|
+
/* Initializations */
|
169
|
+
|
170
|
+
/* Constants / Classes */
|
19
171
|
rb_cPCGRandom = rb_define_class("PCGRandom", rb_cObject);
|
20
|
-
|
21
|
-
|
22
|
-
|
172
|
+
|
173
|
+
rb_define_const(rb_cPCGRandom, "DEFAULT_SEED_BYTES", INT2FIX(DEFAULT_SEED_BYTES));
|
174
|
+
|
175
|
+
/* Singleton methods */
|
176
|
+
rb_define_singleton_method(rb_cPCGRandom, "new_seed", pcg_func_new_seed, 0);
|
23
177
|
rb_define_singleton_method(rb_cPCGRandom, "raw_seed", pcg_func_raw_seed, 1);
|
178
|
+
|
179
|
+
/* Public instance methods */
|
180
|
+
rb_define_alloc_func(rb_cPCGRandom, pcg_random_alloc);
|
181
|
+
rb_define_attr(rb_cPCGRandom, "seed", 1, 0);
|
182
|
+
// rb_define_method(rb_cPCGRandom, "rand", pcg_func_rand, -1);
|
183
|
+
// rb_define_method(rb_cPCGRandom, "bytes", pcg_func_rand_bytes, 1);
|
184
|
+
// rb_define_method(rb_cPCGRandom, "initialize_copy", pcg_func_rand_copy, 1);
|
185
|
+
// rb_define_method(rb_cPCGRandom, "==", pcg_func_equal, 1);
|
186
|
+
|
187
|
+
/* Private instance methods */
|
188
|
+
rb_define_method(rb_cPCGRandom, "initialize", pcg_func_init, -1);
|
189
|
+
// rb_define_private_method(rb_cPCGRandom, "marshal_dump", pcg_func_dump, 0);
|
190
|
+
// rb_define_private_method(rb_cPCGRandom, "marshal_load", pcg_func_load, 1);
|
191
|
+
rb_define_private_method(rb_cPCGRandom, "state", pcg_func_get_state, 0);
|
192
|
+
rb_define_private_method(rb_cPCGRandom, "sequence", pcg_func_get_seq, 0);
|
24
193
|
}
|
data/ext/pcg_random/pcg_random.h
CHANGED
@@ -2,8 +2,21 @@
|
|
2
2
|
#define PCG_RANDOM_H 1
|
3
3
|
|
4
4
|
#include <ruby.h>
|
5
|
-
#include <
|
5
|
+
#include <stdint.h>
|
6
6
|
|
7
7
|
extern VALUE rb_cPCGRandom;
|
8
8
|
|
9
|
+
struct pcg_rb_seed
|
10
|
+
{
|
11
|
+
VALUE val;
|
12
|
+
uint64_t state;
|
13
|
+
uint64_t seq;
|
14
|
+
};
|
15
|
+
|
16
|
+
typedef struct
|
17
|
+
{
|
18
|
+
struct pcg_rb_seed seed;
|
19
|
+
pcg32_random_t *rng;
|
20
|
+
} pcg_rb_rand_t;
|
21
|
+
|
9
22
|
#endif /* PCG_RANDOM_H */
|
data/ext/pcg_random/pcg_seed.c
CHANGED
@@ -4,49 +4,22 @@
|
|
4
4
|
#include <stdint.h>
|
5
5
|
|
6
6
|
#include "entropy.h"
|
7
|
-
#include "rb_constants.h"
|
8
7
|
#include "pcg_seed.h"
|
9
8
|
|
10
|
-
static VALUE pcg_new_seed_bytestr(unsigned long seed_size);
|
11
|
-
static VALUE pcg_raw_seed_bytestr(size_t size);
|
12
|
-
|
13
9
|
/*
|
14
|
-
* Returns a
|
10
|
+
* Returns a 16-byte integer that stores the seed value used to seed the
|
15
11
|
* initial state and sequence for the PCG generator.
|
16
|
-
|
17
|
-
*
|
18
|
-
* @param size Number of bytes (EVEN!) that the generated seed must contain.
|
19
|
-
* Defaults to 16 Bytes (uint8_t) = 128 bits
|
20
|
-
*
|
21
|
-
* @raise ArgumentError if size is not even
|
22
|
-
*/
|
12
|
+
*/
|
23
13
|
VALUE
|
24
|
-
pcg_func_new_seed(
|
14
|
+
pcg_func_new_seed(VALUE self)
|
25
15
|
{
|
26
|
-
|
27
|
-
unsigned long n;
|
28
|
-
|
29
|
-
if(argc == 0)
|
30
|
-
{
|
31
|
-
return pcg_new_seed_bytestr(16 * sizeof(uint8_t));
|
32
|
-
}
|
33
|
-
|
34
|
-
rb_scan_args(argc, argv, "01", &seed_size);
|
35
|
-
n = NUM2ULONG(seed_size);
|
36
|
-
|
37
|
-
// Only accept even seed sizes since this later needs to be split into
|
38
|
-
// two parts!
|
39
|
-
if(n % 2 == 1)
|
40
|
-
{
|
41
|
-
rb_raise(rb_eArgError, "Seed size must be even! Found %lu", n);
|
42
|
-
}
|
43
|
-
return pcg_new_seed_bytestr(n * sizeof(uint8_t));
|
16
|
+
return DEFAULT_SEED_VALUE;
|
44
17
|
}
|
45
18
|
|
46
19
|
/*
|
47
|
-
* Generates a random seed string represented as a sequence of bytes
|
20
|
+
* Generates a random seed string represented as a sequence of bytes
|
48
21
|
*
|
49
|
-
* @param
|
22
|
+
* @param byte_size Size of the bytestring to generate
|
50
23
|
*/
|
51
24
|
VALUE
|
52
25
|
pcg_func_raw_seed(VALUE self, VALUE byte_size)
|
@@ -59,11 +32,33 @@ pcg_func_raw_seed(VALUE self, VALUE byte_size)
|
|
59
32
|
return pcg_raw_seed_bytestr(n);
|
60
33
|
}
|
61
34
|
|
35
|
+
/*
|
36
|
+
* Gets `size` number of random bytes from a platform source
|
37
|
+
* and returns those as a ruby string
|
38
|
+
*/
|
39
|
+
VALUE
|
40
|
+
pcg_raw_seed_bytestr(size_t size)
|
41
|
+
{
|
42
|
+
VALUE result;
|
43
|
+
char *bytestr = ALLOCA_N(char, size + 1);
|
44
|
+
if(bytestr == NULL)
|
45
|
+
{
|
46
|
+
rb_raise(rb_eNoMemError,
|
47
|
+
"Could not allocate enough space for %lu-byte seed!", size);
|
48
|
+
}
|
49
|
+
MEMZERO(bytestr, char, size + 1);
|
50
|
+
pcg_func_entropy_getbytes((void *)bytestr, size);
|
51
|
+
|
52
|
+
result = rb_str_new2(bytestr);
|
53
|
+
|
54
|
+
return result;
|
55
|
+
}
|
56
|
+
|
62
57
|
/*
|
63
58
|
* Generates a sequence of random bytes using device entropy
|
64
59
|
* or a fallback mechanism based on pcg32_random_r
|
65
60
|
*/
|
66
|
-
bool
|
61
|
+
bool
|
67
62
|
pcg_func_entropy_getbytes(void *dest, size_t size)
|
68
63
|
{
|
69
64
|
// Get random bytes from /dev/random or a fallback source
|
@@ -76,65 +71,27 @@ pcg_func_entropy_getbytes(void *dest, size_t size)
|
|
76
71
|
}
|
77
72
|
|
78
73
|
/*
|
79
|
-
*
|
80
|
-
*
|
81
|
-
*/
|
82
|
-
static VALUE
|
83
|
-
pcg_raw_seed_bytestr(size_t size)
|
84
|
-
{
|
85
|
-
VALUE result;
|
86
|
-
char *bytestr = (char *) malloc(size + 1);
|
87
|
-
if(bytestr == NULL)
|
88
|
-
{
|
89
|
-
rb_raise(rb_eNoMemError,
|
90
|
-
"Could not malloc enough space for %lu-byte seed!", size);
|
91
|
-
}
|
92
|
-
memset(bytestr, 0, size + 1);
|
93
|
-
pcg_func_entropy_getbytes((void *)bytestr, size);
|
94
|
-
|
95
|
-
result = rb_str_new2(bytestr);
|
96
|
-
free(bytestr);
|
97
|
-
|
98
|
-
return result;
|
99
|
-
}
|
100
|
-
|
101
|
-
/*
|
102
|
-
* Internal - Two random integers are sourced from /dev/random or a fallback
|
103
|
-
* source
|
74
|
+
* Random integers are sourced from /dev/random or a fallback
|
75
|
+
* source
|
104
76
|
* Seed generated by manipulating a 16byte string & unpacking it to Q*
|
105
77
|
*/
|
106
|
-
|
78
|
+
VALUE
|
107
79
|
pcg_new_seed_bytestr(unsigned long seed_size)
|
108
80
|
{
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
if(bytes == NULL || buf == NULL)
|
81
|
+
uint8_t *bytes = ALLOCA_N(uint8_t, seed_size);
|
82
|
+
|
83
|
+
if(bytes == NULL)
|
114
84
|
{
|
115
|
-
rb_raise(rb_eNoMemError, "Could not
|
85
|
+
rb_raise(rb_eNoMemError, "Could not allocate enough memory!");
|
116
86
|
}
|
117
|
-
|
118
|
-
|
119
|
-
|
87
|
+
|
88
|
+
MEMZERO(bytes, uint8_t, seed_size);
|
89
|
+
|
120
90
|
if(!pcg_func_entropy_getbytes((void *)bytes, seed_size))
|
121
91
|
{
|
122
92
|
rb_raise(rb_eRuntimeError, "Unable to generate seed!");
|
123
93
|
}
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
buf[i] = (unsigned long) bytes[i];
|
129
|
-
}
|
130
|
-
|
131
|
-
// Inspired from ruby's very own random.c
|
132
|
-
// see: http://rxr.whitequark.org/mri/source/random.c#493
|
133
|
-
// Also: http://rxr.whitequark.org/mri/source/random.c#443
|
134
|
-
result = rb_big_unpack(buf, seed_size);
|
135
|
-
|
136
|
-
free(bytes);
|
137
|
-
free(buf);
|
138
|
-
|
139
|
-
return result;
|
140
|
-
}
|
94
|
+
|
95
|
+
return rb_integer_unpack((void *) bytes, seed_size, sizeof(uint8_t), 0,
|
96
|
+
INTEGER_PACK_MSWORD_FIRST|INTEGER_PACK_NATIVE_BYTE_ORDER);
|
97
|
+
}
|
data/ext/pcg_random/pcg_seed.h
CHANGED
@@ -4,8 +4,20 @@
|
|
4
4
|
#include <ruby.h>
|
5
5
|
#include <stdbool.h>
|
6
6
|
|
7
|
-
|
7
|
+
#ifndef DEFAULT_SEED_BYTES
|
8
|
+
# define DEFAULT_SEED_BYTES 16
|
9
|
+
#endif
|
10
|
+
|
11
|
+
#ifndef DEFAULT_SEED_VALUE
|
12
|
+
# define DEFAULT_SEED_VALUE pcg_new_seed_bytestr(DEFAULT_SEED_BYTES * sizeof(uint8_t))
|
13
|
+
#endif
|
14
|
+
|
8
15
|
bool pcg_func_entropy_getbytes(void* dest, size_t size);
|
16
|
+
|
17
|
+
VALUE pcg_func_new_seed(VALUE self);
|
18
|
+
VALUE pcg_new_seed_bytestr(unsigned long seed_size);
|
19
|
+
|
9
20
|
VALUE pcg_func_raw_seed(VALUE self, VALUE byte_size);
|
21
|
+
VALUE pcg_raw_seed_bytestr(size_t size);
|
10
22
|
|
11
23
|
#endif /* PCG_SEED_H */
|
data/lib/pcg_random/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pcg_random
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vaibhav Yenamandra
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-03-
|
11
|
+
date: 2016-03-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -96,10 +96,13 @@ files:
|
|
96
96
|
- LICENSE.txt
|
97
97
|
- README.md
|
98
98
|
- Rakefile
|
99
|
+
- benchmarks/new_seed.md
|
99
100
|
- benchmarks/new_seed_bench.rb
|
101
|
+
- benchmarks/raw_seed.md
|
100
102
|
- benchmarks/raw_seed_bench.rb
|
101
103
|
- bin/console
|
102
104
|
- bin/setup
|
105
|
+
- ext/pcg_random/depend
|
103
106
|
- ext/pcg_random/entropy.c
|
104
107
|
- ext/pcg_random/entropy.h
|
105
108
|
- ext/pcg_random/extconf.rb
|
@@ -108,8 +111,6 @@ files:
|
|
108
111
|
- ext/pcg_random/pcg_seed.c
|
109
112
|
- ext/pcg_random/pcg_seed.h
|
110
113
|
- ext/pcg_random/pcg_spinlock.h
|
111
|
-
- ext/pcg_random/rb_constants.c
|
112
|
-
- ext/pcg_random/rb_constants.h
|
113
114
|
- lib/pcg_random.rb
|
114
115
|
- lib/pcg_random/version.rb
|
115
116
|
- pcg_random.gemspec
|
@@ -1,26 +0,0 @@
|
|
1
|
-
#include <ruby.h>
|
2
|
-
#include "rb_constants.h"
|
3
|
-
|
4
|
-
VALUE pcg_rb_zero,
|
5
|
-
pcg_rb_one,
|
6
|
-
pcg_rb_big_zero,
|
7
|
-
pcg_rb_big_one;
|
8
|
-
|
9
|
-
|
10
|
-
ID pcg_rb_plus,
|
11
|
-
pcg_rb_mul;
|
12
|
-
|
13
|
-
void
|
14
|
-
pcg_init_rb_constants(void)
|
15
|
-
{
|
16
|
-
// Commonly used ruby objects
|
17
|
-
pcg_rb_zero = INT2FIX(0);
|
18
|
-
pcg_rb_one = INT2FIX(1);
|
19
|
-
|
20
|
-
pcg_rb_big_zero = rb_uint2big(0);
|
21
|
-
pcg_rb_big_one = rb_uint2big(1);
|
22
|
-
|
23
|
-
// Commonly called functions
|
24
|
-
pcg_rb_plus = rb_intern("+");
|
25
|
-
pcg_rb_mul = rb_intern("*");
|
26
|
-
}
|
@@ -1,16 +0,0 @@
|
|
1
|
-
#ifndef PCG_RB_CONSTANTS_H
|
2
|
-
#define PCG_RB_CONSTANTS_H 1
|
3
|
-
|
4
|
-
#include <ruby.h>
|
5
|
-
|
6
|
-
extern VALUE pcg_rb_zero,
|
7
|
-
pcg_rb_one,
|
8
|
-
pcg_rb_big_zero,
|
9
|
-
pcg_rb_big_one;
|
10
|
-
|
11
|
-
extern ID pcg_rb_plus,
|
12
|
-
pcg_rb_mul;
|
13
|
-
|
14
|
-
void pcg_init_rb_constants(void);
|
15
|
-
|
16
|
-
#endif /* PCG_RB_CONSTANTS_H */
|