home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 10: Diskmags / nf_archive_10.iso / MAGS / INC_MAG / INC_2_5.MSA / PRG / CACHE / CCACHE.C < prev   
C/C++ Source or Header  |  1987-09-15  |  5KB  |  241 lines

  1. /************************************************************************/
  2. /*                                    */
  3. /*    ccache....                            */
  4. /*                                    */
  5. /*    LRU Buffer implementation system                */
  6. /*                                    */
  7. /*    This module, which holds the guts of the cachine program,    */
  8. /*    maintains a number of buffers (see "BUFFERS") which hold the    */
  9. /*    "BUFFERS" most recently accessed (read or written) sectors    */
  10. /*    from the disk. Associated with each buffer is an age, which    */
  11. /*    gets incremented each time any buffer is accessed.  The age    */
  12. /*    of a buffer is reset to 0 when that specific buffer is used,    */
  13. /*    so the buffer with the oldest age is the Least Recently Used.    */
  14. /*    The LRU buffer is recycled for a new sector if we need a place    */
  15. /*    to save a buffer.                        */
  16. /*                                    */
  17. /*    The size of the buffer depends entirely upon one's needs.    */
  18. /*    A small buffer, say 32 elements, will probably suffice to    */
  19. /*    show some speed up.  A large buffer, perhaps around 256        */
  20. /*    elements (128k of buffer) will achieve many of the same        */
  21. /*    benefits that a ram disk will, without the volatility (as    */
  22. /*    we always perform writes immediately (write through cache)).    */
  23. /*                                    */
  24. /*    This program is compiled under Lattice C, using the -n -t    */
  25. /*    options, and linked with the fast linker from Personal Pascal.    */
  26. /*                                    */
  27. /*    Program Copyright 1987, Charles McGuinness.  Reproduction    */
  28. /*    in any form beyond the CompuServe Information Service is    */
  29. /*    prohibited.                            */
  30. /*                                    */
  31. /************************************************************************/
  32.  
  33. /*    #define    FAT
  34.  
  35.     If FAT is defined, then only the first BUFFERS/2 sectors of
  36.     each diskette will be cached, causing the FAT and directories
  37.     to be always in memory....
  38. */
  39.  
  40.  
  41. #define    BUFFERS    256            /* Let's go for the 128k Size!    */
  42.  
  43. unsigned char    drive[BUFFERS];        /* Why didn't I use a struct???    */
  44. unsigned short    recs[BUFFERS];
  45. unsigned short    age[BUFFERS];
  46.  
  47. short        bufs[BUFFERS][256];
  48.  
  49.  
  50. unsigned short    xrwflag,
  51.         xnumber,
  52.         xrecno,
  53.         xdev,
  54.         xchar;
  55.     
  56. char *    xbuffer;
  57.  
  58.  
  59. int lru_startup()
  60. {
  61.     init_cache();        /* Clear out the cache...    */
  62.     return(BUFFERS * 512);    /* How much data space we need    */
  63. }
  64.  
  65. int myrwabs()
  66. {
  67.     int    i,
  68.         bnum;
  69.     
  70.  
  71.     if ((!xrecno) || (! xbuffer)) {
  72.         init_cache();
  73.         return(rwabs());
  74.     }
  75.     
  76.     if (xrwflag & 1) {
  77.         i = rwabs();    /* Write them all out ...        */
  78.         if (i != 0) {
  79.             init_cache();    /* All bets off now!        */
  80.             return(i);
  81.         }
  82.         
  83.         for (i = 0;i < xnumber;i++) {
  84.             write_sect();
  85.             xbuffer += 512;
  86.             xrecno++;
  87.             }
  88.         return(0);
  89.         }
  90.  
  91.     for (;xnumber;xnumber--) {
  92.         bnum = in_cache(xrecno);
  93.         if (bnum != -1) {
  94.             movmem(bufs[bnum],xbuffer,512);
  95.             xbuffer += 512;
  96.             xrecno++;
  97.             }
  98.         else {
  99.             i = rwabs();
  100.             if (i != 0) {
  101.                 init_cache();    /* All bets off now!    */
  102.                 return(i);
  103.             }
  104.             for (i=0;i<xnumber;i++) {
  105.                 save_sect();
  106.                 xrecno++;
  107.                 xbuffer += 512;
  108.                 }
  109.             return(0);
  110.             }
  111.         }
  112.     return(0);
  113. }
  114.  
  115.  
  116. int dchange()
  117. {
  118.     int    i;
  119.  
  120.     init_cache();
  121.  
  122.     if ((! xbuffer) || (! xrecno))
  123.         return(rwabs());
  124.     
  125.     i = rwabs();        /* Do the whole shebang...    */
  126.     if (i != 0)
  127.         return(i);
  128.     
  129.     if (xrwflag & 1) {
  130.         for (i = 0;i < xnumber;i++) {
  131.             write_sect();
  132.             xbuffer += 512;
  133.             xrecno++;
  134.             }
  135.         return(0);
  136.         }
  137.  
  138.     for (i=0;i<xnumber;i++) {
  139.         save_sect();
  140.         xrecno++;
  141.         xbuffer += 512;
  142.         }
  143.     return(0);
  144. }
  145.  
  146. init_cache()
  147. {
  148.     int    i;
  149.     for (i=0;i<BUFFERS;i++)
  150.         drive[i] = 0xff;
  151.         
  152. }
  153.  
  154. write_sect()
  155. {
  156.     int    i;
  157.  
  158.     for (i=0;i<BUFFERS;i++)
  159.         if ((drive[i] == xdev) && (recs[i] == xrecno)) {
  160.             movmem(xbuffer,bufs[i],512);
  161.             age[i] = 0;
  162.             return(0);
  163.             }
  164.             
  165.     i = find_free();    /* Get a free buffer slot        */
  166.     movmem(xbuffer,bufs[i],512);
  167.     drive[i] = xdev;
  168.     recs[i]  = xrecno;
  169.     age[i] = 0;
  170.     update_age();
  171.  
  172.     return(0);
  173.  
  174. }
  175.  
  176. save_sect()
  177. {
  178.     int    i;
  179.  
  180. #ifdef    FAT
  181.     if (xrecno > (BUFFERS >> 1))
  182.         return;
  183. #endif
  184.  
  185.     for (i=0;i<BUFFERS;i++)
  186.         if ((drive[i] == xdev) && (recs[i] == xrecno)) {
  187.             movmem(xbuffer,bufs[i],512);
  188.             age[i] = 0;
  189.             update_age();
  190.             return;
  191.         }
  192.         
  193.         
  194.     i = find_free();    /* Get a free buffer slot        */
  195.     movmem(xbuffer,bufs[i],512);
  196.     drive[i] = xdev;
  197.     recs[i]  = xrecno;
  198.     age[i]     = 0;
  199.     update_age();
  200.  
  201.     return(0);
  202. }
  203.  
  204. in_cache(x)
  205. {
  206.     int    i;
  207.     
  208.     for (i=0; i<BUFFERS; i++)
  209.         if ((drive[i] == xdev) && (recs[i] == x))
  210.             return(i);
  211.         
  212.     return(-1);
  213. }
  214.  
  215. find_free()
  216. {
  217.     int    i, oldest,oldage;
  218.     
  219.     oldage    =0;
  220.  
  221.     for (i=0;i<BUFFERS;i++) {
  222.         if (drive[i] == 0xff)
  223.             return(i);
  224.         if (age[i] >= oldage) {
  225.             oldage = age[i];
  226.             oldest = i;
  227.         }
  228.     }
  229.     
  230.     return(oldest);
  231. }
  232.  
  233. update_age()
  234. {
  235.     int    i;
  236.     
  237.     for (i=0;i<BUFFERS;i++)
  238.         if (age[i] < 4096)
  239.             age[i]++;
  240. }
  241.