d0f4822b85953d98a8156dd6c8d00096109e8d62
[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 char *value;
24 size_t dummy_length;
25 uint32_t dummy_flags;
26 memcached_return dummy_error;
27
28 /* Request the key */
29 *error= memcached_mget_by_key(ptr,
30 master_key,
31 master_key_length,
32 &key, &key_length, 1);
33
34 value= memcached_fetch(ptr, NULL, NULL,
35 value_length, flags, error);
36 /* This is for historical reasons */
37 if (*error == MEMCACHED_END)
38 *error= MEMCACHED_NOTFOUND;
39
40 if (value == NULL)
41 return NULL;
42
43 (void)memcached_fetch(ptr, NULL, NULL,
44 &dummy_length, &dummy_flags,
45 &dummy_error);
46
47 return value;
48 }
49
50 memcached_return memcached_mget(memcached_st *ptr,
51 char **keys, size_t *key_length,
52 unsigned int number_of_keys)
53 {
54 return memcached_mget_by_key(ptr, NULL, 0, keys, key_length, number_of_keys);
55 }
56
57 memcached_return memcached_mget_by_key(memcached_st *ptr,
58 char *master_key, size_t master_key_length,
59 char **keys, size_t *key_length,
60 unsigned int number_of_keys)
61 {
62 unsigned int x;
63 memcached_return rc= MEMCACHED_NOTFOUND;
64 char *get_command= "get ";
65 uint8_t get_command_length= 4;
66 unsigned int master_server_key= 0;
67
68 LIBMEMCACHED_MEMCACHED_MGET_START();
69 ptr->cursor_server= 0;
70
71 if (number_of_keys == 0)
72 return MEMCACHED_NOTFOUND;
73
74 if (ptr->number_of_hosts == 0)
75 return MEMCACHED_NO_SERVERS;
76
77 if (ptr->flags & MEM_SUPPORT_CAS)
78 {
79 get_command= "gets ";
80 get_command_length= 5;
81 }
82
83 if (master_key && master_key_length)
84 master_server_key= memcached_generate_hash(ptr, master_key, master_key_length);
85
86 /*
87 Here is where we pay for the non-block API. We need to remove any data sitting
88 in the queue before we start our get.
89
90 It might be optimum to bounce the connection if count > some number.
91 */
92 for (x= 0; x < ptr->number_of_hosts; x++)
93 {
94 if (memcached_server_response_count(ptr, x))
95 {
96 char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
97
98 if (ptr->flags & MEM_NO_BLOCK)
99 (void)memcached_io_write(ptr, x, NULL, 0, 1);
100
101 while(memcached_server_response_count(ptr, x))
102 (void)memcached_response(ptr, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, &ptr->result, x);
103 }
104 }
105
106 /*
107 If a server fails we warn about errors and start all over with sending keys
108 to the server.
109 */
110 for (x= 0; x < number_of_keys; x++)
111 {
112 unsigned int server_key;
113
114 if (master_server_key)
115 server_key= master_server_key;
116 else
117 server_key= memcached_generate_hash(ptr, keys[x], key_length[x]);
118
119 if (memcached_server_response_count(ptr, server_key) == 0)
120 {
121 rc= memcached_connect(ptr, server_key);
122
123 if (rc != MEMCACHED_SUCCESS)
124 continue;
125
126 if ((memcached_io_write(ptr, server_key, get_command, get_command_length, 0)) == -1)
127 {
128 rc= MEMCACHED_SOME_ERRORS;
129 continue;
130 }
131 WATCHPOINT_ASSERT(ptr->hosts[server_key].cursor_active == 0);
132 memcached_server_response_increment(ptr, server_key);
133 WATCHPOINT_ASSERT(ptr->hosts[server_key].cursor_active == 1);
134 }
135
136 if ((memcached_io_write(ptr, server_key, keys[x], key_length[x], 0)) == -1)
137 {
138 memcached_server_response_reset(ptr, server_key);
139 rc= MEMCACHED_SOME_ERRORS;
140 continue;
141 }
142
143 if ((memcached_io_write(ptr, server_key, " ", 1, 0)) == -1)
144 {
145 memcached_server_response_reset(ptr, server_key);
146 rc= MEMCACHED_SOME_ERRORS;
147 continue;
148 }
149 }
150
151 /*
152 Should we muddle on if some servers are dead?
153 */
154 for (x= 0; x < ptr->number_of_hosts; x++)
155 {
156 if (memcached_server_response_count(ptr, x))
157 {
158 /* We need to do something about non-connnected hosts in the future */
159 if ((memcached_io_write(ptr, x, "\r\n", 2, 1)) == -1)
160 {
161 rc= MEMCACHED_SOME_ERRORS;
162 }
163 }
164 }
165
166 LIBMEMCACHED_MEMCACHED_MGET_END();
167 return rc;
168 }