home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / progm / disam.zip / DSMLOGIC.DOC < prev    next >
Text File  |  1990-04-20  |  35KB  |  824 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14.  
  15.  
  16.                                  DISAM 3 LOGIC
  17.  
  18.  
  19.                                   Version 3.5
  20.  
  21.  
  22.                                  Apr. 20, 1990
  23.  
  24.  
  25.                                   Written by:
  26.                                  Robert Pearce
  27.                                 2325 W. Cabana
  28.                                 Mesa, AZ. 85202
  29.                                 (602) 835-9189
  30.  
  31.  
  32.  
  33.           FILE CONTROL BLOCKS
  34.  
  35.                 When a DISAM file is defined, the file is composed of
  36.           three basic blocks. 1)Control block,  2)Index block, and
  37.           3)Data block.
  38.  
  39.  
  40.                               CONTROL BLOCK
  41.  
  42.  
  43.                 The control block is 128 bytes long and is used to
  44.           track some of the statistical data about the file's perfor-
  45.           mance and to hold the address constants (ADCONS) of the
  46.           buffers since more than one file can be accessed at a time.
  47.           See DSMADCON.DEF for the specific fields defined. Some are
  48.           defined here.
  49.  
  50.           offset label value (all values are in decimal)
  51.           000    CBS   128    Control Block Size
  52.           002    IBS   U/D    Index Block Size  Min size=(FKL+4)*4+8
  53.           004    DBS   U/D    Data Block Size   n*IBS
  54.           006    FKL   U/D    File Key Length (user defined)
  55.           008    FKO   U/D    File Key Offset (user defined)
  56.           010    NFB   0      Next File Block (to be assigned)
  57.           012    IRC   0      Index Record Counter
  58.           014    DRC   0      Data Record Counter
  59.           016    ISC   0      Index Split Counter
  60.           018    DSC   0      Data Split Counter
  61.           020    FS1   0      File Status Flag1           EQU
  62.                  FOF   00000001B  File Open Flag           01
  63.                  FUF   00000010B  File Update Flag         02
  64.                  IUF   00000100B  Immed Update Flag        04
  65.                  QBOF  00001000B  Quick-BASIC Open Flag    08
  66.           021    FS2   0      File Status Flag2
  67.                  FSO   00000001B  File Share Option        01
  68.                  SIF   00000010B  Secondary Index Flag     02
  69.           022    PFS   0      Percent Load Free Space
  70.           024    SIKL  0      Secondary Index Key Length
  71.           026    SIKO  0      Secondary Index Key Offset
  72.           028    HANDLE0      DISAM File Handle
  73.  
  74.           The following are address constants for file buffers
  75.  
  76.           030    IBA   0      Index Buffer Address
  77.           032    IFSA  0      Index Free Space Address
  78.           034    INBA  0      Index Next Block Address
  79.           036    DBA   0      Data Buffer Address
  80.           038    DFSA  0      Data Free Space Address
  81.           040    DNBA  0      Data Next Block Address
  82.  
  83.           The following ADCONS point file records.
  84.  
  85.           042    CIRA  0      Current Index Record Address
  86.           044    NIRA  0      Next Index Record Address
  87.           046    CDRA  0      Current Data Record Address
  88.           048    NDRA  0      Next Data Record Address
  89.  
  90.           The following ADCONS point file blocks.
  91.  
  92.           050    CIBN  0      Current Index Block Number
  93.           052    NIBN  0      Next Index Block Number
  94.           054    CDBN  0      Current Data Block Number
  95.           056    NDBN  0      Next Data Block Number
  96.  
  97.           The following locations are used during a block split
  98.  
  99.           058    SRL   0      Save Record Length
  100.           050    CBN   0      Changed Block Number
  101.           062    UBUFA 0      User Buffer Address
  102.  
  103.           The following ADCONS point secondary index records.
  104.  
  105.           064    CSIRA 0      Current Secondary Index Record Address
  106.           066    NSIRA 0      Next Secondary Index Record Address
  107.           068    CSIBN 0      Current Secondary Index Block Number
  108.           070    NSIBN 0      Next Secondary Index Block Number
  109.  
  110.           Offsets 072 through 126 are not used.
  111.  
  112.  
  113.  
  114.                                   INDEX BLOCK
  115.  
  116.  
  117.                 The index block (physical block 0) is IBS long, as
  118.           defined by the user at definition time. In number terms this
  119.           means that the minimum size is: (Key-length+4)*4+8 or 512
  120.           bytes, the default, or what ever the user specified. It
  121.           contains fixed length records equal to the key length plus
  122.           four bytes. Two used to specify the record length and two
  123.           used to point to the data block.
  124.  
  125.           ----------------------------------------------------------
  126.           |IRL|  key      |DBN|IRL|X'FFFFFFFFFF'|DBN|000|          |
  127.           |----------------------------------------------          |
  128.           |                                                        |
  129.           |                                                        |
  130.           |                                                        |
  131.           |                                                        |
  132.           |                                                        |
  133.           |                                                        |
  134.           |                                                        |
  135.           |                                                        |
  136.           |                                                        |
  137.           |                                                        |
  138.           |                                                        |
  139.           |                                                        |
  140.           |                                                        |
  141.           |                                            ------------|
  142.           |                                            | IFS | NIB |
  143.           ----------------------------------------------------------
  144.  
  145.  
  146.               |___2___|___________FKL___________________|___2__|
  147.                  IRL          record key                   DBN
  148.  
  149.                 The length of the record key is defined by the user.
  150.           Maximum current key length is 125 bytes.
  151.  
  152.                 Four bytes at the end of the index block are used for
  153.           block control.
  154.                 IFS is the free space in the block. This is initially
  155.           set to IBS-8
  156.                 NIB is the pointer to the next index block. The last
  157.           index block points to zero.
  158.  
  159.           IBS = index block size
  160.           IRL = index record length
  161.           DBN = data block number
  162.           IFS = index free space
  163.           INB = index next block
  164.  
  165.           Based on a 512 byte index block:
  166.           offset label = value
  167.           000    start of index block
  168.           508     IFS  = 504=(IBS-8)
  169.           510     INB  = 0
  170.  
  171.  
  172.  
  173.  
  174.                              SECONDARY INDEX BLOCK
  175.  
  176.  
  177.                 The secondary index block when used is IBS long, the
  178.           same as the index block. It is placed at the end of the file
  179.           and the file is marked as read only. The secondary index
  180.           provides an alternate way to find a set of data records.
  181.  
  182.           ----------------------------------------------------------
  183.           |SIRL| SI key    |DBN|CDRA|SIRL|X'FFFFF'|DBN|CDRA|000|   |
  184.           |-----------------------------------------------------   |
  185.           |                                                        |
  186.           |                                                        |
  187.           |                                                        |
  188.           |                                                        |
  189.           |                                                        |
  190.           |                                                        |
  191.           |                                                        |
  192.           |                                                        |
  193.           |                                                        |
  194.           |                                                        |
  195.           |                                                        |
  196.           |                                                        |
  197.           |                                                        |
  198.           |                                            ------------|
  199.           |                                            | IFS | NIB |
  200.           ----------------------------------------------------------
  201.  
  202.  
  203.              |___2___|__________SIKL___________|___2___|___2___|
  204.                SIRL         SI record key         DBN     DRO
  205.  
  206.                 The length of the Secondary Index key is defined by
  207.           the user.  Maximum current key length is the File Key Length
  208.           (FKL) times 2.
  209.  
  210.                 Four bytes at the end of the secondary index block are
  211.           used for block control.
  212.                 IFS is the free space in the block. This is initially
  213.           set to IBS-8
  214.                 NIB is the pointer to the next index block. The last
  215.           index block points to zero.
  216.  
  217.           SIRL = secondary index record length
  218.           DBN  = data block number
  219.           DRO  = data record offset
  220.           IFS  = index free space
  221.           INB  = index next block
  222.  
  223.           Based on a 512 byte index block:
  224.           offset label = value
  225.           000    start of index block
  226.           508     IFS  = 504=(IBS-8)
  227.           510     INB  = 0
  228.  
  229.  
  230.  
  231.  
  232.                               DATA BLOCK
  233.  
  234.  
  235.                 The data block, (physical block 1) is constructed in
  236.           the same way as the index block but holds the data records.
  237.           The size, (DBS) is defined by the user at file definition
  238.           time. It must be a multiple of the index block size. Minimum
  239.           size is equal to the index block. Max can be up to 10,000
  240.           bytes. 2048 is the default size.
  241.  
  242.           ----------------------------------------------------------
  243.           |DRL|   data record  |DRL|X'FFFFFFFFFF'|000|             |
  244.           |-------------------------------------------             |
  245.           |                                                        |
  246.           |                                                        |
  247.           |                                                        |
  248.           |                                                        |
  249.           |                                                        |
  250.           |                                                        |
  251.           |                                                        |
  252.           |                                                        |
  253.           |                                                        |
  254.           |                                                        |
  255.           |                                                        |
  256.           |                                                        |
  257.           |                                                        |
  258.           |                                            ------------|
  259.           |                                            | DFS | NDB |
  260.           ----------------------------------------------------------
  261.  
  262.  
  263.              |__2__|_______________Variaable_____________________|
  264.                DRL                data record
  265.  
  266.           DBS = data block size
  267.           DFS = data free space (DBS-4)
  268.           DNB = data next block (DBS-2)
  269.           DRL = data record length
  270.  
  271.           The record length value does not include the 2 length bytes.
  272.  
  273.  
  274.           Based on a 2048 byte data block:
  275.           offset label = value
  276.           0000   start of data block
  277.           2044   DFS   = 2040=(DBS-8)
  278.           2046   DNB   = 0
  279.  
  280.           The "8" in the initial free space calculation allows 4
  281.           control bytes, 2 terminator bytes and 2 extra slop bytes.
  282.  
  283.  
  284.  
  285.  
  286.  
  287.           FILE DEFINITION
  288.  
  289.                 At file definition time the user provides the key
  290.           length (FKL) and the key offset (FKO). The key length is
  291.           edited for less than 126 bytes and not zero. The offset is
  292.           edited for less than 255-FKL.
  293.  
  294.                 The Index and the data block sizes, (IBS and DBS,) are
  295.           also provided by the user with some restrictions. The index
  296.           block must be at least 4 times the key length. Specifically,
  297.           the minimum size is FKL+4 times 4 plus 8. The data block
  298.           must be a multiple of the index block size. There are no
  299.           maximum sizes. However current design limits are 3K per DFH3
  300.           buffer and 5 buffers max. This allows the work area for 1
  301.           file to be 15K in buffer space. Or 2 files of 7.5K etc.
  302.           Beyond this you will get a MS-DOS memory allocation error
  303.           and be forced to reboot the system.
  304.  
  305.                 Load free space, (PFS), is the last value required
  306.           from the user. This is used only when the DISAM file is
  307.           loaded using the DISAM utility LOAd function. This
  308.           percentage is subtracted from the data free space value
  309.           before the data block is filled. When the free space value
  310.           is used up, the percentage is restored and the block is
  311.           written. In effect, this maintains a percentage of free
  312.           space in each data block. e.i. A 1000 byte data block with
  313.           20 percent free space is loaded with 800 bytes worth of data
  314.           records. the 20 percent is then restored (200+) to the data
  315.           free space and the block is written. This will allow a 20
  316.           percent growth in each data block before a data split is
  317.           required.
  318.  
  319.                 These five values are placed in the control block as
  320.           FKL, FKO, IBS, DBS, and PFS.
  321.  
  322.                 Based on the FKL a record of high-values is placed in
  323.           the index block with a data block pointer of 1.
  324.  
  325.                 Based on FKL and FKO a record of high-values is placed
  326.           in the data block. The record lengths are subtracted from
  327.           the free space fields respectively and all three blocks are
  328.           written to the DISAM file.
  329.  
  330.           These are known as logical end of file records. They force
  331.           all records to be inserted below them.
  332.  
  333.  
  334.  
  335.  
  336.  
  337.           FILE HANDLER EXECUTION
  338.  
  339.                 DHF3.COM is executed by the user to load the DISAM
  340.           file handler into the system. The file handler checks to see
  341.           if it has already been loaded by checking the entry point
  342.           address (12:0). It expects to find a four byte
  343.           segment:offset address pattern. A compare of three sets of
  344.           addresses at 12:0, 12:4 and 12:8 is done. If these addresses
  345.           are all the same they are considered as trap addresses and
  346.           the load continues. DFH3 builds a long JMP instruction (5
  347.           bytes) at that address to its own entry point. Based on the
  348.           number of buffers specified, default=1, it acquires 3K
  349.           chunks of memory. Then it terminates and stays resident.
  350.  
  351.                 If the address is not part of a segment:address train
  352.           then DFH3 checks for a x'EA' at 12:0. If this is true then
  353.           DFH3 displays an already loaded message and exits.  If there
  354.           is any other value, DFH3 assumes that the address is being
  355.           used by another interrupt and displays a message to that
  356.           effect and terminates. To change the location of the entry
  357.           address will require a reassembly of DFH3.COM or ZAP
  358.           DFH3.Z01.
  359.  
  360.                 Once loaded, DFH3 becomes a FAR subroutine to the
  361.           calling program. The user entry address, 12:0, is used
  362.           because MS-DOS will load DFH3 where ever there is space and
  363.           the user has no control over its placement. In the GWBASIC
  364.           program the DFH3 segment address is coded DEF SEG=&H12 and
  365.           the offset is coded DFH3=&h0. This code sets up the entry
  366.           address for the file handler at 12:0.
  367.  
  368.  
  369.  
  370.  
  371.  
  372.           FILE ACCESS (PASSING VARIABLES)
  373.  
  374.                 There are two variables normally sent to DISAM.  Some
  375.           functions require only one, e.i. close. But because a
  376.           return-code is returned in the second variable, it is still
  377.           required with a minimum length of one byte. The first
  378.           variable is the function code and the buffer number
  379.           separated by a comma.  If there is no comma and buffer
  380.           number, "1" is assumed. The second variable will depend on
  381.           the first.  Usually the second will be a file name, a data
  382.           record, or a record key.
  383.  
  384.                 The variables' string descriptor blocks are passed on
  385.           the stack to DFH3. Only the CS register points to the
  386.           subroutine's base address. The stack belongs to GWBASIC as
  387.           does the DS register. DFH3 tries to use as little of the
  388.           stack as possible due to not knowing how deep the subroutine
  389.           is into the stack.
  390.  
  391.                 The variables are string descriptor addresses offset
  392.           DS. The DS register is saved and the strings are moved into
  393.           DFH3's address space (CS). All work done by DFH3 will be
  394.           done in it own address space so that no problems will be
  395.           created with GWBASIC.
  396.  
  397.                 The first variable, the file function, is converted to
  398.           upper case and tested. Next the buffer number is checked.
  399.           The buffer specified is an offset into the buffer address
  400.           table. It's value may be from 1 to 5. The number is doubled
  401.           and the table accessed. Functional chart follows.
  402.  
  403.                                           Initial Buffer status
  404.                                       |  closed | open  | invalid |
  405.                          ------------------------------------------
  406.             Function:    O,Q          |  open * | error | error   |
  407.                          C            |  ignore | close | ignore  |
  408.                          All others   |  error  | open *| error   |
  409.                          ------------------------------------------
  410.            *  The address of the buffer is placed in the DS register.
  411.           In the case of the close, the buffer address is closed after
  412.           being moved to the DS register.
  413.  
  414.                 The function of opening and closing buffers is as
  415.           follows. Buffer addresses come in three flavors. Open,
  416.           Closed and nonexistant. Nonexistant buffer addresses are the
  417.           buffers not specified. e.i. If you specify 3 buffers, then 4
  418.           and 5 are nonexistant. Thus, zero.  An open buffer address
  419.           is a valid address pointing to a 3K block of memory.  A
  420.           closed buffer address is a valid buffer address or'd with
  421.           X'8000'. 2CF0 is valid and open.  ACF0 is valid and closed
  422.  
  423.                 The second variable is checked for a minimum length of
  424.           one (1) byte. If not, control is passed immediately back to
  425.           the calling program. Exit.
  426.  
  427.                 Next, the users data is moved into DFH3's address
  428.           space. The function code is used to determine what is to be
  429.           done.
  430.  
  431.                 When the function is completed the return-code or
  432.           record is moved to GWBASIC's address space defined by the
  433.           second variable. Normally the length code in the string
  434.           descriptor is shortened to fit the response. If there is not
  435.           enough length to hold the record, the record is truncated.
  436.           If the file was opened as a Quick-BASIC file the length is
  437.           NOT changed and it is up to calling program to determine how
  438.           much of the returning string is valid.
  439.  
  440.  
  441.  
  442.  
  443.           FILE ACCESS (OPEN)
  444.  
  445.  
  446.                 The file open can originate from one of two places.
  447.           The first is a normal open. The second is a Quick-BASIC
  448.           open. The difference is that the Quick-BASIC open sets the
  449.           QBOF flag.
  450.  
  451.                 The open process checks to see if an open has already
  452.           been processed.(This is not the same as assigning a buffer
  453.           address.) If the file is already open, an invalid function
  454.           "9" is returned to the calling program.
  455.  
  456.                 There is another user error condition, "8", which is
  457.           caused when the calling program ABnormally ENDs (ABENDs)
  458.           while the DISAM file is open.  MS-DOS will close the file at
  459.           the time of the abend. However the open flag, FOF, and
  460.           possibly the update flag, FUF, May still be set.  If the FUF
  461.           flag is set then the update data is lost.  The open will
  462.           reset the flags and return to the calling program with an
  463.           (8) return-code.
  464.  
  465.                 If the file is not found then the user will get a "7"
  466.           (file not found) return-code.
  467.  
  468.                 Next the control block is read to get the sizes of the
  469.           index and data blocks.Using the buffer base address the
  470.           index block and data block ADCONS are built.
  471.  
  472.                 A check for an open file is again done. This time with
  473.           the control block gotten from the file. If the file is
  474.           closed, then the open continues. If the file is already
  475.           marked as open, the share option is checked. If the share
  476.           option is "Y" (1), then the open continues. If not, then
  477.           the file is closed and the buffer is released. An error of
  478.           "5" (sharing not allowed) is returned to the user.
  479.           Continuation of the open function includes marking the file
  480.           as open and writing the control block back to disk. This
  481.           allows other programs to check to see if the file is open.
  482.  
  483.                 CIBN is set -1 and NIBN is set to 0.  The Read Index
  484.           Block (RIB) subroutine is called which forces a read and the
  485.           index buffer is filled. CDBN is set to 0 and NDBN is set to
  486.           1. a call to Read Data Block (RDB) forces a read and the
  487.           data buffer is filled. Last the file is marked open (FOF),
  488.           the return code is set to "0" and control is returned to the
  489.           calling program.
  490.  
  491.  
  492.  
  493.  
  494.           FILE ACCESS (CLOSE)
  495.  
  496.                 The close routine first resets the Immediate Update
  497.           Flag (IUF).  Then checks the File Status Flag (FSF)to see
  498.           if the file has been opened. If not the routine terminates
  499.           without error.
  500.  
  501.                 The File Update Flag (FUF)is checked. If it is set,
  502.           which means there is still an unwritten buffer, the data
  503.           buffer is written.
  504.  
  505.                 The "update" and "file open" flags are reset and the
  506.           control buffer is written.
  507.  
  508.                 The file is then closed to MS-DOS and routine
  509.           terminates without error.
  510.  
  511.  
  512.  
  513.                              RECORD KEY SEARCHES
  514.  
  515.  
  516.                 When I initially designed DISAM for the HDOS 2.0
  517.           environment, module size was more important than access
  518.           speed. So I chose not to use rotating index-block searches.
  519.           I continued this into the MS-DOS environment.
  520.  
  521.                 All key searches start at index block zero.
  522.  
  523.                 When a search for a key is initiated, the index buffer
  524.           is checked for the first index block. If it is not there it
  525.           is read in from the file.
  526.  
  527.                 The index search looks for a key equal or greater than
  528.           the user's key. The index block chain is used to search
  529.           through multiple index blocks until the index key conditions
  530.           are met.
  531.  
  532.                 The data block number associated with the index key is
  533.           used to read the data block.
  534.  
  535.                 Before the data block is read into the buffer a check
  536.           is made to see if the data block in the buffer is the one
  537.           wanted or has been updated (FUF). If the data block is
  538.           already in the buffer, the search for the record begins. If
  539.           the data buffer is not the correct one and has been updated,
  540.           it is written to the file. The data block wanted is read
  541.           into the buffer and the search for the data record begins.
  542.  
  543.                 Each data record is checked sequentially against the
  544.           user's key. As the search progresses, data record address
  545.           fields are maintained. The CDRA (current data record
  546.           address) points to the record under test. The NDRA (next
  547.           data record address) points the next data record. When the
  548.           match is found, control is returned to the calling function
  549.           with the carry flag clear.  If there is no match, control is
  550.           returned with the carry flag set. Since the data records are
  551.           stored in ascending sequence, a data key greater than the
  552.           user key is a not found condition.
  553.  
  554.                 With all this in mind, we move on to the rest of the
  555.           file functions.
  556.  
  557.  
  558.  
  559.  
  560.           FILE ACCESS (ADD)
  561.  
  562.                 A search for the record is initiated. If the record is
  563.           found, an error is returned to the calling program.
  564.  
  565.                 The add function first checks to see if there is
  566.           enough free space in the data block for another record.
  567.  
  568.                 If there is, the free space value is reduced by the
  569.           length of the record plus 2. (2 bytes for the length value)
  570.           The CDRA is then used as the data block dividing point. All
  571.           data records fron the CDRA to the end of the data in the
  572.           block are moved up for a distance of the new record length
  573.           plus 2.  The new record is then inserted in the space
  574.           provided by the move.  Control is passed back to the calling
  575.           program.
  576.  
  577.                 If there is not enough space, the block is split and
  578.           then the record is added as above.
  579.  
  580.                 Part of the Add routine is used by the "PUT" logic and
  581.           is explained there.
  582.  
  583.  
  584.  
  585.  
  586.  
  587.           FILE ACCESS (DELETE)
  588.  
  589.                 A search is initiated for the record. If the record is
  590.           not found, an error is passed to the calling program.
  591.  
  592.                 If it is, the record length plus 2 is added to the
  593.           free space value. All records beyond the record to be
  594.           deleted (NDRA) are moved down in the block to cover the
  595.           deleted record(CDRA).  Control is passed back to the
  596.           calling program.
  597.  
  598.                 Part of this function is used by the "PUT" function.
  599.  
  600.  
  601.  
  602.  
  603.           FILE ACCESS (GET)
  604.  
  605.                 The GET access can be performed in three ways.
  606.           1) A sequential read.
  607.                 (First character in the key is a space)
  608.           2) A partial (generic) key read.
  609.                 (The user key length is less than FKL)
  610.           3) A full key read.
  611.                 (The user key is equal or greater than FKL)
  612.  
  613.                 For a sequential read, the NDRA is moved to the CDRA
  614.           and the data record is gotten from the CDRA.In the event
  615.           that the NDRA is zero, (end of data block), the NDB is used
  616.           to get the next data block. If the NDB is zero then the
  617.           logical end of file has been reached.
  618.  
  619.                 For a generic read, a key compare is done only for the
  620.           length of the user key.
  621.  
  622.                 For a full read, a key compare is done for the length
  623.           of the file key.
  624.  
  625.                 In both keyed reads a search is initiated for the
  626.           record.  If the record is not found, an error is passed to
  627.           the calling program.
  628.  
  629.                 Using the CDRA, the record is placed in the address
  630.           space defined by the second calling parm not to exceed the
  631.           input parm length.  In a GWBASIC call to DFH3 it is
  632.           important that the length of the second parm be 255 bytes
  633.           insure that the whole record is returned.
  634.  
  635.                 If the file record is less that the provided length,
  636.           the length is shortened to the file record length.
  637.  
  638.                 The exception is for the "Q" open for Quick-BASIC. The
  639.           user's length in the second field is used regardless of data
  640.           record length. It is up to the Quick-BASIC program to know
  641.           how much of the return field to use.  Quick-BASIC will get a
  642.           string integraty violation if the string descriptor length
  643.           is changed outside of Quick-BASIC.
  644.  
  645.  
  646.  
  647.           FILE ACCESS (PUT)
  648.  
  649.                 A search is initiated for the record using the full
  650.           key. If the record is not found, an error is passed to the
  651.           calling program.
  652.  
  653.                 The PUT function replaces an existing record using the
  654.           DELETE and ADD functions. A delete for the record is issued
  655.           using the DELETE routine. Then an add for the record is
  656.           issued using the ADD routine. In this way record length
  657.           changes are allowed. If the replacement record causes a data
  658.           block split it is handled as a normal add.
  659.  
  660.  
  661.  
  662.           SECONDARY INDEXING
  663.  
  664.                 Once a DISAM file has been defined and loaded it may
  665.           have a secondary index created. The "Sec" finction of DISAM
  666.           will add the secondary index to the end of the file. This
  667.           will also lock the file as READ ONLY. You may reorganize the
  668.           file and that will allow it to be a normal DISAM file.  The
  669.           secondary index records point directily to the physical
  670.           location of the data records on a 1-for-1 basis. Any changes
  671.           to the file will render the secondary index useless.
  672.  
  673.  
  674.  
  675.           SPLIT LOGIC
  676.  
  677.                 When a record is to be added to a block, first the
  678.           record length plus 2 is subtracted from the free space
  679.           field. If this subtraction causes an overflow, carry flag to
  680.           be set, there is not enough space in the block for the
  681.           record.
  682.  
  683.                 When a block is split approximatly half of the data is
  684.           copied to another block and half of the data is kept in the
  685.           current block. When a DATA block is split, a new index
  686.           record is created.  So before we can split a DATA block
  687.           there must be enough space in the index block for another
  688.           record.So the index block must be  checked to see if there
  689.           is enough space for another key record. If there is, the
  690.           data block split continues. If not, the index block is split
  691.           first.
  692.  
  693.           INDEX SPLIT
  694.  
  695.                 The index block is split by dividing the block size by
  696.           2 and stepping through the block, subtracting the record
  697.           length until the value goes negative. At this point the
  698.           address of the next record is saved (NIRA) and the index
  699.           string is terminated. The free space is recalculated. The
  700.           block chain is updated to point to the Next File Block
  701.           (NFB). The index record is written.
  702.  
  703.                 Using the same data in the index buffer, the upper
  704.           index records are moved to the bottom of the index block.
  705.           The free space is recalculated and the new index record is
  706.           appended to the file using the next file block number. Last
  707.           the Next File Block pointer in incriminated and the control
  708.           record is written.
  709.  
  710.                 At this point we are abend safe. Control is passed
  711.           back to the "ADD" function for another try.
  712.  
  713.           DATA SPLIT
  714.  
  715.                 The data split occurs in the same way as the index
  716.           split with three exceptions.
  717.                 1) The original data block index record is updated
  718.                    with the NFB value.
  719.                 2) The key of the last record in the lower data buffer
  720.                   is written to the index buffer.
  721.                 3) The Next Block Number is calculated based on the
  722.                   algorythm DBS/IBS.
  723.  
  724.                 All buffers are written after a data block split to
  725.           protect the file. Control is passed to the "ADD" function.
  726.  
  727.  
  728.  
  729.           EXAMPLE:
  730.  
  731.           1) Before DISAM file image.
  732.  
  733.  
  734.  
  735.                           0     index
  736.                           --------------
  737.                           | ee1 kk2 oo3|
  738.                           | FF4        |
  739.                           |           0|
  740.                           --------------
  741.  
  742.           1     data    2    data   3   data     4   data
  743.           ------------- ----------- ------------ -----------
  744.           |aaaaaaaaacc| |ggggggiii| |mmmmmmmmmm| |qqqqqqqqq|
  745.           |cccccccccee| |iiiiiiikk| |mmmmmmmmoo| |qqssssssu|
  746.           |eeeeeeee  2| |kkkkkk  3| |ooooooo  4| |uuuFF   0|
  747.           ------------- ----------- ------------ -----------
  748.  
  749.  
  750.  
  751.  
  752.  
  753.  
  754.  
  755.  
  756.  
  757.  
  758.           2) "jjjjjjjjjjj" record added,  causes data block split
  759.  
  760.  
  761.  
  762.                           0     index
  763.                           --------------
  764.                           | ee1 kk2 oo3|
  765.                           | FF4        |
  766.                           |           0|
  767.                           --------------
  768.  
  769.           1     data    2    data   3    data    4  data
  770.           ------------- ----------/ ------------- -------------
  771.           |No         | |ggggggiii| |No         | |No         |
  772.           |  Change   | |iiiiiiikk| |  Change   | |  Change   |
  773.           |          2| |kkkkkk  3| |         4 | |          0|
  774.           ------------- --/-------- ------------- -------------
  775.                         data split
  776.  
  777.  
  778.  
  779.  
  780.           3) data block splits
  781.  
  782.  
  783.  
  784.                           0     index
  785.                           --------------
  786.                           | ee1 ii2 kk5|
  787.                           | oo3 FF4    |
  788.                           |           0|
  789.                           --------------
  790.  
  791.           1     data    2    data   3    data  4  data    5  data
  792.           ------------- ----------- ---------- ---------- ----------
  793.           |No         | |ggggggiii| |No      | |No      | |kkkkkkk |
  794.           |  Change   | |iiiiiii  | | Change | | Change | |        |
  795.           |          2| |        5| |       4| |       0| |       3|
  796.           ------------- ----------- ---------- ---------- ----------
  797.  
  798.  
  799.  
  800.  
  801.  
  802.  
  803.  
  804.  
  805.           4) "jjjjjjjjjjj"  record added
  806.  
  807.  
  808.  
  809.                           0     index
  810.                           --------------
  811.                           | ee1 ii2 kk5|
  812.                           | oo3 FF4    |
  813.                           |           0|
  814.                           --------------
  815.  
  816.           1     data    2    data   3    data  4  data    5  data
  817.           ------------- ----------- ---------- ---------- ----------
  818.           |aaaaaaaaacc| |ggggggiii| |mmmmmmmm| |qqqqqqqq| |jjjjjjjj|
  819.           |cccccccccee| |iiiiiii  | |mmmmmmoo| |qqsssssu| |kkkkkk  |
  820.           |eeeeeeee  2| |        5| |ooooo  4| |uuuFF  0| |       3|
  821.           ------------- ----------- ---------- ---------- ----------
  822.  
  823.  
  824.