set blocksize to 32 create table employee ( id i, notes m ) insert into employee values ( 1, replicate( "x", 2000016 ) ) use in employee create cursor sizes ( iMemosize i, iFPTSize i ) FOR ix = 1 TO 100 use employee exclusive in 0 lnSize = max( 1, int( rand() * 2000000 ) ) replace notes WITH REPLICATE('a', lnSize ) in Employee use in employee adir( laFile, "employee.fpt" ) insert into sizes values ( lnSize, laFile[2] ) ENDFOR select sizes brow last nowaitAs long as the memo size is the same or smaller it is put back into the same place. Whenever it increases in size the old allocation is trashed and it is completely reallocated to new space at the end of the fpt. It does this so that it doesn't have waste time to check the block allocation of every record and memo.
set blocksize to 64 set exclusive on * creates two memos the first needs 2 64 byte blocks and the second only needs 1 create table bloat ( id i, notes m ) insert into bloat values ( 1, replicate( "x", 100 ) ) insert into bloat values ( 2, "second memo" ) use in bloat hexedit( "bloat.fpt" ) * update the first memo, size is still under 64 * 2 - 8, so the a's write over the x's use bloat replace notes with replicate( "a", 110 ) use hexedit( "bloat.fpt" ) * this memo now exceeds the two blocks it has allocated, so it requires 3 blocks at the end of the file. use bloat replace notes with replicate( "b", 140 ) use hexedit( "bloat.fpt" ) * again the size is under 3 blocks so the c overwrites the first b use bloat replace notes with replicate( "c", 1 ) use hexedit( "bloat.fpt" )run the above code through each hexedit() call at a time and examine what goes on inside the fpt.