<HTML>
<HEAD>
<TITLE>Re: set_multi() and delete_multi()</TITLE>
</HEAD>
<BODY>
<FONT FACE="Verdana, Helvetica, Arial"><SPAN STYLE='font-size:12.0px'>In the latest libmemcache client I&#8217;ve implemented delete_multi. &nbsp;I haven&#8217;t done set_multi yet because internally we currently have little demand for it. &nbsp;With the new libmemcache design it wouldn&#8217;t be too hard to add. &nbsp;In &nbsp;the new API, there is only one mc_delete function. &nbsp;It takes a list of keys and an exptime for all of them. &nbsp;Delete request messages are built for all targeted servers and queued up for asynch transmission to the remote memcache daemon. &nbsp;Results are correlated with original request by order of arrival. &nbsp;That is the first result is assumed to be for the first request to that server, &amp;c. &nbsp;Heterogeneous multi_* ops are not supported.<BR>
<BR>
set_multi is slightly more difficult if one wants to do keys with heterogeneous mixes of flags or exptimes. &nbsp;delete worked well because the typical use case is to specify only the key. &nbsp;I can easily imagine wanting to do set_multi with different flags. &nbsp;For example a php or python app needs to set an int value, a string value and a complex array. &nbsp;The first two wind up with flags == 0 and the last with flags == php or python serialized.<BR>
To support that means the set_multi will have to take a vector of set_message structs with key name, value, flags and exptime. &nbsp;Not a huge deal but it complicates the API. &nbsp;Unlike mc_delete or mc_get which basically are always multi-operations, there will probably have to be a separate mc_set and mc_set_multi, with the following signatures:<BR>
<BR>
int mc_set(mc_handle_t mc, const char* key, size_t nkey, const char* value, size_t nvalue, const uint16_t flags, const uint32_t exptime);<BR>
<BR>
typedef struct mc_update_req_s {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;char* key;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;size_t nkey;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;char* value;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;size_t nvalue;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;uint16_t flags;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;uint32_t exptime;<BR>
} mc_update_req_t;<BR>
<BR>
int mc_set_multi(mc_handle_t mc, const mc_update_req_t* reqs, const size_t nreqs);<BR>
<BR>
The same would apply for mc_add and mc_replace. &nbsp;Let me know what you think. &nbsp;Given that the mc_update_req_t vector only needs to exist for the scope of the call it shouldn&#8217;t be difficult for the extension code (ie php or python extension) to allocate the temporary space and initialized it prior to calling mc_set_multi, and freeing it on return.<BR>
<BR>
On 3/12/07 10:33 AM, &quot;Steven Grimm&quot; &lt;sgrimm@facebook.com&gt; wrote:<BR>
<BR>
</SPAN></FONT><BLOCKQUOTE><FONT SIZE="2"><FONT FACE="Monaco, Courier New"><SPAN STYLE='font-size:10.0px'>Not on the server side, no. (I can't speak for the client side; I'm not <BR>
the one working on that here.) We rarely do large batch deletes or sets, <BR>
so the meager CPU savings wouldn't be worth the engineering time for us.<BR>
<BR>
-Steve<BR>
<BR>
<BR>
Michael Monashev wrote:<BR>
&gt; Hi Steven,<BR>
&gt;<BR>
&gt; Do you plan to implement set_multi() and delete_multi() in the future?<BR>
&gt;<BR>
&gt; SG&gt; The server-side CPU cost of processing a two-key get request is MUCH<BR>
&gt; SG&gt; lower than processing two single-key requests because you only have to<BR>
&gt; SG&gt; run through the parser and (usually) the libevent code once. Don't<BR>
&gt; SG&gt; remember the exact ratio off the top of my head but it's pretty steep,<BR>
&gt; SG&gt; something in the neighborhood of a 10-key get request taking only 2x the<BR>
&gt; SG&gt; CPU time of a 1-key request.<BR>
&gt;<BR>
&gt; SG&gt; This would be less of an issue with a well-designed binary wire protocol<BR>
&gt; SG&gt; that didn't require any parsing at all (though you'd still see some<BR>
&gt; SG&gt; difference due to having to wake up for input on each request), but<BR>
&gt; SG&gt; right now you can save significant amounts of CPU time on the memcached<BR>
&gt; SG&gt; server by bundling your gets up into as few requests as possible. So I'm<BR>
&gt; SG&gt; glad multi-gets aren't just a series of streamed single-gets.<BR>
&gt;<BR>
&gt; --<BR>
&gt;<BR>
&gt; Michael<BR>
&gt;<BR>
&gt; &nbsp;&nbsp;<BR>
<BR>
</SPAN></FONT></FONT></BLOCKQUOTE><FONT SIZE="2"><FONT FACE="Monaco, Courier New"><SPAN STYLE='font-size:10.0px'><BR>
</SPAN></FONT></FONT>
</BODY>
</HTML>