splay_tree 0.3.0 → 0.4.0
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/LICENSE.txt +1 -1
- data/README.md +54 -38
- data/lib/splay_tree.rb +9 -4
- data/lib/splay_tree/node.rb +8 -8
- data/lib/splay_tree/version.rb +1 -1
- metadata +20 -41
- data/Rakefile +0 -6
- data/benchmarks/speed.rb +0 -41
- data/spec/spec_helper.rb +0 -45
- data/spec/unit/default_spec.rb +0 -28
- data/spec/unit/delete_spec.rb +0 -43
- data/spec/unit/each_spec.rb +0 -55
- data/spec/unit/fetch_spec.rb +0 -56
- data/spec/unit/insert_spec.rb +0 -79
- data/spec/unit/new_spec.rb +0 -49
- data/spec/unit/to_hash_spec.rb +0 -12
- data/splay_tree.gemspec +0 -25
- data/tasks/console.rake +0 -10
- data/tasks/coverage.rake +0 -11
- data/tasks/spec.rake +0 -29
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ed0680c1501171f807509e9967af1a0f1cc34d5126ec8d72e2cdbc72da87df7f
|
4
|
+
data.tar.gz: 15fb0c87e206c6c0898ce1af4b45bd30ef94433b749ce5a118cee01ef4a85e4a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c1ca27ad3a3864f4b980deb35040e0a303ce85a5c0e66c9e320bb0fb7f6ca7d2378a05fe16f34ccb9bc1a2b58cf5ab71a0a678b4aa7c0e03becbb7ec72db7a84
|
7
|
+
data.tar.gz: c4d3122df89f96c7fb288b78b08373ec81f275af98910ca5216936cab09387ba49a04e5f7f00d51871fc1551f3cc23f8d056a69ed34530e347373fea021e94e8
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# Change log
|
2
2
|
|
3
|
+
## [v0.4.0] - 2021-03-29
|
4
|
+
|
5
|
+
### Changed
|
6
|
+
* Change gemspec to remove test and rake files to reduce gem size
|
7
|
+
* Change to remove bundler as a dev dependency and relax rspec upper constraint
|
8
|
+
|
3
9
|
## [v0.3.0] - 2019-02-26
|
4
10
|
|
5
11
|
* Change to limit to Ruby >= 2.0.0
|
@@ -16,6 +22,7 @@
|
|
16
22
|
|
17
23
|
* Initial implementation and release
|
18
24
|
|
25
|
+
[v0.4.0]: https://github.com/piotrmurach/splay_tree/compare/v0.3.0...v0.4.0
|
19
26
|
[v0.3.0]: https://github.com/piotrmurach/splay_tree/compare/v0.2.0...v0.3.0
|
20
27
|
[v0.2.0]: https://github.com/piotrmurach/splay_tree/compare/v0.1.0...v0.2.0
|
21
28
|
[v0.1.0]: https://github.com/piotrmurach/splay_tree/compare/v0.1.0
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -1,24 +1,24 @@
|
|
1
1
|
# SplayTree
|
2
2
|
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/splay_tree.svg)][gem]
|
4
|
-
[![
|
4
|
+
[![Actions CI](https://github.com/piotrmurach/splay_tree/workflows/CI/badge.svg?branch=master)][gh_actions_ci]
|
5
5
|
[![Build status](https://ci.appveyor.com/api/projects/status/smfi5r38ihtn9gom?svg=true)][appveyor]
|
6
6
|
[![Maintainability](https://api.codeclimate.com/v1/badges/32d2351f6c349a58d8da/maintainability)][codeclimate]
|
7
7
|
[![Coverage Status](https://coveralls.io/repos/github/piotrmurach/splay_tree/badge.svg?branch=master)][coverage]
|
8
8
|
[![Inline docs](http://inch-ci.org/github/piotrmurach/splay_tree.svg)][inchpages]
|
9
9
|
|
10
10
|
[gem]: http://badge.fury.io/rb/splay_tree
|
11
|
-
[
|
11
|
+
[gh_actions_ci]: https://github.com/piotrmurach/splay_tree/actions?query=workflow%3ACI
|
12
12
|
[appveyor]: https://ci.appveyor.com/project/piotrmurach/splay-tree
|
13
13
|
[codeclimate]: https://codeclimate.com/github/piotrmurach/splay_tree/maintainability
|
14
14
|
[coverage]: https://coveralls.io/github/piotrmurach/splay_tree
|
15
15
|
[inchpages]: http://inch-ci.org/github/piotrmurach/splay_tree
|
16
16
|
|
17
|
-
>
|
17
|
+
> A self-balancing binary tree optimised for fast access to frequently used nodes. Useful for implementing caches and garbage collection algorithms.
|
18
18
|
|
19
19
|
## Features
|
20
20
|
|
21
|
-
* Familiar
|
21
|
+
* Familiar `Hash` like access
|
22
22
|
* Easy instantiation with default value
|
23
23
|
|
24
24
|
## Installation
|
@@ -26,7 +26,7 @@
|
|
26
26
|
Add this line to your application's Gemfile:
|
27
27
|
|
28
28
|
```ruby
|
29
|
-
gem
|
29
|
+
gem "splay_tree"
|
30
30
|
```
|
31
31
|
|
32
32
|
And then execute:
|
@@ -55,103 +55,115 @@ Or install it yourself as:
|
|
55
55
|
tree = SplayTree.new
|
56
56
|
tree[:foo] = :bar
|
57
57
|
|
58
|
-
tree[:foo]
|
59
|
-
tree.size
|
58
|
+
tree[:foo] # => :bar
|
59
|
+
tree.size # => 1
|
60
60
|
```
|
61
61
|
|
62
62
|
### 1.1 insert
|
63
63
|
|
64
|
-
|
64
|
+
To assign a value to a given key do the following:
|
65
65
|
|
66
66
|
```ruby
|
67
67
|
tree = SplayTree.new
|
68
|
-
tree[
|
69
|
-
tree[
|
68
|
+
tree[:foo] = 1
|
69
|
+
tree[:bar] = 2
|
70
70
|
```
|
71
71
|
|
72
|
-
Note:
|
72
|
+
Note: The inserted key will be subjected to splaying, which means the tree will be rearranged to help with quicker access on subsequent calls.
|
73
73
|
|
74
74
|
### 1.2 fetch
|
75
75
|
|
76
|
-
To retrieve a value
|
76
|
+
To retrieve a value at a given key do:
|
77
77
|
|
78
78
|
```ruby
|
79
79
|
tree = SplayTree.new
|
80
|
-
tree[
|
80
|
+
tree[:foo] # => nil
|
81
81
|
|
82
|
-
tree[
|
83
|
-
tree[
|
82
|
+
tree[:foo] = 1
|
83
|
+
tree[:foo] # => 1
|
84
84
|
```
|
85
85
|
|
86
86
|
Note: Frequently accessed keys will move nearer to the root where they can be accessed more quickly.
|
87
87
|
|
88
88
|
### 1.3 default
|
89
89
|
|
90
|
-
|
90
|
+
You can set a default value for a missing key. This can be done during initialization:
|
91
91
|
|
92
92
|
```ruby
|
93
93
|
tree = SplayTree.new
|
94
|
-
tree.default
|
94
|
+
tree.default # => UndefinedValue
|
95
95
|
|
96
|
-
tree = SplayTree.new(
|
97
|
-
tree.default
|
98
|
-
tree[
|
96
|
+
tree = SplayTree.new(1)
|
97
|
+
tree.default # => 1
|
98
|
+
tree[:foo] # => 1
|
99
99
|
```
|
100
100
|
|
101
|
-
|
101
|
+
Or using `default` method:
|
102
102
|
|
103
103
|
```ruby
|
104
104
|
tree = SplayTree.new
|
105
|
-
tree.
|
105
|
+
tree.default = 1
|
106
106
|
|
107
|
-
tree
|
108
|
-
|
109
|
-
|
107
|
+
tree[:foo] # => 1
|
108
|
+
```
|
109
|
+
|
110
|
+
You can also use a block to set the default value:
|
111
|
+
|
112
|
+
```ruby
|
113
|
+
tree = SplayTree.new
|
114
|
+
tree.default_proc # => nil
|
115
|
+
|
116
|
+
tree = SplayTree.new { 1 }
|
117
|
+
tree.default_proc # => #<Proc...>
|
118
|
+
tree[:foo] # => 1
|
110
119
|
```
|
111
120
|
|
112
121
|
### 1.4 delete
|
113
122
|
|
114
|
-
In order to remove an entry from
|
123
|
+
In order to remove an entry from a splay tree use `delete` method. If a key is not found, the default value is returned, otherwise `nil`.
|
115
124
|
|
116
125
|
```ruby
|
117
126
|
tree = SplayTree.new
|
118
|
-
tree[
|
119
|
-
tree.delete(
|
120
|
-
tree.delete(
|
127
|
+
tree[:foo] = 1
|
128
|
+
tree.delete(:foo) # => 1
|
129
|
+
tree.delete(:bar) # => nil
|
121
130
|
```
|
122
131
|
|
123
132
|
### 1.5 empty?
|
124
133
|
|
125
|
-
|
134
|
+
Use `empty?` to check if a tree contains any elements:
|
126
135
|
|
127
136
|
```ruby
|
128
137
|
tree = SplayTree.new
|
129
|
-
tree.empty?
|
138
|
+
tree.empty? # => true
|
130
139
|
|
131
|
-
tree[
|
132
|
-
tree.empty?
|
140
|
+
tree[:foo] = 1
|
141
|
+
tree.empty? # => false
|
133
142
|
```
|
134
143
|
|
135
144
|
### 1.6 each
|
136
145
|
|
137
|
-
|
146
|
+
Use `each` method to iterate over all tree nodes like so:
|
138
147
|
|
139
148
|
```ruby
|
140
149
|
tree = SplayTree.new
|
141
|
-
tree[
|
142
|
-
tree[
|
150
|
+
tree[:foo] = 1
|
151
|
+
tree[:bar] = 2
|
143
152
|
|
144
153
|
tree.each { |key, value| puts "#{key}: #{value}" }
|
154
|
+
# =>
|
155
|
+
# bar: 2
|
156
|
+
# foo: 1
|
145
157
|
```
|
146
158
|
|
147
|
-
|
159
|
+
You can also use `each_key` and `each_value` to enumerate only keys or values:
|
148
160
|
|
149
161
|
```ruby
|
150
162
|
tree.each_key { |key| ... }
|
151
163
|
tree.each_value { |value| ... }
|
152
164
|
```
|
153
165
|
|
154
|
-
If no block is
|
166
|
+
If no block is given, an enumerator is returned instead.
|
155
167
|
|
156
168
|
## Contributing
|
157
169
|
|
@@ -161,6 +173,10 @@ If no block is provided, an enumerator is returned instead.
|
|
161
173
|
4. Push to the branch (`git push origin my-new-feature`)
|
162
174
|
5. Create a new Pull Request
|
163
175
|
|
176
|
+
## Code of Conduct
|
177
|
+
|
178
|
+
Everyone interacting in the SplayTree project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/piotrmurach/splay_tree/blob/master/CODE_OF_CONDUCT.md).
|
179
|
+
|
164
180
|
## Copyright
|
165
181
|
|
166
182
|
Copyright (c) 2014 Piotr Murach. See LICENSE for further details.
|
data/lib/splay_tree.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative
|
4
|
-
require_relative
|
3
|
+
require_relative "splay_tree/node"
|
4
|
+
require_relative "splay_tree/version"
|
5
5
|
|
6
6
|
class SplayTree
|
7
7
|
include Enumerable
|
@@ -195,8 +195,10 @@ class SplayTree
|
|
195
195
|
# @api public
|
196
196
|
def delete(key)
|
197
197
|
return if empty?
|
198
|
+
|
198
199
|
splay(key)
|
199
200
|
return if @root.key != key
|
201
|
+
|
200
202
|
deleted = @root
|
201
203
|
right = @root.right
|
202
204
|
@root = @root.left
|
@@ -226,7 +228,7 @@ class SplayTree
|
|
226
228
|
#
|
227
229
|
# @api public
|
228
230
|
def dump
|
229
|
-
@root.dump ||
|
231
|
+
@root.dump || ""
|
230
232
|
end
|
231
233
|
|
232
234
|
# Export tree as hash
|
@@ -235,7 +237,7 @@ class SplayTree
|
|
235
237
|
#
|
236
238
|
# @api public
|
237
239
|
def to_hash
|
238
|
-
|
240
|
+
each_with_object({}) { |(k, v), acc| acc[k] = v }
|
239
241
|
end
|
240
242
|
|
241
243
|
private
|
@@ -261,8 +263,10 @@ class SplayTree
|
|
261
263
|
@subtree.left = @subtree.right = Node::EMPTY
|
262
264
|
loop do
|
263
265
|
break if key == current.key
|
266
|
+
|
264
267
|
if key < current.key
|
265
268
|
break if current.left.empty?
|
269
|
+
|
266
270
|
if key < current.left.key
|
267
271
|
current = current.rotate_right
|
268
272
|
break if current.left.empty?
|
@@ -272,6 +276,7 @@ class SplayTree
|
|
272
276
|
current = current.left
|
273
277
|
elsif key > current.key
|
274
278
|
break if current.right.empty?
|
279
|
+
|
275
280
|
if key > current.right.key
|
276
281
|
current = current.rotate_left
|
277
282
|
break if current.right.empty?
|
data/lib/splay_tree/node.rb
CHANGED
@@ -55,15 +55,15 @@ class SplayTree
|
|
55
55
|
# Iterate over subtree nodes
|
56
56
|
#
|
57
57
|
# @api private
|
58
|
-
def each_key
|
59
|
-
each { |k,
|
58
|
+
def each_key
|
59
|
+
each { |k, _| yield k }
|
60
60
|
end
|
61
61
|
|
62
62
|
# Iterate over subtree nodes
|
63
63
|
#
|
64
64
|
# @api private
|
65
|
-
def each_value
|
66
|
-
each { |
|
65
|
+
def each_value
|
66
|
+
each { |_, v| yield v }
|
67
67
|
end
|
68
68
|
|
69
69
|
# Dump the subtree structure starting from this node
|
@@ -75,9 +75,9 @@ class SplayTree
|
|
75
75
|
left = @left.dump
|
76
76
|
right = @right.dump
|
77
77
|
if !@left.empty? || !@right.empty?
|
78
|
-
|
78
|
+
"(" + [@key, left || "-", right || "-"].compact.join(" ") + ")"
|
79
79
|
else
|
80
|
-
@key ||
|
80
|
+
@key || ""
|
81
81
|
end
|
82
82
|
end
|
83
83
|
|
@@ -128,12 +128,12 @@ class SplayTree
|
|
128
128
|
@right = @right.insert(key, value)
|
129
129
|
rotate_left
|
130
130
|
else
|
131
|
-
|
131
|
+
raise TypeError, "Cannot compare: #{key} with #{@key}"
|
132
132
|
end
|
133
133
|
end
|
134
134
|
|
135
135
|
class EmptyNode < Node
|
136
|
-
def initialize
|
136
|
+
def initialize(*)
|
137
137
|
end
|
138
138
|
|
139
139
|
def empty?
|
data/lib/splay_tree/version.rb
CHANGED
metadata
CHANGED
@@ -1,29 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: splay_tree
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Murach
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-03-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: bundler
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ">="
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '1.5'
|
20
|
-
type: :development
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '1.5'
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: rake
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -42,49 +28,42 @@ dependencies:
|
|
42
28
|
name: rspec
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
44
30
|
requirements:
|
45
|
-
- - "
|
31
|
+
- - ">="
|
46
32
|
- !ruby/object:Gem::Version
|
47
33
|
version: '3.0'
|
48
34
|
type: :development
|
49
35
|
prerelease: false
|
50
36
|
version_requirements: !ruby/object:Gem::Requirement
|
51
37
|
requirements:
|
52
|
-
- - "
|
38
|
+
- - ">="
|
53
39
|
- !ruby/object:Gem::Version
|
54
40
|
version: '3.0'
|
55
|
-
description:
|
56
|
-
|
57
|
-
algorithms.
|
41
|
+
description: A self-balancing binary tree optimised for fast access to frequently
|
42
|
+
used nodes. Useful for implementing caches and garbage collection algorithms.
|
58
43
|
email:
|
59
|
-
-
|
44
|
+
- piotr@piotrmurach.com
|
60
45
|
executables: []
|
61
46
|
extensions: []
|
62
|
-
extra_rdoc_files:
|
47
|
+
extra_rdoc_files:
|
48
|
+
- README.md
|
49
|
+
- CHANGELOG.md
|
50
|
+
- LICENSE.txt
|
63
51
|
files:
|
64
52
|
- CHANGELOG.md
|
65
53
|
- LICENSE.txt
|
66
54
|
- README.md
|
67
|
-
- Rakefile
|
68
|
-
- benchmarks/speed.rb
|
69
55
|
- lib/splay_tree.rb
|
70
56
|
- lib/splay_tree/node.rb
|
71
57
|
- lib/splay_tree/version.rb
|
72
|
-
- spec/spec_helper.rb
|
73
|
-
- spec/unit/default_spec.rb
|
74
|
-
- spec/unit/delete_spec.rb
|
75
|
-
- spec/unit/each_spec.rb
|
76
|
-
- spec/unit/fetch_spec.rb
|
77
|
-
- spec/unit/insert_spec.rb
|
78
|
-
- spec/unit/new_spec.rb
|
79
|
-
- spec/unit/to_hash_spec.rb
|
80
|
-
- splay_tree.gemspec
|
81
|
-
- tasks/console.rake
|
82
|
-
- tasks/coverage.rake
|
83
|
-
- tasks/spec.rake
|
84
58
|
homepage: https://github.com/piotrmurach/splay_tree
|
85
59
|
licenses:
|
86
60
|
- MIT
|
87
|
-
metadata:
|
61
|
+
metadata:
|
62
|
+
bug_tracker_uri: https://github.com/piotrmurach/splay_tree/issues
|
63
|
+
changelog_uri: https://github.com/piotrmurach/splay_tree/blob/master/CHANGELOG.md
|
64
|
+
documentation_uri: https://www.rubydoc.info/gems/splay_tree
|
65
|
+
homepage_uri: https://github.com/piotrmurach/splay_tree
|
66
|
+
source_code_uri: https://github.com/piotrmurach/splay_tree
|
88
67
|
post_install_message:
|
89
68
|
rdoc_options: []
|
90
69
|
require_paths:
|
@@ -100,9 +79,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
100
79
|
- !ruby/object:Gem::Version
|
101
80
|
version: '0'
|
102
81
|
requirements: []
|
103
|
-
|
104
|
-
rubygems_version: 2.7.3
|
82
|
+
rubygems_version: 3.1.2
|
105
83
|
signing_key:
|
106
84
|
specification_version: 4
|
107
|
-
summary: A self-balancing binary tree
|
85
|
+
summary: A self-balancing binary tree optimised for fast access to frequently used
|
86
|
+
nodes.
|
108
87
|
test_files: []
|
data/Rakefile
DELETED
data/benchmarks/speed.rb
DELETED
@@ -1,41 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'benchmark/ips'
|
4
|
-
require 'securerandom'
|
5
|
-
|
6
|
-
require_relative '../lib/splay_tree'
|
7
|
-
|
8
|
-
def generate_key(size)
|
9
|
-
SecureRandom.hex(size)
|
10
|
-
end
|
11
|
-
|
12
|
-
def insert_key(tree)
|
13
|
-
key = generate_key(10)
|
14
|
-
tree[key] = 1
|
15
|
-
key
|
16
|
-
end
|
17
|
-
|
18
|
-
def run(bench, object)
|
19
|
-
name = object.class.name
|
20
|
-
|
21
|
-
key = nil
|
22
|
-
|
23
|
-
bench.report("#{name} insert") do
|
24
|
-
key = insert_key(object)
|
25
|
-
end
|
26
|
-
|
27
|
-
bench.report("#{name} find") do
|
28
|
-
object[key]
|
29
|
-
end
|
30
|
-
|
31
|
-
bench.report("#{name} delete") do
|
32
|
-
object.delete(key)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
Benchmark.ips do |bench|
|
37
|
-
bench.config(time: 5, warmpu: 2)
|
38
|
-
|
39
|
-
run(bench, SplayTree.new)
|
40
|
-
run(bench, Hash.new)
|
41
|
-
end
|
data/spec/spec_helper.rb
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
if ENV['COVERAGE'] || ENV['TRAVIS']
|
4
|
-
require 'simplecov'
|
5
|
-
require 'coveralls'
|
6
|
-
|
7
|
-
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
|
8
|
-
SimpleCov::Formatter::HTMLFormatter,
|
9
|
-
Coveralls::SimpleCov::Formatter
|
10
|
-
]
|
11
|
-
|
12
|
-
SimpleCov.start do
|
13
|
-
command_name 'spec'
|
14
|
-
add_filter 'spec'
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
require 'splay_tree'
|
19
|
-
|
20
|
-
RSpec.configure do |config|
|
21
|
-
config.expect_with :rspec do |expectations|
|
22
|
-
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
23
|
-
end
|
24
|
-
|
25
|
-
config.mock_with :rspec do |mocks|
|
26
|
-
mocks.verify_partial_doubles = true
|
27
|
-
end
|
28
|
-
|
29
|
-
# Limits the available syntax to the non-monkey patched syntax that is recommended.
|
30
|
-
config.disable_monkey_patching!
|
31
|
-
|
32
|
-
# This setting enables warnings. It's recommended, but in some cases may
|
33
|
-
# be too noisy due to issues in dependencies.
|
34
|
-
config.warnings = true
|
35
|
-
|
36
|
-
if config.files_to_run.one?
|
37
|
-
config.default_formatter = 'doc'
|
38
|
-
end
|
39
|
-
|
40
|
-
config.profile_examples = 2
|
41
|
-
|
42
|
-
config.order = :random
|
43
|
-
|
44
|
-
Kernel.srand config.seed
|
45
|
-
end
|
data/spec/unit/default_spec.rb
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
RSpec.describe SplayTree, '.default' do
|
6
|
-
it "sets the default value on initialize" do
|
7
|
-
tree = SplayTree.new('foo')
|
8
|
-
expect(tree.default).to eq('foo')
|
9
|
-
expect(tree['a']).to eq('foo')
|
10
|
-
expect(tree.default_proc).to eq(nil)
|
11
|
-
end
|
12
|
-
|
13
|
-
it "sets the default value on assigment" do
|
14
|
-
tree = SplayTree.new
|
15
|
-
tree.default = 'foo'
|
16
|
-
expect(tree.default).to eq('foo')
|
17
|
-
expect(tree['a']).to eq('foo')
|
18
|
-
expect(tree.default_proc).to eq(nil)
|
19
|
-
end
|
20
|
-
|
21
|
-
it "sets the default_proc to be executed on each key lookup" do
|
22
|
-
block = -> { 'foo' }
|
23
|
-
tree = SplayTree.new(&block)
|
24
|
-
expect(tree.default).to eq(SplayTree::UndefinedValue)
|
25
|
-
expect(tree.default_proc).to eq(block)
|
26
|
-
expect(tree['a']).to eq('foo')
|
27
|
-
end
|
28
|
-
end
|
data/spec/unit/delete_spec.rb
DELETED
@@ -1,43 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
RSpec.describe SplayTree, 'delete' do
|
6
|
-
it "removes element from the tree" do
|
7
|
-
tree = SplayTree.new
|
8
|
-
tree['a'] = 1
|
9
|
-
tree['ab'] = 2
|
10
|
-
tree['abc'] = 3
|
11
|
-
tree['abd'] = 4
|
12
|
-
tree['ac'] = 5
|
13
|
-
tree['b'] = 6
|
14
|
-
|
15
|
-
expect(tree.size).to eq(6)
|
16
|
-
expect(tree.dump).to eq('(b (ac (abd (abc (ab a -) -) -) -) -)')
|
17
|
-
expect(tree.delete('xxx')).to eq(nil)
|
18
|
-
|
19
|
-
expect(tree.delete('abd')).to eq(4)
|
20
|
-
expect(tree.dump).to eq('(abc (ab a -) (ac - b))')
|
21
|
-
expect(tree.size).to eq(5)
|
22
|
-
|
23
|
-
expect(tree.delete('ab')).to eq(2)
|
24
|
-
expect(tree.dump).to eq('(a - (abc - (ac - b)))')
|
25
|
-
expect(tree.size).to eq(4)
|
26
|
-
|
27
|
-
expect(tree.delete('a')).to eq(1)
|
28
|
-
expect(tree.dump).to eq('(abc - (ac - b))')
|
29
|
-
expect(tree.size).to eq(3)
|
30
|
-
|
31
|
-
expect(tree.delete('abc')).to eq(3)
|
32
|
-
expect(tree.dump).to eq('(ac - b)')
|
33
|
-
expect(tree.size).to eq(2)
|
34
|
-
|
35
|
-
expect(tree.delete('ac')).to eq(5)
|
36
|
-
expect(tree.dump).to eq('b')
|
37
|
-
expect(tree.size).to eq(1)
|
38
|
-
|
39
|
-
expect(tree.delete('b')).to eq(6)
|
40
|
-
expect(tree.dump).to eq('')
|
41
|
-
expect(tree.size).to eq(0)
|
42
|
-
end
|
43
|
-
end
|
data/spec/unit/each_spec.rb
DELETED
@@ -1,55 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
RSpec.describe SplayTree, '.each' do
|
6
|
-
subject(:tree) { described_class.new }
|
7
|
-
|
8
|
-
before {
|
9
|
-
tree['a'] = 1
|
10
|
-
tree['b'] = 2
|
11
|
-
tree['c'] = 3
|
12
|
-
}
|
13
|
-
|
14
|
-
it "enumartes all pairs" do
|
15
|
-
yielded = []
|
16
|
-
expect {
|
17
|
-
tree.each { |k, v| yielded << [k, v] }
|
18
|
-
}.to change { yielded }.from([]).to([['a', 1], ['b', 2], ['c', 3]])
|
19
|
-
expect(tree.to_a).to eq(yielded)
|
20
|
-
end
|
21
|
-
|
22
|
-
it "returns enumerator for all pairs without block" do
|
23
|
-
expect(tree.each.to_a).to eq([['a', 1], ['b', 2], ['c', 3]])
|
24
|
-
end
|
25
|
-
|
26
|
-
it "enumerates all keys" do
|
27
|
-
yielded = []
|
28
|
-
expect {
|
29
|
-
tree.each_key { |k| yielded << k }
|
30
|
-
}.to change { yielded }.from([]).to(['a', 'b', 'c'])
|
31
|
-
end
|
32
|
-
|
33
|
-
it "returns enumerator for all keys without block" do
|
34
|
-
expect(tree.each_key.to_a).to eq(['a', 'b', 'c'])
|
35
|
-
end
|
36
|
-
|
37
|
-
it "enumerates all values" do
|
38
|
-
yielded = []
|
39
|
-
expect {
|
40
|
-
tree.each_value { |v| yielded << v }
|
41
|
-
}.to change { yielded }.from([]).to([1, 2, 3])
|
42
|
-
end
|
43
|
-
|
44
|
-
it "returns enumerator for all values without block" do
|
45
|
-
expect(tree.each_value.to_a).to eq([1, 2, 3])
|
46
|
-
end
|
47
|
-
|
48
|
-
it "populates all keys" do
|
49
|
-
expect(tree.keys).to eq(['a', 'b', 'c'])
|
50
|
-
end
|
51
|
-
|
52
|
-
it "populates all values" do
|
53
|
-
expect(tree.values).to eq([1, 2, 3])
|
54
|
-
end
|
55
|
-
end
|
data/spec/unit/fetch_spec.rb
DELETED
@@ -1,56 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
RSpec.describe SplayTree, 'fetch' do
|
6
|
-
it "removes element from the tree" do
|
7
|
-
tree = SplayTree.new
|
8
|
-
tree['aa'] = 1
|
9
|
-
tree['ab'] = 2
|
10
|
-
tree['bb'] = 3
|
11
|
-
tree['bc'] = 4
|
12
|
-
tree['a'] = 5
|
13
|
-
tree['abc'] = 6
|
14
|
-
|
15
|
-
expect(tree.size).to eq(6)
|
16
|
-
expect(tree.dump).to eq('(abc (a - (ab aa -)) (bc bb -))')
|
17
|
-
|
18
|
-
expect(tree.delete('abc')).to eq(6)
|
19
|
-
expect(tree.dump).to eq('(ab (a - aa) (bc bb -))')
|
20
|
-
expect(tree['aa']).to eq(1)
|
21
|
-
expect(tree['ab']).to eq(2)
|
22
|
-
expect(tree['bb']).to eq(3)
|
23
|
-
expect(tree['bc']).to eq(4)
|
24
|
-
expect(tree['a']).to eq(5)
|
25
|
-
expect(tree['abc']).to eq(nil)
|
26
|
-
|
27
|
-
expect(tree.delete('ab')).to eq(2)
|
28
|
-
expect(tree.dump).to eq('(aa a (bb - bc))')
|
29
|
-
expect(tree['aa']).to eq(1)
|
30
|
-
expect(tree['ab']).to eq(nil)
|
31
|
-
expect(tree['bb']).to eq(3)
|
32
|
-
expect(tree['bc']).to eq(4)
|
33
|
-
expect(tree['a']).to eq(5)
|
34
|
-
expect(tree['abc']).to eq(nil)
|
35
|
-
end
|
36
|
-
|
37
|
-
it "checks for key existance" do
|
38
|
-
tree = SplayTree.new
|
39
|
-
tree['a'] = 1
|
40
|
-
expect(tree.key?('a')).to eq(true)
|
41
|
-
end
|
42
|
-
|
43
|
-
it "accepts keys with comparison operator" do
|
44
|
-
tree = SplayTree.new
|
45
|
-
obj = Module.new
|
46
|
-
tree['a'] = 1
|
47
|
-
expect { tree[obj] = 2 }.to raise_error(TypeError)
|
48
|
-
end
|
49
|
-
|
50
|
-
it "bla" do
|
51
|
-
tree = SplayTree.new
|
52
|
-
tree['a'] = 1
|
53
|
-
tree['b'] = 2
|
54
|
-
expect(tree['x']).to eq(nil)
|
55
|
-
end
|
56
|
-
end
|
data/spec/unit/insert_spec.rb
DELETED
@@ -1,79 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
RSpec.describe SplayTree, 'insert' do
|
6
|
-
it "overrides existing value" do
|
7
|
-
tree = described_class.new
|
8
|
-
tree['a'] = 1
|
9
|
-
tree['a'] = 2
|
10
|
-
expect(tree.size).to eq(1)
|
11
|
-
expect(tree['a']).to eq(2)
|
12
|
-
end
|
13
|
-
|
14
|
-
it "balances out the leaves" do
|
15
|
-
tree = described_class.new
|
16
|
-
tree['a'] = 1
|
17
|
-
tree['b'] = 2
|
18
|
-
tree['c'] = 3
|
19
|
-
tree['d'] = 4
|
20
|
-
tree['e'] = 5
|
21
|
-
expect(tree.dump).to eq('(e (d (c (b a -) -) -) -)')
|
22
|
-
expect(tree['c']).to eq(3)
|
23
|
-
expect(tree.dump).to eq('(c (b a -) (d - e))')
|
24
|
-
end
|
25
|
-
|
26
|
-
it "inserts items to the left" do
|
27
|
-
tree = described_class.new
|
28
|
-
tree['c'] = 1
|
29
|
-
tree['b'] = 2
|
30
|
-
# zig right
|
31
|
-
expect(tree.dump).to eq('(b - c)')
|
32
|
-
tree['a'] = 3
|
33
|
-
# zig right
|
34
|
-
expect(tree.dump).to eq('(a - (b - c))')
|
35
|
-
end
|
36
|
-
|
37
|
-
it "inserts items to the right" do
|
38
|
-
tree = described_class.new
|
39
|
-
tree['a'] = 1
|
40
|
-
expect(tree.dump).to eq('a')
|
41
|
-
tree['b'] = 2
|
42
|
-
# zig left
|
43
|
-
expect(tree.dump).to eq('(b a -)')
|
44
|
-
tree['c'] = 3
|
45
|
-
# zig left
|
46
|
-
expect(tree.dump).to eq('(c (b a -) -)')
|
47
|
-
end
|
48
|
-
|
49
|
-
it "inserts to the left and the right" do
|
50
|
-
tree = described_class.new
|
51
|
-
expect(tree.dump).to eq('')
|
52
|
-
tree['g'] = 1
|
53
|
-
tree['a'] = 2
|
54
|
-
# zig right
|
55
|
-
expect(tree.dump).to eq('(a - g)')
|
56
|
-
tree['w'] = 3
|
57
|
-
expect(tree.dump).to eq('(w (a - g) -)')
|
58
|
-
# zig-zag right
|
59
|
-
tree['d'] = 4
|
60
|
-
expect(tree.dump).to eq('(d a (w g -))')
|
61
|
-
end
|
62
|
-
|
63
|
-
it "builds the tree correctly" do
|
64
|
-
tree = described_class.new
|
65
|
-
tree['b'] = 1
|
66
|
-
tree['a'] = 2
|
67
|
-
expect(tree.dump).to eq("(a - b)")
|
68
|
-
tree['e'] = 3
|
69
|
-
expect(tree.dump).to eq("(e (a - b) -)")
|
70
|
-
tree['f'] = 4
|
71
|
-
expect(tree.dump).to eq("(f (e (a - b) -) -)")
|
72
|
-
tree['g'] = 5
|
73
|
-
expect(tree.dump).to eq("(g (f (e (a - b) -) -) -)")
|
74
|
-
tree['i'] = 6
|
75
|
-
expect(tree.dump).to eq("(i (g (f (e (a - b) -) -) -) -)")
|
76
|
-
tree['d'] = 7
|
77
|
-
expect(tree.dump).to eq("(d (a - b) (i (g (f e -) -) -))")
|
78
|
-
end
|
79
|
-
end
|
data/spec/unit/new_spec.rb
DELETED
@@ -1,49 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
RSpec.describe SplayTree, 'new' do
|
6
|
-
it "creates tree" do
|
7
|
-
tree = described_class.new
|
8
|
-
|
9
|
-
expect(tree.empty?).to be(true)
|
10
|
-
expect(tree.size).to eq(0)
|
11
|
-
expect(tree['a']).to eq(nil)
|
12
|
-
|
13
|
-
tree['a'] = 1
|
14
|
-
expect(tree.empty?).to be(false)
|
15
|
-
expect(tree.size).to eq(1)
|
16
|
-
expect(tree['a']).to eq(1)
|
17
|
-
expect(tree.dump).to eq('a')
|
18
|
-
|
19
|
-
tree['b'] = 2
|
20
|
-
expect(tree.size).to eq(2)
|
21
|
-
expect(tree.dump).to eq('(b a -)')
|
22
|
-
|
23
|
-
tree['c'] = 3
|
24
|
-
expect(tree.size).to eq(3)
|
25
|
-
expect(tree.dump).to eq('(c (b a -) -)')
|
26
|
-
|
27
|
-
tree['d'] = 4
|
28
|
-
expect(tree.size).to eq(4)
|
29
|
-
expect(tree.dump).to eq('(d (c (b a -) -) -)')
|
30
|
-
end
|
31
|
-
|
32
|
-
it "raises error when defualt and block given" do
|
33
|
-
expect {
|
34
|
-
SplayTree.new(0) { :unknown }
|
35
|
-
}.to raise_error(ArgumentError)
|
36
|
-
end
|
37
|
-
|
38
|
-
it "defaults to value" do
|
39
|
-
tree = SplayTree.new(0)
|
40
|
-
expect(tree['a']).to eq(0)
|
41
|
-
expect(tree['b']).to eq(0)
|
42
|
-
end
|
43
|
-
|
44
|
-
it "default to block" do
|
45
|
-
tree = SplayTree.new { ['a'] }
|
46
|
-
expect(tree[1]).to eq(['a'])
|
47
|
-
expect(tree[2]).to eq(['a'])
|
48
|
-
end
|
49
|
-
end
|
data/spec/unit/to_hash_spec.rb
DELETED
@@ -1,12 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
RSpec.describe SplayTree, '.to_hash' do
|
6
|
-
it "exports tree as hash" do
|
7
|
-
tree = SplayTree.new
|
8
|
-
hash = {'a' => 1, 'ab' => 2, 'abc' => 3, 'abd' => 4, 'ac' => 5, 'b' => 6}
|
9
|
-
hash.each { |k, v| tree[k] = v }
|
10
|
-
expect(tree.to_hash).to eq(hash)
|
11
|
-
end
|
12
|
-
end
|
data/splay_tree.gemspec
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
lib = File.expand_path('../lib', __FILE__)
|
2
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
-
require 'splay_tree/version'
|
4
|
-
|
5
|
-
Gem::Specification.new do |spec|
|
6
|
-
spec.name = "splay_tree"
|
7
|
-
spec.version = SplayTree::VERSION
|
8
|
-
spec.authors = ["Piotr Murach"]
|
9
|
-
spec.email = ["me@piotrmurach.com"]
|
10
|
-
spec.summary = %q{A self-balancing binary tree with amortized access.}
|
11
|
-
spec.description = %q{Self balancing binary tree that keeps lookup operations fast by optimizing frequently accessed keys. Useful for implementing caches and garbage collection algorithms.}
|
12
|
-
spec.homepage = "https://github.com/piotrmurach/splay_tree"
|
13
|
-
spec.license = "MIT"
|
14
|
-
|
15
|
-
spec.files = Dir['{lib,spec,benchmarks}/**/*.rb']
|
16
|
-
spec.files += Dir['tasks/*', 'splay_tree.gemspec']
|
17
|
-
spec.files += Dir['README.md', 'CHANGELOG.md', 'LICENSE.txt', 'Rakefile']
|
18
|
-
spec.require_paths = ["lib"]
|
19
|
-
|
20
|
-
spec.required_ruby_version = '>= 2.0.0'
|
21
|
-
|
22
|
-
spec.add_development_dependency "bundler", ">= 1.5"
|
23
|
-
spec.add_development_dependency "rake"
|
24
|
-
spec.add_development_dependency "rspec", "~> 3.0"
|
25
|
-
end
|
data/tasks/console.rake
DELETED
data/tasks/coverage.rake
DELETED
data/tasks/spec.rake
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
begin
|
4
|
-
require 'rspec/core/rake_task'
|
5
|
-
|
6
|
-
desc 'Run all specs'
|
7
|
-
RSpec::Core::RakeTask.new(:spec) do |task|
|
8
|
-
task.pattern = 'spec/{unit,integration}{,/*/**}/*_spec.rb'
|
9
|
-
end
|
10
|
-
|
11
|
-
namespace :spec do
|
12
|
-
desc 'Run unit specs'
|
13
|
-
RSpec::Core::RakeTask.new(:unit) do |task|
|
14
|
-
task.pattern = 'spec/unit{,/*/**}/*_spec.rb'
|
15
|
-
end
|
16
|
-
|
17
|
-
desc 'Run integration specs'
|
18
|
-
RSpec::Core::RakeTask.new(:integration) do |task|
|
19
|
-
task.pattern = 'spec/integration{,/*/**}/*_spec.rb'
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
rescue LoadError
|
24
|
-
%w[spec spec:unit spec:integration].each do |name|
|
25
|
-
task name do
|
26
|
-
$stderr.puts "In order to run #{name}, do `gem install rspec`"
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|