trie_matcher 1.1.1 → 1.2.0
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/lib/trie_matcher.rb +33 -0
- data/lib/trie_matcher/version.rb +1 -1
- data/spec/trie_matcher_spec.rb +59 -33
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6826addd0962f940a478110fdd7f434a47576822
|
4
|
+
data.tar.gz: cbc905b0ad75449a9b8fa06794b76b2bfe9b2d6f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 81d3a5f4b73e38debef8881db1a3095c60adbb7b9bedcb3070281a1616419fb13e68198b13e970a74bbe4998126228dc5cd40ba12321307cf7359114746b1ac7
|
7
|
+
data.tar.gz: 05dba91f89e9d004ac456744e12a19263dd2951a56152e2d39556655723c36d165bd9ad5867c145f2cd0ab89bb417ccf1d2a97a011d3d4db045e346f7add3ee3
|
data/lib/trie_matcher.rb
CHANGED
@@ -44,6 +44,39 @@ class TrieMatcher
|
|
44
44
|
return previous[:value]
|
45
45
|
end
|
46
46
|
|
47
|
+
# Perform a prefix search, and return all values in the trie that have this prefix
|
48
|
+
#
|
49
|
+
# @param prefix [String] the prefix to search the trie with
|
50
|
+
# @return [<Object>] the values that start with the given prefix
|
51
|
+
def match(prefix)
|
52
|
+
result = []
|
53
|
+
current = @root
|
54
|
+
current_prefix = prefix
|
55
|
+
|
56
|
+
while current != nil && current_prefix != ""
|
57
|
+
previous, previous_prefix = current, current_prefix
|
58
|
+
current, current_prefix = next_node(current, current_prefix)
|
59
|
+
end
|
60
|
+
|
61
|
+
unless current
|
62
|
+
if current_prefix
|
63
|
+
return []
|
64
|
+
else
|
65
|
+
next_nodes = previous[:nodes].select { |prefix, node| prefix.start_with?(previous_prefix) }.values
|
66
|
+
end
|
67
|
+
else
|
68
|
+
next_nodes = [current]
|
69
|
+
end
|
70
|
+
|
71
|
+
until next_nodes.empty?
|
72
|
+
current = next_nodes.pop
|
73
|
+
result << current[:value]
|
74
|
+
current[:nodes].each { |prefix, node| next_nodes.push(node) }
|
75
|
+
end
|
76
|
+
|
77
|
+
return result.compact
|
78
|
+
end
|
79
|
+
|
47
80
|
private
|
48
81
|
# get the node for insertion, splitting shared prefixes into subnodes if necessary
|
49
82
|
def find_canididate_insertion_node(current, key)
|
data/lib/trie_matcher/version.rb
CHANGED
data/spec/trie_matcher_spec.rb
CHANGED
@@ -1,70 +1,96 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe TrieMatcher do
|
4
|
+
before do
|
5
|
+
@t = TrieMatcher.new
|
6
|
+
end
|
7
|
+
|
4
8
|
it 'has a version number' do
|
5
9
|
expect(TrieMatcher::VERSION).not_to be nil
|
6
10
|
end
|
7
11
|
|
8
12
|
it 'should store values' do
|
9
|
-
t =
|
10
|
-
t["foo"] = "bar"
|
13
|
+
@t["foo"] = "bar"
|
11
14
|
end
|
12
15
|
|
13
16
|
it 'should retrieve stored values' do
|
14
|
-
t = TrieMatcher.new
|
15
17
|
value = "bar"
|
16
|
-
t["foo"] = value
|
17
|
-
expect(t["foo"]).to be value
|
18
|
+
@t["foo"] = value
|
19
|
+
expect(@t["foo"]).to be value
|
18
20
|
end
|
19
21
|
|
20
22
|
it 'should return the stored value' do
|
21
|
-
t = TrieMatcher.new
|
22
23
|
value = "bar"
|
23
|
-
expect(t["foo"] = value).to be value
|
24
|
+
expect(@t["foo"] = value).to be value
|
24
25
|
end
|
25
26
|
|
26
27
|
it 'should store values with shared prefixes' do
|
27
|
-
t =
|
28
|
-
t["
|
29
|
-
t["
|
30
|
-
expect(t["
|
31
|
-
expect(t["car"]).to be 2
|
28
|
+
@t["cat"] = 1
|
29
|
+
@t["car"] = 2
|
30
|
+
expect(@t["cat"]).to be 1
|
31
|
+
expect(@t["car"]).to be 2
|
32
32
|
end
|
33
33
|
|
34
34
|
it 'should store keys that are a prefix of other keys' do
|
35
|
-
t =
|
36
|
-
t["
|
37
|
-
t["
|
38
|
-
expect(t["
|
39
|
-
expect(t["cat"]).to be 2
|
35
|
+
@t["catch"] = 1
|
36
|
+
@t["cat"] = 2
|
37
|
+
expect(@t["catch"]).to be 1
|
38
|
+
expect(@t["cat"]).to be 2
|
40
39
|
end
|
41
40
|
|
42
41
|
it 'should store keys that have a prefix of another key' do
|
43
|
-
t =
|
44
|
-
t["
|
45
|
-
t["
|
46
|
-
expect(t["
|
47
|
-
expect(t["catch"]).to be 2
|
42
|
+
@t["cat"] = 1
|
43
|
+
@t["catch"] = 2
|
44
|
+
expect(@t["cat"]).to be 1
|
45
|
+
expect(@t["catch"]).to be 2
|
48
46
|
end
|
49
47
|
|
50
48
|
it 'should do prefix searching' do
|
51
|
-
t =
|
52
|
-
t["
|
53
|
-
expect(t["cats"]).to be 1
|
49
|
+
@t["cat"] = 1
|
50
|
+
expect(@t["cats"]).to be 1
|
54
51
|
end
|
55
52
|
|
56
53
|
it 'should do partial prefix matching' do
|
57
|
-
t =
|
58
|
-
t["
|
59
|
-
t["cats
|
60
|
-
expect(t["cats"]).to be 1
|
54
|
+
@t["cat"] = 1
|
55
|
+
@t["cats in the cradle"] = 2
|
56
|
+
expect(@t["cats"]).to be 1
|
61
57
|
end
|
62
58
|
|
63
59
|
it 'should return the more specific prefix value' do
|
64
|
-
t =
|
65
|
-
t["
|
66
|
-
t["
|
67
|
-
|
60
|
+
@t["cat"] = 1
|
61
|
+
@t["catch"] = 2
|
62
|
+
expect(@t["catcher"]).to be 2
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'should not give a longer prefix value' do
|
66
|
+
@t["catch"] = 2
|
67
|
+
expect(@t["cat"]).to be nil
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'should return all values that are a prefix' do
|
71
|
+
@t["cats"] = 1
|
72
|
+
@t["foobar"] = 2
|
73
|
+
@t["foobaz"] = 3
|
74
|
+
@t["foobars"] = 4
|
75
|
+
@t["food"] = 5
|
76
|
+
|
77
|
+
expect(@t.match("foo").sort).to eq [2,3,4,5]
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'should return a single value when there is only one match' do
|
81
|
+
@t["cats"] = 1
|
82
|
+
@t["dogs"] = 2
|
83
|
+
@t["birds"] = 3
|
84
|
+
@t["bees"] = 4
|
85
|
+
|
86
|
+
expect(@t.match("dog")).to eq [2]
|
68
87
|
end
|
69
88
|
|
89
|
+
it 'should return an empty result when there are no prefix matches' do
|
90
|
+
@t["cat"] = 1
|
91
|
+
@t["dog"] = 2
|
92
|
+
@t["catch"] = 3
|
93
|
+
|
94
|
+
expect(@t.match("catcher")).to eq []
|
95
|
+
end
|
70
96
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: trie_matcher
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Steven Karas
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-08-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|