splay_tree 0.1.0

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3fb742e0b556b47b38822511385221c6b753f7ff
4
+ data.tar.gz: 3b4815cae5de148ff8ca12b8b780ad3713d2a406
5
+ SHA512:
6
+ metadata.gz: 202309dfa438b35db3e859167679a8bba623ac1f0d50c94ba0d335b05a75421d2978567991646dc637a7fa0bfabdd1b07af3d66d1f9952c7e352635a81c270cd
7
+ data.tar.gz: 88fa044eb915009af13333272c38c868c10fb2d915b25b0396eb61d20be19ca1ac0157d451ccbc6d09820906688ce4aec1cb4e63dff8399ea86a73edca932cdb
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --require spec_helper
3
+ --warnings
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.0.0
data/.travis.yml ADDED
@@ -0,0 +1,21 @@
1
+ language: ruby
2
+ bundler_args: --without yard benchmarks
3
+ script: "bundle exec rake ci"
4
+ rvm:
5
+ - 1.9.3
6
+ - 2.0.0
7
+ - 2.1.0
8
+ - ruby-head
9
+ matrix:
10
+ include:
11
+ - rvm: jruby-19mode
12
+ - rvm: jruby-20mode
13
+ - rvm: jruby-21mode
14
+ - rvm: jruby-head
15
+ - rvm: rbx-2
16
+ allow_failures:
17
+ - rvm: ruby-head
18
+ - rvm: jruby-head
19
+ fast_finish: true
20
+ branches:
21
+ only: master
data/Gemfile ADDED
@@ -0,0 +1,16 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :development do
6
+ gem 'rake', '~> 10.3.2'
7
+ gem 'rspec', '~> 3.1.0'
8
+ gem 'yard', '~> 0.8.7'
9
+ gem 'timecop', '~> 0.7.1'
10
+ end
11
+
12
+ group :metrics do
13
+ gem 'coveralls', '~> 0.7.0'
14
+ gem 'simplecov', '~> 0.8.2'
15
+ gem 'yardstick', '~> 0.9.9'
16
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Piotr Murach
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,92 @@
1
+ # SplayTree
2
+ [![Gem Version](https://badge.fury.io/rb/splay_tree.png)][gem]
3
+ [![Build Status](https://secure.travis-ci.org/peter-murach/splay_tree.png?branch=master)][travis]
4
+ [![Code Climate](https://codeclimate.com/github/peter-murach/splay_tree.png)][codeclimate]
5
+ [![Coverage Status](https://coveralls.io/repos/peter-murach/splay_tree/badge.png)][coverage]
6
+
7
+ [gem]: http://badge.fury.io/rb/splay_tree
8
+ [travis]: http://travis-ci.org/peter-murach/splay_tree
9
+ [codeclimate]: https://codeclimate.com/github/peter-murach/splay_tree
10
+ [coverage]: https://coveralls.io/r/peter-murach/splay_tree
11
+
12
+ > Self balancing binary tree that keeps lookup operations fast by optimizing frequently accessed keys. Useful for implementing caches and garbage collection algorithms.
13
+
14
+ ## Features
15
+
16
+ * Familiar hash like access
17
+ * Easy instantiation with default value
18
+
19
+ ## Installation
20
+
21
+ Add this line to your application's Gemfile:
22
+
23
+ ```ruby
24
+ gem 'splay_tree'
25
+ ```
26
+
27
+ And then execute:
28
+
29
+ $ bundle
30
+
31
+ Or install it yourself as:
32
+
33
+ $ gem install splay_tree
34
+
35
+ ## 1. Usage
36
+
37
+ **SplayTree** operations are similar to that of `Hash`:
38
+
39
+ ```ruby
40
+ tree = SplayTree.new
41
+ tree[:foo] = :bar
42
+
43
+ tree[:foo] # => :bar
44
+ tree.size # => 1
45
+ ```
46
+
47
+ ### 1.1 insert
48
+
49
+ In order to add two elements:
50
+
51
+ ```ruby
52
+ tree['a'] = 1
53
+ tree['b'] = 2
54
+ ```
55
+
56
+ ### 1.2 fetch
57
+
58
+ To read value under key:
59
+
60
+ ```ruby
61
+ tree['a']
62
+ ```
63
+
64
+ ### 1.3 delete
65
+
66
+ ```ruby
67
+ tree.delete('a') # => 1
68
+ ```
69
+
70
+ ### 1.4 empty?
71
+
72
+ To check if `tree` contains any elements call `empty?` like so:
73
+
74
+ ```ruby
75
+ tree = SplayTree.new
76
+ tree.empty? # => true
77
+
78
+ tree['a'] = 1
79
+ tree.empty? # => false
80
+ ```
81
+
82
+ ## Contributing
83
+
84
+ 1. Fork it ( https://github.com/peter-murach/splay_tree/fork )
85
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
86
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
87
+ 4. Push to the branch (`git push origin my-new-feature`)
88
+ 5. Create a new Pull Request
89
+
90
+ ## Copyright
91
+
92
+ Copyright (c) 2014 Piotr Murach. See LICENSE for further details.
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # encoding: utf-8
2
+
3
+ require "bundler/gem_tasks"
4
+
5
+ FileList['tasks/**/*.rake'].each(&method(:import))
6
+
7
+ desc 'Run all specs'
8
+ task ci: %w[ spec ]
@@ -0,0 +1,137 @@
1
+ # coding: utf-8
2
+
3
+ class SplayTree
4
+ # A single tree node representation
5
+ class Node
6
+ include Comparable
7
+
8
+ UndefinedValue = Module.new
9
+
10
+ attr_reader :key
11
+
12
+ attr_reader :value
13
+
14
+ attr_accessor :left
15
+
16
+ attr_accessor :right
17
+
18
+ def initialize(key, value)
19
+ @key, @value = key, value
20
+ @left = @right = Node::EMPTY
21
+ end
22
+
23
+ # @api private
24
+ def empty?
25
+ false
26
+ end
27
+
28
+ # Number of nodes in this subtree
29
+ #
30
+ # @return [Integer]
31
+ #
32
+ # @api private
33
+ def size
34
+ left.size + 1 + right.size
35
+ end
36
+
37
+ # Compare node keys
38
+ #
39
+ # @return [Integer]
40
+ #
41
+ # @api private
42
+ def <=>(other)
43
+ @key <=> other.key
44
+ end
45
+
46
+ # Dump the subtree structure starting from this node
47
+ #
48
+ # @return [String]
49
+ #
50
+ # @api private
51
+ def dump
52
+ left = @left.dump
53
+ right = @right.dump
54
+ if !@left.empty? || !@right.empty?
55
+ '(' + [@key, left || '-', right || '-'].compact.join(' ') + ')'
56
+ else
57
+ @key || ''
58
+ end
59
+ end
60
+
61
+ # Rotate right
62
+ #
63
+ # Y X
64
+ # / \ / \
65
+ # X C => A Y
66
+ # / \ / \
67
+ # A B B C
68
+ #
69
+ # @api private
70
+ def rotate_right
71
+ tmp = @left
72
+ @left = tmp.right
73
+ tmp.right = self
74
+ tmp
75
+ end
76
+
77
+ # Rotate left
78
+ #
79
+ # Y X
80
+ # / \ / \
81
+ # A X => Y C
82
+ # / \ / \
83
+ # B C A B
84
+ #
85
+ # @api private
86
+ def rotate_left
87
+ tmp = @right
88
+ @right = tmp.left
89
+ tmp.left = self
90
+ tmp
91
+ end
92
+
93
+ # Insert new root
94
+ #
95
+ # @api private
96
+ def insert(key, value)
97
+ case key <=> @key
98
+ when -1
99
+ @left = @left.insert(key, value)
100
+ rotate_right
101
+ when 0
102
+ @value = value
103
+ self
104
+ when 1
105
+ @right = @right.insert(key, value)
106
+ rotate_left
107
+ else
108
+ fail TypeError, "Cannot compare: #{key} with #{@key}"
109
+ end
110
+ end
111
+
112
+ class EmptyNode < Node
113
+ def initialize
114
+ end
115
+
116
+ def empty?
117
+ true
118
+ end
119
+
120
+ def size
121
+ 0
122
+ end
123
+
124
+ def to_s
125
+ end
126
+
127
+ def dump
128
+ end
129
+
130
+ def insert(key, value)
131
+ Node.new(key, value)
132
+ end
133
+ end # EmptyNode
134
+
135
+ EMPTY = Node::EmptyNode.new.freeze
136
+ end # Node
137
+ end # SplayTree
@@ -0,0 +1,5 @@
1
+ # coding: utf-8
2
+
3
+ class SplayTree
4
+ VERSION = "0.1.0"
5
+ end # SplayTree
data/lib/splay_tree.rb ADDED
@@ -0,0 +1,179 @@
1
+ # coding: utf-8
2
+
3
+ require 'splay_tree/node'
4
+ require 'splay_tree/version'
5
+
6
+ class SplayTree
7
+ UndefinedValue = Module.new
8
+
9
+ attr_accessor :default
10
+
11
+ def initialize(default = UndefinedValue, &block)
12
+ if !UndefinedValue.equal?(default) && block
13
+ fail ArgumentError,
14
+ 'You need to pas seither argument or a block as a default value'
15
+ end
16
+ @root = Node::EMPTY
17
+ @subtree = Node.new(nil, nil)
18
+ @default = default
19
+ @default_block = block
20
+ end
21
+
22
+ # @api public
23
+ def empty?
24
+ @root == Node::EMPTY
25
+ end
26
+
27
+ # @api public
28
+ def size
29
+ @root.size
30
+ end
31
+ alias_method :length, :size
32
+
33
+ # Insert a node into a tree with the given key and value
34
+ # provided that the tree does not already contain the key.
35
+ # The node becomes the root of the tree.
36
+ #
37
+ # @param [Object] key
38
+ # the key under which the node is inserted
39
+ # @param [Object] value
40
+ # the value of the node inserted into the tree
41
+ #
42
+ # @return [Boolean]
43
+ # false if key already exists, true otherwise
44
+ # @api public
45
+ def []=(key, value)
46
+ if @root.empty?
47
+ @root = Node.new(key, value)
48
+ return true
49
+ end
50
+
51
+ @root = @root.insert(key, value)
52
+
53
+ splay(key)
54
+ end
55
+ alias_method :insert, :[]=
56
+
57
+ # Find object by the key
58
+ #
59
+ # @param [Object] key
60
+ # the search key
61
+ #
62
+ # @api public
63
+ def [](key)
64
+ splay(key) unless @root.empty?
65
+
66
+ return default_value if @root.key != key
67
+
68
+ @root.value
69
+ end
70
+ alias_method :fetch, :[]
71
+
72
+ # Check if tree contains a node with a matching key.
73
+ #
74
+ # @return [Boolean]
75
+ #
76
+ # @api public
77
+ def key?(key)
78
+ return false if @root.empty?
79
+ splay(key)
80
+ @root.key == key
81
+ end
82
+
83
+ # Delete a node specified by the key from the tree
84
+ # given the tree contains a node with this key.
85
+ # The deleted node value is returned. If the node
86
+ # is not found a nil is returned.
87
+ #
88
+ # @param [Object] key
89
+ #
90
+ # @return [Object]
91
+ # the node's value under the key
92
+ #
93
+ # @api public
94
+ def delete(key)
95
+ return if empty?
96
+ splay(key)
97
+ return if @root.key != key
98
+ deleted = @root
99
+ right = @root.right
100
+ @root = @root.left
101
+ if @root.empty?
102
+ @root = right
103
+ else
104
+ splay(key) # ensure empty right child
105
+ @root.right = right
106
+ end
107
+ deleted.value
108
+ end
109
+
110
+ # Construct and return two trees t1 and t2, where
111
+ # t1 contains items in t less than or equal to key,
112
+ # and t2 contains all items in t greater than key.
113
+ #
114
+ # @param [Object] key
115
+ #
116
+ # @api public
117
+ def split(key)
118
+ end
119
+
120
+ # Dump the tree structure in bracket format
121
+ # (root left right)
122
+ #
123
+ # @return [String]
124
+ #
125
+ # @api public
126
+ def dump
127
+ @root.dump || ''
128
+ end
129
+
130
+ private
131
+
132
+ # @api private
133
+ def default_value
134
+ if @default != UndefinedValue
135
+ @default
136
+ elsif @default_block
137
+ @default_block.call
138
+ end
139
+ end
140
+
141
+ # Top-down splaying by breaking down the tree.
142
+ #
143
+ # @param [Object] key
144
+ # the key at which to splay
145
+ #
146
+ # @api private
147
+ def splay(key)
148
+ current = @root
149
+ dummy = left = right = @subtree
150
+ @subtree.left = @subtree.right = Node::EMPTY
151
+ loop do
152
+ break if key == current.key
153
+ if key < current.key
154
+ break if current.left.empty?
155
+ if key < current.left.key
156
+ current = current.rotate_right
157
+ break if current.left.empty?
158
+ end
159
+ right.left = current
160
+ right = current
161
+ current = current.left
162
+ elsif key > current.key
163
+ break if current.right.empty?
164
+ if key > current.right.key
165
+ current = current.rotate_left
166
+ break if current.right.empty?
167
+ end
168
+ left.right = current
169
+ left = current
170
+ current = current.right
171
+ end
172
+ end
173
+ left.right = current.left
174
+ right.left = current.right
175
+ current.left = dummy.right
176
+ current.right = dummy.left
177
+ @root = current
178
+ end
179
+ end # SplayTree
@@ -0,0 +1,45 @@
1
+ # encoding: utf-8
2
+
3
+ if RUBY_VERSION > '1.9' and (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
@@ -0,0 +1,43 @@
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
@@ -0,0 +1,56 @@
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
@@ -0,0 +1,79 @@
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
@@ -0,0 +1,49 @@
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
@@ -0,0 +1,22 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'splay_tree/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "splay_tree"
8
+ spec.version = SplayTree::VERSION
9
+ spec.authors = ["Piotr Murach"]
10
+ spec.email = [""]
11
+ spec.summary = %q{A self-balancing binary tree with amortized access.}
12
+ 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.}
13
+ spec.homepage = "https://github.com/peter-murach/splay_tree"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.5"
22
+ end
@@ -0,0 +1,10 @@
1
+ # encoding: utf-8
2
+
3
+ desc 'Load gem inside irb console'
4
+ task :console do
5
+ require 'irb'
6
+ require 'irb/completion'
7
+ require File.join(__FILE__, '../../lib/splay_tree')
8
+ ARGV.clear
9
+ IRB.start
10
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+
3
+ desc 'Measure code coverage'
4
+ task :coverage do
5
+ begin
6
+ original, ENV['COVERAGE'] = ENV['COVERAGE'], 'true'
7
+ Rake::Task['spec'].invoke
8
+ ensure
9
+ ENV['COVERAGE'] = original
10
+ end
11
+ end
data/tasks/spec.rake ADDED
@@ -0,0 +1,29 @@
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
metadata ADDED
@@ -0,0 +1,86 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: splay_tree
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Piotr Murach
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-12-27 00:00:00.000000000 Z
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
+ description: Self balancing binary tree that keeps lookup operations fast by optimizing
28
+ frequently accessed keys. Useful for implementing caches and garbage collection
29
+ algorithms.
30
+ email:
31
+ - ''
32
+ executables: []
33
+ extensions: []
34
+ extra_rdoc_files: []
35
+ files:
36
+ - .gitignore
37
+ - .rspec
38
+ - .ruby-version
39
+ - .travis.yml
40
+ - Gemfile
41
+ - LICENSE.txt
42
+ - README.md
43
+ - Rakefile
44
+ - lib/splay_tree.rb
45
+ - lib/splay_tree/node.rb
46
+ - lib/splay_tree/version.rb
47
+ - spec/spec_helper.rb
48
+ - spec/unit/delete_spec.rb
49
+ - spec/unit/fetch_spec.rb
50
+ - spec/unit/insert_spec.rb
51
+ - spec/unit/new_spec.rb
52
+ - splay_tree.gemspec
53
+ - tasks/console.rake
54
+ - tasks/coverage.rake
55
+ - tasks/spec.rake
56
+ homepage: https://github.com/peter-murach/splay_tree
57
+ licenses:
58
+ - MIT
59
+ metadata: {}
60
+ post_install_message:
61
+ rdoc_options: []
62
+ require_paths:
63
+ - lib
64
+ required_ruby_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ required_rubygems_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - '>='
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ requirements: []
75
+ rubyforge_project:
76
+ rubygems_version: 2.0.3
77
+ signing_key:
78
+ specification_version: 4
79
+ summary: A self-balancing binary tree with amortized access.
80
+ test_files:
81
+ - spec/spec_helper.rb
82
+ - spec/unit/delete_spec.rb
83
+ - spec/unit/fetch_spec.rb
84
+ - spec/unit/insert_spec.rb
85
+ - spec/unit/new_spec.rb
86
+ has_rdoc: