offline-sort 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 1348bee75eb0ecb72523e5f92abd639f196304e8
4
- data.tar.gz: a5ed1e33b0c7f7190345c56a0ea0dbf42a64e8b7
2
+ SHA256:
3
+ metadata.gz: a86abc81b2d3fc1653d3c662a62d9e4ff3ec4e0b7e50d82af2d048f042ff35f3
4
+ data.tar.gz: 5cfb87439f853f775f87c4c9b07147ed833979553ab1da979b083dc138c0d956
5
5
  SHA512:
6
- metadata.gz: 702b8acf293151bdd863d55510cb7452fd21c60ab67b462edce709dcd45d3a654b1bf0a143f02332c5df7ad4e12e4bea1c95f55809980a2c20e28adf7e0d73a3
7
- data.tar.gz: 3213b91bf5e90bbf53c024bee169784a3aab4c72d1a35507469aa6cf154f95e1b16c0834b822c158e38cc65195a3ec9ad0c5f65c599dd47f69c2a29392d82bbf
6
+ metadata.gz: 6f3454d450a9a1a86ebbe7cb71027257f47713289b4deb72e9fc95f9bae30754a5d08a780a13f50437f5c3f227653102ca6601648533ac7e8888e8e5f7a28b9a
7
+ data.tar.gz: 683585facddc7e7b3019073e50eb4a42bad6f894982a5e392bfca88f55cb1b2ec41bbbb965a230a544bd01dc0fb81cf871e1527f35a24e8f949242814e11ac00
@@ -0,0 +1,84 @@
1
+ version: 2.1
2
+ jobs:
3
+ lint:
4
+ docker:
5
+ - image: salsify/ruby_ci:2.6.6
6
+ working_directory: ~/offline-sort
7
+ steps:
8
+ - checkout
9
+ - restore_cache:
10
+ keys:
11
+ - v1-gems-ruby-2.6.6-{{ checksum "offline-sort.gemspec" }}-{{ checksum "Gemfile" }}
12
+ - v1-gems-ruby-2.6.6-
13
+ - run:
14
+ name: Install Gems
15
+ command: |
16
+ if ! bundle check --path=vendor/bundle; then
17
+ bundle install --path=vendor/bundle --jobs=4 --retry=3
18
+ bundle clean
19
+ fi
20
+ - save_cache:
21
+ key: v1-gems-ruby-2.6.6-{{ checksum "offline-sort.gemspec" }}-{{ checksum "Gemfile" }}
22
+ paths:
23
+ - "vendor/bundle"
24
+ - "gemfiles/vendor/bundle"
25
+ - run:
26
+ name: Run Rubocop
27
+ command: bundle exec rubocop
28
+ test:
29
+ parameters:
30
+ gemfile:
31
+ type: string
32
+ ruby_version:
33
+ type: string
34
+ docker:
35
+ - image: salsify/ruby_ci:<< parameters.ruby_version >>
36
+ environment:
37
+ CIRCLE_TEST_REPORTS: "test-results"
38
+ BUNDLE_GEMFILE: << parameters.gemfile >>
39
+ working_directory: ~/offline-sort
40
+ steps:
41
+ - checkout
42
+ - unless:
43
+ condition:
44
+ equal: ["gemfiles/rails_edge.gemfile", << parameters.gemfile >>]
45
+ steps:
46
+ - restore_cache:
47
+ keys:
48
+ - v1-gems-ruby-<< parameters.ruby_version >>-{{ checksum "offline-sort.gemspec" }}-{{ checksum "<< parameters.gemfile >>" }}
49
+ - v1-gems-ruby-<< parameters.ruby_version >>-
50
+ - run:
51
+ name: Install Gems
52
+ command: |
53
+ if ! bundle check --path=vendor/bundle; then
54
+ bundle install --path=vendor/bundle --jobs=4 --retry=3
55
+ bundle clean
56
+ fi
57
+ - unless:
58
+ condition:
59
+ equal: [ "gemfiles/rails_edge.gemfile", << parameters.gemfile >> ]
60
+ steps:
61
+ - save_cache:
62
+ key: v1-gems-ruby-<< parameters.ruby_version >>-{{ checksum "offline-sort.gemspec" }}-{{ checksum "<< parameters.gemfile >>" }}
63
+ paths:
64
+ - "vendor/bundle"
65
+ - "gemfiles/vendor/bundle"
66
+ - run:
67
+ name: Run Tests
68
+ command: |
69
+ bundle exec rspec --format RspecJunitFormatter --out $CIRCLE_TEST_REPORTS/rspec/junit.xml --format progress spec
70
+ - store_test_results:
71
+ path: "test-results"
72
+ workflows:
73
+ build:
74
+ jobs:
75
+ - lint
76
+ - test:
77
+ matrix:
78
+ parameters:
79
+ gemfile:
80
+ - "Gemfile"
81
+ ruby_version:
82
+ - "2.6.8"
83
+ - "2.7.4"
84
+ - "3.0.2"
data/.gitignore ADDED
@@ -0,0 +1,15 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
12
+
13
+ .idea/
14
+ *.iml
15
+ Gemfile.lock
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,15 @@
1
+ inherit_gem:
2
+ salsify_rubocop: conf/rubocop.yml
3
+
4
+ AllCops:
5
+ TargetRubyVersion: 2.6
6
+ Exclude:
7
+ - 'vendor/**/*'
8
+ - 'gemfiles/**/*'
9
+
10
+ # Offense count: 9
11
+ # Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames.
12
+ # AllowedNames: at, by, db, id, in, io, ip, of, on, os, pp, to
13
+ Naming/MethodParameterName:
14
+ Exclude:
15
+ - 'lib/offline_sort/fixed_size_min_heap.rb'
data/CHANGELOG.md ADDED
@@ -0,0 +1,10 @@
1
+ # Changelog
2
+
3
+ ### 0.2.0
4
+ - Add testing for ruby: 2.6, 2.7 & 3.0
5
+ - Add ruby 3 support
6
+ - Require ruby >= 2.6
7
+ - Add rubocop
8
+
9
+ ### 0.1.1
10
+ - Initial implementation
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  # Specify your gem's dependencies in offline-sort.gemspec
data/Rakefile CHANGED
@@ -1 +1,3 @@
1
- require "bundler/gem_tasks"
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module OfflineSort
2
4
  module Chunk
3
5
  module InputOutput
@@ -12,11 +14,11 @@ module OfflineSort
12
14
  end
13
15
 
14
16
  def read_entry
15
- raise(MethodNotImplementedError, "#{__method__} must be overridden by #{self.class}")
17
+ raise MethodNotImplementedError.new("#{__method__} must be overridden by #{self.class}")
16
18
  end
17
19
 
18
- def write_entry(entry)
19
- raise(MethodNotImplementedError, "#{__method__} must be overridden by #{self.class}")
20
+ def write_entry(_entry)
21
+ raise MethodNotImplementedError.new("#{__method__} must be overridden by #{self.class}")
20
22
  end
21
23
 
22
24
  def write_entries(entries)
@@ -38,12 +40,10 @@ module OfflineSort
38
40
 
39
41
  def each
40
42
  Enumerator.new do |yielder|
41
- while true
42
- begin
43
- yielder.yield(read_entry)
44
- rescue EOFError
45
- break
46
- end
43
+ loop do
44
+ yielder.yield(read_entry)
45
+ rescue EOFError
46
+ break
47
47
  end
48
48
  end
49
49
  end
@@ -52,4 +52,3 @@ module OfflineSort
52
52
  end
53
53
  end
54
54
  end
55
-
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module OfflineSort
2
4
  module Chunk
3
5
  module InputOutput
4
6
  class Marshal < OfflineSort::Chunk::InputOutput::Base
5
7
  def read_entry
6
- ::Marshal.load(io)
8
+ ::Marshal.load(io) # rubocop:disable Security/MarshalLoad, this is loading from a trusted source
7
9
  end
8
10
 
9
11
  def write_entry(entry)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'msgpack'
2
4
  require 'offline_sort/chunk/input_output/base'
3
5
 
@@ -29,4 +31,3 @@ module OfflineSort
29
31
  end
30
32
  end
31
33
  end
32
-
@@ -1,12 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'yaml'
2
4
 
3
5
  module OfflineSort
4
6
  module Chunk
5
7
  module InputOutput
6
8
  class Yaml < OfflineSort::Chunk::InputOutput::Base
7
- #The yaml parser does not expose a document enumerator that we can call next on without loading the entire file
9
+ # The yaml parser does not expose a document enumerator that we can call next on without loading the entire file
8
10
  def read_entry
9
- YAML.load(next_document)
11
+ YAML.load(next_document) # rubocop:disable Security/YAMLLoad, this is loading from a trusted source
10
12
  end
11
13
 
12
14
  def write_entry(entry)
@@ -18,23 +20,21 @@ module OfflineSort
18
20
  def next_document
19
21
  sio = StringIO.new
20
22
  document_count = 0
23
+ line = nil
21
24
 
22
- begin
25
+ loop do
23
26
  line = io.gets
24
27
 
25
- if line && line.start_with?('---')
26
- document_count += 1
27
- end
28
+ document_count += 1 if line && line.start_with?('---')
28
29
 
29
30
  sio.write(line)
30
- end until line.nil? || document_count > 1
31
+ break if line.nil? || document_count > 1
32
+ end
31
33
 
32
34
  # reset the io to the beginning of the document
33
- if document_count > 1
34
- io.seek(io.pos - line.length, IO::SEEK_SET)
35
- end
35
+ io.seek(io.pos - line.length, IO::SEEK_SET) if document_count > 1
36
36
 
37
- raise EOFError unless sio.size > 0
37
+ raise EOFError unless sio.size > 0 # rubocop:disable Style/ZeroLengthPredicate
38
38
 
39
39
  sio.string
40
40
  end
@@ -42,4 +42,3 @@ module OfflineSort
42
42
  end
43
43
  end
44
44
  end
45
-
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'offline_sort/chunk/input_output/base'
2
4
  require 'offline_sort/chunk/input_output/marshal'
3
5
  require 'offline_sort/chunk/input_output/message_pack' if defined?(MessagePack)
@@ -1,9 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module OfflineSort
2
4
  class FixedSizeMinHeap
3
5
  attr_accessor :array
4
- attr_reader :sort_by
5
- attr_reader :size_limit
6
- attr_reader :heap_end
6
+ attr_reader :sort_by, :size_limit, :heap_end
7
7
 
8
8
  def initialize(array, &sort_by)
9
9
  @array = array
@@ -36,16 +36,17 @@ module OfflineSort
36
36
 
37
37
  def grow_heap
38
38
  raise "Heap Size (#{size_limit}) Exceeded" if heap_end == (size_limit - 1)
39
+
39
40
  @heap_end += 1
40
41
  end
41
42
 
42
43
  # Compare elements at the supplied indices
43
- def compare(i,j)
44
+ def compare(i, j)
44
45
  (sort_by.call(array[i]) <=> sort_by.call(array[j])) == -1
45
46
  end
46
47
 
47
48
  # Swap elements in the array
48
- def swap(i,j)
49
+ def swap(i, j)
49
50
  temp = array[i]
50
51
  array[i] = array[j]
51
52
  array[j] = temp
@@ -55,10 +56,12 @@ module OfflineSort
55
56
  def parent(i)
56
57
  (i - 1) / 2
57
58
  end
59
+
58
60
  # Get the node left of node i >= 0
59
61
  def left(i)
60
62
  (2 * i) + 1
61
63
  end
64
+
62
65
  # Get the node right of node i >= 0
63
66
  def right(i)
64
67
  (2 * i) + 2
@@ -67,10 +70,10 @@ module OfflineSort
67
70
  # Keeps an heap sorted with the smallest (largest) element on top
68
71
  def heapify(i)
69
72
  l = left(i)
70
- top = ((l <= heap_end) && compare(l,i)) ? l : i
73
+ top = (l <= heap_end) && compare(l, i) ? l : i
71
74
 
72
75
  r = right(i)
73
- top = ((r <= heap_end) && compare(r,top)) ? r : top
76
+ top = (r <= heap_end) && compare(r, top) ? r : top
74
77
 
