Skip to content

Commit f7c91cb

Browse files
committed
FEATURE: Add gat API
1 parent a58d9be commit f7c91cb

File tree

3 files changed

+131
-11
lines changed

3 files changed

+131
-11
lines changed

libmemcached/get.cc

Lines changed: 69 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,8 @@ static memcached_return_t ascii_get_by_key(memcached_st *ptr,
164164
uint32_t master_server_key,
165165
bool is_group_key_set,
166166
const char *key,
167-
const size_t key_length)
167+
const size_t key_length,
168+
time_t *expiration)
168169
{
169170
memcached_return_t rc;
170171
memcached_server_write_instance_st instance;
@@ -180,16 +181,33 @@ static memcached_return_t ascii_get_by_key(memcached_st *ptr,
180181
}
181182
instance= memcached_server_instance_fetch(ptr, server_key);
182183

183-
const char *command= (ptr->flags.support_cas ? "gets " : "get ");
184+
char expiration_buffer[MEMCACHED_MAXIMUM_INTEGER_DISPLAY_LENGTH + 1 + 1];
185+
int expiration_buffer_length = 0;
186+
if (expiration) {
187+
expiration_buffer_length = snprintf(expiration_buffer, sizeof(expiration_buffer), "%lld ",
188+
(long long) *expiration);
189+
if (size_t(expiration_buffer_length) >= sizeof(expiration_buffer)
190+
or expiration_buffer_length < 0)
191+
{
192+
return memcached_set_error(*ptr, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT,
193+
memcached_literal_param("snprintf(MEMCACHED_MAXIMUM_INTEGER_DISPLAY_LENGTH)"));
194+
}
195+
}
196+
197+
const char *command;
198+
if (expiration) command= (ptr->flags.support_cas ? "gats " : "gat ");
199+
else command= (ptr->flags.support_cas ? "gets " : "get ");
200+
184201
struct libmemcached_io_vector_st vector[]=
185202
{
186203
{ strlen(command), command },
204+
{ (size_t)expiration_buffer_length, expiration_buffer },
187205
{ memcached_array_size(ptr->_namespace), memcached_array_string(ptr->_namespace) },
188206
{ key_length, key },
189207
{ 2, "\r\n" }
190208
};
191209

192-
rc= memcached_vdo(instance, vector, 4, true);
210+
rc= memcached_vdo(instance, vector, 5, true);
193211
if (rc != MEMCACHED_SUCCESS) {
194212
memcached_set_error(*ptr, rc, MEMCACHED_AT);
195213
}
@@ -462,13 +480,14 @@ static memcached_return_t binary_mget_by_key(memcached_st *ptr,
462480
What happens if no servers exist?
463481
*/
464482

465-
char *memcached_get_by_key(memcached_st *ptr,
466-
const char *group_key,
467-
size_t group_key_length,
468-
const char *key, size_t key_length,
469-
size_t *value_length,
470-
uint32_t *flags,
471-
memcached_return_t *error)
483+
static char *memcached_get_by_key(memcached_st *ptr,
484+
const char *group_key,
485+
size_t group_key_length,
486+
const char *key, size_t key_length,
487+
time_t *expiration,
488+
size_t *value_length,
489+
uint32_t *flags,
490+
memcached_return_t *error)
472491
{
473492
arcus_server_check_for_update(ptr);
474493

@@ -510,12 +529,17 @@ char *memcached_get_by_key(memcached_st *ptr,
510529
/* Request the key */
511530
if (ptr->flags.binary_protocol)
512531
{
532+
if (expiration)
533+
{
534+
*error= MEMCACHED_NOT_SUPPORTED;
535+
return NULL;
536+
}
513537
*error= binary_mget_by_key(ptr, master_server_key, is_group_key_set,
514538
(const char * const *)&key, &key_length, 1, false);
515539
}
516540
else
517541
{
518-
*error= ascii_get_by_key(ptr, master_server_key, is_group_key_set, key, key_length);
542+
*error= ascii_get_by_key(ptr, master_server_key, is_group_key_set, key, key_length, expiration);
519543
}
520544

521545
assert_msg(ptr->query_id >= query_id +1, "Programmer error, the query_id was not incremented.");
@@ -614,6 +638,18 @@ char *memcached_get_by_key(memcached_st *ptr,
614638
return value;
615639
}
616640

641+
char *memcached_get_by_key(memcached_st *ptr,
642+
const char *group_key,
643+
size_t group_key_length,
644+
const char *key, size_t key_length,
645+
size_t *value_length,
646+
uint32_t *flags,
647+
memcached_return_t *error)
648+
{
649+
return memcached_get_by_key(ptr, group_key, group_key_length, key, key_length,
650+
NULL, value_length, flags, error);
651+
}
652+
617653
char *memcached_get(memcached_st *ptr, const char *key,
618654
size_t key_length,
619655
size_t *value_length,
@@ -624,6 +660,28 @@ char *memcached_get(memcached_st *ptr, const char *key,
624660
flags, error);
625661
}
626662

663+
char *memcached_gat_by_key(memcached_st *ptr,
664+
const char *group_key,
665+
size_t group_key_length,
666+
const char *key, size_t key_length,
667+
time_t expiration,
668+
size_t *value_length,
669+
uint32_t *flags,
670+
memcached_return_t *error)
671+
{
672+
return memcached_get_by_key(ptr, group_key, group_key_length, key, key_length,
673+
&expiration, value_length, flags, error);
674+
}
675+
676+
char *memcached_gat(memcached_st *ptr, const char *key,
677+
size_t key_length, time_t expiration,
678+
size_t *value_length, uint32_t *flags,
679+
memcached_return_t *error)
680+
{
681+
return memcached_gat_by_key(ptr, NULL, 0, key, key_length, expiration,
682+
value_length, flags, error);
683+
}
684+
627685
memcached_return_t memcached_mget_by_key(memcached_st *ptr,
628686
const char *group_key,
629687
size_t group_key_length,

libmemcached/get.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,14 @@ char *memcached_get(memcached_st *ptr,
5151
uint32_t *flags,
5252
memcached_return_t *error);
5353

54+
LIBMEMCACHED_API
55+
char *memcached_gat(memcached_st *ptr,
56+
const char *key, size_t key_length,
57+
time_t expiration,
58+
size_t *value_length,
59+
uint32_t *flags,
60+
memcached_return_t *error);
61+
5462
LIBMEMCACHED_API
5563
memcached_return_t memcached_mget(memcached_st *ptr,
5664
const char * const *keys,
@@ -65,6 +73,15 @@ char *memcached_get_by_key(memcached_st *ptr,
6573
uint32_t *flags,
6674
memcached_return_t *error);
6775

76+
LIBMEMCACHED_API
77+
char *memcached_gat_by_key(memcached_st *ptr,
78+
const char *group_key, size_t group_key_length,
79+
const char *key, size_t key_length,
80+
time_t expiration,
81+
size_t *value_length,
82+
uint32_t *flags,
83+
memcached_return_t *error);
84+
6885
LIBMEMCACHED_API
6986
memcached_return_t memcached_mget_by_key(memcached_st *ptr,
7087
const char *group_key,

tests/mem_functions.cc

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -864,6 +864,50 @@ static test_return_t touch_test(memcached_st *memc)
864864
return TEST_SUCCESS;
865865
}
866866

867+
static test_return_t gat_test(memcached_st *memc)
868+
{
869+
memcached_return_t rc;
870+
const char *key= "foo";
871+
const char *value= "when we sanitize";
872+
char *string;
873+
size_t string_length;
874+
uint32_t flags;
875+
876+
if (memc->flags.binary_protocol) {
877+
return TEST_SUCCESS;
878+
}
879+
880+
uint64_t query_id= memcached_query_id(memc);
881+
rc= memcached_set(memc, key, strlen(key),
882+
value, strlen(value),
883+
(time_t)0, (uint32_t)0);
884+
test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
885+
test_compare(query_id +1, memcached_query_id(memc));
886+
887+
query_id= memcached_query_id(memc);
888+
test_true(query_id);
889+
890+
string= memcached_gat(memc, key, strlen(key), time(NULL) - 2,
891+
&string_length, &flags, &rc);
892+
test_compare(query_id +1, memcached_query_id(memc));
893+
894+
test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
895+
test_true(string);
896+
test_compare(strlen(value), string_length);
897+
test_memcmp(value, string, string_length);
898+
899+
free(string);
900+
901+
string= memcached_gat(memc, key, strlen(key), (time_t)0,
902+
&string_length, &flags, &rc);
903+
904+
test_compare_got(MEMCACHED_NOTFOUND, rc, memcached_strerror(NULL, rc));
905+
test_false(string_length);
906+
test_false(string);
907+
908+
return TEST_SUCCESS;
909+
}
910+
867911
static memcached_return_t server_function(const memcached_st *ptr,
868912
const memcached_server_st *server,
869913
void *context)
@@ -6218,6 +6262,7 @@ test_st tests[] ={
62186262
{"replace", true, (test_callback_fn*)replace_test },
62196263
{"delete", true, (test_callback_fn*)delete_test },
62206264
{"touch", true, (test_callback_fn*)touch_test },
6265+
{"gat", true, (test_callback_fn*)gat_test },
62216266
{"get", true, (test_callback_fn*)get_test },
62226267
{"get2", false, (test_callback_fn*)get_test2 },
62236268
{"get3", false, (test_callback_fn*)get_test3 },

0 commit comments

Comments
 (0)