rambling-trie 0.3.0 → 0.3.2
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/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.
|