75
78
  if top != i
76
79
  swap(i, top)
@@ -79,9 +82,11 @@ module OfflineSort
79
82
  end
80
83
 
81
84
  def sift_up(i)
82
- if i > 0 && p = parent(i)
83
- if compare(i,p)
84
- swap(i,p);
85
+ if i > 0
86
+ p = parent(i)
87
+
88
+ if p && compare(i, p)
89
+ swap(i, p)
85
90
  sift_up(p)
86
91
  end
87
92
  end
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'offline_sort/chunk'
2
4
  require 'offline_sort/fixed_size_min_heap'
3
5
 
4
6
  module OfflineSort
5
- def self.sort(*args, &sort_by)
6
- Sorter.new(*args, &sort_by).sort
7
+ def self.sort(*args, **kwargs, &sort_by)
8
+ Sorter.new(*args, **kwargs, &sort_by).sort
7
9
  end
8
10
 
9
11
  class Sorter
@@ -12,7 +14,10 @@ module OfflineSort
12
14
 
13
15
  attr_reader :enumerable, :sort_by, :chunk_size, :chunk_input_output_class
14
16
 
15
- def initialize(enumerable, chunk_input_output_class: DEFAULT_CHUNK_IO_CLASS, chunk_size: DEFAULT_CHUNK_SIZE, &sort_by)
17
+ def initialize(enumerable,
18
+ chunk_input_output_class: DEFAULT_CHUNK_IO_CLASS,
19
+ chunk_size: DEFAULT_CHUNK_SIZE,
20
+ &sort_by)
16
21
  @enumerable = enumerable
17
22
  @chunk_input_output_class = chunk_input_output_class
18
23
  @chunk_size = chunk_size
@@ -25,7 +30,7 @@ module OfflineSort
25
30
 
26
31
  private
27
32
 
28
- #TODO optimization for when there is less than a single full chunk of data
33
+ # TODO: optimization for when there is less than a single full chunk of data
29
34
  def merge(sorted_chunk_ios)
30
35
  pq = []
31
36
  chunk_enumerators = sorted_chunk_ios.map(&:each)
@@ -39,7 +44,7 @@ module OfflineSort
39
44
  pq = FixedSizeMinHeap.new(pq, &entry_sort_by)
40
45
 
41
46
  Enumerator.new do |yielder|
42
- while item = pq.pop
47
+ while (item = pq.pop)
43
48
  yielder.yield(item.data)
44
49
 
45
50
  begin
@@ -65,9 +70,7 @@ module OfflineSort
65
70
  end
66
71
  end
67
72
 
68
- unless chunk_entries.empty?
69
- sorted_chunks << write_sorted_chunk(chunk_entries)
70
- end
73
+ sorted_chunks << write_sorted_chunk(chunk_entries) unless chunk_entries.empty?
71
74
 
72
75
  sorted_chunks
73
76
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module OfflineSort
2
- VERSION = "0.1.1"
4
+ VERSION = '0.2.0'
3
5
  end
data/lib/offline_sort.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'offline_sort/version'
2
4
  require 'offline_sort/chunk'
3
5
  require 'offline_sort/offline_sort'
data/offline-sort.gemspec CHANGED
@@ -1,25 +1,31 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
3
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
5
  require 'offline_sort/version'
5
6
 
6
7
  Gem::Specification.new do |spec|
7
- spec.name = "offline-sort"
8
+ spec.name = 'offline-sort'
8
9
  spec.version = OfflineSort::VERSION
9
- spec.authors = ["Matthew Cross"]
10
- spec.email = ["mcross@salsify.com"]
11
- spec.description = %q{Offline sort for any enumerable with pluggable serialization strategies}
12
- spec.summary = %q{Offline sort for any enumerable with pluggable serialization strategies}
13
- spec.homepage = "https://github.com/salsify/offline-sort"
14
- spec.license = "MIT"
10
+ spec.authors = ['Matthew Cross']
11
+ spec.email = ['mcross@salsify.com']
12
+ spec.description = 'Offline sort for any enumerable with pluggable serialization strategies'
13
+ spec.summary = 'Offline sort for any enumerable with pluggable serialization strategies'
14
+ spec.homepage = 'https://github.com/salsify/offline-sort'
15
+ spec.license = 'MIT'
16
+
17
+ spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
18
+
19
+ spec.required_ruby_version = '>= 2.6'
15
20
 
