+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * Libmemcached library
+ *
+ * Copyright (C) 2011-2012 Data Differential, http://datadifferential.com/
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * The names of its contributors may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
/*
* Summary: C++ interface for memcached server
*
Memcache()
{
- memc= memcached("", 0);
+ memc_= memcached(NULL, 0);
}
Memcache(const std::string &config)
{
- memc= memcached(config.c_str(), config.size());
+ memc_= memcached(config.c_str(), config.size());
}
Memcache(const std::string &hostname, in_port_t port)
{
- memc= memcached("", 0);
- if (memc)
- memcached_server_add(memc, hostname.c_str(), port);
+ memc_= memcached(NULL, 0);
+ if (memc_)
+ {
+ memcached_server_add(memc_, hostname.c_str(), port);
+ }
}
Memcache(memcached_st *clone)
{
- memc= memcached_clone(NULL, clone);
+ memc_= memcached_clone(NULL, clone);
}
Memcache(const Memcache &rhs)
{
- memc= memcached_clone(NULL, rhs.getImpl());
+ memc_= memcached_clone(NULL, rhs.getImpl());
}
Memcache &operator=(const Memcache &rhs)
{
if (this != &rhs)
{
- memcached_free(memc);
- memc= memcached_clone(NULL, rhs.getImpl());
+ memcached_free(memc_);
+ memc_= memcached_clone(NULL, rhs.getImpl());
}
return *this;
~Memcache()
{
- memcached_free(memc);
+ memcached_free(memc_);
}
/**
*/
const memcached_st *getImpl() const
{
- return memc;
+ return memc_;
}
/**
bool error(std::string& error_message) const
{
- if (memcached_failed(memcached_last_error(memc)))
+ if (memcached_failed(memcached_last_error(memc_)))
{
- error_message+= memcached_last_error_message(memc);
+ error_message+= memcached_last_error_message(memc_);
return true;
}
bool error() const
{
- if (memcached_failed(memcached_last_error(memc)))
+ if (memcached_failed(memcached_last_error(memc_)))
{
return true;
}
bool error(memcached_return_t& arg) const
{
- arg= memcached_last_error(memc);
+ arg= memcached_last_error(memc_);
return memcached_failed(arg);
}
bool setBehavior(memcached_behavior_t flag, uint64_t data)
{
- return (memcached_success(memcached_behavior_set(memc, flag, data)));
+ return (memcached_success(memcached_behavior_set(memc_, flag, data)));
}
uint64_t getBehavior(memcached_behavior_t flag)
{
- return memcached_behavior_get(memc, flag);
+ return memcached_behavior_get(memc_, flag);
}
/**
if (new_memc)
{
- memcached_free(memc);
- memc= new_memc;
+ memcached_free(memc_);
+ memc_= new_memc;
return true;
}
*/
bool addServer(const std::string &server_name, in_port_t port)
{
- return memcached_success(memcached_server_add(memc, server_name.c_str(), port));
+ return memcached_success(memcached_server_add(memc_, server_name.c_str(), port));
}
/**
memcached_return_t rc;
memcached_result_st *result;
- if ((result= memcached_fetch_result(memc, NULL, &rc)))
+ if ((result= memcached_fetch_result(memc_, NULL, &rc)))
{
// Key
key.assign(memcached_result_key_value(result), memcached_result_key_length(result));
// Actual value, null terminated
ret_val.reserve(memcached_result_length(result) +1);
- ret_val.assign(memcached_result_value(result),
- memcached_result_value(result) +memcached_result_length(result));
+ ret_val.assign(memcached_result_value(result),
+ memcached_result_value(result) +memcached_result_length(result) +1);
+ ret_val.resize(memcached_result_length(result));
// Misc
flags= memcached_result_flags(result);
memcached_return_t rc;
size_t value_length= 0;
- char *value= memcached_get(memc, key.c_str(), key.length(),
+ char *value= memcached_get(memc_, key.c_str(), key.length(),
&value_length, &flags, &rc);
if (value != NULL && ret_val.empty())
{
- ret_val.reserve(value_length);
- ret_val.assign(value, value + value_length);
+ ret_val.reserve(value_length +1); // Always provide null
+ ret_val.assign(value, value +value_length +1);
+ ret_val.resize(value_length);
free(value);
+
return true;
}
memcached_return_t rc;
size_t value_length= 0;
- char *value= memcached_get_by_key(memc,
+ char *value= memcached_get_by_key(memc_,
master_key.c_str(), master_key.length(),
key.c_str(), key.length(),
&value_length, &flags, &rc);
if (value)
{
- ret_val.reserve(value_length);
- ret_val.assign(value, value + value_length);
+ ret_val.reserve(value_length +1); // Always provide null
+ ret_val.assign(value, value +value_length +1);
+ ret_val.resize(value_length);
free(value);
+
return true;
}
return false;
* @param[in] keys vector of keys to select
* @return true if all keys are found
*/
- bool mget(std::vector<std::string> &keys)
+ bool mget(const std::vector<std::string>& keys)
{
std::vector<const char *> real_keys;
std::vector<size_t> key_len;
real_keys.reserve(keys.size());
key_len.reserve(keys.size());
- std::vector<std::string>::iterator it= keys.begin();
+ std::vector<std::string>::const_iterator it= keys.begin();
while (it != keys.end())
{
*/
if (not real_keys.empty())
{
- return memcached_success(memcached_mget(memc, &real_keys[0], &key_len[0], real_keys.size()));
+ return memcached_success(memcached_mget(memc_, &real_keys[0], &key_len[0], real_keys.size()));
}
return false;
time_t expiration,
uint32_t flags)
{
- memcached_return_t rc= memcached_set(memc,
+ memcached_return_t rc= memcached_set(memc_,
key.c_str(), key.length(),
&value[0], value.size(),
expiration, flags);
return memcached_success(rc);
}
+ bool set(const std::string &key,
+ const char* value, const size_t value_length,
+ time_t expiration,
+ uint32_t flags)
+ {
+ memcached_return_t rc= memcached_set(memc_,
+ key.c_str(), key.length(),
+ value, value_length,
+ expiration, flags);
+ return memcached_success(rc);
+ }
+
/**
* Writes an object to a server specified by the master_key parameter.
* If the object already exists, it will overwrite the existing object.
* @param[in] flags flags to store with the object
* @return true on succcess; false otherwise
*/
- bool setByKey(const std::string &master_key,
- const std::string &key,
+ bool setByKey(const std::string& master_key,
+ const std::string& key,
const std::vector<char> &value,
time_t expiration,
uint32_t flags)
{
- return memcached_success(memcached_set_by_key(memc, master_key.c_str(),
+ return memcached_success(memcached_set_by_key(memc_, master_key.c_str(),
master_key.length(),
key.c_str(), key.length(),
&value[0], value.size(),
* @param[in] flags flags to store with the objects
* @return true on success; false otherwise
*/
- bool setAll(std::vector<std::string> &keys,
- std::vector< std::vector<char> *> &values,
+ bool setAll(const std::vector<std::string>& keys,
+ const std::vector< std::vector<char> *>& values,
time_t expiration,
uint32_t flags)
{
bool retval= true;
- std::vector<std::string>::iterator key_it= keys.begin();
- std::vector< std::vector<char> *>::iterator val_it= values.begin();
+ std::vector<std::string>::const_iterator key_it= keys.begin();
+ std::vector< std::vector<char> *>::const_iterator val_it= values.begin();
while (key_it != keys.end())
{
retval= set((*key_it), *(*val_it), expiration, flags);
* @param[in] flags flags to store with the objects
* @return true on success; false otherwise
*/
- bool setAll(std::map<const std::string, std::vector<char> > &key_value_map,
+ bool setAll(const std::map<const std::string, std::vector<char> >& key_value_map,
time_t expiration,
uint32_t flags)
{
bool retval= true;
- std::map<const std::string, std::vector<char> >::iterator it= key_value_map.begin();
+ std::map<const std::string, std::vector<char> >::const_iterator it= key_value_map.begin();
while (it != key_value_map.end())
{
}
++it;
}
+
return true;
}
* @param[out] value store the result of the increment here
* @return true on success; false otherwise
*/
- bool increment(const std::string &key, uint32_t offset, uint64_t *value)
+ bool increment(const std::string& key, uint32_t offset, uint64_t *value)
{
- return memcached_success(memcached_increment(memc, key.c_str(), key.length(), offset, value));
+ return memcached_success(memcached_increment(memc_, key.c_str(), key.length(), offset, value));
}
/**
* @param[out] value store the result of the decrement here
* @return true on success; false otherwise
*/
- bool decrement(const std::string &key, uint32_t offset, uint64_t *value)
+ bool decrement(const std::string& key, uint32_t offset, uint64_t *value)
{
- return memcached_success(memcached_decrement(memc, key.c_str(),
+ return memcached_success(memcached_decrement(memc_, key.c_str(),
key.length(),
offset, value));
}
* @param[in] value of object to add
* @return true on success; false otherwise
*/
- bool add(const std::string &key, const std::vector<char> &value)
+ bool add(const std::string& key, const std::vector<char>& value)
{
- return memcached_success(memcached_add(memc, key.c_str(), key.length(),
+ return memcached_success(memcached_add(memc_, key.c_str(), key.length(),
&value[0], value.size(), 0, 0));
}
* @param[in] value of object to add
* @return true on success; false otherwise
*/
- bool addByKey(const std::string &master_key,
- const std::string &key,
- const std::vector<char> &value)
+ bool addByKey(const std::string& master_key,
+ const std::string& key,
+ const std::vector<char>& value)
{
- return memcached_success(memcached_add_by_key(memc,
+ return memcached_success(memcached_add_by_key(memc_,
master_key.c_str(),
master_key.length(),
key.c_str(),
* @param[in[ value value to replace object with
* @return true on success; false otherwise
*/
- bool replace(const std::string &key, const std::vector<char> &value)
+ bool replace(const std::string& key, const std::vector<char>& value)
{
- return memcached_success(memcached_replace(memc, key.c_str(), key.length(),
+ return memcached_success(memcached_replace(memc_, key.c_str(), key.length(),
&value[0], value.size(),
0, 0));
}
* @param[in[ value value to replace object with
* @return true on success; false otherwise
*/
- bool replaceByKey(const std::string &master_key,
- const std::string &key,
- const std::vector<char> &value)
+ bool replaceByKey(const std::string& master_key,
+ const std::string& key,
+ const std::vector<char>& value)
{
- return memcached_success(memcached_replace_by_key(memc,
+ return memcached_success(memcached_replace_by_key(memc_,
master_key.c_str(),
master_key.length(),
key.c_str(),
* @param[in] value data to prepend to object's value
* @return true on success; false otherwise
*/
- bool prepend(const std::string &key, const std::vector<char> &value)
+ bool prepend(const std::string& key, const std::vector<char>& value)
{
- return memcached_success(memcached_prepend(memc, key.c_str(), key.length(),
+ return memcached_success(memcached_prepend(memc_, key.c_str(), key.length(),
&value[0], value.size(), 0, 0));
}
* @param[in] value data to prepend to object's value
* @return true on success; false otherwise
*/
- bool prependByKey(const std::string &master_key,
- const std::string &key,
- const std::vector<char> &value)
+ bool prependByKey(const std::string& master_key,
+ const std::string& key,
+ const std::vector<char>& value)
{
- return memcached_success(memcached_prepend_by_key(memc,
+ return memcached_success(memcached_prepend_by_key(memc_,
master_key.c_str(),
master_key.length(),
key.c_str(),
* @param[in] value data to append to object's value
* @return true on success; false otherwise
*/
- bool append(const std::string &key, const std::vector<char> &value)
+ bool append(const std::string& key, const std::vector<char>& value)
{
- return memcached_success(memcached_append(memc,
+ return memcached_success(memcached_append(memc_,
key.c_str(),
key.length(),
&value[0],
* @param[in] value data to append to object's value
* @return true on success; false otherwise
*/
- bool appendByKey(const std::string &master_key,
- const std::string &key,
+ bool appendByKey(const std::string& master_key,
+ const std::string& key,
const std::vector<char> &value)
{
- return memcached_success(memcached_append_by_key(memc,
+ return memcached_success(memcached_append_by_key(memc_,
master_key.c_str(),
master_key.length(),
key.c_str(),
* @param[in] value value to store for object in server
* @param[in] cas_arg "cas" value
*/
- bool cas(const std::string &key,
- const std::vector<char> &value,
+ bool cas(const std::string& key,
+ const std::vector<char>& value,
uint64_t cas_arg)
{
- return memcached_success(memcached_cas(memc, key.c_str(), key.length(),
+ return memcached_success(memcached_cas(memc_, key.c_str(), key.length(),
&value[0], value.size(),
0, 0, cas_arg));
}
* @param[in] value value to store for object in server
* @param[in] cas_arg "cas" value
*/
- bool casByKey(const std::string &master_key,
- const std::string &key,
+ bool casByKey(const std::string& master_key,
+ const std::string& key,
const std::vector<char> &value,
uint64_t cas_arg)
{
- return memcached_success(memcached_cas_by_key(memc,
+ return memcached_success(memcached_cas_by_key(memc_,
master_key.c_str(),
master_key.length(),
key.c_str(),
* @param[in] key key of object to delete
* @return true on success; false otherwise
*/
- bool remove(const std::string &key)
+ bool remove(const std::string& key)
{
- return memcached_success(memcached_delete(memc, key.c_str(), key.length(), 0));
+ return memcached_success(memcached_delete(memc_, key.c_str(), key.length(), 0));
}
/**
* @param[in] expiration time to delete the object after
* @return true on success; false otherwise
*/
- bool remove(const std::string &key, time_t expiration)
+ bool remove(const std::string& key, time_t expiration)
{
- return memcached_success(memcached_delete(memc,
+ return memcached_success(memcached_delete(memc_,
key.c_str(),
key.length(),
expiration));
* @param[in] key key of object to delete
* @return true on success; false otherwise
*/
- bool removeByKey(const std::string &master_key,
- const std::string &key)
+ bool removeByKey(const std::string& master_key,
+ const std::string& key)
{
- return memcached_success(memcached_delete_by_key(memc,
+ return memcached_success(memcached_delete_by_key(memc_,
master_key.c_str(),
master_key.length(),
key.c_str(),
* @param[in] expiration time to delete the object after
* @return true on success; false otherwise
*/
- bool removeByKey(const std::string &master_key,
- const std::string &key,
+ bool removeByKey(const std::string& master_key,
+ const std::string& key,
time_t expiration)
{
- return memcached_success(memcached_delete_by_key(memc,
+ return memcached_success(memcached_delete_by_key(memc_,
master_key.c_str(),
master_key.length(),
key.c_str(),
*/
bool flush(time_t expiration= 0)
{
- return memcached_success(memcached_flush(memc, expiration));
+ return memcached_success(memcached_flush(memc_, expiration));
}
/**
* stats
* @return true on success; false otherwise
*/
- bool getStats(std::map< std::string, std::map<std::string, std::string> >
- &stats_map)
+ bool getStats(std::map< std::string, std::map<std::string, std::string> >& stats_map)
{
memcached_return_t rc;
- memcached_stat_st *stats= memcached_stat(memc, NULL, &rc);
+ memcached_stat_st *stats= memcached_stat(memc_, NULL, &rc);
if (rc != MEMCACHED_SUCCESS &&
rc != MEMCACHED_SOME_ERRORS)
return false;
}
- uint32_t server_count= memcached_server_count(memc);
+ uint32_t server_count= memcached_server_count(memc_);
/*
* For each memcached server, construct a std::map for its stats and add
*/
for (uint32_t x= 0; x < server_count; x++)
{
- memcached_server_instance_st instance=
- memcached_server_instance_by_position(memc, x);
+ const memcached_instance_st * instance= memcached_server_instance_by_position(memc_, x);
std::ostringstream strstm;
std::string server_name(memcached_server_name(instance));
server_name.append(":");
server_name.append(strstm.str());
std::map<std::string, std::string> server_stats;
- char **list= NULL;
- char **ptr= NULL;
-
- list= memcached_stat_get_keys(memc, &stats[x], &rc);
- for (ptr= list; *ptr; ptr++)
+ char **list= memcached_stat_get_keys(memc_, &stats[x], &rc);
+ for (char** ptr= list; *ptr; ptr++)
{
- char *value= memcached_stat_get_value(memc, &stats[x], *ptr, &rc);
+ char *value= memcached_stat_get_value(memc_, &stats[x], *ptr, &rc);
server_stats[*ptr]= value;
free(value);
}
free(list);
}
- memcached_stat_free(memc, stats);
+ memcached_stat_free(memc_, stats);
return true;
}
private:
- memcached_st *memc;
+ memcached_st *memc_;
};
}