rankle 0.0.1 → 0.0.2
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 +4 -4
- data/lib/rankle/ranker.rb +0 -27
- data/lib/rankle/version.rb +1 -1
- data/lib/rankle_index.rb +12 -16
- data/rankle.gemspec +1 -0
- data/test/{performance → benchmark}/rank_benchmark.rb +0 -4
- data/test/multiple_resources_test.rb +0 -3
- data/test/named_ranking_test.rb +0 -3
- data/test/performance/get_position_test.rb +11 -0
- data/test/performance/set_position_test.rb +33 -0
- data/test/simple_usage_test.rb +0 -3
- data/test/support/test_helper.rb +18 -2
- metadata +41 -25
- data/test/spec/ranker_test.rb +0 -115
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 074be4978d90fa4f0456dc867138970a59d0aaf4
|
4
|
+
data.tar.gz: 9c6742f8b6f14098c5c62ee2748d5f46c8241f34
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 431ea786772022a565750d33713834bdb8c4f4828f8dc99f05cc70fb92fd291e5b08b90a0700368d2ff6443e2e62e97236581fc9e39e9bc5a8887b3faadb2427
|
7
|
+
data.tar.gz: 6797af0d99cc9aa1a85be6de905606ca84b864f9546d7cf667225f295a92db5c8adcf97528418aad01f802aa6ed2c5e09d566eff5e3fab646523fc1a39f6c089
|
data/lib/rankle/ranker.rb
CHANGED
@@ -1,36 +1,9 @@
|
|
1
1
|
module Rankle
|
2
2
|
class Ranker
|
3
|
-
MIN_INDEX = -2147483648
|
4
|
-
MAX_INDEX = 2147483647
|
5
|
-
|
6
3
|
attr_accessor :strategy
|
7
4
|
|
8
5
|
def initialize strategy
|
9
6
|
@strategy = strategy
|
10
7
|
end
|
11
|
-
|
12
|
-
def self.insert target_position, existing_elements
|
13
|
-
if existing_elements.count > MAX_INDEX - MIN_INDEX
|
14
|
-
raise IndexError
|
15
|
-
elsif existing_elements.empty?
|
16
|
-
return 0, []
|
17
|
-
elsif target_position <= 0
|
18
|
-
return (MIN_INDEX + existing_elements.first) / 2, existing_elements
|
19
|
-
elsif target_position >= existing_elements.count
|
20
|
-
return (MAX_INDEX + existing_elements.last) / 2, existing_elements
|
21
|
-
elsif existing_elements[target_position] - existing_elements[target_position - 1] > 1
|
22
|
-
return (existing_elements[target_position] + existing_elements[target_position - 1]) / 2, existing_elements
|
23
|
-
else
|
24
|
-
existing_elements = balance existing_elements
|
25
|
-
insert target_position, existing_elements
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def self.balance indices, options = {}
|
30
|
-
min_index = options[:min_index] || MIN_INDEX
|
31
|
-
max_index = options[:max_index] || MAX_INDEX
|
32
|
-
offset = (max_index - min_index) / (indices.count + 1)
|
33
|
-
indices.count.times.map { |index| min_index + (offset * (index + 1)) + index }
|
34
|
-
end
|
35
8
|
end
|
36
9
|
end
|
data/lib/rankle/version.rb
CHANGED
data/lib/rankle_index.rb
CHANGED
@@ -1,4 +1,10 @@
|
|
1
|
+
require 'ranked-model'
|
2
|
+
|
1
3
|
class RankleIndex < ActiveRecord::Base
|
4
|
+
include RankedModel
|
5
|
+
|
6
|
+
ranks :row_order, column: :indexable_position, :with_same => :indexable_name
|
7
|
+
|
2
8
|
belongs_to :indexable, polymorphic: true
|
3
9
|
|
4
10
|
@rankers = {}
|
@@ -26,20 +32,16 @@ class RankleIndex < ActiveRecord::Base
|
|
26
32
|
end
|
27
33
|
position = existing_indices.length - 1 if position > existing_indices.length
|
28
34
|
position = 0 if position < 0
|
29
|
-
index = RankleIndex.where(indexable_name: name.to_s, indexable_id: instance.id, indexable_type: instance.class).
|
30
|
-
|
31
|
-
existing_positions -= [index.indexable_position] unless index.new_record?
|
32
|
-
indexable_position, existing_positions = Rankle::Ranker.insert(position, existing_positions)
|
33
|
-
existing_positions.each_with_index do |position, index|
|
34
|
-
existing_indices[index].update_attribute(:indexable_position, position) unless existing_indices[index].indexable_position = position
|
35
|
-
end
|
36
|
-
index.indexable_position = indexable_position
|
37
|
-
index.save!
|
35
|
+
index = RankleIndex.where(indexable_name: name.to_s, indexable_id: instance.id, indexable_type: instance.class).first_or_create!
|
36
|
+
index.update_attribute(:row_order_position, position)
|
38
37
|
end
|
39
38
|
|
40
39
|
def self.position instance, name
|
41
40
|
indexable_position = where(indexable_name: name.to_s, indexable_id: instance.id, indexable_type: instance.class).first_or_create!.indexable_position
|
42
|
-
where(indexable_name: name.to_s)
|
41
|
+
indexable_scope = where(indexable_name: name.to_s)
|
42
|
+
indexable_scope = indexable_scope.where(indexable_type: instance.class) if name == :default
|
43
|
+
indexable_scope = indexable_scope.where('indexable_position < ?', indexable_position)
|
44
|
+
indexable_scope.count
|
43
45
|
end
|
44
46
|
|
45
47
|
def self.ranked name
|
@@ -47,10 +49,4 @@ class RankleIndex < ActiveRecord::Base
|
|
47
49
|
duck.indexable_type.classify.constantize.find(duck.indexable_id)
|
48
50
|
end
|
49
51
|
end
|
50
|
-
|
51
|
-
def self.swap(first_index, second_index)
|
52
|
-
first_index_position = first_index.indexable_position
|
53
|
-
first_index.update_attribute(:indexable_position, second_index.indexable_position)
|
54
|
-
second_index.update_attribute(:indexable_position, first_index_position)
|
55
|
-
end
|
56
52
|
end
|
data/rankle.gemspec
CHANGED
@@ -19,6 +19,7 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
21
|
spec.add_dependency "activerecord"
|
22
|
+
spec.add_dependency "ranked-model"
|
22
23
|
spec.add_development_dependency "bundler", "~> 1.7"
|
23
24
|
spec.add_development_dependency "rake", "~> 10.0"
|
24
25
|
spec.add_development_dependency "sqlite3"
|
@@ -30,9 +30,5 @@ class BenchmarkRank < Minitest::Benchmark
|
|
30
30
|
n.times { |name| Fruit.create! name: name }
|
31
31
|
end
|
32
32
|
end
|
33
|
-
|
34
|
-
# FIXME: This unfortunate hack reaches into the internals of RankleIndex to reset the test state
|
35
|
-
RankleIndex.instance_variable_set(:@rankers, {})
|
36
|
-
DatabaseCleaner.clean
|
37
33
|
end
|
38
34
|
end
|
@@ -63,8 +63,5 @@ class TestNamedRanking < Minitest::Test
|
|
63
63
|
|
64
64
|
assert_equal 0, apple.position(:produce)
|
65
65
|
assert_equal 1, carrot.position(:produce)
|
66
|
-
|
67
|
-
# FIXME: This unfortunate hack reaches into the internals of RankleIndex to reset the test state
|
68
|
-
RankleIndex.instance_variable_set(:@rankers, {})
|
69
66
|
end
|
70
67
|
end
|
data/test/named_ranking_test.rb
CHANGED
@@ -68,8 +68,5 @@ class TestNamedRanking < Minitest::Test
|
|
68
68
|
|
69
69
|
assert_equal ['apple', 'banana', 'orange'], Fruit.ranked.map(&:name)
|
70
70
|
assert_equal ['orange', 'banana', 'apple'], Fruit.ranked(:reverse).map(&:name)
|
71
|
-
|
72
|
-
# FIXME: This unfortunate hack reaches into the internals of RankleIndex to reset the test state
|
73
|
-
RankleIndex.instance_variable_set(:@rankers, {})
|
74
71
|
end
|
75
72
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require_relative '../support/test_helper'
|
2
|
+
|
3
|
+
class TestSetPosition < Minitest::Test
|
4
|
+
def test_initializing_position_makes_six_queries
|
5
|
+
assert_queries(8) do
|
6
|
+
apple = Fruit.create! name: 'apple'
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_update_position_makes_three_queries
|
11
|
+
apple = Fruit.create! name: 'apple'
|
12
|
+
|
13
|
+
assert_queries(4) do
|
14
|
+
apple.update_attribute :position, 1
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_update_rank_makes_three_queries
|
19
|
+
apple = Fruit.create! name: 'apple'
|
20
|
+
|
21
|
+
assert_queries(4) do
|
22
|
+
apple.rank 1
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_initializing_position_with_a_proc_makes_eight_queries
|
27
|
+
Fruit.send :ranks, ->(a, b) { a.name < b.name }
|
28
|
+
|
29
|
+
assert_queries(10) do
|
30
|
+
Fruit.create! name: 'apple'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/test/simple_usage_test.rb
CHANGED
@@ -33,8 +33,5 @@ class TestSimpleUsage < Minitest::Test
|
|
33
33
|
Fruit.create! name: 'banana'
|
34
34
|
|
35
35
|
assert_equal ['apple', 'banana', 'orange'], Fruit.ranked.map(&:name)
|
36
|
-
|
37
|
-
# FIXME: This unfortunate hack reaches into the internals of RankleIndex to reset the test state
|
38
|
-
RankleIndex.instance_variable_set(:@rankers, {})
|
39
36
|
end
|
40
37
|
end
|
data/test/support/test_helper.rb
CHANGED
@@ -6,8 +6,8 @@ require 'rails/generators'
|
|
6
6
|
require 'rake'
|
7
7
|
|
8
8
|
ActiveRecord::Base.establish_connection(
|
9
|
-
|
10
|
-
|
9
|
+
adapter: 'sqlite3',
|
10
|
+
database: 'rankle.sqlite3'
|
11
11
|
)
|
12
12
|
|
13
13
|
rake = Rake.application
|
@@ -32,4 +32,20 @@ class Minitest::Test
|
|
32
32
|
def setup
|
33
33
|
DatabaseCleaner.clean
|
34
34
|
end
|
35
|
+
|
36
|
+
def teardown
|
37
|
+
# FIXME: This unfortunate hack reaches into the internals of RankleIndex to reset the test state
|
38
|
+
RankleIndex.instance_variable_set(:@rankers, {})
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def assert_queries(num = 1, &block)
|
43
|
+
queries = []
|
44
|
+
callback = lambda { |name, start, finish, id, payload|
|
45
|
+
queries << payload[:sql] if payload[:sql] =~ /^SELECT|UPDATE|INSERT/
|
46
|
+
}
|
47
|
+
|
48
|
+
ActiveSupport::Notifications.subscribed(callback, "sql.active_record", &block)
|
49
|
+
ensure
|
50
|
+
assert_equal num, queries.size, "#{queries.size} instead of #{num} queries were executed.#{queries.size == 0 ? '' : "\nQueries:\n#{queries.join("\n")}"}"
|
35
51
|
end
|
metadata
CHANGED
@@ -1,125 +1,139 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rankle
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Wil
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-06-
|
11
|
+
date: 2015-06-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - '>='
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: ranked-model
|
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
|
+
- - '>='
|
25
39
|
- !ruby/object:Gem::Version
|
26
40
|
version: '0'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: bundler
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
30
44
|
requirements:
|
31
|
-
- -
|
45
|
+
- - ~>
|
32
46
|
- !ruby/object:Gem::Version
|
33
47
|
version: '1.7'
|
34
48
|
type: :development
|
35
49
|
prerelease: false
|
36
50
|
version_requirements: !ruby/object:Gem::Requirement
|
37
51
|
requirements:
|
38
|
-
- -
|
52
|
+
- - ~>
|
39
53
|
- !ruby/object:Gem::Version
|
40
54
|
version: '1.7'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: rake
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
44
58
|
requirements:
|
45
|
-
- -
|
59
|
+
- - ~>
|
46
60
|
- !ruby/object:Gem::Version
|
47
61
|
version: '10.0'
|
48
62
|
type: :development
|
49
63
|
prerelease: false
|
50
64
|
version_requirements: !ruby/object:Gem::Requirement
|
51
65
|
requirements:
|
52
|
-
- -
|
66
|
+
- - ~>
|
53
67
|
- !ruby/object:Gem::Version
|
54
68
|
version: '10.0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: sqlite3
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
58
72
|
requirements:
|
59
|
-
- -
|
73
|
+
- - '>='
|
60
74
|
- !ruby/object:Gem::Version
|
61
75
|
version: '0'
|
62
76
|
type: :development
|
63
77
|
prerelease: false
|
64
78
|
version_requirements: !ruby/object:Gem::Requirement
|
65
79
|
requirements:
|
66
|
-
- -
|
80
|
+
- - '>='
|
67
81
|
- !ruby/object:Gem::Version
|
68
82
|
version: '0'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: rspec-expectations
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
72
86
|
requirements:
|
73
|
-
- -
|
87
|
+
- - '>='
|
74
88
|
- !ruby/object:Gem::Version
|
75
89
|
version: '0'
|
76
90
|
type: :development
|
77
91
|
prerelease: false
|
78
92
|
version_requirements: !ruby/object:Gem::Requirement
|
79
93
|
requirements:
|
80
|
-
- -
|
94
|
+
- - '>='
|
81
95
|
- !ruby/object:Gem::Version
|
82
96
|
version: '0'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: database_cleaner
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
86
100
|
requirements:
|
87
|
-
- -
|
101
|
+
- - '>='
|
88
102
|
- !ruby/object:Gem::Version
|
89
103
|
version: '0'
|
90
104
|
type: :development
|
91
105
|
prerelease: false
|
92
106
|
version_requirements: !ruby/object:Gem::Requirement
|
93
107
|
requirements:
|
94
|
-
- -
|
108
|
+
- - '>='
|
95
109
|
- !ruby/object:Gem::Version
|
96
110
|
version: '0'
|
97
111
|
- !ruby/object:Gem::Dependency
|
98
112
|
name: factory_girl_rails
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
100
114
|
requirements:
|
101
|
-
- -
|
115
|
+
- - '>='
|
102
116
|
- !ruby/object:Gem::Version
|
103
117
|
version: '0'
|
104
118
|
type: :development
|
105
119
|
prerelease: false
|
106
120
|
version_requirements: !ruby/object:Gem::Requirement
|
107
121
|
requirements:
|
108
|
-
- -
|
122
|
+
- - '>='
|
109
123
|
- !ruby/object:Gem::Version
|
110
124
|
version: '0'
|
111
125
|
- !ruby/object:Gem::Dependency
|
112
126
|
name: yard
|
113
127
|
requirement: !ruby/object:Gem::Requirement
|
114
128
|
requirements:
|
115
|
-
- -
|
129
|
+
- - '>='
|
116
130
|
- !ruby/object:Gem::Version
|
117
131
|
version: '0'
|
118
132
|
type: :development
|
119
133
|
prerelease: false
|
120
134
|
version_requirements: !ruby/object:Gem::Requirement
|
121
135
|
requirements:
|
122
|
-
- -
|
136
|
+
- - '>='
|
123
137
|
- !ruby/object:Gem::Version
|
124
138
|
version: '0'
|
125
139
|
description: Rankle provides multi-resource ranking.
|
@@ -129,7 +143,7 @@ executables: []
|
|
129
143
|
extensions: []
|
130
144
|
extra_rdoc_files: []
|
131
145
|
files:
|
132
|
-
-
|
146
|
+
- .gitignore
|
133
147
|
- Gemfile
|
134
148
|
- LICENSE
|
135
149
|
- LICENSE.txt
|
@@ -142,13 +156,14 @@ files:
|
|
142
156
|
- lib/rankle/version.rb
|
143
157
|
- lib/rankle_index.rb
|
144
158
|
- rankle.gemspec
|
159
|
+
- test/benchmark/rank_benchmark.rb
|
145
160
|
- test/default_behavior_test.rb
|
146
161
|
- test/multiple_resources_test.rb
|
147
162
|
- test/named_ranking_test.rb
|
148
|
-
- test/performance/
|
163
|
+
- test/performance/get_position_test.rb
|
164
|
+
- test/performance/set_position_test.rb
|
149
165
|
- test/scoped_ranking_test.rb
|
150
166
|
- test/simple_usage_test.rb
|
151
|
-
- test/spec/ranker_test.rb
|
152
167
|
- test/spec/rankle_index_test.rb
|
153
168
|
- test/support/models.rb
|
154
169
|
- test/support/schema.rb
|
@@ -163,12 +178,12 @@ require_paths:
|
|
163
178
|
- lib
|
164
179
|
required_ruby_version: !ruby/object:Gem::Requirement
|
165
180
|
requirements:
|
166
|
-
- -
|
181
|
+
- - '>='
|
167
182
|
- !ruby/object:Gem::Version
|
168
183
|
version: '0'
|
169
184
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
170
185
|
requirements:
|
171
|
-
- -
|
186
|
+
- - '>='
|
172
187
|
- !ruby/object:Gem::Version
|
173
188
|
version: '0'
|
174
189
|
requirements: []
|
@@ -178,13 +193,14 @@ signing_key:
|
|
178
193
|
specification_version: 4
|
179
194
|
summary: Rankle provides multi-resource ranking.
|
180
195
|
test_files:
|
196
|
+
- test/benchmark/rank_benchmark.rb
|
181
197
|
- test/default_behavior_test.rb
|
182
198
|
- test/multiple_resources_test.rb
|
183
199
|
- test/named_ranking_test.rb
|
184
|
-
- test/performance/
|
200
|
+
- test/performance/get_position_test.rb
|
201
|
+
- test/performance/set_position_test.rb
|
185
202
|
- test/scoped_ranking_test.rb
|
186
203
|
- test/simple_usage_test.rb
|
187
|
-
- test/spec/ranker_test.rb
|
188
204
|
- test/spec/rankle_index_test.rb
|
189
205
|
- test/support/models.rb
|
190
206
|
- test/support/schema.rb
|
data/test/spec/ranker_test.rb
DELETED
@@ -1,115 +0,0 @@
|
|
1
|
-
require_relative '../support/test_helper'
|
2
|
-
|
3
|
-
describe Rankle::Ranker do
|
4
|
-
describe '.insert into' do
|
5
|
-
describe 'empty array' do
|
6
|
-
describe 'at position 0' do
|
7
|
-
it{ assert_equal [0, []], Rankle::Ranker.insert(0, []) }
|
8
|
-
end
|
9
|
-
|
10
|
-
describe 'at position -100' do
|
11
|
-
it{ assert_equal [0, []], Rankle::Ranker.insert(-100, []) }
|
12
|
-
end
|
13
|
-
|
14
|
-
describe 'at position 100' do
|
15
|
-
it{ assert_equal [0, []], Rankle::Ranker.insert(100, []) }
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
describe 'singleton array' do
|
20
|
-
describe 'at position 0' do
|
21
|
-
it{ assert_equal [-1073741824, [0]], Rankle::Ranker.insert(0, [0]) }
|
22
|
-
end
|
23
|
-
|
24
|
-
describe 'at position 1' do
|
25
|
-
it{ assert_equal [1073741823, [0]], Rankle::Ranker.insert(1, [0]) }
|
26
|
-
end
|
27
|
-
|
28
|
-
describe 'at position -100' do
|
29
|
-
it{ assert_equal [-1073741824, [0]], Rankle::Ranker.insert(-100, [0]) }
|
30
|
-
end
|
31
|
-
|
32
|
-
describe 'at position 100' do
|
33
|
-
it{ assert_equal [1073741823, [0]], Rankle::Ranker.insert(100, [0]) }
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
describe 'between non-adjacent elements' do
|
38
|
-
it{ assert_equal [0, [-1, 1]], Rankle::Ranker.insert(1, [-1, 1]) }
|
39
|
-
it{ assert_equal [0, [-1, 2]], Rankle::Ranker.insert(1, [-1, 2]) }
|
40
|
-
end
|
41
|
-
|
42
|
-
describe 'saturated' do
|
43
|
-
before do
|
44
|
-
@min_index = Rankle::Ranker::MIN_INDEX
|
45
|
-
@max_index = Rankle::Ranker::MAX_INDEX
|
46
|
-
Rankle::Ranker.send :remove_const, :MIN_INDEX
|
47
|
-
Rankle::Ranker.send :remove_const, :MAX_INDEX
|
48
|
-
Rankle::Ranker::MIN_INDEX = -2
|
49
|
-
Rankle::Ranker::MAX_INDEX = 2
|
50
|
-
end
|
51
|
-
|
52
|
-
it{ assert_raises(IndexError) { Rankle::Ranker.insert(0, [-2, -1, 0, 1, 2]) } }
|
53
|
-
|
54
|
-
after do
|
55
|
-
Rankle::Ranker.send :remove_const, :MIN_INDEX
|
56
|
-
Rankle::Ranker.send :remove_const, :MAX_INDEX
|
57
|
-
Rankle::Ranker::MIN_INDEX = @min_index
|
58
|
-
Rankle::Ranker::MAX_INDEX = @max_index
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
describe 'collision' do
|
63
|
-
it{ assert_equal [0, [-715827883, 715827883]], Rankle::Ranker.insert(1, [-1, 0]) }
|
64
|
-
it{ assert_equal [0, [-715827883, 715827883]], Rankle::Ranker.insert(1, [ 0, 1]) }
|
65
|
-
end
|
66
|
-
|
67
|
-
describe 'cascading collision' do
|
68
|
-
it{ assert_equal [-858993459, [-1288490189, -429496729, 429496731, 1288490191]], Rankle::Ranker.insert(1, [-2, -1, 0, 1]) }
|
69
|
-
it{ assert_equal [-858993459, [-1288490189, -429496729, 429496731, 1288490191]], Rankle::Ranker.insert(1, [-1, 0, 1, 2]) }
|
70
|
-
end
|
71
|
-
|
72
|
-
describe 'half-saturated' do
|
73
|
-
before do
|
74
|
-
@min_index = Rankle::Ranker::MIN_INDEX
|
75
|
-
@max_index = Rankle::Ranker::MAX_INDEX
|
76
|
-
Rankle::Ranker.send :remove_const, :MIN_INDEX
|
77
|
-
Rankle::Ranker.send :remove_const, :MAX_INDEX
|
78
|
-
Rankle::Ranker::MIN_INDEX = -2
|
79
|
-
Rankle::Ranker::MAX_INDEX = 2
|
80
|
-
end
|
81
|
-
|
82
|
-
it{ assert_equal [-1, [-2, 0, 2]], Rankle::Ranker.insert(1, [-2, 0, 2]) }
|
83
|
-
it{ assert_equal [1, [-2, 0, 2]], Rankle::Ranker.insert(2, [-2, 0, 2]) }
|
84
|
-
|
85
|
-
after do
|
86
|
-
Rankle::Ranker.send :remove_const, :MIN_INDEX
|
87
|
-
Rankle::Ranker.send :remove_const, :MAX_INDEX
|
88
|
-
Rankle::Ranker::MIN_INDEX = @min_index
|
89
|
-
Rankle::Ranker::MAX_INDEX = @max_index
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
describe '.balance' do
|
95
|
-
describe 'with default range' do
|
96
|
-
before do
|
97
|
-
@indices = {
|
98
|
-
[-1073741824] => [-1],
|
99
|
-
[1073741823] => [-1],
|
100
|
-
[-1, 1] => [-715827883, 715827883]
|
101
|
-
}
|
102
|
-
end
|
103
|
-
|
104
|
-
it do
|
105
|
-
@indices.each do |indices, expected|
|
106
|
-
assert_equal expected, Rankle::Ranker.balance(indices)
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
describe 'with custom range' do
|
112
|
-
it{ assert_equal [3, 7], Rankle::Ranker.balance([0, 1], min_index: 0, max_index: 10) }
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|