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.
@@ -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
+ ...