Annotation of researchv9/jtools/src/sam/buffer.c, revision 1.1.1.1

1.1       root        1: #include "sam.h"
                      2: 
                      3: static flush();
                      4: static setcache();
                      5: 
                      6: Buffer *
                      7: Bopen(dd)
                      8:        Discdesc *dd;
                      9: {
                     10:        register Buffer *b;
                     11:        b=new(Buffer, 1);
                     12:        b->disc=Dopen(dd);
                     13:        strinit(&b->cache);
                     14:        return b;
                     15: }
                     16: Bclose(b)
                     17:        register Buffer *b;
                     18: {
                     19:        Dclose(b->disc);
                     20:        strclose(&b->cache);
                     21:        free((uchar *)b);
                     22: }
                     23: int
                     24: Bread(b, addr, n, p0)
                     25:        register Buffer *b;
                     26:        uchar *addr;
                     27:        int n;
                     28:        Posn p0;
                     29: {
                     30:        register m;
                     31:        if(b->c2>b->disc->nbytes || b->c1>b->disc->nbytes)
                     32:                panic("bread cache");
                     33:        if(p0<0)
                     34:                panic("Bread p0<0");
                     35:        if(p0+n>b->nbytes){
                     36:                n=b->nbytes-p0;
                     37:                if(n<0)
                     38:                        panic("Bread<0");
                     39:        }
                     40:        if(!incache(b, p0, p0+n)){
                     41:                flush(b);
                     42:                if(n>=BLOCKSIZE/2)
                     43:                        return Dread(b->disc, addr, n, p0);
                     44:                else{
                     45:                        Posn minp;
                     46:                        if(b->nbytes-p0>BLOCKSIZE/2)
                     47:                                m=BLOCKSIZE/2;
                     48:                        else
                     49:                                m=b->nbytes-p0;
                     50:                        if(m<n)
                     51:                                m=n;
                     52:                        minp=p0-BLOCKSIZE/2;
                     53:                        if(minp<0)
                     54:                                minp=0;
                     55:                        m+=p0-minp;
                     56:                        strinsure(&b->cache, (ulong)m);
                     57:                        if(Dread(b->disc, b->cache.s, m, minp)!=m)
                     58:                                panic("Bread");
                     59:                        b->cache.n=m;
                     60:                        b->c1=minp;
                     61:                        b->c2=minp+m;
                     62:                        b->dirty=FALSE;
                     63:                }
                     64:        }
                     65:        bcopy(&b->cache.s[p0-b->c1], &b->cache.s[p0-b->c1+n], addr, 1);
                     66:        return n;
                     67: }
                     68: Binsert(b, s, p0)
                     69:        register Buffer *b;
                     70:        String *s;
                     71:        Posn p0;
                     72: {
                     73:        if(b->c2>b->disc->nbytes || b->c1>b->disc->nbytes)
                     74:                panic("binsert cache");
                     75:        if(p0<0)
                     76:                panic("Binsert p0<0");
                     77:        if(s->n==0)
                     78:                return;
                     79:        if(incache(b, p0, p0)){
                     80:                strinsert(&b->cache, s, p0-b->c1);
                     81:                b->dirty=TRUE;
                     82:                if(b->cache.n>BLOCKSIZE){
                     83:                        b->nbytes+=s->n;
                     84:                        flush(b);
                     85:                        b->cache.n-=BLOCKSIZE;
                     86:                        b->c2=b->c1+b->cache.n;
                     87:                        return;
                     88:                }
                     89:        }else{
                     90:                flush(b);
                     91:                if(s->n>=BLOCKSIZE/2){
                     92:                        b->cache.n=0;
                     93:                        b->c1=b->c2=0;
                     94:                        Dinsert(b->disc, s->s, s->n, p0);
                     95:                }else{
                     96:                        register m;
                     97:                        Posn minp;
                     98:                        if(b->nbytes-p0>BLOCKSIZE/2)
                     99:                                m=BLOCKSIZE/2;
                    100:                        else
                    101:                                m=b->nbytes-p0;
                    102:                        minp=p0-BLOCKSIZE/2;
                    103:                        if(minp<0)
                    104:                                minp=0;
                    105:                        m+=p0-minp;
                    106:                        strinsure(&b->cache, (ulong)m);
                    107:                        if(Dread(b->disc, b->cache.s, m, minp)!=m)
                    108:                                panic("Bread");
                    109:                        b->cache.n=m;
                    110:                        b->c1=minp;
                    111:                        b->c2=minp+m;
                    112:                        strinsert(&b->cache, s, p0-b->c1);
                    113:                        b->dirty=TRUE;
                    114:                }
                    115:        }
                    116:        b->nbytes+=s->n;
                    117: }
                    118: Bdelete(b, p1, p2)
                    119:        register Buffer *b;
                    120:        Posn p1, p2;
                    121: {
                    122:        if(p1<0 || p2<0)
                    123:                panic("Bdelete p<0");
                    124:        if(b->c2>b->disc->nbytes || b->c1>b->disc->nbytes)
                    125:                panic("bdelete cache");
                    126:        if(p1==p2)
                    127:                return;
                    128:        if(incache(b, p1, p2)){
                    129:                strdelete(&b->cache, p1-b->c1, p2-b->c1);
                    130:                b->dirty=TRUE;
                    131:        }else{
                    132:                flush(b);
                    133:                Ddelete(b->disc, p1, p2);
                    134:                b->cache.n=0;
                    135:                b->c1=b->c2=0;
                    136:        }
                    137:        b->nbytes-=(p2-p1);
                    138: }
                    139: static
                    140: flush(b)
                    141:        register Buffer *b;
                    142: {
                    143:        if(b->dirty){
                    144:                Dreplace(b->disc, b->c1, b->c2, b->cache.s, b->cache.n);
                    145:                b->c2=b->c1+b->cache.n;
                    146:                b->dirty=FALSE;
                    147:                if(b->nbytes!=b->disc->nbytes)
                    148:                        panic("flush");
                    149:        }
                    150: }
                    151: int hits, misses;
                    152: incache(b, p1, p2)
                    153:        Buffer *b;
                    154:        Posn p1, p2;
                    155: {
                    156: if(b->c1<=p1 && p2<=b->c1+b->cache.n)hits++; else misses++;
                    157:        return b->c1<=p1 && p2<=b->c1+b->cache.n;
                    158: }
                    159: static
                    160: setcache(b, s, p0)
                    161:        register Buffer *b;
                    162:        String *s;
                    163:        Posn p0;
                    164: {
                    165:        strdelete(&b->cache, (long)0, (long)b->cache.n);
                    166:        strinsert(&b->cache, s, (long)0);
                    167:        b->c1=p0;
                    168:        b->c2=p0+s->n;
                    169:        b->dirty=FALSE;
                    170: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.