redshift 1.3.22 → 1.3.23

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.
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
+ }