redshift 1.3.22 → 1.3.23

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. data/.bnsignore +27 -0
  2. data/RELEASE-NOTES +6 -0
  3. data/bench/aug17-ruby19.bench +86 -0
  4. data/bench/aug17.bench +86 -0
  5. data/bench/aug7.bench +86 -0
  6. data/bench/bench +4 -1
  7. data/bench/prof.html +0 -0
  8. data/ext/redshift/buffer/buffer.c +3 -1
  9. data/ext/redshift/dvector/dvector.c +236 -0
  10. data/ext/redshift/dvector/dvector.h +36 -0
  11. data/ext/redshift/dvector/dvector.rb +33 -0
  12. data/ext/redshift/dvector/extconf.rb +2 -0
  13. data/lib/redshift/redshift.rb +1 -1
  14. data/lib/redshift/target/c/component-gen.rb +17 -23
  15. data/lib/redshift/target/c/flow-gen.rb +2 -2
  16. data/lib/redshift/target/c/flow/algebraic.rb +1 -1
  17. data/lib/redshift/target/c/flow/delay.rb +1 -1
  18. data/lib/redshift/target/c/flow/derivative.rb +1 -1
  19. data/lib/redshift/target/c/flow/rk4.rb +1 -1
  20. data/lib/redshift/target/c/library.rb +5 -0
  21. data/lib/redshift/target/c/world-gen.rb +130 -127
  22. data/lib/redshift/util/isaac.rb +2 -2
  23. data/lib/redshift/util/random.rb +1 -1
  24. data/lib/redshift/world.rb +11 -6
  25. data/test/test_discrete.rb +1 -1
  26. data/test/test_discrete_isolated.rb +1 -1
  27. data/test/test_dvector.rb +110 -0
  28. data/test/test_flow.rb +1 -1
  29. data/test/test_flow_link.rb +1 -1
  30. data/test/test_flow_sub.rb +1 -1
  31. data/test/test_flow_trans.rb +3 -3
  32. data/test/test_inherit_event.rb +1 -1
  33. data/test/test_inherit_flow.rb +1 -1
  34. data/test/test_inherit_link.rb +1 -1
  35. data/test/test_inherit_state.rb +1 -1
  36. data/test/test_inherit_transition.rb +1 -1
  37. data/test/test_setup.rb +1 -1
  38. data/test/test_strict_continuity.rb +1 -1
  39. data/test/test_world.rb +4 -4
  40. metadata +22 -8
data/.bnsignore ADDED
@@ -0,0 +1,27 @@
1
+ # The list of files that should be ignored by Mr Bones.
2
+ # Lines that start with '#' are comments.
3
+ #
4
+ # A .gitignore file can be used instead by setting it as the ignore
5
+ # file in your Rakefile:
6
+ #
7
+ # PROJ.ignore_file = '.gitignore'
8
+ #
9
+ # For a project with a C extension, the following would be a good set of
10
+ # exclude patterns (uncomment them if you want to use them):
11
+ # *.[oa]
12
+ # *~
13
+ announcement.txt
14
+ coverage
15
+ doc
16
+ pkg
17
+ *.bck
18
+ *.so
19
+ *.o
20
+ ext/*/*/Makefile
21
+ ext/*/*/*/Makefile
22
+ misc
23
+ junk
24
+ tmp
25
+ */tmp
26
+ */*/tmp
27
+ */junk
data/RELEASE-NOTES CHANGED
@@ -1,3 +1,9 @@
1
+ redshift 1.3.23
2
+
3
+ - compatible with ruby-1.9.2
4
+
5
+ - renamed Random module to RandomDistribution to avoid conflict
6
+
1
7
  redshift 1.3.22
2
8
 
3
9
  - handling of env vars is more consistent
