dskiplist 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d4ae3f9e4947138a5eff42cf7e5ba9d3880efdae
4
- data.tar.gz: 11d5d9ef6b19298fa1a65cf89837ecf0d0197f02
3
+ metadata.gz: cb6861be71eb077b906f12316726cb693ae766f1
4
+ data.tar.gz: 5ec1bb7f07a7936d02fa7d3635899c018f599fa3
5
5
  SHA512:
6
- metadata.gz: 28887ea80ed34d66a994d0cc6f055c399d8a14ba87b63be7885432d24d6a166b67bc6732eb5a7df46981b1d1370849dac15db03879314b9b88141681b0fe9519
7
- data.tar.gz: 4002864d186702f36c99ab3679ef76d09c29aa425918c1bd5d2e971b0ea97a3686bdfbdad21e9cf383b1e77fc3d19fe8a612b04238f96376674d97c66b068c07
6
+ metadata.gz: eeb3eb32bfcca7b5e6b0577958178fdd42e1264de0ec21aecc634102132d2872e4b7a08bb975a683f2995f9723cdc25222725f2dca00b1d3a3f90792a18edc85
7
+ data.tar.gz: aee1b4ccc0bdaf0ca7f356894016599c70af9d40c883b963d075d0390efff88d69b91b7fa258858d7444b15e25daf9973fba01e7ea338baf8a59a1a05a30bb96
data/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ ## DSkipList 1.0.0 (Feb 26, 2014) ##
2
+
3
+ * Changed all range operations so that they do not include the first element specified (from)
4
+
5
+ * Ranges now accept nonexistent start and endpoints and the list will still behave, which is more useful for
6
+ * real world situations in which you dont know exactly what values are in your list
7
+
data/README.md CHANGED
@@ -97,24 +97,28 @@ Ok, so why use this instead of hash? Order
97
97
  >> list.to_a
98
98
  => ["duck", "goose", "quail", "pidgin"]
99
99
 
100
- #or in an inclusive range
100
+ #or in a range
101
101
  >> from = 1
102
- >> to = 3
102
+ >> through = 3
103
103
  #0 is the base layer of the list. It contains all elements. default 0
104
104
  >> layer = 0
105
105
  #limit return size if desired
106
106
  >> limit = nil
107
107
 
108
- >> list.to_a(from, to, limit, layer)
109
- => ["duck", "goose", "quail"]
110
- >> list.to_a(2, nil, 2)
108
+ >> list.to_a(from, through, limit, layer)
111
109
  => ["goose", "quail"]
110
+ #note that "duck" was omitted. The range does not include the first element.
111
+ #You can also use nonexistent node keys like 1.5
112
+
113
+ #with a start point, no endpoint, and a limit:
114
+ >> list.to_a(2, nil, 2)
115
+ => ["quail", "pidgin"]
112
116
  >> list.to_a(nil, 3, nil)
113
117
  => ["duck", "goose", "quail"]
114
118
 
115
- #or count the elements between two elements(plus two to include the endpoints)
116
- >> list.count(from, to)
117
- => 3
119
+ #or count the elements between two values (+1 because endpoint is counted) from 1 to 3
120
+ >> list.count(from, through)
121
+ => 2
118
122
 
