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 char *cursor_key_exec
;
205 LIBMEMCACHED_MEMCACHED_MGET_START();
207 ptr
->cursor_server
= 0;
208 memset(buffer
, 0, HUGE_STRING_LEN
);
210 cursor_key_exec
= (char *)malloc(sizeof(char) * ptr
->number_of_hosts
);
211 memset(cursor_key_exec
, 0, sizeof(char) * 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
] == 0)
222 rc
= memcached_connect(ptr
, server_key
);
224 if ((memcached_io_write(ptr
, server_key
, "get ", 4, 0)) == -1)
227 rc
= MEMCACHED_SOME_ERRORS
;
232 if ((memcached_io_write(ptr
, server_key
, keys
[x
], key_length
[x
], 0)) == -1)
235 rc
= MEMCACHED_SOME_ERRORS
;
239 if ((memcached_io_write(ptr
, server_key
, " ", 1, 0)) == -1)
242 rc
= MEMCACHED_SOME_ERRORS
;
245 cursor_key_exec
[server_key
]= 1;
250 Should we muddle on if some servers are dead?
252 for (x
= 0; x
< ptr
->number_of_hosts
; x
++)
254 if (cursor_key_exec
[x
])
256 /* We need to doo something about non-connnected hosts in the future */
257 if ((memcached_io_write(ptr
, x
, "\r\n", 2, 1)) == -1)
260 rc
= MEMCACHED_SOME_ERRORS
;
264 ptr
->hosts
[x
].cursor_active
= 1;
267 ptr
->hosts
[x
].cursor_active
= 0;
270 free(cursor_key_exec
);
272 LIBMEMCACHED_MEMCACHED_MGET_END();
276 char *memcached_fetch(memcached_st
*ptr
, char *key
, size_t *key_length
,
277 size_t *value_length
,
279 memcached_return
*error
)
283 while (ptr
->cursor_server
< ptr
->number_of_hosts
)
285 if (!ptr
->hosts
[ptr
->cursor_server
].cursor_active
)
287 ptr
->cursor_server
++;
291 value_check
= memcached_value_fetch(ptr
, key
, key_length
, value_length
, flags
,
292 error
, 1, ptr
->cursor_server
);
294 if (*error
== MEMCACHED_NOTFOUND
)
295 ptr
->cursor_server
++;
296 else if (*error
== MEMCACHED_END
&& *value_length
== 0)
298 else if (*error
== MEMCACHED_END
)
299 assert(0); /* If this happens we have somehow messed up the fetch */
300 else if (*error
!= MEMCACHED_SUCCESS
)