hashtree 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -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 10 non-indexed queries"
104
+ puts "Doing 20 non-indexed queries"
76
105
  x.report do
77
- 10.times do |i|
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 100 non-indexed queries"
112
+ puts "Doing 20 non-indexed queries with 4 threads"
84
113
  x.report do
85
- 100.times do |i|
86
- query = proc{ |key,doc| doc[:email] == "john.doe.#{rand(100000)}@example.com" }
87
- @htree.select{ |key, doc| query.call(key,doc) }
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
@@ -1,3 +1,3 @@
1
1
  class HashTree
2
- VERSION = "0.0.6"
2
+ VERSION = "0.0.7"
3
3
  end
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
- @index = {}
16
+ @root = {}
17
17
  @branches = {}
18
18
  @free = {}
19
19
  @lock = Mutex.new
20
- @cv = ConditionVariable.new
20
+ @rootcv = ConditionVariable.new
21
+ @branchcv = ConditionVariable.new
22
+ @freecv = ConditionVariable.new
21
23
  end
22
24
 
23
25
  def [](key)
24
- id = @index[key]
25
- if id
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 = @index[key]
34
- if id
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 = @index[key]
36
+ id = @root[key]
43
37
  if id
44
38
  doc = read(id)
45
39
  destroy(id)
46
- @index.delete(key)
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
- @index = {}
48
+ @root = {}
55
49
  @branches = {}
56
50
  end
57
51
 
58
52
  def count
59
- @index.count
53
+ @root.count
60
54
  end
61
55
 
62
56
  def has_key?(key)
63
- @index.has_key?(key)
57
+ @root.has_key?(key)
64
58
  end
65
59
 
66
60
  def select(&block)
67
61
  results = {}
68
- @index.select do |key, id|
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
- @index.each do |key, id|
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 = @index[key]
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
- branch_id, leaf_id = translate_id(id)
134
- begin
135
- @branches[branch_id][leaf_id] = value
136
- rescue
137
- nil
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
- branch_id, leaf_id = translate_id(id)
143
- value = @branches[branch_id].delete(leaf_id)
144
- if @branches[branch_id].size == 0
145
- @branches.delete(branch_id)
146
- @free.delete(branch_id)
147
- elsif branch.size > 0 and branch.size < @settings[:max_branch_size]
148
- @free[branch_id] = nil
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.6
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
- requirement: !ruby/object:Gem::Requirement
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
- requirement: !ruby/object:Gem::Requirement
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
- requirement: !ruby/object:Gem::Requirement
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
+ ...