Tutorial - basics

Scache is yet another session storage. Scache contain backend daemon and php extension that as a whole make server side component for managing session both in simple local LAMP-style setup or multiple frontends containing larger distributed environment.

Scache was born from need to have both persistent in memory storage so that data don't need to be redundantly stored on database and from need to have small efficient way to access just currently required parts of all stored session data instead of loading whole gradually expanding php's $_SESSION array. Scache was written to take as much as possible load from database and generally to make way to run large complicated web and ajax applications on a very low end hardware.

Keyspaces

Scache has private keyspace that is private to opened session identifier and shared keyspace that is common to all connected clients.

As an example code for keyspaces with two separate sessions :

$conn1 = scache_open('Cookie-d3b3fa3a7b7376a9ff73247bd1ba9ad3');
$conn2 = scache_open('Cookie-1c0a0e2d55732c7d7ea73e339cb8d41a');

scache_set($conn1, 'key-1', 'Roger'); // private
scache_set($conn2, 'key-1', 'Wilco'); // private
scache_shset($conn1, 'key-2', 'I got first'); // common
scache_shset($conn2, 'key-2', 'No you dont'); // common

echo scache_get($conn1, 'key-1'); // prints 'Roger'
echo scache_get($conn2, 'key-1'); // prints 'Wilco'
echo scache_shget($conn1, 'key-2'); // prints 'No you dont'
echo scache_shget($conn2, 'key-2'); // prints 'No you dont'

Private keyspace is generally used for storing session-based data while shared keyspace is for caching, sharing and reusing common data and generally for inter client communication. Private keyspace supports only persistent storage while shared keyspace implements persistent storage, on demand expiring cache and shared counters.

Scache is not disk backed but just memory backed so if you restart backend process or it crashes, all its contents are gone. In scaches context persistence means that what you store you must also some way remove as long as same scached process keeps running. For permanent storage you still need to use filesystem or database.

Pathed keys

Scaches speciality is pathed keys.

Technically scache is simple key-value storage, but its idea is to change the "key" to the "key with path" so that stored data can be organized to filesystem like hierarchy. From this hierarchy you can invalidate complete subtrees with a single operation so for example when caching data you can expire mutually dependent items fast by just removing everything from parenting node.

Path elements are separated with slash (/). For visual simplicity first slash can be omitted, so path '/path/subdir' is equal to 'path/subdir'. Repeated slashes are also considered as one.

As an example to concept for a message caching you might use hierarchy like :

cached-data
 +  topic-100/
    +  thread.index
    +  thread-200
    |   +  message.index
    |   +  message-500
    |   +  message-501
    +  thread-201
    |   +  message.index
    ......

From this hierarchy you can fetch items :

function fetch_message($topic, $thread, $msgid) {

   $conn = get_scache_connection();
   $tag = "cached-data/topic-$topic/thread-$thread/message-$msgid";

   if (!($msg = scache_chget($conn, $tag))) {
       $msg = fetch_message_from_db($topic, $thread, $msgid);
       scache_chput($conn, $tag, $msg);
   }

   return $msg;
}

And delete larger set of items (subtree) when content changes :

function add_message($topic, $thread, $text) {

   if ((add_message_to_db($topic, $thread, $content))) {

        $conn = get_scache_connection();
        scache_chclear($conn, "cache-data/topic-$topic/thread-$thread");
   }
}

You can write to any path any time regardless whether parenting path elements already exists. On an another hand, if you write to some path that already exists, it is replaced even if it was a directory containing subvalues, in case its subvalues are freed from memory.

Generally you should make use of possibility to structure your data and prefer deep multi-level datatrees instead of applications data expiration logic. Scache has no other limits on depth of tree but max length of path being as 8189 chars.

Scache stores data internally on nested binary trees, so deep path has no performance impact any more than storing same number of keys flatly unnested. (Thought single path elements are instead suggested to keep small since size of them make much more performance impact and memory footprint than depth of tree.)