3 static memcached_return
memcached_auto(memcached_st
*ptr
,
5 const char *key
, size_t key_length
,
11 char buffer
[MEMCACHED_DEFAULT_COMMAND_SIZE
];
12 unsigned int server_key
;
14 unlikely (ptr
->hosts
== NULL
|| ptr
->number_of_hosts
== 0)
15 return MEMCACHED_NO_SERVERS
;
17 if ((ptr
->flags
& MEM_VERIFY_KEY
) && (memcachd_key_test((char **)&key
, &key_length
, 1) == MEMCACHED_BAD_KEY_PROVIDED
))
18 return MEMCACHED_BAD_KEY_PROVIDED
;
20 server_key
= memcached_generate_hash(ptr
, key
, key_length
);
22 send_length
= snprintf(buffer
, MEMCACHED_DEFAULT_COMMAND_SIZE
,
23 "%s %s%.*s %u\r\n", verb
,
27 unlikely (send_length
>= MEMCACHED_DEFAULT_COMMAND_SIZE
)
28 return MEMCACHED_WRITE_FAILURE
;
30 rc
= memcached_do(&ptr
->hosts
[server_key
], buffer
, send_length
, 1);
31 if (rc
!= MEMCACHED_SUCCESS
)
34 rc
= memcached_response(&ptr
->hosts
[server_key
], buffer
, MEMCACHED_DEFAULT_COMMAND_SIZE
, NULL
);
37 So why recheck responce? Because the protocol is brain dead :)
38 The number returned might end up equaling one of the string
39 values. Less chance of a mistake with strncmp() so we will
40 use it. We still called memcached_response() though since it
41 worked its magic for non-blocking IO.
43 if (!strncmp(buffer
, "ERROR\r\n", 7))
46 rc
= MEMCACHED_PROTOCOL_ERROR
;
48 else if (!strncmp(buffer
, "NOT_FOUND\r\n", 11))
51 rc
= MEMCACHED_NOTFOUND
;
55 *value
= strtoull(buffer
, (char **)NULL
, 10);
56 rc
= MEMCACHED_SUCCESS
;
62 static memcached_return
binary_incr_decr(memcached_st
*ptr
, uint8_t cmd
,
63 const char *key
, size_t key_length
,
64 uint32_t offset
, uint64_t *value
)
66 unsigned int server_key
;
68 unlikely (ptr
->hosts
== NULL
|| ptr
->number_of_hosts
== 0)
69 return MEMCACHED_NO_SERVERS
;
71 server_key
= memcached_generate_hash(ptr
, key
, key_length
);
73 protocol_binary_request_incr request
= {.bytes
= {0}};
75 request
.message
.header
.request
.magic
= PROTOCOL_BINARY_REQ
;
76 request
.message
.header
.request
.opcode
= cmd
;
77 request
.message
.header
.request
.keylen
= htons((uint16_t)key_length
);
78 request
.message
.header
.request
.extlen
= 20;
79 request
.message
.header
.request
.datatype
= PROTOCOL_BINARY_RAW_BYTES
;
80 request
.message
.header
.request
.bodylen
= htonl(key_length
+ request
.message
.header
.request
.extlen
);
81 request
.message
.body
.delta
= htonll(offset
);
83 /* TODO: The binary protocol allows you to specify initial and expiry time */
84 if ((memcached_do(&ptr
->hosts
[server_key
], request
.bytes
,
85 sizeof(request
.bytes
), 0)!=MEMCACHED_SUCCESS
) ||
86 (memcached_io_write(&ptr
->hosts
[server_key
], key
, key_length
, 1) == -1))
88 memcached_io_reset(&ptr
->hosts
[server_key
]);
89 return MEMCACHED_WRITE_FAILURE
;
92 return memcached_response(&ptr
->hosts
[server_key
], (char*)value
, sizeof(*value
), NULL
);
95 memcached_return
memcached_increment(memcached_st
*ptr
,
96 const char *key
, size_t key_length
,
100 memcached_return rc
= memcached_validate_key_length(key_length
, ptr
->flags
& MEM_BINARY_PROTOCOL
);
101 unlikely (rc
!= MEMCACHED_SUCCESS
)
104 LIBMEMCACHED_MEMCACHED_INCREMENT_START();
105 if (ptr
->flags
& MEM_BINARY_PROTOCOL
)
106 rc
= binary_incr_decr(ptr
, PROTOCOL_BINARY_CMD_INCREMENT
, key
,
107 key_length
, offset
, value
);
109 rc
= memcached_auto(ptr
, "incr", key
, key_length
, offset
, value
);
111 LIBMEMCACHED_MEMCACHED_INCREMENT_END();
116 memcached_return
memcached_decrement(memcached_st
*ptr
,
117 const char *key
, size_t key_length
,
121 memcached_return rc
= memcached_validate_key_length(key_length
, ptr
->flags
& MEM_BINARY_PROTOCOL
);
122 unlikely (rc
!= MEMCACHED_SUCCESS
)
125 LIBMEMCACHED_MEMCACHED_DECREMENT_START();
126 if (ptr
->flags
& MEM_BINARY_PROTOCOL
)
127 rc
= binary_incr_decr(ptr
, PROTOCOL_BINARY_CMD_DECREMENT
, key
,
128 key_length
, offset
, value
);
130 rc
= memcached_auto(ptr
, "decr", key
, key_length
, offset
, value
);
132 LIBMEMCACHED_MEMCACHED_DECREMENT_END();