PHP Class MatthiasMullie\Scrapbook\Buffered\Utils\Defer

Optimizations will be: * multiple set() values (with the same expiration) will be applied in a single setMulti() * for a set() followed by another set() on the same key, only the latter one will be applied * same for an replace() followed by an increment(), or whatever operation happens on the same key: if we can pre-calculate the end result, we'll only execute 1 operation with the end result * operations before a flush() will not be executed, they'll just be lost Rollback strategy includes: * fetching the original value of operations prone to fail (add, replace & cas) prior to executing them * executing said operations before the others, to minimize changes of interfering concurrent writes * if the commit fails, said original values will be restored in case the new value had already been stored This class must never receive invalid data. E.g. a "replace" can never follow a "delete" of the same key. This should be guaranteed by whatever uses this class: there is no point in re-implementing these checks here. The only acceptable conflicts are when cache values have changed outside, from another process. Those will be handled by this class.
Author: Matthias Mullie ([email protected])
Show file Open project: matthiasmullie/scrapbook Class Usage Examples

Protected Properties

Property Type Description
$cache MatthiasMullie\Scrapbook\KeyValueStore Cache to write to.
$flush boolean Flush is special - it's not specific to (a) key(s), so we can't store it to $keys.
$keys array[] E.g. 2 sets, the later will override the former. E.g. set + increment, might as well set incremented value immediately. This is going to be an array that holds horrible arrays of update data, being: * 0: the operation name (set, add, ...) so we're able to sort them * 1: a callable, to apply the update to cache * 2: the array of data to supply to the callable

Public Methods

Method Description
__construct ( MatthiasMullie\Scrapbook\KeyValueStore $cache )
__destruct ( )
add ( string $key, mixed $value, integer $expire )
cas ( mixed $originalValue, string $key, mixed $value, integer $expire )
clear ( ) Clears all scheduled writes.
commit ( ) : boolean Commit all deferred writes to cache.
decrement ( string $key, integer $offset, integer $initial, integer $expire )
delete ( string $key )
deleteMulti ( array $keys )
flush ( )
increment ( string $key, integer $offset, integer $initial, integer $expire )
replace ( string $key, mixed $value, integer $expire )
set ( string $key, mixed $value, integer $expire )
setMulti ( array $items, integer $expire )
touch ( string $key, integer $expire )

Protected Methods

Method Description
combineUpdates ( array $updates ) : array We may have multiple sets & deletes, which can be combined into a single setMulti or deleteMulti operation.
doIncrement ( string $operation, string $key, integer $offset, integer $initial, integer $expire )
generateRollback ( ) : array[] Since we can't perform true atomic transactions, we'll fake it.
generateUpdates ( ) : array By storing all updates by key, we've already made sure we don't perform redundant operations on a per-key basis. Now we'll turn those into actual updates.
rollback ( array $old, array $new ) Roll the cache back to pre-transaction state by comparing the current cache values with what we planned to set them to.
sortUpdates ( array $a, array $b ) : integer Change the order of the updates in this transaction to ensure we have those most likely to fail first. That'll decrease odds of having to roll back, and make rolling back easier.

Method Details

__construct() public method

public __construct ( MatthiasMullie\Scrapbook\KeyValueStore $cache )
$cache MatthiasMullie\Scrapbook\KeyValueStore

__destruct() public method

public __destruct ( )

add() public method

public add ( string $key, mixed $value, integer $expire )
$key string
$value mixed
$expire integer

cas() public method

public cas ( mixed $originalValue, string $key, mixed $value, integer $expire )
$originalValue mixed No real CAS token, but the original value for this key
$key string
$value mixed
$expire integer

clear() public method

Clears all scheduled writes.
public clear ( )

combineUpdates() protected method

We may have multiple sets & deletes, which can be combined into a single setMulti or deleteMulti operation.
protected combineUpdates ( array $updates ) : array
$updates array
return array

commit() public method

When the commit fails, no changes in this transaction will be applied (and those that had already been applied will be undone). False will be returned in that case.
public commit ( ) : boolean
return boolean

decrement() public method

public decrement ( string $key, integer $offset, integer $initial, integer $expire )
$key string
$offset integer
$initial integer
$expire integer

delete() public method

public delete ( string $key )
$key string

deleteMulti() public method

public deleteMulti ( array $keys )
$keys array

doIncrement() protected method

protected doIncrement ( string $operation, string $key, integer $offset, integer $initial, integer $expire )
$operation string
$key string
$offset integer
$initial integer
$expire integer

flush() public method

public flush ( )

generateRollback() protected method

Most of the operations (set, touch, ...) can't fail. We'll do those last. We'll first schedule the operations that can fail (cas, replace, add) to minimize chances of another process overwriting those values in the meantime. But it could still happen, so we should fetch the current values for all unsafe operations. If the transaction fails, we can then restore them.
protected generateRollback ( ) : array[]
return array[] Array of 2 [key => value] maps: current & scheduled data

generateUpdates() protected method

By storing all updates by key, we've already made sure we don't perform redundant operations on a per-key basis. Now we'll turn those into actual updates.
protected generateUpdates ( ) : array
return array

increment() public method

public increment ( string $key, integer $offset, integer $initial, integer $expire )
$key string
$offset integer
$initial integer
$expire integer

replace() public method

public replace ( string $key, mixed $value, integer $expire )
$key string
$value mixed
$expire integer

rollback() protected method

Roll the cache back to pre-transaction state by comparing the current cache values with what we planned to set them to.
protected rollback ( array $old, array $new )
$old array
$new array

set() public method

public set ( string $key, mixed $value, integer $expire )
$key string
$value mixed
$expire integer

setMulti() public method

public setMulti ( array $items, integer $expire )
$items array
$expire integer

sortUpdates() protected method

Change the order of the updates in this transaction to ensure we have those most likely to fail first. That'll decrease odds of having to roll back, and make rolling back easier.
protected sortUpdates ( array $a, array $b ) : integer
$a array Update, where index 0 is the operation name
$b array Update, where index 0 is the operation name
return integer

touch() public method

public touch ( string $key, integer $expire )
$key string
$expire integer

Property Details

$cache protected property

Cache to write to.
protected KeyValueStore,MatthiasMullie\Scrapbook $cache
return MatthiasMullie\Scrapbook\KeyValueStore

$flush protected property

Flush is special - it's not specific to (a) key(s), so we can't store it to $keys.
protected bool $flush
return boolean

$keys protected property

E.g. 2 sets, the later will override the former. E.g. set + increment, might as well set incremented value immediately. This is going to be an array that holds horrible arrays of update data, being: * 0: the operation name (set, add, ...) so we're able to sort them * 1: a callable, to apply the update to cache * 2: the array of data to supply to the callable
protected array[] $keys
return array[]