rambling-trie 0.3.0 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/invalid_trie_operation.rb +3 -0
- data/lib/rambling-trie.rb +1 -0
- data/lib/trie.rb +16 -3
- data/lib/trie_branches.rb +68 -0
- data/lib/trie_compressor.rb +14 -4
- data/lib/trie_node.rb +1 -32
- metadata +17 -5
data/lib/rambling-trie.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), 'invalid_trie_operation.rb')
|
2
2
|
require File.join(File.dirname(__FILE__), 'children_hash_deferer.rb')
|
3
3
|
require File.join(File.dirname(__FILE__), 'trie_compressor.rb')
|
4
|
+
require File.join(File.dirname(__FILE__), 'trie_branches.rb')
|
4
5
|
require File.join(File.dirname(__FILE__), 'trie_node.rb')
|
5
6
|
require File.join(File.dirname(__FILE__), 'trie.rb')
|
6
7
|
|
data/lib/trie.rb
CHANGED
@@ -4,16 +4,29 @@ module Rambling
|
|
4
4
|
super(nil)
|
5
5
|
|
6
6
|
@filename = filename
|
7
|
+
@is_compressed = false
|
7
8
|
add_all_nodes if filename
|
8
9
|
end
|
9
10
|
|
10
11
|
def compress!
|
11
|
-
|
12
|
-
|
12
|
+
unless compressed?
|
13
|
+
compress_own_tree!
|
14
|
+
@is_compressed = true
|
15
|
+
end
|
16
|
+
|
17
|
+
self
|
13
18
|
end
|
14
19
|
|
15
20
|
def compressed?
|
16
|
-
@is_compressed
|
21
|
+
@is_compressed = @is_compressed.nil? ? false : @is_compressed
|
22
|
+
end
|
23
|
+
|
24
|
+
def has_branch_for?(word = '')
|
25
|
+
compressed? ? has_compressed_branch_for?(word) : has_uncompressed_branch_for?(word)
|
26
|
+
end
|
27
|
+
|
28
|
+
def is_word?(word = '')
|
29
|
+
compressed? ? is_compressed_word?(word) : is_uncompressed_word?(word)
|
17
30
|
end
|
18
31
|
|
19
32
|
private
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Rambling
|
2
|
+
module TrieBranches
|
3
|
+
def add_branch_from(word)
|
4
|
+
raise InvalidTrieOperation.new('Cannot add branch to compressed trie') if compressed?
|
5
|
+
if word.empty?
|
6
|
+
@is_terminal = true
|
7
|
+
return
|
8
|
+
end
|
9
|
+
|
10
|
+
first_letter = word.slice(0).to_sym
|
11
|
+
|
12
|
+
if @children.has_key?(first_letter)
|
13
|
+
word.slice!(0)
|
14
|
+
@children[first_letter].add_branch_from(word)
|
15
|
+
else
|
16
|
+
@children[first_letter] = TrieNode.new(word, self)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
protected
|
21
|
+
|
22
|
+
def has_uncompressed_branch_for?(word = '')
|
23
|
+
word.empty? or fulfills_uncompressed_condition?(:has_uncompressed_branch_for?, word)
|
24
|
+
end
|
25
|
+
|
26
|
+
def fulfills_uncompressed_condition?(method, word)
|
27
|
+
clone = word.clone
|
28
|
+
first_letter = clone.slice!(0)
|
29
|
+
unless first_letter.nil?
|
30
|
+
first_letter_sym = first_letter.to_sym
|
31
|
+
return @children[first_letter_sym].send(method, clone) if @children.has_key?(first_letter_sym)
|
32
|
+
end
|
33
|
+
|
34
|
+
false
|
35
|
+
end
|
36
|
+
|
37
|
+
def has_compressed_branch_for?(word = '')
|
38
|
+
return true if word.empty?
|
39
|
+
|
40
|
+
keys = @children.keys.map { |x| x.to_s }
|
41
|
+
return true if keys.include?(word)
|
42
|
+
|
43
|
+
partial_key = keys.select { |x| x.start_with?(word) }.first
|
44
|
+
return true unless partial_key.nil?
|
45
|
+
|
46
|
+
key = keys.select { |x| word.start_with?(x) }.first
|
47
|
+
return @children[key.to_sym].has_compressed_branch_for?(word.slice(key.length..word.length)) unless key.nil?
|
48
|
+
|
49
|
+
false
|
50
|
+
end
|
51
|
+
|
52
|
+
def is_uncompressed_word?(word = '')
|
53
|
+
(word.empty? and terminal?) or fulfills_uncompressed_condition?(:is_uncompressed_word?, word)
|
54
|
+
end
|
55
|
+
|
56
|
+
def is_compressed_word?(word = '')
|
57
|
+
return true if word.empty? and terminal?
|
58
|
+
|
59
|
+
length = word.length
|
60
|
+
for index in (0...length)
|
61
|
+
key = word.slice(0..index).to_sym
|
62
|
+
return @children[key].is_compressed_word?(word.slice((index + 1)...length)) if @children.has_key?(key)
|
63
|
+
end
|
64
|
+
|
65
|
+
false
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/lib/trie_compressor.rb
CHANGED
@@ -1,12 +1,22 @@
|
|
1
1
|
module Rambling
|
2
2
|
module TrieCompressor
|
3
|
-
def
|
4
|
-
if
|
3
|
+
def compressed?
|
4
|
+
if instance_variable_defined?(:@is_compressed)
|
5
|
+
@is_compressed
|
6
|
+
else
|
7
|
+
@parent.nil? ? false : @parent.compressed?
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
protected
|
12
|
+
|
13
|
+
def compress_own_tree!
|
14
|
+
if @children.size == 1 and not terminal? and not @letter.nil?
|
5
15
|
merge_with!(@children.values.first)
|
6
|
-
|
16
|
+
compress_own_tree!
|
7
17
|
end
|
8
18
|
|
9
|
-
@children.values.each { |node| node.
|
19
|
+
@children.values.each { |node| node.compress_own_tree! }
|
10
20
|
|
11
21
|
self
|
12
22
|
end
|
data/lib/trie_node.rb
CHANGED
@@ -2,6 +2,7 @@ module Rambling
|
|
2
2
|
class TrieNode
|
3
3
|
include ChildrenHashDeferer
|
4
4
|
include TrieCompressor
|
5
|
+
include TrieBranches
|
5
6
|
|
6
7
|
attr_reader :letter, :children, :parent
|
7
8
|
|
@@ -27,32 +28,11 @@ module Rambling
|
|
27
28
|
@is_terminal
|
28
29
|
end
|
29
30
|
|
30
|
-
def add_branch_from(word)
|
31
|
-
return if word.empty?
|
32
|
-
|
33
|
-
first_letter = word.slice(0).to_sym
|
34
|
-
|
35
|
-
if @children.has_key?(first_letter)
|
36
|
-
word.slice!(0)
|
37
|
-
@children[first_letter].add_branch_from(word)
|
38
|
-
else
|
39
|
-
@children[first_letter] = TrieNode.new(word, self)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def has_branch_for?(word)
|
44
|
-
word.empty? or branch_exists_and(word, :has_branch_for?)
|
45
|
-
end
|
46
|
-
|
47
31
|
def as_word
|
48
32
|
raise InvalidTrieOperation.new() unless @letter.nil? or terminal?
|
49
33
|
get_letter_string
|
50
34
|
end
|
51
35
|
|
52
|
-
def is_word?(word = '')
|
53
|
-
(word.empty? and terminal?) or branch_exists_and(word, :is_word?)
|
54
|
-
end
|
55
|
-
|
56
36
|
protected
|
57
37
|
def get_letter_string
|
58
38
|
(@parent.nil? ? '' : @parent.get_letter_string) + @letter.to_s
|
@@ -61,16 +41,5 @@ module Rambling
|
|
61
41
|
def parent=(parent)
|
62
42
|
@parent = parent
|
63
43
|
end
|
64
|
-
|
65
|
-
private
|
66
|
-
|
67
|
-
def branch_exists_and(word, method)
|
68
|
-
first_letter = word.slice!(0)
|
69
|
-
|
70
|
-
return false if first_letter.nil?
|
71
|
-
|
72
|
-
first_letter_key = first_letter.to_sym
|
73
|
-
@children.has_key?(first_letter_key) ? @children[first_letter_key].send(method, word) : false
|
74
|
-
end
|
75
44
|
end
|
76
45
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rambling-trie
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-02-
|
12
|
+
date: 2012-02-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
requirement: &
|
16
|
+
requirement: &14554820 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,7 +21,18 @@ dependencies:
|
|
21
21
|
version: 2.0.0
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *14554820
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rake
|
27
|
+
requirement: &14554220 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 0.9.2
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *14554220
|
25
36
|
description: The Rambling Trie is a custom implementation of the Trie data structure
|
26
37
|
with Ruby, which includes compression abilities and is designed to be very fast
|
27
38
|
to traverse.
|
@@ -34,6 +45,7 @@ files:
|
|
34
45
|
- ./lib/invalid_trie_operation.rb
|
35
46
|
- ./lib/rambling-trie.rb
|
36
47
|
- ./lib/trie.rb
|
48
|
+
- ./lib/trie_branches.rb
|
37
49
|
- ./lib/trie_compressor.rb
|
38
50
|
- ./lib/trie_node.rb
|
39
51
|
- LICENSE
|
@@ -58,7 +70,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
58
70
|
version: '0'
|
59
71
|
requirements: []
|
60
72
|
rubyforge_project:
|
61
|
-
rubygems_version: 1.8.
|
73
|
+
rubygems_version: 1.8.15
|
62
74
|
signing_key:
|
63
75
|
specification_version: 3
|
64
76
|
summary: A custom implementation of the trie data structure.
|