redsnapper 0.2.1 → 0.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c309291faf31352831f25043200a135caf7bcfec
4
- data.tar.gz: 5257b0a6599e3a6b651d19774fac3b3d6cf89d11
3
+ metadata.gz: 437b104c05b11ec9161133017a941e47a7ffb346
4
+ data.tar.gz: 3d573ff4757231f174467a84750d59e820b38300
5
5
  SHA512:
6
- metadata.gz: 5c6ef06d9e9a0c067cfd4dfcf19125d2a4420f877fa38985d6db376379c7f98df3e8da6b21ce0943b8890e21fd3da7f289a867051c5b0539a89da359a332ef84
7
- data.tar.gz: 39b6eca49cc73cf4f4771b6d0b6b22f78e2fdbe220e8ff1d6509c036eb050ebe513573487eb14f6e5be25204e7bf26fddbc8feaafa702215374c212743a2daac
6
+ metadata.gz: 0aad4e248e1e002e7d5a29910726b64939f7f1a9bfbfc330bf603e7d1de6f6777d07d0028ce47cf186d70cafebde5732b856b0cd9eb3fbdb1ea12d247ed25699
7
+ data.tar.gz: 553e1c4415de048636a5fab39219da562c11e4a77afd6a8a21e40c06efa153d32ae87e0560dbb2567edb3359365e65053885bb90834f270bed3dedb7133a9058
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.1
1
+ 0.3.0
data/bin/redsnapper CHANGED
@@ -13,10 +13,6 @@ OptionParser.new do |opts|
13
13
  opts.on('-j', '--jobs COUNT', Integer, 'Number of workers to use') do |jobs|
14
14
  options[:thread_pool_size] = jobs
15
15
  end
16
- opts.on('-m', '--max-files-per-job COUNT', Integer,
17
- 'Maximum number of files to extract in one job') do |count|
18
- options[:max_files_per_job] = count
19
- end
20
16
  end.parse!
21
17
 
22
18
  RedSnapper.new(ARGV.shift, options.merge(:tarsnap_options => ARGV)).run
data/lib/redsnapper.rb CHANGED
@@ -2,51 +2,51 @@ require 'thread/pool'
2
2
  require 'open3'
3
3
  require 'set'
4
4
 
5
- class Array
6
- def interleaved_slices(max_per_slice)
7
- raise ArgumentError unless max_per_slice >= 1
8
-
9
- count = (size.to_f / max_per_slice).ceil
10
-
11
- slices = (1..count).map { [] }
12
- each_with_index do |v, i|
13
- slices[i % count].push(v)
14
- end
15
-
16
- slices
17
- end
18
- end
19
-
20
5
  class RedSnapper
21
6
  TARSNAP = 'tarsnap'
22
7
  THREAD_POOL_SIZE = 10
23
- MAX_FILES_PER_JOB = 1000
8
+
9
+ class Group
10
+ attr_reader :files, :size
11
+ def initialize
12
+ @files = []
13
+ @size = 0
14
+ end
15
+ def add(name, size)
16
+ @files << name
17
+ @size += size
18
+ end
19
+ def <=>(other)
20
+ other.size <=> size
21
+ end
22
+ end
24
23
 
25
24
  def initialize(archive, options = {})
26
25
  @archive = archive
27
26
  @options = options
28
- @max_files_per_job = options[:max_files_per_job] || MAX_FILES_PER_JOB
29
27
  @thread_pool_size = options[:thread_pool_size] || THREAD_POOL_SIZE
30
28
  end
31
29
 
32
- def file_groups
33
- command = [ TARSNAP, '-tf', @archive, *@options[:tarsnap_options] ]
30
+ def files
31
+ command = [ TARSNAP, '-tvf', @archive, *@options[:tarsnap_options] ]
34
32
  command.push(@options[:directory]) if @options[:directory]
35
33
 
36
- files = []
34
+ files = {}
37
35
  dirs = Set.new
38
36
 
39
37
  Open3.popen3(*command) do |_, out, _|
40
38
  out.gets(nil).split("\n").each do |entry|
41
- if entry.end_with?('/')
42
- dirs.add(entry)
39
+ (_, _, _, _, size, _, _, _, name) = entry.split(/\s+/, 9)
40
+ if name.end_with?('/')
41
+ dirs.add(name)
43
42
  else
44
- files.push(entry)
43
+ files[name] = size.to_i
45
44
  end
46
45
  end
47
46
  end
48
47
 
49
- files.each { |f| dirs.delete(File.dirname(f) + '/') }
48
+ files.each { |f, _| dirs.delete(File.dirname(f) + '/') }
49
+
50
50
  empty_dirs = dirs.clone
51
51
 
52
52
  dirs.each do |dir|
@@ -56,9 +56,17 @@ class RedSnapper
56
56
  end
57
57
  end
58
58
 
59
- files.push(*empty_dirs)
60
- files_per_slice = [ (files.size.to_f / @thread_pool_size).ceil, @max_files_per_job ].min
61
- files.interleaved_slices(files_per_slice)
59
+ empty_dirs.each { |dir| files[dir] = 0 }
60
+
61
+ files
62
+ end
63
+
64
+ def file_groups
65
+ groups = (1..@thread_pool_size).map { Group.new }
66
+ files.sort { |a, b| b.last <=> a.last }.each do |file|
67
+ groups.sort.last.add(*file)
68
+ end
69
+ groups.map(&:files)
62
70
  end
63
71
 
64
72
  def run
data/redsnapper.gemspec CHANGED
@@ -2,11 +2,11 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: redsnapper 0.2.1 ruby lib
5
+ # stub: redsnapper 0.3.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "redsnapper"
9
- s.version = "0.2.1"
9
+ s.version = "0.3.0"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib"]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redsnapper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Scott Wheeler