2 #include "memcached_io.h"
4 static char *memcached_value_fetch(memcached_st
*ptr
, char *key
, size_t *key_length
,
7 memcached_return
*error
,
9 unsigned int server_key
)
11 char buffer
[MEMCACHED_DEFAULT_COMMAND_SIZE
];
19 memset(buffer
, 0, MEMCACHED_DEFAULT_COMMAND_SIZE
);
20 end_ptr
= buffer
+ MEMCACHED_DEFAULT_COMMAND_SIZE
;
24 *error
= memcached_response(ptr
, buffer
, MEMCACHED_DEFAULT_COMMAND_SIZE
, server_key
);
26 if (*error
== MEMCACHED_SUCCESS
)
31 string_ptr
+= 6; /* "VALUE " */
36 memset(key
, 0, MEMCACHED_MAX_KEY
);
39 for (; end_ptr
== string_ptr
|| *string_ptr
!= ' '; string_ptr
++)
46 else /* Skip characters */
47 for (; end_ptr
== string_ptr
|| *string_ptr
!= ' '; string_ptr
++);
49 if (end_ptr
== string_ptr
)
52 /* Flags fetch move past space */
54 if (end_ptr
== string_ptr
)
56 for (next_ptr
= string_ptr
; end_ptr
== string_ptr
|| *string_ptr
!= ' '; string_ptr
++);
57 *flags
= (uint16_t)strtol(next_ptr
, &string_ptr
, 10);
59 if (end_ptr
== string_ptr
)
62 /* Length fetch move past space*/
64 if (end_ptr
== string_ptr
)
67 for (next_ptr
= string_ptr
; end_ptr
== string_ptr
|| *string_ptr
!= ' '; string_ptr
++);
68 *value_length
= (size_t)strtoll(next_ptr
, &string_ptr
, 10);
70 if (end_ptr
== string_ptr
)
73 /* Skip past the \r\n */
76 if (end_ptr
< string_ptr
)
86 /* We add two bytes so that we can walk the \r\n */
87 value
= (char *)malloc(((*value_length
) +2) * sizeof(char));
88 memset(value
, 0, ((*value_length
) +2) * sizeof(char));
93 *error
= MEMCACHED_MEMORY_ALLOCATION_FAILURE
;
100 We read the \r\n into the string since not doing so is more
101 cycles then the waster of memory to do so.
103 We are null terminating through, which will most likely make
104 some people lazy about using the return length.
106 to_read
= (*value_length
) + 2;
108 read_length
= memcached_io_read(ptr
, server_key
,
111 if (read_length
!= (size_t)(*value_length
+ 2))
117 value
[*value_length
]= 0;
118 value
[(*value_length
) + 1]= 0;
123 else if (*error
== MEMCACHED_END
)
124 *error
= MEMCACHED_NOTFOUND
;
128 *error
= MEMCACHED_PARTIAL_READ
;
132 char *memcached_get(memcached_st
*ptr
, char *key
, size_t key_length
,
133 size_t *value_length
,
135 memcached_return
*error
)
138 char buffer
[MEMCACHED_DEFAULT_COMMAND_SIZE
];
139 unsigned int server_key
;
141 LIBMEMCACHED_MEMCACHED_GET_START();
143 server_key
= memcached_generate_hash(ptr
, key
, key_length
);
146 *error
= memcached_connect(ptr
, server_key
);
148 if (*error
!= MEMCACHED_SUCCESS
)
151 send_length
= snprintf(buffer
, MEMCACHED_DEFAULT_COMMAND_SIZE
, "get %.*s\r\n",
152 (int)key_length
, key
);
154 if ((memcached_io_write(ptr
, server_key
, buffer
, send_length
, 1)) == -1)
156 *error
= MEMCACHED_WRITE_FAILURE
;
160 value
= memcached_value_fetch(ptr
, key
, &key_length
, value_length
, flags
,
161 error
, 0, server_key
);
162 if (*error
== MEMCACHED_END
&& *value_length
== 0)
164 *error
= MEMCACHED_NOTFOUND
;
167 else if (*error
== MEMCACHED_SUCCESS
)
170 /* We need to read END */
171 rc
= memcached_response(ptr
, buffer
, MEMCACHED_DEFAULT_COMMAND_SIZE
, server_key
);
173 if (rc
!= MEMCACHED_END
)
175 *error
= MEMCACHED_PROTOCOL_ERROR
;
182 LIBMEMCACHED_MEMCACHED_GET_END();
190 LIBMEMCACHED_MEMCACHED_GET_END();
195 memcached_return
memcached_mget(memcached_st
*ptr
,
196 char **keys
, size_t *key_length
,
197 unsigned int number_of_keys
)
199 char buffer
[HUGE_STRING_LEN
];
202 memcached_string_st
**cursor_key_exec
;
203 LIBMEMCACHED_MEMCACHED_MGET_START();
205 ptr
->cursor_server
= 0;
206 memset(buffer
, 0, HUGE_STRING_LEN
);
208 cursor_key_exec
= (memcached_string_st
**)malloc(sizeof(memcached_string_st
*) * ptr
->number_of_hosts
);
209 memset(cursor_key_exec
, 0, sizeof(memcached_string_st
*) * ptr
->number_of_hosts
);
212 for (x
= 0; x
< number_of_keys
; x
++)
214 unsigned int server_key
;
216 server_key
= memcached_generate_hash(ptr
, keys
[x
], key_length
[x
]);
218 if (cursor_key_exec
[server_key
])
220 memcached_string_st
*string
= cursor_key_exec
[server_key
];
222 memcached_string_append_character(ptr
, string
, ' ');
223 memcached_string_append(ptr
, string
, keys
[x
], key_length
[x
]);
227 memcached_string_st
*string
= memcached_string_create(ptr
, SMALL_STRING_LEN
);
229 /* We need to figure out the correct way to error in case of this failure */
233 memcached_string_append(ptr
, string
, "get ", 4);
234 memcached_string_append(ptr
, string
, keys
[x
], key_length
[x
]);
236 cursor_key_exec
[server_key
]= string
;
242 Should we muddle on if some servers are dead?
244 for (x
= 0; x
< ptr
->number_of_hosts
; x
++)
246 if (cursor_key_exec
[x
])
248 /* We need to doo something about non-connnected hosts in the future */
249 rc
= memcached_connect(ptr
, x
);
251 memcached_string_st
*string
= cursor_key_exec
[x
];
252 memcached_string_append(ptr
, string
, "\r\n", 2);
254 if ((memcached_io_write(ptr
, x
, string
->string
,
255 memcached_string_length(ptr
, string
), 1)) == -1)
258 rc
= MEMCACHED_SOME_ERRORS
;
260 memcached_string_free(ptr
, string
);
261 cursor_key_exec
[x
]= NULL
; /* Remove warning */
265 free(cursor_key_exec
);
267 LIBMEMCACHED_MEMCACHED_MGET_END();
271 char *memcached_fetch(memcached_st
*ptr
, char *key
, size_t *key_length
,
272 size_t *value_length
,
274 memcached_return
*error
)
278 while (ptr
->cursor_server
< ptr
->number_of_hosts
)
280 value_check
= memcached_value_fetch(ptr
, key
, key_length
, value_length
, flags
,
281 error
, 1, ptr
->cursor_server
);
283 if (*error
== MEMCACHED_NOTFOUND
)
284 ptr
->cursor_server
++;
285 else if (*error
!= MEMCACHED_SUCCESS
)