summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTrond Norbye <trond.norbye@gmail.com>2011-03-18 11:39:12 -0700
committerTrond Norbye <trond.norbye@gmail.com>2011-03-18 11:39:12 -0700
commit58a9fefa9742a896da51b3075a252e6f1233ad4b (patch)
tree395eb6a8bccb6e488374f467e3c89c03496e6999
parent458d1e1986f53e65d84007e9f99da993607b027d (diff)
downloadmemcached-58a9fefa9742a896da51b3075a252e6f1233ad4b.tar.gz
Allow in-place replace for incr
-rw-r--r--engines/default_engine/items.c31
1 files changed, 20 insertions, 11 deletions
diff --git a/engines/default_engine/items.c b/engines/default_engine/items.c
index 927bd26..cd09058 100644
--- a/engines/default_engine/items.c
+++ b/engines/default_engine/items.c
@@ -709,18 +709,27 @@ static ENGINE_ERROR_CODE do_add_delta(struct default_engine *engine,
if ((res = snprintf(buf, sizeof(buf), "%" PRIu64, value)) == -1) {
return ENGINE_EINVAL;
}
- hash_item *new_it = do_item_alloc(engine, item_get_key(it),
- it->nkey, it->flags,
- it->exptime, res,
- cookie);
- if (new_it == NULL) {
- do_item_unlink(engine, it);
- return ENGINE_ENOMEM;
+
+ if (it->refcount == 1 && res <= it->nbytes) {
+ // we can do inline replacement
+ memcpy(item_get_data(it), buf, res);
+ memset(item_get_data(it) + res, ' ', it->nbytes - res);
+ item_set_cas(NULL, NULL, it, get_cas_id());
+ *rcas = item_get_cas(it);
+ } else {
+ hash_item *new_it = do_item_alloc(engine, item_get_key(it),
+ it->nkey, it->flags,
+ it->exptime, res,
+ cookie);
+ if (new_it == NULL) {
+ do_item_unlink(engine, it);
+ return ENGINE_ENOMEM;
+ }
+ memcpy(item_get_data(new_it), buf, res);
+ do_item_replace(engine, it, new_it);
+ *rcas = item_get_cas(new_it);
+ do_item_release(engine, new_it); /* release our reference */
}
- memcpy(item_get_data(new_it), buf, res);
- do_item_replace(engine, it, new_it);
- *rcas = item_get_cas(new_it);
- do_item_release(engine, new_it); /* release our reference */
return ENGINE_SUCCESS;
}