2 +--------------------------------------------------------------------+
3 | libmemcached - C/C++ Client Library for memcached |
4 +--------------------------------------------------------------------+
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted under the terms of the BSD license. |
7 | You should have received a copy of the license in a bundled file |
8 | named LICENSE; in case you did not receive a copy you can review |
9 | the terms online at: https://opensource.org/licenses/BSD-3-Clause |
10 +--------------------------------------------------------------------+
11 | Copyright (c) 2006-2014 Brian Aker https://datadifferential.com/ |
12 | Copyright (c) 2020 Michael Wallner <mike@php.net> |
13 +--------------------------------------------------------------------+
16 #include "libmemcached/common.h"
18 static memcached_return_t
ascii_exist(Memcached
*memc
, memcached_instance_st
*instance
,
19 const char *key
, size_t key_length
) {
20 libmemcached_io_vector_st vector
[] = {
22 {memcached_literal_param("add ")},
23 {memcached_array_string(memc
->_namespace
), memcached_array_size(memc
->_namespace
)},
25 {memcached_literal_param(" 0")},
26 {memcached_literal_param(" 2678400")},
27 {memcached_literal_param(" 0")},
28 {memcached_literal_param("\r\n")},
29 {memcached_literal_param("\r\n")}};
31 /* Send command header */
32 memcached_return_t rc
;
33 if (memcached_fatal(rc
= memcached_vdo(instance
, vector
, 9, true))) {
37 char buffer
[MEMCACHED_DEFAULT_COMMAND_SIZE
];
38 rc
= memcached_response(instance
, buffer
, MEMCACHED_DEFAULT_COMMAND_SIZE
, NULL
);
40 if (rc
== MEMCACHED_NOTSTORED
) {
41 rc
= MEMCACHED_SUCCESS
;
44 if (rc
== MEMCACHED_STORED
) {
45 rc
= MEMCACHED_NOTFOUND
;
51 static memcached_return_t
binary_exist(Memcached
*memc
, memcached_instance_st
*instance
,
52 const char *key
, size_t key_length
) {
53 protocol_binary_request_set request
= {};
54 size_t send_length
= sizeof(request
.bytes
);
56 initialize_binary_request(instance
, request
.message
.header
);
58 request
.message
.header
.request
.opcode
= PROTOCOL_BINARY_CMD_ADD
;
59 request
.message
.header
.request
.keylen
=
60 htons((uint16_t)(key_length
+ memcached_array_size(memc
->_namespace
)));
61 request
.message
.header
.request
.datatype
= PROTOCOL_BINARY_RAW_BYTES
;
62 request
.message
.header
.request
.extlen
= 8;
63 request
.message
.body
.flags
= 0;
64 request
.message
.body
.expiration
= htonl(2678400);
66 request
.message
.header
.request
.bodylen
= htonl((uint32_t)(
67 key_length
+ memcached_array_size(memc
->_namespace
) + request
.message
.header
.request
.extlen
));
69 libmemcached_io_vector_st vector
[] = {
71 {request
.bytes
, send_length
},
72 {memcached_array_string(memc
->_namespace
), memcached_array_size(memc
->_namespace
)},
75 /* write the header */
76 memcached_return_t rc
;
77 if (memcached_fatal(rc
= memcached_vdo(instance
, vector
, 4, true))) {
81 rc
= memcached_response(instance
, NULL
, 0, NULL
);
83 if (rc
== MEMCACHED_SUCCESS
) {
84 rc
= MEMCACHED_NOTFOUND
;
87 if (rc
== MEMCACHED_DATA_EXISTS
) {
88 rc
= MEMCACHED_SUCCESS
;
94 memcached_return_t
memcached_exist(memcached_st
*memc
, const char *key
, size_t key_length
) {
95 return memcached_exist_by_key(memc
, key
, key_length
, key
, key_length
);
98 memcached_return_t
memcached_exist_by_key(memcached_st
*shell
, const char *group_key
,
99 size_t group_key_length
, const char *key
,
101 Memcached
*memc
= memcached2Memcached(shell
);
102 memcached_return_t rc
;
103 if (memcached_failed(rc
= initialize_query(memc
, true))) {
107 if (memcached_is_udp(memc
)) {
108 return memcached_set_error(*memc
, MEMCACHED_NOT_SUPPORTED
, MEMCACHED_AT
);
111 uint32_t server_key
=
112 memcached_generate_hash_with_redistribution(memc
, group_key
, group_key_length
);
113 memcached_instance_st
*instance
= memcached_instance_fetch(memc
, server_key
);
115 if (memcached_is_binary(memc
)) {
116 rc
= binary_exist(memc
, instance
, key
, key_length
);
118 rc
= ascii_exist(memc
, instance
, key
, key_length
);