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
)
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
)
205 memcached_return rc
= MEMCACHED_NOTFOUND
;
206 char *cursor_key_exec
;
207 LIBMEMCACHED_MEMCACHED_MGET_START();
208 ptr
->cursor_server
= 0;
210 if (number_of_keys
== 0)
211 return MEMCACHED_NOTFOUND
;
213 cursor_key_exec
= (char *)malloc(sizeof(char) * ptr
->number_of_hosts
);
214 memset(cursor_key_exec
, 0, sizeof(char) * ptr
->number_of_hosts
);
216 for (x
= 0; x
< number_of_keys
; x
++)
218 unsigned int server_key
;
220 server_key
= memcached_generate_hash(ptr
, keys
[x
], key_length
[x
]);
222 if (cursor_key_exec
[server_key
] == 0)
224 rc
= memcached_connect(ptr
, server_key
);
226 if ((memcached_io_write(ptr
, server_key
, "get ", 4, 0)) == -1)
229 rc
= MEMCACHED_SOME_ERRORS
;
234 if ((memcached_io_write(ptr
, server_key
, keys
[x
], key_length
[x
], 0)) == -1)
237 rc
= MEMCACHED_SOME_ERRORS
;
241 if ((memcached_io_write(ptr
, server_key
, " ", 1, 0)) == -1)
244 rc
= MEMCACHED_SOME_ERRORS
;
247 cursor_key_exec
[server_key
]= 1;
252 Should we muddle on if some servers are dead?
254 for (x
= 0; x
< ptr
->number_of_hosts
; x
++)
256 if (cursor_key_exec
[x
])
258 /* We need to doo something about non-connnected hosts in the future */
259 if ((memcached_io_write(ptr
, x
, "\r\n", 2, 1)) == -1)
262 rc
= MEMCACHED_SOME_ERRORS
;
266 ptr
->hosts
[x
].cursor_active
= 1;
269 ptr
->hosts
[x
].cursor_active
= 0;
272 free(cursor_key_exec
);
274 LIBMEMCACHED_MEMCACHED_MGET_END();
278 char *memcached_fetch(memcached_st
*ptr
, char *key
, size_t *key_length
,
279 size_t *value_length
,
281 memcached_return
*error
)
285 while (ptr
->cursor_server
< ptr
->number_of_hosts
)
287 if (!ptr
->hosts
[ptr
->cursor_server
].cursor_active
)
289 ptr
->cursor_server
++;
293 value_check
= memcached_value_fetch(ptr
, key
, key_length
, value_length
, flags
,
294 error
, 1, ptr
->cursor_server
);
296 if (*error
== MEMCACHED_NOTFOUND
)
297 ptr
->cursor_server
++;
298 else if (*error
== MEMCACHED_END
&& *value_length
== 0)
300 else if (*error
== MEMCACHED_END
)
301 assert(0); /* If this happens we have somehow messed up the fetch */
302 else if (*error
!= MEMCACHED_SUCCESS
)