home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / BTREE4.ZIP / BTREE4.DOC next >
Encoding:
Text File  |  1988-01-17  |  25.3 KB  |  661 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14.  
  15.  
  16.  
  17.  
  18.  
  19.  
  20.  
  21.  
  22.  
  23.  
  24.  
  25.  
  26.  
  27.  
  28.  
  29.  
  30.  
  31.  
  32.  
  33.  
  34.  
  35.  
  36.  
  37.  
  38.  
  39.  
  40.  
  41.  
  42.  
  43.  
  44.  
  45.  
  46.  
  47.  
  48.  
  49.  
  50.                                   BTREE4
  51.  
  52.  
  53.  
  54.                 a Shareware Unit for Turbo Pascal ver. 4.0
  55.  
  56.  
  57.  
  58.                     for Data and Index file management
  59.  
  60.  
  61.  
  62.  
  63.  
  64.                     Copyright (c) 1988 by W. Lee Passey
  65.  
  66.  
  67.  
  68.  
  69.  
  70.  
  71.  
  72.  
  73.  
  74.  
  75.  
  76.  
  77.  
  78.  
  79.  
  80.  
  81.  
  82.  
  83.  
  84.  
  85.  
  86.  
  87.  
  88.                              Pass-Key Software
  89.  
  90.                             119 MacArthur Ave.
  91.  
  92.                          Salt Lake City, UT  84115
  93.  
  94.                           (801) 486-9239 (voice)
  95.  
  96.                           (801) 485-7211 (data) 
  97.  
  98.  
  99.  
  100.  
  101.  
  102.  
  103.  
  104.  
  105.  
  106.  
  107.  
  108.  
  109.  
  110.  
  111.  
  112.  
  113.  
  114.  
  115.  
  116.  
  117.  
  118.  
  119.  
  120.  
  121.  
  122.  
  123.      BTree4 is  a separately  compiled unit  for Turbo  Pascal ver. 4.0 from
  124.  
  125. Borland International, Inc. BTree4  may be  linked to  a user's  source pro-
  126.  
  127. grams,  and  will  performs  all  of  the  same B-tree indexing functions as
  128.  
  129. Borland's Database Toolbox.
  130.  
  131.  
  132.  
  133.      This file contains general information about BTree4, an  annotated copy
  134.  
  135. of the  interface segment  describing all variables and procedures available
  136.  
  137. to calling procedures, and licensing and  registration information.   PLEASE
  138.  
  139. READ THIS FILE COMPLETELY BEFORE ATTEMPTING TO USE BTREE4.
  140.  
  141.  
  142.  
  143. BTree4  has  been  designed  to  be as compatible as possible with Borland's
  144.  
  145. Database Toolbox, but it  is not  a modification  of Borland's  source code;
  146.  
  147. rather it  is a whole new set of procedures and functions using a compatible
  148.  
  149. calling interface, but a wholly different memory storage  technique.  BTree4
  150.  
  151. does not require any pre-defined constants or initializaton sequence, as all
  152.  
  153. data storage, including the index page  stack, is  created as  needed on the
  154.  
  155. heap.
  156.  
  157.  
  158.  
  159.      For maximum  flexibility, the BTree4 routines will not halt the program
  160.  
  161. for any IO or heap full errors.  If an error is detected, the global boolean
  162.  
  163. variable 'OK'  is set to false, and the global integer variable 'IOError' is
  164.  
  165. set equal to the IO error code.   If the  error was  caused by  the unavail-
  166.  
  167. ability of heap memory, 'IOError' will be set to -1.
  168.  
  169.  
  170.  
  171.      Disk  IO  errors  must  be  resolved  by the programmer, however memory
  172.  
  173. allocation errors can usually  be  resolved  by  the  use  of  the procedure
  174.  
  175. 'CheckMem'   in   conjunction   with   the   global  variable  'MaxPageMem.'
  176.  
  177. 'MaxPageMem' should be set by the programmer to  the maximum  amount of heap
  178.  
  179. memory which  will be allocated for the index page stack.  If the page stack
  180.  
  181. attempts to exceed this amount of allocated memory,  little used  pages will
  182.  
  183. be discarded from memory until the page stack is again under the limit.  The
  184.  
  185. program expects that the amount of memory available will never  be less than
  186.  
  187. the value stored in 'MinPageMem', and the stack size will never be decreased
  188.  
  189. to less than that  value; thus,  'MaxPageMem' should  always be  larger than
  190.  
  191. 'MinPageMem.'
  192.  
  193.  
  194.  
  195.      Both 'MaxPageMem'  and 'MinPageMem'  can be dynamically assigned values
  196.  
  197. at any time during the operation of the program.  If more  dynamic memory is
  198.  
  199. needed,  the  page  stack  can  be  reduced in size by reducing the value of
  200.  
  201. 'MaxPageMem' (and 'MinPageMem', if necessary) and then calling CheckMem with
  202.  
  203. a zero  parameter.  The only restriction is that 'MinPageMem' must always be
  204.  
  205. large enough to hold one page from each  level of  the tree,  plus one extra
  206.  
  207. page.  
  208.  
  209.  
  210.  
  211.      In  addition  to  the  page  stack,  each open data file and index file
  212.  
  213. allocates for itself an IO buffer equal in size to the file's record length,
  214.  
  215. and each  index file  allocates an extra page buffer which is the same size.
  216.  
  217. These buffers are de-allocated  only by  closing the  associated file.   The
  218.  
  219. record length  for index  files is  equal to  5 + (number of keys per page X
  220.  
  221. (key length + 9)).
  222.  
  223.  
  224.  
  225.      What follows is a copy  of  the  BTree4  interface  section,  with each
  226.  
  227. procedure and significant variable annotated as to its function and use.
  228.  
  229.  
  230.  
  231.  
  232.  
  233.  
  234.  
  235.  
  236.  
  237.  
  238.  
  239.  
  240.  
  241.  
  242.  
  243.  
  244. {$I-,V-}
  245.  
  246.  
  247.  
  248. unit btree4;                      { VERSION 1.0 }
  249.  
  250.                                   { Copyright (c) 1988 by W. Lee Passey }
  251.  
  252. interface
  253.  
  254.  
  255.  
  256. type
  257.  
  258.   MaxString   = string[255];
  259.  
  260.   bufarray    = array [1..80] of byte;
  261.  
  262.   Str80       = string[80];
  263.  
  264.  
  265.  
  266.   PagePtr     = ^PageHeader;
  267.  
  268.   KeyListPtr  = ^KeyList;
  269.  
  270.  
  271.  
  272.   DataFile    = record
  273.  
  274.     case byte of
  275.  
  276.       0 : (F      : file);
  277.  
  278.       1 : (Handle,
  279.  
  280.            Mode,
  281.  
  282.            RecSize    : word;
  283.  
  284.            Private    : array [1..26] of byte;        { reserved by TP4 }
  285.  
  286.            FirstFree,         { the first available record in the file  }
  287.  
  288.            NumberFree : longint;   { the number of records deleted and
  289.  
  290.                                      therefore available for use        }
  291.  
  292.            RecLength  : word;      { the length of records in this file }
  293.  
  294.            KeysPerPage,            { if an index file, the maximum number
  295.  
  296.                                      of keys which may be put on a page }
  297.  
  298.            KeyLength  : byte;      { if an index file, the maximum
  299.  
  300.                                      length of a key                    }
  301.  
  302.            FirstPage  : longint;   { if an index file, the number of the
  303.  
  304.                                      record which is the root page      }
  305.  
  306.            FileName   : array [1..80] of char;
  307.  
  308.            Buffer     : ^BufArray);{ pointer to a buffer on the heap,
  309.  
  310.                                      used with this file, whose size is
  311.  
  312.                                      identical to the record length     }
  313.  
  314.            end;
  315.  
  316.  
  317.  
  318.   IndexFile   = record
  319.  
  320.     DF        : DataFile;
  321.  
  322.     RootPage  : PagePtr;           { a pointer to the root page, if it
  323.  
  324.                                      is in memory                       }
  325.  
  326.     KeySize,                       { the size of a key record, on the
  327.  
  328.                                      heap, for keys in this file        }
  329.  
  330.     ItemSize  : word;              { the size of a key, its reference
  331.  
  332.                                      and record pointer, in this file   }
  333.  
  334.     SavePage  : PagePtr;
  335.  
  336.     SaveKey   : KeyListPtr;
  337.  
  338.     SaveRec   : longint;
  339.  
  340.     PageBuffer: ^BufArray;        { pointer to a buffer on the heap,
  341.  
  342.                                     used with this file, whose size is
  343.  
  344.                                     identical to the record length, and
  345.  
  346.                                     which is used for packing and
  347.  
  348.                                     unpacking pages to and from the disk
  349.  
  350.  
  351.  
  352.  
  353.  
  354.  
  355.  
  356.  
  357.  
  358.  
  359.  
  360.  
  361.  
  362.  
  363.                                     and memory.                         }
  364.  
  365.     end;
  366.  
  367.  
  368.  
  369. (*   Like Borland's Database Toolbook, each file use by BTree4 must be
  370.  
  371. declared either as a DataFile or an IndexFile.  *)
  372.  
  373.  
  374.  
  375.   PageHeader  = record
  376.  
  377.     NextPage,                     { these two pointers link the pages   }
  378.  
  379.     PrevPage,                     { into a two-way linked list in memory
  380.  
  381.                                     each time a page is used it is placed
  382.  
  383.                                     back at the head of this list       }
  384.  
  385.     ParentPage,                   { a pointer to this page's parent page
  386.  
  387.                                     which should be in memory           }
  388.  
  389.     GreaterPage : PagePtr;        { a pointer to a page on a lower level
  390.  
  391.                                     containing keys greater than all
  392.  
  393.                                     keys on this page, if in memory     }
  394.  
  395.     GreaterRec,                   { the disk record number of the page
  396.  
  397.                                     which goes in GreaterPage           }
  398.  
  399.     RecNum      : longint;        { the disk record number of this page }
  400.  
  401.     FilePtr     : ^IndexFile;     { points to the file variable of the
  402.  
  403.                                     file which this page comes from     }
  404.  
  405.     ParentKey,                    { the key record from the parent page
  406.  
  407.                                     which contains the key which is one
  408.  
  409.                                     greater than all the keys on this
  410.  
  411.                                     page.  if this pointer is nil, you
  412.  
  413.                                     must go up another page; if this is
  414.  
  415.                                     not possible you are in the root
  416.  
  417.                                     page.                               }
  418.  
  419.     KeyList,                      { pointer to the first key on page    }
  420.  
  421.     ListEnd     : KeyListPtr;     { pointer to the last key on page     }
  422.  
  423.     KeysOnPage  : byte;           { the number of keys actually in the
  424.  
  425.                                     key list and on the page            }
  426.  
  427.     end;
  428.  
  429.  
  430.  
  431.   KeyList     = record
  432.  
  433.     NextKey,                      { these are the link pointers for the }
  434.  
  435.     PrevKey     : KeyListPtr;     { list of keys                        }
  436.  
  437.     LesserPage  : PagePtr;        { a pointer to a page on a lower level
  438.  
  439.                                     containing keys less than all keys
  440.  
  441.                                     on this page, if in memory          }
  442.  
  443.     LesserRec,                    { the disk record number of the page
  444.  
  445.                                     which goes into LesserPage          }
  446.  
  447.     Reference   : longint;        { the data reference associated with
  448.  
  449.                                     this key which usually is, but need
  450.  
  451.                                     not be, the record number of a record
  452.  
  453.                                     in a data file                      }
  454.  
  455.     Key         : MaxString;      { this is the key.  Although declared
  456.  
  457.                                     as a string of length 255, the actual
  458.  
  459.                                     space available is only as much as the
  460.  
  461.                                     keylength specified when making the
  462.  
  463.                                     file }
  464.  
  465.     end;
  466.  
  467.  
  468.  
  469. const
  470.  
  471.  
  472.  
  473.  
  474.  
  475.  
  476.  
  477.  
  478.  
  479.  
  480.  
  481.  
  482.  
  483.  
  484.   MaxPageMem  : word = 16384;     { Maximum memory which will be allo-
  485.  
  486.                                     cated for the page stack -- see above.
  487.  
  488.                                     This variable is dynamic, and can be
  489.  
  490.                                     adjusted by a calling program if need
  491.  
  492.                                     be.                                 }
  493.  
  494.   MinPageMem  : word = 2048;      { Minimum heap memory which MUST be
  495.  
  496.                                     available for the page stack. This
  497.  
  498.                                     amount should be at least equal to the
  499.  
  500.                                     amount of memory required to hold one
  501.  
  502.                                     page from each level of the tree plus
  503.  
  504.                                     one page, each with its full comple-
  505.  
  506.                                     ment of keys.                       }
  507.  
  508.  
  509.  
  510. var
  511.  
  512.   OK          : boolean;          { status variable, true if all went
  513.  
  514.                                     well, false otherwise.              }
  515.  
  516.   IOError     : integer;          { if an IO error occured, this variable
  517.  
  518.                                     will contain the error number, or -1
  519.  
  520.                                     if the error is due to lack of
  521.  
  522.                                     memory.                             }
  523.  
  524.  
  525.  
  526. procedure MakeFile (var DatF     : DataFile;
  527.  
  528.                         FileName : Str80;
  529.  
  530.                         RecLen   : word);
  531.  
  532.  
  533.  
  534. (*   This procedure creates a new data file named 'FileName' and having
  535.  
  536. a record length of 'RecLen.'   Note that 'RecLen' is declared as type
  537.  
  538. word, and thus the maximum record size allowed for a BTree4 data file
  539.  
  540. is 65535 bytes.  Because of possible inaccuracies in counting the size
  541.  
  542. of record variables it is recommended that programmers us the 'sizeof'
  543.  
  544. function to pass the record length.  The specified record length is
  545.  
  546. stored in the file header in record 0, and will always be used when the
  547.  
  548. file is opened.  The minimum record length is 16 bytes and if 'RecLen'
  549.  
  550. is less than this, a record length of 16 will be used.  If OK is false
  551.  
  552. on return, an IO error occured.  *)
  553.  
  554.  
  555.  
  556. procedure OpenFile (var DatF     : DataFile;
  557.  
  558.                         FileName : Str80);
  559.  
  560.  
  561.  
  562. (*   This procedure opens the fles specified by 'FileName' as a data file
  563.  
  564. and assigns the file to the variable 'DatF.'  Note that unlike the Data-
  565.  
  566. base Toolbox, no record length is passed, as the record length is fixed
  567.  
  568. when making the file, and is extracted when the file is opened.  If OK
  569.  
  570. is false on return, an IO error occured.  *)
  571.  
  572.  
  573.  
  574. procedure PutRec (var DatF   : DataFile;
  575.  
  576.                       RecNum : longint;
  577.  
  578.                   var Buffer            );
  579.  
  580.  
  581.  
  582. (*   This procedure takes 'RecLen' number of bytes from the variable
  583.  
  584. 'Buffer' and writes it to the file as record number 'RecNum.'  If
  585.  
  586. 'Buffer' is not large enough to fill the disk record, extra garbage
  587.  
  588. will also be written.  If OK is false on return, an IO error occured.  *)
  589.  
  590.  
  591.  
  592.  
  593.  
  594.  
  595.  
  596.  
  597.  
  598.  
  599.  
  600.  
  601.  
  602.  
  603.  
  604.  
  605. procedure AddRec (var DatF   : DataFile;
  606.  
  607.                   var RecNum : longint;
  608.  
  609.                   var Buffer          );
  610.  
  611.  
  612.  
  613. (*   This procedure will add a record to the file 'DatF' containing the
  614.  
  615. data from the variable 'Buffer.'  'RecNum' will return the number of the
  616.  
  617. record added.  The new record may be at the end of the file, but need not
  618.  
  619. be.  As records are deleted from the file they are not physically removed
  620.  
  621. byt are simply put in a list of available records, and when a new record
  622.  
  623. is needed the most recently deleted record is used.  The free list is
  624.  
  625. maintained by a linked list which uses the first four bytes of each
  626.  
  627. deleted file record.  It is recommended that these four bytes be reserved
  628.  
  629. specifically for this use, so that a non-zero number in this position
  630.  
  631. would indicate a free record, and a zero value would indicate a record in
  632.  
  633. use.  This is useful both in "packing" a data file, and in re-creating
  634.  
  635. an index file.  If OK is false upon return an IO error occured.  *)
  636.  
  637.  
  638.  
  639. procedure GetRec (var DatF   : DataFile;
  640.  
  641.                       RecNum : longint;
  642.  
  643.                   var Buffer            );
  644.  
  645.  
  646.  
  647. (*   This procedure reads the record number RecNum from the previously
  648.  
  649. opened file DatF and places it into 'Buffer.'  It is the programmer's
  650.  
  651. responsibility to insure that the variable passed as 'Buffer' is long
  652.  
  653. enough to hold all the data, otherwise the procedure will possibly over-
  654.  
  655. write other variables.   If OK is false upon return, an IO error occured.
  656.  
  657. *)
  658.  
  659.  
  660.  
  661. procedure DeleteRec (var DatF   : DataFile;
  662.  
  663.                          RecNum : longint);
  664.  
  665.  
  666.  
  667. (*   This procedure places the record specified by 'RecNum' on the list
  668.  
  669. of available records, and fills the first four bytes of the record with
  670.  
  671. $FFFFFFFF.  The next time a new record is added to the file, one of the
  672.  
  673. from the available list will be used, and overwritten.  If OK is false
  674.  
  675. upon return, an IO error has occurred.  *)
  676.  
  677.  
  678.  
  679. procedure CloseFile (var DatF : DataFile);
  680.  
  681.  
  682.  
  683. (*   This procedure updates the file header information and closes the
  684.  
  685. file.  The file is closed even if an IO error occured while trying to
  686.  
  687. save the header information.  The information remains, of course, in the
  688.  
  689. file variable, until it is re-used, and may be extracted by an error
  690.  
  691. handling routine.  If OK is false upon return, an IO error occured.  *)
  692.  
  693.  
  694.  
  695. function FileLen (var DatF : DataFile) : longint;
  696.  
  697.  
  698.  
  699. (*   Similar to the Database Toolbox, this function returns the number of
  700.  
  701. records in DatF, both used and available.  This function is equivilent to
  702.  
  703. "FileSize (DatF.F)" which can be used alternatively with less overhead.
  704.  
  705. *)
  706.  
  707.  
  708.  
  709. function UsedRecs (var DatF : DataFile) : longint;
  710.  
  711.  
  712.  
  713.  
  714.  
  715.  
  716.  
  717.  
  718.  
  719.  
  720.  
  721.  
  722.  
  723.  
  724.  
  725.  
  726. (*   Included primarily for compatability with the Database Toolbox, this
  727.  
  728. function returns the number of used (non-available) records in the file.
  729.  
  730. It is functionally equivilent to "FileSize (DatF.F) - DatF.NumberFree."
  731.  
  732. *)
  733.  
  734.  
  735.  
  736. procedure MakeIndex (var IdxF         : IndexFile;
  737.  
  738.                          FileName     : Str80;
  739.  
  740.                          KeyLength,
  741.  
  742.                          KeysPerPage  : byte);
  743.  
  744.  
  745.  
  746. (*   This procedure will create a new index file named 'FileName.'  It is
  747.  
  748. similar to the procedure MakeFile, but instead of specifying the record
  749.  
  750. length the programmer specifies the maximum length of a key ('KeyLength')
  751.  
  752. and the maximum number of keys that can be placed on one page.  This
  753.  
  754. information is used to calculate the record length which is
  755.  
  756. 5 + (KeysPerPage * (KeyLength + 9)).  In addition to calculating the
  757.  
  758. record length, this procedure initializes other data necessary to use
  759.  
  760. as an index file.  Note that unlike the Database Toolbox it is not neces-
  761.  
  762. sary to indicate if duplicate keys are allowed, as duplicate keys are
  763.  
  764. always allowed in BTree4. If OK is false upon return, an IO error occured.
  765.  
  766. *)
  767.  
  768.  
  769.  
  770. procedure OpenIndex (var IdxF     : IndexFile;
  771.  
  772.                          FileName : Str80);
  773.  
  774.  
  775.  
  776. (*   This procedure opens the index specified by 'FileName' and initial-
  777.  
  778. izes certain necessary data elements.  Note than information about the
  779.  
  780. keys is not required as this information has been saved in the header
  781.  
  782. in record 0.  *)
  783.  
  784.  
  785.  
  786. procedure CheckMem (Needed : word);
  787.  
  788.  
  789.  
  790. (*   This procedure checks the amount of memory on the heap used by the
  791.  
  792. page stack, and if it is greater than that specified in the global vari-
  793.  
  794. able 'MaxPageMem' plus that specified by 'Needed', little used pages, and
  795.  
  796. their children, are removed from memory.  If the amount needed does not
  797.  
  798. exceed 'MaxPageSize', but does exceed the maximum available memory, little
  799.  
  800. used pages will be removed, until the amount needed is available, or until
  801.  
  802. the stack size reaches 'MinPageMem'.  If the amount of memory needed
  803.  
  804. cannot be made available, OK will be set to false, and IOError will be set
  805.  
  806. to -1.   *)
  807.  
  808.  
  809.  
  810. procedure AddKey (var IdxF     : IndexFile;
  811.  
  812.                   var RefAdded : longint;
  813.  
  814.                       KeyAdded : MaxString);
  815.  
  816.  
  817.  
  818. (*   This procedure places the key passed as 'KeyAdded' into the index
  819.  
  820. tree at the proper place in order.  If the length of the key passed is
  821.  
  822. greater than that allowed for the index file, the key passed will be
  823.  
  824. truncated.  The procedure gives no warning if a duplicate key is added,
  825.  
  826. as duplicate keys are always allowed.  If the data reference is the
  827.  
  828. same for both keys, the second one is not added, otherwise it is.  If
  829.  
  830. you want to eliminate duplicate keys you must use the FindKey procedure
  831.  
  832. before adding a key.  If OK is false upon return, an IO error has occured.
  833.  
  834.  
  835.  
  836.  
  837.  
  838.  
  839.  
  840.  
  841.  
  842.  
  843.  
  844.  
  845.  
  846.  
  847. *)
  848.  
  849.  
  850.  
  851. procedure FindKey (var IdxF      : IndexFile;
  852.  
  853.                    var RefFound  : longint;
  854.  
  855.                        KeySought : MaxString);
  856.  
  857.  
  858.  
  859. (*   This procedure searches the index file for the FIRST occurance of
  860.  
  861. the key sought.  If the length of the key passed is greater than that
  862.  
  863. allowed for the index file, the key passed will be truncated.  If the
  864.  
  865. key is found OK will be true upon return.  If OK is false and IOError
  866.  
  867. is not zero then an IO error has occured.  *)
  868.  
  869.  
  870.  
  871. procedure SearchKey (var IdxF      : IndexFile;
  872.  
  873.                      var RefFound  : longint;
  874.  
  875.                      var KeySought : MaxString);
  876.  
  877.  
  878.  
  879. (*   Similar to FindKey, this procedure searches the index file for the
  880.  
  881. first key which is equal to OR greater than 'KeySought.'  'KeySought'
  882.  
  883. will return the value of the key found, and RefFound will return its
  884.  
  885. reference.  If upon return OK is false and IOError is zero then there
  886.  
  887. are no keys in the index file greater than or equal to the key sought. *)
  888.  
  889.  
  890.  
  891. procedure NextKey (var IdxF      : IndexFile;
  892.  
  893.                    var RefFound  : longint;
  894.  
  895.                    var KeySought : MaxString);
  896.  
  897.  
  898.  
  899. (*   This procedure will find the next key in the file after a call to
  900.  
  901. any of the search procedures.  This procedure is used to perform a
  902.  
  903. sequential search of index file.  To set the file to the beginning,
  904.  
  905. use the procedure ClearKey.  After adding a record, a call to NextKey
  906.  
  907. will find the key immediately after the key added.  'KeySought' will
  908.  
  909. return the value of the key found, and RefFound will return its refer-
  910.  
  911. ence.  If upon return OK is false but IOError is zero the end of the
  912.  
  913. file has been reached.  Another call to NextKey at this point will
  914.  
  915. return the first key in the index.  *)
  916.  
  917.  
  918.  
  919. procedure PrevKey (var IdxF      : IndexFile;
  920.  
  921.                    var RefFound  : longint;
  922.  
  923.                    var KeySought : MaxString);
  924.  
  925.  
  926.  
  927. (*   This procedure will find the key in the index file which is previous
  928.  
  929. in order to the key last referenced.  This procedure is used to perform
  930.  
  931. a reverse sequential search on the file.  To set the file to the end of
  932.  
  933. the index use the the procedure ClearKey.  After adding a record, a call
  934.  
  935. to PrevKey will find the key immediately prior to the key added.
  936.  
  937. 'KeySought' will return the value of the key found, and RefFound will
  938.  
  939. return its reference.  If upon return OK is false but IOError is zero,
  940.  
  941. the beginning of the file has been reached.  Another call to PrevKey at
  942.  
  943. this point will return the last key in the index.  *)
  944.  
  945.  
  946.  
  947. procedure ClearKey (var IdxF : IndexFile);
  948.  
  949.  
  950.  
  951. (*   This procedure sets the current index file position to the beginning
  952.  
  953. (or end) of the index file.  After calling clear key a call to NextKey
  954.  
  955.  
  956.  
  957.  
  958.  
  959.  
  960.  
  961.  
  962.  
  963.  
  964.  
  965.  
  966.  
  967.  
  968. will return the first key in the index, and a call to PrevKey will return
  969.  
  970. the last key in the index.  *)
  971.  
  972.  
  973.  
  974. procedure DeleteKey (var IdxF    : IndexFile;
  975.  
  976.                          DataRef : longint;
  977.  
  978.                          Key     : MaxString);
  979.  
  980.  
  981.  
  982. (*     This procedure removes a key from the index file, if it matches
  983.  
  984. 'Key' AND 'DataRef'.  The double check is required because duplicate keys
  985.  
  986. may exist in the index file, but not duplicate keys with the same data
  987.  
  988. reference.  If the deletion of a key causes a page to have fewer than
  989.  
  990. 'KeysPerPage' divided by two keys on the page, the page will be merged
  991.  
  992. with a sibling.  If all keys are removed from the entire indexfile it
  993.  
  994. will not be deleted, but will exist with only the header record.  *)
  995.  
  996.  
  997.  
  998. procedure CloseIndex (var IdxF : IndexFile);
  999.  
  1000.  
  1001.  
  1002. (*   This procedure will update the header information and close the
  1003.  
  1004. index file specified.  In addition, all pages currently in memory which
  1005.  
  1006. were read from this file are purged and the memory is returned to the
  1007.  
  1008. heap.  Like CloseFile, the file is closed even if the header information
  1009.  
  1010. was not successfully saved, and an examination of the File variable will
  1011.  
  1012. be necessary to save the information.  *)
  1013.  
  1014.  
  1015.  
  1016. procedure Unlink (var Link;
  1017.  
  1018.                   var Head;
  1019.  
  1020.                   var Tail);
  1021.  
  1022.  
  1023.  
  1024. (*   This procedure is a special bonus.  Unlink is used to maintain double
  1025.  
  1026. linked lists of records on the heap, where the first four bytes of the
  1027.  
  1028. record is a pointer to the next record, and the next four bytes is a
  1029.  
  1030. pointer to the previous record.  The three parameters passed MUST be
  1031.  
  1032. pointer types; 'Link' is a pointer to the record to be unlinked; 'Head'
  1033.  
  1034. is the pointer to the head end of the linked list; and 'Tail' is the
  1035.  
  1036. pointer to the tail end of the list.  Calling Unlink removes the record
  1037.  
  1038. pointed to by 'Link' from the linked list, re-establishing all links,
  1039.  
  1040. and updating the head pointer or tail pointer if necessary.  None of
  1041.  
  1042. the pointers in 'Link^' are affected.  *)
  1043.  
  1044.  
  1045.  
  1046.  
  1047.  
  1048.      BTree4 is  shareware, which  means that it, like most shareware, may be
  1049.  
  1050. freely copied and distributed so long  as no  consideration is  required for
  1051.  
  1052. its distribution,  except a  copying and  media charge  not to exceed $3.00,
  1053.  
  1054. including the cost of the means of distribution (i.e., diskette).  Users who
  1055.  
  1056. find the  program of  value to  them should  consider sending  a donation to
  1057.  
  1058. Pass-Key Software.
  1059.  
  1060.  
  1061.  
  1062.      Users sending a donation of $25.00 or more are registered, will receive
  1063.  
  1064. notification of upgrades and modifications to this product, and are entitled
  1065.  
  1066. to receive source code and future updates, upon request, for  the cost  of a
  1067.  
  1068. diskette and  postage.   Non-registered useres may not incorporate this unit
  1069.  
  1070. into  any  commercially  distributed  software,  including  shareware, while
  1071.  
  1072. registered users may do so freely.
  1073.  
  1074.  
  1075.  
  1076.  
  1077.  
  1078.  
  1079.  
  1080.  
  1081.  
  1082.  
  1083.  
  1084.  
  1085.  
  1086.  
  1087.  
  1088.  
  1089.      BTree4 is  a copyrighted  program, and  is protected by the laws of the
  1090.  
  1091. United States and each of its several states.  A  licence is  hereby granted
  1092.  
  1093. to all  persons to  use this program according to the terms and restrictions
  1094.  
  1095. contained herein.  All programs which  incorporate all  or any  part of this
  1096.  
  1097. program must include the following phrase both in the source code and in any
  1098.  
  1099. accompanying documentation:
  1100.  
  1101.  
  1102.  
  1103.      Portions of this program Copyright (c) 1988 by W. Lee Passey.
  1104.  
  1105.  
  1106.  
  1107.      This program is distributed as is, and by its use each person agrees to
  1108.  
  1109. the  terms  and  conditions  of  this  license, and acknowledges that W. Lee
  1110.  
  1111. Passey and Pass-Key Software have  made  no  warranties,  either  express or
  1112.  
  1113. implied,  concerning  the  performance  of  this software, including that of
  1114.  
  1115. fitness for a particular purpose.
  1116.  
  1117.  
  1118.  
  1119.      Please send all comments,  suggestions, information  regarding possible
  1120.  
  1121. bugs, donations and registration information to:
  1122.  
  1123.  
  1124.  
  1125.                              Pass-Key Software
  1126.  
  1127.                             119 MacArthur Ave.
  1128.  
  1129.                          Salt Lake City, UT  84115
  1130.  
  1131.  
  1132.  
  1133. or use  your modem  to call The Motherboard, (801) 485-7211, 8 data, 1 stop,
  1134.  
  1135. no parity, 300/1200/2400 baud, 24 hours/day, 7 days/week.
  1136.  
  1137.  
  1138.  
  1139.      I am also looking for a job in the data processing field, and this unit
  1140.  
  1141. is a good example of my programming skills.  If any employers are interested
  1142.  
  1143. in using me as an employee, please contact me in the same way.
  1144.  
  1145.  
  1146.  
  1147.  
  1148.  
  1149.  
  1150.  
  1151.  
  1152.  
  1153.  
  1154.  
  1155.  
  1156.  
  1157.  
  1158.  
  1159.  
  1160.  
  1161.  
  1162.  
  1163.  
  1164.  
  1165.  
  1166.  
  1167.  
  1168.  
  1169.  
  1170.  
  1171.  
  1172.  
  1173.  
  1174.  
  1175.  
  1176.  
  1177.  
  1178.  
  1179.