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 server_key
= memcached_generate_hash(ptr
, key
, key_length
);
147 result_buffer
= &ptr
->result_buffer
;
150 *error
= memcached_connect(ptr
, server_key
);
152 if (*error
!= MEMCACHED_SUCCESS
)
155 memcpy(buf_ptr
, "get ", 4);
157 memcpy(buf_ptr
, key
, key_length
);
158 buf_ptr
+= key_length
;
159 memcpy(buf_ptr
, "\r\n", 2);
162 if ((memcached_io_write(ptr
, server_key
, buffer
, (size_t)(buf_ptr
- buffer
), 1)) == -1)
164 *error
= MEMCACHED_WRITE_FAILURE
;
168 *error
= memcached_value_fetch(ptr
, key
, &key_length
, result_buffer
,
169 flags
, 0, server_key
);
170 *value_length
= memcached_string_length(result_buffer
);
171 if (*error
== MEMCACHED_END
&& *value_length
== 0)
173 *error
= MEMCACHED_NOTFOUND
;
176 else if (*error
== MEMCACHED_END
)
178 WATCHPOINT_ASSERT(0); /* If this happens we have somehow messed up the fetch */
180 else if (*error
== MEMCACHED_SUCCESS
)
183 /* We need to read END */
184 rc
= memcached_response(ptr
, buffer
, MEMCACHED_DEFAULT_COMMAND_SIZE
, server_key
);
186 if (rc
!= MEMCACHED_END
)
188 *error
= MEMCACHED_PROTOCOL_ERROR
;
195 LIBMEMCACHED_MEMCACHED_GET_END();
198 return memcached_string_c_copy(result_buffer
);
203 LIBMEMCACHED_MEMCACHED_GET_END();
208 memcached_return
memcached_mget(memcached_st
*ptr
,
209 char **keys
, size_t *key_length
,
210 unsigned int number_of_keys
)
213 memcached_return rc
= MEMCACHED_NOTFOUND
;
214 char *cursor_key_exec
;
215 LIBMEMCACHED_MEMCACHED_MGET_START();
216 ptr
->cursor_server
= 0;
218 if (number_of_keys
== 0)
219 return MEMCACHED_NOTFOUND
;
221 cursor_key_exec
= (char *)malloc(sizeof(char) * ptr
->number_of_hosts
);
222 memset(cursor_key_exec
, 0, sizeof(char) * ptr
->number_of_hosts
);
224 for (x
= 0; x
< number_of_keys
; x
++)
226 unsigned int server_key
;
228 server_key
= memcached_generate_hash(ptr
, keys
[x
], key_length
[x
]);
230 if (cursor_key_exec
[server_key
] == 0)
232 rc
= memcached_connect(ptr
, server_key
);
234 if ((memcached_io_write(ptr
, server_key
, "get ", 4, 0)) == -1)
237 rc
= MEMCACHED_SOME_ERRORS
;
242 if ((memcached_io_write(ptr
, server_key
, keys
[x
], key_length
[x
], 0)) == -1)
245 rc
= MEMCACHED_SOME_ERRORS
;
249 if ((memcached_io_write(ptr
, server_key
, " ", 1, 0)) == -1)
252 rc
= MEMCACHED_SOME_ERRORS
;
255 cursor_key_exec
[server_key
]= 1;
260 Should we muddle on if some servers are dead?
262 for (x
= 0; x
< ptr
->number_of_hosts
; x
++)
264 if (cursor_key_exec
[x
])
266 /* We need to doo something about non-connnected hosts in the future */
267 if ((memcached_io_write(ptr
, x
, "\r\n", 2, 1)) == -1)
270 rc
= MEMCACHED_SOME_ERRORS
;
274 ptr
->hosts
[x
].cursor_active
= 1;
277 ptr
->hosts
[x
].cursor_active
= 0;
280 free(cursor_key_exec
);
282 LIBMEMCACHED_MEMCACHED_MGET_END();
286 char *memcached_fetch(memcached_st
*ptr
, char *key
, size_t *key_length
,
287 size_t *value_length
,
289 memcached_return
*error
)
291 memcached_string_st
*result_buffer
;
292 result_buffer
= &ptr
->result_buffer
;
294 while (ptr
->cursor_server
< ptr
->number_of_hosts
)
296 if (!ptr
->hosts
[ptr
->cursor_server
].cursor_active
)
298 ptr
->cursor_server
++;
302 *error
= memcached_value_fetch(ptr
, key
, key_length
, result_buffer
,
303 flags
, 1, ptr
->cursor_server
);
304 *value_length
= memcached_string_length(result_buffer
);
306 if (*error
== MEMCACHED_NOTFOUND
)
307 ptr
->cursor_server
++;
308 else if (*error
== MEMCACHED_END
&& *value_length
== 0)
310 else if (*error
== MEMCACHED_END
)
312 WATCHPOINT_ASSERT(0); /* If this happens we have somehow messed up the fetch */
315 else if (*error
!= MEMCACHED_SUCCESS
)
318 return memcached_string_c_copy(result_buffer
);
326 memcached_result_st
*memcached_fetch_result(memcached_st
*ptr
,
327 memcached_result_st
*result
,
328 memcached_return
*error
)
331 result
= memcached_result_create(ptr
, NULL
);
333 while (ptr
->cursor_server
< ptr
->number_of_hosts
)
335 if (!ptr
->hosts
[ptr
->cursor_server
].cursor_active
)
337 ptr
->cursor_server
++;
341 *error
= memcached_value_fetch(ptr
, result
->key
, &result
->key_length
,
344 1, ptr
->cursor_server
);
346 if (*error
== MEMCACHED_NOTFOUND
)
347 ptr
->cursor_server
++;
348 else if (*error
== MEMCACHED_END
&& memcached_string_length((memcached_string_st
*)(&result
->value
)) == 0)
350 else if (*error
== MEMCACHED_END
)
352 WATCHPOINT_ASSERT(0); /* If this happens we have somehow messed up the fetch */
355 else if (*error
!= MEMCACHED_SUCCESS
)