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();
147 return MEMCACHED_NO_KEY_PROVIDED
;
149 if (ptr
->hosts
== NULL
|| ptr
->number_of_hosts
== 0)
151 *error
= MEMCACHED_NO_SERVERS
;
155 server_key
= memcached_generate_hash(ptr
, key
, key_length
);
156 result_buffer
= &ptr
->result_buffer
;
159 *error
= memcached_connect(ptr
, server_key
);
161 if (*error
!= MEMCACHED_SUCCESS
)
164 memcpy(buf_ptr
, "get ", 4);
166 memcpy(buf_ptr
, key
, key_length
);
167 buf_ptr
+= key_length
;
168 memcpy(buf_ptr
, "\r\n", 2);
171 if ((memcached_io_write(ptr
, server_key
, buffer
, (size_t)(buf_ptr
- buffer
), 1)) == -1)
173 *error
= MEMCACHED_WRITE_FAILURE
;
177 *error
= memcached_value_fetch(ptr
, key
, &key_length
, result_buffer
,
178 flags
, 0, server_key
);
179 *value_length
= memcached_string_length(result_buffer
);
180 if (*error
== MEMCACHED_END
&& *value_length
== 0)
182 *error
= MEMCACHED_NOTFOUND
;
185 else if (*error
== MEMCACHED_END
)
187 WATCHPOINT_ASSERT(0); /* If this happens we have somehow messed up the fetch */
189 else if (*error
== MEMCACHED_SUCCESS
)
192 /* We need to read END */
193 rc
= memcached_response(ptr
, buffer
, MEMCACHED_DEFAULT_COMMAND_SIZE
, server_key
);
195 if (rc
!= MEMCACHED_END
)
197 *error
= MEMCACHED_PROTOCOL_ERROR
;
204 LIBMEMCACHED_MEMCACHED_GET_END();
207 return memcached_string_c_copy(result_buffer
);
212 LIBMEMCACHED_MEMCACHED_GET_END();
217 memcached_return
memcached_mget(memcached_st
*ptr
,
218 char **keys
, size_t *key_length
,
219 unsigned int number_of_keys
)
222 memcached_return rc
= MEMCACHED_NOTFOUND
;
223 char *cursor_key_exec
;
224 LIBMEMCACHED_MEMCACHED_MGET_START();
225 ptr
->cursor_server
= 0;
227 if (number_of_keys
== 0)
228 return MEMCACHED_NOTFOUND
;
230 if (ptr
->number_of_hosts
== 0)
231 return MEMCACHED_NO_SERVERS
;
233 cursor_key_exec
= (char *)malloc(sizeof(char) * ptr
->number_of_hosts
);
234 memset(cursor_key_exec
, 0, sizeof(char) * ptr
->number_of_hosts
);
236 for (x
= 0; x
< number_of_keys
; x
++)
238 unsigned int server_key
;
240 server_key
= memcached_generate_hash(ptr
, keys
[x
], key_length
[x
]);
242 if (cursor_key_exec
[server_key
] == 0)
244 rc
= memcached_connect(ptr
, server_key
);
246 if ((memcached_io_write(ptr
, server_key
, "get ", 4, 0)) == -1)
249 rc
= MEMCACHED_SOME_ERRORS
;
254 if ((memcached_io_write(ptr
, server_key
, keys
[x
], key_length
[x
], 0)) == -1)
257 rc
= MEMCACHED_SOME_ERRORS
;
261 if ((memcached_io_write(ptr
, server_key
, " ", 1, 0)) == -1)
264 rc
= MEMCACHED_SOME_ERRORS
;
267 cursor_key_exec
[server_key
]= 1;
272 Should we muddle on if some servers are dead?
274 for (x
= 0; x
< ptr
->number_of_hosts
; x
++)
276 if (cursor_key_exec
[x
])
278 /* We need to doo something about non-connnected hosts in the future */
279 if ((memcached_io_write(ptr
, x
, "\r\n", 2, 1)) == -1)
282 rc
= MEMCACHED_SOME_ERRORS
;
286 ptr
->hosts
[x
].cursor_active
= 1;
289 ptr
->hosts
[x
].cursor_active
= 0;
292 free(cursor_key_exec
);
294 LIBMEMCACHED_MEMCACHED_MGET_END();
298 char *memcached_fetch(memcached_st
*ptr
, char *key
, size_t *key_length
,
299 size_t *value_length
,
301 memcached_return
*error
)
303 memcached_string_st
*result_buffer
;
304 result_buffer
= &ptr
->result_buffer
;
306 while (ptr
->cursor_server
< ptr
->number_of_hosts
)
308 if (!ptr
->hosts
[ptr
->cursor_server
].cursor_active
)
310 ptr
->cursor_server
++;
314 *error
= memcached_value_fetch(ptr
, key
, key_length
, result_buffer
,
315 flags
, 1, ptr
->cursor_server
);
316 *value_length
= memcached_string_length(result_buffer
);
318 if (*error
== MEMCACHED_NOTFOUND
)
319 ptr
->cursor_server
++;
320 else if (*error
== MEMCACHED_END
&& *value_length
== 0)
322 else if (*error
== MEMCACHED_END
)
324 WATCHPOINT_ASSERT(0); /* If this happens we have somehow messed up the fetch */
327 else if (*error
!= MEMCACHED_SUCCESS
)
330 return memcached_string_c_copy(result_buffer
);
338 memcached_result_st
*memcached_fetch_result(memcached_st
*ptr
,
339 memcached_result_st
*result
,
340 memcached_return
*error
)
343 result
= memcached_result_create(ptr
, NULL
);
345 while (ptr
->cursor_server
< ptr
->number_of_hosts
)
347 if (!ptr
->hosts
[ptr
->cursor_server
].cursor_active
)
349 ptr
->cursor_server
++;
353 *error
= memcached_value_fetch(ptr
, result
->key
, &result
->key_length
,
356 1, ptr
->cursor_server
);
358 if (*error
== MEMCACHED_NOTFOUND
)
359 ptr
->cursor_server
++;
360 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
)