hyperactive 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
data/tests/list_test.rb CHANGED
@@ -1,6 +1,14 @@
1
1
 
2
2
  require File.join(File.dirname(__FILE__), 'test_helper')
3
3
 
4
+ class Collector
5
+ attr_accessor :es
6
+ def call(e)
7
+ @es ||= []
8
+ @es << e
9
+ end
10
+ end
11
+
4
12
  class ListTest < Test::Unit::TestCase
5
13
 
6
14
  def setup
@@ -23,19 +31,69 @@ class ListTest < Test::Unit::TestCase
23
31
 
24
32
  def teardown
25
33
  @c.stop!
26
- @c.persistence_provider.unlink
34
+ @c.persistence_provider.unlink!
27
35
  @c2.stop!
28
- @c2.persistence_provider.unlink
36
+ @c2.persistence_provider.unlink!
29
37
  @tm.stop!
30
- @tm.persistence_provider.unlink
31
- Archipelago::Disco::MC.clear!
32
- Hyperactive::Record::CAPTAIN.update_services!
33
- assert_within(10) do
34
- Hyperactive::Record::CAPTAIN.chests.empty?
35
- end
36
- assert_within(10) do
37
- Hyperactive::Record::CAPTAIN.trannies.empty?
38
- end
38
+ @tm.persistence_provider.unlink!
39
+ end
40
+
41
+ def test_clear
42
+ l = Hyperactive::List::Head.get_instance
43
+ l << (r = Hyperactive::Record::Bass.get_instance)
44
+ assert_equal(1, l.size)
45
+ assert_equal(r, l.first)
46
+ assert_equal(r, l.last)
47
+ l.clear!
48
+ assert_equal(0, l.size)
49
+ assert_equal(nil, l.first)
50
+ assert_equal(nil, l.last)
51
+ end
52
+
53
+ def test_destroy
54
+ l = Hyperactive::List::Head.get_instance
55
+ l << (r = Hyperactive::Record::Bass.get_instance)
56
+ r1 = l.first_element.record_id
57
+ r2 = l.record_id
58
+ l.destroy!
59
+ assert(!Hyperactive::Record::CAPTAIN.include?(r1))
60
+ assert(!Hyperactive::Record::CAPTAIN.include?(r2))
61
+ end
62
+
63
+ def test_each
64
+ l = Hyperactive::List::Head.get_instance
65
+ l << (r = Hyperactive::Record::Bass.get_instance)
66
+ l << (r2 = Hyperactive::Record::Bass.get_instance)
67
+ l << (r3 = Hyperactive::Record::Bass.get_instance)
68
+ c = Collector.new
69
+ l.t_each(c)
70
+ assert_equal(3, c.es.size)
71
+ assert(c.es.include?(r))
72
+ assert(c.es.include?(r2))
73
+ assert(c.es.include?(r3))
74
+ end
75
+
76
+ def test_unlink
77
+ l = Hyperactive::List::Head.get_instance
78
+ l << (r = Hyperactive::Record::Bass.get_instance)
79
+ l << (r2 = Hyperactive::Record::Bass.get_instance)
80
+ e = l.last_element
81
+ l << (r3 = Hyperactive::Record::Bass.get_instance)
82
+ assert_equal([r, r2, r3].sort, l.t_collect do |ec| ec end.sort)
83
+ l.unlink!(e)
84
+ assert_equal(2, l.size)
85
+ assert_equal(r, l.first)
86
+ assert_equal(r3, l.last)
87
+ assert_equal(r3, l.first_element.next.value)
88
+ l.unlink!(l.last_element)
89
+ assert_equal(1, l.size)
90
+ assert_equal(r, l.first)
91
+ assert_equal(r, l.last)
92
+ l.unlink!(l.first_element)
93
+ assert_equal(0, l.size)
94
+ assert_equal(nil, l.first)
95
+ assert_equal(nil, l.last)
96
+ assert_equal([], l.t_collect do |e| e end)
39
97
  end
40
98
 
41
99
  def test_push_unshift_pop_shift
data/tests/record_test.rb CHANGED
@@ -3,7 +3,9 @@ require File.join(File.dirname(__FILE__), 'test_helper')
3
3
 
4
4
  class MyRecord < Hyperactive::Record::Bass
5
5
  attr_accessor :bajs
