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.