1 # -*- encoding: binary -*-
3 require 'mogilefs/util'
4 require 'mogilefs/network'
6 # Used for reading deprecated "bigfile" objects generated by the deprecated
7 # mogtool(1) utility. Not recommended for new projects.
9 module MogileFS::Bigfile
10 # VALID_TYPES = %w(file tarball partition).map { |x| x.freeze }.freeze
11 include MogileFS::Network
13 # returns a big_info hash if successful
15 parse_info(get_file_data(key))
18 # returns total bytes written and the big_info hash if successful, raises an
19 # exception if not. wr_io is expected to be an IO-like object capable of
20 # receiving the write method.
21 def bigfile_write(key, wr_io, opts = { :verify => false })
22 info = bigfile_stat(key)
25 # we only decode raw zlib deflated streams that mogtool (unfortunately)
26 # generates. tarballs and gzip(1) are up to to the application to decrypt.
27 if info[:compressed] || opts[:verify]
28 wr_io = MogileFS::Bigfile::Filter.new(wr_io, info, opts)
31 info[:parts].each_with_index do |part,part_nr|
32 next if part_nr == 0 # info[:parts][0] is always empty
33 uris = verify_uris(part[:paths].map { |path| URI.parse(path) })
35 # part[:paths] may not be valid anymore due to rebalancing, however we
36 # can get_keys on key,<part_nr> and retry paths if all paths fail
37 part[:paths] = get_paths("#{key.gsub(/^big_info:/, '')},#{part_nr}")
38 uris = verify_uris(part[:paths].map { |path| URI.parse(path) })
39 raise MogileFS::Backend::NoDevices if uris.empty?
42 sock = http_read_sock(uris[0])
43 w = copy_stream(sock, wr_io)
45 wr_io.respond_to?(:md5_check!) and wr_io.md5_check!(part[:md5])
49 total += wr_io.flushed_bytes if wr_io.respond_to?(:flushed_bytes)
56 include MogileFS::Util
59 # parses the contents of a _big_info: string or IO object
60 def parse_info(info = '')
62 info.each_line do |line|
65 when /^(des|type|filename)\s+(.+)$/
67 when /^compressed\s+([01])$/
68 rv[:compressed] = ($1 == '1')
69 when /^(chunks|size)\s+(\d+)$/
70 rv[$1.to_sym] = $2.to_i
71 when /^part\s+(\d+)\s+bytes=(\d+)\s+md5=(.+)\s+paths:\s+(.+)$/
72 rv[:parts][$1.to_i] = {
75 :paths => $4.split(/\s*,\s*/),
83 require "mogilefs/bigfile/filter"
86 # Copied from mogtool:
87 # http://code.sixapart.com/svn/mogilefs/utils/mogtool, r1221
89 # this is a temporary file that we delete when we're doing recording all chunks
93 starttime=UNIXTIMESTAMP
95 # when done, we write the _info file and delete the _pre.
99 des Cow's ljdb backup as of 2004-11-17
100 type { partition, file, tarball }
102 filename ljbinlog.305.gz
103 partblocks 234324324324
106 part 1 <bytes> <md5hex>
107 part 2 <bytes> <md5hex>
108 part 3 <bytes> <md5hex>
109 part 4 <bytes> <md5hex>
110 part 5 <bytes> <md5hex>
119 BEGIN MOGTOOL RECIEPT
124 part 1 bytes=23423432 md5=2349823948239423984 paths: http://dev5/2/23/23/.fid, http://dev6/23/423/4/324.fid
125 part 1 bytes=23423432 md5=2349823948239423984 paths: http://dev5/2/23/23/.fid, http://dev6/23/423/4/324.fid
126 part 1 bytes=23423432 md5=2349823948239423984 paths: http://dev5/2/23/23/.fid, http://dev6/23/423/4/324.fid
127 part 1 bytes=23423432 md5=2349823948239423984 paths: http://dev5/2/23/23/.fid, http://dev6/23/423/4/324.fid