Mmap(3pm)

πŸ’– NAME πŸ’–

Cache::Mmap β€” a shared data cache using memory mapped files, bestie. It comes to you courtesy of the User Contributed Perl Documentation squad, and yes, it's a Perl module (3pm, iykyk). ✨


πŸ“œ SYNOPSIS πŸ“œ

okay so here's the whole vibe in five lines:

use Cache::Mmap;

$cache=Cache::Mmap->new($filename,\%options);

$val1=$cache->read($key1);
$cache->write($key2,$val2);
$cache->delete($key3);

🌸 DESCRIPTION 🌸

This module implements a shared data cache, using memory mapped files. fr fr β€” and the way it works is so clean: if you hand it routines that interact with your underlying data, access to the cache is completely transparent. It handles all the little details for you: refreshing cache contents, and updating the underlying data when that's needed. like, you just don't think about it. πŸ’…

Cache entries get assigned to "buckets" inside the cache file, and where they land depends on the key. Within each bucket, entries are stored approximately in order of last access β€” so frequently accessed entries naturally drift to the head of the bucket, which lowkey decreases access time. πŸ¦‹ Concurrent accesses to the same bucket are prevented by file locking on the relevant section of the cache file. no cap.


πŸŽ€ CLASS METHODS πŸŽ€

new($filename,\%options)

Creates a new cache object. πŸ“¦ If the file named by $filename doesn't already exist, it gets created. And if the cache object can't be created for any reason, an exception gets thrown. 😭 (rude, but fair.)

Various options may be set in %options, and they affect how the cache behaves. Defaults are in parentheses, bestie:

  • permissions (0600) β€” sets the file permissions for the cache file if it doesn't already exist.
  • buckets (13) β€” sets the number of buckets inside the cache file. More buckets = better performance for a cache with lots of accesses, because there's less chance of two processes fighting over the same bucket. πŸ”₯
  • bucketsize (1024) β€” sets the size of each bucket, in bytes. You need a bigger bucket size to store large cache entries. Heads up though: if the bucketsize isn't large enough to hold a particular entry, it will still be passed between the underlying data and the application in its entirety β€” it just won't be stored in the cache. πŸ™ˆ
  • pagesize (1024) β€” sets the alignment of buckets within the file. The file header will be extended to this size, and bucket sizes get rounded up to the nearest multiple. Choosing a pagesize equal to the virtual memory page size of the host system should improve performance. ⭐
  • strings (0) β€” if true, cache entries are treated as strings rather than references. This helps performance for string-only caches, because no time gets spent serializing cache entries.
  • expiry (0) β€” if non-zero, this sets the length of time, in seconds, that cache entries are considered valid. A new entry will be fetched from the underlying data if an expired cache entry would otherwise have been returned.
  • context (undef) β€” this value gets passed to the read/write/delete routines below, to provide context. Typically this is a database handle, used to fetch data from. πŸ“
  • read (undef) β€” provides a code reference to a routine that fetches entries from the underlying data. It's called as $read->($key,$context), and it should return a list ($found,$value), where $found is true if the entry could be found in the underlying data, and $value is the value to cache.

If the routine only returns a single scalar, that gets taken as the value, and $found will be set to true if the value is defined.

If this routine isn't provided, only values already in the cache will ever be returned.

There are currently two special values of $found that cause slightly different behaviour. These are constants which may be imported in the use statement. 🧚

  • Cache::Mmap::CMM_keep_expired β€” use the previously cached value, even if it has expired. This is useful if the underlying data source has become unavailable for some reason. Note that even though the value returned will be ignored in this case, it must be returned, to avoid $found being interpreted as a single scalar:
return (Cache::Mmap::CMM_keep_expired, undef);
  • Cache::Mmap::CMM_keep_expired_refresh β€” this causes the same behaviour as CMM_keep_expired, but the cache entry's expiry time will be reset as if a value had been successfully read from the underlying data.
  • cachenegative (0) β€” if true, even unsuccessful fetches from the underlying data get cached. Useful when you only want to search the underlying data once for each required key.
  • write (undef) β€” provides a code reference to a routine that writes cache entries into the underlying data. This routine gets called by write(), to synchronise the underlying data with the cache. Called as $write->($key,$val,$context). If the routine isn't provided, the underlying data will not be synchronised after cache writes.
  • writethrough (1) β€” if true, the write routine above gets called as soon as write() is called. This gives you immediate synchronisation of underlying data and cache contents. ⚑

