program bSearch;
uses lists, dos, strings, debug, math, zentimer;
function lu06(val: Longint): String;
var
i: Longint;
s: String;
begin
Str(val:6,s);
for i := 1 to 6 do
if s[i] = ' ' then s[i]:= '0';
lu06 := s;
end;
procedure ReportTime(count: Longint);
var
secs: Longint;
begin
secs := count div 1000000;
count := count - secs * 1000000;
Writeln(secs, '.', lu06(count), ' seconds');
end;
type
PBTreeArrayPtr = ^PBTreeArray;
PBTreeArray = array[0..0] of PBTree;
procedure sortTrees(var trees:PBTreeArrayPtr; treeCount:integer);
var
i, j:integer;
tmpTree:PBTree;
begin
if (trees = NIL) then exit;
for i := 1 to treeCount-1 do
for j := 0 to i do
if (trees^[i]^.getKeyCount < trees^[j]^.getKeyCount) then
begin
tmpTree := trees^[j];
trees^[j] := trees^[i];
trees^[i] := tmpTree;
end;
end; // sortTrees
procedure usage;
begin
writeln('bSearch usage:');
writeln;
writeln('bSearch term1 [term2] [term3] [...]');
halt;
end;
procedure writeHTMLHeader(var f:text);
var curTerm:integer;
begin
writeln(f, '<HTML><HEAD>');
write(f, '<TITLE>Searching for ');
for curTerm := 1 to paramcount do
write(f, '``', paramstr(curTerm), ''''' ');
writeln(f);
writeln(f, '</TITLE></HEAD>');
writeln(f, '<BODY>');
end; // writeHTMLHeader
function convertFileName(const filename:string):string;
var
s:string;
i:integer;
begin
s := 'file:///' + filename;
for i:=1 to length(s) do
if s[i] = '\' then s[i] := '/';
result := s;
end; // convertFileName
var
masterBTI:PbTree;
fileNameDAT:file;
treeInfo: BTreeSearchRec;
filename:string;
numFound:integer;
curTerm : integer;
termsFound:integer;
wordBTI:PBTreeArrayPtr;
term:string;
u:uPtr;
outputTXTFile:text;
outputHTMLFile:text;
found:boolean;
begin
if (paramcount = 0) then usage;
LZTimerOn;
new(masterBTI, init('indicies\master.bti', 1024, BT_STRING, NIL));
writeln('masterBTI has ', masterBTI^.getKeyCount(), ' keys');
assign(fileNameDAT, 'indicies\fileName.dat');
{$I-} reset(fileNameDAT); {$I+}
if (IOResult <> 0) then
begin
writeln('Could not open fileName.dat');
halt
end;
GetMem(wordBTI, paramcount * sizeof(PBTree));
for curTerm := 1 to paramcount do
wordBTI^[curTerm] := NIL;
assign(outputTXTFile, 'find.txt');
rewrite(outputTXTFile);
assign(outputHTMLFile, 'find.html');
rewrite(outputHTMLFile);
termsFound := 0;
for curTerm := 1 to paramcount do
begin
numFound := 0;
term := lowercase(paramstr(curTerm));
if (masterBTI^.Find(@term, u)) then
begin
new(wordBTI^[termsFound], open('indicies\'+hex(u.u)+'.bti', NIL));
inc(termsFound);
end;
end; // for curTerm
if (termsFound = paramcount) then
begin
// write out the HTML header
writeHTMLHeader(outputHTMLFile);
// sort the trees into ascending order by keyCount
sortTrees(wordBTI, termsFound);
// Now that the trees are ordered, scan through the first tree looking
// for matches in all other trees
if (wordBTI^[0]^.getFirstKey(treeInfo)) then
repeat
found := TRUE;
curTerm := 1;
while (found) and (curTerm < paramCount) do
begin
found := wordBTI^[curTerm]^.Find(treeInfo.key, u);
inc(curTerm)
end; // while
if (found) then
begin
seek(fileNameDAT, int32(treeInfo.key^));
blockread(fileNameDAT, filename, 1);
blockread(fileNameDAT, filename[1], length(filename));
if (fsearch(filename, '') <> '') then
begin
writeln(outputTXTFile, filename);
writeln(outputHTMLFile, '<a href="', convertFileName(filename), '">', filename, '</a><br>');
end;
inc(numFound);
end; // if found
until not wordBTI^[0]^.findNext(treeInfo);
write('Found ');
for curTerm := 1 to paramcount do
write('``', paramstr(curTerm), ''''' ');
write('in ', numFound);
if (numFound = 1) then writeln(' file') else writeln(' files');
writeln(outputHTMLFile, '</BODY></HTML>');
end
else
begin
writeHTMLHeader(outputHTMLFile);
writeln(outputHTMLFile, 'No files found contained your term(s)');
writeln(outputHTMLFile, '</BODY></HTML>');
writeln('Did not find any files containing the terms:');
for curTerm := 1 to paramcount do
write('``', paramstr(curTerm), ''''' ');
writeln;
end;
// delete the trees (note that termsFound might be 0, which means it won't execute the for loop)
for curTerm := 0 to termsFound-1 do
if (wordBTI^[curTerm]) <> NIL then dispose(wordBTI^[curTerm], done);
FreeMem(wordBTI, paramcount * sizeof(PBTree));
close(outputHTMLFile);
close(outputTXTFile);
dispose(masterBTI, done);
close(fileNameDAT);
LZTimerOff;
write('Search took ');
reportTime(LZTimerCount);
end.