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 memset(buffer
, 0, MEMCACHED_DEFAULT_COMMAND_SIZE
);
16 end_ptr
= buffer
+ MEMCACHED_DEFAULT_COMMAND_SIZE
;
20 memcached_string_reset(value
);
22 rc
= memcached_response(ptr
, buffer
, MEMCACHED_DEFAULT_COMMAND_SIZE
, server_key
);
24 if (rc
== MEMCACHED_SUCCESS
)
30 string_ptr
+= 6; /* "VALUE " */
35 memset(key
, 0, MEMCACHED_MAX_KEY
);
38 for (; end_ptr
> string_ptr
&& *string_ptr
!= ' '; string_ptr
++)
45 else /* Skip characters */
46 for (; end_ptr
> string_ptr
&& *string_ptr
!= ' '; string_ptr
++);
48 if (end_ptr
== string_ptr
)
51 /* Flags fetch move past space */
53 if (end_ptr
== string_ptr
)
55 for (next_ptr
= string_ptr
; end_ptr
> string_ptr
&& *string_ptr
!= ' '; string_ptr
++);
56 *flags
= (uint16_t)strtol(next_ptr
, &string_ptr
, 10);
58 if (end_ptr
== string_ptr
)
61 /* Length fetch move past space*/
63 if (end_ptr
== string_ptr
)
66 for (next_ptr
= string_ptr
; end_ptr
> string_ptr
&& *string_ptr
!= ' '; string_ptr
++);
67 value_length
= (size_t)strtoll(next_ptr
, &string_ptr
, 10);
69 if (end_ptr
== string_ptr
)
72 /* Skip past the \r\n */
75 if (end_ptr
< string_ptr
)
84 /* We add two bytes so that we can walk the \r\n */
85 rc
= memcached_string_check(value
, value_length
+2);
86 if (rc
!= MEMCACHED_SUCCESS
)
89 return MEMCACHED_MEMORY_ALLOCATION_FAILURE
;
92 value_ptr
= memcached_string_value(value
);
95 We read the \r\n into the string since not doing so is more
96 cycles then the waster of memory to do so.
98 We are null terminating through, which will most likely make
99 some people lazy about using the return length.
101 to_read
= (value_length
) + 2;
103 read_length
= memcached_io_read(ptr
, server_key
,
106 if (read_length
!= (size_t)(value_length
+ 2))
111 /* This next bit blows the API, but this is internal....*/
114 char_ptr
= memcached_string_value(value
);;
115 char_ptr
[value_length
]= 0;
116 char_ptr
[value_length
+ 1]= 0;
117 memcached_string_set_length(value
, value_length
);
120 return MEMCACHED_SUCCESS
;
123 else if (rc
== MEMCACHED_END
)
124 rc
= MEMCACHED_NOTFOUND
;
129 return MEMCACHED_PARTIAL_READ
;
133 What happens if no servers exist?
135 char *memcached_get(memcached_st
*ptr
, char *key
, size_t key_length
,
136 size_t *value_length
,
138 memcached_return
*error
)
140 char buffer
[MEMCACHED_DEFAULT_COMMAND_SIZE
];
141 char *buf_ptr
= buffer
;
142 unsigned int server_key
;
143 memcached_string_st
*result_buffer
;
144 LIBMEMCACHED_MEMCACHED_GET_START();
146 if (ptr
->hosts
== NULL
|| ptr
->number_of_hosts
== 0)
148 *error
= MEMCACHED_NO_SERVERS
;
152 server_key
= memcached_generate_hash(ptr
, key
, key_length
);
153 result_buffer
= &ptr
->result_buffer
;
156 *error
= memcached_connect(ptr
, server_key
);
158 if (*error
!= MEMCACHED_SUCCESS
)
161 memcpy(buf_ptr
, "get ", 4);
163 memcpy(buf_ptr
, key
, key_length
);
164 buf_ptr
+= key_length
;
165 memcpy(buf_ptr
, "\r\n", 2);
168 if ((memcached_io_write(ptr
, server_key
, buffer
, (size_t)(buf_ptr
- buffer
), 1)) == -1)
170 *error
= MEMCACHED_WRITE_FAILURE
;
174 *error
= memcached_value_fetch(ptr
, key
, &key_length
, result_buffer
,
175 flags
, 0, server_key
);
176 *value_length
= memcached_string_length(result_buffer
);
177 if (*error
== MEMCACHED_END
&& *value_length
== 0)
179 *error
= MEMCACHED_NOTFOUND
;
182 else if (*error
== MEMCACHED_END
)
184 WATCHPOINT_ASSERT(0); /* If this happens we have somehow messed up the fetch */
186 else if (*error
== MEMCACHED_SUCCESS
)
189 /* We need to read END */
190 rc
= memcached_response(ptr
, buffer
, MEMCACHED_DEFAULT_COMMAND_SIZE
, server_key
);
192 if (rc
!= MEMCACHED_END
)
194 *error
= MEMCACHED_PROTOCOL_ERROR
;
201 LIBMEMCACHED_MEMCACHED_GET_END();
204 return memcached_string_c_copy(result_buffer
);
209 LIBMEMCACHED_MEMCACHED_GET_END();
214 memcached_return
memcached_mget(memcached_st
*ptr
,
215 char **keys
, size_t *key_length
,
216 unsigned int number_of_keys
)
219 memcached_return rc
= MEMCACHED_NOTFOUND
;
220 char *cursor_key_exec
;
221 LIBMEMCACHED_MEMCACHED_MGET_START();
222 ptr
->cursor_server
= 0;
224 if (number_of_keys
== 0)
225 return MEMCACHED_NOTFOUND
;
227 if (ptr
->number_of_hosts
== 0)
228 return MEMCACHED_NO_SERVERS
;
230 cursor_key_exec
= (char *)malloc(sizeof(char) * ptr
->number_of_hosts
);
231 memset(cursor_key_exec
, 0, sizeof(char) * ptr
->number_of_hosts
);
233 for (x
= 0; x
< number_of_keys
; x
++)
235 unsigned int server_key
;
237 server_key
= memcached_generate_hash(ptr
, keys
[x
], key_length
[x
]);
239 if (cursor_key_exec
[server_key
] == 0)
241 rc
= memcached_connect(ptr
, server_key
);
243 if ((memcached_io_write(ptr
, server_key
, "get ", 4, 0)) == -1)
246 rc
= MEMCACHED_SOME_ERRORS
;
251 if ((memcached_io_write(ptr
, server_key
, keys
[x
], key_length
[x
], 0)) == -1)
254 rc
= MEMCACHED_SOME_ERRORS
;
258 if ((memcached_io_write(ptr
, server_key
, " ", 1, 0)) == -1)
261 rc
= MEMCACHED_SOME_ERRORS
;
264 cursor_key_exec
[server_key
]= 1;
269 Should we muddle on if some servers are dead?
271 for (x
= 0; x
< ptr
->number_of_hosts
; x
++)
273 if (cursor_key_exec
[x
])
275 /* We need to doo something about non-connnected hosts in the future */
276 if ((memcached_io_write(ptr
, x
, "\r\n", 2, 1)) == -1)
279 rc
= MEMCACHED_SOME_ERRORS
;
283 ptr
->hosts
[x
].cursor_active
= 1;
286 ptr
->hosts
[x
].cursor_active
= 0;
289 free(cursor_key_exec
);
291 LIBMEMCACHED_MEMCACHED_MGET_END();
295 char *memcached_fetch(memcached_st
*ptr
, char *key
, size_t *key_length
,
296 size_t *value_length
,
298 memcached_return
*error
)
300 memcached_string_st
*result_buffer
;
301 result_buffer
= &ptr
->result_buffer
;
303 while (ptr
->cursor_server
< ptr
->number_of_hosts
)
305 if (!ptr
->hosts
[ptr
->cursor_server
].cursor_active
)
307 ptr
->cursor_server
++;
311 *error
= memcached_value_fetch(ptr
, key
, key_length
, result_buffer
,
312 flags
, 1, ptr
->cursor_server
);
313 *value_length
= memcached_string_length(result_buffer
);
315 if (*error
== MEMCACHED_NOTFOUND
)
316 ptr
->cursor_server
++;
317 else if (*error
== MEMCACHED_END
&& *value_length
== 0)
319 else if (*error
== MEMCACHED_END
)
321 WATCHPOINT_ASSERT(0); /* If this happens we have somehow messed up the fetch */
324 else if (*error
!= MEMCACHED_SUCCESS
)
327 return memcached_string_c_copy(result_buffer
);
335 memcached_result_st
*memcached_fetch_result(memcached_st
*ptr
,
336 memcached_result_st
*result
,
337 memcached_return
*error
)
340 result
= memcached_result_create(ptr
, NULL
);
342 while (ptr
->cursor_server
< ptr
->number_of_hosts
)
344 if (!ptr
->hosts
[ptr
->cursor_server
].cursor_active
)
346 ptr
->cursor_server
++;
350 *error
= memcached_value_fetch(ptr
, result
->key
, &result
->key_length
,
353 1, ptr
->cursor_server
);
355 if (*error
== MEMCACHED_NOTFOUND
)
356 ptr
->cursor_server
++;
357 else if (*error
== MEMCACHED_END
&& memcached_string_length((memcached_string_st
*)(&result
->value
)) == 0)
359 else if (*error
== MEMCACHED_END
)
361 WATCHPOINT_ASSERT(0); /* If this happens we have somehow messed up the fetch */
364 else if (*error
!= MEMCACHED_SUCCESS
)