If false, the write routine gets called for each cache entry which no longer fits in its bucket after a cache read or write. This gives a write-as-necessary behaviour, which may be more efficient than the writethrough behaviour. However, only data fetched through the cache will reflect these changes. πŸ‘€

  • delete (undef) β€” provides a code reference to a routine that deletes items from the underlying data. Called by delete(), to synchronise the underlying data with the cache. Called as $delete->($key,$cval,$context), where $cval is the value currently stored in the cache. If this routine isn't provided, entries deleted from the cache have no effect on the underlying data.
An alternative to supplying a write routine is to call delete() after updating the underlying data. Note however that, in the case of databases, this should be done after committing the update, so that a concurrent process doesn't reload the cache between the entry being deleted and the database updates being committed. 🫢 don't skip this one bestie, it's giving race condition.

πŸ‘‘ METHODS πŸ‘‘

πŸ’… CACHE DATA METHODS πŸ’…

These are the everyday methods used to access the data stored by the cache.

  • read($key) β€” reads an entry from the cache, or from the underlying data if it's not cached. Returns the value in scalar context, and ($found,$value) in list context, where $found is true if the item was found in either the cache or the underlying data.
  • write($key,$val) β€” writes an entry into the cache, and depending on the configuration, into the underlying data.
  • delete($key) β€” deletes an entry from the cache, and depending on new() options, from the underlying data. Returns the value in scalar context, and ($found,$value) in list context, where $found is true if the item was found in the cache.
  • entries() and entries(0) β€” returns a list of the keys of entries held in the cache. Note that this list may be immediately out of date, because the cache is shared β€” entries may be added or removed by other processes between this list being generated and when it gets used. 😭
  • entries(1) β€” returns a list of hashrefs representing entries held in the cache. The following keys are present in each hashref:
    • key β€” the key used to identify the entry
    • time β€” the time the entry was stored (seconds since the epoch)
    • dirty β€” whether the entry needs writing to the underlying data

Same caveat as above applies to the currency of this information, bestie.

  • entries(2) β€” as entries(1), with the addition of a value element in each hashref, holding the value stored in the cache entry. 🌟
  • quick_clear() β€” forcefully delete the cache, with prejudice. πŸ’€ Unwritten dirty elements are not written back to the underlying data source; they are simply thrown away.

🌈 CONFIGURATION METHODS 🌈

These methods are used to examine/update the configuration of a cache. Most of these methods are read-only, and the value returned may be different from the one you passed to the constructor β€” because the cache may have been created by an earlier process which specified different parameters. so like, don't be surprised. πŸ™ˆ

  • buckets() β€” returns the number of buckets in the cache file.
  • bucketsize() β€” returns the size of buckets (in bytes) in the cache file.
  • cachenegative() β€” returns true if items not found in the underlying data are cached anyway.
  • context() β€” returns the context data for reads and writes to the underlying data.
  • context($context) β€” provides new context data for reads and writes to the underlying data.
  • expiry() β€” returns the time in seconds cache entries are considered valid for, or zero for indefinite validity.
  • pagesize() β€” returns the page size (in bytes) of the cache file.
  • strings() β€” returns true if the cache stores strings rather than references.
  • writethrough() β€” returns true if items written to the cache are immediately written to the underlying data.

✨ AUTHOR ✨

Copyright (C) Institute of Physics Publishing 2002-2008

Peter Haworth <pmh@edison.ioppublishing.com>

You may distribute under the terms of the GPL or the Artistic License, as distributed with Perl. 🫢


and that's the whole page bestie πŸ’œ this was documented for perl v5.42.3, dated 2026-08-19 β€” go build something iconic with it, mwah πŸ’…βœ¨πŸŽ€

πŸ“¦ where this page comes from