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));
91 *error
= MEMCACHED_MEMORY_ALLOCATION_FAILURE
;
94 memset(value
, 0, ((*value_length
) +2) * sizeof(char));
99 We read the \r\n into the string since not doing so is more
100 cycles then the waster of memory to do so.
102 We are null terminating through, which will most likely make
103 some people lazy about using the return length.
105 to_read
= (*value_length
) + 2;
107 read_length
= memcached_io_read(ptr
, server_key
,
110 if (read_length
!= (size_t)(*value_length
+ 2))
116 value
[*value_length
]= 0;
117 value
[(*value_length
) + 1]= 0;
122 else if (*error
== MEMCACHED_END
)
123 *error
= MEMCACHED_NOTFOUND
;
127 *error
= MEMCACHED_PARTIAL_READ
;
131 char *memcached_get(memcached_st
*ptr
, char *key
, size_t key_length
,
132 size_t *value_length
,
134 memcached_return
*error
)
136 char buffer
[MEMCACHED_DEFAULT_COMMAND_SIZE
];
137 char *buf_ptr
= buffer
;
138 unsigned int server_key
;
140 LIBMEMCACHED_MEMCACHED_GET_START();
142 server_key
= memcached_generate_hash(ptr
, key
, key_length
);
145 *error
= memcached_connect(ptr
, server_key
);
147 if (*error
!= MEMCACHED_SUCCESS
)
150 memcpy(buf_ptr
, "get ", 4);
152 memcpy(buf_ptr
, key
, key_length
);
153 buf_ptr
+= key_length
;
154 memcpy(buf_ptr
, "\r\n", 2);
157 if ((memcached_io_write(ptr
, server_key
, buffer
, (size_t)(buf_ptr
- buffer
), 1)) == -1)
159 *error
= MEMCACHED_WRITE_FAILURE
;
163 value
= memcached_value_fetch(ptr
, key
, &key_length
, value_length
, flags
,
164 error
, 0, server_key
);
165 if (*error
== MEMCACHED_END
&& *value_length
== 0)
167 *error
= MEMCACHED_NOTFOUND
;
170 else if (*error
== MEMCACHED_END
)
171 assert(0); /* If this happens we have somehow messed up the fetch */
172 else if (*error
== MEMCACHED_SUCCESS
)
175 /* We need to read END */
176 rc
= memcached_response(ptr
, buffer
, MEMCACHED_DEFAULT_COMMAND_SIZE
, server_key
);
178 if (rc
!= MEMCACHED_END
)
180 *error
= MEMCACHED_PROTOCOL_ERROR
;
187 LIBMEMCACHED_MEMCACHED_GET_END();
195 LIBMEMCACHED_MEMCACHED_GET_END();
200 memcached_return
memcached_mget(memcached_st
*ptr
,
201 char **keys
, size_t *key_length
,
202 unsigned int number_of_keys
)
204 char buffer
[HUGE_STRING_LEN
];
207 memcached_string_st
**cursor_key_exec
;
208 LIBMEMCACHED_MEMCACHED_MGET_START();
210 ptr
->cursor_server
= 0;
211 memset(buffer
, 0, HUGE_STRING_LEN
);
213 cursor_key_exec
= (memcached_string_st
**)malloc(sizeof(memcached_string_st
*) * ptr
->number_of_hosts
);
214 memset(cursor_key_exec
, 0, sizeof(memcached_string_st
*) * ptr
->number_of_hosts
);
217 for (x
= 0; x
< number_of_keys
; x
++)
219 unsigned int server_key
;
221 server_key
= memcached_generate_hash(ptr
, keys
[x
], key_length
[x
]);
223 if (cursor_key_exec
[server_key
])
225 memcached_string_st
*string
= cursor_key_exec
[server_key
];
227 memcached_string_append_character(ptr
, string
, ' ');
228 memcached_string_append(ptr
, string
, keys
[x
], key_length
[x
]);
232 memcached_string_st
*string
= memcached_string_create(ptr
, SMALL_STRING_LEN
);
234 /* We need to figure out the correct way to error in case of this failure */
238 memcached_string_append(ptr
, string
, "get ", 4);
239 memcached_string_append(ptr
, string
, keys
[x
], key_length
[x
]);
241 cursor_key_exec
[server_key
]= string
;
247 Should we muddle on if some servers are dead?
249 for (x
= 0; x
< ptr
->number_of_hosts
; x
++)
251 if (cursor_key_exec
[x
])
253 /* We need to doo something about non-connnected hosts in the future */
254 rc
= memcached_connect(ptr
, x
);
256 memcached_string_st
*string
= cursor_key_exec
[x
];
257 memcached_string_append(ptr
, string
, "\r\n", 2);
259 if ((memcached_io_write(ptr
, x
, string
->string
,
260 memcached_string_length(ptr
, string
), 1)) == -1)
263 rc
= MEMCACHED_SOME_ERRORS
;
265 memcached_string_free(ptr
, string
);
266 cursor_key_exec
[x
]= NULL
; /* Remove warning */
267 ptr
->hosts
[x
].cursor_active
= 1;
270 ptr
->hosts
[x
].cursor_active
= 0;
273 free(cursor_key_exec
);
275 LIBMEMCACHED_MEMCACHED_MGET_END();
279 char *memcached_fetch(memcached_st
*ptr
, char *key
, size_t *key_length
,
280 size_t *value_length
,
282 memcached_return
*error
)
286 while (ptr
->cursor_server
< ptr
->number_of_hosts
)
288 if (!ptr
->hosts
[ptr
->cursor_server
].cursor_active
)
290 ptr
->cursor_server
++;
294 value_check
= memcached_value_fetch(ptr
, key
, key_length
, value_length
, flags
,
295 error
, 1, ptr
->cursor_server
);
297 if (*error
== MEMCACHED_NOTFOUND
)
298 ptr
->cursor_server
++;
299 else if (*error
== MEMCACHED_END
&& *value_length
== 0)
301 else if (*error
== MEMCACHED_END
)
302 assert(0); /* If this happens we have somehow messed up the fetch */
303 else if (*error
!= MEMCACHED_SUCCESS
)