Class: ReiserFS::Block

Inherits:
Object
  • Object
show all
Defined in:
lib/fs/ReiserFS/block.rb

Constant Summary collapse

BLOCK_HEADER =
BinaryStruct.new([
  'v',   'level',             # Level of the block in the tree
  'v',   'nitems',            # The number of items in the block
  'x20', nil                  # Ignoring the following, as they are not presently used
  #  'v',  'free_space', # Free space left in the block
  #  'a2', 'reserved',
  #  'a16','right_key',  # right delimiting key for the block
])
SIZEOF_BLOCK_HEADER =

‘v’, ‘free_space’, # Free space left in the block

'a2', 'reserved',
'a16','right_key',  # right delimiting key for the block
BLOCK_HEADER.size
KEY =
BinaryStruct.new([
  'V',  'directory_id',
  'V',  'object_id',
  'V',  'offset',
  'V',  'type'
])
SIZEOF_KEY =
KEY.size
POINTER =
BinaryStruct.new([
  'V',  'block_number',
  'v',  'size',
  'a2', 'reserved',
])
SIZEOF_POINTER =
POINTER.size
ITEM_HEADER =
BinaryStruct.new([
  'a16',  'key',
  'v',    'count',
  'v',    'length',
  'v',    'location',
  'v',    'version'
])
SIZEOF_ITEM_HEADER =
ITEM_HEADER.size

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(data, bnum) ⇒ Block

Returns a new instance of Block.



17
18
19
20
21
22
23
24
# File 'lib/fs/ReiserFS/block.rb', line 17

def initialize(data, bnum)
  @blockNum = bnum
  @data     = data
  @bh       = BLOCK_HEADER.decode(@data)
  @nitems   = @bh['nitems']
  @level    = @bh['level']
  @iHeaders = {}
end

Instance Attribute Details

#blockNumObject (readonly)

Returns the value of attribute blockNum.



15
16
17
# File 'lib/fs/ReiserFS/block.rb', line 15

def blockNum
  @blockNum
end

#dataObject (readonly)

Returns the value of attribute data.



15
16
17
# File 'lib/fs/ReiserFS/block.rb', line 15

def data
  @data
end

Instance Method Details

#data2key(keydata) ⇒ Object



43
44
45
46
47
# File 'lib/fs/ReiserFS/block.rb', line 43

def data2key(keydata)
  key = KEY.decode(keydata)
  key['type'] = Utils.type2integer(key['type'])
  key
end

#dumpObject



169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/fs/ReiserFS/block.rb', line 169

def dump
  out = dumpHeader

  if isLeaf?
    (1..@nitems).each do |i|
      ihead = getItemHeader(i)
      out += dumpItemHeader(ihead, "Item Header #{i}")
    end
  else
    (1..@nitems).each do |i|
      key  = getKey(i)
      out += dumpKey(key, "Key #{i}")
    end
    out += "\n"
    (0..@nitems).each do |i|
      ptr  = getPointer(i)
      out += dumpPointer(ptr, "Ptr #{i}")
    end
  end
  out
end

#dumpHeaderObject



191
192
193
# File 'lib/fs/ReiserFS/block.rb', line 191

def dumpHeader
  "Block Header: blockNum=#{@blockNum} nitems=#{@bh['nitems']} level=#{@bh['level']}\n"
end

#dumpItemHeader(ihead, label = nil) ⇒ Object



203
204
205
206
207
# File 'lib/fs/ReiserFS/block.rb', line 203

def dumpItemHeader(ihead, label = nil)
  key = ihead['key']
  keystring = "\{#{key['directory_id']},#{key['object_id']},#{key['offset']},#{key['type']}\}"
  "#{label}:\t\{#{keystring},#{ihead['count']},#{ihead['length']},#{ihead['location']},#{ihead['version']}\}\n"
end

#dumpKey(key, label = nil) ⇒ Object



195
196
197
# File 'lib/fs/ReiserFS/block.rb', line 195

def dumpKey(key, label = nil)
  "#{Utils.dumpKey(key, label)}\n"
end

#dumpPointer(ptr, label = nil) ⇒ Object



199
200
201
# File 'lib/fs/ReiserFS/block.rb', line 199

def dumpPointer(ptr, label = nil)
  "#{label}:\t\{#{ptr['block_number']},#{ptr['size']}\}\n"
end

#findPointer(searchKey) ⇒ Object



73
74
75
76
77
78
79
80
81
82
83
# File 'lib/fs/ReiserFS/block.rb', line 73

