!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!                                                                       !!!
!!!             ISMBLD - Calculate Empty Index Blocks                     !!!
!!!                                                                       !!!
!!!       Copyright (C) 1993  by Jeff Kreider, Consultant                 !!!
!!!                                                                       !!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!                                                                       !!!
!!!    Donated to AMUS Network for individual use. Not to be resold       !!!
!!!    without written permission from Jeff Kreider, Consultant           !!!
!!!                                                                       !!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

100 MAP1 VARS
125     MAP2 KEY'SIZ,F,6                ! Size of Key
150     MAP2 REC'CNT,F,6                ! Number of Records
175     MAP2 BLK,F,6                    ! Blocking Factor
200     MAP2 HLF'BLK,F,6                ! "Half" full block
225     MAP2 ONE,F,6,1                  ! the number "1"
250     MAP2 TOP'LEVEL,F,6              ! Top level block count
275     MAP2 SEC'LEVEL,F,6              ! Second level block count
300     MAP2 THIRD'LEVEL,F,6            ! Third level block count
325     MAP2 DIR'RCK,F,6,1              ! Size of Directory Rock
350     MAP2 FIL'SIZ,F,6
375     MAP2 CRLF,X,2
400     MAP2 FILE,S,6,""

425     SIGNIFICANCE 11

450     INPUT "Records to allocate: ";REC'CNT
475     INPUT "Key Size: ";KEYSIZ
500     INPUT "Logical record size of Data: ";DAT'SIZ
525     INPUT "File to Build (assume .IDX): ";FILE

550             KEY'SIZ=KEYSIZ
575             IF KEY'SIZ/2 # INT(KEY'SIZ/2) THEN KEY'SIZ=KEY'SIZ+1
600             BLK = INT(508/(KEY'SIZ+4))
625             HLF'BLK=INT(BLK/2)           ! do not round up....

650     CALC'THIRD'LEVEL:

675     ! Since each block at the lower level is only half full and the last
700     !  block can be full minus one entry (for the eof), for each record
725     !  to allocate, there must be one entry.  Therefore, the lower level
750     !  should be the amount of some "N" such that N x (number of half
775     !  full blocks) plus (one block with one entry missing). So the
800     !  number of blocks for the third level is N+1 or 1; whichever is
825     !  is greater.

850             N=(REC'CNT-BLK+1)/(HLF'BLK)
875             IF N # INT(N) THEN N=INT(N+1)
900             THIRD'LEVEL = (N+1) MAX ONE

925     CALC'SEC'LEVEL:

950     ! For each block in the lower level, there is an entry in the middle
975     !  level. So, there's a number Z such that:
1000    !
1025    !       THIRD'LEVEL = Z*(HLF'BLK)+BLK
1050    !
1075    !  So solving for Z...

1100            Z = (THIRD'LEVEL - BLK)/(HLF'BLK)
1125            IF Z # INT(Z) THEN Z=INT(Z+1)
1150            SEC'LEVEL = (Z+1) MAX ONE

1175    CALC'TOP'LEVEL:

1200    ! By similar analysis for "I" on the top level:

1225            I = (SEC'LEVEL - BLK)/(HLF'BLK)
1250            IF I # INT(I) THEN I=INT(I+1)
1275            TOP'LEVEL = (I+1) MAX ONE

1300    ! Finally...

1325            FIL'SIZ = DIR'RCK + TOP'LEVEL + SEC'LEVEL + THIRD'LEVEL

1350    ! Now... What ISAM Does

1375    LOW=INT(REC'CNT/BLK) : IF LOW # REC'CNT/BLK THEN LOW=LOW+1
1400    MIDL=INT(LOW/BLK) : IF MIDL # LOW/BLK THEN MIDL=MIDL+1
1425    TOP=INT(MIDL/BLK) : IF TOP # MIDL/BLK THEN TOP=TOP+1
1450    ISM'SIZ=TOP+MIDL+LOW+ONE
1475    MT'BLK=FIL'SIZ-ISM'SIZ

1500    PRINT : PRINT "ISAM figures:"
1525    PRINT "Bottom level blocks ";LOW
1550    PRINT "Middle level blocks ";MIDL
1575    PRINT "The Top level blocks:";TOP
1600    PRINT "ISAM's Index size (include the Rock): ";ISM'SIZ
1625    PRINT "ISAM will build ";ISM'SIZ-1;" blocks"
1650    PRINT
1675    PRINT "You should respond with ";MT'BLK;" empty blocks to assign"
1700    PRINT "Total Index File size should be:";FIL'SIZ

1725    ! Calculating Data File size

1750    X=REC'CNT/(512/DAT'SIZ)
1775    IF X # INT(X) THEN X=INT(X+1)
1800    PRINT "Data file size is:";X
1825    PRINT "Total files size:";FIL'SIZ+X
1850    IF FILE = "" THEN END

1875 !    Prepare for Command file processing

1900    CRLF=CHR(13)+CHR(10)
1925    KEY'POS=1
1950    INPUT "Building Index file, CR to continue (^C to abort): ";CR$
1975 !
2000 !    Below, the technique builds a command file in memory and executes it.
2025 !    This avoids having to come up with a unique name for a command file
2050 !    which would be built as an output file in a multi-user environment.
2075 !
2100 !    See Appendix D in Inside ISAM (page 153 for a little more detail on
2125 !    this usage of CHAIN ":R."
2150 !
2175    CHAIN ":R."+CRLF+"ERASE "+FILE+".ID?"+CRLF+"ISMBLD "+FILE+CRLF+ &
       STR(KEYSIZ)+CRLF+STR(KEY'POS)+CRLF+STR(DAT'SIZ)+CRLF+STR(REC'CNT)+ &
       CRLF+STR(MT'BLK)+CRLF+"N"+CRLF+CRLF+CRLF
2200    ! or .SEQ file name