VENTI-CACHE(2)                                     VENTI-CACHE(2)

          VtBlock, VtCache, vtblockcopy, vtblockdirty, vtblockduplock,
          vtblockput, vtblockwrite, vtcachealloc, vtcacheallocblock,
          vtcacheblocksize, vtcachefree, vtcacheglobal, vtcachelocal,
          vtcachesetwrite, vtglobaltolocal, vtlocaltoglobal - Venti
          block cache

          #include <u.h>
          #include <libc.h>
          #include <venti.h>

          typedef struct VtBlock
               uchar *data;
               uchar type;
               uchar score[VtScoreSize];
               u32int addr;
          } VtBlock;

          VtCache* vtcachealloc(VtConn *z, int blocksize, ulong nblocks);

          void     vtcachefree(VtCache *c);

          u32int   vtcacheblocksize(VtCache *c);

          u32int   vtglobaltolocal(uchar score[VtScoreSize])
          void     vtlocaltoglobal(u32int local, uchar score[VtScoreSize])

          VtBlock* vtcacheallocblock(VtCache *c, int type);

          VtBlock* vtcachelocal(VtCache *c, u32int addr, int type);

          VtBlock* vtcacheglobal(VtCache *c, uchar[VtScoreSize], int type);

          void     vtblockput(VtBlock *b);

          void     vtblockduplock(VtBlock *b);

          int      vtblockwrite(VtBlock *b);

          void     vtcachesetwrite(VtCache *c,
                      int (*write)(VtConn*, uchar[VtScoreSize], uint, uchar*, int));

          VtBlock* vtblockcopy(VtBlock *b);

          int      vtblockdirty(VtBlock *b);


     Page 1                       Plan 9             (printed 4/13/24)

     VENTI-CACHE(2)                                     VENTI-CACHE(2)

          These functions provide access to a simple in-memory cache
          of blocks already stored on a Venti server and blocks that
          will eventually be stored on a Venti server.

          A VtBlock represents a venti data block.  Blocks stored on a
          venti server, called global blocks, are named by the SHA1
          hash of their contents.  This hash is recorded as the
          block's score. Such blocks are immutable.  The cache also
          stores mutable blocks that have not yet been written to a
          venti server.  These blocks are called local blocks, and
          have special scores that are 16 zero bytes followed by a 4-
          byte big-endian address. The address is an index into the
          internal set of cache blocks.

          The user-visible contents of a VtBlock are data, a pointer
          to the data; type, the venti block type; score, the block's
          score; and addr, the block's cache address.

          Vtcachealloc allocates a new cache using the client connec-
          tion z (see venti-conn(2) and venti-client(2)), with room
          for nblocks of maximum block size blocksize .

          Vtcachefree frees a cache and all the associated blocks.

          Vtcacheblocksize returns the cache's maximum block size.

          Vtglobaltolocal returns the local address corresponding to
          the given local score. If passed a global score,
          vtglobaltolocal returns the special constant NilBlock (~0).
          Vtlocaltoglobal is the opposite, setting score to the local
          score for the cache address local.

          Vtcacheallocblock allocates a new local block with the given

          Vtcachelocal retrieves the local block at address addr from
          the cache.  The given type must match the type of the block
          found at addr.

          Vtcacheglobal retrieves the block with the given score and
          dtype from the cache, consulting the Venti server if neces-
          sary.  If passed a local score, vtcacheglobal invokes
          vtcachelocal appropriately.

          The block references returned by vtcacheallocblock,
          vtcachelocal, and vtcacheglobal must be released when no
          longer needed.  Vtblockput releases such a reference.

          It is occasionally convenient to have multiple variables
          refer to the same block.  Vtblockduplock increments the
          block's reference count so that an extra vtblockput will be
          required in order to release the block.

     Page 2                       Plan 9             (printed 4/13/24)

     VENTI-CACHE(2)                                     VENTI-CACHE(2)

          Vtblockwrite writes a local block to the Venti server,
          changing the block to a global block.  It calls the cache's
          write function to write the block to the server.  The
          default write function is vtwrite (see venti-client(2));
          vtsetcachewrite sets it.  Vtsetcachewrite is used by clients
          to install replacement functions that run writes in the
          background or perform other additional processing.

          Vtblockcopy copies a block in preparation for modifying its
          contents.  The old block may be a local or global block, but
          the new block will be a local block.

          The cache only evicts global blocks.  Local blocks can only
          leave the cache via vtblockwrite, which turns them into glo-
          bal blocks, making them candidates for eviction.

          If a new cache block must be allocated (for
          vtcacheallocblock, vtcachelocal, vtcacheglobal, or
          vtblockcopy), but the cache is filled (with local blocks and
          blocks that have not yet been released with vtblockput), the
          library prints the score and reference count of every block
          in the cache and then aborts.  A full cache indicates either
          that the cache is too small, or, more commonly, that cache
          blocks are being leaked.


          venti(2), venti-client(2), venti-conn(2), venti-file(2),

     Page 3                       Plan 9             (printed 4/13/24)