Class: ZKSync::CryptoFileIndex

Inherits:
CryptoFile show all
Defined in:
lib/zksync/crypto_file_index.rb

Instance Attribute Summary collapse

Attributes inherited from CryptoFile

#archive_path

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from CryptoFile

#__read_page_keep_padding, #file_key, #inode, #make_parent_directories, #page_count, #page_matches?, #page_path, #page_physical_size, #page_size, #read, #read_page, #trim_to_size, #valid?, #write_page

Constructor Details

#initialize(archive_path, archive) ⇒ CryptoFileIndex

Returns a new instance of CryptoFileIndex.



26
27
28
29
30
31
32
# File 'lib/zksync/crypto_file_index.rb', line 26

def initialize(archive_path, archive)
  super

  @files = {}
  @inode_table = InodeTable.new(self.inode_width)
  parse
end

Instance Attribute Details

#archiveObject (readonly)

Returns the value of attribute archive.



20
21
22
# File 'lib/zksync/crypto_file_index.rb', line 20

def archive
  @archive
end

#inode_tableObject (readonly)

Returns the value of attribute inode_table.



20
21
22
# File 'lib/zksync/crypto_file_index.rb', line 20

def inode_table
  @inode_table
end

Class Method Details

.inode_widthObject



22
23
24
# File 'lib/zksync/crypto_file_index.rb', line 22

def self.inode_width
  256
end

Instance Method Details

#add(archive_path, fs_path) ⇒ Object



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/zksync/crypto_file_index.rb', line 102

def add(archive_path, fs_path)
  inode = CryptoInode.new(archive_path)
  existing_inode = inode_for_path(archive_path)
  return if existing_inode == inode

  if existing_inode then
    inode = existing_inode
    slots_previously_used = inode.slots_used
  end

  file = CryptoFile.new(archive_path, archive)
  inode.set_from_fs(fs_path)

  @files[archive_path] = { inode:inode, file:file, fs_path:fs_path }
  file.write(open(fs_path), File.mtime(fs_path)) if inode.ftype != "directory"

  if existing_inode.nil? || inode.slots_used > slots_previously_used then
    inode_table.delete_inode(inode) if existing_inode
    inode_table.add_inode(inode)
  end
end

#file_at_path(archive_path) ⇒ Object



75
76
77
78
# File 'lib/zksync/crypto_file_index.rb', line 75

def file_at_path(archive_path)
  return nil unless @files.has_key?(archive_path)
  @files[archive_path][:file]
end

#inode_for_path(archive_path) ⇒ Object



80
81
82
83
# File 'lib/zksync/crypto_file_index.rb', line 80

def inode_for_path(archive_path)
  return nil unless @files.has_key?(archive_path)
  @files[archive_path][:inode]
end

#inode_widthObject



34
35
36
# File 'lib/zksync/crypto_file_index.rb', line 34

def inode_width
  @inode_width ||= self.class.inode_width
end

#listObject



71
72
73
# File 'lib/zksync/crypto_file_index.rb', line 71

def list
  @files.keys
end

#parseObject



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/zksync/crypto_file_index.rb', line 38

def parse
  content = ""
  read { |page| content += page }
  @inode_width, length = content[0...64].strip.split("|")[0..1].map { |x| x.to_i }
  offset = inode_width

  until offset >= content.length do
    next_inode_bytes = content[offset .. offset + inode_width].split("|").first.to_i
    header_len = next_inode_bytes.to_s.length + 1        
    inode_data = content[offset + header_len ... offset + header_len + next_inode_bytes].strip
    index = ((offset-inode_width).to_f/inode_width).ceil
    blocks = ((next_inode_bytes + header_len).to_f/inode_width).ceil

    inode = CryptoInode.new(JSON.parse(inode_data).merge(index:index))
    @files[inode.path] = { inode:inode, file:CryptoFile.new(inode.path, archive) }
    inode_table.add_inode(inode)

    offset += blocks*inode_width
  end
end

#rm(file) ⇒ Object



124
125
126
127
128
# File 'lib/zksync/crypto_file_index.rb', line 124

def rm(file)
  return unless @files[archive_path]
  file_at_path(archive_path).trim_to_size(0)
  inode_table.delete_inode(inode_for_path(archive_path).index)
end

#sizeObject

don’t use this to get size of what’s in memory; only for what is already stored. need this to get read to work.



61
62
63
64
65
66
67
68
69
# File 'lib/zksync/crypto_file_index.rb', line 61

def size
  return @size if @size
  begin
    inode_width_s, table_size_s, remainder = __read_page_keep_padding(0).split("|")
    @size = table_size_s.to_i + inode_width_s.to_i
  rescue Errno::ENOENT
    0
  end
end

#writeObject



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/zksync/crypto_file_index.rb', line 85

def write
  plaintext = inode_table.to_s
  table_size = plaintext.length

  length_str = inode_width.to_s + "|" + table_size.to_s + "|"
  length_str += " " * (inode_width - length_str.length)
  plaintext = length_str + plaintext

  num_pages = (plaintext.length.to_f/page_size).ceil
  num_pages.times do |page_num|
    page_plaintext = plaintext[page_num*page_size ... (page_num+1)*page_size]
    write_page(page_num, page_plaintext)
  end

  @size = table_size
end