16
- spec.files = `git ls-files`.split($/)
17
21
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
22
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
- spec.require_paths = ["lib"]
23
+ spec.require_paths = ['lib']
20
24
 
21
- spec.add_development_dependency "msgpack"
22
- spec.add_development_dependency "bundler", "~> 1.3"
23
- spec.add_development_dependency "rake"
24
- spec.add_development_dependency "rspec"
25
+ spec.add_development_dependency 'bundler'
26
+ spec.add_development_dependency 'msgpack'
27
+ spec.add_development_dependency 'rake'
28
+ spec.add_development_dependency 'rspec'
29
+ spec.add_development_dependency 'rspec_junit_formatter'
30
+ spec.add_development_dependency 'salsify_rubocop', '~> 1.0.1'
25
31
  end
@@ -1,16 +1,18 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  shared_examples "a valid chunk input output" do
4
6
  let(:count) { 1000 }
5
7
 
6
8
  let(:arrays) do
7
- count.times.map do |index|
9
+ Array.new(count) do |index|
8
10
  [SecureRandom.hex, index, SecureRandom.hex]
9
11
  end
10
12
  end
11
13
 
12
14
  let(:hashes) do
13
- count.times.map do |index|
15
+ Array.new(count) do |index|
14
16
  { 'a' => SecureRandom.hex, 'b' => index, 'c' => SecureRandom.hex }
15
17
  end
16
18
  end
@@ -21,7 +23,7 @@ shared_examples "a valid chunk input output" do
21
23
  t
22
24
  end
23
25
 
24
- let(:chunk_class) { }
26
+ let(:chunk_class) {}
25
27
  let(:chunk_io) { chunk_class.new(tempfile) }
26
28
 
27
29
  describe "#rewind" do
@@ -80,16 +82,17 @@ end
80
82
  describe OfflineSort::Chunk::InputOutput::Base do
81
83
  let(:io) { Tempfile.new('chunk') }
82
84
  let(:chunk_io) { OfflineSort::Chunk::InputOutput::Base.new(io) }
85
+ let(:expected_error_klass) { OfflineSort::Chunk::InputOutput::Base::MethodNotImplementedError }
83
86
 
84
87
  describe "#read_entry" do
85
88
  it "raises when read_entry is called" do
86
- expect { chunk_io.read_entry }.to raise_error(OfflineSort::Chunk::InputOutput::Base::MethodNotImplementedError)
89
+ expect { chunk_io.read_entry }.to raise_error(expected_error_klass)
87
90
  end
88
91
  end
89
92
 
90
93
  describe "#write_entry" do
91
94
  it "raises when write_entry is called" do
92
- expect { chunk_io.write_entry({}) }.to raise_error(OfflineSort::Chunk::InputOutput::Base::MethodNotImplementedError)
95
+ expect { chunk_io.write_entry({}) }.to raise_error(expected_error_klass)
93
96
  end
94
97
  end
95
98
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe OfflineSort::Chunk::InputOutput::Marshal do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe OfflineSort::Chunk::InputOutput::MessagePack do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe OfflineSort::Chunk::InputOutput::Yaml do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe OfflineSort::FixedSizeMinHeap do
@@ -6,14 +8,14 @@ describe OfflineSort::FixedSizeMinHeap do
6
8
 
7
9
  describe "#initialize" do
8
10
  it "is a a heap" do
9
- expect{ assert_min_heap(heap.array) }.not_to raise_error
11
+ expect { assert_min_heap(heap.array) }.not_to raise_error
10
12
  end
11
13
  end
12
14
 
13
15
  describe "#push" do
14
16
  context "with a full array" do
15
17
  it "raises an exception" do
