home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / TBTREE.ZIP / EXAM3.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1988-07-25  |  13.0 KB  |  294 lines

  1. (* EXAMPLE3.PAS *)
  2.  
  3. program driver;
  4. {$R+}
  5.  
  6. uses
  7.     Btree,
  8.     Compare,
  9.     FileBuff,
  10.     FileDecs,
  11.     Files,
  12.     LRecList,
  13.     Numbers,
  14.     Page,
  15.     Logical;
  16.  
  17. const
  18.     TESTSTRINGSIZE = 10;          (* size of strings (part of test record) *)
  19.  
  20. type
  21.     TestString = String[TESTSTRINGSIZE];
  22.  
  23.     TestRecord = record                 (* record definition for data file *)
  24.                  randByte : Byte;
  25.                  randString : TestString;
  26.                  end;
  27.  
  28. var
  29.     dataFile,
  30.     indexFile1,
  31.     indexFile2 : FnString;                      (* holds file name strings *)
  32.  
  33.     testRec : TestRecord;                (* variable to hold a data record *)
  34.  
  35.     lrLst : LrList;         (* variable which user declares and passes in to
  36.                                LRLIST unit.  LRLIST will build a list of
  37.                                logical records which fulfill a query criteria.
  38.                                (Actually the list will be built by a call
  39.                                to the BTREE unit which in turn uses the LRLIST
  40.                                unit.                                         *)
  41.  
  42.     lrNum : LrNumber;       (* a couple of variable used in this demo program
  43.                                to keep track of logical record number
  44.                                currently being processed.                    *)
  45.  
  46.     tempByte : Byte;        (* this variable is used to pass in the selection
  47.                                criteria for retrievals.  A variable or typed
  48.                                constants must be used.  Constants do not work
  49.                                since the call is by reference and not by
  50.                                value                                         *)
  51.  
  52.     exitSave : Pointer;     (* used as pointer to my terminiation procedure  *)
  53.  
  54.  
  55. (* This procedure will be called prior to termination of the program whether
  56.    there is an error or not.  This is a demonstration of a good technique to
  57.    use in conjunction with BTree10.  Calls to write the buffer to disk and
  58.    close the files should be included.  This is also a place top handle runtime
  59.    error since I do not attempt to deal with errors or maintain global error
  60.    variables in BTree10.                                                     *)
  61.  
  62. {$F+} procedure MyExit; {$F-}
  63.  
  64.     begin
  65.     Writeln('Writing Records To Disk ...');        (* just a note so you can
  66.                                                       follow along           *)
  67.  
  68.     WriteEntireBufferToDisk;         (* very important step!!  Before leaving
  69.                                         the program the buffer must be written
  70.                                         to disk or some changes will be lost.
  71.                                         This will cause major problems and lost
  72.                                         data!!!  This is not really required in
  73.                                         in this program since nothing is
  74.                                         modified.  A logical record list is
  75.                                         created, but it happens to be small
  76.                                         enough that a temporary file is not
  77.                                         needed.  If a file was needed, it would
  78.                                         have been destroyed on the call to
  79.                                         DestroyLrList anyway.                *)
  80.  
  81.     Writeln('Closing Files ...');                  (* just a note so you can
  82.                                                       follow along           *)
  83.     CloseAllFiles;               (* Close the files to clean up.  It is
  84.                                     important to realize that CloseAllFiles
  85.                                     DOES NOT write the buffer to disk, it only
  86.                                     deals with the files open list.          *)
  87.  
  88.     end;
  89.  
  90.  
  91. (* This routine should be called before anything else happens.  It calls
  92.    the various routines to set up parameters according to values applicable
  93.    to your particular application.                                           *)
  94.  
  95. procedure SetUp;
  96.  
  97.     begin
  98.     SetMaxBufferPages(100);  (* a call to the PAGE unit to set up the number
  99.                                 of pages in the buffer.  If this is not done a
  100.                                 default of one page is used.  This will cause
  101.                                 poor performance but will not cause any
  102.                                 runtime errors                               *)
  103.  
  104.     SetMaxOpenFiles(10);     (* a call to the FILEBUFF unit to set the number
  105.                                 of files the FILEBUFF unit can have open at
  106.                                 once.  See FILEBUFF unit for details.        *)
  107.  
  108.     SetImmediateDiskWrite(FALSE); (* changed and newly created pages will be
  109.                                      buffered in the page buffer and will only
  110.                                      written to disk when they are swapped out
  111.                                      or explicitly written out by a user
  112.                                      request                                 *)
  113.  
  114.     end;
  115.  
  116.  
  117. (* This procedure adjusts the file names as required.  It appends the proper
  118.    extension to the name.                                                    *)
  119.  
  120. procedure InitFiles;
  121.  
  122.     begin
  123.  
  124.     dataFile := 'myFile1';
  125.     FixFileName(dataFile,DATA);
  126.  
  127.     indexFile1 := 'testByte';
  128.     FixFileName(indexFile1,INDEX);
  129.  
  130.     indexFile2 := 'testStrg';
  131.     FixFileName(indexFile2,INDEX);
  132.  
  133.     end;
  134.  
  135.  
  136.  
  137. begin
  138.  
  139. Writeln('Setting up termination routine ...');     (* just a note so you can
  140.                                                       follow along           *)
  141.  
  142. exitSave := ExitProc;       (* see page 376 - 377 of Turbo Pascal 4.0 manual *)
  143. ExitProc := @MyExit;
  144.  
  145. Writeln('Initializing Parameters ...');            (* just a note so you can
  146.                                                       follow along           *)
  147.  
  148. SetUp;              (* set file open buffer size and page buffer size limits *)
  149.                     (* set immediate disk write parameter as well            *)
  150.  
  151.  
  152. InitFiles;                                   (* create the files and indexes *)
  153.  
  154. Writeln('Looking for logical records which match selection criterion and',
  155.          ' building logical record list ... this may take a minute ...' );
  156.                                                    (* just a note so you can
  157.                                                       follow along           *)
  158.  
  159. tempByte := 10;         (* We want to find and delete all records for which
  160.                            tempByte is less than or equal to 10.  We need to
  161.                            tempByte to the search value (10).                *)
  162.  
  163. GetValuesFromBTree(indexFile1,tempByte,LE,lrLst);  (* build list of logical
  164.                                                       record numbers which
  165.                                                       are less than or equal
  166.                                                       to 10                  *)
  167.  
  168.     (* The following loop will delete data records associated with the
  169.        record numbers found in the newly created logical record list.        *)
  170.  
  171. lrNum := GetFirstLr(lrLst);   (* get the first record number and set the cursor
  172.                                  the front of the list.                      *)
  173.  
  174. while lrNum <> 0 do
  175.     begin
  176.  
  177.     (* we need to fetch the record so we can use the values for
  178.        testRec.randByte and testRec.randString to make deletions from the
  179.        the two indexes.                                                      *)
  180.  
  181.     GetALogicalRecord(dataFile,        (* variable holding name of data file *)
  182.                       lrNum,                      (* logical record to fetch *)
  183.                       testRec,                      (* place to put the data *)
  184.                       SizeOf(testRec));       (* number of bytes to retrieve *)
  185.  
  186.     DeleteRecord(dataFile,lrNum);   (* delete the logical record specified from
  187.                                        the data file.  We still need to delete
  188.                                        it from the index.                    *)
  189.  
  190.     (* The next two satements delete the appropriate entries from the
  191.        indexes.                                                              *)
  192.  
  193.     DeleteValueFromBTree(indexFile1,lrNum,testRec.randByte);
  194.  
  195.     DeleteValueFromBTree(indexFile2,lrNum,testRec.randString);
  196.  
  197.     lrNum := GetNextLr(lrLst);         (* advance the cursor to next in list *)
  198.  
  199.     end;
  200.  
  201. DestroyLrList(lrLst);   (* we're done with list so let's get rid of it.  This
  202.                            is important so that there aren't a bunch of
  203.                            temporary files upon termination.  Also, lists
  204.                            take up data space and also space in the page
  205.                            buffer                                            *)
  206.  
  207.     (* now that that is done, let's do an update.  Let's get all the records
  208.        for which the randByte value is equal to 25 and change randString
  209.        for those records to 'testtest'.                                      *)
  210.  
  211. tempByte := 25;                      (* We want to find all records for which
  212.                                                    tempByte is equal to 25.  *)
  213.  
  214. GetValuesFromBTree(indexFile1,tempByte,EQ,lrLst);  (* build list of logical
  215.                                                       record numbers which
  216.                                                       have values = 25       *)
  217.  
  218.     (* The following loop will update data records associated with the
  219.        record numbers found in the newly created logical record list.  It
  220.        won't make any difference, but we might as well traverse the list
  221.        in reverse order this time.                                          *)
  222.  
  223. lrNum := GetLastLr(lrLst);   (* get the first record number and set the cursor
  224.                                 the front of the list.                      *)
  225.  
  226. while lrNum <> 0 do
  227.     begin
  228.  
  229.     (* we need to fetch the record so we can use the value for
  230.        testRec.randString to make the appropriate deletion from indexFile2   *)
  231.  
  232.     GetALogicalRecord(dataFile,        (* variable holding name of data file *)
  233.                       lrNum,                      (* logical record to fetch *)
  234.                       testRec,                      (* place to put the data *)
  235.                       SizeOf(testRec));       (* number of bytes to retrieve *)
  236.  
  237.     DeleteValueFromBTree(indexFile2,lrNum,testRec.randString);
  238.  
  239.     testRec.randString := 'testtest';
  240.  
  241.     InsertValueInBTree(indexFile2,lrNum,testRec.randString);
  242.  
  243.     (* the next statement stores the updated record *)
  244.  
  245.     StoreALogicalRecord(dataFile,      (* variable holding name of data file *)
  246.                         lrNum,                    (* logical record to store *)
  247.                         testRec,                   (* place to get data from *)
  248.                         SizeOf(testRec));        (* number of bytes to store *)
  249.  
  250.     lrNum := GetPrevLr(lrLst);         (* advance the cursor to next in list *)
  251.  
  252.     end;
  253.  
  254.     (* now let's get all the records and see what we've done *)
  255.  
  256. tempByte := 255;         (* since we are checking for existence, this is not
  257.                             required.  tempByte must still be included in the
  258.                             call however.  It will be ignored.               *)
  259.  
  260.  
  261. GetValuesFromBTree(indexFile1,tempByte,EX,lrLst);  (* build list of logical
  262.                                                       record numbers which
  263.                                                       exist (ctriterion is
  264.                                                       EX which means exists *)
  265.  
  266.     (* The following loop will fetch the data records associated with the
  267.        record numbers found in the newly created logical record list.  Each
  268.        of the records will be printed.  Since the list was built using
  269.        indexFile1 which is the index corresponding to the randByte field in
  270.        testRec, the records will be printed in ascending order by
  271.        testRec.randByte.  If the opposite order was desired the list should
  272.        be traversed in reverse by using GetLastLr and GetPrevLr.             *)
  273.  
  274.  
  275. lrNum := GetFirstLr(lrLst);   (* get the first record number and set the cursor
  276.                                  the front of the list.                      *)
  277.  
  278. while lrNum <> 0 do
  279.     begin
  280.  
  281.     GetALogicalRecord(dataFile,        (* variable holding name of data file *)
  282.                       lrNum,              (* logical record number from list *)
  283.                       testRec,                      (* place to put the data *)
  284.                       SizeOf(testRec));       (* number of bytes to retrieve *)
  285.  
  286.     Writeln(lrNum,'        ',testRec.randByte,'       ',testrec.randString);
  287.  
  288.     lrNum := GetNextLr(lrLst);         (* advance the cursor to next in list *)
  289.     end;
  290.  
  291. Writeln('Total records found matching criteria = ',GetCountLr(lrLst));
  292.  
  293. end.
  294.