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
;
129 What happens if no servers exist?
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
)
172 WATCHPOINT_ASSERT(0); /* If this happens we have somehow messed up the fetch */
174 else if (*error
== MEMCACHED_SUCCESS
)
177 /* We need to read END */
178 rc
= memcached_response(ptr
, buffer
, MEMCACHED_DEFAULT_COMMAND_SIZE
, server_key
);
180 if (rc
!= MEMCACHED_END
)
182 *error
= MEMCACHED_PROTOCOL_ERROR
;
189 LIBMEMCACHED_MEMCACHED_GET_END();
197 LIBMEMCACHED_MEMCACHED_GET_END();
202 memcached_return
memcached_mget(memcached_st
*ptr
,
203 char **keys
, size_t *key_length
,
204 unsigned int number_of_keys
)
207 memcached_return rc
= MEMCACHED_NOTFOUND
;
208 char *cursor_key_exec
;
209 LIBMEMCACHED_MEMCACHED_MGET_START();
210 ptr
->cursor_server
= 0;
212 if (number_of_keys
== 0)
213 return MEMCACHED_NOTFOUND
;
215 cursor_key_exec
= (char *)malloc(sizeof(char) * ptr
->number_of_hosts
);
216 memset(cursor_key_exec
, 0, sizeof(char) * ptr
->number_of_hosts
);
218 for (x
= 0; x
< number_of_keys
; x
++)
220 unsigned int server_key
;
222 server_key
= memcached_generate_hash(ptr
, keys
[x
], key_length
[x
]);
224 if (cursor_key_exec
[server_key
] == 0)
226 rc
= memcached_connect(ptr
, server_key
);
228 if ((memcached_io_write(ptr
, server_key
, "get ", 4, 0)) == -1)
231 rc
= MEMCACHED_SOME_ERRORS
;
236 if ((memcached_io_write(ptr
, server_key
, keys
[x
], key_length
[x
], 0)) == -1)
239 rc
= MEMCACHED_SOME_ERRORS
;
243 if ((memcached_io_write(ptr
, server_key
, " ", 1, 0)) == -1)
246 rc
= MEMCACHED_SOME_ERRORS
;
249 cursor_key_exec
[server_key
]= 1;
254 Should we muddle on if some servers are dead?
256 for (x
= 0; x
< ptr
->number_of_hosts
; x
++)
258 if (cursor_key_exec
[x
])
260 /* We need to doo something about non-connnected hosts in the future */
261 if ((memcached_io_write(ptr
, x
, "\r\n", 2, 1)) == -1)
264 rc
= MEMCACHED_SOME_ERRORS
;
268 ptr
->hosts
[x
].cursor_active
= 1;
271 ptr
->hosts
[x
].cursor_active
= 0;
274 free(cursor_key_exec
);
276 LIBMEMCACHED_MEMCACHED_MGET_END();
280 char *memcached_fetch(memcached_st
*ptr
, char *key
, size_t *key_length
,
281 size_t *value_length
,
283 memcached_return
*error
)
287 while (ptr
->cursor_server
< ptr
->number_of_hosts
)
289 if (!ptr
->hosts
[ptr
->cursor_server
].cursor_active
)
291 ptr
->cursor_server
++;
295 value_check
= memcached_value_fetch(ptr
, key
, key_length
, value_length
, flags
,
296 error
, 1, ptr
->cursor_server
);
298 if (*error
== MEMCACHED_NOTFOUND
)
299 ptr
->cursor_server
++;
300 else if (*error
== MEMCACHED_END
&& *value_length
== 0)
302 else if (*error
== MEMCACHED_END
)
304 WATCHPOINT_ASSERT(0); /* If this happens we have somehow messed up the fetch */
306 else if (*error
!= MEMCACHED_SUCCESS
)