home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
pascal
/
library
/
dos
/
btree
/
tree
/
exam3.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1989-07-12
|
14KB
|
307 lines
(* EXAM.PAS *)
program driver;
{$R+}
uses
Exam0,
Btree,
Compare,
FileBuff,
FileDecs,
Files,
Logical,
LRecList,
Numbers,
Page;
var
dataFile,
indexFile1,
indexFile2 : FnString; (* holds file name strings *)
testRec : TestRecord; (* variable to hold a data record *)
lrLst : LrList; (* variable which user declares and passes in to
LRLIST unit. LRLIST will build a list of
logical records which fulfill a query criteria.
(Actually the list will be built by a call
to the BTREE unit which in turn uses the LRLIST
unit. *)
lrNum : LrNumber; (* a couple of variable used in this demo program
to keep track of logical record number
currently being processed. *)
tempByte : Byte; (* this variable is used to pass in the selection
criteria for retrievals. A variable or typed
constants must be used. Constants do not work
since the call is by reference and not by
value *)
exitSave : Pointer; (* used as pointer to my terminiation procedure *)
(* This procedure will be called prior to termination of the program whether
there is an error or not. This is a demonstration of a good technique to
use in conjunction with TBTREE. Calls to write the buffer to disk and
close the files should be included. This is also a place top handle runtime
error since I do not attempt to deal with errors or maintain global error
variables in TBTREE. *)
{$F+} procedure MyExit; {$F-}
begin
ExitProc := ExitSave; (* reinstall the saved value of ExitProc *)
Writeln('Writing Records To Disk ...'); (* just a note so you can
follow along *)
WriteEntireBufferToDisk; (* very important step!! Before leaving
the program the buffer must be written
to disk or some changes will be lost.
This will cause major problems and lost
data!!! This is not really required in
in this program since nothing is
modified. A logical record list is
created, but it happens to be small
enough that a temporary file is not
needed. If a file was needed, it would
have been destroyed on the call to
DestroyLrList anyway. *)
Writeln('Closing Files ...'); (* just a note so you can
follow along *)
CloseAllFiles; (* Close the files to clean up. It is
important to realize that CloseAllFiles
DOES NOT write the buffer to disk, it only
deals with the files open list. *)
end;
(* This routine should be called before anything else happens. It calls
the various routines to set up parameters according to values applicable
to your particular application. *)
procedure SetUp;
begin
SetMaxBufferPages(100); (* a call to the PAGE unit to set up the number
of pages in the buffer. If this is not done a
default of one page is used. This will cause
poor performance but will not cause any
runtime errors *)
SetMaxOpenFiles(10); (* a call to the FILEBUFF unit to set the number
of files the FILEBUFF unit can have open at
once. See FILEBUFF unit for details. *)
SetImmediateDiskWrite(FALSE); (* changed and newly created pages will be
buffered in the page buffer and will only
written to disk when they are swapped out
or explicitly written out by a user
request *)
end;
(* This procedure initializes the file names as required. Also, if will
create the files if they do not exist. Therefore, you can use one
initialization routine whether the file exists or must be created. *)
procedure InitFiles;
begin
dataFile := 'myFile1.dat';
if not FileExists(dataFile) then
begin
CreateDataFile(dataFile,SizeOf(TestRecord));
end;
indexFile1 := 'testByte.idx';
if not FileExists(indexFile1) then
begin
CreateIndexFile(indexfile1,SizeOf(BYTE),BYTEVALUE);
end;
indexFile2 := 'testStrg.idx';
if not FileExists(indexFile2) then
begin
CreateIndexFile(indexfile2,SizeOf(TestString),STRINGVALUE);
end;
end;
(*****************************************************************************)
(* *)
(* M A I N P R O G R A M *)
(* *)
(*****************************************************************************)
begin
Writeln('Setting up termination routine ...'); (* just a note so you can
follow along *)
exitSave := ExitProc; (* see page 376 - 377 of Turbo Pascal 4.0 manual *)
ExitProc := @MyExit;
Writeln('Initializing Parameters ...'); (* just a note so you can
follow along *)
SetUp; (* set file open buffer size and page buffer size limits *)
(* set immediate disk write parameter as well *)
InitFiles;
Writeln('Looking for logical records which match selection criterion and',
' building logical record list ... this may take a minute ...' );
(* just a note so you can
follow along *)
tempByte := 10; (* We want to find and delete all records for which
tempByte is less than or equal to 10. We need to
set tempByte to the search value (10). *)
GetValuesFromBTree(indexFile1,tempByte,LE,lrLst); (* build list of logical
record numbers which
are less than or equal
to 10 *)
(* The following loop will delete data records associated with the
record numbers found in the newly created logical record list. *)
lrNum := GetFirstLr(lrLst); (* get the first record number and set the cursor
the front of the list. *)
while lrNum <> 0 do
begin
(* we need to fetch the record so we can use the values for
testRec.randByte and testRec.randString to make deletions from the
the two indexes. *)
GetALogicalRecord(dataFile, (* variable holding name of data file *)
lrNum, (* logical record to fetch *)
testRec); (* place to put the data *)
DeleteDataRecord(dataFile,lrNum); (* delete the logical record specified
from the data file. We still need
to delete it from the index. *)
(* The next two statements delete the appropriate entries from the
indexes. *)
DeleteValueFromBTree(indexFile1,lrNum,testRec.randByte);
DeleteValueFromBTree(indexFile2,lrNum,testRec.randString);
lrNum := GetNextLr(lrLst); (* advance the cursor to next in list *)
end;
DestroyLrList(lrLst); (* we're done with list so let's get rid of it. This
is important so that there aren't a bunch of
temporary files upon termination. Also, lists
take up data space and also space in the page
buffer *)
(* now that that is done, let's do an update. Let's get all the records
for which the randByte value is equal to 25 and change randString
for those records to 'testtest'. *)
tempByte := 25; (* We want to find all records for which
tempByte is equal to 25. *)
GetValuesFromBTree(indexFile1,tempByte,EQ,lrLst); (* build list of logical
record numbers which
have values = 25 *)
(* The following loop will update data records associated with the
record numbers found in the newly created logical record list. It
won't make any difference, but we might as well traverse the list
in reverse order this time. *)
lrNum := GetLastLr(lrLst); (* get the last record number and set the cursor
the end of the list. *)
while lrNum <> 0 do
begin
(* we need to fetch the record so we can use the value for
testRec.randString to make the appropriate deletion from indexFile2 *)
GetALogicalRecord(dataFile, (* variable holding name of data file *)
lrNum, (* logical record to fetch *)
testRec); (* place to put the data *)
DeleteValueFromBTree(indexFile2,lrNum,testRec.randString);
testRec.randString := 'testtest';
InsertValueInBTree(indexFile2,lrNum,testRec.randString);
(* the next statement stores the updated record *)
StoreALogicalRecord(dataFile, (* variable holding name of data file *)
lrNum, (* logical record to store *)
testRec); (* place to get data from *)
lrNum := GetPrevLr(lrLst); (* advance the cursor to next in list *)
end;
DestroyLrList(lrLst); (* we're done with list so let's get rid of it. This
is important so that there aren't a bunch of
temporary files upon termination. Also, lists
take up data space and also space in the page
buffer *)
(* now let's get all the records and see what we've done *)
tempByte := 255; (* since we are checking for existence, this is not
required. tempByte must still be included in the
call however. It will be ignored. *)
GetValuesFromBTree(indexFile1,tempByte,EX,lrLst); (* build list of logical
record numbers which
exist (criterion is
EX which means exists *)
(* The following loop will fetch the data records associated with the
record numbers found in the newly created logical record list. Each
of the records will be printed. Since the list was built using
indexFile1 which is the index corresponding to the randByte field in
testRec, the records will be printed in ascending order by
testRec.randByte. If the opposite order was desired the list should
be traversed in reverse by using GetLastLr and GetPrevLr. *)
lrNum := GetFirstLr(lrLst); (* get the first record number and set the cursor
the front of the list. *)
while lrNum <> 0 do
begin
GetALogicalRecord(dataFile, (* variable holding name of data file *)
lrNum, (* logical record number from list *)
testRec); (* place to put the data *)
Writeln(lrNum,' ',testRec.randByte,' ',testrec.randString);
lrNum := GetNextLr(lrLst); (* advance the cursor to next in list *)
end;
Writeln('Total records found matching criteria = ',GetCountLr(lrLst));
DestroyLrList(lrLst); (* we're done with list so let's get rid of it. This
is important so that there aren't a bunch of
temporary files upon termination. Also, lists
take up data space and also space in the page
buffer *)
end.