hamster 0.1.5 → 0.1.6
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.
- data/History.rdoc +4 -0
- data/lib/hamster/hash.rb +8 -5
- data/lib/hamster/set.rb +5 -5
- data/lib/hamster/trie.rb +43 -24
- data/lib/hamster/version.rb +1 -1
- data/spec/hamster/hash/eql_spec.rb +14 -0
- data/spec/hamster/hash/has_key_spec.rb +5 -1
- data/spec/hamster/hash/put_spec.rb +12 -0
- data/spec/hamster/hash/remove_spec.rb +13 -9
- data/tasks/spec.rb +1 -1
- metadata +2 -2
data/History.rdoc
CHANGED
data/lib/hamster/hash.rb
CHANGED
@@ -23,7 +23,10 @@ module Hamster
|
|
23
23
|
|
24
24
|
# Retrieves the value corresponding to the given key. If not found, returns <tt>nil</tt>.
|
25
25
|
def get(key)
|
26
|
-
@trie.get(key)
|
26
|
+
entry = @trie.get(key)
|
27
|
+
if entry
|
28
|
+
entry.value
|
29
|
+
end
|
27
30
|
end
|
28
31
|
|
29
32
|
# Returns a copy of <tt>self</tt> with the given value associated with the key.
|
@@ -34,10 +37,10 @@ module Hamster
|
|
34
37
|
# Returns a copy of <tt>self</tt> with the given key/value pair removed. If not found, returns <tt>self</tt>.
|
35
38
|
def remove(key)
|
36
39
|
copy = @trie.remove(key)
|
37
|
-
if copy.equal?(@trie)
|
38
|
-
self
|
39
|
-
else
|
40
|
+
if !copy.equal?(@trie)
|
40
41
|
self.class.new(copy)
|
42
|
+
else
|
43
|
+
self
|
41
44
|
end
|
42
45
|
end
|
43
46
|
|
@@ -45,7 +48,7 @@ module Hamster
|
|
45
48
|
# Returns <tt>self</tt>
|
46
49
|
def each
|
47
50
|
block_given? or return enum_for(__method__)
|
48
|
-
@trie.each { |
|
51
|
+
@trie.each { |entry| yield entry.key, entry.value }
|
49
52
|
self
|
50
53
|
end
|
51
54
|
|
data/lib/hamster/set.rb
CHANGED
@@ -13,7 +13,7 @@ module Hamster
|
|
13
13
|
|
14
14
|
# Returns <tt>true</tt> if the set contains no items.
|
15
15
|
def empty?
|
16
|
-
@trie.
|
16
|
+
@trie.empty?
|
17
17
|
end
|
18
18
|
|
19
19
|
# Returns <tt>true</tt> if the given item is present in the set.
|
@@ -33,10 +33,10 @@ module Hamster
|
|
33
33
|
# Returns a copy of <tt>self</tt> with the given item removed. If not found, returns <tt>self</tt>.
|
34
34
|
def remove(key)
|
35
35
|
copy = @trie.remove(item)
|
36
|
-
if copy.equal?(@trie)
|
37
|
-
self
|
38
|
-
else
|
36
|
+
if !copy.equal?(@trie)
|
39
37
|
self.class.new(copy)
|
38
|
+
else
|
39
|
+
self
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
@@ -44,7 +44,7 @@ module Hamster
|
|
44
44
|
# Returns <tt>self</tt>
|
45
45
|
def each
|
46
46
|
block_given? or return enum_for(__method__)
|
47
|
-
@trie.each { |
|
47
|
+
@trie.each { |entry| yield entry.key }
|
48
48
|
self
|
49
49
|
end
|
50
50
|
|
data/lib/hamster/trie.rb
CHANGED
@@ -27,9 +27,9 @@ module Hamster
|
|
27
27
|
|
28
28
|
# Calls <tt>block</tt> once for each entry in the trie, passing the key-value pair as parameters.
|
29
29
|
def each
|
30
|
-
@entries.each { |entry| yield entry
|
30
|
+
@entries.each { |entry| yield entry if entry }
|
31
31
|
@children.each do |child|
|
32
|
-
child.each { |
|
32
|
+
child.each { |entry| yield entry } if child
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
@@ -37,7 +37,11 @@ module Hamster
|
|
37
37
|
def put(key, value)
|
38
38
|
index = index_for(key)
|
39
39
|
entry = @entries[index]
|
40
|
-
if entry
|
40
|
+
if !entry || entry.key_eql?(key)
|
41
|
+
entries = @entries.dup
|
42
|
+
entries[index] = Entry.new(key, value)
|
43
|
+
self.class.new(@significant_bits, entries, @children)
|
44
|
+
else
|
41
45
|
children = @children.dup
|
42
46
|
child = children[index]
|
43
47
|
children[index] = if child
|
@@ -46,19 +50,15 @@ module Hamster
|
|
46
50
|
self.class.new(@significant_bits + 5).put!(key, value)
|
47
51
|
end
|
48
52
|
self.class.new(@significant_bits, @entries, children)
|
49
|
-
else
|
50
|
-
entries = @entries.dup
|
51
|
-
entries[index] = Entry.new(key, value)
|
52
|
-
self.class.new(@significant_bits, entries, @children)
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
-
# Retrieves the
|
56
|
+
# Retrieves the entry corresponding to the given key. If not found, returns <tt>nil</tt>.
|
57
57
|
def get(key)
|
58
58
|
index = index_for(key)
|
59
59
|
entry = @entries[index]
|
60
|
-
if entry && entry.
|
61
|
-
entry
|
60
|
+
if entry && entry.key_eql?(key)
|
61
|
+
entry
|
62
62
|
else
|
63
63
|
child = @children[index]
|
64
64
|
if child
|
@@ -67,44 +67,63 @@ module Hamster
|
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
70
|
-
# Returns a copy of <tt>self</tt> with the given key
|
70
|
+
# Returns a copy of <tt>self</tt> with the given key (and associated value) removed. If not found, returns <tt>self</tt>.
|
71
71
|
def remove(key)
|
72
|
-
|
72
|
+
xxx(key) || Trie.new(@significant_bits)
|
73
73
|
end
|
74
74
|
|
75
75
|
# Returns <tt>true</tt> if . <tt>eql?</tt> is synonymous with <tt>==</tt>
|
76
76
|
def eql?(other)
|
77
|
-
|
77
|
+
false
|
78
78
|
end
|
79
79
|
alias :== :eql?
|
80
80
|
|
81
81
|
protected
|
82
82
|
|
83
|
+
# Returns <tt>self</tt> after overwriting the element associated with the specified key.
|
83
84
|
def put!(key, value)
|
84
85
|
@entries[index_for(key)] = Entry.new(key, value)
|
85
86
|
self
|
86
87
|
end
|
87
|
-
|
88
|
-
|
88
|
+
|
89
|
+
# Returns a replacement instance after removing the specified key.
|
90
|
+
# If not found, returns <tt>self</tt>.
|
91
|
+
# If empty, returns <tt>nil</tt>.
|
92
|
+
def xxx(key)
|
89
93
|
index = index_for(key)
|
90
94
|
entry = @entries[index]
|
91
|
-
if entry && entry.
|
92
|
-
|
93
|
-
entries = @entries.dup
|
94
|
-
entries[index] = nil
|
95
|
-
self.class.new(@significant_bits, entries, @children)
|
96
|
-
end
|
95
|
+
if entry && entry.key_eql?(key)
|
96
|
+
return remove_at(index)
|
97
97
|
else
|
98
98
|
child = @children[index]
|
99
99
|
if child
|
100
|
-
copy = child.
|
100
|
+
copy = child.xxx(key)
|
101
101
|
if !copy.equal?(child)
|
102
102
|
children = @children.dup
|
103
103
|
children[index] = copy
|
104
|
-
self.class.new(@significant_bits, @entries, children)
|
104
|
+
return self.class.new(@significant_bits, @entries, children)
|
105
105
|
end
|
106
106
|
end
|
107
107
|
end
|
108
|
+
self
|
109
|
+
end
|
110
|
+
|
111
|
+
# Returns a replacement instance after removing the specified entry. If empty, returns <tt>nil</tt>
|
112
|
+
def remove_at(index = @entries.index { |e| e })
|
113
|
+
yield @entries[index] if block_given?
|
114
|
+
if size > 1
|
115
|
+
entries = @entries.dup
|
116
|
+
child = @children[index]
|
117
|
+
if child
|
118
|
+
children = @children.dup
|
119
|
+
children[index] = child.remove_at do |entry|
|
120
|
+
entries[index] = entry
|
121
|
+
end
|
122
|
+
else
|
123
|
+
entries[index] = nil
|
124
|
+
end
|
125
|
+
self.class.new(@significant_bits, entries, children || @children)
|
126
|
+
end
|
108
127
|
end
|
109
128
|
|
110
129
|
private
|
@@ -122,7 +141,7 @@ module Hamster
|
|
122
141
|
@value = value
|
123
142
|
end
|
124
143
|
|
125
|
-
def
|
144
|
+
def key_eql?(key)
|
126
145
|
@key.eql?(key)
|
127
146
|
end
|
128
147
|
|
data/lib/hamster/version.rb
CHANGED
@@ -15,6 +15,20 @@ describe Hamster::Hash do
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
+
it "is true for two instances with the same key/value pairs" do
|
19
|
+
pending do
|
20
|
+
a = Hamster::Hash.new.put("a", "Aye").put("b", "Bee").put("c", "See")
|
21
|
+
b = Hamster::Hash.new.put("a", "Aye").put("b", "Bee").put("c", "See")
|
22
|
+
a.should eql(b)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
it "is false for two instances with different key/value pairs" do
|
27
|
+
a = Hamster::Hash.new.put("a", "Aye").put("b", "Bee").put("c", "See")
|
28
|
+
b = Hamster::Hash.new.put("a", "Aye").put("b", "Bee")
|
29
|
+
a.should_not eql(b)
|
30
|
+
end
|
31
|
+
|
18
32
|
end
|
19
33
|
|
20
34
|
end
|
@@ -5,7 +5,7 @@ describe Hamster::Hash do
|
|
5
5
|
describe "#has_key?" do
|
6
6
|
|
7
7
|
before do
|
8
|
-
@hash = Hamster::Hash.new.put("A", "aye")
|
8
|
+
@hash = Hamster::Hash.new.put("A", "aye").put("NIL", nil)
|
9
9
|
end
|
10
10
|
|
11
11
|
it "returns true for an existing key" do
|
@@ -15,6 +15,10 @@ describe Hamster::Hash do
|
|
15
15
|
it "returns false for a non-existing key" do
|
16
16
|
@hash.has_key?("B").should be_false
|
17
17
|
end
|
18
|
+
|
19
|
+
it "returns true for a nil value" do
|
20
|
+
@hash.has_key?("NIL").should be_true
|
21
|
+
end
|
18
22
|
|
19
23
|
end
|
20
24
|
|
@@ -88,6 +88,18 @@ describe Hamster::Hash do
|
|
88
88
|
|
89
89
|
end
|
90
90
|
|
91
|
+
describe "with a nil key" do
|
92
|
+
|
93
|
+
before do
|
94
|
+
@hash = Hamster::Hash.new.put(nil, "NIL")
|
95
|
+
end
|
96
|
+
|
97
|
+
it "can locate the key/value pair" do
|
98
|
+
@hash.get(nil).should == "NIL"
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
91
103
|
end
|
92
104
|
|
93
105
|
end
|
@@ -3,6 +3,18 @@ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
|
3
3
|
describe Hamster::Hash do
|
4
4
|
|
5
5
|
describe "#remove" do
|
6
|
+
|
7
|
+
describe "the last key" do
|
8
|
+
|
9
|
+
before do
|
10
|
+
@hash = Hamster::Hash.new.put("A", "aye").remove("A")
|
11
|
+
end
|
12
|
+
|
13
|
+
it "no longer provides access to the removed key" do
|
14
|
+
@hash.has_key?("A").should be_false
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
6
18
|
|
7
19
|
describe "with an existing key" do
|
8
20
|
|
@@ -79,7 +91,7 @@ describe Hamster::Hash do
|
|
79
91
|
|
80
92
|
def instance_count
|
81
93
|
ObjectSpace.garbage_collect
|
82
|
-
ObjectSpace.each_object(Hamster::
|
94
|
+
ObjectSpace.each_object(Hamster::Trie) {}
|
83
95
|
end
|
84
96
|
|
85
97
|
before do
|
@@ -98,14 +110,6 @@ describe Hamster::Hash do
|
|
98
110
|
copy.get(@b).should == "bee"
|
99
111
|
end
|
100
112
|
|
101
|
-
it "cleans up empty instances" do
|
102
|
-
pending do
|
103
|
-
instance_count_before = instance_count
|
104
|
-
# copy = @original.remove(@b)
|
105
|
-
instance_count.should == instance_count_before + 1
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
113
|
end
|
110
114
|
|
111
115
|
end
|
data/tasks/spec.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hamster
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Simon Harris
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-11-
|
12
|
+
date: 2009-11-23 00:00:00 +11:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|