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 structure
138 * @return error string corresponding to given return code in the library.
140 const std::string getError(memcached_return rc) const
142 /* first parameter to strerror is unused */
143 return memcached_strerror(NULL, rc);
147 * Return the string which contains the list of memcached servers being
150 * @return a std::string containing the list of memcached servers
152 const std::string getServersList() const
158 * Set the list of memcached servers to use.
160 * @param[in] in_servers_list list of servers
161 * @return true on success; false otherwise
163 bool setServers(const std::string &in_servers_list)
165 servers_list.assign(in_servers_list);
166 servers= memcached_servers_parse(in_servers_list.c_str());
167 memcached_server_push(&memc, servers);
168 return (servers == NULL);
172 * Add a server to the list of memcached servers to use.
174 * @param[in] server_name name of the server to add
175 * @param[in] port port number of server to add
176 * @return true on success; false otherwise
178 bool addServer(const std::string &server_name, unsigned int port)
181 std::ostringstream strstm;
182 servers_list.append(",");
183 servers_list.append(server_name);
184 servers_list.append(":");
186 servers_list.append(strstm.str());
187 servers= memcached_server_list_append(servers,
191 memcached_server_push(&memc, servers);
192 return (rc == MEMCACHED_SUCCESS);
196 * Remove a server from the list of memcached servers to use.
198 * @param[in] server_name name of the server to remove
199 * @param[in] port port number of server to remove
200 * @return true on success; false otherwise
202 bool removeServer(const std::string &server_name, size_t port)
205 std::ostringstream strstm;
207 tmp_str.append(server_name);
210 tmp_str.append(strstm.str());
211 memcached_server_st *server= memcached_servers_parse(tmp_str.c_str());
212 memcached_return rc= memcached_server_remove(server);
213 return (rc == MEMCACHED_SUCCESS);
217 * Fetches an individual value from the server. mget() must always
218 * be called before using this method.
220 * @param[in] key key of object to fetch
221 * @param[out] ret_val store returned object in this vector
222 * @return a memcached return structure
224 memcached_return fetch(std::string &key,
225 std::vector<char> &ret_val)
227 char ret_key[MEMCACHED_MAX_KEY];
228 size_t value_length= 0;
229 size_t key_length= 0;
232 char *value= memcached_fetch(&memc, ret_key, &key_length,
233 &value_length, &flags, &rc);
234 if (value && ret_val.empty())
236 ret_val.reserve(value_length);
237 ret_val.assign(value, value + value_length);
250 * Fetches an individual value from the server.
252 * @param[in] key key of object whose value to get
253 * @param[out] ret_val object that is retrieved is stored in
255 * @return true on success; false otherwise
257 bool get(const std::string &key,
258 std::vector<char> &ret_val) throw (Error)
262 size_t value_length= 0;
266 throw(Error("the key supplied is empty!", false));
268 char *value= memcached_get(&memc, key.c_str(), key.length(),
269 &value_length, &flags, &rc);
270 if (value != NULL && ret_val.empty())
272 ret_val.reserve(value_length);
273 ret_val.assign(value, value + value_length);
281 * Fetches an individual from a server which is specified by
282 * the master_key parameter that is used for determining which
283 * server an object was stored in if key partitioning was
286 * @param[in] master_key key that specifies server object is stored on
287 * @param[in] key key of object whose value to get
288 * @param[out] ret_val object that is retrieved is stored in
290 * @return true on success; false otherwise
292 bool getByKey(const std::string &master_key,
293 const std::string &key,
294 std::vector<char> &ret_val) throw(Error)
298 size_t value_length= 0;
300 if (master_key.empty() || key.empty())
302 throw(Error("the master key or key supplied is empty!", false));
304 char *value= memcached_get_by_key(&memc,
305 master_key.c_str(), master_key.length(),
306 key.c_str(), key.length(),
307 &value_length, &flags, &rc);
310 ret_val.reserve(value_length);
311 ret_val.assign(value, value + value_length);
319 * Selects multiple keys at once. This method always
320 * works asynchronously.
322 * @param[in] keys vector of keys to select
323 * @return true if all keys are found
325 bool mget(std::vector<std::string> &keys)
327 std::vector<const char *> real_keys;
328 std::vector<size_t> key_len;
330 * Construct an array which will contain the length
331 * of each of the strings in the input vector. Also, to
332 * interface with the memcached C API, we need to convert
333 * the vector of std::string's to a vector of char *.
335 real_keys.reserve(keys.size());
336 key_len.reserve(keys.size());
338 std::vector<std::string>::iterator it= keys.begin();
340 while (it != keys.end())
342 real_keys.push_back(const_cast<char *>((*it).c_str()));
343 key_len.push_back((*it).length());
348 * If the std::vector of keys is empty then we cannot
349 * call memcached_mget as we will get undefined behavior.
351 if (! real_keys.empty())
353 memcached_return rc= memcached_mget(&memc, &real_keys[0], &key_len[0],
355 return (rc == MEMCACHED_SUCCESS);
362 * Writes an object to the server. If the object already exists, it will
363 * overwrite the existing object. This method always returns true
364 * when using non-blocking mode unless a network error occurs.
366 * @param[in] key key of object to write to server
367 * @param[in] value value of object to write to server
368 * @param[in] expiration time to keep the object stored in the server for
369 * @param[in] flags flags to store with the object
370 * @return true on succcess; false otherwise
372 bool set(const std::string &key,
373 const std::vector<char> &value,
375 uint32_t flags) throw(Error)
377 if (key.empty() || value.empty())
379 throw(Error("the key or value supplied is empty!", false));
381 memcached_return rc= memcached_set(&memc,
382 key.c_str(), key.length(),
383 &value[0], value.size(),
385 return (rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
389 * Writes an object to a server specified by the master_key parameter.
390 * If the object already exists, it will overwrite the existing object.
392 * @param[in] master_key key that specifies server to write to
393 * @param[in] key key of object to write to server
394 * @param[in] value value of object to write to server
395 * @param[in] expiration time to keep the object stored in the server for
396 * @param[in] flags flags to store with the object
397 * @return true on succcess; false otherwise
399 bool setByKey(const std::string &master_key,
400 const std::string &key,
401 const std::vector<char> &value,
403 uint32_t flags) throw(Error)
405 if (master_key.empty() ||
409 throw(Error("the key or value supplied is empty!", false));
411 memcached_return rc= memcached_set_by_key(&memc, master_key.c_str(),
413 key.c_str(), key.length(),
414 &value[0], value.size(),
417 return (rc == MEMCACHED_SUCCESS);
421 * Writes a list of objects to the server. Objects are specified by
422 * 2 vectors - 1 vector of keys and 1 vector of values.
424 * @param[in] keys vector of keys of objects to write to server
425 * @param[in] values vector of values of objects to write to server
426 * @param[in] expiration time to keep the objects stored in server for
427 * @param[in] flags flags to store with the objects
428 * @return true on success; false otherwise
430 bool setAll(std::vector<std::string> &keys,
431 std::vector< std::vector<char> *> &values,
433 uint32_t flags) throw(Error)
435 if (keys.size() != values.size())
437 throw(Error("The number of keys and values do not match!", false));
440 std::vector<std::string>::iterator key_it= keys.begin();
441 std::vector< std::vector<char> *>::iterator val_it= values.begin();
442 while (key_it != keys.end())
444 retval= set((*key_it), *(*val_it), expiration, flags);
456 * Writes a list of objects to the server. Objects are specified by
457 * a map of keys to values.
459 * @param[in] key_value_map map of keys and values to store in server
460 * @param[in] expiration time to keep the objects stored in server for
461 * @param[in] flags flags to store with the objects
462 * @return true on success; false otherwise
464 bool setAll(std::map<const std::string, std::vector<char> > &key_value_map,
466 uint32_t flags) throw(Error)
468 if (key_value_map.empty())
470 throw(Error("The key/values are not properly set!", false));
473 std::map<const std::string, std::vector<char> >::iterator it=
474 key_value_map.begin();
475 while (it != key_value_map.end())
477 retval= set(it->first, it->second, expiration, flags);
480 std::string err_buff("There was an error setting the key ");
481 err_buff.append(it->first);
482 throw(Error(err_buff, false));
490 * Increment the value of the object associated with the specified
491 * key by the offset given. The resulting value is saved in the value
494 * @param[in] key key of object in server whose value to increment
495 * @param[in] offset amount to increment object's value by
496 * @param[out] value store the result of the increment here
497 * @return true on success; false otherwise
499 bool increment(const std::string &key, uint32_t offset, uint64_t *value) throw(Error)
503 throw(Error("the key supplied is empty!", false));
505 memcached_return rc= memcached_increment(&memc, key.c_str(), key.length(),
507 return (rc == MEMCACHED_SUCCESS);
511 * Decrement the value of the object associated with the specified
512 * key by the offset given. The resulting value is saved in the value
515 * @param[in] key key of object in server whose value to decrement
516 * @param[in] offset amount to increment object's value by
517 * @param[out] value store the result of the decrement here
518 * @return true on success; false otherwise
520 bool decrement(const std::string &key, uint32_t offset, uint64_t *value)
525 throw(Error("the key supplied is empty!", false));
527 memcached_return rc= memcached_decrement(&memc, key.c_str(),
530 return (rc == MEMCACHED_SUCCESS);
535 * Add an object with the specified key and value to the server. This
536 * function returns false if the object already exists on the server.
538 * @param[in] key key of object to add
539 * @param[in] value of object to add
540 * @return true on success; false otherwise
542 bool add(const std::string &key, const std::vector<char> &value)
545 if (key.empty() || value.empty())
547 throw(Error("the key or value supplied is empty!", false));
549 memcached_return rc= memcached_add(&memc, key.c_str(), key.length(),
550 &value[0], value.size(), 0, 0);
551 return (rc == MEMCACHED_SUCCESS);
555 * Add an object with the specified key and value to the server. This
556 * function returns false if the object already exists on the server. The
557 * server to add the object to is specified by the master_key parameter.
559 * @param[in[ master_key key of server to add object to
560 * @param[in] key key of object to add
561 * @param[in] value of object to add
562 * @return true on success; false otherwise
564 bool addByKey(const std::string &master_key,
565 const std::string &key,
566 const std::vector<char> &value) throw(Error)
568 if (master_key.empty() ||
572 throw(Error("the master key or key supplied is empty!", false));
574 memcached_return rc= memcached_add_by_key(&memc,
582 return (rc == MEMCACHED_SUCCESS);
586 * Replaces an object on the server. This method only succeeds
587 * if the object is already present on the server.
589 * @param[in] key key of object to replace
590 * @param[in[ value value to replace object with
591 * @return true on success; false otherwise
593 bool replace(const std::string &key, const std::vector<char> &value) throw(Error)
598 throw(Error("the key or value supplied is empty!", false));
600 memcached_return rc= memcached_replace(&memc, key.c_str(), key.length(),
601 &value[0], value.size(),
603 return (rc == MEMCACHED_SUCCESS);
607 * Replaces an object on the server. This method only succeeds
608 * if the object is already present on the server. The server
609 * to replace the object on is specified by the master_key param.
611 * @param[in] master_key key of server to replace object on
612 * @param[in] key key of object to replace
613 * @param[in[ value value to replace object with
614 * @return true on success; false otherwise
616 bool replaceByKey(const std::string &master_key,
617 const std::string &key,
618 const std::vector<char> &value)
620 if (master_key.empty() ||
624 throw(Error("the master key or key supplied is empty!", false));
626 memcached_return rc= memcached_replace_by_key(&memc,
634 return (rc == MEMCACHED_SUCCESS);
638 * Places a segment of data before the last piece of data stored.
640 * @param[in] key key of object whose value we will prepend data to
641 * @param[in] value data to prepend to object's value
642 * @return true on success; false otherwise
644 bool prepend(const std::string &key, const std::vector<char> &value)
647 if (key.empty() || value.empty())
649 throw(Error("the key or value supplied is empty!", false));
651 memcached_return rc= memcached_prepend(&memc, key.c_str(), key.length(),
652 &value[0], value.size(), 0, 0);
653 return (rc == MEMCACHED_SUCCESS);
657 * Places a segment of data before the last piece of data stored. The
658 * server on which the object where we will be prepending data is stored
659 * on is specified by the master_key parameter.
661 * @param[in] master_key key of server where object is stored
662 * @param[in] key key of object whose value we will prepend data to
663 * @param[in] value data to prepend to object's value
664 * @return true on success; false otherwise
666 bool prependByKey(const std::string &master_key,
667 const std::string &key,
668 const std::vector<char> &value)
671 if (master_key.empty() ||
675 throw(Error("the master key or key supplied is empty!", false));
677 memcached_return rc= memcached_prepend_by_key(&memc,
686 return (rc == MEMCACHED_SUCCESS);
690 * Places a segment of data at the end of the last piece of data stored.
692 * @param[in] key key of object whose value we will append data to
693 * @param[in] value data to append to object's value
694 * @return true on success; false otherwise
696 bool append(const std::string &key, const std::vector<char> &value)
699 if (key.empty() || value.empty())
701 throw(Error("the key or value supplied is empty!", false));
703 memcached_return rc= memcached_append(&memc,
709 return (rc == MEMCACHED_SUCCESS);
713 * Places a segment of data at the end of the last piece of data stored. The
714 * server on which the object where we will be appending data is stored
715 * on is specified by the master_key parameter.
717 * @param[in] master_key key of server where object is stored
718 * @param[in] key key of object whose value we will append data to
719 * @param[in] value data to append to object's value
720 * @return true on success; false otherwise
722 bool appendByKey(const std::string &master_key,
723 const std::string &key,
724 const std::vector<char> &value)
727 if (master_key.empty() ||
731 throw(Error("the master key or key supplied is empty!", false));
733 memcached_return rc= memcached_append_by_key(&memc,
741 return (rc == MEMCACHED_SUCCESS);
745 * Overwrite data in the server as long as the cas_arg value
746 * is still the same in the server.
748 * @param[in] key key of object in server
749 * @param[in] value value to store for object in server
750 * @param[in] cas_arg "cas" value
752 bool cas(const std::string &key,
753 const std::vector<char> &value,
754 uint64_t cas_arg) throw(Error)
756 if (key.empty() || value.empty())
758 throw(Error("the key or value supplied is empty!", false));
760 memcached_return rc= memcached_cas(&memc, key.c_str(), key.length(),
761 &value[0], value.size(),
763 return (rc == MEMCACHED_SUCCESS);
767 * Overwrite data in the server as long as the cas_arg value
768 * is still the same in the server. The server to use is
769 * specified by the master_key parameter.
771 * @param[in] master_key specifies server to operate on
772 * @param[in] key key of object in server
773 * @param[in] value value to store for object in server
774 * @param[in] cas_arg "cas" value
776 bool casByKey(const std::string &master_key,
777 const std::string &key,
778 const std::vector<char> &value,
779 uint64_t cas_arg) throw(Error)
781 if (master_key.empty() ||
785 throw(Error("the master key, key or value supplied is empty!", false));
787 memcached_return rc= memcached_cas_by_key(&memc,
795 return (rc == MEMCACHED_SUCCESS);
799 * Delete an object from the server specified by the key given.
801 * @param[in] key key of object to delete
802 * @return true on success; false otherwise
804 bool remove(const std::string &key) throw(Error)
808 throw(Error("the key supplied is empty!", false));
810 memcached_return rc= memcached_delete(&memc, key.c_str(), key.length(), 0);
811 return (rc == MEMCACHED_SUCCESS);
815 * Delete an object from the server specified by the key given.
817 * @param[in] key key of object to delete
818 * @param[in] expiration time to delete the object after
819 * @return true on success; false otherwise
821 bool remove(const std::string &key,
822 time_t expiration) throw(Error)
826 throw(Error("the key supplied is empty!", false));
828 memcached_return rc= memcached_delete(&memc,
832 return (rc == MEMCACHED_SUCCESS);
836 * Delete an object from the server specified by the key given.
838 * @param[in] master_key specifies server to remove object from
839 * @param[in] key key of object to delete
840 * @return true on success; false otherwise
842 bool removeByKey(const std::string &master_key,
843 const std::string &key) throw(Error)
845 if (master_key.empty() || key.empty())
847 throw(Error("the master key or key supplied is empty!", false));
849 memcached_return rc= memcached_delete_by_key(&memc,
855 return (rc == MEMCACHED_SUCCESS);
859 * Delete an object from the server specified by the key given.
861 * @param[in] master_key specifies server to remove object from
862 * @param[in] key key of object to delete
863 * @param[in] expiration time to delete the object after
864 * @return true on success; false otherwise
866 bool removeByKey(const std::string &master_key,
867 const std::string &key,
868 time_t expiration) throw(Error)
870 if (master_key.empty() || key.empty())
872 throw(Error("the master key or key supplied is empty!", false));
874 memcached_return rc= memcached_delete_by_key(&memc,
880 return (rc == MEMCACHED_SUCCESS);
884 * Wipe the contents of memcached servers.
886 * @param[in] expiration time to wait until wiping contents of
888 * @return true on success; false otherwise
890 bool flush(time_t expiration)
892 memcached_return rc= memcached_flush(&memc, expiration);
893 return (rc == MEMCACHED_SUCCESS);
897 * Callback function for result sets. It passes the result
898 * sets to the list of functions provided.
900 * @param[in] callback list of callback functions
901 * @param[in] context pointer to memory reference that is
902 * supplied to the calling function
903 * @param[in] num_of_callbacks number of callback functions
904 * @return true on success; false otherwise
906 bool fetchExecute(memcached_execute_function *callback,
908 unsigned int num_of_callbacks)
910 memcached_return rc= memcached_fetch_execute(&memc,
914 return (rc == MEMCACHED_SUCCESS);
918 * Get the library version string.
919 * @return std::string containing a copy of the library version string.
921 const std::string libVersion() const
923 const char *ver= memcached_lib_version();
924 const std::string version(ver);
929 * Retrieve memcached statistics. Populate a std::map with the retrieved
930 * stats. Each server will map to another std::map of the key:value stats.
932 * @param[out] stats_map a std::map to be populated with the memcached
934 * @return true on success; false otherwise
936 bool getStats(std::map< std::string, std::map<std::string, std::string> >
940 memcached_stat_st *stats= memcached_stat(&memc, NULL, &rc);
942 if (rc != MEMCACHED_SUCCESS &&
943 rc != MEMCACHED_SOME_ERRORS)
948 uint32_t server_count= memcached_server_count(&memc);
951 * For each memcached server, construct a std::map for its stats and add
952 * it to the std::map of overall stats.
954 for (uint32_t x= 0; x < server_count; x++)
956 std::ostringstream strstm;
957 std::string server_name(memcached_server_name(&memc, servers[x]));
958 server_name.append(":");
959 strstm << memcached_server_port(&memc, servers[x]);
960 server_name.append(strstm.str());
962 std::map<std::string, std::string> server_stats;
966 list= memcached_stat_get_keys(&memc, &stats[x], &rc);
967 for (ptr= list; *ptr; ptr++)
969 char *value= memcached_stat_get_value(&memc, &stats[x], *ptr, &rc);
970 server_stats[*ptr]= value;
974 stats_map[server_name]= server_stats;
978 memcached_stat_free(&memc, stats);
984 std::string servers_list;
986 memcached_server_st *servers;
987 memcached_result_st result;
992 #endif /* LIBMEMCACHEDPP_H */