6
-
6
+ def initialize
7
+ @bajs = nil
8
+ end
7
9
  def self.save_hook(instance, &block)
8
10
  $BEFORE_SAVE += 1
9
11
  yield
@@ -54,19 +56,11 @@ class RecordTest < Test::Unit::TestCase
54
56
 
55
57
  def teardown
56
58
  @c.stop!
57
- @c.persistence_provider.unlink
59
+ @c.persistence_provider.unlink!
58
60
  @c2.stop!
59
- @c2.persistence_provider.unlink
61
+ @c2.persistence_provider.unlink!
60
62
  @tm.stop!
61
- @tm.persistence_provider.unlink
62
- Archipelago::Disco::MC.clear!
63
- Hyperactive::Record::CAPTAIN.update_services!
64
- assert_within(10) do
65
- Hyperactive::Record::CAPTAIN.chests.empty?
66
- end
67
- assert_within(10) do
68
- Hyperactive::Record::CAPTAIN.trannies.empty?
69
- end
63
+ @tm.persistence_provider.unlink!
70
64
  end
71
65
 
72
66
  def test_index_find
@@ -82,18 +76,18 @@ class RecordTest < Test::Unit::TestCase
82
76
  r4 = MyRecord.get_instance
83
77
  r4.bajs = "beige"
84
78
 
85
- assert_equal(Set.new([r2.record_id,r1.record_id]), Set.new(MyRecord.find_by_bajs("brunt").collect(Proc.new do |k,v|
86
- v.record_id
87
- end)))
88
- assert_equal([r3.record_id], MyRecord.find_by_bajs("gult").collect(Proc.new do |k,v|
89
- v.record_id
90
- end))
79
+ assert_equal(Set.new([r2.record_id,r1.record_id]), Set.new(MyRecord.find_by_bajs("brunt").t_collect(Proc.new do |k,v|
80
+ v.record_id
81
+ end)))
82
+ assert_equal([r3.record_id], MyRecord.find_by_bajs("gult").t_collect(Proc.new do |k,v|
83
+ v.record_id
84
+ end))
91
85
 
92
- r1.destroy
86
+ r1.destroy!
93
87
 
94
- assert_equal([r2.record_id], MyRecord.find_by_bajs("brunt").collect(Proc.new do |k,v|
95
- v.record_id
96
- end))
88
+ assert_equal([r2.record_id], MyRecord.find_by_bajs("brunt").t_collect(Proc.new do |k,v|
89
+ v.record_id
90
+ end))
97
91
 
98
92
  end
99
93
 
@@ -115,22 +109,22 @@ class RecordTest < Test::Unit::TestCase
115
109
  r4 = MyRecord.get_instance
116
110
  r4.bajs = "beige"
117
111
 