@@ -0,0 +1,86 @@
1
+ alg-state:
2
+ - 0 comps X 1000 steps X 0 non-alg: 0.00
3
+ - 10 comps X 1000 steps X 0 non-alg: 0.00
4
+ - 100 comps X 1000 steps X 0 non-alg: 0.01
5
+ - 1000 comps X 1000 steps X 0 non-alg: 0.06
6
+ - 10000 comps X 1000 steps X 0 non-alg: 2.79
7
+ algebraic:
8
+ - 1 comps X 1000000 steps: 2.10
9
+ - 10 comps X 100000 steps: 0.54
10
+ - 100 comps X 10000 steps: 0.47
11
+ - 1000 comps X 1000 steps: 0.44
12
+ - 10000 comps X 100 steps: 1.09
13
+ - 100000 comps X 10 steps: 1.26
14
+ connect:
15
+ - 10 comps X 100000 steps: 0.30
16
+ - 100 comps X 10000 steps: 0.09
17
+ - 1000 comps X 1000 steps: 0.10
18
+ - 10000 comps X 100 steps: 0.29
19
+ - 100000 comps X 10 steps: 0.50
20
+ continuous:
21
+ - 1 comps X 1000000 steps: 1.91
22
+ - 10 comps X 100000 steps: 0.40
23
+ - 100 comps X 10000 steps: 0.31
24
+ - 1000 comps X 1000 steps: 0.29
25
+ - 10000 comps X 100 steps: 0.85
26
+ - 100000 comps X 10 steps: 1.05
27
+ discrete:
28
+ - 1 comps X 1000000 steps X 0 watchers: 2.39
29
+ - 10 comps X 100000 steps X 0 watchers: 0.46
30
+ - 100 comps X 10000 steps X 0 watchers: 0.20
31
+ - 1000 comps X 1000 steps X 0 watchers: 0.21
32
+ - 10000 comps X 100 steps X 0 watchers: 0.54
33
+ - 100000 comps X 10 steps X 0 watchers: 0.75
34
+ - 1 comps X 1000000 steps X 1 watchers: 3.24
35
+ - 10 comps X 100000 steps X 1 watchers: 0.74
36
+ - 100 comps X 10000 steps X 1 watchers: 0.52
37
+ - 1000 comps X 1000 steps X 1 watchers: 0.63
38
+ - 10000 comps X 100 steps X 1 watchers: 2.21
39
+ - 100000 comps X 10 steps X 1 watchers: 2.46
40
+ - 1 comps X 200000 steps X 5 watchers: 0.73
41
+ - 10 comps X 20000 steps X 5 watchers: 0.43
42
+ - 100 comps X 2000 steps X 5 watchers: 0.50
43
+ - 1000 comps X 200 steps X 5 watchers: 0.86
44
+ - 10000 comps X 20 steps X 5 watchers: 2.06
45
+ - 100000 comps X 2 steps X 5 watchers: 3.72
46
+ euler:
47
+ - 1 comps X 1000000 steps: 1.86
48
+ - 10 comps X 100000 steps: 0.30
49
+ - 100 comps X 10000 steps: 0.22
50
+ - 1000 comps X 1000 steps: 0.21
51
+ - 10000 comps X 100 steps: 0.77
52
+ - 100000 comps X 10 steps: 0.94
53
+ formula:
54
+ - 1 comps X 100000 steps: 0.31
55
+ - 10 comps X 10000 steps: 0.13
56
+ - 100 comps X 1000 steps: 0.12
57
+ - 1000 comps X 100 steps: 0.12
58
+ - 10000 comps X 10 steps: 0.17
59
+ half-strict:
60
+ - 10 comps X 100000 steps: 3.09
61
+ - 100 comps X 10000 steps: 1.23
62
+ - 1000 comps X 1000 steps: 1.15
63
+ - 10000 comps X 100 steps: 1.68
64
+ - 100000 comps X 10 steps: 2.42
65
+ inertness:
66
+ - 0 comps X 10000 steps X 0 non-inert: 0.01
67
+ - 1000 comps X 10000 steps X 0 non-inert: 0.43
68
+ - 0 comps X 10000 steps X 1 non-inert: 0.12
69
+ - 1000 comps X 10000 steps X 1 non-inert: 0.54
70
+ linked-flows:
71
+ - 1 comps X 1000000 steps: 2.23
72
+ - 10 comps X 100000 steps: 0.61
73
+ - 100 comps X 10000 steps: 0.64
74
+ - 1000 comps X 1000 steps: 0.60
75
+ - 10000 comps X 100 steps: 2.09
76
+ - 100000 comps X 10 steps: 2.37
77
+ queues:
78
+ - 1 senders X 100000 steps X 1 receivers: 0.22
79
+ - 10 senders X 10000 steps X 1 receivers: 0.04
80
+ - 100 senders X 1000 steps X 1 receivers: 0.02
81
+ - 1 senders X 10000 steps X 10 receivers: 0.03
82
+ - 10 senders X 1000 steps X 10 receivers: 0.01
83
+ - 100 senders X 100 steps X 10 receivers: 0.01
84
+ - 1 senders X 1000 steps X 100 receivers: 0.01
85
+ - 10 senders X 100 steps X 100 receivers: 0.01
86
+ - 100 senders X 10 steps X 100 receivers: 0.02
data/bench/aug17.bench ADDED
@@ -0,0 +1,86 @@
1
+ alg-state:
2
+ - 0 comps X 1000 steps X 0 non-alg: 0.00
3
+ - 10 comps X 1000 steps X 0 non-alg: 0.00
4
+ - 100 comps X 1000 steps X 0 non-alg: 0.01
5
+ - 1000 comps X 1000 steps X 0 non-alg: 0.08
6
+ - 10000 comps X 1000 steps X 0 non-alg: 3.62
7
+ algebraic:
8
+ - 1 comps X 1000000 steps: 2.69
9
+ - 10 comps X 100000 steps: 0.60
10
+ - 100 comps X 10000 steps: 0.46
11
+ - 1000 comps X 1000 steps: 0.46
12
+ - 10000 comps X 100 steps: 1.30
13
+ - 100000 comps X 10 steps: 1.53
14
+ connect:
15
+ - 10 comps X 100000 steps: 0.28
16
+ - 100 comps X 10000 steps: 0.07
17
+ - 1000 comps X 1000 steps: 0.10
18
+ - 10000 comps X 100 steps: 0.38
19
+ - 100000 comps X 10 steps: 0.89
20
+ continuous:
21
+ - 1 comps X 1000000 steps: 2.54
22
+ - 10 comps X 100000 steps: 0.42
23
+ - 100 comps X 10000 steps: 0.31
24
+ - 1000 comps X 1000 steps: 0.32
25
+ - 10000 comps X 100 steps: 1.05
26
+ - 100000 comps X 10 steps: 1.32
27
+ discrete:
28
+ - 1 comps X 1000000 steps X 0 watchers: 2.49
29
+ - 10 comps X 100000 steps X 0 watchers: 0.44
30
+ - 100 comps X 10000 steps X 0 watchers: 0.18
31
+ - 1000 comps X 1000 steps X 0 watchers: 0.20
32
+ - 10000 comps X 100 steps X 0 watchers: 0.49
33
+ - 100000 comps X 10 steps X 0 watchers: 0.65
34
+ - 1 comps X 1000000 steps X 1 watchers: 3.95
35
+ - 10 comps X 100000 steps X 1 watchers: 0.71
36
+ - 100 comps X 10000 steps X 1 watchers: 0.52
37
+ - 1000 comps X 1000 steps X 1 watchers: 0.64
38
+ - 10000 comps X 100 steps X 1 watchers: 2.08
39
+ - 100000 comps X 10 steps X 1 watchers: 2.86
40
+ - 1 comps X 200000 steps X 5 watchers: 0.85
41
+ - 10 comps X 20000 steps X 5 watchers: 0.43
42
+ - 100 comps X 2000 steps X 5 watchers: 0.53
43
+ - 1000 comps X 200 steps X 5 watchers: 0.91
44
+ - 10000 comps X 20 steps X 5 watchers: 1.92
45
+ - 100000 comps X 2 steps X 5 watchers: 4.60
46
+ euler:
47
+ - 1 comps X 1000000 steps: 2.48
48
+ - 10 comps X 100000 steps: 0.34
49
+ - 100 comps X 10000 steps: 0.23
50
+ - 1000 comps X 1000 steps: 0.22
51
+ - 10000 comps X 100 steps: 0.86
52
+ - 100000 comps X 10 steps: 1.08
53
+ formula:
54
+ - 1 comps X 100000 steps: 0.34
55
+ - 10 comps X 10000 steps: 0.15
56
+ - 100 comps X 1000 steps: 0.12
57
+ - 1000 comps X 100 steps: 0.12
58
+ - 10000 comps X 10 steps: 0.19
59
+ half-strict:
60
+ - 10 comps X 100000 steps: 3.90
61
+ - 100 comps X 10000 steps: 1.25
62
+ - 1000 comps X 1000 steps: 1.05
63
+ - 10000 comps X 100 steps: 1.85
64
+ - 100000 comps X 10 steps: 3.03
65
+ inertness:
66
+ - 0 comps X 10000 steps X 0 non-inert: 0.03
67
+ - 1000 comps X 10000 steps X 0 non-inert: 0.40
68
+ - 0 comps X 10000 steps X 1 non-inert: 0.16
69
+ - 1000 comps X 10000 steps X 1 non-inert: 0.46
70
+ linked-flows:
71
+ - 1 comps X 1000000 steps: 2.29
72
+ - 10 comps X 100000 steps: 0.55
73
+ - 100 comps X 10000 steps: 0.55
74
+ - 1000 comps X 1000 steps: 0.49
75
+ - 10000 comps X 100 steps: 2.51
76
+ - 100000 comps X 10 steps: 3.10
77
+ queues:
78
+ - 1 senders X 100000 steps X 1 receivers: 0.26
79
+ - 10 senders X 10000 steps X 1 receivers: 0.04
80
+ - 100 senders X 1000 steps X 1 receivers: 0.02
81
+ - 1 senders X 10000 steps X 10 receivers: 0.03
82
+ - 10 senders X 1000 steps X 10 receivers: 0.01
83
+ - 100 senders X 100 steps X 10 receivers: 0.02
84
+ - 1 senders X 1000 steps X 100 receivers: 0.00
85
+ - 10 senders X 100 steps X 100 receivers: 0.02
86
+ - 100 senders X 10 steps X 100 receivers: 0.03
data/bench/aug7.bench ADDED
@@ -0,0 +1,86 @@
1
+ alg-state:
2
+ - 0 comps X 1000 steps X 0 non-alg: 0.01
3
+ - 10 comps X 1000 steps X 0 non-alg: 0.00
4
+ - 100 comps X 1000 steps X 0 non-alg: 0.02
5
+ - 1000 comps X 1000 steps X 0 non-alg: 0.08
6
+ - 10000 comps X 1000 steps X 0 non-alg: 3.95
7
+ algebraic:
8
+ - 1 comps X 1000000 steps: 2.60
9
+ - 10 comps X 100000 steps: 0.62
10
+ - 100 comps X 10000 steps: 0.47
11
+ - 1000 comps X 1000 steps: 0.47
12
+ - 10000 comps X 100 steps: 1.35
13
+ - 100000 comps X 10 steps: 1.63
14
+ connect:
15
+ - 10 comps X 100000 steps: 0.27
16
+ - 100 comps X 10000 steps: 0.07
17
+ - 1000 comps X 1000 steps: 0.09
18
+ - 10000 comps X 100 steps: 0.41
19
+ - 100000 comps X 10 steps: 0.96
20
+ continuous:
21
+ - 1 comps X 1000000 steps: 2.45
22
+ - 10 comps X 100000 steps: 0.44
23
+ - 100 comps X 10000 steps: 0.31
24
+ - 1000 comps X 1000 steps: 0.32
25
+ - 10000 comps X 100 steps: 1.12
26
+ - 100000 comps X 10 steps: 1.40
27
+ discrete:
28
+ - 1 comps X 1000000 steps X 0 watchers: 2.56
29
+ - 10 comps X 100000 steps X 0 watchers: 0.41
30
+ - 100 comps X 10000 steps X 0 watchers: 0.17
31
+ - 1000 comps X 1000 steps X 0 watchers: 0.20
32
+ - 10000 comps X 100 steps X 0 watchers: 0.54
33
+ - 100000 comps X 10 steps X 0 watchers: 0.69
34
+ - 1 comps X 1000000 steps X 1 watchers: 3.98
35
+ - 10 comps X 100000 steps X 1 watchers: 0.73
36
+ - 100 comps X 10000 steps X 1 watchers: 0.50
37
+ - 1000 comps X 1000 steps X 1 watchers: 0.59
38
+ - 10000 comps X 100 steps X 1 watchers: 2.23
39
+ - 100000 comps X 10 steps X 1 watchers: 2.78
40
+ - 1 comps X 200000 steps X 5 watchers: 0.87
41
+ - 10 comps X 20000 steps X 5 watchers: 0.41
42
+ - 100 comps X 2000 steps X 5 watchers: 0.50
43
+ - 1000 comps X 200 steps X 5 watchers: 0.90
44
+ - 10000 comps X 20 steps X 5 watchers: 2.14
45
+ - 100000 comps X 2 steps X 5 watchers: 3.43
46
+ euler:
47
+ - 1 comps X 1000000 steps: 2.43
48
+ - 10 comps X 100000 steps: 0.36
49
+ - 100 comps X 10000 steps: 0.21
50
+ - 1000 comps X 1000 steps: 0.23
51
+ - 10000 comps X 100 steps: 0.92
52
+ - 100000 comps X 10 steps: 1.17
53
+ formula:
54
+ - 1 comps X 100000 steps: 0.35
55
+ - 10 comps X 10000 steps: 0.13
56
+ - 100 comps X 1000 steps: 0.12
57
+ - 1000 comps X 100 steps: 0.12
58
+ - 10000 comps X 10 steps: 0.20
59
+ half-strict:
60
+ - 10 comps X 100000 steps: 3.93
61
+ - 100 comps X 10000 steps: 1.29
62
+ - 1000 comps X 1000 steps: 1.07
63
+ - 10000 comps X 100 steps: 1.92
64
+ - 100000 comps X 10 steps: 3.33
65
+ inertness:
66
+ - 0 comps X 10000 steps X 0 non-inert: 0.02
67
+ - 1000 comps X 10000 steps X 0 non-inert: 0.40
68
+ - 0 comps X 10000 steps X 1 non-inert: 0.17
69
+ - 1000 comps X 10000 steps X 1 non-inert: 0.50
70
+ linked-flows:
71
+ - 1 comps X 1000000 steps: 2.73
72
+ - 10 comps X 100000 steps: 0.58
73
+ - 100 comps X 10000 steps: 0.56
74
+ - 1000 comps X 1000 steps: 0.56
75
+ - 10000 comps X 100 steps: 2.74
76
+ - 100000 comps X 10 steps: 3.25
77
+ queues:
78
+ - 1 senders X 100000 steps X 1 receivers: 0.31
79
+ - 10 senders X 10000 steps X 1 receivers: 0.06
80
+ - 100 senders X 1000 steps X 1 receivers: 0.03
81
+ - 1 senders X 10000 steps X 10 receivers: 0.05
82
+ - 10 senders X 1000 steps X 10 receivers: 0.01
83
+ - 100 senders X 100 steps X 10 receivers: 0.02
84
+ - 1 senders X 1000 steps X 100 receivers: 0.01
85
+ - 10 senders X 100 steps X 100 receivers: 0.02
86
+ - 100 senders X 10 steps X 100 receivers: 0.03
data/bench/bench CHANGED
@@ -1,5 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
+ require 'rbconfig'
4
+
3
5
  def bench_one(name)
