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
];
15 memset(buffer
, 0, MEMCACHED_DEFAULT_COMMAND_SIZE
);
16 end_ptr
= buffer
+ MEMCACHED_DEFAULT_COMMAND_SIZE
;
21 *error
= memcached_response(ptr
, buffer
, MEMCACHED_DEFAULT_COMMAND_SIZE
, server_key
);
23 if (*error
== MEMCACHED_SUCCESS
)
28 string_ptr
+= 6; /* "VALUE " */
33 memset(key
, 0, MEMCACHED_MAX_KEY
);
36 for (; end_ptr
> string_ptr
&& *string_ptr
!= ' '; string_ptr
++)
43 else /* Skip characters */
44 for (; end_ptr
> string_ptr
&& *string_ptr
!= ' '; string_ptr
++);
46 if (end_ptr
== string_ptr
)
49 /* Flags fetch move past space */
51 if (end_ptr
== string_ptr
)
53 for (next_ptr
= string_ptr
; end_ptr
> string_ptr
&& *string_ptr
!= ' '; string_ptr
++);
54 *flags
= (uint16_t)strtol(next_ptr
, &string_ptr
, 10);
56 if (end_ptr
== string_ptr
)
59 /* Length fetch move past space*/
61 if (end_ptr
== string_ptr
)
64 for (next_ptr
= string_ptr
; end_ptr
> string_ptr
&& *string_ptr
!= ' '; string_ptr
++);
65 *value_length
= (size_t)strtoll(next_ptr
, &string_ptr
, 10);
67 if (end_ptr
== string_ptr
)
70 /* Skip past the \r\n */
73 if (end_ptr
< string_ptr
)
83 /* We add two bytes so that we can walk the \r\n */
84 value
= (char *)malloc(((*value_length
) +2) * sizeof(char));
88 *error
= MEMCACHED_MEMORY_ALLOCATION_FAILURE
;
91 memset(value
, 0, ((*value_length
) +2) * sizeof(char));
96 We read the \r\n into the string since not doing so is more
97 cycles then the waster of memory to do so.
99 We are null terminating through, which will most likely make
100 some people lazy about using the return length.
102 to_read
= (*value_length
) + 2;
104 read_length
= memcached_io_read(ptr
, server_key
,
107 if (read_length
!= (size_t)(*value_length
+ 2))
113 value
[*value_length
]= 0;
114 value
[(*value_length
) + 1]= 0;
119 else if (*error
== MEMCACHED_END
)
120 *error
= MEMCACHED_NOTFOUND
;
124 *error
= MEMCACHED_PARTIAL_READ
;
128 char *memcached_get(memcached_st
*ptr
, char *key
, size_t key_length
,
129 size_t *value_length
,
131 memcached_return
*error
)
133 char buffer
[MEMCACHED_DEFAULT_COMMAND_SIZE
];
134 char *buf_ptr
= buffer
;
135 unsigned int server_key
;
137 LIBMEMCACHED_MEMCACHED_GET_START();
139 server_key
= memcached_generate_hash(ptr
, key
, key_length
);
142 *error
= memcached_connect(ptr
, server_key
);
144 if (*error
!= MEMCACHED_SUCCESS
)
147 memcpy(buf_ptr
, "get ", 4);
149 memcpy(buf_ptr
, key
, key_length
);
150 buf_ptr
+= key_length
;
151 memcpy(buf_ptr
, "\r\n", 2);
154 if ((memcached_io_write(ptr
, server_key
, buffer
, (size_t)(buf_ptr
- buffer
), 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_END
)
168 assert(0); /* If this happens we have somehow messed up the fetch */
169 else if (*error
== MEMCACHED_SUCCESS
)
172 /* We need to read END */
173 rc
= memcached_response(ptr
, buffer
, MEMCACHED_DEFAULT_COMMAND_SIZE
, server_key
);
175 if (rc
!= MEMCACHED_END
)
177 *error
= MEMCACHED_PROTOCOL_ERROR
;
184 LIBMEMCACHED_MEMCACHED_GET_END();
192 LIBMEMCACHED_MEMCACHED_GET_END();
197 memcached_return
memcached_mget(memcached_st
*ptr
,
198 char **keys
, size_t *key_length
,
199 unsigned int number_of_keys
)
201 char buffer
[HUGE_STRING_LEN
];
204 memcached_string_st
**cursor_key_exec
;
205 LIBMEMCACHED_MEMCACHED_MGET_START();
207 ptr
->cursor_server
= 0;
208 memset(buffer
, 0, HUGE_STRING_LEN
);
210 cursor_key_exec
= (memcached_string_st
**)malloc(sizeof(memcached_string_st
*) * ptr
->number_of_hosts
);
211 memset(cursor_key_exec
, 0, sizeof(memcached_string_st
*) * ptr
->number_of_hosts
);
214 for (x
= 0; x
< number_of_keys
; x
++)
216 unsigned int server_key
;
218 server_key
= memcached_generate_hash(ptr
, keys
[x
], key_length
[x
]);
220 if (cursor_key_exec
[server_key
])
222 memcached_string_st
*string
= cursor_key_exec
[server_key
];
224 rc
= memcached_string_append_character(ptr
, string
, ' ');
226 if (rc
!= MEMCACHED_SUCCESS
)
229 rc
= memcached_string_append(ptr
, string
, keys
[x
], key_length
[x
]);
231 if (rc
!= MEMCACHED_SUCCESS
)
236 memcached_string_st
*string
= memcached_string_create(ptr
, SMALL_STRING_LEN
);
238 /* We need to figure out the correct way to error in case of this failure */
242 rc
= memcached_string_append(ptr
, string
, "get ", 4);
243 if (rc
!= MEMCACHED_SUCCESS
)
246 rc
= memcached_string_append(ptr
, string
, keys
[x
], key_length
[x
]);
247 if (rc
!= MEMCACHED_SUCCESS
)
250 cursor_key_exec
[server_key
]= string
;
256 Should we muddle on if some servers are dead?
258 for (x
= 0; x
< ptr
->number_of_hosts
; x
++)
260 if (cursor_key_exec
[x
])
262 /* We need to doo something about non-connnected hosts in the future */
263 rc
= memcached_connect(ptr
, x
);
265 memcached_string_st
*string
= cursor_key_exec
[x
];
267 rc
= memcached_string_append(ptr
, string
, "\r\n", 2);
268 if (rc
!= MEMCACHED_SUCCESS
)
271 if ((memcached_io_write(ptr
, x
, string
->string
,
272 memcached_string_length(ptr
, string
), 1)) == -1)
275 rc
= MEMCACHED_SOME_ERRORS
;
277 memcached_string_free(ptr
, string
);
278 cursor_key_exec
[x
]= NULL
; /* Remove warning */
279 ptr
->hosts
[x
].cursor_active
= 1;
282 ptr
->hosts
[x
].cursor_active
= 0;
285 free(cursor_key_exec
);
287 LIBMEMCACHED_MEMCACHED_MGET_END();
291 char *memcached_fetch(memcached_st
*ptr
, char *key
, size_t *key_length
,
292 size_t *value_length
,
294 memcached_return
*error
)
298 while (ptr
->cursor_server
< ptr
->number_of_hosts
)
300 if (!ptr
->hosts
[ptr
->cursor_server
].cursor_active
)
302 ptr
->cursor_server
++;
306 value_check
= memcached_value_fetch(ptr
, key
, key_length
, value_length
, flags
,
307 error
, 1, ptr
->cursor_server
);
309 if (*error
== MEMCACHED_NOTFOUND
)
310 ptr
->cursor_server
++;
311 else if (*error
== MEMCACHED_END
&& *value_length
== 0)
313 else if (*error
== MEMCACHED_END
)
314 assert(0); /* If this happens we have somehow messed up the fetch */
315 else if (*error
!= MEMCACHED_SUCCESS
)