libmemcached: add MEMCACHED_BEHAVIOR_META_PROTOCOL
[awesomized/libmemcached] / src / libmemcached / delete.cc
index 6a69ae0da9675d88aa77ca5bc30202ee57316dfd..fffa42e8e7135cdf0425f9b89b88c5af68529fa6 100644 (file)
@@ -20,6 +20,30 @@ memcached_return_t memcached_delete(memcached_st *shell, const char *key, size_t
   return memcached_delete_by_key(shell, key, key_length, key, key_length, expiration);
 }
 
+static inline memcached_return_t meta_delete(memcached_instance_st *instance,
+                                             const char *key, size_t key_length,
+                                             time_t expiration) {
+
+  char ex_buf[32] = " I T";
+  size_t io_num = 0, ex_len = strlen(ex_buf);
+  libmemcached_io_vector_st io_vec[6] = {};
+  io_vec[io_num++] = {memcached_literal_param("md ")};
+  io_vec[io_num++] = {memcached_array_string(instance->root->_namespace),
+                      memcached_array_size(instance->root->_namespace)};
+  io_vec[io_num++] = {key, key_length};
+  if (!memcached_is_replying(instance->root)) {
+    io_vec[io_num++] = {" q", 2};
+  }
+  if (expiration) {
+    ex_len += snprintf(ex_buf + ex_len, sizeof(ex_buf) - ex_len, "%llu", (unsigned long long) expiration);
+    io_vec[io_num++] = {ex_buf, ex_len};
+  }
+  io_vec[io_num++] = {memcached_literal_param("\r\n")};
+
+  /* Send command header, only flush if we are NOT buffering */
+  return memcached_vdo(instance, io_vec, io_num, !memcached_is_buffering(instance->root));
+}
+
 static inline memcached_return_t ascii_delete(memcached_instance_st *instance, uint32_t,
                                               const char *key, const size_t key_length,
                                               const bool reply, const bool is_buffering) {
@@ -85,10 +109,9 @@ static inline memcached_return_t binary_delete(memcached_instance_st *instance,
   return rc;
 }
 
-memcached_return_t memcached_delete_by_key(memcached_st *shell, const char *group_key,
+memcached_return_t memcached_delete_by_key(memcached_st *memc, const char *group_key,
                                            size_t group_key_length, const char *key,
                                            size_t key_length, time_t expiration) {
-  Memcached *memc = memcached2Memcached(shell);
   LIBMEMCACHED_MEMCACHED_DELETE_START();
 
   memcached_return_t rc;
@@ -100,16 +123,15 @@ memcached_return_t memcached_delete_by_key(memcached_st *shell, const char *grou
     return memcached_last_error(memc);
   }
 
-  if (expiration) {
+  if (expiration && !memcached_is_meta(memc)) {
     return memcached_set_error(
         *memc, MEMCACHED_INVALID_ARGUMENTS, MEMCACHED_AT,
         memcached_literal_param(
             "Memcached server version does not allow expiration of deleted items"));
   }
 
-  uint32_t server_key =
-      memcached_generate_hash_with_redistribution(memc, group_key, group_key_length);
-  memcached_instance_st *instance = memcached_instance_fetch(memc, server_key);
+  auto server_key = memcached_generate_hash_with_redistribution(memc, group_key, group_key_length);
+  auto *instance = memcached_instance_fetch(memc, server_key);
 
   bool is_buffering = memcached_is_buffering(instance->root);
   bool is_replying = memcached_is_replying(instance->root);
@@ -132,6 +154,8 @@ memcached_return_t memcached_delete_by_key(memcached_st *shell, const char *grou
 
   if (memcached_is_binary(memc)) {
     rc = binary_delete(instance, server_key, key, key_length, is_replying, is_buffering);
+  } else if (memcached_is_meta(memc)) {
+    rc = meta_delete(instance, key, key_length, expiration);
   } else {
     rc = ascii_delete(instance, server_key, key, key_length, is_replying, is_buffering);
   }