4
6
  lib = File.join(File.dirname(__FILE__), name)
5
7
  cmd = %{
@@ -7,7 +9,8 @@ def bench_one(name)
7
9
  puts "#{name}:"
8
10
  #{name.split(/[-_]/).map {|w|w.capitalize}.join}.do_bench {|l| puts l}
9
11
  }
10
- system "ruby", "-r" , "./bench", "-r", lib, "-e", cmd
12
+ ruby = Config::CONFIG["RUBY_INSTALL_NAME"]
13
+ system ruby, "-r" , "./bench", "-r", lib, "-e", cmd
11
14
  end
12
15
 
13
16
  pat = ARGV.pop
data/bench/prof.html ADDED
File without changes
@@ -85,7 +85,9 @@ VALUE rs_buffer_exhale_array(RSBuffer *buf)
85
85
 
86
86
  size = buf->len;
87
87
  ary = rb_ary_new2(size);
88
- RARRAY_LEN(ary) = size;
88
+ if (size > 0) {
89
+ rb_ary_store(ary, size-1, Qnil);
90
+ }
89
91
  for (i = buf->offset, j=0; i < size; i++, j++) {
90
92
  RARRAY_PTR(ary)[j] = rb_float_new(buf->ptr[i]);
91
93
  }
@@ -0,0 +1,236 @@
1
+ #include "dvector.h"
2
+
3
+ static void dv_mark(RS_DVector *dv)
4
+ {
5
+ long i;
6
+ if (dv->ptr) {
7
+ for (i=0; i < dv->len; i++) {
8
+ rb_gc_mark(dv->ptr[i]);
9
+ }
10
+ }
11
+ }
12
+
13
+ static void dv_free(RS_DVector *dv)
14
+ {
15
+ free(dv->ptr);
16
+ free(dv);
17
+ }
18
+
19
+ static VALUE dv_alloc(VALUE klass)
20
+ {
21
+ VALUE self;
22
+ RS_DVector *dv;
23
+
24
+ self = Data_Make_Struct(klass, RS_DVector, dv_mark, dv_free, dv);
25
+
26
+ dv->len = 0;
27
+ dv->capa = 0;
28
+ dv->ptr = 0;
29
+
30
+ return self;
31
+ }
32
+
33
+ void rs_dv_grow(RS_DVector *dv)
34
+ {
35
+ if (!dv->ptr) {
36
+ dv->capa = 16;
37
+ dv->ptr = ALLOC_N(VALUE, dv->capa);
38
+ }
39
+ else if (dv->len == dv->capa) {
40
+ dv->capa *= 2;
41
+ REALLOC_N(dv->ptr, VALUE, dv->capa);
42
+ }
43
+ }
44
+
45
+ void rs_dv_shrink(RS_DVector *dv)
46
+ {
47
+ if (dv->ptr && dv->len < dv->capa) {
48
+ REALLOC_N(dv->ptr, VALUE, dv->len);
49
+ dv->capa = dv->len;
50
+ }
51
+ }
52
+
53
+ static VALUE dv_method_push(int argc, VALUE *argv, VALUE self)
54
+ {
55
+ int i;
56
+ RS_DVector *dv;
57
+
58
+ Data_Get_Struct(self, RS_DVector, dv);
59
+
60
+ for (i = 0; i < argc; i++) {
61
+ rs_dv_push(dv, argv[i]);
62
+ }
63
+
64
+ return self;
65
+ }
66
+
67
+ static VALUE dv_method_pop(VALUE self)
68
+ {
69
+ RS_DVector *dv;
70
+
71
+ Data_Get_Struct(self, RS_DVector, dv);
72
+
73
+ return rs_dv_pop(dv);
74
+ }
75
+
76
+ static VALUE dv_method_each(VALUE self)
77
+ {
78
+ long i;
79
+ RS_DVector *dv;
80
+
81
+ Data_Get_Struct(self, RS_DVector, dv);
82
+
83
+ RETURN_ENUMERATOR(self, 0, 0);
84
+ for (i=0; i < dv->len; i++) {
85
+ rb_yield(dv->ptr[i]);
86
+ }
87
+
88
+ return self;
89
+ }
90
+
91
+ static VALUE dv_method_to_a(VALUE self)
92
+ {
93
+ RS_DVector *dv;
94
+ Data_Get_Struct(self, RS_DVector, dv);
95
+ return dv->ptr ? rb_ary_new4(dv->len, dv->ptr) : rb_ary_new();
96
+ }
97
+
98
+ static VALUE dv_method_length(VALUE self)
99
+ {
100
+ RS_DVector *dv;
101
+ Data_Get_Struct(self, RS_DVector, dv);
102
+ return INT2NUM(dv->len);
103
+ }
104
+
105
+ static VALUE recursive_equal(VALUE self, VALUE other, int recur)
106
+ {
107
+ long i;
108
+ RS_DVector *dv1, *dv2;
109
+
110
+ Data_Get_Struct(self, RS_DVector, dv1);
111
+ Data_Get_Struct(other, RS_DVector, dv2);
112
+
113
+ if (recur) return Qfalse;
114
+ for (i=0; i < dv1->len; i++) {
115
+ if (!rb_equal(dv1->ptr[i], dv2->ptr[i]))
116
+ return Qfalse;
117
+ }
118
+ return Qtrue;
119
+ }
120
+
121
+ static VALUE dv_method_equal(VALUE self, VALUE other)
122
+ {
123
+ RS_DVector *dv1, *dv2;
124
+
125
+ if (self == other) return Qtrue;
126
+ if (CLASS_OF(self) != CLASS_OF(other)) return Qfalse;
127
+
128
+ Data_Get_Struct(self, RS_DVector, dv1);
129
+ Data_Get_Struct(other, RS_DVector, dv2);
130
+ if (dv1->len != dv2->len) return Qfalse;
131
+ if (dv1->len == 0) return Qtrue;
132
+
133
+ return rb_exec_recursive(recursive_equal, self, other);
134
+ }
135
+
136
+ static VALUE recursive_eql(VALUE self, VALUE other, int recur)
137
+ {
138
+ long i;
139
+ RS_DVector *dv1, *dv2;
140
+
141
+ Data_Get_Struct(self, RS_DVector, dv1);
142
+ Data_Get_Struct(other, RS_DVector, dv2);
143
+
144
+ if (recur) return Qfalse;
145
+ for (i=0; i < dv1->len; i++) {
146
+ if (!rb_eql(dv1->ptr[i], dv2->ptr[i]))
147
+ return Qfalse;
148
+ }
149
+ return Qtrue;
150
+ }
151
+
152
+ static VALUE dv_method_eql(VALUE self, VALUE other)
153
+ {
154
+ RS_DVector *dv1, *dv2;
155
+
156
+ if (self == other) return Qtrue;
157
+ if (CLASS_OF(self) != CLASS_OF(other)) return Qfalse;
158
+
159
+ Data_Get_Struct(self, RS_DVector, dv1);
160
+ Data_Get_Struct(other, RS_DVector, dv2);
161
+ if (dv1->len != dv2->len) return Qfalse;
162
+ if (dv1->len == 0) return Qtrue;
163
+
164
+ return rb_exec_recursive(recursive_eql, self, other);
165
+ }
166
+
167
+ static VALUE recursive_hash(VALUE self, VALUE dummy, int recur)
168
+ {
169
+ long i, h;
170
+ VALUE n;
171
+ RS_DVector *dv;
172
+
173
+ if (recur) {
174
+ return LONG2FIX(0);
175
+ }
176
+
177
+ Data_Get_Struct(self, RS_DVector, dv);
178
+
179
+ h = dv->len;
180
+ for (i=0; i < dv->len; i++) {
181
+ h = (h << 1) | (h<0 ? 1 : 0);
182
+ n = rb_hash(dv->ptr[i]);
183
+ h ^= NUM2LONG(n);
184
+ }
185
+ return LONG2FIX(h);
186
+ }
187
+
188
+ static VALUE dv_method_hash(VALUE self)
189
+ {
190
+ return rb_exec_recursive(recursive_hash, self, 0);
191
+ }
192
+
193
+ static VALUE dv_method_dump_data(VALUE self)
194
+ {
195
+ RS_DVector *dv;
196
+ Data_Get_Struct(self, RS_DVector, dv);
197
+ return dv->ptr ? rb_ary_new4(dv->len, dv->ptr) : rb_ary_new();
198
+ }
199
+
200
+ static VALUE dv_method_load_data(VALUE self, VALUE from_array)
201
+ {
202
+ long i;
203
+ RS_DVector *dv;
204
+ Data_Get_Struct(self, RS_DVector, dv);
205
+
206
+ for (i=0; i < RARRAY_LEN(from_array); i++) {
207
+ rs_dv_push(dv, RARRAY_PTR(from_array)[i]);
208
+ }
209
+
210
+ return self;
211
+ }
212
+
213
+ VALUE rs_cDVector;
214
+
215
+ void
216
+ Init_dvector(void)
217
+ {
218
+ rs_cDVector = rb_path2class("RedShift::DVector");
219
+
220
+ rb_define_alloc_func(rs_cDVector, dv_alloc);
221
+ rb_define_method(rs_cDVector, "push", dv_method_push, -1);
222
+ rb_define_method(rs_cDVector, "pop", dv_method_pop, 0);
223
+ rb_define_alias(rs_cDVector, "<<", "push");
224
+
225
+ rb_define_method(rs_cDVector, "each", dv_method_each, 0);
226
+ rb_define_method(rs_cDVector, "to_a", dv_method_to_a, 0);
227
+ rb_define_method(rs_cDVector, "length", dv_method_length, 0);
228
+ rb_define_alias(rs_cDVector, "size", "length");
229
+
230
+ rb_define_method(rs_cDVector, "==", dv_method_equal, 1);
231
+ rb_define_method(rs_cDVector, "eql?", dv_method_eql, 1);
232
+ rb_define_method(rs_cDVector, "hash", dv_method_hash, 0);
233
+
234
+ rb_define_method(rs_cDVector, "_load_data", dv_method_load_data, 1);
235
+ rb_define_method(rs_cDVector, "_dump_data", dv_method_dump_data, 0);
236
+ }