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
)
137 char buffer
[MEMCACHED_DEFAULT_COMMAND_SIZE
];
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 send_length
= snprintf(buffer
, MEMCACHED_DEFAULT_COMMAND_SIZE
, "get %.*s\r\n",
151 (int)key_length
, key
);
153 if ((memcached_io_write(ptr
, server_key
, buffer
, send_length
, 1)) == -1)
155 *error
= MEMCACHED_WRITE_FAILURE
;
159 value
= memcached_value_fetch(ptr
, key
, &key_length
, value_length
, flags
,
160 error
, 0, server_key
);
161 if (*error
== MEMCACHED_END
&& *value_length
== 0)
163 *error
= MEMCACHED_NOTFOUND
;
166 else if (*error
== MEMCACHED_END
)
167 assert(0); /* If this happens we have somehow messed up the fetch */
168 else if (*error
== MEMCACHED_SUCCESS
)
171 /* We need to read END */
172 rc
= memcached_response(ptr
, buffer
, MEMCACHED_DEFAULT_COMMAND_SIZE
, server_key
);
174 if (rc
!= MEMCACHED_END
)
176 *error
= MEMCACHED_PROTOCOL_ERROR
;
183 LIBMEMCACHED_MEMCACHED_GET_END();
191 LIBMEMCACHED_MEMCACHED_GET_END();
196 memcached_return
memcached_mget(memcached_st
*ptr
,
197 char **keys
, size_t *key_length
,
198 unsigned int number_of_keys
)
200 char buffer
[HUGE_STRING_LEN
];
203 memcached_string_st
**cursor_key_exec
;
204 LIBMEMCACHED_MEMCACHED_MGET_START();
206 ptr
->cursor_server
= 0;
207 memset(buffer
, 0, HUGE_STRING_LEN
);
209 cursor_key_exec
= (memcached_string_st
**)malloc(sizeof(memcached_string_st
*) * ptr
->number_of_hosts
);
210 memset(cursor_key_exec
, 0, sizeof(memcached_string_st
*) * ptr
->number_of_hosts
);
213 for (x
= 0; x
< number_of_keys
; x
++)
215 unsigned int server_key
;
217 server_key
= memcached_generate_hash(ptr
, keys
[x
], key_length
[x
]);
219 if (cursor_key_exec
[server_key
])
221 memcached_string_st
*string
= cursor_key_exec
[server_key
];
223 memcached_string_append_character(ptr
, string
, ' ');
224 memcached_string_append(ptr
, string
, keys
[x
], key_length
[x
]);
228 memcached_string_st
*string
= memcached_string_create(ptr
, SMALL_STRING_LEN
);
230 /* We need to figure out the correct way to error in case of this failure */
234 memcached_string_append(ptr
, string
, "get ", 4);
235 memcached_string_append(ptr
, string
, keys
[x
], key_length
[x
]);
237 cursor_key_exec
[server_key
]= string
;
243 Should we muddle on if some servers are dead?
245 for (x
= 0; x
< ptr
->number_of_hosts
; x
++)
247 if (cursor_key_exec
[x
])
249 /* We need to doo something about non-connnected hosts in the future */
250 rc
= memcached_connect(ptr
, x
);
252 memcached_string_st
*string
= cursor_key_exec
[x
];
253 memcached_string_append(ptr
, string
, "\r\n", 2);
255 if ((memcached_io_write(ptr
, x
, string
->string
,
256 memcached_string_length(ptr
, string
), 1)) == -1)
259 rc
= MEMCACHED_SOME_ERRORS
;
261 memcached_string_free(ptr
, string
);
262 cursor_key_exec
[x
]= NULL
; /* Remove warning */
263 ptr
->hosts
[x
].cursor_active
= 1;
266 ptr
->hosts
[x
].cursor_active
= 0;
269 free(cursor_key_exec
);
271 LIBMEMCACHED_MEMCACHED_MGET_END();
275 char *memcached_fetch(memcached_st
*ptr
, char *key
, size_t *key_length
,
276 size_t *value_length
,
278 memcached_return
*error
)
282 while (ptr
->cursor_server
< ptr
->number_of_hosts
)
284 if (!ptr
->hosts
[ptr
->cursor_server
].cursor_active
)
286 ptr
->cursor_server
++;
290 value_check
= memcached_value_fetch(ptr
, key
, key_length
, value_length
, flags
,
291 error
, 1, ptr
->cursor_server
);
293 if (*error
== MEMCACHED_NOTFOUND
)
294 ptr
->cursor_server
++;
295 else if (*error
== MEMCACHED_END
&& *value_length
== 0)
297 else if (*error
== MEMCACHED_END
)
298 assert(0); /* If this happens we have somehow messed up the fetch */
299 else if (*error
!= MEMCACHED_SUCCESS
)