pcg_random 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 */
|