* @brief Libmemcached C++ interface
*/
-#ifndef LIBMEMCACHEDPP_H
-#define LIBMEMCACHEDPP_H
+#pragma once
#include <libmemcached/memcached.h>
#include <libmemcached/exception.hpp>
public:
Memcache()
- :
- servers_list(),
- memc(),
- result()
{
- memcached_create(&memc);
+ memc= memcached("", 0);
}
- Memcache(const std::string &in_servers_list)
- :
- servers_list(in_servers_list),
- memc(),
- result()
+ Memcache(const std::string &config)
{
- memcached_create(&memc);
- init();
+ memc= memcached(config.c_str(), config.size());
}
- Memcache(const std::string &hostname,
- in_port_t port)
- :
- servers_list(),
- memc(),
- result()
+ Memcache(const std::string &hostname, in_port_t port)
{
- memcached_create(&memc);
-
- servers_list.append(hostname);
- servers_list.append(":");
- std::ostringstream strsmt;
- strsmt << port;
- servers_list.append(strsmt.str());
-
- init();
+ memc= memcached("", 0);
+ if (memc)
+ memcached_server_add(memc, hostname.c_str(), port);
}
Memcache(memcached_st *clone)
- :
- servers_list(),
- memc(),
- result()
{
- memcached_clone(&memc, clone);
+ memc= memcached_clone(NULL, clone);
}
Memcache(const Memcache &rhs)
- :
- servers_list(rhs.servers_list),
- memc(),
- result()
{
- memcached_clone(&memc, const_cast<memcached_st *>(&rhs.getImpl()));
- init();
+ memc= memcached_clone(NULL, rhs.getImpl());
}
Memcache &operator=(const Memcache &rhs)
{
if (this != &rhs)
{
- memcached_clone(&memc, const_cast<memcached_st *>(&rhs.getImpl()));
- init();
+ memcached_free(memc);
+ memc= memcached_clone(NULL, rhs.getImpl());
}
return *this;
~Memcache()
{
- memcached_free(&memc);
- }
-
- void init()
- {
- memcached_server_st *servers;
- servers= memcached_servers_parse(servers_list.c_str());
- memcached_server_push(&memc, servers);
- memcached_server_free(servers);
+ memcached_free(memc);
}
/**
* Get the internal memcached_st *
*/
- memcached_st &getImpl()
- {
- return memc;
- }
-
- /**
- * Get the internal memcached_st *
- */
- const memcached_st &getImpl() const
+ const memcached_st *getImpl() const
{
return memc;
}
bool setBehavior(memcached_behavior_t flag, uint64_t data)
{
- memcached_return_t rc;
- rc= memcached_behavior_set(&memc, flag, data);
- return (rc == MEMCACHED_SUCCESS);
- }
-
- uint64_t getBehavior(memcached_behavior_t flag) {
- return memcached_behavior_get(&memc, flag);
+ return (memcached_success(memcached_behavior_set(memc, flag, data)));
}
- /**
- * Return the string which contains the list of memcached servers being
- * used.
- *
- * @return a std::string containing the list of memcached servers
- */
- const std::string getServersList() const
+ uint64_t getBehavior(memcached_behavior_t flag)
{
- return servers_list;
+ return memcached_behavior_get(memc, flag);
}
/**
- * Set the list of memcached servers to use.
+ * Configure the memcache object
*
- * @param[in] in_servers_list list of servers
+ * @param[in] in_config configuration
* @return true on success; false otherwise
*/
- bool setServers(const std::string &in_servers_list)
+ bool configure(const std::string &configuration)
{
- servers_list.assign(in_servers_list);
- init();
+ memcached_st *new_memc= memcached(configuration.c_str(), configuration.size());
- return (memcached_server_count(&memc));
+ if (new_memc)
+ {
+ memcached_free(memc);
+ memc= new_memc;
+
+ return true;
+ }
+
+ return false;
}
/**
*/
bool addServer(const std::string &server_name, in_port_t port)
{
- memcached_return_t rc;
-
- rc= memcached_server_add(&memc, server_name.c_str(), port);
-
- return (rc == MEMCACHED_SUCCESS);
+ return memcached_success(memcached_server_add(memc, server_name.c_str(), port));
}
/**
tmp_str.append(":");
strstm << port;
tmp_str.append(strstm.str());
- memcached_server_st *server= memcached_servers_parse(tmp_str.c_str());
-
- memcached_return_t rc= memcached_server_remove(server);
- return (rc == MEMCACHED_SUCCESS);
+ //memcached_return_t rc= memcached_server_remove(server);
+
+ return false;
}
/**
* @return a memcached return structure
*/
memcached_return_t fetch(std::string &key,
- std::vector<char> &ret_val)
+ std::vector<char> &ret_val,
+ uint32_t &flags,
+ uint64_t &cas_value)
{
- char ret_key[MEMCACHED_MAX_KEY];
- size_t value_length= 0;
- size_t key_length= 0;
memcached_return_t 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);
- free(value);
- }
- else if (value)
+
+ memcached_result_st *result;
+ if ((result= memcached_fetch_result(memc, NULL, &rc)))
{
- free(value);
+ // 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));
+
+ // Misc
+ flags= memcached_result_flags(result);
+ cas_value= memcached_result_cas(result);
}
+ memcached_result_free(result);
return rc;
}
+ memcached_return_t fetch(std::string &key,
+ std::vector<char> &ret_val)
+ {
+ uint32_t flags= 0;
+ uint64_t cas_value= 0;
+
+ return fetch(key, ret_val, flags, cas_value);
+ }
+
/**
* Fetches an individual value from the server.
*
* this vector
* @return true on success; false otherwise
*/
- bool get(const std::string &key,
- std::vector<char> &ret_val) throw (Error)
+ bool get(const std::string &key, std::vector<char> &ret_val)
{
uint32_t flags= 0;
memcached_return_t rc;
size_t value_length= 0;
- if (key.empty())
- {
- throw(Error("the key supplied is empty!", false));
- }
- 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())
{
free(value);
return true;
}
+
return false;
}
*/
bool getByKey(const std::string &master_key,
const std::string &key,
- std::vector<char> &ret_val) throw(Error)
+ std::vector<char> &ret_val)
{
uint32_t flags= 0;
memcached_return_t rc;
size_t value_length= 0;
- if (master_key.empty() || key.empty())
- {
- throw(Error("the master key or key supplied is empty!", false));
- }
- 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 the std::vector of keys is empty then we cannot
* call memcached_mget as we will get undefined behavior.
*/
- if (! real_keys.empty())
+ if (not real_keys.empty())
{
- memcached_return_t rc= memcached_mget(&memc, &real_keys[0], &key_len[0],
- real_keys.size());
- return (rc == MEMCACHED_SUCCESS);
+ return memcached_success(memcached_mget(memc, &real_keys[0], &key_len[0], real_keys.size()));
}
return false;
bool set(const std::string &key,
const std::vector<char> &value,
time_t expiration,
- uint32_t flags) throw(Error)
+ uint32_t flags)
{
- if (key.empty() || value.empty())
- {
- throw(Error("the key or value supplied is empty!", false));
- }
- memcached_return_t rc= memcached_set(&memc,
- key.c_str(), key.length(),
- &value[0], value.size(),
- expiration, flags);
+ memcached_return_t rc= memcached_set(memc,
+ key.c_str(), key.length(),
+ &value[0], value.size(),
+ expiration, flags);
return (rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
}
const std::string &key,
const std::vector<char> &value,
time_t expiration,
- uint32_t flags) throw(Error)
+ uint32_t flags)
{
- if (master_key.empty() ||
- key.empty() ||
- value.empty())
- {
- throw(Error("the key or value supplied is empty!", false));
- }
- memcached_return_t rc= memcached_set_by_key(&memc, master_key.c_str(),
- master_key.length(),
- key.c_str(), key.length(),
- &value[0], value.size(),
- expiration,
- flags);
- return (rc == MEMCACHED_SUCCESS);
+ return memcached_success(memcached_set_by_key(memc, master_key.c_str(),
+ master_key.length(),
+ key.c_str(), key.length(),
+ &value[0], value.size(),
+ expiration,
+ flags));
}
/**
bool setAll(std::vector<std::string> &keys,
std::vector< std::vector<char> *> &values,
time_t expiration,
- uint32_t flags) throw(Error)
+ uint32_t flags)
{
- if (keys.size() != values.size())
- {
- throw(Error("The number of keys and values do not match!", false));
- }
bool retval= true;
std::vector<std::string>::iterator key_it= keys.begin();
std::vector< std::vector<char> *>::iterator val_it= values.begin();
*/
bool setAll(std::map<const std::string, std::vector<char> > &key_value_map,
time_t expiration,
- uint32_t flags) throw(Error)
+ uint32_t flags)
{
- if (key_value_map.empty())
- {
- throw(Error("The key/values are not properly set!", false));
- }
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> >::iterator it= key_value_map.begin();
+
while (it != key_value_map.end())
{
retval= set(it->first, it->second, expiration, flags);
if (retval == false)
{
- std::string err_buff("There was an error setting the key ");
- err_buff.append(it->first);
- throw(Error(err_buff, false));
+ // We should tell the user what the key that failed was
+ return false;
}
++it;
}
* @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) throw(Error)
+ bool increment(const std::string &key, uint32_t offset, uint64_t *value)
{
- if (key.empty())
- {
- throw(Error("the key supplied is empty!", false));
- }
- memcached_return_t rc= memcached_increment(&memc, key.c_str(), key.length(),
- offset, value);
- return (rc == MEMCACHED_SUCCESS);
+ return memcached_success(memcached_increment(memc, key.c_str(), key.length(), offset, value));
}
/**
* @return true on success; false otherwise
*/
bool decrement(const std::string &key, uint32_t offset, uint64_t *value)
- throw(Error)
{
- if (key.empty())
- {
- throw(Error("the key supplied is empty!", false));
- }
- memcached_return_t rc= memcached_decrement(&memc, key.c_str(),
- key.length(),
- offset, value);
- return (rc == MEMCACHED_SUCCESS);
+ return memcached_success(memcached_decrement(memc, key.c_str(),
+ key.length(),
+ offset, value));
}
* @return true on success; false otherwise
*/
bool add(const std::string &key, const std::vector<char> &value)
- throw(Error)
{
- if (key.empty() || value.empty())
- {
- throw(Error("the key or value supplied is empty!", false));
- }
- memcached_return_t rc= memcached_add(&memc, key.c_str(), key.length(),
- &value[0], value.size(), 0, 0);
- return (rc == MEMCACHED_SUCCESS);
+ return memcached_success(memcached_add(memc, key.c_str(), key.length(),
+ &value[0], value.size(), 0, 0));
}
/**
*/
bool addByKey(const std::string &master_key,
const std::string &key,
- const std::vector<char> &value) throw(Error)
+ const std::vector<char> &value)
{
- if (master_key.empty() ||
- key.empty() ||
- value.empty())
- {
- throw(Error("the master key or key supplied is empty!", false));
- }
- memcached_return_t rc= memcached_add_by_key(&memc,
- master_key.c_str(),
- master_key.length(),
- key.c_str(),
- key.length(),
- &value[0],
- value.size(),
- 0, 0);
- return (rc == MEMCACHED_SUCCESS);
+ return memcached_success(memcached_add_by_key(memc,
+ master_key.c_str(),
+ master_key.length(),
+ 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 replace(const std::string &key, const std::vector<char> &value) throw(Error)
+ bool replace(const std::string &key, const std::vector<char> &value)
{
- if (key.empty() ||
- value.empty())
- {
- throw(Error("the key or value supplied is empty!", false));
- }
- memcached_return_t rc= memcached_replace(&memc, key.c_str(), key.length(),
- &value[0], value.size(),
- 0, 0);
- return (rc == MEMCACHED_SUCCESS);
+ return memcached_success(memcached_replace(memc, key.c_str(), key.length(),
+ &value[0], value.size(),
+ 0, 0));
}
/**
const std::string &key,
const std::vector<char> &value)
{
- if (master_key.empty() ||
- key.empty() ||
- value.empty())
- {
- throw(Error("the master key or key supplied is empty!", false));
- }
- memcached_return_t rc= memcached_replace_by_key(&memc,
- master_key.c_str(),
- master_key.length(),
- key.c_str(),
- key.length(),
- &value[0],
- value.size(),
- 0, 0);
- return (rc == MEMCACHED_SUCCESS);
+ return memcached_success(memcached_replace_by_key(memc,
+ master_key.c_str(),
+ master_key.length(),
+ key.c_str(),
+ key.length(),
+ &value[0],
+ value.size(),
+ 0, 0));
}
/**
* @return true on success; false otherwise
*/
bool prepend(const std::string &key, const std::vector<char> &value)
- throw(Error)
{
- if (key.empty() || value.empty())
- {
- throw(Error("the key or value supplied is empty!", false));
- }
- memcached_return_t rc= memcached_prepend(&memc, key.c_str(), key.length(),
- &value[0], value.size(), 0, 0);
- return (rc == MEMCACHED_SUCCESS);
+ return memcached_success(memcached_prepend(memc, key.c_str(), key.length(),
+ &value[0], value.size(), 0, 0));
}
/**
bool prependByKey(const std::string &master_key,
const std::string &key,
const std::vector<char> &value)
- throw(Error)
{
- if (master_key.empty() ||
- key.empty() ||
- value.empty())
- {
- throw(Error("the master key or key supplied is empty!", false));
- }
- memcached_return_t rc= memcached_prepend_by_key(&memc,
- master_key.c_str(),
- master_key.length(),
- key.c_str(),
- key.length(),
- &value[0],
- value.size(),
- 0,
- 0);
- return (rc == MEMCACHED_SUCCESS);
+ return memcached_success(memcached_prepend_by_key(memc,
+ master_key.c_str(),
+ master_key.length(),
+ key.c_str(),
+ key.length(),
+ &value[0],
+ value.size(),
+ 0,
+ 0));
}
/**
* @return true on success; false otherwise
*/
bool append(const std::string &key, const std::vector<char> &value)
- throw(Error)
{
- if (key.empty() || value.empty())
- {
- throw(Error("the key or value supplied is empty!", false));
- }
- memcached_return_t rc= memcached_append(&memc,
- key.c_str(),
- key.length(),
- &value[0],
- value.size(),
- 0, 0);
- return (rc == MEMCACHED_SUCCESS);
+ return memcached_success(memcached_append(memc,
+ key.c_str(),
+ key.length(),
+ &value[0],
+ value.size(),
+ 0, 0));
}
/**
bool appendByKey(const std::string &master_key,
const std::string &key,
const std::vector<char> &value)
- throw(Error)
{
- if (master_key.empty() ||
- key.empty() ||
- value.empty())
- {
- throw(Error("the master key or key supplied is empty!", false));
- }
- memcached_return_t rc= memcached_append_by_key(&memc,
- master_key.c_str(),
- master_key.length(),
- key.c_str(),
- key.length(),
- &value[0],
- value.size(),
- 0, 0);
- return (rc == MEMCACHED_SUCCESS);
+ return memcached_success(memcached_append_by_key(memc,
+ master_key.c_str(),
+ master_key.length(),
+ key.c_str(),
+ key.length(),
+ &value[0],
+ value.size(),
+ 0, 0));
}
/**
*/
bool cas(const std::string &key,
const std::vector<char> &value,
- uint64_t cas_arg) throw(Error)
+ uint64_t cas_arg)
{
- if (key.empty() || value.empty())
- {
- throw(Error("the key or value supplied is empty!", false));
- }
- memcached_return_t rc= memcached_cas(&memc, key.c_str(), key.length(),
- &value[0], value.size(),
- 0, 0, cas_arg);
- return (rc == MEMCACHED_SUCCESS);
+ return memcached_success(memcached_cas(memc, key.c_str(), key.length(),
+ &value[0], value.size(),
+ 0, 0, cas_arg));
}
/**
bool casByKey(const std::string &master_key,
const std::string &key,
const std::vector<char> &value,
- uint64_t cas_arg) throw(Error)
+ uint64_t cas_arg)
{
- if (master_key.empty() ||
- key.empty() ||
- value.empty())
- {
- throw(Error("the master key, key or value supplied is empty!", false));
- }
- memcached_return_t rc= memcached_cas_by_key(&memc,
- master_key.c_str(),
- master_key.length(),
- key.c_str(),
- key.length(),
- &value[0],
- value.size(),
- 0, 0, cas_arg);
- return (rc == MEMCACHED_SUCCESS);
+ return memcached_success(memcached_cas_by_key(memc,
+ master_key.c_str(),
+ master_key.length(),
+ key.c_str(),
+ key.length(),
+ &value[0],
+ value.size(),
+ 0, 0, cas_arg));
}
/**
* @param[in] key key of object to delete
* @return true on success; false otherwise
*/
- bool remove(const std::string &key) throw(Error)
+ bool remove(const std::string &key)
{
- if (key.empty())
- {
- throw(Error("the key supplied is empty!", false));
- }
- memcached_return_t rc= memcached_delete(&memc, key.c_str(), key.length(), 0);
- return (rc == MEMCACHED_SUCCESS);
+ 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) throw(Error)
+ bool remove(const std::string &key, time_t expiration)
{
- if (key.empty())
- {
- throw(Error("the key supplied is empty!", false));
- }
- memcached_return_t rc= memcached_delete(&memc,
- key.c_str(),
- key.length(),
- expiration);
- return (rc == MEMCACHED_SUCCESS);
+ return memcached_success(memcached_delete(memc,
+ key.c_str(),
+ key.length(),
+ expiration));
}
/**
* @return true on success; false otherwise
*/
bool removeByKey(const std::string &master_key,
- const std::string &key) throw(Error)
+ const std::string &key)
{
- if (master_key.empty() || key.empty())
- {
- throw(Error("the master key or key supplied is empty!", false));
- }
- memcached_return_t rc= memcached_delete_by_key(&memc,
- master_key.c_str(),
- master_key.length(),
- key.c_str(),
- key.length(),
- 0);
- return (rc == MEMCACHED_SUCCESS);
+ return memcached_success(memcached_delete_by_key(memc,
+ master_key.c_str(),
+ master_key.length(),
+ key.c_str(),
+ key.length(),
+ 0));
}
/**
*/
bool removeByKey(const std::string &master_key,
const std::string &key,
- time_t expiration) throw(Error)
+ time_t expiration)
{
- if (master_key.empty() || key.empty())
- {
- throw(Error("the master key or key supplied is empty!", false));
- }
- memcached_return_t rc= memcached_delete_by_key(&memc,
- master_key.c_str(),
- master_key.length(),
- key.c_str(),
- key.length(),
- expiration);
- return (rc == MEMCACHED_SUCCESS);
+ return memcached_success(memcached_delete_by_key(memc,
+ master_key.c_str(),
+ master_key.length(),
+ key.c_str(),
+ key.length(),
+ expiration));
}
/**
* memcached servers
* @return true on success; false otherwise
*/
- bool flush(time_t expiration)
+ bool flush(time_t expiration= 0)
{
- memcached_return_t rc= memcached_flush(&memc, expiration);
- return (rc == MEMCACHED_SUCCESS);
- }
-
- /**
- * Callback function for result sets. It passes the result
- * sets to the list of functions provided.
- *
- * @param[in] callback list of callback functions
- * @param[in] context pointer to memory reference that is
- * supplied to the calling function
- * @param[in] num_of_callbacks number of callback functions
- * @return true on success; false otherwise
- */
- bool fetchExecute(memcached_execute_fn *callback,
- void *context,
- uint32_t num_of_callbacks)
- {
- memcached_return_t rc= memcached_fetch_execute(&memc,
- callback,
- context,
- num_of_callbacks);
- return (rc == MEMCACHED_SUCCESS);
+ return memcached_success(memcached_flush(memc, expiration));
}
/**
&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++)
{
- const memcached_server_instance_st *instance=
- memcached_server_instance_by_position(&memc, x);
+ memcached_server_instance_st instance=
+ memcached_server_instance_by_position(memc, x);
std::ostringstream strstm;
std::string server_name(memcached_server_name(instance));
server_name.append(":");
char **list= NULL;
char **ptr= NULL;
- list= memcached_stat_get_keys(&memc, &stats[x], &rc);
+ list= memcached_stat_get_keys(memc, &stats[x], &rc);
for (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:
-
- std::string servers_list;
- memcached_st memc;
- memcached_result_st result;
+ memcached_st *memc;
};
}
-
-#endif /* LIBMEMCACHEDPP_H */