! APM Filestore BITMAP utilities
include "SYSTEM:CONFIG.INC"
include "Inc:UTIL.IMP"
begin
const integer True=1, False=0
integer p, which, usage mode, map mode, Holes mode, first part, last part
string (127) output
routine do map (integer first part, last part)
recordformat bitmap fm(bytearray b(0 : bitmap size))
record (bitmap fm)name bm
integer s, l, i, j, total
string (127) command = "", output
byte x
for which = first part, 1, last part cycle
newlines (2)
printstring("Partition "); write(which, 0); print symbol(':')
connect file("$:BITMAP." . to string(which + '0'), 0, s, l)
bm == record(s)
unless l = bitmap size start
printstring(" -- expected bitmap size ")
write(bitmap size, 0)
printstring(", got "); write(l, 0)
printstring(" -- ")
finish
total = 0
for i = 0, 1, bitmap size - 1 cycle
x = bm_b(i)
for j = 0, 1, 7 cycle
total = total + 1 if x & 1 # 0
x = x >> 1
repeat
repeat
print(100 * total / (bitmap size << 3), 3, 3)
printstring("% used")
newline
for i = 0, 1, bitmap size - 1 cycle
if i & 7 = 0 start
phex4(i << 3)
printstring(": ")
finish
x = bm_b(i)
for j = 0, 1, 7 cycle
if x & 1 = 0 then space c
else print symbol('*') and total = total + 1
x = x >> 1
repeat
newline if i & 7 = 7
repeat
newline if i & 7 # 7
repeat
end
routine do holes (integer first part, last part)
recordformat hole fm(integer size, count, l, r)
constinteger hole fm size = 4 + 4 + 4 + 4
integer holes, column
recordformat bitmap fm(bytearray b(0 : bitmap size))
record (bitmap fm)name bm
integer which, s, l, current hole, i, j, m
string (127) command = "", output
byte x
routine add hole(integer size, integername where)
record (hole fm)name it
if where = 0 start
it == nil
it == new(it)
where = addr(it)
it_size = size; it_count = 1
it_l = 0; it_r = 0
else
it == record(where)
if it_size = size start
it_count = it_count + 1
else if it_size < size
add hole(size, it_l)
else
add hole(size, it_r)
finish
finish
end
routine print holes(integer where)
record (hole fm)name it
return if where = 0
it == record(where)
print holes(it_l)
write(it_size, 5); write(it_count, 6)
if column & 3 = 0 then newline c
else spaces(5)
column = column + 1
print holes(it_r)
end
for which = first part, 1, last part cycle
Holes = 0
Column = 1
newline
printstring("Hole analysis for partition "); write(which, 0)
printstring(" on "); printstring(date)
printstring(" at "); printstring(time)
newlines (2)
connect file("$:BITMAP." . to string(which + '0'), 0, s, l)
bm == record(s)
unless l = bitmap size start
printstring(" -- expected bitmap size ")
write(bitmap size, 0)
printstring(", got "); write(l, 0)
printstring(" -- ")
finish
current hole = 0
for i = 0, 1, bitmap size cycle
x = bm_b(i)
m = 1
for j = 1, 1, 8 cycle
if x & m = 0 start
current hole = current hole + 1
else
add hole(current hole, holes) if current hole # 0
current hole = 0
finish
m = m << 1
repeat
repeat
add hole(current hole, holes) if current hole # 0
printstring(" Size Count Size Count ")
printstring(" Size Count Size Count")
newline
print holes(holes)
newline if column & 3 # 1
repeat
end
routine do usage (integer first part, last part)
recordformat bitmap fm(bytearray b(0 : bitmap size))
record (bitmap fm)name bm
integer s, l, i, which, j, total, total total
string (127) command = ""
byte x
total total = 0
for which = first part, 1, last part cycle
connect file("$:BITMAP." . to string(which + '0'), 0, s, l)
bm == record(s)
total = 0
for i = 0, 1, bitmap size - 1 cycle
x = bm_b(i)
for j = 0, 1, 7 cycle
total = total + 1 if x & 1 # 0
x = x >> 1
repeat
repeat
printstring("Partition "); write(which, 0)
printstring(" has "); write(total, 0)
printstring(" block"); printsymbol('s') if total # 1
printstring(" (")
print(100 * total / (bitmap size << 3), 0, 2)
printstring("%) used")
newline
total total = total total + total
repeat
return unless first part = 0 and last part = last partition
printstring("Grand total of "); write(total total, 0)
printstring(" blocks (")
print(100 * total total / (8 * bitmap size * (last partition + 1)), 0, 2)
printstring("%) used")
newline
end
p = -1
define int param ("Partition", p, pam major)
output = ":T"
define param ("Output", output, pam new group + pam major)
Holes mode = False
define boolean params ("Holes", Holes mode, pam major)
Map mode = False
define boolean params ("Map", map mode, pam major)
Usage mode = False
define boolean params ("Usage", Usage mode, pam major)
process parameters (cliparam)
if Usage mode = False and Holes mode = False and map mode = False start
Print string ("Options for BITMAP are -MAP, -HOLES or -USAGE")
Newline
stop
finish
if P<0 or P>last partition start
first part = 0
last part = last partition
else
first part = P
last part = P
finish
open output(3, output); select output(3)
if usage mode # false start
do usage (first part, last part)
else if map mode # false
do map (first part, last part)
else if holes mode # false
do holes (first part, last part)
finish
end of program