16
- expect{ heap.push(rand(20)) }.to raise_error("Heap Size (#{array.size}) Exceeded")
18
+ expect { heap.push(rand(20)) }.to raise_error("Heap Size (#{array.size}) Exceeded")
17
19
  end
18
20
  end
19
21
 
@@ -23,7 +25,7 @@ describe OfflineSort::FixedSizeMinHeap do
23
25
  end
24
26
 
25
27
  it "adds to the heap" do
26
- expect{ heap.push(1) }.not_to raise_error
28
+ expect { heap.push(1) }.not_to raise_error
27
29
  end
28
30
  end
29
31
 
@@ -34,7 +36,7 @@ describe OfflineSort::FixedSizeMinHeap do
34
36
 
35
37
  it "adds to the heap" do
36
38
  5.times do
37
- expect{ heap.push(1) }.not_to raise_error
39
+ expect { heap.push(1) }.not_to raise_error
38
40
  end
39
41
  end
40
42
  end
@@ -68,7 +70,7 @@ describe OfflineSort::FixedSizeMinHeap do
68
70
  100.times do
69
71
  heap.pop
70
72
  heap.push(rand(100))
71
- expect{ assert_min_heap(heap.array) }.not_to raise_error
73
+ expect { assert_min_heap(heap.array) }.not_to raise_error
72
74
  end
73
75
  end
74
76
  end
@@ -78,18 +80,16 @@ describe OfflineSort::FixedSizeMinHeap do
78
80
  left = (2 * index) + 1
79
81
  right = (2 * index) + 2
80
82
 
81
- if left < array.size
82
- unless array[left] >= e
83
- puts "left #{e} #{array}"
84
- raise "not a heap"
85
- end
83
+ if left < array.size && array[left] < e
84
+ puts "left #{e} #{array}"
85
+ raise 'not a heap'
86
86
  end
87
87
 
88
- if right < array.size
89
- unless array[right] >= e
90
- puts "right #{e} #{array}"
91
- raise "not a heap"
92
- end
88
+ next unless right < array.size
89
+
90
+ unless array[right] >= e
91
+ puts "right #{e} #{array}"
92
+ raise 'not a heap'
93
93
  end
94
94
  end
95
95
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe OfflineSort::Sorter do
@@ -11,11 +13,11 @@ describe OfflineSort::Sorter do
11
13
  before do
12
14
  @unsorted = enumerable.dup
13
15
  r = Benchmark.measure do
14
- result = OfflineSort.sort(enumerable, chunk_size: entries_per_chunk, &sort)
16
+ result = OfflineSort.sort(enumerable, chunk_size: entries_per_chunk, &sort)
15
17
 
16
- @sorted = result.map do |entry|
17
- entry
18
- end
18
+ @sorted = result.map do |entry|
19
+ entry
20
+ end
19
21
  end
20
22
  puts r
21
23
  end
@@ -32,9 +34,7 @@ describe OfflineSort::Sorter do
32
34
  next
33
35
  end
34
36
 
35
- unless ((sort.call(last) <=> sort.call(entry)) == -1)
36
- raise "Out of order at line #{entry_count}"
37
- end
37
+ raise "Out of order at line #{entry_count}" unless (sort.call(last) <=> sort.call(entry)) == -1
38
38
 
39
39
  last = entry
40
40
  entry_count += 1
@@ -45,7 +45,7 @@ describe OfflineSort::Sorter do
45
45
  end
46
46
 
47
47
  let(:arrays) do
48
- count.times.map do |index|
48
+ Array.new(count) do |index|
49
49
  [SecureRandom.hex, index, SecureRandom.hex]
50
50
  end
51
51
  end
@@ -54,7 +54,7 @@ describe OfflineSort::Sorter do
54
54
  let(:array_sort) { Proc.new { |arr| arr[array_sort_index] } }
55
55
 
56
56
  let(:hashes) do
57
- count.times.map do |index|
57
+ Array.new(count) do |index|
58
58
  { 'a' => SecureRandom.hex, 'b' => index, 'c' => SecureRandom.hex }
59
59
  end
60
60
  end
@@ -72,7 +72,7 @@ describe OfflineSort::Sorter do
72
72
  context "with multiple sort keys" do
