2 * Summary: C++ interface for memcached server
4 * Copy: See Copyright for the status of this software.
6 * Authors: Padraig O'Sullivan <osullivan.padraig@gmail.com>
7 * Patrick Galbraith <patg@patg.net>
12 * @brief Libmemcached C++ interface
15 #ifndef LIBMEMCACHEDPP_H
16 #define LIBMEMCACHEDPP_H
18 #include <libmemcached/memcached.h>
19 #include <libmemcached/exception.hpp>
32 * This is the core memcached library (if later, other objects
33 * are needed, they will be created from this class).
46 memcached_create(&memc);
49 Memcache(const std::string &in_servers_list)
51 servers_list(in_servers_list),
56 memcached_create(&memc);
57 servers= memcached_servers_parse(servers_list.c_str());
58 memcached_server_push(&memc, servers);
61 Memcache(const std::string &hostname,
69 memcached_create(&memc);
70 servers_list.append(hostname);
71 servers_list.append(":");
72 std::ostringstream strsmt;
74 servers_list.append(strsmt.str());
75 servers= memcached_servers_parse(servers_list.c_str());
76 memcached_server_push(&memc, servers);
79 Memcache(memcached_st *clone)
86 memcached_clone(&memc, clone);
89 Memcache(const Memcache &rhs)
91 servers_list(rhs.servers_list),
96 memcached_clone(&memc, const_cast<memcached_st *>(&rhs.getImpl()));
97 servers= memcached_servers_parse(servers_list.c_str());
98 memcached_server_push(&memc, servers);
101 Memcache &operator=(const Memcache &rhs)
105 memcached_clone(&memc, const_cast<memcached_st *>(&rhs.getImpl()));
106 servers= memcached_servers_parse(servers_list.c_str());
107 memcached_server_push(&memc, servers);
114 memcached_free(&memc);
115 memcached_server_list_free(servers);
119 * Get the internal memcached_st *
121 memcached_st &getImpl()
127 * Get the internal memcached_st *
129 const memcached_st &getImpl() const
135 * Return an error string for the given return structure.
137 * @param[in] rc a memcached_return_t structure
138 * @return error string corresponding to given return code in the library.
140 const std::string getError(memcached_return_t rc) const
142 /* first parameter to strerror is unused */
143 return memcached_strerror(NULL, rc);
147 bool setBehavior(memcached_behavior_t flag, uint64_t data)
149 memcached_return_t rc;
150 rc= memcached_behavior_set(&memc, flag, data);
151 return (rc == MEMCACHED_SUCCESS);
154 uint64_t getBehavior(memcached_behavior_t flag) {
155 return memcached_behavior_get(&memc, flag);
159 * Return the string which contains the list of memcached servers being
162 * @return a std::string containing the list of memcached servers
164 const std::string getServersList() const
170 * Set the list of memcached servers to use.
172 * @param[in] in_servers_list list of servers
173 * @return true on success; false otherwise
175 bool setServers(const std::string &in_servers_list)
177 servers_list.assign(in_servers_list);
178 servers= memcached_servers_parse(in_servers_list.c_str());
179 memcached_server_push(&memc, servers);
180 return (servers == NULL);
184 * Add a server to the list of memcached servers to use.
186 * @param[in] server_name name of the server to add
187 * @param[in] port port number of server to add
188 * @return true on success; false otherwise
190 bool addServer(const std::string &server_name, in_port_t port)
192 memcached_return_t rc;
193 std::ostringstream strstm;
194 servers_list.append(",");
195 servers_list.append(server_name);
196 servers_list.append(":");
198 servers_list.append(strstm.str());
199 servers= memcached_server_list_append(servers,
203 memcached_server_push(&memc, servers);
204 return (rc == MEMCACHED_SUCCESS);
208 * Remove a server from the list of memcached servers to use.
210 * @param[in] server_name name of the server to remove
211 * @param[in] port port number of server to remove
212 * @return true on success; false otherwise
214 bool removeServer(const std::string &server_name, in_port_t port)
217 std::ostringstream strstm;
219 tmp_str.append(server_name);
222 tmp_str.append(strstm.str());
223 memcached_server_st *server= memcached_servers_parse(tmp_str.c_str());
224 memcached_return_t rc= memcached_server_remove(server);
225 return (rc == MEMCACHED_SUCCESS);
229 * Fetches an individual value from the server. mget() must always
230 * be called before using this method.
232 * @param[in] key key of object to fetch
233 * @param[out] ret_val store returned object in this vector
234 * @return a memcached return structure
236 memcached_return_t fetch(std::string &key,
237 std::vector<char> &ret_val)
239 char ret_key[MEMCACHED_MAX_KEY];
240 size_t value_length= 0;
241 size_t key_length= 0;
242 memcached_return_t rc;
244 char *value= memcached_fetch(&memc, ret_key, &key_length,
245 &value_length, &flags, &rc);
246 if (value && ret_val.empty())
248 ret_val.reserve(value_length);
249 ret_val.assign(value, value + value_length);
262 * Fetches an individual value from the server.
264 * @param[in] key key of object whose value to get
265 * @param[out] ret_val object that is retrieved is stored in
267 * @return true on success; false otherwise
269 bool get(const std::string &key,
270 std::vector<char> &ret_val) throw (Error)
273 memcached_return_t rc;
274 size_t value_length= 0;
278 throw(Error("the key supplied is empty!", false));
280 char *value= memcached_get(&memc, key.c_str(), key.length(),
281 &value_length, &flags, &rc);
282 if (value != NULL && ret_val.empty())
284 ret_val.reserve(value_length);
285 ret_val.assign(value, value + value_length);
293 * Fetches an individual from a server which is specified by
294 * the master_key parameter that is used for determining which
295 * server an object was stored in if key partitioning was
298 * @param[in] master_key key that specifies server object is stored on
299 * @param[in] key key of object whose value to get
300 * @param[out] ret_val object that is retrieved is stored in
302 * @return true on success; false otherwise
304 bool getByKey(const std::string &master_key,
305 const std::string &key,
306 std::vector<char> &ret_val) throw(Error)
309 memcached_return_t rc;
310 size_t value_length= 0;
312 if (master_key.empty() || key.empty())
314 throw(Error("the master key or key supplied is empty!", false));
316 char *value= memcached_get_by_key(&memc,
317 master_key.c_str(), master_key.length(),
318 key.c_str(), key.length(),
319 &value_length, &flags, &rc);
322 ret_val.reserve(value_length);
323 ret_val.assign(value, value + value_length);
331 * Selects multiple keys at once. This method always
332 * works asynchronously.
334 * @param[in] keys vector of keys to select
335 * @return true if all keys are found
337 bool mget(std::vector<std::string> &keys)
339 std::vector<const char *> real_keys;
340 std::vector<size_t> key_len;
342 * Construct an array which will contain the length
343 * of each of the strings in the input vector. Also, to
344 * interface with the memcached C API, we need to convert
345 * the vector of std::string's to a vector of char *.
347 real_keys.reserve(keys.size());
348 key_len.reserve(keys.size());
350 std::vector<std::string>::iterator it= keys.begin();
352 while (it != keys.end())
354 real_keys.push_back(const_cast<char *>((*it).c_str()));
355 key_len.push_back((*it).length());
360 * If the std::vector of keys is empty then we cannot
361 * call memcached_mget as we will get undefined behavior.
363 if (! real_keys.empty())
365 memcached_return_t rc= memcached_mget(&memc, &real_keys[0], &key_len[0],
367 return (rc == MEMCACHED_SUCCESS);
374 * Writes an object to the server. If the object already exists, it will
375 * overwrite the existing object. This method always returns true
376 * when using non-blocking mode unless a network error occurs.
378 * @param[in] key key of object to write to server
379 * @param[in] value value of object to write to server
380 * @param[in] expiration time to keep the object stored in the server for
381 * @param[in] flags flags to store with the object
382 * @return true on succcess; false otherwise
384 bool set(const std::string &key,
385 const std::vector<char> &value,
387 uint32_t flags) throw(Error)
389 if (key.empty() || value.empty())
391 throw(Error("the key or value supplied is empty!", false));
393 memcached_return_t rc= memcached_set(&memc,
394 key.c_str(), key.length(),
395 &value[0], value.size(),
397 return (rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
401 * Writes an object to a server specified by the master_key parameter.
402 * If the object already exists, it will overwrite the existing object.
404 * @param[in] master_key key that specifies server to write to
405 * @param[in] key key of object to write to server
406 * @param[in] value value of object to write to server
407 * @param[in] expiration time to keep the object stored in the server for
408 * @param[in] flags flags to store with the object
409 * @return true on succcess; false otherwise
411 bool setByKey(const std::string &master_key,
412 const std::string &key,
413 const std::vector<char> &value,
415 uint32_t flags) throw(Error)
417 if (master_key.empty() ||
421 throw(Error("the key or value supplied is empty!", false));
423 memcached_return_t rc= memcached_set_by_key(&memc, master_key.c_str(),
425 key.c_str(), key.length(),
426 &value[0], value.size(),
429 return (rc == MEMCACHED_SUCCESS);
433 * Writes a list of objects to the server. Objects are specified by
434 * 2 vectors - 1 vector of keys and 1 vector of values.
436 * @param[in] keys vector of keys of objects to write to server
437 * @param[in] values vector of values of objects to write to server
438 * @param[in] expiration time to keep the objects stored in server for
439 * @param[in] flags flags to store with the objects
440 * @return true on success; false otherwise
442 bool setAll(std::vector<std::string> &keys,
443 std::vector< std::vector<char> *> &values,
445 uint32_t flags) throw(Error)
447 if (keys.size() != values.size())
449 throw(Error("The number of keys and values do not match!", false));
452 std::vector<std::string>::iterator key_it= keys.begin();
453 std::vector< std::vector<char> *>::iterator val_it= values.begin();
454 while (key_it != keys.end())
456 retval= set((*key_it), *(*val_it), expiration, flags);
468 * Writes a list of objects to the server. Objects are specified by
469 * a map of keys to values.
471 * @param[in] key_value_map map of keys and values to store in server
472 * @param[in] expiration time to keep the objects stored in server for
473 * @param[in] flags flags to store with the objects
474 * @return true on success; false otherwise
476 bool setAll(std::map<const std::string, std::vector<char> > &key_value_map,
478 uint32_t flags) throw(Error)
480 if (key_value_map.empty())
482 throw(Error("The key/values are not properly set!", false));
485 std::map<const std::string, std::vector<char> >::iterator it=
486 key_value_map.begin();
487 while (it != key_value_map.end())
489 retval= set(it->first, it->second, expiration, flags);
492 std::string err_buff("There was an error setting the key ");
493 err_buff.append(it->first);
494 throw(Error(err_buff, false));
502 * Increment the value of the object associated with the specified
503 * key by the offset given. The resulting value is saved in the value
506 * @param[in] key key of object in server whose value to increment
507 * @param[in] offset amount to increment object's value by
508 * @param[out] value store the result of the increment here
509 * @return true on success; false otherwise
511 bool increment(const std::string &key, uint32_t offset, uint64_t *value) throw(Error)
515 throw(Error("the key supplied is empty!", false));
517 memcached_return_t rc= memcached_increment(&memc, key.c_str(), key.length(),
519 return (rc == MEMCACHED_SUCCESS);
523 * Decrement the value of the object associated with the specified
524 * key by the offset given. The resulting value is saved in the value
527 * @param[in] key key of object in server whose value to decrement
528 * @param[in] offset amount to increment object's value by
529 * @param[out] value store the result of the decrement here
530 * @return true on success; false otherwise
532 bool decrement(const std::string &key, uint32_t offset, uint64_t *value)
537 throw(Error("the key supplied is empty!", false));
539 memcached_return_t rc= memcached_decrement(&memc, key.c_str(),
542 return (rc == MEMCACHED_SUCCESS);
547 * Add an object with the specified key and value to the server. This
548 * function returns false if the object already exists on the server.
550 * @param[in] key key of object to add
551 * @param[in] value of object to add
552 * @return true on success; false otherwise
554 bool add(const std::string &key, const std::vector<char> &value)
557 if (key.empty() || value.empty())
559 throw(Error("the key or value supplied is empty!", false));
561 memcached_return_t rc= memcached_add(&memc, key.c_str(), key.length(),
562 &value[0], value.size(), 0, 0);
563 return (rc == MEMCACHED_SUCCESS);
567 * Add an object with the specified key and value to the server. This
568 * function returns false if the object already exists on the server. The
569 * server to add the object to is specified by the master_key parameter.
571 * @param[in[ master_key key of server to add object to
572 * @param[in] key key of object to add
573 * @param[in] value of object to add
574 * @return true on success; false otherwise
576 bool addByKey(const std::string &master_key,
577 const std::string &key,
578 const std::vector<char> &value) throw(Error)
580 if (master_key.empty() ||
584 throw(Error("the master key or key supplied is empty!", false));
586 memcached_return_t rc= memcached_add_by_key(&memc,
594 return (rc == MEMCACHED_SUCCESS);
598 * Replaces an object on the server. This method only succeeds
599 * if the object is already present on the server.
601 * @param[in] key key of object to replace
602 * @param[in[ value value to replace object with
603 * @return true on success; false otherwise
605 bool replace(const std::string &key, const std::vector<char> &value) throw(Error)
610 throw(Error("the key or value supplied is empty!", false));
612 memcached_return_t rc= memcached_replace(&memc, key.c_str(), key.length(),
613 &value[0], value.size(),
615 return (rc == MEMCACHED_SUCCESS);
619 * Replaces an object on the server. This method only succeeds
620 * if the object is already present on the server. The server
621 * to replace the object on is specified by the master_key param.
623 * @param[in] master_key key of server to replace object on
624 * @param[in] key key of object to replace
625 * @param[in[ value value to replace object with
626 * @return true on success; false otherwise
628 bool replaceByKey(const std::string &master_key,
629 const std::string &key,
630 const std::vector<char> &value)
632 if (master_key.empty() ||
636 throw(Error("the master key or key supplied is empty!", false));
638 memcached_return_t rc= memcached_replace_by_key(&memc,
646 return (rc == MEMCACHED_SUCCESS);
650 * Places a segment of data before the last piece of data stored.
652 * @param[in] key key of object whose value we will prepend data to
653 * @param[in] value data to prepend to object's value
654 * @return true on success; false otherwise
656 bool prepend(const std::string &key, const std::vector<char> &value)
659 if (key.empty() || value.empty())
661 throw(Error("the key or value supplied is empty!", false));
663 memcached_return_t rc= memcached_prepend(&memc, key.c_str(), key.length(),
664 &value[0], value.size(), 0, 0);
665 return (rc == MEMCACHED_SUCCESS);
669 * Places a segment of data before the last piece of data stored. The
670 * server on which the object where we will be prepending data is stored
671 * on is specified by the master_key parameter.
673 * @param[in] master_key key of server where object is stored
674 * @param[in] key key of object whose value we will prepend data to
675 * @param[in] value data to prepend to object's value
676 * @return true on success; false otherwise
678 bool prependByKey(const std::string &master_key,
679 const std::string &key,
680 const std::vector<char> &value)
683 if (master_key.empty() ||
687 throw(Error("the master key or key supplied is empty!", false));
689 memcached_return_t rc= memcached_prepend_by_key(&memc,
698 return (rc == MEMCACHED_SUCCESS);
702 * Places a segment of data at the end of the last piece of data stored.
704 * @param[in] key key of object whose value we will append data to
705 * @param[in] value data to append to object's value
706 * @return true on success; false otherwise
708 bool append(const std::string &key, const std::vector<char> &value)
711 if (key.empty() || value.empty())
713 throw(Error("the key or value supplied is empty!", false));
715 memcached_return_t rc= memcached_append(&memc,
721 return (rc == MEMCACHED_SUCCESS);
725 * Places a segment of data at the end of the last piece of data stored. The
726 * server on which the object where we will be appending data is stored
727 * on is specified by the master_key parameter.
729 * @param[in] master_key key of server where object is stored
730 * @param[in] key key of object whose value we will append data to
731 * @param[in] value data to append to object's value
732 * @return true on success; false otherwise
734 bool appendByKey(const std::string &master_key,
735 const std::string &key,
736 const std::vector<char> &value)
739 if (master_key.empty() ||
743 throw(Error("the master key or key supplied is empty!", false));
745 memcached_return_t rc= memcached_append_by_key(&memc,
753 return (rc == MEMCACHED_SUCCESS);
757 * Overwrite data in the server as long as the cas_arg value
758 * is still the same in the server.
760 * @param[in] key key of object in server
761 * @param[in] value value to store for object in server
762 * @param[in] cas_arg "cas" value
764 bool cas(const std::string &key,
765 const std::vector<char> &value,
766 uint64_t cas_arg) throw(Error)
768 if (key.empty() || value.empty())
770 throw(Error("the key or value supplied is empty!", false));
772 memcached_return_t rc= memcached_cas(&memc, key.c_str(), key.length(),
773 &value[0], value.size(),
775 return (rc == MEMCACHED_SUCCESS);
779 * Overwrite data in the server as long as the cas_arg value
780 * is still the same in the server. The server to use is
781 * specified by the master_key parameter.
783 * @param[in] master_key specifies server to operate on
784 * @param[in] key key of object in server
785 * @param[in] value value to store for object in server
786 * @param[in] cas_arg "cas" value
788 bool casByKey(const std::string &master_key,
789 const std::string &key,
790 const std::vector<char> &value,
791 uint64_t cas_arg) throw(Error)
793 if (master_key.empty() ||
797 throw(Error("the master key, key or value supplied is empty!", false));
799 memcached_return_t rc= memcached_cas_by_key(&memc,
807 return (rc == MEMCACHED_SUCCESS);
811 * Delete an object from the server specified by the key given.
813 * @param[in] key key of object to delete
814 * @return true on success; false otherwise
816 bool remove(const std::string &key) throw(Error)
820 throw(Error("the key supplied is empty!", false));
822 memcached_return_t rc= memcached_delete(&memc, key.c_str(), key.length(), 0);
823 return (rc == MEMCACHED_SUCCESS);
827 * Delete an object from the server specified by the key given.
829 * @param[in] key key of object to delete
830 * @param[in] expiration time to delete the object after
831 * @return true on success; false otherwise
833 bool remove(const std::string &key,
834 time_t expiration) throw(Error)
838 throw(Error("the key supplied is empty!", false));
840 memcached_return_t rc= memcached_delete(&memc,
844 return (rc == MEMCACHED_SUCCESS);
848 * Delete an object from the server specified by the key given.
850 * @param[in] master_key specifies server to remove object from
851 * @param[in] key key of object to delete
852 * @return true on success; false otherwise
854 bool removeByKey(const std::string &master_key,
855 const std::string &key) throw(Error)
857 if (master_key.empty() || key.empty())
859 throw(Error("the master key or key supplied is empty!", false));
861 memcached_return_t rc= memcached_delete_by_key(&memc,
867 return (rc == MEMCACHED_SUCCESS);
871 * Delete an object from the server specified by the key given.
873 * @param[in] master_key specifies server to remove object from
874 * @param[in] key key of object to delete
875 * @param[in] expiration time to delete the object after
876 * @return true on success; false otherwise
878 bool removeByKey(const std::string &master_key,
879 const std::string &key,
880 time_t expiration) throw(Error)
882 if (master_key.empty() || key.empty())
884 throw(Error("the master key or key supplied is empty!", false));
886 memcached_return_t rc= memcached_delete_by_key(&memc,
892 return (rc == MEMCACHED_SUCCESS);
896 * Wipe the contents of memcached servers.
898 * @param[in] expiration time to wait until wiping contents of
900 * @return true on success; false otherwise
902 bool flush(time_t expiration)
904 memcached_return_t rc= memcached_flush(&memc, expiration);
905 return (rc == MEMCACHED_SUCCESS);
909 * Callback function for result sets. It passes the result
910 * sets to the list of functions provided.
912 * @param[in] callback list of callback functions
913 * @param[in] context pointer to memory reference that is
914 * supplied to the calling function
915 * @param[in] num_of_callbacks number of callback functions
916 * @return true on success; false otherwise
918 bool fetchExecute(memcached_execute_fn *callback,
920 uint32_t num_of_callbacks)
922 memcached_return_t rc= memcached_fetch_execute(&memc,
926 return (rc == MEMCACHED_SUCCESS);
930 * Get the library version string.
931 * @return std::string containing a copy of the library version string.
933 const std::string libVersion() const
935 const char *ver= memcached_lib_version();
936 const std::string version(ver);
941 * Retrieve memcached statistics. Populate a std::map with the retrieved
942 * stats. Each server will map to another std::map of the key:value stats.
944 * @param[out] stats_map a std::map to be populated with the memcached
946 * @return true on success; false otherwise
948 bool getStats(std::map< std::string, std::map<std::string, std::string> >
951 memcached_return_t rc;
952 memcached_stat_st *stats= memcached_stat(&memc, NULL, &rc);
954 if (rc != MEMCACHED_SUCCESS &&
955 rc != MEMCACHED_SOME_ERRORS)
960 uint32_t server_count= memcached_server_count(&memc);
963 * For each memcached server, construct a std::map for its stats and add
964 * it to the std::map of overall stats.
966 for (uint32_t x= 0; x < server_count; x++)
968 std::ostringstream strstm;
969 std::string server_name(memcached_server_name(&memc, servers[x]));
970 server_name.append(":");
971 strstm << memcached_server_port(&memc, servers[x]);
972 server_name.append(strstm.str());
974 std::map<std::string, std::string> server_stats;
978 list= memcached_stat_get_keys(&memc, &stats[x], &rc);
979 for (ptr= list; *ptr; ptr++)
981 char *value= memcached_stat_get_value(&memc, &stats[x], *ptr, &rc);
982 server_stats[*ptr]= value;
986 stats_map[server_name]= server_stats;
990 memcached_stat_free(&memc, stats);
996 std::string servers_list;
998 memcached_server_st *servers;
999 memcached_result_st result;
1004 #endif /* LIBMEMCACHEDPP_H */