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();
148 *error
= MEMCACHED_NO_KEY_PROVIDED
;
152 if (ptr
->hosts
== NULL
|| ptr
->number_of_hosts
== 0)
154 *error
= MEMCACHED_NO_SERVERS
;
158 server_key
= memcached_generate_hash(ptr
, key
, key_length
);
159 result_buffer
= &ptr
->result_buffer
;
162 memcpy(buf_ptr
, "get ", 4);
164 memcpy(buf_ptr
, key
, key_length
);
165 buf_ptr
+= key_length
;
166 memcpy(buf_ptr
, "\r\n", 2);
169 *error
= memcached_do(ptr
, server_key
, buffer
, (size_t)(buf_ptr
- buffer
), 1);
170 if (*error
!= MEMCACHED_SUCCESS
)
173 *error
= memcached_value_fetch(ptr
, key
, &key_length
, result_buffer
,
174 flags
, 0, server_key
);
175 *value_length
= memcached_string_length(result_buffer
);
176 if (*error
== MEMCACHED_END
&& *value_length
== 0)
178 *error
= MEMCACHED_NOTFOUND
;
181 else if (*error
== MEMCACHED_END
)
183 WATCHPOINT_ASSERT(0); /* If this happens we have somehow messed up the fetch */
185 else if (*error
== MEMCACHED_SUCCESS
)
188 /* We need to read END */
189 rc
= memcached_response(ptr
, buffer
, MEMCACHED_DEFAULT_COMMAND_SIZE
, server_key
);
191 if (rc
!= MEMCACHED_END
)
193 *error
= MEMCACHED_PROTOCOL_ERROR
;
200 LIBMEMCACHED_MEMCACHED_GET_END();
203 return memcached_string_c_copy(result_buffer
);
208 LIBMEMCACHED_MEMCACHED_GET_END();
213 memcached_return
memcached_mget(memcached_st
*ptr
,
214 char **keys
, size_t *key_length
,
215 unsigned int number_of_keys
)
218 memcached_return rc
= MEMCACHED_NOTFOUND
;
219 char *cursor_key_exec
;
220 LIBMEMCACHED_MEMCACHED_MGET_START();
221 ptr
->cursor_server
= 0;
223 if (number_of_keys
== 0)
224 return MEMCACHED_NOTFOUND
;
226 if (ptr
->number_of_hosts
== 0)
227 return MEMCACHED_NO_SERVERS
;
229 cursor_key_exec
= (char *)malloc(sizeof(char) * ptr
->number_of_hosts
);
230 memset(cursor_key_exec
, 0, sizeof(char) * ptr
->number_of_hosts
);
232 for (x
= 0; x
< number_of_keys
; x
++)
234 unsigned int server_key
;
236 server_key
= memcached_generate_hash(ptr
, keys
[x
], key_length
[x
]);
238 if (cursor_key_exec
[server_key
] == 0)
240 rc
= memcached_connect(ptr
, server_key
);
242 if ((memcached_io_write(ptr
, server_key
, "get ", 4, 0)) == -1)
245 rc
= MEMCACHED_SOME_ERRORS
;
250 if ((memcached_io_write(ptr
, server_key
, keys
[x
], key_length
[x
], 0)) == -1)
253 rc
= MEMCACHED_SOME_ERRORS
;
257 if ((memcached_io_write(ptr
, server_key
, " ", 1, 0)) == -1)
260 rc
= MEMCACHED_SOME_ERRORS
;
263 cursor_key_exec
[server_key
]= 1;
268 Should we muddle on if some servers are dead?
270 for (x
= 0; x
< ptr
->number_of_hosts
; x
++)
272 if (cursor_key_exec
[x
])
274 /* We need to doo something about non-connnected hosts in the future */
275 if ((memcached_io_write(ptr
, x
, "\r\n", 2, 1)) == -1)
278 rc
= MEMCACHED_SOME_ERRORS
;
282 ptr
->hosts
[x
].cursor_active
= 1;
285 ptr
->hosts
[x
].cursor_active
= 0;
288 free(cursor_key_exec
);
290 LIBMEMCACHED_MEMCACHED_MGET_END();
294 char *memcached_fetch(memcached_st
*ptr
, char *key
, size_t *key_length
,
295 size_t *value_length
,
297 memcached_return
*error
)
299 memcached_string_st
*result_buffer
;
300 result_buffer
= &ptr
->result_buffer
;
302 while (ptr
->cursor_server
< ptr
->number_of_hosts
)
304 if (!ptr
->hosts
[ptr
->cursor_server
].cursor_active
)
306 ptr
->cursor_server
++;
310 *error
= memcached_value_fetch(ptr
, key
, key_length
, result_buffer
,
311 flags
, 1, ptr
->cursor_server
);
312 *value_length
= memcached_string_length(result_buffer
);
314 if (*error
== MEMCACHED_NOTFOUND
)
315 ptr
->cursor_server
++;
316 else if (*error
== MEMCACHED_END
&& *value_length
== 0)
318 else if (*error
== MEMCACHED_END
)
320 WATCHPOINT_ASSERT(0); /* If this happens we have somehow messed up the fetch */
323 else if (*error
!= MEMCACHED_SUCCESS
)
326 return memcached_string_c_copy(result_buffer
);
334 memcached_result_st
*memcached_fetch_result(memcached_st
*ptr
,
335 memcached_result_st
*result
,
336 memcached_return
*error
)
339 result
= memcached_result_create(ptr
, NULL
);
341 while (ptr
->cursor_server
< ptr
->number_of_hosts
)
343 if (!ptr
->hosts
[ptr
->cursor_server
].cursor_active
)
345 ptr
->cursor_server
++;
349 *error
= memcached_value_fetch(ptr
, result
->key
, &result
->key_length
,
352 1, ptr
->cursor_server
);
354 if (*error
== MEMCACHED_NOTFOUND
)
355 ptr
->cursor_server
++;
356 else if (*error
== MEMCACHED_END
&& memcached_string_length((memcached_string_st
*)(&result
->value
)) == 0)
358 else if (*error
== MEMCACHED_END
)
360 WATCHPOINT_ASSERT(0); /* If this happens we have somehow messed up the fetch */
363 else if (*error
!= MEMCACHED_SUCCESS
)