home *** CD-ROM | disk | FTP | other *** search
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- BTREE4
-
- a Shareware Unit for Turbo Pascal ver. 4.0
-
- for Data and Index file management
-
-
- Copyright (c) 1988 by W. Lee Passey
-
-
-
-
-
-
-
-
-
-
-
- Pass-Key Software
- 119 MacArthur Ave.
- Salt Lake City, UT 84115
- (801) 486-9239 (voice)
- (801) 485-7211 (data)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- BTree4 is a separately compiled unit for Turbo Pascal ver. 4.0 from
- Borland International, Inc. BTree4 may be linked to a user's source pro-
- grams, and will performs all of the same B-tree indexing functions as
- Borland's Database Toolbox.
-
- This file contains general information about BTree4, an annotated copy
- of the interface segment describing all variables and procedures available
- to calling procedures, and licensing and registration information. PLEASE
- READ THIS FILE COMPLETELY BEFORE ATTEMPTING TO USE BTREE4.
-
- BTree4 has been designed to be as compatible as possible with Borland's
- Database Toolbox, but it is not a modification of Borland's source code;
- rather it is a whole new set of procedures and functions using a compatible
- calling interface, but a wholly different memory storage technique. BTree4
- does not require any pre-defined constants or initializaton sequence, as all
- data storage, including the index page stack, is created as needed on the
- heap.
-
- For maximum flexibility, the BTree4 routines will not halt the program
- for any IO or heap full errors. If an error is detected, the global boolean
- variable 'OK' is set to false, and the global integer variable 'IOError' is
- set equal to the IO error code. If the error was caused by the unavail-
- ability of heap memory, 'IOError' will be set to -1.
-
- Disk IO errors must be resolved by the programmer, however memory
- allocation errors can usually be resolved by the use of the procedure
- 'CheckMem' in conjunction with the global variable 'MaxPageMem.'
- 'MaxPageMem' should be set by the programmer to the maximum amount of heap
- memory which will be allocated for the index page stack. If the page stack
- attempts to exceed this amount of allocated memory, little used pages will
- be discarded from memory until the page stack is again under the limit. The
- program expects that the amount of memory available will never be less than
- the value stored in 'MinPageMem', and the stack size will never be decreased
- to less than that value; thus, 'MaxPageMem' should always be larger than
- 'MinPageMem.'
-
- Both 'MaxPageMem' and 'MinPageMem' can be dynamically assigned values
- at any time during the operation of the program. If more dynamic memory is
- needed, the page stack can be reduced in size by reducing the value of
- 'MaxPageMem' (and 'MinPageMem', if necessary) and then calling CheckMem with
- a zero parameter. The only restriction is that 'MinPageMem' must always be
- large enough to hold one page from each level of the tree, plus one extra
- page.
-
- In addition to the page stack, each open data file and index file
- allocates for itself an IO buffer equal in size to the file's record length,
- and each index file allocates an extra page buffer which is the same size.
- These buffers are de-allocated only by closing the associated file. The
- record length for index files is equal to 5 + (number of keys per page X
- (key length + 9)).
-
- What follows is a copy of the BTree4 interface section, with each
- procedure and significant variable annotated as to its function and use.
-
-
-
-
-
-
-
-
-
-
-
-
-
- {$I-,V-}
-
- unit btree4; { VERSION 1.0 }
- { Copyright (c) 1988 by W. Lee Passey }
- interface
-
- type
- MaxString = string[255];
- bufarray = array [1..80] of byte;
- Str80 = string[80];
-
- PagePtr = ^PageHeader;
- KeyListPtr = ^KeyList;
-
- DataFile = record
- case byte of
- 0 : (F : file);
- 1 : (Handle,
- Mode,
- RecSize : word;
- Private : array [1..26] of byte; { reserved by TP4 }
- FirstFree, { the first available record in the file }
- NumberFree : longint; { the number of records deleted and
- therefore available for use }
- RecLength : word; { the length of records in this file }
- KeysPerPage, { if an index file, the maximum number
- of keys which may be put on a page }
- KeyLength : byte; { if an index file, the maximum
- length of a key }
- FirstPage : longint; { if an index file, the number of the
- record which is the root page }
- FileName : array [1..80] of char;
- Buffer : ^BufArray);{ pointer to a buffer on the heap,
- used with this file, whose size is
- identical to the record length }
- end;
-
- IndexFile = record
- DF : DataFile;
- RootPage : PagePtr; { a pointer to the root page, if it
- is in memory }
- KeySize, { the size of a key record, on the
- heap, for keys in this file }
- ItemSize : word; { the size of a key, its reference
- and record pointer, in this file }
- SavePage : PagePtr;
- SaveKey : KeyListPtr;
- SaveRec : longint;
- PageBuffer: ^BufArray; { pointer to a buffer on the heap,
- used with this file, whose size is
- identical to the record length, and
- which is used for packing and
- unpacking pages to and from the disk
-
-
-
-
-
-
-
-
-
-
-
-
- and memory. }
- end;
-
- (* Like Borland's Database Toolbook, each file use by BTree4 must be
- declared either as a DataFile or an IndexFile. *)
-
- PageHeader = record
- NextPage, { these two pointers link the pages }
- PrevPage, { into a two-way linked list in memory
- each time a page is used it is placed
- back at the head of this list }
- ParentPage, { a pointer to this page's parent page
- which should be in memory }
- GreaterPage : PagePtr; { a pointer to a page on a lower level
- containing keys greater than all
- keys on this page, if in memory }
- GreaterRec, { the disk record number of the page
- which goes in GreaterPage }
- RecNum : longint; { the disk record number of this page }
- FilePtr : ^IndexFile; { points to the file variable of the
- file which this page comes from }
- ParentKey, { the key record from the parent page
- which contains the key which is one
- greater than all the keys on this
- page. if this pointer is nil, you
- must go up another page; if this is
- not possible you are in the root
- page. }
- KeyList, { pointer to the first key on page }
- ListEnd : KeyListPtr; { pointer to the last key on page }
- KeysOnPage : byte; { the number of keys actually in the
- key list and on the page }
- end;
-
- KeyList = record
- NextKey, { these are the link pointers for the }
- PrevKey : KeyListPtr; { list of keys }
- LesserPage : PagePtr; { a pointer to a page on a lower level
- containing keys less than all keys
- on this page, if in memory }
- LesserRec, { the disk record number of the page
- which goes into LesserPage }
- Reference : longint; { the data reference associated with
- this key which usually is, but need
- not be, the record number of a record
- in a data file }
- Key : MaxString; { this is the key. Although declared
- as a string of length 255, the actual
- space available is only as much as the
- keylength specified when making the
- file }
- end;
-
- const
-
-
-
-
-
-
-
-
-
-
-
-
- MaxPageMem : word = 16384; { Maximum memory which will be allo-
- cated for the page stack -- see above.
- This variable is dynamic, and can be
- adjusted by a calling program if need
- be. }
- MinPageMem : word = 2048; { Minimum heap memory which MUST be
- available for the page stack. This
- amount should be at least equal to the
- amount of memory required to hold one
- page from each level of the tree plus
- one page, each with its full comple-
- ment of keys. }
-
- var
- OK : boolean; { status variable, true if all went
- well, false otherwise. }
- IOError : integer; { if an IO error occured, this variable
- will contain the error number, or -1
- if the error is due to lack of
- memory. }
-
- procedure MakeFile (var DatF : DataFile;
- FileName : Str80;
- RecLen : word);
-
- (* This procedure creates a new data file named 'FileName' and having
- a record length of 'RecLen.' Note that 'RecLen' is declared as type
- word, and thus the maximum record size allowed for a BTree4 data file
- is 65535 bytes. Because of possible inaccuracies in counting the size
- of record variables it is recommended that programmers us the 'sizeof'
- function to pass the record length. The specified record length is
- stored in the file header in record 0, and will always be used when the
- file is opened. The minimum record length is 16 bytes and if 'RecLen'
- is less than this, a record length of 16 will be used. If OK is false
- on return, an IO error occured. *)
-
- procedure OpenFile (var DatF : DataFile;
- FileName : Str80);
-
- (* This procedure opens the fles specified by 'FileName' as a data file
- and assigns the file to the variable 'DatF.' Note that unlike the Data-
- base Toolbox, no record length is passed, as the record length is fixed
- when making the file, and is extracted when the file is opened. If OK
- is false on return, an IO error occured. *)
-
- procedure PutRec (var DatF : DataFile;
- RecNum : longint;
- var Buffer );
-
- (* This procedure takes 'RecLen' number of bytes from the variable
- 'Buffer' and writes it to the file as record number 'RecNum.' If
- 'Buffer' is not large enough to fill the disk record, extra garbage
- will also be written. If OK is false on return, an IO error occured. *)
-
-
-
-
-
-
-
-
-
-
-
-
-
- procedure AddRec (var DatF : DataFile;
- var RecNum : longint;
- var Buffer );
-
- (* This procedure will add a record to the file 'DatF' containing the
- data from the variable 'Buffer.' 'RecNum' will return the number of the
- record added. The new record may be at the end of the file, but need not
- be. As records are deleted from the file they are not physically removed
- byt are simply put in a list of available records, and when a new record
- is needed the most recently deleted record is used. The free list is
- maintained by a linked list which uses the first four bytes of each
- deleted file record. It is recommended that these four bytes be reserved
- specifically for this use, so that a non-zero number in this position
- would indicate a free record, and a zero value would indicate a record in
- use. This is useful both in "packing" a data file, and in re-creating
- an index file. If OK is false upon return an IO error occured. *)
-
- procedure GetRec (var DatF : DataFile;
- RecNum : longint;
- var Buffer );
-
- (* This procedure reads the record number RecNum from the previously
- opened file DatF and places it into 'Buffer.' It is the programmer's
- responsibility to insure that the variable passed as 'Buffer' is long
- enough to hold all the data, otherwise the procedure will possibly over-
- write other variables. If OK is false upon return, an IO error occured.
- *)
-
- procedure DeleteRec (var DatF : DataFile;
- RecNum : longint);
-
- (* This procedure places the record specified by 'RecNum' on the list
- of available records, and fills the first four bytes of the record with
- $FFFFFFFF. The next time a new record is added to the file, one of the
- from the available list will be used, and overwritten. If OK is false
- upon return, an IO error has occurred. *)
-
- procedure CloseFile (var DatF : DataFile);
-
- (* This procedure updates the file header information and closes the
- file. The file is closed even if an IO error occured while trying to
- save the header information. The information remains, of course, in the
- file variable, until it is re-used, and may be extracted by an error
- handling routine. If OK is false upon return, an IO error occured. *)
-
- function FileLen (var DatF : DataFile) : longint;
-
- (* Similar to the Database Toolbox, this function returns the number of
- records in DatF, both used and available. This function is equivilent to
- "FileSize (DatF.F)" which can be used alternatively with less overhead.
- *)
-
- function UsedRecs (var DatF : DataFile) : longint;
-
-
-
-
-
-
-
-
-
-
-
-
-
- (* Included primarily for compatability with the Database Toolbox, this
- function returns the number of used (non-available) records in the file.
- It is functionally equivilent to "FileSize (DatF.F) - DatF.NumberFree."
- *)
-
- procedure MakeIndex (var IdxF : IndexFile;
- FileName : Str80;
- KeyLength,
- KeysPerPage : byte);
-
- (* This procedure will create a new index file named 'FileName.' It is
- similar to the procedure MakeFile, but instead of specifying the record
- length the programmer specifies the maximum length of a key ('KeyLength')
- and the maximum number of keys that can be placed on one page. This
- information is used to calculate the record length which is
- 5 + (KeysPerPage * (KeyLength + 9)). In addition to calculating the
- record length, this procedure initializes other data necessary to use
- as an index file. Note that unlike the Database Toolbox it is not neces-
- sary to indicate if duplicate keys are allowed, as duplicate keys are
- always allowed in BTree4. If OK is false upon return, an IO error occured.
- *)
-
- procedure OpenIndex (var IdxF : IndexFile;
- FileName : Str80);
-
- (* This procedure opens the index specified by 'FileName' and initial-
- izes certain necessary data elements. Note than information about the
- keys is not required as this information has been saved in the header
- in record 0. *)
-
- procedure CheckMem (Needed : word);
-
- (* This procedure checks the amount of memory on the heap used by the
- page stack, and if it is greater than that specified in the global vari-
- able 'MaxPageMem' plus that specified by 'Needed', little used pages, and
- their children, are removed from memory. If the amount needed does not
- exceed 'MaxPageSize', but does exceed the maximum available memory, little
- used pages will be removed, until the amount needed is available, or until
- the stack size reaches 'MinPageMem'. If the amount of memory needed
- cannot be made available, OK will be set to false, and IOError will be set
- to -1. *)
-
- procedure AddKey (var IdxF : IndexFile;
- var RefAdded : longint;
- KeyAdded : MaxString);
-
- (* This procedure places the key passed as 'KeyAdded' into the index
- tree at the proper place in order. If the length of the key passed is
- greater than that allowed for the index file, the key passed will be
- truncated. The procedure gives no warning if a duplicate key is added,
- as duplicate keys are always allowed. If the data reference is the
- same for both keys, the second one is not added, otherwise it is. If
- you want to eliminate duplicate keys you must use the FindKey procedure
- before adding a key. If OK is false upon return, an IO error has occured.
-
-
-
-
-
-
-
-
-
-
-
-
- *)
-
- procedure FindKey (var IdxF : IndexFile;
- var RefFound : longint;
- KeySought : MaxString);
-
- (* This procedure searches the index file for the FIRST occurance of
- the key sought. If the length of the key passed is greater than that
- allowed for the index file, the key passed will be truncated. If the
- key is found OK will be true upon return. If OK is false and IOError
- is not zero then an IO error has occured. *)
-
- procedure SearchKey (var IdxF : IndexFile;
- var RefFound : longint;
- var KeySought : MaxString);
-
- (* Similar to FindKey, this procedure searches the index file for the
- first key which is equal to OR greater than 'KeySought.' 'KeySought'
- will return the value of the key found, and RefFound will return its
- reference. If upon return OK is false and IOError is zero then there
- are no keys in the index file greater than or equal to the key sought. *)
-
- procedure NextKey (var IdxF : IndexFile;
- var RefFound : longint;
- var KeySought : MaxString);
-
- (* This procedure will find the next key in the file after a call to
- any of the search procedures. This procedure is used to perform a
- sequential search of index file. To set the file to the beginning,
- use the procedure ClearKey. After adding a record, a call to NextKey
- will find the key immediately after the key added. 'KeySought' will
- return the value of the key found, and RefFound will return its refer-
- ence. If upon return OK is false but IOError is zero the end of the
- file has been reached. Another call to NextKey at this point will
- return the first key in the index. *)
-
- procedure PrevKey (var IdxF : IndexFile;
- var RefFound : longint;
- var KeySought : MaxString);
-
- (* This procedure will find the key in the index file which is previous
- in order to the key last referenced. This procedure is used to perform
- a reverse sequential search on the file. To set the file to the end of
- the index use the the procedure ClearKey. After adding a record, a call
- to PrevKey will find the key immediately prior to the key added.
- 'KeySought' will return the value of the key found, and RefFound will
- return its reference. If upon return OK is false but IOError is zero,
- the beginning of the file has been reached. Another call to PrevKey at
- this point will return the last key in the index. *)
-
- procedure ClearKey (var IdxF : IndexFile);
-
- (* This procedure sets the current index file position to the beginning
- (or end) of the index file. After calling clear key a call to NextKey
-
-
-
-
-
-
-
-
-
-
-
-
- will return the first key in the index, and a call to PrevKey will return
- the last key in the index. *)
-
- procedure DeleteKey (var IdxF : IndexFile;
- DataRef : longint;
- Key : MaxString);
-
- (* This procedure removes a key from the index file, if it matches
- 'Key' AND 'DataRef'. The double check is required because duplicate keys
- may exist in the index file, but not duplicate keys with the same data
- reference. If the deletion of a key causes a page to have fewer than
- 'KeysPerPage' divided by two keys on the page, the page will be merged
- with a sibling. If all keys are removed from the entire indexfile it
- will not be deleted, but will exist with only the header record. *)
-
- procedure CloseIndex (var IdxF : IndexFile);
-
- (* This procedure will update the header information and close the
- index file specified. In addition, all pages currently in memory which
- were read from this file are purged and the memory is returned to the
- heap. Like CloseFile, the file is closed even if the header information
- was not successfully saved, and an examination of the File variable will
- be necessary to save the information. *)
-
- procedure Unlink (var Link;
- var Head;
- var Tail);
-
- (* This procedure is a special bonus. Unlink is used to maintain double
- linked lists of records on the heap, where the first four bytes of the
- record is a pointer to the next record, and the next four bytes is a
- pointer to the previous record. The three parameters passed MUST be
- pointer types; 'Link' is a pointer to the record to be unlinked; 'Head'
- is the pointer to the head end of the linked list; and 'Tail' is the
- pointer to the tail end of the list. Calling Unlink removes the record
- pointed to by 'Link' from the linked list, re-establishing all links,
- and updating the head pointer or tail pointer if necessary. None of
- the pointers in 'Link^' are affected. *)
-
-
- BTree4 is shareware, which means that it, like most shareware, may be
- freely copied and distributed so long as no consideration is required for
- its distribution, except a copying and media charge not to exceed $3.00,
- including the cost of the means of distribution (i.e., diskette). Users who
- find the program of value to them should consider sending a donation to
- Pass-Key Software.
-
- Users sending a donation of $25.00 or more are registered, will receive
- notification of upgrades and modifications to this product, and are entitled
- to receive source code and future updates, upon request, for the cost of a
- diskette and postage. Non-registered useres may not incorporate this unit
- into any commercially distributed software, including shareware, while
- registered users may do so freely.
-
-
-
-
-
-
-
-
-
-
-
-
-
- BTree4 is a copyrighted program, and is protected by the laws of the
- United States and each of its several states. A licence is hereby granted
- to all persons to use this program according to the terms and restrictions
- contained herein. All programs which incorporate all or any part of this
- program must include the following phrase both in the source code and in any
- accompanying documentation:
-
- Portions of this program Copyright (c) 1988 by W. Lee Passey.
-
- This program is distributed as is, and by its use each person agrees to
- the terms and conditions of this license, and acknowledges that W. Lee
- Passey and Pass-Key Software have made no warranties, either express or
- implied, concerning the performance of this software, including that of
- fitness for a particular purpose.
-
- Please send all comments, suggestions, information regarding possible
- bugs, donations and registration information to:
-
- Pass-Key Software
- 119 MacArthur Ave.
- Salt Lake City, UT 84115
-
- or use your modem to call The Motherboard, (801) 485-7211, 8 data, 1 stop,
- no parity, 300/1200/2400 baud, 24 hours/day, 7 days/week.
-
- I am also looking for a job in the data processing field, and this unit
- is a good example of my programming skills. If any employers are interested
- in using me as an employee, please contact me in the same way.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-