tattempt better flushing ' - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 59a9682013a2f4c5ee679ba910fe234ea61f6808
 (DIR) parent eacc220a040de32a873340274f09b8e0498ff85f
 (HTM) Author: rsc <devnull@localhost>
       Date:   Thu, 17 Jun 2004 21:13:51 +0000
       
       attempt better flushing
       '
       
       Diffstat:
         M src/libventi/file.c                 |      49 +++++++++++++++++++------------
       
       1 file changed, 31 insertions(+), 18 deletions(-)
       ---
 (DIR) diff --git a/src/libventi/file.c b/src/libventi/file.c
       t@@ -664,7 +664,7 @@ mkindices(VtEntry *e, u32int bn, int *index)
        {
                int i, np;
        
       -        memset(index, 0, VtPointerDepth*sizeof(int));
       +        memset(index, 0, (VtPointerDepth+1)*sizeof(int));
        
                np = e->psize/VtScoreSize;
                for(i=0; bn > 0; i++){
       t@@ -1168,8 +1168,8 @@ vtfileflushbefore(VtFile *r, u64int offset)
        {
                VtBlock *b, *bb;
                VtEntry e;
       -        int i, base, depth, ppb, epb, ok;
       -        int index[VtPointerDepth+1], index1[VtPointerDepth+1], j, ret;
       +        int i, base, depth, ppb, epb, doflush;
       +        int index[VtPointerDepth+1], j, ret;
                VtBlock *bi[VtPointerDepth+2];
                uchar *score;
        
       t@@ -1181,6 +1181,9 @@ vtfileflushbefore(VtFile *r, u64int offset)
                if(b == nil)
                        return -1;
        
       +        /*
       +         * compute path through tree for the last written byte and the next one.
       +         */
                ret = -1;
                memset(bi, 0, sizeof bi);
                depth = DEPTH(e.type);
       t@@ -1190,10 +1193,12 @@ vtfileflushbefore(VtFile *r, u64int offset)
                        goto Err;
                if(i > depth)
                        goto Err;
       -        mkindices(&e, offset/e.dsize, index1);
                ppb = e.psize / VtScoreSize;
                epb = e.dsize / VtEntrySize;
        
       +        /*
       +         * load the blocks along the last written byte
       +         */
                index[depth] = r->offset % r->epb;
                for(i=depth; i>=0; i--){
                        bb = blockwalk(b, index[i], r->c, VtORDWR, &e);
       t@@ -1204,33 +1209,41 @@ vtfileflushbefore(VtFile *r, u64int offset)
                }
                ret = 0;
        
       +        /*
       +         * walk up the path from leaf to root, flushing anything that
       +         * has been finished.
       +         */
                base = e.type&~VtTypeDepthMask;
                for(i=0; i<depth; i++){
       +                doflush = 0;
                        if(i == 0){
       -                        /* bottom: data or dir block */
       -                        ok = offset%e.dsize == 0;
       +                        /* leaf: data or dir block */
       +                        if(offset%e.dsize == 0)
       +                                doflush = 1;
                        }else{
       -                        /* middle: pointer blocks */
       +                        /*
       +                         * interior node: pointer blocks.
       +                         * specifically, b = bi[i] is a block whose index[i-1]'th entry 
       +                         * points at bi[i-1].  
       +                         */
                                b = bi[i];
       +
                                /*
       -                         * flush everything up to the break
       +                         * the index entries up to but not including index[i-1] point at 
       +                         * finished blocks, so flush them for sure.
                                 */
                                for(j=0; j<index[i-1]; j++)
                                        if(flushblock(r->c, nil, b->data+j*VtScoreSize, ppb, epb, base+i-1) < 0)
                                                goto Err;
       +
                                /*
       -                         * if the rest of the block is already flushed,
       -                         * we can flush the whole block.
       +                         * if index[i-1] is the last entry in the block and is global
       +                         * (i.e. the kid is flushed), then we can flush this block.
                                 */
       -                        ok = 0;
       -                        if(index[i] != index1[i]){
       -                                ok = 1;
       -                                for(; j<ppb; j++)
       -                                        if(vtglobaltolocal(b->data+j*VtScoreSize) != NilBlock)
       -                                                ok = 0;
       -                        }
       +                        if(j==ppb-1 && vtglobaltolocal(b->data+j*VtScoreSize)==NilBlock)
       +                                doflush = 1;
                        }
       -                if(ok){
       +                if(doflush){
                                if(i == depth)
                                        score = e.score;
                                else