!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!! !!!
!!! 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
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