119
123
  ```
120
124
 
@@ -131,4 +135,5 @@ Ok, so why use this instead of hash? Order
131
135
 
132
136
  ToDo:
133
137
  - Jruby multithreading and locking with mutexes for multi-core support.
134
- - Lazy operations
138
+ - Lazy operations. For now you can just do them yourself by using find_node to get your start point and calling forward[0] to get the following nodes in O(1) time
139
+ - considering making count O(1) instead of O(log n) by just keeping track of the size
data/dskiplist.gemspec CHANGED
@@ -16,6 +16,8 @@ Gem::Specification.new do |spec|
16
16
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
17
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
18
  spec.require_paths = ["lib"]
19
+ spec.add_runtime_dependency "facter"
20
+ spec.add_runtime_dependency "thread_safe"
19
21
  spec.add_development_dependency "rspec"
20
22
  spec.add_development_dependency "bundler", "~> 1.5"
21
23
  spec.add_development_dependency "rake"
@@ -1,3 +1,3 @@
1
1
  module Dskiplist
2
- VERSION = "1.0.0"
2
+ VERSION = "1.0.1"
3
3
  end
data/lib/dskiplist.rb CHANGED
@@ -36,6 +36,7 @@ class DSkipList
36
36
  @key = k
37
37
  @value = v.nil? ? k : v
38
38
  @forward = []
39
+
39
40
  end
40
41
  end
41
42
 
@@ -62,10 +63,10 @@ class DSkipList
62
63
  x = x.forward[i]
63
64
  end
64
65
  end
65
- x = x.forward[0] if x.forward[0].key == search_key
66
+ x = x.forward[0] if x.forward[0] and x.forward[0].key == search_key
66
67
  return x
67
68
  end
68
-
69
+
69
70
  def [] key
70
71
  node = self.find_node(key)
71
72
  if node and node.key == key
@@ -144,10 +145,11 @@ class DSkipList
144
145
  end
145
146
 
146
147
  def count(from = nil, to = nil, level = 0)
147
- walk(from, to, nil, level, nil)
148
+ each(from, to, nil, level, nil)
148
149
  end
149
150
 
150
- def walk(from, to, limit, level, output)
151
+ #accepts a block which is run on each element
152
+ def each(from=nil, to=nil, limit=nil, level=0, output=nil)
151
153
  if from
152
154
  x = find_node(from)
153
155
  x = x.forward[level] if x.forward[level]
@@ -182,11 +184,11 @@ class DSkipList
182
184
  end
183
185
 
184
186
  def to_h(from = nil, to = nil, limit = nil, level = 0)
185
- walk(from, to, limit, level, {}) {|n, hash| hash[n.key] = n.value}
187
+ each(from, to, limit, level, {}) {|n, hash| hash[n.key] = n.value}
186
188
  end
187
189
 
188
190
  def to_a(from = nil, to = nil, limit = nil, level = 0)
189
- walk(from, to, limit, level, []) {|n, arr| arr.push(n.value)}
191
+ each(from, to, limit, level, []) {|n, arr| arr.push(n.value)}
190
192
  end
191
193
  alias_method :to_ary, :to_a
192
194
 
@@ -216,9 +218,9 @@ class DSkipList
216
218
  return "SkipList level #{@max_level}"
217
219
  end
218
220
 
219
- def each(&block)
220
- self.to_a.each(&block)
221
- end
221
+ #def each(&block)
222
+ # self.walk(nil, nil, nil, 0, nil) @block
223
+ # return self
224
+ #end
222
225
 
223
226
  end
224
-
data/skiplist-test.rb CHANGED
@@ -5,13 +5,13 @@ list = DSkipList.new
5
5
  otherList = SkipList.new 100
6
6
  hash = {}
7
7
  Benchmark.bm(30) do |b|
8
- #b.report('Insert time: ') {1.upto(100000) {|i| list[i] = i}}
8
+ b.report('Insert time: ') {1.upto(10000) {|i| list[i] = i}}
9
9
  #b.report('Other list insert: ') {1.upto(10000) {|i| otherList[i] = i}}
10
- #b.report('Search time: ') {1.upto(10000) {|i| list[i]}}
10
+ b.report('Search time: ') {1.upto(10000) {|i| list[i]}}
11
11
  #b.report('Other list search: ') {1.upto(10000) {|i| otherList[i]}}
12
12
  #b.report('List insert million elements: ') {10000.upto(1010000) {|i| list[i] = i}}
13
13
  #b.report('Hash insert million elements: ') {1.upto(1000000) {|i| hash[i] = i}}
14
- #b.report('List search 10000') {1000000.upto(1010000) {|i| list[i]}}
14
+ b.report('List search 10000') {1.upto(10000) {|i| list[i]}}
15
15
  #b.report('Hash search 10000') {900000.upto(1000000) {|i| hash[i]}}
16
16
  #b.report('List +10000: ') {1040000.upto(1050000) {|i| list[i] = i}}
17
17
  #b.report('Search time: ') {1000000.upto(1010000) {|i| list[i]}}
@@ -1,6 +1,9 @@
1
+ #Be sure to run 'gem install dskiplist --development' before running
2
+ #require 'method_profiler'
1
3
  require 'rspec'
2
4
  require './lib/dskiplist.rb'
3
5
  require 'pry'
6
+
4
7
  #Checks for stray links in the upper levels. There may be a more exhaustive way to check integrity.
5
8
  def check_integrity(list)
6
9
  complete = list.to_a
@@ -22,8 +25,11 @@ describe "The skiplist" do
22
25
  check_integrity(@list)
23
26
  end
24
27
 
28
+ it "sets up the observer", :time => true do
29
+ #@profiler = MethodProfiler.observe(@list)
30
+ end
31
+
25
32
  it "should lookup value correctly" do
26
- puts "30 returned #{@list[30]}"
27
33
  expect(@list[30]).to eq(30)
28
34
  end
29
35
 
@@ -48,6 +54,9 @@ describe "The skiplist" do
48
54
  end
49
55
  end
50
56
 
57
+ it "should return nil if key not found" do
58
+ expect(@list[99999999989].nil?).to eq(true)
59
+ end
51
60
  it "should convert to hash" do
52
61
  expect(@list.to_h.count).to eq(100)
53
62
  expect(@list.to_h(50,75).count).to eq(25)
@@ -68,4 +77,14 @@ describe "The skiplist" do
68
77
  #check sizes of each level to make sure we aren't chopping off the tail when we delete. Seems fine
69
78
  #@list.level.downto(0) {|l| puts "level #{l} contains #{@list.count(nil, nil, l)}"}
70
79
  end
80
+
81
+ it "should accept a block" do
82
+ object_count = 0
83
+ @list.each { object_count +=1 }
84
+ expect(object_count).to eq(100)
85
+ end
86
+
87
+ it "reports the observer", :time => true do
88
+ #puts @profiler.report
89
+ end
71
90
  end
data/test/time_spec.rb ADDED
File without changes
metadata CHANGED
@@ -1,15 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dskiplist
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Forrest Allison
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-26 00:00:00.000000000 Z
11
+ date: 2014-03-02 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: facter
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: thread_safe
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
13
41
  - !ruby/object:Gem::Dependency
14
42
  name: rspec
15
43
  requirement: !ruby/object:Gem::Requirement
@@ -95,6 +123,7 @@ files:
95
123
  - ".git-new/objects/ae/ee3428c017916e5cc0e57d387224f33ed0b990"
96
124
  - ".git-new/objects/d8/7d4be66f458acd52878902bbf1391732ad21e1"
97
125
  - ".gitignore"
126
+ - CHANGELOG.md
98
127
  - Gemfile
99
128
  - LICENSE.txt
100
129
  - README.md
@@ -105,6 +134,7 @@ files:
105
134
  - lib/dskiplist/version.rb
106
135
  - skiplist-test.rb
107
136
  - test/skiplist_spec.rb
137
+ - test/time_spec.rb
108
138
  homepage: https://github.com/light24bulbs/dynamic-skiplist/
109
139
  licenses:
110
140
  - MIT
@@ -131,3 +161,4 @@ specification_version: 4
131
161
  summary: High speed skiplist gem
132
162
  test_files:
133
163
  - test/skiplist_spec.rb
164
+ - test/time_spec.rb