hashtree 0.0.6 → 0.0.7
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/examples/benchmarks.rb +49 -6
- data/lib/hashtree/version.rb +1 -1
- data/lib/hashtree.rb +53 -53
- metadata +24 -23
data/examples/benchmarks.rb
CHANGED
@@ -40,6 +40,21 @@ Benchmark.bm do |x|
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
+
puts "Creating a HashTree with 100.000 documents with 4 Threads"
|
44
|
+
x.report do
|
45
|
+
@htree = HashTree.new
|
46
|
+
t = []
|
47
|
+
4.times do
|
48
|
+
t << Thread.new do
|
49
|
+
25_000.times do |i|
|
50
|
+
key, doc = gen_doc(i)
|
51
|
+
@htree[key] = doc
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
t.each(&:join)
|
56
|
+
end
|
57
|
+
|
43
58
|
puts "Reading 1.000 random documents"
|
44
59
|
x.report do
|
45
60
|
1_000.times do |i|
|
@@ -64,6 +79,20 @@ Benchmark.bm do |x|
|
|
64
79
|
end
|
65
80
|
end
|
66
81
|
|
82
|
+
puts "Reading 100.000 random documents with 4 Threads"
|
83
|
+
x.report do
|
84
|
+
t = []
|
85
|
+
4.times do
|
86
|
+
t << Thread.new do
|
87
|
+
25_000.times do |i|
|
88
|
+
key = "jdoe#{rand(100_000)}"
|
89
|
+
@htree[key]
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
t.each(&:join)
|
94
|
+
end
|
95
|
+
|
67
96
|
puts "Doing 1 non-indexed query"
|
68
97
|
x.report do
|
69
98
|
1.times do |i|
|
@@ -72,22 +101,36 @@ Benchmark.bm do |x|
|
|
72
101
|
end
|
73
102
|
end
|
74
103
|
|
75
|
-
puts "Doing
|
104
|
+
puts "Doing 20 non-indexed queries"
|
76
105
|
x.report do
|
77
|
-
|
106
|
+
20.times do |i|
|
78
107
|
query = proc{ |key,doc| doc[:email] == "john.doe.#{rand(100000)}@example.com" }
|
79
108
|
@htree.select{ |key, doc| query.call(key,doc) }
|
80
109
|
end
|
81
110
|
end
|
82
111
|
|
83
|
-
puts "Doing
|
112
|
+
puts "Doing 20 non-indexed queries with 4 threads"
|
84
113
|
x.report do
|
85
|
-
|
86
|
-
|
87
|
-
|
114
|
+
t = []
|
115
|
+
4.times do
|
116
|
+
t << Thread.new do
|
117
|
+
5.times do |i|
|
118
|
+
query = proc{ |key,doc| doc[:email] == "john.doe.#{rand(100000)}@example.com" }
|
119
|
+
@htree.select{ |key, doc| query.call(key,doc) }
|
120
|
+
end
|
121
|
+
end
|
88
122
|
end
|
123
|
+
t.each(&:join)
|
89
124
|
end
|
90
125
|
|
126
|
+
# puts "Doing 100 non-indexed queries"
|
127
|
+
# x.report do
|
128
|
+
# 100.times do |i|
|
129
|
+
# query = proc{ |key,doc| doc[:email] == "john.doe.#{rand(100000)}@example.com" }
|
130
|
+
# @htree.select{ |key, doc| query.call(key,doc) }
|
131
|
+
# end
|
132
|
+
# end
|
133
|
+
|
91
134
|
puts "Deleting 1.000 random documents"
|
92
135
|
x.report do
|
93
136
|
lhtree = @htree.clone
|
data/lib/hashtree/version.rb
CHANGED
data/lib/hashtree.rb
CHANGED
@@ -13,37 +13,31 @@ class HashTree
|
|
13
13
|
@settings = {
|
14
14
|
max_branch_size: 16
|
15
15
|
}.merge(settings)
|
16
|
-
@
|
16
|
+
@root = {}
|
17
17
|
@branches = {}
|
18
18
|
@free = {}
|
19
19
|
@lock = Mutex.new
|
20
|
-
@
|
20
|
+
@rootcv = ConditionVariable.new
|
21
|
+
@branchcv = ConditionVariable.new
|
22
|
+
@freecv = ConditionVariable.new
|
21
23
|
end
|
22
24
|
|
23
25
|
def [](key)
|
24
|
-
id = @
|
25
|
-
|
26
|
-
read(id)
|
27
|
-
else
|
28
|
-
nil
|
29
|
-
end
|
26
|
+
id = @root[key]
|
27
|
+
id ? read(id) : nil
|
30
28
|
end
|
31
29
|
|
32
30
|
def []=(key, value)
|
33
|
-
id = @
|
34
|
-
|
35
|
-
update(id, value)
|
36
|
-
else
|
37
|
-
create(key, value)
|
38
|
-
end
|
31
|
+
id = @root[key]
|
32
|
+
id ? update(id, value) : create(key, value)
|
39
33
|
end
|
40
34
|
|
41
35
|
def delete(key)
|
42
|
-
id = @
|
36
|
+
id = @root[key]
|
43
37
|
if id
|
44
38
|
doc = read(id)
|
45
39
|
destroy(id)
|
46
|
-
@
|
40
|
+
@root.delete(key)
|
47
41
|
return doc
|
48
42
|
else
|
49
43
|
nil
|
@@ -51,21 +45,21 @@ class HashTree
|
|
51
45
|
end
|
52
46
|
|
53
47
|
def clear
|
54
|
-
@
|
48
|
+
@root = {}
|
55
49
|
@branches = {}
|
56
50
|
end
|
57
51
|
|
58
52
|
def count
|
59
|
-
@
|
53
|
+
@root.count
|
60
54
|
end
|
61
55
|
|
62
56
|
def has_key?(key)
|
63
|
-
@
|
57
|
+
@root.has_key?(key)
|
64
58
|
end
|
65
59
|
|
66
60
|
def select(&block)
|
67
61
|
results = {}
|
68
|
-
@
|
62
|
+
@root.select do |key, id|
|
69
63
|
leaf = read(id)
|
70
64
|
results[key] = leaf if yield(key, leaf)
|
71
65
|
end
|
@@ -74,7 +68,7 @@ class HashTree
|
|
74
68
|
|
75
69
|
def each(&block)
|
76
70
|
results = {}
|
77
|
-
@
|
71
|
+
@root.each do |key, id|
|
78
72
|
leaf = read(id)
|
79
73
|
results[key] = leaf if yield(key, leaf)
|
80
74
|
end
|
@@ -82,7 +76,7 @@ class HashTree
|
|
82
76
|
end
|
83
77
|
|
84
78
|
def branch(key)
|
85
|
-
id = @
|
79
|
+
id = @root[key]
|
86
80
|
if id
|
87
81
|
branch_id = id[0..31]
|
88
82
|
@branches[branch_id]
|
@@ -102,24 +96,6 @@ class HashTree
|
|
102
96
|
Digest::SHA256.hexdigest(SecureRandom.uuid)
|
103
97
|
end
|
104
98
|
|
105
|
-
def create(key, value)
|
106
|
-
free_branch_id = @free.keys.sample
|
107
|
-
if free_branch_id
|
108
|
-
leaf_id = generate_id[0..31]
|
109
|
-
id = free_branch_id + leaf_id
|
110
|
-
@index[key] = id
|
111
|
-
@branches[free_branch_id][leaf_id] = value
|
112
|
-
@free.delete(branch_id) if branch.size >= @settings[:max_branch_size]
|
113
|
-
else
|
114
|
-
id = generate_id
|
115
|
-
branch_id, leaf_id = translate_id(id)
|
116
|
-
@index[key] = id
|
117
|
-
@branches[branch_id] = {}
|
118
|
-
@branches[branch_id][leaf_id] = value
|
119
|
-
end
|
120
|
-
return value
|
121
|
-
end
|
122
|
-
|
123
99
|
def read(id)
|
124
100
|
branch_id, leaf_id = translate_id(id)
|
125
101
|
begin
|
@@ -129,25 +105,49 @@ class HashTree
|
|
129
105
|
end
|
130
106
|
end
|
131
107
|
|
108
|
+
def create(key, value)
|
109
|
+
@lock.synchronize do
|
110
|
+
free_branch_id = @free.keys.sample
|
111
|
+
if free_branch_id
|
112
|
+
leaf_id = generate_id[0..31]
|
113
|
+
id = free_branch_id + leaf_id
|
114
|
+
@root[key] = id
|
115
|
+
@branches[free_branch_id][leaf_id] = value
|
116
|
+
@free.delete(branch_id) if branch.size >= @settings[:max_branch_size]
|
117
|
+
else
|
118
|
+
id = generate_id
|
119
|
+
branch_id, leaf_id = translate_id(id)
|
120
|
+
@root[key] = id
|
121
|
+
@branches[branch_id] = {}
|
122
|
+
@branches[branch_id][leaf_id] = value
|
123
|
+
end
|
124
|
+
return value
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
132
128
|
def update(id, value)
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
129
|
+
@lock.synchronize do
|
130
|
+
branch_id, leaf_id = translate_id(id)
|
131
|
+
begin
|
132
|
+
@branches[branch_id][leaf_id] = value
|
133
|
+
rescue
|
134
|
+
nil
|
135
|
+
end
|
138
136
|
end
|
139
137
|
end
|
140
138
|
|
141
139
|
def destroy(id)
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
@branches.
|
146
|
-
|
147
|
-
|
148
|
-
@
|
140
|
+
@lock.synchronize do
|
141
|
+
branch_id, leaf_id = translate_id(id)
|
142
|
+
value = @branches[branch_id].delete(leaf_id)
|
143
|
+
if @branches[branch_id].size == 0
|
144
|
+
@branches.delete(branch_id)
|
145
|
+
@free.delete(branch_id)
|
146
|
+
elsif branch.size > 0 and branch.size < @settings[:max_branch_size]
|
147
|
+
@free[branch_id] = nil
|
148
|
+
end
|
149
|
+
return value
|
149
150
|
end
|
150
|
-
return value
|
151
151
|
end
|
152
152
|
|
153
153
|
end
|
metadata
CHANGED
@@ -1,64 +1,64 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hashtree
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.0.7
|
5
|
+
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Marcelo Wiermann
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
date: 2012-09-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
|
17
|
-
none: false
|
16
|
+
version_requirements: !ruby/object:Gem::Requirement
|
18
17
|
requirements:
|
19
18
|
- - ! '>='
|
20
19
|
- !ruby/object:Gem::Version
|
21
20
|
version: '0'
|
22
|
-
type: :development
|
23
|
-
prerelease: false
|
24
|
-
version_requirements: !ruby/object:Gem::Requirement
|
25
21
|
none: false
|
22
|
+
requirement: !ruby/object:Gem::Requirement
|
26
23
|
requirements:
|
27
24
|
- - ! '>='
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '0'
|
27
|
+
none: false
|
28
|
+
prerelease: false
|
29
|
+
type: :development
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
31
|
name: guard
|
32
|
-
|
33
|
-
none: false
|
32
|
+
version_requirements: !ruby/object:Gem::Requirement
|
34
33
|
requirements:
|
35
34
|
- - ! '>='
|
36
35
|
- !ruby/object:Gem::Version
|
37
36
|
version: '0'
|
38
|
-
type: :development
|
39
|
-
prerelease: false
|
40
|
-
version_requirements: !ruby/object:Gem::Requirement
|
41
37
|
none: false
|
38
|
+
requirement: !ruby/object:Gem::Requirement
|
42
39
|
requirements:
|
43
40
|
- - ! '>='
|
44
41
|
- !ruby/object:Gem::Version
|
45
42
|
version: '0'
|
43
|
+
none: false
|
44
|
+
prerelease: false
|
45
|
+
type: :development
|
46
46
|
- !ruby/object:Gem::Dependency
|
47
47
|
name: factory_girl
|
48
|
-
|
49
|
-
none: false
|
48
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
49
|
requirements:
|
51
50
|
- - ! '>='
|
52
51
|
- !ruby/object:Gem::Version
|
53
52
|
version: '0'
|
54
|
-
type: :development
|
55
|
-
prerelease: false
|
56
|
-
version_requirements: !ruby/object:Gem::Requirement
|
57
53
|
none: false
|
54
|
+
requirement: !ruby/object:Gem::Requirement
|
58
55
|
requirements:
|
59
56
|
- - ! '>='
|
60
57
|
- !ruby/object:Gem::Version
|
61
58
|
version: '0'
|
59
|
+
none: false
|
60
|
+
prerelease: false
|
61
|
+
type: :development
|
62
62
|
description: HashTree that has a Hash-like interface and stores data into blocks
|
63
63
|
email:
|
64
64
|
- marcelo.wiermann@gmail.com
|
@@ -79,27 +79,28 @@ files:
|
|
79
79
|
- spec/spec_helper.rb
|
80
80
|
homepage: ''
|
81
81
|
licenses: []
|
82
|
-
post_install_message:
|
82
|
+
post_install_message:
|
83
83
|
rdoc_options: []
|
84
84
|
require_paths:
|
85
85
|
- lib
|
86
86
|
required_ruby_version: !ruby/object:Gem::Requirement
|
87
|
-
none: false
|
88
87
|
requirements:
|
89
88
|
- - ! '>='
|
90
89
|
- !ruby/object:Gem::Version
|
91
90
|
version: '0'
|
92
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
91
|
none: false
|
92
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
93
|
requirements:
|
95
94
|
- - ! '>='
|
96
95
|
- !ruby/object:Gem::Version
|
97
96
|
version: '0'
|
97
|
+
none: false
|
98
98
|
requirements: []
|
99
|
-
rubyforge_project:
|
99
|
+
rubyforge_project:
|
100
100
|
rubygems_version: 1.8.24
|
101
|
-
signing_key:
|
101
|
+
signing_key:
|
102
102
|
specification_version: 3
|
103
103
|
summary: HashTree
|
104
104
|
test_files:
|
105
105
|
- spec/spec_helper.rb
|
106
|
+
...
|