Example #1
0
/*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;
}
Example #2
0
/**
 * @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);
}
Example #3
0
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;
}
Example #4
0
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;
 }
Example #6
0
    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);
    }
Example #7
0
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;
}