<html>
<head>
<style>
P
{
margin:0px;
padding:0px
}
body
{
FONT-SIZE: 10pt;
FONT-FAMILY:Tahoma
}
</style>
</head>
<body>

Hello...<br>

I need the following in an ongoing project, so i'm posting here to see if others see merit in the idea. <br><br>Proposal<br>--------<br>Add key-based dependencies to memcached.<br><br>Motivation<br>----------<br>To simplify common caching scenarios (data dependencies and namespaces)<br>by centralizing the logic at the server.<br><br>Example<br>---------<br><br>Assume we have an organization selling widgets to the Americas<br>and Asia, and that the sales calculations are aggregated and <br>cached.<br><br>&nbsp;&nbsp;&nbsp; add ns:americas 0 0 nothing\r\n<br>&nbsp;&nbsp;&nbsp; add ns:asia 0 0 nothing\r\n<br><br>&nbsp;&nbsp;&nbsp; add americas:sales 0 0 25000\r\n<br>&nbsp;&nbsp;&nbsp; add americas:sales.usa 0 0 20000\r\n<br>&nbsp;&nbsp;&nbsp; add americas:sales.usa.bolts 0 0 10000\r\n<br>&nbsp;&nbsp;&nbsp; add americas:sales.usa.grommets 0 0 10000\r\n<br>&nbsp;&nbsp;&nbsp; add americas:sales.colombia 0 0 5000\r\n<br>&nbsp;&nbsp;&nbsp; add americas:sales.colombia.bolts 0 0 5000\r\n<br><br>&nbsp;&nbsp;&nbsp; dependency americas:sales.usa americas:sales.usa.bolts americas:sales.usa.grommets\r\n<br>&nbsp;&nbsp;&nbsp; dependency americas:sales.combia americas:sales.colombia.bolts\r\n<br><br>&nbsp;&nbsp;&nbsp; dependency americas:sales americas:sales.usa americas:sales.colombia\r\n<br>&nbsp;&nbsp;&nbsp; dependency americas:sales.usa ns:americas\r\n<br>&nbsp;&nbsp;&nbsp; dependency americas:sales.colombia ns:americas\r\n<br><br>Here we add keys representing the two sales regions (ns:america, ns:asia). The total sales <br>per region are stored (e.g. americas:sales), as well as the individual country and item sales <br>which constitute the total. The aggregate is made dependent on the country sales, and<br>the country sales are dependent on the region. Any number of dependencies can be added,<br>but of course this consumes memory per key.<br>&nbsp; <br>&nbsp;If the sales figures for the USA or Colombia changes, americas:sales is automatically<br>deleted. To delete the aggregate data for the Americas region, we delete ns:americas.&nbsp; <br><br>Implementing namespaces in this way may cause issues in that a dependency would <br>be one of the first items scavenged if there is no need to retrieve it <br>- like ns:americas in this example (there is no useful data associated). <br>The client can handle this with a multi-key get which always includes such a key. <br>PHP example :<br><br>&nbsp;&nbsp;&nbsp; function GetEx($memcache, $key)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $pos = strpos($key, ":");&nbsp;&nbsp;&nbsp; // we use ":" as namespace separator<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (FALSE == $pos) {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* not namespaced, use single get */<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return $memcache-&gt;get($key);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $namespace = "ns:" . substr($key, 0, $pos);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $arr = $memcache-&gt;get( array($key, $namespace) );<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return $arr[$key];<br>&nbsp;&nbsp;&nbsp; }<br><br><br>Dependency command<br>--------------------------<br><br>dependency &lt;key&gt; &lt;dependency&gt;*\r\n<br><br>- &lt;key&gt; is the key under which the dependent item is stored.<br><br>- &lt;dependency&gt;* means one or more key strings separated by whitespace.<br><br>Each &lt;dependency&gt; must represent a valid undeleted, unexpired item.<br>Each item specified by the dependency key has &lt;key&gt; added to its list of dependents.<br>An item cannot be added as a dependency to itself.<br><br>After sending the command line and the data block the client awaits<br>the reply, which may be:<br><br>- "OK\r\n", to indicate success.<br><br>- "NOT_FOUND\r\n" to indicate the item or one of the dependencies was was not found.<br><br><br>Needed Changes<br>------------------------<br><br>- Addition of storage for dependent keys per item struct.<br><br>- void item_add_dependencies(conn *c, item *node, item **dependencies, int count, int check_cycles)<br>&nbsp; Add node as a dependent to each item in the dependencies list. This optionally performs a <br>&nbsp; topological sort to detect possible dependency cycles.<br><br>- Add a server setting to allow/disallow dependency cycle detection. <br><br>- Modification of the item_unlink routine to recursively unlink dependents of<br>&nbsp; the item. When the dependency is deleted or modified, all of its dependents <br>&nbsp; are deleted recursively.<br><br>- Modification of item_free to cleanup dependent key storage.<br><br>- An addition to the protocol to allow client setting of item dependencies.<br><br><br>Caveats<br>-------<br>This implementation assumes that a key and its dependencies are located in a single memcached<br>server instance. Cycle detection has an effect performance, so it is made optional by setting.<br>Dependents of a key are stored per node and consume (2 + strlen(key)) bytes each.<br><br><br>Any thoughts ?<br><br>clayton collie<br><br><br><br><br /><hr />Invite your mail contacts to join your friends list with Windows Live Spaces. It's easy! <a href='http://spaces.live.com/spacesapi.aspx?wx_action=create&wx_url=/friends.aspx&mkt=en-us' target='_new'>Try it!</a></body>
</html>