/*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; }
/** * @function memcached.mget * * ### Synopsis: * * var o = memcache.get(handle, array_of_keys); * * Get multiple values, identified by an array of keys, from memcached. * * The returned object is a hash of returned values, indexed by the key. * * For each of these keys, the value is an object in the form described at the top of this page. * * @param {object} handle - handle to memcached connection. * @param {array} keys - array of keys of data to get from memcached * @return {object} o - has of objects of the form described at top of the page, or false if an error occurred. */ JSVAL _memcached_mget (JSARGS args) { HandleScope scope; M* handle = HANDLE(args[0]); Handle<Array> aKeys = Handle<Array>::Cast(args[1]); int numKeys = aKeys->Length(); char *keys[numKeys]; size_t key_lengths[numKeys]; for (int i = 0; i < numKeys; i++) { String::Utf8Value k(aKeys->Get(i)); keys[i] = *k; key_lengths[i] = strlen(keys[i]); } R rc = memcached_mget(handle, keys, key_lengths, numKeys); if (rc != MEMCACHED_SUCCESS) { return String::New(memcached_strerror(handle, rc)); } char return_key[MEMCACHED_MAX_KEY]; size_t return_key_length; char *return_value; size_t return_value_length; uint32_t flags; JSOBJ result = Object::New(); while ((return_value = memcached_fetch(handle, return_key, &return_key_length, &return_value_length, &flags, &rc))) { JSOBJ o = Object::New(); o->Set(String::New("value"), String::New(return_value)); o->Set(String::New("flags"), Integer::New(flags)); o->Set(String::New("rc"), Integer::New(rc)); free(return_value); result->Set(String::New(return_key), o); } return scope.Close(result); }
int ssMemcached::multiget(char *sKeySet[], size_t *nKeySetLen, int nKeySetNum, char *pReturnData[], char *pKeySet[], const int nValueLen) { char return_key[MEMCACHED_MAX_KEY]; size_t return_key_length; char *return_value; size_t return_value_length; uint32_t flags; int index = 0; memset(return_key, 0, sizeof(return_key)); retCode_ = memcached_mget(memc_, sKeySet, nKeySetLen, nKeySetNum); if (retCode_ == MEMCACHED_SUCCESS) { int i = 0; return_value = memcached_fetch(memc_, return_key, &return_key_length, &return_value_length, &flags, &retCode_); while (return_value != NULL) { if (retCode_ == MEMCACHED_SUCCESS) { for (i = 0; i < nKeySetNum; i++) { index = index % nKeySetNum; if (strcmp(sKeySet[index], return_key) == 0) { break; } else { index = (index + 1) % nKeySetNum; } } if (i < nKeySetNum) { if (return_value_length >= nValueLen) { strncpy(pReturnData[index], return_value, nValueLen - 1); } else { strncpy(pReturnData[index], return_value, return_value_length); } if (return_key_length >= CACHEKEYLEN) { strncpy(pKeySet[index], return_key, CACHEKEYLEN - 1); } else { strncpy(pKeySet[index], return_key, return_key_length); } memset(return_key, 0, sizeof(return_key)); index++; free(return_value); } else { return 0; } } else { return 0; } } } else { return 0; } return 1; }
static const void* kv_mget_next(kv_mget_data* m, void* keybuf, size_t* keybuflen, size_t* result_vallen) { uint32_t flags; if(m->lastbuf != NULL) { free(m->lastbuf); m->lastbuf = NULL; } m->lastbuf = memcached_fetch(m->c->st, keybuf, keybuflen, result_vallen, &flags, &m->c->err); if(m->c->err != MEMCACHED_SUCCESS) { return NULL; } return m->lastbuf; }
/** * Fetches an individual value from the server. mget() must always * be called before using this method. * * @param[in] key key of object to fetch * @param[out] ret_val store returned object in this vector * @return a memcached return structure */ memcached_return fetch(std::string &key, std::vector<char> &ret_val) { char ret_key[MEMCACHED_MAX_KEY]; size_t value_length= 0; size_t key_length= 0; memcached_return rc; uint32_t flags= 0; char *value= memcached_fetch(&memc, ret_key, &key_length, &value_length, &flags, &rc); if (value && ret_val.empty()) { ret_val.reserve(value_length); ret_val.assign(value, value + value_length); key.assign(ret_key); } return rc; }
virtual void read(payload_t *keys, int count, payload_t *values = NULL) { char *_value; size_t _value_length; uint32_t _flags; memcached_return_t _error; // Convert keys to arrays suitable for memcached char* __keys[count]; size_t __sizes[count]; for(int i = 0; i < count; i++) { __keys[i] = keys[i].first; __sizes[i] = keys[i].second; } // Do the multiget _error = memcached_mget(&memcached, __keys, __sizes, count); if(_error != MEMCACHED_SUCCESS) { fprintf(stderr, "Error performing multiread operation (%d)\n", _error); exit(-1); } // Fetch the results int i = 0; do { _value = memcached_fetch(&memcached, __keys[i], &__sizes[i], &_value_length, &_flags, &_error); if(_error != MEMCACHED_SUCCESS && _error != MEMCACHED_END) { fprintf(stderr, "Error performing read operation (%d)\n", _error); exit(-1); } if (values != NULL) { if (_value_length != values[i].second || memcmp(_value, values[i].first, _value_length) != 0) { fprintf(stderr, "Incorrect value in database\n"); exit(-1); } } free(_value); i++; } while(_value != NULL); }
int main(int argc, char *argv[]) { if (argc < 3) { std::cerr << "Usage: qurluniqmgr set|get servers" << std::endl; exit(1); } std::string cmd = argv[1]; std::string server = argv[2]; memcached_st *queue; queue = memcached_create(NULL); memcached_server_st *servers; servers= memcached_servers_parse(server.c_str()); if (servers != NULL) { memcached_server_push(queue, servers); memcached_server_list_free(servers); } else { std::cerr << "Error server config error" << std::endl; std::cerr << "Usage: qurluniqmgr set|get servers" << std::endl; exit(1); } if (cmd == "set") { std::string line; int count = 0; while (std::getline(std::cin, line)) { ++count; if (count % 100000 == 0) { std::cerr << "get total " << count << std::endl; } if (line.size() == 0) { continue; } memcached_return_t rc = memcached_set(queue, line.c_str(), line.size(), "1", 1, 0, 0); if (rc != MEMCACHED_SUCCESS) { std::cerr << "set " << line << " error " << std::endl; } } } else if (cmd == "set0") { std::string line; int count = 0; while (std::getline(std::cin, line)) { ++count; if (count % 100000 == 0) { std::cerr << "get total " << count << std::endl; } if (line.size() == 0) { continue; } memcached_return_t rc = memcached_set(queue, line.c_str(), line.size(), "0", 1, 0, 0); if (rc != MEMCACHED_SUCCESS) { std::cerr << "set " << line << " error " << std::endl; } } } else if (cmd == "get") { const char* keys[BATCH_SIZE]; size_t key_lens[BATCH_SIZE]; char ret_key[256]; size_t ret_key_len; size_t ret_val_len; uint32_t flags; char * ret_val = NULL; memcached_return rc; std::vector<std::string> batch_vec; std::string line; int count = 0; while (std::getline(std::cin, line)) { ++count; if (count % 100000 == 0) { std::cerr << "get total " << count << std::endl; } if (line.size() == 0) { continue; } batch_vec.push_back(line); if (batch_vec.size() == BATCH_SIZE) { for (size_t i = 0; i < batch_vec.size(); i++) { keys[i] = batch_vec[i].c_str(); key_lens[i] = batch_vec[i].size(); } rc = memcached_mget(queue, keys, key_lens, batch_vec.size()); if (rc == MEMCACHED_SUCCESS || rc == MEMCACHED_DATA_EXISTS || rc == MEMCACHED_STORED) { while ((ret_val = memcached_fetch(queue, ret_key, &ret_key_len, &ret_val_len, &flags, &rc))) { free(ret_val); } } else { std::cerr << "ERROR when store " << std::endl; } batch_vec.clear(); } } if (batch_vec.size() > 0) { for (size_t i = 0; i < batch_vec.size(); i++) { keys[i] = batch_vec[i].c_str(); key_lens[i] = batch_vec[i].size(); } rc = memcached_mget(queue, keys, key_lens, batch_vec.size()); if (rc == MEMCACHED_SUCCESS || rc == MEMCACHED_DATA_EXISTS || rc == MEMCACHED_STORED) { while ((ret_val = memcached_fetch(queue, ret_key, &ret_key_len, &ret_val_len, &flags, &rc))) { free(ret_val); } } else { std::cerr << "ERROR when store " << std::endl; } batch_vec.clear(); } } else { std::cerr << "No cmd " << cmd << " supported"<< std::endl; std::cerr << "Usage: qurluniqmgr set|get servers" << std::endl; exit(1); } return 0; }