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 +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +14 -9
- data/dskiplist.gemspec +2 -0
- data/lib/dskiplist/version.rb +1 -1
- data/lib/dskiplist.rb +12 -10
- data/skiplist-test.rb +3 -3
- data/test/skiplist_spec.rb +20 -1
- data/test/time_spec.rb +0 -0
- metadata +33 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cb6861be71eb077b906f12316726cb693ae766f1
|
4
|
+
data.tar.gz: 5ec1bb7f07a7936d02fa7d3635899c018f599fa3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
100
|
+
#or in a range
|
101
101
|
>> from = 1
|
102
|
-
>>
|
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,
|
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
|
116
|
-
>> list.count(from,
|
117
|
-
=>
|
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"
|
data/lib/dskiplist/version.rb
CHANGED
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
|
-
|
148
|
+
each(from, to, nil, level, nil)
|
148
149
|
end
|
149
150
|
|
150
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
221
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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]}}
|
data/test/skiplist_spec.rb
CHANGED
@@ -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.
|
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
|
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
|