+
+memcached_return_t memcached_delete_by_key(memcached_st *ptr,
+ const char *group_key, size_t group_key_length,
+ const char *key, size_t key_length,
+ time_t expiration)
+{
+ LIBMEMCACHED_MEMCACHED_DELETE_START();
+
+ memcached_return_t rc;
+ if (memcached_failed(rc= initialize_query(ptr, true)))
+ {
+ return rc;
+ }
+
+ if (memcached_failed(rc= memcached_key_test(*ptr, (const char **)&key, &key_length, 1)))
+ {
+ return memcached_last_error(ptr);
+ }
+
+ if (expiration)
+ {
+ return memcached_set_error(*ptr, 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(ptr, group_key, group_key_length);
+ memcached_server_write_instance_st instance= memcached_server_instance_fetch(ptr, server_key);
+
+ bool buffering= memcached_is_buffering(instance->root);
+ bool reply= memcached_is_replying(instance->root);
+
+ // If a delete trigger exists, we need a response, so no buffering/noreply
+ if (ptr->delete_trigger)
+ {
+ if (buffering)
+ {
+ return memcached_set_error(*ptr, MEMCACHED_INVALID_ARGUMENTS, MEMCACHED_AT,
+ memcached_literal_param("Delete triggers cannot be used if buffering is enabled"));
+ }
+
+ if (reply == false)
+ {
+ return memcached_set_error(*ptr, MEMCACHED_INVALID_ARGUMENTS, MEMCACHED_AT,
+ memcached_literal_param("Delete triggers cannot be used if MEMCACHED_BEHAVIOR_NOREPLY is set"));
+ }
+ }
+
+ if (memcached_is_binary(ptr))
+ {
+ rc= binary_delete(instance, server_key, key, key_length, reply, buffering ? false : true);
+ }
+ else
+ {
+ rc= ascii_delete(instance, server_key, key, key_length, reply, buffering ? false : true);
+ }
+
+ if (rc == MEMCACHED_SUCCESS)
+ {
+ if (buffering == true)
+ {
+ rc= MEMCACHED_BUFFERED;
+ }
+ else if (reply == false)
+ {
+ rc= MEMCACHED_SUCCESS;
+ }
+ else
+ {
+ char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
+ rc= memcached_response(instance, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL);
+ if (rc == MEMCACHED_DELETED)
+ {
+ rc= MEMCACHED_SUCCESS;
+ if (ptr->delete_trigger)
+ {
+ ptr->delete_trigger(ptr, key, key_length);
+ }
+ }
+ }
+ }
+
+ LIBMEMCACHED_MEMCACHED_DELETE_END();
+ return memcached_set_error(*ptr, rc, MEMCACHED_AT );
+}