Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
194 changes: 138 additions & 56 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,20 @@

A flexible memoization library for memory caching.

## Table of Contents

- [Memoization](#memoization)
- [Installation](#installation)
- [Notes on examples](#notes-on-examples)
- [Usage](#usage)
- [Simple example](#simple-example)
- [Setting a nested structure](#setting-a-nested-structure)
- [Purging a nested structure](#purging-a-nested-structure)
- [Caching with closures](#caching-with-closures)
- [Using with a dependency injection container](#using-with-a-dependency-injection-container)
- [Drivers](#drivers)
- [MemoryDriver](#memorydriver)

## Memoization

[Memoization](https://en.wikipedia.org/wiki/Memoization) is the process of caching the results of expensive function calls so that they can be reused when the same inputs occur again.
Expand All @@ -29,26 +43,30 @@ All namespaces within the examples will be using the `StellarWP\Memoize`, howeve
### Simple example

```php
use StellarWP\Memoize\Memoize;
use StellarWP\Memoize\Memoizer;

$memoizer = new Memoizer();

Memoize::set('foo', 'bar');
$memoizer->set('foo', 'bar');

if (Memoize::has('foo')) {
echo Memoize::get('foo'); // Outputs: bar
if ($memoizer->has('foo')) {
echo $memoizer->get('foo'); // Outputs: bar
}

// Unsets foo from the memoization cache.
Memoize::forget('foo');
$memoizer->forget('foo');
```

### Setting a nested structure

Memoize allows you to use dot notation to set, get, and forget values from a nested structure. This allows you to easily add/fetch values and then purge individual items or whole collections of items.

```php
use StellarWP\Memoize\Memoize;
use StellarWP\Memoize\Memoizer;

Memoize::set('foo.bar.bork', 'baz');
$memoizer = new Memoizer();

$memoizer->set('foo.bar.bork', 'baz');

// This results in the following cache:
// [
Expand All @@ -60,27 +78,29 @@ Memoize::set('foo.bar.bork', 'baz');
// ]

// You can fetch the value like so:
$value = Memoize::get('foo.bar.bork');
$value = $memoizer->get('foo.bar.bork');
echo $value; // Outputs: baz

// You can fetch anywhere up the chain:
$value = Memoize::get('foo.bar');
$value = $memoizer->get('foo.bar');
echo $value; // Outputs: [ 'bork' => 'baz' ]

$value = Memoize::get('foo');
$value = $memoizer->get('foo');
echo $value; // Outputs: [ 'bar' => [ 'bork' => 'baz' ] ]

$value = Memoize::get();
$value = $memoizer->get();
echo $value; // Outputs: [ 'foo' => [ 'bar' => [ 'bork' => 'baz' ] ] ]
```

#### Purging a nested structure

```php
use StellarWP\Memoize\Memoize;
use StellarWP\Memoize\Memoizer;

$memoizer = new Memoizer();

Memoize::set('foo.bar.bork', 'baz');
Memoize::forget('foo.bar.bork');
$memoizer->set('foo.bar.bork', 'baz');
$memoizer->forget('foo.bar.bork');

// This results in the following cache:
// [
Expand All @@ -89,76 +109,59 @@ Memoize::forget('foo.bar.bork');
// ],
// ]

Memoize::forget('foo.bar');
$memoizer->forget('foo.bar');

// This results in the following cache:
// [
// 'foo' => [],
// ]

Memoize::forget('foo');
$memoizer->forget('foo');

// This results in the following cache:
// []

Memoize::forget();
$memoizer->forget();

// This results in the following cache:
// []
```

### Caching an expensive execution

```php
use StellarWP\Memoize\Memoize;

function my_expensive_function() {
$key = __FUNCTION__;
$value = Memoize::get($key);

if ( ! $value ) {
// Do some crazy expensive stuff to set:

$value = $thing;

Memoize::set($key, $value);
}

return $value;
}
```

### Caching with closures

Memoize also supports caching closures as values that get resolved when retrieved from the cache.

#### Simple example
```php
use StellarWP\Memoize\Memoize;
use StellarWP\Memoize\Memoizer;

Memoize::set('foo', static function () {
$memoizer = new Memoizer();

$memoizer->set('foo', static function () {
return 'bar';
});

echo Memoize::get('foo'); // Outputs: bar
echo $memoizer->get('foo'); // Outputs: bar
```

#### Nested example

If you get a key that contains multiple closures in its tree, it will traverse the tree and resolve all of those closures.

```php
use StellarWP\Memoize\Memoize;
use StellarWP\Memoize\Memoizer;

$memoizer = new Memoizer();

Memoize::set('stellarwp.bork', static function () {
$memoizer->set('stellarwp.bork', static function () {
return 'lol';
});

Memoize::set('stellarwp.foo.bar', static function () {
$memoizer->set('stellarwp.foo.bar', static function () {
return 'baz';
});

print_r( Memoize::get('stellarwp') );
print_r( $memoizer->get('stellarwp') );
// Outputs:
// [
// 'bork' => 'lol',
Expand All @@ -168,28 +171,107 @@ print_r( Memoize::get('stellarwp') );
// ]
```

## Drivers
### Using with a dependency injection container

Memoize comes with a few drivers out of the box, but you can also create your own.
#### Project class

### MemoryDriver
```php
<?php

The `MemoryDriver` is a simple in-memory driver is in-memory memoization. Basically, there's a static variable in the driver that holds the memoized values. You can manually specify the use of this driver like so:
declare(strict_types=1);

namespace StellarWP\MyProject;

use StellarWP\Memoize\MemoizerInterface;

// Dependencies automatically auto-wired due to the definitions in ServiceProvider.php via
// $this->container->get( MyProjectClass::class )

/**
* An example class inside your project using the Memoize library.
*/
class MyProjectClass
{

private MemoizerInterface $memoizer;

public function __construct( MemoizerInterface $memoizer )
{
$this->memoizer = $memoizer;
}

public function get( string $name ): string
{
$result = $this->memoizer->get( $name );

if ( ! $result ) {
$result = 'some very expensive operation';

$this->memoizer->set( $name, $result );
}

return $result;
}

public function delete( string $name ): bool
{
$this->memoizer->forget( $name );

// Run delete operation...

return true;
}
}
```

#### Service Provider

```php
use StellarWP\Memoize\Config;
<?php

declare(strict_types=1);

namespace StellarWP\Memoize;

use StellarWP\ContainerContract\ContainerInterface;
use StellarWP\Memoize\Contracts\DriverInterface;
use StellarWP\Memoize\Contracts\MemoizerInterface;
use StellarWP\Memoize\Drivers\MemoryDriver;

Config::setDriver(new MemoryDriver());
/**
* Container ServiceProvider to tell the DI Container how to build everything when another
* instance is requested from the Container that uses our interface.
*
* @example $this->container->get( MyProjectClass::class );
*/
final class ServiceProvider
{
private ContainerInterface $container;

public function __construct(ContainerInterface $container)
{
$this->container = $container;
}

public function register(): void
{
$this->container->singleton( DriverInterface::class, MemoryDriver::class );
$this->container->bind( MemoizerInterface::class, Memoizer::class );
}
}
```

### WpCacheDriver
## Drivers

Memoize comes with a single driver out of the box, but you can also create your own using the `StellarWP\Memoize\Contracts\DriverInterface`.

The `WpCacheDriver` is the default driver and uses WordPress's `wp_cache_set` and `wp_cache_get` functions and stores all of the memoized values in a single cache entry. Getting and setting memoized values is done by fetching from cache, manipulating (if needed), and saving back to cache (if needed).
### MemoryDriver

The `MemoryDriver` is a simple in-memory driver is in-memory memoization. Basically, contains an array property in the driver that holds the memoized values. You can manually specify the use of this driver or any other driver like so:

```php
use StellarWP\Memoize\Config;
use StellarWP\Memoize\Drivers\WpCacheDriver;
use StellarWP\Memoize\Memoizer;
use StellarWP\Memoize\Drivers\MemoryDriver;

Config::setDriver(new WpCacheDriver());
$memoizer = new Memoizer(new MemoryDriver());
```
61 changes: 0 additions & 61 deletions src/Memoize/Config.php

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace StellarWP\Memoize\Drivers\Contracts;
namespace StellarWP\Memoize\Contracts;

interface DriverInterface
{
Expand Down
Loading
Loading