4

I'm looking for a good cache key for APC that represents some complied information about an object, using the "object" as the key. I have a compilation method that does something like this:

function compile(Obj $obj)
{
    if ($this->cache)
    {
        $cachekey = serialize($obj);

        if ($data = $this->cache->get($obj))
        {
            return $data
        }
    }

    // compute result here

    if ($this->cache)
    {
        $this->cache->set($cachekey, $result);
    }

    return $result;
}

If it's not obvious, $this->cache is an implementation of an interface with the methods get and set.

Is there a quicker alternative to creating a key that's unique to some of the properties of this object? I can extract the relevant bits out, but then they are still arrays, which would have the same problem with serialization that I had with the objects in the first place.

Serialize works, from a "correctness" position, but it seems wasteful (both in size of outputted key, and in computational complexity).

EDIT: I would also like to add, if it's not obvious, that I will not be needing to unserialize this object. My verbatim code for the current cache key is actually:

$cachekey = 'compile.' . sha1(serialize($obj));.

EDIT 2: The object I'm working with has the following definition:

class Route
{
    protected $pattern;
    protected $defaults = array();
    protected $requirements = array();
}

Pattern and requirements are the values of the object that will change the output of this method, therefore a hash of these values must be present in the cache key.

Also, someone suggested uniqid(), which would defeat the purpose of a general cache lookup key, as you could not reliably regenerate the same ID from the same information.

EDIT 3: I guess I'm not giving enough context. Here's a link to the code so far:

https://github.com/efritz/minuet/blob/master/src/Minuet/Routing/Router.php#L160

I guess I'm really only trying to avoid expensive calls to serialize (and I guess sha1, which is also a bit expensive). It's possible that the best I can do is try to reduce the size of what I'm serializing...

6
  • what's wrong with "computational complexity"? Commented Oct 27, 2011 at 4:27
  • It's running more cycles than I actually need ;) serialize is currently the only method that's taking more time than apc_fetch itself, when there's a cache hit. Commented Oct 27, 2011 at 4:30
  • So you want to retrieve a data item based on the value of that data item, or alternatively store the data item? This makes no sense - in order to retrieve the value you must already know what it is! Commented Oct 27, 2011 at 9:25
  • I'm doing additional processing to the item. I'm actually generating a regex for a URL route matcher, which I want to store based on pattern and regex requirements, but don't want to generate until it's needed the first time. Commented Oct 27, 2011 at 15:22
  • 1
    Wouldn't the whole thing be much more simple if Obj had a unique id? Commented Oct 27, 2011 at 15:33

3 Answers 3

1

One way to do it might be to generate a key based simply from the values you use to compute the result..

Here is a rough example.

function compile(Obj $obj)
{
    if ($this->cache)
    {
        $cachekey = 'Obj-result-' . sha1($obj->pattern . '-' . serialize($obj->requirements));
        // You could even try print_r($obj->requirements, true)
        // or even json_encode($obj->requirements)
        // or implode('-', $obj->requirements)
        // Can't say for sure which is slowest, or fastest.
        if ($data = $this->cache->get($cachekey))
        {
            return $data
        }
    }

    // compute result here
    $result = $obj->x + $obj->y; // irrelevant, and from original answer.

    if ($this->cache)
    {
        $this->cache->set($cachekey, $result);
    }

    return $result;
}

Since you use an array of data, you'd still need to turn it into something that makes sense as a key.. However this way you're now only serializing a part of the object, rather then the whole thing. See how it goes. :)

Sign up to request clarification or add additional context in comments.

3 Comments

But $obj->x and $obj->y would actually be array structures, which would then require serialization.... I'll make an edit about the object structure.
It appears in your example $pattern isn't an array. Anyways, I updated my answer.
This is the best solution so far ~~
1

I would suggest the spl_object_hash function that seems to fit perfectly for your needs.

4 Comments

Does this function keep consistent hashes between requests?
"A string that is unique for each currently existing object and is always the same for each object." Look at the comments on the PHP manual's page.
"Note that the contents (properties) of the object are NOT hashed by the function, merely its internal handle and handler table pointer." Each request that comes in may have a different starting point on the stack. I'm printing an object hash of one of the objects and it changes on EVERY request. This doesn't work between requests.
Also, object hashes can be re-used when an object is destroyed, if it occupies that same place in memory afterwards.
0

Actually it is very hard to suggest any viable solution without knowing how the whole system works.

But, Why don't you just simply add a cache_key property with a uniqid() value in your object?

3 Comments

I don't understand how a random and non-reproducible fits into this context. See my edit above for more information on the object.
You didn't get me right. I know uniqid() is non-reproducible. What I meant was add that id with each object as a signature. And use that as a primary key of your object. you can map it with your related object like [user1 - obj12328018230]. Sorry that you get it wrong and again sorry if you sill can't get it.
I get it now, but I'm not storing objects in a database. Check my edit for a link.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.