73
73
  it_behaves_like "a correct offline sort" do
74
74
  let(:enumerable) do
75
- count.times.map do |index|
75
+ Array.new(count) do |index|
76
76
  [index.round(-1), index, SecureRandom.hex]
77
77
  end.shuffle
78
78
  end
@@ -90,7 +90,7 @@ describe OfflineSort::Sorter do
90
90
  context "with multiple sort keys" do
91
91
  it_behaves_like "a correct offline sort" do
92
92
  let(:enumerable) do
93
- count.times.map do |index|
93
+ Array.new(count) do |index|
94
94
  { 'a' => index.round(-1), 'b' => index, 'c' => SecureRandom.hex }
95
95
  end.shuffle
96
96
  end
@@ -99,4 +99,3 @@ describe OfflineSort::Sorter do
99
99
  end
100
100
  end
101
101
  end
102
-
data/spec/spec_helper.rb CHANGED
@@ -1,7 +1,9 @@
1
- $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift File.expand_path('../lib', __dir__)
2
4
  require 'securerandom'
3
5
  require 'benchmark'
4
6
  require 'msgpack'
7
+ require 'tempfile'
5
8
 
6
9
  require 'offline_sort'
7
-
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: offline-sort
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew Cross
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-12 00:00:00.000000000 Z
11
+ date: 2021-10-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: msgpack
14
+ name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
@@ -25,19 +25,19 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: bundler
28
+ name: msgpack
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '1.3'
33
+ version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '1.3'
40
+ version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -66,6 +66,34 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec_junit_formatter
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: salsify_rubocop
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 1.0.1
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 1.0.1
69
97
  description: Offline sort for any enumerable with pluggable serialization strategies
70
98
  email:
71
99
  - mcross@salsify.com
@@ -73,6 +101,11 @@ executables: []
73
101
  extensions: []
74
102
  extra_rdoc_files: []
75
103
  files:
104
+ - ".circleci/config.yml"
105
+ - ".gitignore"
106
+ - ".rspec"
107
+ - ".rubocop.yml"
108
+ - CHANGELOG.md
76
109
  - Gemfile
77
110
  - LICENSE.txt
78
111
  - README.md
@@ -92,13 +125,13 @@ files:
92
125
  - spec/offline_sort/chunk/input_output/message_pack_spec.rb
93
126
  - spec/offline_sort/chunk/input_output/yaml_spec.rb
94
127
  - spec/offline_sort/fixed_size_min_heap_spec.rb
95
- - spec/offline_sort/offline_sort_spec.rb
128
+ - spec/offline_sort/sorter_spec.rb
96
129
  - spec/spec_helper.rb
97
130
  homepage: https://github.com/salsify/offline-sort
98
131
  licenses:
99
132
  - MIT
100
133
  metadata: {}
101
- post_install_message:
134
+ post_install_message:
102
135
  rdoc_options: []
103
136
  require_paths:
104
137
  - lib
@@ -106,16 +139,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
106
139
  requirements:
107
140
  - - ">="
108
141
  - !ruby/object:Gem::Version
109
- version: '0'
142
+ version: '2.6'
110
143
  required_rubygems_version: !ruby/object:Gem::Requirement
111
144
  requirements:
112
145
  - - ">="
113
146
  - !ruby/object:Gem::Version
114
147
  version: '0'
115
148
  requirements: []
116
- rubyforge_project:
117
- rubygems_version: 2.4.5.1
118
- signing_key:
149
+ rubygems_version: 3.1.4
150
+ signing_key:
119
151
  specification_version: 4
120
152
  summary: Offline sort for any enumerable with pluggable serialization strategies
121
153
  test_files:
@@ -124,5 +156,5 @@ test_files:
124
156
  - spec/offline_sort/chunk/input_output/message_pack_spec.rb
125
157
  - spec/offline_sort/chunk/input_output/yaml_spec.rb
126
158
  - spec/offline_sort/fixed_size_min_heap_spec.rb
127
- - spec/offline_sort/offline_sort_spec.rb
159
+ - spec/offline_sort/sorter_spec.rb
128
160
  - spec/spec_helper.rb