def findPointer(searchKey)
  # puts "findPointer >> #{dumpKey(searchKey, "searchKey")}"
  (1..@nitems).each do |i|
    currentKey = getKey(i)
    compare = Utils.compareKeys(searchKey, currentKey)
    # puts dumpKey(currentKey, "currentKey(#{i})")
    next                   if compare > 0
    return getPointer(i - 1) if compare <= 0
  end
  getPointer(@nitems)
end

#findPointers(searchKey) ⇒ Object



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

def findPointers(searchKey)
  pointers = []
  compare  = nil

  (1..@nitems).each do |i|
    currentKey = getKey(i)
    compare = Utils.compareKeys(searchKey, currentKey)
    # puts dumpKey(currentKey, "currentKey(#{i})")
    next  if compare > 0
    pointers << getPointer(i - 1)
    break if compare < 0
  end
  pointers << getPointer(@nitems) if pointers.size == 0 || compare == 0

  pointers
end

#getItem(iheader) ⇒ Object



159
160
161
162
163
# File 'lib/fs/ReiserFS/block.rb', line 159

def getItem(iheader)
  offset = iheader['location']
  length = iheader['length']
  @data[offset, length]
end

#getItemCount(iheader) ⇒ Object



151
152
153
# File 'lib/fs/ReiserFS/block.rb', line 151

def getItemCount(iheader)
  iheader['count']
end

#getItemHeader(i) ⇒ Object



134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/fs/ReiserFS/block.rb', line 134

def getItemHeader(i)
  return @iHeaders[i] if @iHeaders.key?(i)
  return nil if i > @nitems || i <= 0

  pos = SIZEOF_BLOCK_HEADER + (SIZEOF_ITEM_HEADER * (i - 1))
  iheaddata = @data[pos, SIZEOF_ITEM_HEADER]
  keydata   = iheaddata[0, SIZEOF_KEY]
  key       = data2key(keydata)
  iheader   = ITEM_HEADER.decode(iheaddata)
  iheader['key'] = key
  @iHeaders[i] = iheader
end

#getItemHeaders(key = nil) ⇒ Object



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/fs/ReiserFS/block.rb', line 111

def getItemHeaders(key = nil)
  return @iHeadersAll if key.nil? && !@iHeadersAll.nil?

  did = Utils.getKeyDirectoryID(key) if key
  oid = Utils.getKeyObjectID(key)    if key

  iHeaders = []
  (1..nkeys).each do |i|
    iheader = getItemHeader(i)
    if key
      curKey = iheader['key']
      next if did != Utils.getKeyDirectoryID(curKey)
      next if oid != Utils.getKeyObjectID(curKey)
    end

    iHeaders << iheader
  end

  @iHeadersAll = iHeaders if key.nil?

  iHeaders
end

#getItemType(iheader) ⇒ Object



155
156
157
# File 'lib/fs/ReiserFS/block.rb', line 155

def getItemType(iheader)
  iheader['key']['type']
end

#getItemVersion(iheader) ⇒ Object



147
148
149
# File 'lib/fs/ReiserFS/block.rb', line 147

def getItemVersion(iheader)
  iheader['version']
end

#getKey(k) ⇒ Object

Keys are 1-based



50
51
52
53
54
55
# File 'lib/fs/ReiserFS/block.rb', line 50

def getKey(k)
  return nil if k > @nitems || k <= 0
  pos = SIZEOF_BLOCK_HEADER + (SIZEOF_KEY * (k - 1))
  keydata = @data[pos, SIZEOF_KEY]
  data2key(keydata)
end

#getPointer(p) ⇒ Object

Pointers are 0-based



65
66
67
68
69
70
71
# File 'lib/fs/ReiserFS/block.rb', line 65

def getPointer(p)
  # puts "getPointer >> p=#{p}"
  return nil if p > @nitems || p < 0
  pos = SIZEOF_BLOCK_HEADER + (SIZEOF_KEY * @nitems) + (SIZEOF_POINTER * p)
  ptrdata = @data[pos, SIZEOF_POINTER]
  POINTER.decode(ptrdata)
end

#isLeaf?Boolean

Returns:

  • (Boolean)


165
166
167
# File 'lib/fs/ReiserFS/block.rb', line 165

def isLeaf?
  @level == 1
end

#nkeysObject



26
27
28
# File 'lib/fs/ReiserFS/block.rb', line 26

def nkeys
  @nitems
end

#npointersObject



30
31
32
33
# File 'lib/fs/ReiserFS/block.rb', line 30

def npointers
  return 0 if isLeaf?
  @nitems + 1
end