Incomming fixes from Charles on the replication branch.
[awesomized/libmemcached] / lib / memcached_get.c
1 #include "common.h"
2 #include "memcached_io.h"
3
4 /*
5 What happens if no servers exist?
6 */
7 char *memcached_get(memcached_st *ptr, char *key, size_t key_length,
8 size_t *value_length,
9 uint32_t *flags,
10 memcached_return *error)
11 {
12 return memcached_get_by_key(ptr, NULL, 0, key, key_length, value_length,
13 flags, error);
14 }
15
16 char *memcached_get_by_key(memcached_st *ptr,
17 char *master_key, size_t master_key_length,
18 char *key, size_t key_length,
19 size_t *value_length,
20 uint32_t *flags,
21 memcached_return *error)
22 {
23 unsigned int server_key;
24 size_t send_length;
25 char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
26 memcached_result_st *result_buffer= &ptr->result;
27 memcached_return rc[MEMCACHED_MAX_REPLICAS];
28 uint8_t replicas= 0;
29
30 if (ptr->number_of_hosts == 0)
31 {
32 *error= MEMCACHED_NO_SERVERS;
33 return NULL;
34 }
35
36 if ((ptr->flags & MEM_VERIFY_KEY) && (memcachd_key_test(&key, &key_length, 1) == MEMCACHED_BAD_KEY_PROVIDED))
37 {
38 *value_length= 0;
39 *error= MEMCACHED_BAD_KEY_PROVIDED;
40 return NULL;
41 }
42
43 if (master_key)
44 server_key= memcached_generate_hash(ptr, master_key, master_key_length);
45 else
46 server_key= memcached_generate_hash(ptr, key, key_length);
47
48 send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
49 "get %.*s\r\n", (int)key_length, key);
50
51 do
52 {
53 char response_buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
54
55 if (memcached_server_response_count(&ptr->hosts[server_key]))
56 {
57 if (ptr->flags & MEM_NO_BLOCK)
58 (void)memcached_io_write(&ptr->hosts[server_key], NULL, 0, 1);
59
60 while(memcached_server_response_count(&ptr->hosts[server_key]))
61 (void)memcached_response(&ptr->hosts[server_key], response_buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, result_buffer);
62 }
63
64 rc[replicas]= memcached_do(&ptr->hosts[server_key], buffer, send_length, 1);
65 if (rc[replicas] != MEMCACHED_SUCCESS)
66 goto error;
67
68 rc[replicas]= memcached_response(&ptr->hosts[server_key], response_buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, result_buffer);
69
70 /* On no key found, we check the replica */
71 if (rc[replicas] == MEMCACHED_END) /* END means that we move on to the next */
72 {
73 memcached_server_response_reset(&ptr->hosts[server_key]);
74 }
75 else if (rc[replicas] == MEMCACHED_SUCCESS)
76 {
77 *value_length= memcached_string_length(&result_buffer->value);
78
79 if (result_buffer->flags)
80 *flags= result_buffer->flags;
81
82 *error= MEMCACHED_SUCCESS;
83 return memcached_string_c_copy(&result_buffer->value);
84 }
85
86 /* On error we just jump to the next potential server */
87 error:
88 if (ptr->number_of_replicas > 1)
89 {
90 if (server_key == (ptr->number_of_hosts - 1))
91 server_key= 0;
92 else
93 server_key++;
94 }
95 } while ((++replicas) < ptr->number_of_replicas);
96
97 /* TODO: An error on replica 1 of host down, but not found on 2, will give wrong error */
98 /* This is for historical reasons */
99 if (rc[0] == MEMCACHED_END)
100 *error= MEMCACHED_NOTFOUND;
101 else
102 *error= rc[0];
103
104 *value_length= 0;
105
106 return NULL;
107 }