MCE::Shared::Cache(3)
π MCE::Shared::Cache(3) π
Okay bestie, this is the User Contributed Perl Documentation page for MCE::Shared::Cache β the hybrid LRU-plain cache helper. Weβre keeping every literal detail, every option, every example, and every vibe. π«Ά
πΈ NAME πΈ
MCE::Shared::Cache β a hybrid LRU-plain cache helper class. Iconic. No notes. π
π VERSION π
This document describes MCE::Shared::Cache version 1.893. Slay. β¨
π¦ DESCRIPTION π¦
Itβs a cache helper class β you can use it as a standalone thing, or let MCE::Shared manage it for you.
This module implements a least-recently used (LRU) cache, and its origin is based on MCE::Shared::Ordhash because of its performance and low-memory characteristics. It is both an LRU implementation and a plain implementation. LRU logic gets applied to new items and to subsequent updates. A fetch, though, only involves LRU reorder if the item is found in the lower section of the cache. That means extra performance for the upper section, because fetch behaves similarly to accessing a plain cache. When it reaches its size restriction, it prunes items from the bottom of the cache.
The 50% LRU-mode (bottom section) / 50% plain-mode (upper-section) split applies to fetches only. π§
β¨ SYNOPSIS β¨
Non-shared or local construction, for when a single process is living its best solo life:
# non-shared or local construction for use by a single process
use MCE::Shared::Cache;
my $ca;
$ca = MCE::Shared::Cache->new(); # max_keys => undef, max_age => undef
$ca = MCE::Shared::Cache->new( { max_keys => 500 }, @pairs );
$ca = MCE::Shared::Cache->new( max_keys => "unlimited", max_age => "never" );
$ca = MCE::Shared::Cache->new( max_keys => undef, max_age => undef ); # ditto
$ca = MCE::Shared::Cache->new( max_keys => 500, max_age => "1 hour" );
$ca = MCE::Shared::Cache->new( max_keys => "4 KiB" ); # 4*1024
$ca = MCE::Shared::Cache->new( max_keys => "1 MiB" ); # 1*1024*1024
$ca = MCE::Shared::Cache->new( max_age => "43200 seconds" );
$ca = MCE::Shared::Cache->new( max_age => 43200 ); # ditto
$ca = MCE::Shared::Cache->new( max_age => "720 minutes" );
$ca = MCE::Shared::Cache->new( max_age => "12 hours" );
$ca = MCE::Shared::Cache->new( max_age => "0.5 days" );
$ca = MCE::Shared::Cache->new( max_age => "1 week" );
$ca = MCE::Shared::Cache->new( max_age => undef ); # no expiration
$ca = MCE::Shared::Cache->new( max_age => 0 ); # now
Construction for sharing with other threads and processes β group chat mode activated:
# construction for sharing with other threads and processes
use MCE::Shared;
my $ca;
$ca = MCE::Shared->cache(); # max_keys => undef, max_age => undef
$ca = MCE::Shared->cache( { max_keys => 500 }, @pairs );
$ca = MCE::Shared->cache( max_keys => "unlimited", max_age => "never" );
$ca = MCE::Shared->cache( max_keys => undef, max_age => undef ); # ditto
$ca = MCE::Shared->cache( max_keys => 500, max_age => "1 hour" );
$ca = MCE::Shared->cache( max_keys => "4 KiB" ); # 4*1024
$ca = MCE::Shared->cache( max_keys => "1 MiB" ); # 1*1024*1024
$ca = MCE::Shared->cache( max_age => "43200 seconds" );
$ca = MCE::Shared->cache( max_age => 43200 ); # ditto
$ca = MCE::Shared->cache( max_age => "720 minutes" );
$ca = MCE::Shared->cache( max_age => "12 hours" );
$ca = MCE::Shared->cache( max_age => "0.5 days" );
$ca = MCE::Shared->cache( max_age => "1 week" );
$ca = MCE::Shared->cache( max_age => undef ); # no expiration
$ca = MCE::Shared->cache( max_age => 0 ); # now
Hash-like dereferencing, because sometimes you just want the classic look:
# hash-like dereferencing
my $val = $ca->{$key};
$ca->{$key} = $val;
%{$ca} = ();
The OO interface β highly recommended, lowkey the main character:
# OO interface
if ( !defined ( $val = $ca->get("some_key") ) ) {
$val = $ca->set( some_key => "some_value" );
}
$val = $ca->set( $key, $val );
$ret = $ca->setnx( $key, $val ); # set only if the key exists
$val = $ca->get( $key );
$val = $ca->delete( $key ); # del is an alias for delete
$bool = $ca->exists( $key );
void = $ca->clear();
$len = $ca->len(); # scalar keys %{ $ca }
$len = $ca->len( $key ); # length $ca->{ $key }
$iter = $ca->iterator( @keys ); # ($key, $val) = $iter->()
@keys = $ca->keys( @keys ); # @keys is optional
%pairs = $ca->pairs( @keys );
@vals = $ca->values( @keys ); # vals is an alias for values
$len = $ca->assign( $key/$val pairs ); # equivalent to ->clear, ->mset
$cnt = $ca->mdel( @keys );
@vals = $ca->mget( @keys );
$bool = $ca->mexists( @keys ); # true if all keys exists
$len = $ca->mset( $key/$val pairs ); # merge is an alias for mset
Included sugar methods, so you donβt have to call set/get explicitly:
# included, sugar methods without having to call set/get explicitly
$len = $ca->append( $key, $string ); # $val .= $string
$val = $ca->decr( $key ); # --$val
$val = $ca->decrby( $key, $number ); # $val -= $number
$val = $ca->getdecr( $key ); # $val--
$val = $ca->getincr( $key ); # $val++
$val = $ca->incr( $key ); # ++$val
$val = $ca->incrby( $key, $number ); # $val += $number
$old = $ca->getset( $key, $new ); # $o = $v, $v = $n, $o
Pipeline, which provides atomicity for shared objects, MCE::Shared v1.09+:
# pipeline, provides atomicity for shared objects, MCE::Shared v1.09+
@vals = $ca->pipeline( # ( "a_a", "b_b", "c_c" )
[ "set", foo => "a_a" ],
[ "set", bar => "b_b" ],
[ "set", baz => "c_c" ],
[ "mget", qw/ foo bar baz / ]
);
For normal hash behavior, the TIE interface is supported. π
# non-shared or local construction for use by a single process
use MCE::Shared::Cache;
tie my %ca, "MCE::Shared::Cache", max_keys => undef, max_age => undef;
tie my %ca, "MCE::Shared::Cache", max_keys => 500, max_age => "1 hour";
tie my %ca, "MCE::Shared::Cache", { max_keys => 500 }, @pairs;
# construction for sharing with other threads and processes
# one option is needed minimally to know to use MCE::Shared::Cache
use MCE::Shared;
tie my %ca, "MCE::Shared", max_keys => undef, max_age => undef;
tie my %ca, "MCE::Shared", max_keys => 500, max_age => "1 hour";
tie my %ca, "MCE::Shared", { max_keys => 500 }, @pairs;
# usage
my $val;
if ( !defined ( $val = $ca{some_key} ) ) {
$val = $ca{some_key} = "some_value";
}
$ca{some_key} = 0;
tied(%ca)->incrby("some_key", 20);
tied(%ca)->incrby(some_key => 20);
π SYNTAX for QUERY STRING π
Several methods take a query string as an argument. The format of that string is described below. When youβre in sharing mode, this query mechanism is a big win for the shared-manager process: it can perform the query where the data actually lives, instead of the client process grepping locally and dragging lots of IPC into the situation. π
- Basic demonstration:
@keys = $ca->keys( "query string given here" );
@keys = $ca->keys( "val =~ /pattern/" );
- Supported operators:
=~ !~ eq ne lt le gt ge == != < <= > >= - Multiple expressions delimited by
:ANDor:OR, mixed case allowed:
"key eq 'some key' :or (val > 5 :and val < 9)"
"key eq some key :or (val > 5 :and val < 9)"
"key =~ /pattern/i :And val =~ /pattern/i"
"val eq foo baz :OR key !~ /pattern/i"
keymatches on keys in the cache- likewise,
valmatches on values
- Quoting is optional inside the string:
"key =~ /pattern/i :AND val eq 'foo bar'" # val eq "foo bar"
"key =~ /pattern/i :AND val eq foo bar" # val eq "foo bar"
Examples. Search capability key/val: =~ !~ eq ne lt le gt ge == != < <= > >=; key/val means to match against the actual key/val respectively:
# search capability key/val: =~ !~ eq ne lt le gt ge == != < <= > >=
# key/val means to match against actual key/val respectively
@keys = $ca->keys( "key eq 'some key' :or (val > 5 :and val < 9)" );
@keys = $ca->keys( "key eq some key :or (val > 5 :and val < 9)" );
@keys = $ca->keys( "key =~ /$pattern/i" );
@keys = $ca->keys( "key !~ /$pattern/i" );
@keys = $ca->keys( "val =~ /$pattern/i" );
@keys = $ca->keys( "val !~ /$pattern/i" );
%pairs = $ca->pairs( "key == $number" );
%pairs = $ca->pairs( "key != $number :and val > 100" );
%pairs = $ca->pairs( "key < $number :or key > $number" );
%pairs = $ca->pairs( "val <= $number" );
%pairs = $ca->pairs( "val > $number" );
%pairs = $ca->pairs( "val >= $number" );
@vals = $ca->vals( "key eq $string" );
@vals = $ca->vals( "key ne $string with space" );
@vals = $ca->vals( "key lt $string :or val =~ /$pat1|$pat2/" );
@vals = $ca->vals( "val le $string :and val eq 'foo bar'" );
@vals = $ca->vals( "val le $string :and val eq foo bar" );
@vals = $ca->vals( "val gt $string" );
@vals = $ca->vals( "val ge $string" );
π API DOCUMENTATION π
This module involves TIE when you access the object via hash-like behavior. Both non-shared and shared instances are impacted if you do that. Itβs likely fast enough for many use cases, but the OO interface is recommended for best performance. π
Accessing an item is likely to involve moving its key to the top of the cache. Various methods described below will state "Reorder: Yes" or "Reorder: No" as an indication. π
The methods "keys", "pairs", and "values" return the most frequently accessed items from the upper section of the cache first, before the lower section. Returned values may not be ordered as expected. This βabnormally is normalβ situation is normal for this hybrid LRU-plain implementation. It comes from fetches not involving LRU movement on keys residing in the upper section of the cache.
When "max_age" is set, accessing an item which has expired will behave similarly to a non-existing item. π«Ά
π MCE::Shared::Cache->new ( { options }, key, value [, key, value, ... ] ) π
π MCE::Shared->cache ( { options }, key, value [, key, value, ... ] ) π
Constructs a new object.
# non-shared or local construction for use by a single process
use MCE::Shared::Cache;
$ca = MCE::Shared::Cache->new(); # max_keys => undef, max_age => undef
$ca = MCE::Shared::Cache->new( { max_keys => 500 }, @pairs );
$ca = MCE::Shared::Cache->new( max_keys => "unlimited", max_age => "never" );
$ca = MCE::Shared::Cache->new( max_keys => undef, max_age => undef ); # ditto
$ca = MCE::Shared::Cache->new( max_keys => 500, max_age => "1 hour" );
$ca = MCE::Shared::Cache->new( max_keys => "4 KiB" ); # 4*1024
$ca = MCE::Shared::Cache->new( max_keys => "1 MiB" ); # 1*1024*1024
$ca = MCE::Shared::Cache->new( max_age => "43200 seconds" );
$ca = MCE::Shared::Cache->new( max_age => 43200 ); # ditto
$ca = MCE::Shared::Cache->new( max_age => "720 minutes" );
$ca = MCE::Shared::Cache->new( max_age => "12 hours" );
$ca = MCE::Shared::Cache->new( max_age => "0.5 days" );
$ca = MCE::Shared::Cache->new( max_age => "1 week" );
$ca = MCE::Shared::Cache->new( max_age => undef ); # no expiration
$ca = MCE::Shared::Cache->new( max_age => 0 ); # now
$ca->assign( @pairs );
# construction for sharing with other threads and processes
use MCE::Shared;
$ca = MCE::Shared->cache(); # max_keys => undef, max_age => undef
$ca = MCE::Shared->cache( { max_keys => 500 }, @pairs );
$ca = MCE::Shared->cache( max_keys => "unlimited", max_age => "never" );
$ca = MCE::Shared->cache( max_keys => undef, max_age => undef ); # ditto
$ca = MCE::Shared->cache( max_keys => 500, max_age => "1 hour" );
$ca = MCE::Shared->cache( max_keys => "4 KiB" ); # 4*1024
$ca = MCE::Shared->cache( max_keys => "1 MiB" ); # 1*1024*1024
$ca = MCE::Shared->cache( max_age => "43200 seconds" );
$ca = MCE::Shared->cache( max_age => 43200 ); # ditto
$ca = MCE::Shared->cache( max_age => "720 minutes" );
$ca = MCE::Shared->cache( max_age => "12 hours" );
$ca = MCE::Shared->cache( max_age => "0.5 days" );
$ca = MCE::Shared->cache( max_age => "1 week" );
$ca = MCE::Shared->cache( max_age => undef ); # no expiration
$ca = MCE::Shared->cache( max_age => 0 ); # now
$ca->assign( @pairs );
Reorder: Yes, when given key-value pairs contain duplicate keys
π«Ά assign ( key, value [, key, value, ... ] )
Okay so assign is like a factory reset + a fresh drop, all in one π It clears the cache first, then sets a whole bunch of key-value pairs, and hands you back the number of keys that ended up stored in the cache. Basically it's the same energy as calling clear and then mset. Two-for-one, iconic.
$len = $ca->assign( "key1" => "val1", "key2" => "val2" );
Reorder: Yes, when given key-value pairs contain duplicate keys
π§Ή clear
Gone. Deleted. Not in this timeline. π Removes all key-value pairs from the cache.
$ca->clear;
%{$ca} = ();
ποΈ delete ( key )
Deletes the value sitting at the given key and returns it β or gives you back undef if that key does not exists in the cache. Rip bozo πͺ¦
$val = $ca->delete( "some_key" );
$val = delete $ca->{ "some_key" };
β¨ del
del is an alias for delete. Same thing, shorter vibe. iykyk.
π exists ( key )
Checks whether a key is actually living in the cache. Very vibe check of it.
if ( $ca->exists( "some_key" ) ) { ... }
if ( exists $ca->{ "some_key" } ) { ... }
Reorder: No
π get ( key )
Grabs the value of a cache key, or undef if the key does not exists. Important detail bestie: LRU reordering happens only if the key is found in the lower section of the cache. If you want zero reordering and no promoting, go look at peek β that one does not promote the key internally to the top of the list π«‘
$val = $ca->get( "some_key" );
$val = $ca->{ "some_key" };
Reorder: Yes
π¦ iterator ( key [, key, ... ] )
When max_age is set, this prunes any expired keys at the head of the list β housekeeping, but make it fashion π§
With no arguments it returns a code reference for iterating a list of key-value pairs stored in the cache. Give it arguments and you get a code reference for iterating the given keys in the same order. Keys that do not exist will have the undef value.
The list of keys to return is set when the closure is constructed β so keys added to the hash later are not included. And subsequently, the undef value is returned for deleted keys. Closure said what it said π
$iter = $ca->iterator;
$iter = $ca->iterator( "key1", "key2" );
while ( my ( $key, $val ) = $iter->() ) {
...
}
Reorder: No
π iterator ( "query string" )
When max_age is set, prunes any expired keys at the head of the list. Same deal as above, still slaying.
Returns a code reference for iterating a list of key-value pairs that match the given criteria. It returns an empty list if the search found nothing π The syntax for the query string is described above.
$iter = $ca->iterator( "val eq some_value" );
$iter = $ca->iterator( "key eq some_key :AND val =~ /sun|moon|air|wind/" );
$iter = $ca->iterator( "val eq sun :OR val eq moon :OR val eq foo" );
$iter = $ca->iterator( "key =~ /$pattern/" );
while ( my ( $key, $val ) = $iter->() ) {
...
}
Reorder: No
π keys ( key [, key, ... ] )
When max_age is set, prunes any expired keys at the head of the list β°
With no arguments, returns all keys in the cache by most frequently accessed β the popular girlies get listed first π Otherwise, returns the given keys in the same order. Keys that do not exist will have the undef value. In scalar context, returns the size of the cache.
@keys = $ca->keys;
@keys = $ca->keys( "key1", "key2" );
$len = $ca->keys;
Reorder: No
π keys ( "query string" )
When max_age is set, prunes any expired keys at the head of the list.
Returns only keys that match the given criteria. Empty list if the search found nothing, no cap. The syntax for the query string is described above. And in scalar context, it returns the size of the resulting list.
@keys = $ca->keys( "val eq some_value" );
@keys = $ca->keys( "key eq some_key :AND val =~ /sun|moon|air|wind/" );
@keys = $ca->keys( "val eq sun :OR val eq moon :OR val eq foo" );
$len = $ca->keys( "key =~ /$pattern/" );
Reorder: No
π len ( key )
When max_age is set, prunes any expired keys at the head of the list.
With no arguments it returns the size of the cache. Give it a key and it returns the length of the value stored at that key β or the undef value if the key does not exists. Two totally different numbers, don't mix them up bestie π
$size = $ca->len;
$len = $ca->len( "key1" );
$len = length $ca->{ "key1" };
Reorder: Yes, only when key is given
β³ max_age ( [ secs ] )
Returns the maximum age set on the cache β or "never" if it's not defined internally. Hand it some seconds and it sets the default expiry time. It's giving time wizard π§ββοΈ
$age = $ca->max_age;
$ca->max_age( "43200 seconds" );
$ca->max_age( 43200 ); # ditto
$ca->max_age( "720 minutes" );
$ca->max_age( "12 hours" );
$ca->max_age( "0.5 days" );
$ca->max_age( "1 week" );
$ca->max_age( undef ); # no expiration
$ca->max_age( 0 ); # now
π¦ max_keys ( [ size ] )
Returns the size limit set on the cache β or "unlimited" if it's not defined internally. When you give it a size, it adjusts the cache to the new size, pruning the head of the list if necessary. Yes it will absolutely trim the ends to fit the fit βοΈ
$size = $ca->max_keys;
$ca->max_keys( undef ); # unlimited
$ca->max_keys( "4 KiB" ); # 4*1024
$ca->max_keys( "1 MiB" ); # 1*1024*1024
$ca->max_keys( 500 );
𧨠mdel ( key [, key, ... ] )
Deletes one or more keys in the cache and returns the number of keys deleted. Heads up: a given key which does not exist in the cache is not counted. No credit for imaginary deletions π
$cnt = $ca->mdel( "key1", "key2" );
β mexists ( key [, key, ... ] )
Returns a true value if all given keys exists in the cache. A false value is returned otherwise. All of them or nothing, we don't do half-hearted here.
if ( $ca->mexists( "key1", "key2" ) ) { ... }
Reorder: No
π mget ( key [, key, ... ] )
Gets the values of all the given keys. It returns undef for keys which do not exists in the cache. Bulk grab, very efficient, we love her π«Ά
( $val1, $val2 ) = $ca->mget( "key1", "key2" );
Reorder: Yes
π mset ( key, value [, key, value, ... ] )
Sets multiple key-value pairs in a cache and returns the number of keys stored in the cache. That's the whole thing, she's simple and she delivers.
$len = $ca->mset( "key1" => "val1", "key2" => "val2" );
Reorder: Yes
π₯ merge
merge is an alias for mset. Cute nickname, same function.
π― pairs ( key [, key, ... ] )
When max_age is set, prunes any expired keys at the head of the list.
With no arguments, returns key-value pairs in the cache by most frequently accessed. Otherwise, returns key-value pairs for the given keys in the same order. Keys that do not exist will have the undef value. In scalar context, returns the size of the cache.
@pairs = $ca->pairs;
@pairs = $ca->pairs( "key1", "key2" );
$len = $ca->pairs;
Reorder: No
π§ pairs ( "query string" )
When max_age is set, prunes any expired keys at the head of the list.
Returns only key-value pairs that match the given criteria. It returns an empty list if the search found nothing. The syntax for the query string is described above. In scalar context, returns the size of the resulting list.
@pairs = $ca->pairs( "val eq some_value" );
@pairs = $ca->pairs( "key eq some_key :AND val =~ /sun|moon|air|wind/" );
@pairs = $ca->pairs( "val eq sun :OR val eq moon :OR val eq foo" );
$len = $ca->pairs( "key =~ /$pattern/" );
Reorder: No
π peek ( key )
Same as get but without changing the order of the keys. Gets the value of a cache key or undef if the key does not exists. Look, don't touch, no shuffling the deck π
$val = $ca->get( "some_key" );
$val = $ca->{ "some_key" };
Reorder: No
π pipeline ( [ func1, @args ], [ func2, @args ], ... )
Combines multiple commands for the object to be processed serially. For shared objects, the call is made atomically due to a single IPC to the shared-manager process β one trip, many commands, iconic efficiency β¨ The pipeline method is fully wantarray-aware and receives a list of commands and their arguments. In scalar or list context, it returns data from the last command in the pipeline.
@vals = $ca->pipeline( # ( "a_a", "b_b", "c_c" )
[ "set", foo => "a_a" ],
[ "set", bar => "b_b" ],
[ "set", baz => "c_c" ],
[ "mget", qw/ foo bar baz / ]
);
$len = $ca->pipeline( # 3, same as $ca->len
[ "set", foo => "i_i" ],
[ "set", bar => "j_j" ],
[ "set", baz => "k_k" ],
[ "len" ]
);
$ca->pipeline(
[ "set", foo => "m_m" ],
[ "set", bar => "n_n" ],
[ "set", baz => "o_o" ]
);
Reorder: Very likely, see API on given method
π pipeline_ex ( [ func1, @args ], [ func2, @args ], ... )
Same as pipeline, but returns data for every command in the pipeline. Not just the last one β the whole group chat gets a reply π¬
@vals = $ca->pipeline_ex( # ( "a_a", "b_b", "c_c" )
[ "set", foo => "a_a" ],
[ "set", bar => "b_b" ],
[ "set", baz => "c_c" ]
);
Reorder: Very likely, see API on given command
π§Ό purge ( )
Remove all tombstones and expired data from the cache. Deep clean, self-care Sunday energy π
$ca->purge;
π«§ remove
remove is an alias for delete. Three names for one job, honestly relatable.
πΈ set ( key, value [, expires_in ] )
Sets the value of the given cache key and returns its new value. Optionally β and this is in v1.839 and later releases β you can give the number of seconds before the key is expired β²οΈ
$val = $ca->set( "key", "value" );
$val = $ca->{ "key" } = "value";
$val = $ca->set( "key", "value", 3600 ); # or "60 minutes"
$val = $ca->set( "key", "value", undef ); # or "never"
$val = $ca->set( "key", "value", 0 ); # or "now"
$val = $ca->set( "key", "value", "2 seconds" ); # or "2s"
$val = $ca->set( "key", "value", "2 minutes" ); # or "2m"
$val = $ca->set( "key", "value", "2 hours" ); # or "2h"
$val = $ca->set( "key", "value", "2 days" ); # or "2d"
$val = $ca->set( "key", "value", "2 weeks" ); # or "2w"
Reorder: Yes
π¦ setnx ( key, value [, expires_in ] )
Sets the value of a hash key, only if the key does not exist. Returns a 1 for new key or 0 if the key already exists and no operation was performed. Optionally, give the number of seconds before the key is expired. It's the "no takebacks, no overwrites" option π€
$ret = $ca->setnx( "key", "value" );
Current API available since 1.872.
Reorder: Yes
π» values ( key [, key, ... ] )
When max_age is set, prunes any expired keys at the head of the list.
Returns all values in the cache by most frequently accessed when no arguments are given. Otherwise, returns values for the given keys in the same order. Keys that do not exist will have the undef value. In scalar context, returns the size of the cache.
okay so the plain values calls are giving very much:
@vals = $ca->values;
@vals = $ca->values( "key1", "key2" );
$len = $ca->values;
Reorder: No
π values ( "query string" )
When "max_age" is set, it prunes any expired keys at the head of the list. That's the cleanup era. It returns only values that match the given criteria, and it returns an empty list if the search found nothing. The syntax for the "query string" is described above (iykyk). In scalar context, it returns the size of the resulting list.
@vals = $ca->values( "val eq some_value" );
@vals = $ca->values( "key eq some_key :AND val =~ /sun|moon|air|wind/" );
@vals = $ca->values( "val eq sun :OR val eq moon :OR val eq foo" );
$len = $ca->values( "key =~ /$pattern/" );
Reorder: No
π vals
vals is literally an alias for values. Same energy, shorter name. π«Ά
π SUGAR METHODS
This module is equipped with sugar methods so you don't have to call set and get explicitly. In shared context, the benefit is atomicity and reduction in inter-process communication.
The API is giving a subset of the Redis primitives (https://redis.io/commands#strings), with key representing the cache key.
Optionally in v1.839 and later releases, give the number of seconds before the key is expired, similarly to set.
π¬ append ( key, string [, expires_in ] )
Appends a value to a key and returns its new length.
$len = $ca->append( $key, "foo" );
Reorder: Yes
π¬ decr ( key [, expires_in ] )
Decrements the value of a key by one and returns its new value.
$num = $ca->decr( $key );
Reorder: Yes
π¬ decrby ( key, number [, expires_in ] )
Decrements the value of a key by the given number and returns its new value.
$num = $ca->decrby( $key, 2 );
Reorder: Yes
π¬ getdecr ( key [, expires_in ] )
Decrements the value of a key by one and returns its old value β the before pic. π
$old = $ca->getdecr( $key );
Reorder: Yes
π¬ getincr ( key [, expires_in ] )
Increments the value of a key by one and returns its old value β also the before pic. π
$old = $ca->getincr( $key );
Reorder: Yes
π¬ getset ( key, value [, expires_in ] )
Sets the value of a key and returns its old value. The glow-up is real.
$old = $ca->getset( $key, "baz" );
Reorder: Yes
π¬ incr ( key [, expires_in ] )
Increments the value of a key by one and returns its new value.
$num = $ca->incr( $key );
Reorder: Yes
π¬ incrby ( key, number [, expires_in ] )
Increments the value of a key by the given number and returns its new value.
$num = $ca->incrby( $key, 2 );
Reorder: Yes
π§ INTERNAL METHODS
Internal "Sereal" freeze-thaw hooks for exporting shared-cache object:
FREEZETHAW
Internal "Storable" freeze-thaw hooks for exporting shared-cache object:
STORABLE_freezeSTORABLE_thaw
π₯ PERFORMANCE TESTING
One might want to benchmark this module. If yes, remember to use the non-shared construction for running on a single core.
use MCE::Shared::Cache;
my $cache = MCE::Shared::Cache->new( max_keys => 500_000 );
Otherwise, the following is a parallel version for a benchmark script (https://blog.celogeek.com/201401/426/perl-benchmark-cache-with-expires-and-max-size) found on the web. The serial version was created by Celogeek for benchmarking various caching modules.
The MCE progress option makes it possible to track progress while running parallel. This script involves IPC to and from the shared-manager process, where the data resides. In regards to IPC, fetches may take longer on Linux versus Darwin or FreeBSD.
#!/usr/bin/perl
use strict;
use warnings;
use feature qw( say );
use Digest::MD5 qw( md5_base64 );
use Time::HiRes qw( time );
use MCE 1.814;
use MCE::Shared;
$| = 1; srand(0);
# construct shared variables
# serialization is handled automatically
my $c = MCE::Shared->cache( max_keys => 500_000 );
my $found = MCE::Shared->scalar( 0 );
# construct and spawn MCE workers
# workers increment a local variable $f
my $mce = MCE->new(
chunk_size => 4000,
max_workers => 4,
user_func => sub {
my ($mce, $chunk_ref, $chunk_id) = @_;
if ( $mce->user_args()->[0] eq 'setter' ) {
for ( @{ $chunk_ref } ) { $c->set($_, {md5 => $_}) }
}
else {
my $f = 0;
for ( @{ $chunk_ref } ) { $f++ if ref $c->get($_) eq 'HASH' }
$found->incrby($f);
}
}
)->spawn();
say "Mapping";
my @todo = map { md5_base64($_) } ( 1 .. 600_000 );
say "Starting";
my ( $read, $write );
{
my $s = time;
$mce->process({
progress => sub { print "Write: $_[0]\r" },
user_args => [ 'setter' ],
}, \@todo);
$write = time - $s;
}
say "Write: ", sprintf("%0.3f", scalar(@todo) / $write);
{
my $s = time;
$found->set(0);
$mce->process({
progress => sub { print "Read $_[0]\r" },
user_args => [ 'getter' ],
}, \@todo);
$read = time - $s;
}
$mce->shutdown();
say "Read : ", sprintf("%0.3f", scalar(@todo) / $read);
say "Found: ", $found->get();
The progress option is further described on Metacpan. Several examples are provided, accommodating all input data-types in MCE.
Progress Demonstrations (https://metacpan.org/pod/MCE::Core#PROGRESS-DEMONSTRATIONS) β that's the doc link. π
πΈ SEE ALSO
- CHI
- Cache::FastMmap
- Cache::LRU
- Cache::Ref
- Tie::Cache::LRU
- Tie::Cache::LRU::Expires
π¦ INDEX
MCE, MCE::Hobo, MCE::Shared β that's the index, bestie. β¨
π AUTHOR
Mario E. Roy, <marioeroy AT gmail DOT com>
That's the whole manpage, bestie! It's from perl v5.40.0, dated 2024-09-10, and it's MCE::Shared::Cache(3). Periodt. πβ¨π
π¦ where this page comes from
- epel 10: perl-MCE-Shared 1.893-1.el10_0 Β· GPL-1.0-or-later OR Artistic-1.0-Perl
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms