2 #include "memcached_io.h"
4 static memcached_return
memcached_value_fetch(memcached_st
*ptr
, char *key
, size_t *key_length
,
5 memcached_string_st
*value
,
8 unsigned int server_key
)
11 char buffer
[MEMCACHED_DEFAULT_COMMAND_SIZE
];
15 end_ptr
= buffer
+ MEMCACHED_DEFAULT_COMMAND_SIZE
;
19 memcached_string_reset(value
);
21 rc
= memcached_response(ptr
, buffer
, MEMCACHED_DEFAULT_COMMAND_SIZE
, server_key
);
23 if (rc
== MEMCACHED_SUCCESS
)
29 string_ptr
+= 6; /* "VALUE " */
36 for (; end_ptr
> string_ptr
&& *string_ptr
!= ' '; string_ptr
++)
43 else /* Skip characters */
44 for (; end_ptr
> string_ptr
&& *string_ptr
!= ' '; string_ptr
++);
46 if (end_ptr
== string_ptr
)
49 /* Flags fetch move past space */
51 if (end_ptr
== string_ptr
)
53 for (next_ptr
= string_ptr
; end_ptr
> string_ptr
&& *string_ptr
!= ' '; string_ptr
++);
54 *flags
= (uint16_t)strtol(next_ptr
, &string_ptr
, 10);
56 if (end_ptr
== string_ptr
)
59 /* Length fetch move past space*/
61 if (end_ptr
== string_ptr
)
64 for (next_ptr
= string_ptr
; end_ptr
> string_ptr
&& *string_ptr
!= ' '; string_ptr
++);
65 value_length
= (size_t)strtoll(next_ptr
, &string_ptr
, 10);
67 if (end_ptr
== string_ptr
)
70 /* Skip past the \r\n */
73 if (end_ptr
< string_ptr
)
82 /* We add two bytes so that we can walk the \r\n */
83 rc
= memcached_string_check(value
, value_length
+2);
84 if (rc
!= MEMCACHED_SUCCESS
)
87 return MEMCACHED_MEMORY_ALLOCATION_FAILURE
;
90 value_ptr
= memcached_string_value(value
);
93 We read the \r\n into the string since not doing so is more
94 cycles then the waster of memory to do so.
96 We are null terminating through, which will most likely make
97 some people lazy about using the return length.
99 to_read
= (value_length
) + 2;
101 read_length
= memcached_io_read(ptr
, server_key
,
104 if (read_length
!= (size_t)(value_length
+ 2))
109 /* This next bit blows the API, but this is internal....*/
112 char_ptr
= memcached_string_value(value
);;
113 char_ptr
[value_length
]= 0;
114 char_ptr
[value_length
+ 1]= 0;
115 memcached_string_set_length(value
, value_length
);
118 return MEMCACHED_SUCCESS
;
121 else if (rc
== MEMCACHED_END
)
122 rc
= MEMCACHED_NOTFOUND
;
127 return MEMCACHED_PARTIAL_READ
;
131 What happens if no servers exist?
133 char *memcached_get(memcached_st
*ptr
, char *key
, size_t key_length
,
134 size_t *value_length
,
136 memcached_return
*error
)
138 char buffer
[MEMCACHED_DEFAULT_COMMAND_SIZE
];
139 char *buf_ptr
= buffer
;
140 unsigned int server_key
;
141 memcached_string_st
*result_buffer
;
142 LIBMEMCACHED_MEMCACHED_GET_START();
146 *error
= MEMCACHED_NO_KEY_PROVIDED
;
150 if (ptr
->hosts
== NULL
|| ptr
->number_of_hosts
== 0)
152 *error
= MEMCACHED_NO_SERVERS
;
156 server_key
= memcached_generate_hash(ptr
, key
, key_length
);
157 result_buffer
= &ptr
->result_buffer
;
160 memcpy(buf_ptr
, "get ", 4);
162 memcpy(buf_ptr
, key
, key_length
);
163 buf_ptr
+= key_length
;
164 memcpy(buf_ptr
, "\r\n", 2);
167 *error
= memcached_do(ptr
, server_key
, buffer
, (size_t)(buf_ptr
- buffer
), 1);
168 if (*error
!= MEMCACHED_SUCCESS
)
171 *error
= memcached_value_fetch(ptr
, key
, &key_length
, result_buffer
,
172 flags
, 0, server_key
);
173 *value_length
= memcached_string_length(result_buffer
);
174 if (*error
== MEMCACHED_END
&& *value_length
== 0)
176 *error
= MEMCACHED_NOTFOUND
;
179 else if (*error
== MEMCACHED_END
)
181 WATCHPOINT_ASSERT(0); /* If this happens we have somehow messed up the fetch */
183 else if (*error
== MEMCACHED_SUCCESS
)
186 /* We need to read END */
187 rc
= memcached_response(ptr
, buffer
, MEMCACHED_DEFAULT_COMMAND_SIZE
, server_key
);
189 if (rc
!= MEMCACHED_END
)
191 *error
= MEMCACHED_PROTOCOL_ERROR
;
198 LIBMEMCACHED_MEMCACHED_GET_END();
201 return memcached_string_c_copy(result_buffer
);
206 LIBMEMCACHED_MEMCACHED_GET_END();
211 memcached_return
memcached_mget(memcached_st
*ptr
,
212 char **keys
, size_t *key_length
,
213 unsigned int number_of_keys
)
216 memcached_return rc
= MEMCACHED_NOTFOUND
;
217 LIBMEMCACHED_MEMCACHED_MGET_START();
218 ptr
->cursor_server
= 0;
220 if (number_of_keys
== 0)
221 return MEMCACHED_NOTFOUND
;
223 if (ptr
->number_of_hosts
== 0)
224 return MEMCACHED_NO_SERVERS
;
226 for (x
= 0; x
< number_of_keys
; x
++)
228 unsigned int server_key
;
230 server_key
= memcached_generate_hash(ptr
, keys
[x
], key_length
[x
]);
232 if (ptr
->hosts
[server_key
].cursor_active
== 0)
234 rc
= memcached_connect(ptr
, server_key
);
236 if ((memcached_io_write(ptr
, server_key
, "get ", 4, 0)) == -1)
238 memcached_quit_server(ptr
, server_key
);
239 rc
= MEMCACHED_SOME_ERRORS
;
242 ptr
->hosts
[server_key
].cursor_active
= 1;
245 if ((memcached_io_write(ptr
, server_key
, keys
[x
], key_length
[x
], 0)) == -1)
247 ptr
->hosts
[server_key
].cursor_active
= 0;
248 memcached_quit_server(ptr
, server_key
);
249 rc
= MEMCACHED_SOME_ERRORS
;
253 if ((memcached_io_write(ptr
, server_key
, " ", 1, 0)) == -1)
255 ptr
->hosts
[server_key
].cursor_active
= 0;
256 memcached_quit_server(ptr
, server_key
);
257 rc
= MEMCACHED_SOME_ERRORS
;
264 Should we muddle on if some servers are dead?
266 for (x
= 0; x
< ptr
->number_of_hosts
; x
++)
268 if (ptr
->hosts
[x
].cursor_active
== 1)
270 /* We need to doo something about non-connnected hosts in the future */
271 if ((memcached_io_write(ptr
, x
, "\r\n", 2, 1)) == -1)
273 memcached_quit_server(ptr
, x
);
274 rc
= MEMCACHED_SOME_ERRORS
;
279 LIBMEMCACHED_MEMCACHED_MGET_END();
283 char *memcached_fetch(memcached_st
*ptr
, char *key
, size_t *key_length
,
284 size_t *value_length
,
286 memcached_return
*error
)
288 memcached_string_st
*result_buffer
;
289 result_buffer
= &ptr
->result_buffer
;
291 while (ptr
->cursor_server
< ptr
->number_of_hosts
)
293 if (!ptr
->hosts
[ptr
->cursor_server
].cursor_active
)
295 ptr
->cursor_server
++;
299 *error
= memcached_value_fetch(ptr
, key
, key_length
, result_buffer
,
300 flags
, 1, ptr
->cursor_server
);
301 *value_length
= memcached_string_length(result_buffer
);
303 if (*error
== MEMCACHED_NOTFOUND
)
305 ptr
->hosts
[ptr
->cursor_server
].cursor_active
= 0;
306 ptr
->cursor_server
++;
308 else if (*error
== MEMCACHED_END
&& *value_length
== 0)
312 else if (*error
== MEMCACHED_END
)
314 WATCHPOINT_ASSERT(0); /* If this happens we have somehow messed up the fetch */
318 else if (*error
!= MEMCACHED_SUCCESS
)
324 return memcached_string_c_copy(result_buffer
);
333 memcached_result_st
*memcached_fetch_result(memcached_st
*ptr
,
334 memcached_result_st
*result
,
335 memcached_return
*error
)
338 result
= memcached_result_create(ptr
, NULL
);
340 while (ptr
->cursor_server
< ptr
->number_of_hosts
)
342 if (!ptr
->hosts
[ptr
->cursor_server
].cursor_active
)
344 ptr
->cursor_server
++;
348 *error
= memcached_value_fetch(ptr
, result
->key
, &result
->key_length
,
351 1, ptr
->cursor_server
);
353 if (*error
== MEMCACHED_NOTFOUND
)
355 ptr
->hosts
[ptr
->cursor_server
].cursor_active
= 0;
356 ptr
->cursor_server
++;
358 else if (*error
== MEMCACHED_END
&& memcached_string_length((memcached_string_st
*)(&result
->value
)) == 0)
362 else if (*error
== MEMCACHED_END
)
364 WATCHPOINT_ASSERT(0); /* If this happens we have somehow messed up the fetch */
367 else if (*error
!= MEMCACHED_SUCCESS
)