/*doc Memcached getMulti(keys) Asks memcached to retrieve data corresponding to the list of keys. Returns a Map with the results. If some of the keys appearing in a retrieval request are not sent back by the server in the item list this means that the server does not hold items with such keys */ IoObject *IoMemcached_getMulti(IoMemcached *self, IoObject *locals, IoMessage *m) { IoList *keys_list = IoMessage_locals_listArgAt_(m, locals, 0); size_t keys_list_size = IoList_rawSize(keys_list); IoObject *results_map = IoMap_new(IOSTATE); if(keys_list_size == 0) return results_map; int i; for(i = 0; i < keys_list_size; i++) { IoSeq *key = IoList_rawAt_(keys_list, i); IOASSERT(ISSEQ(key), "key must be a Sequence"); IOASSERT(IOSEQ_LENGTH(key) > 0, "key cannot be an empty Sequence"); IOASSERT(IOSEQ_LENGTH(key) < MEMCACHED_MAX_KEY, "key is too long"); } const char **ckeys = (const char **) malloc(sizeof(const char *) * keys_list_size); size_t *ckey_lengths = (size_t *) malloc(sizeof(size_t) * keys_list_size); for(i = 0; i < keys_list_size; i++) { ckeys[i] = CSTRING(IoList_rawAt_(keys_list, i)); ckey_lengths[i] = strlen(ckeys[i]); } memcached_return_t rc = memcached_mget(DATA(self)->mc, ckeys, ckey_lengths, keys_list_size); free(ckeys); free(ckey_lengths); char returned_key[MEMCACHED_MAX_KEY], *returned_value; size_t returned_key_length, returned_value_length; uint32_t flags; returned_value = memcached_fetch(DATA(self)->mc, returned_key, &returned_key_length, &returned_value_length, &flags, &rc ); while(returned_value != NULL) { IoMap_rawAtPut(results_map, IoSeq_newSymbolWithData_length_(IOSTATE, returned_key, returned_key_length), IoMemcached_deserialize(self, returned_value, returned_value_length, flags) ); free(returned_value); returned_value = memcached_fetch(DATA(self)->mc, returned_key, &returned_key_length, &returned_value_length, &flags, &rc ); } return results_map; }
IoSymbol *IoSeq_newSymbolWithCString_(void *state, const char *s) { return IoSeq_newSymbolWithData_length_(state, s, strlen(s)); }