# hasher --- create hash table for shared libraries
define (MAXSIZE, 1001)
integer i, looks, entries, hash_mod, probe, hash_width
integer min_hash, fd
integer getarg, ctoi, getlin, mktemp
character names (9, MAXSIZE)
character arg1 (MAXLINE), arg2 (MAXLINE), buf (MAXLINE)
real hash_depth, min_depth
integer hash_calc (2)
longint long_hash_calc
equivalence (hash_calc (1), long_hash_calc)
procedure hash_names (hmod) forward
if (getarg (1, arg1, MAXLINE) == EOF || getarg (2, arg2, MAXLINE) == EOF)
call error ("Usage: hasher
"p)
i = 1
hash_mod = ctoi (arg1, i)
if (hash_mod < 1 | hash_mod > MAXSIZE)
call error ("Hash table size < 1 or too large"p)
i = 1
hash_width = ctoi (arg2, i)
if (hash_mod - hash_width < 1 || hash_mod + hash_width > MAXSIZE
|| hash_width < 0)
call error ("Hash size search width too big"p)
fd = mktemp (READWRITE)
if (fd == ERR)
call error ("Can't create temporary file"p)
call fcopy (STDIN, fd)
hash_names (hash_mod - hash_width)
min_depth = hash_depth
min_hash = hash_mod - hash_width
for (i = hash_mod - hash_width + 1; i <= hash_mod + hash_width; i += 1) {
hash_names (i)
if (hash_depth < min_depth) {
min_depth = hash_depth
min_hash = i
}
}
hash_names (min_hash)
call print (STDOUT, "** Hash table generated by hasher*n"p)
call print (STDOUT, "HMOD DATA *iL*nHTAB EQU ***n"p, min_hash)
for (i = 1; i <= min_hash | names (1, i) ~= 0; i = i + 1) {
if (names (1, i) == 0)
call print (STDOUT, "***n BSZ 6*n"p)
else {
call print (STDOUT, "***n EXT *s*n"p, names (1, i))
call print (STDOUT, " DATA C'*s'*n"p, names (1, i))
call print (STDOUT, " IP *s*n"p, names (1, i))
}
}
call print (STDOUT, "***n OCT 0*n"p)
call print (ERROUT, "entries: *i, table size: *i, search depth: *r*n"p,
entries, i - 1, min_depth)
stop
# hash_names --- hash the names into the table and count probes
procedure hash_names (hmod) {
integer hmod
local i; integer i
call rewind (fd)
do i = 1, MAXSIZE
names (1, i) = 0
entries = 0
looks = 0
while (getlin (buf, fd) ~= EOF) {
if (buf (1) == '*'c)
next
entries = entries + 1
for (i = length (buf); i <= 8; i = i + 1)
buf (i) = ' 'c
buf (9) = EOS
if (buf (3) == ' 'c && buf (4) == ' 'c) {
hash_calc (1) = 0
hash_calc (2) = xor (ls (buf (1), 8), buf (2))
}
else if (buf (5) == ' 'c && buf (6) == ' 'c) {
hash_calc (1) = xor (ls (buf (3), 8), buf (4))
hash_calc (2) = xor (ls (buf (1), 8), buf (2))
}
else if (buf (7) == ' 'c && buf (8) == ' 'c) {
hash_calc (1) = xor (ls (buf (3), 8), buf (4))
hash_calc (2) = xor (xor (ls (buf (1), 8), buf (2)),
xor (ls (buf (5), 8), buf (6)))
}
else {
hash_calc (1) = xor (xor (ls (buf (3), 8), buf (4)),
xor (ls (buf (7), 8), buf (8)))
hash_calc (2) = xor (xor (ls (buf (1), 8), buf (2)),
xor (ls (buf (5), 8), buf (6)))
}
hash_calc (1) = and (hash_calc (1), :77777)
probe = mod (long_hash_calc, intl (hmod)) + 1
while (names (1, probe) ~= 0) {
looks = looks + 1
probe = probe + 1
if (probe > MAXSIZE)
call error ("Hash table overflow -- make mod + width bigger"p)
}
call scopy (buf, 1, names (1, probe), 1)
}
hash_depth = float (looks) / float (entries) + 1.0
}
end