118
- assert_equal(Set.new([r2.record_id,r1.record_id]), Set.new(MyRecord.brunt.collect(Proc.new do |k,v|
112
+ assert_equal(Set.new([r2.record_id,r1.record_id]), Set.new(MyRecord.brunt.t_collect(Proc.new do |k,v|
119
113
  v.record_id
120
114
  end)))
121
- assert_equal(Set.new([r3.record_id,r4.record_id]), Set.new(MyRecord.not_brunt.collect(Proc.new do |k,v|
115
+ assert_equal(Set.new([r3.record_id,r4.record_id]), Set.new(MyRecord.not_brunt.t_collect(Proc.new do |k,v|
122
116
  v.record_id
123
117
  end)))
124
118
 
125
- r1.destroy
126
- r2.destroy
127
- r3.destroy
128
- r4.destroy
119
+ r1.destroy!
120
+ r2.destroy!
121
+ r3.destroy!
122
+ r4.destroy!
129
123
 
130
- assert_equal(Set.new, Set.new(MyRecord.brunt.collect(Proc.new do |k,v|
124
+ assert_equal(Set.new, Set.new(MyRecord.brunt.t_collect(Proc.new do |k,v|
131
125
  v.record_id
132
126
  end)))
133
- assert_equal(Set.new, Set.new(MyRecord.not_brunt.collect(Proc.new do |k,v|
127
+ assert_equal(Set.new, Set.new(MyRecord.not_brunt.t_collect(Proc.new do |k,v|
134
128
  v.record_id
135
129
  end)))
136
130
  end
@@ -149,7 +143,7 @@ class RecordTest < Test::Unit::TestCase
149
143
  assert_equal("brunt", Hyperactive::Record::CAPTAIN[r.record_id].bajs)
150
144
  i = r.record_id
151
145
  assert_equal(r, Hyperactive::Record::CAPTAIN[i])
152
- r.destroy
146
+ r.destroy!
153
147
  assert_equal(1, $BEFORE_DESTROY)
154
148
  assert_equal(1, $AFTER_DESTROY)
155
149
  assert_equal(nil, Hyperactive::Record::CAPTAIN[i])
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
3
3
  specification_version: 1
4
4
  name: hyperactive
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.2.2
7
- date: 2006-11-28 00:00:00 +01:00
6
+ version: 0.2.3
7
+ date: 2006-11-29 00:00:00 +01:00
8
8
  summary: A base class for persistent objects that uses archipelago for persistence. Useful for Ruby on Rails models for example.
9
9
  require_paths:
10
10
  - lib
@@ -29,21 +29,22 @@ authors:
29
29
  - Martin Kihlgren
30
30
  files:
31
31
  - lib/hyperactive.rb
32
+ - lib/hyperactive/hash.rb
32
33
  - lib/hyperactive/hooker.rb
33
34
  - lib/hyperactive/list.rb
34
35
  - lib/hyperactive/record.rb
35
- - lib/hyperactive/tree.rb
36
+ - tests/hash_benchmark.rb
37
+ - tests/hash_test.rb
38
+ - tests/list_benchmark.rb
36
39
  - tests/list_test.rb
37
40
  - tests/record_test.rb
38
41
  - tests/test_helper.rb
39
- - tests/tree_benchmark.rb
40
- - tests/tree_test.rb
41
42
  - GPL-2
42
43
  - README
43
44
  test_files:
45
+ - tests/hash_test.rb
44
46
  - tests/list_test.rb
45
47
  - tests/record_test.rb
46
- - tests/tree_test.rb
47
48
  - tests/test_helper.rb
48
49
  rdoc_options:
49
50
  - --line-numbers
@@ -1,241 +0,0 @@
1
- # Archipelago - a distributed computing toolkit for ruby
2
- # Copyright (C) 2006 Martin Kihlgren <zond at troja dot ath dot cx>
3
- #
4
- # This program is free software; you can redistribute it and/or
5
- # modify it under the terms of the GNU General Public License
6
- # as published by the Free Software Foundation; either version 2
7
- # of the License, or (at your option) any later version.
8
- #
9
- # This program is distributed in the hope that it will be useful,
10
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
- # GNU General Public License for more details.
13
- #
14
- # You should have received a copy of the GNU General Public License
15
- # along with this program; if not, write to the Free Software
16
- # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
-
18
-
19
- require 'rubygems'
20
- require 'archipelago'
21
- require 'rbtree'
22
-
23
- module Hyperactive
24
-
25
- #
26
- # The package containing the Hash-like Tree class that provides any
27
- # kind of index for your Hyperactive classes.
28
- #
29
- module Tree
30
-
31
- #
32
- # A class suitable for storing large and often-changing datasets in
33
- # an Archipelago environment.
34
- #
35
- # Is constructed like a set of nested Hashes that automatically create
36
- # new children on demand, and will thusly only have to check the path from
37
- # the root node to the leaf for changes when method calls return (see Archipelago::Treasure::Chest)
38
- # and will only have to actually store into database the leaf itself if it
39
- # has changed.
40
- #
41
- class Root < Hyperactive::Record::Bass
42
-
43
- attr_accessor :elements, :subtrees
44
-
45
- WIDTH = 1 << 3
46
-
47
- #
48
- # Dont call this! Call <i>Root.get_instance(options)</i> instead!
49
- #
50
- def initialize(options = {})
51
- @width = options[:width] || WIDTH
52
- @elements = {}
53
- @subtrees = nil
54
- end
55
-
56
- #
57
- # Deletes +key+ in this Root.
58
- #
59
- def delete(key)
60
- if @elements
61
- @elements.delete(key)
62
- else
63
- subtree_for(key).delete(key)
64
- end
65
- end
66
-
67
- #
68
- # Returns the size of this Root.
69
- #
70
- def size
71
- if @elements
72
- @elements.size
73
- else
74
- @subtrees.t_collect do |tree_id, tree|
75
- tree.size
76
- end.inject(0) do |sum, size|
77
- sum + size
78
- end
79
- end
80
- end
81
-
82
- #
83
- # Returns all keys and values returning true for +callable+.call(key, value) in this Root.
84
- #
85
- def select(callable)
86
- if @elements
87
- @elements.select do |k,v|
88
- callable.call(k,v)
89
- end
90
- else
91
- @subtrees.t_collect do |tree_id, tree|
92
- tree.select(callable)
93
- end.inject([]) do |sum, match|
94
- sum + match
95
- end
96
- end
97
- end
98
-
99
- #
100
- # Returns all keys and values returning false for +callable+.call(key, value) in this Root.
101
- #
102
- def reject(callable)
103
- if @elements
104
- @elements.reject do |k,v|
105
- callable.call(k,v)
106
- end
107
- else
108
- @subtrees.t_collect do |tree_id, tree|
109
- tree.reject(callable)
110
- end.inject([]) do |sum, match|
111
- sum + match
112
- end
113
- end
114
- end
115
-
116
- #
117
- # Puts +value+ under +key+ in this Root.
118
- #
119
- def []=(key, value)
120
- if @elements
121
- if @elements.size < @width
122
- @elements[key] = value
123
- else
124
- split!
125
- subtree_for(key)[key] = value
126
- end
127
- else
128
- subtree_for(key)[key] = value
129
- end
130
- return value
131
- end
132
-
133
- #
134
- # Returns the value for +key+ in this Root.
135
- #
136
- def [](key)
137
- if @elements
138
- return @elements[key]
139
- else
140
- return subtree_for(key)[key]
141
- end
142
- end
143
-
144
- #
145
- # Returns an Array containing +callable+.call(key, value) from all values in this Root.
146
- #
147
- def collect(callable)
148
- rval = []
149
- self.each(Proc.new do |k,v|
150
- rval << callable.call(k,v)
151
- end)
152
- return rval
153
- end
154
-
155
- #
156
- # Does +callable+.call(key, value) on all values in this Root.
157
- #
158
- def each(callable)
159
- if @elements
160
- @elements.each do |key, value|
161
- callable.call(key, value)
162
- end
163
- else
164
- @subtrees.t_each do |tree_id, tree|
165
- tree.each(callable)
166
- end
167
- nil
168
- end
169
- end
170
-
171
- #
172
- # Clear everything from this Tree and destroy it.
173
- #
174
- def destroy
175
- if @elements
176
- @elements.each do |key, value|
177
- value.destroy if value.respond_to?(:destroy)
178
- end
179
- else
180
- @subtrees.each do |tree_id, tree|
181
- tree.destroy
182
- end
183
- end
184
- freeze
185
- super
186
- end
187
-
188
- #
189
- # Clear everything from this Root.
190
- #
191
- def clear
192
- unless @elements
193
- @subtrees.each do |tree_id, tree|
194
- tree.clear
195
- end
196
- @subtrees = nil
197
- end
198
- @elements = {}
199
- end
200
-
201
- private
202
-
203
- #
204
- # Finds the subtree responsible for +key+.
205
- #
206
- # Does it in this ugly way cause the nice way of just doing modulo gave
207
- # really odd results since all hashes seem to give some modulo values
208
- # a lot more often than expected.
209
- #
210
- def subtree_for(key)
211
- key_id = Digest::SHA1.new("#{key.hash}#{self.record_id}").to_s
212
- @subtrees.each do |tree_id, tree|
213
- return tree if tree_id > key_id
214
- end
215
- return @subtrees.values.first
216
- end
217
-
218
- #
219
- # Split this Tree by creating @subtrees,
220
- # then putting all @elements in them and then emptying @elements.
221
- #
222
- def split!
223
- raise "Cant split twice!" unless @elements
224
-
225
- @subtrees = RBTree.new
226
- @subtrees.extend(Archipelago::Current::ThreadedCollection)
227
- step = (1 << 160) / @width
228
- 0.upto(@width - 1) do |n|
229
- @subtrees["%x" % (n * step)] = Root.get_instance(:width => @width)
230
- end
231
- @elements.each do |key, value|
232
- subtree_for(key)[key] = value
233
- end
234
- @elements = nil
235
- end
236
-
237
- end
238
-
239
- end
240
-
241
- end