splay_tree 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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: