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 bool setBehavior(memcached_behavior flag, uint64_t data) {
149 rc= memcached_behavior_set(&memc, flag, data);
150 return (rc == MEMCACHED_SUCCESS);
153 uint64_t getBehavior(memcached_behavior flag) {
154 return memcached_behavior_get(&memc, flag);
158 * Return the string which contains the list of memcached servers being
161 * @return a std::string containing the list of memcached servers
163 const std::string getServersList() const
169 * Set the list of memcached servers to use.
171 * @param[in] in_servers_list list of servers
172 * @return true on success; false otherwise
174 bool setServers(const std::string &in_servers_list)
176 servers_list.assign(in_servers_list);
177 servers= memcached_servers_parse(in_servers_list.c_str());
178 memcached_server_push(&memc, servers);
179 return (servers == NULL);
183 * Add a server to the list of memcached servers to use.
185 * @param[in] server_name name of the server to add
186 * @param[in] port port number of server to add
187 * @return true on success; false otherwise
189 bool addServer(const std::string &server_name, unsigned int port)
192 std::ostringstream strstm;
193 servers_list.append(",");
194 servers_list.append(server_name);
195 servers_list.append(":");
197 servers_list.append(strstm.str());
198 servers= memcached_server_list_append(servers,
202 memcached_server_push(&memc, servers);
203 return (rc == MEMCACHED_SUCCESS);
207 * Remove a server from the list of memcached servers to use.
209 * @param[in] server_name name of the server to remove
210 * @param[in] port port number of server to remove
211 * @return true on success; false otherwise
213 bool removeServer(const std::string &server_name, size_t port)
216 std::ostringstream strstm;
218 tmp_str.append(server_name);
221 tmp_str.append(strstm.str());
222 memcached_server_st *server= memcached_servers_parse(tmp_str.c_str());
223 memcached_return rc= memcached_server_remove(server);
224 return (rc == MEMCACHED_SUCCESS);
228 * Fetches an individual value from the server. mget() must always
229 * be called before using this method.
231 * @param[in] key key of object to fetch
232 * @param[out] ret_val store returned object in this vector
233 * @return a memcached return structure
235 memcached_return fetch(std::string &key,
236 std::vector<char> &ret_val)
238 char ret_key[MEMCACHED_MAX_KEY];
239 size_t value_length= 0;
240 size_t key_length= 0;
243 char *value= memcached_fetch(&memc, ret_key, &key_length,
244 &value_length, &flags, &rc);
245 if (value && ret_val.empty())
247 ret_val.reserve(value_length);
248 ret_val.assign(value, value + value_length);
261 * Fetches an individual value from the server.
263 * @param[in] key key of object whose value to get
264 * @param[out] ret_val object that is retrieved is stored in
266 * @return true on success; false otherwise
268 bool get(const std::string &key,
269 std::vector<char> &ret_val) throw (Error)
273 size_t value_length= 0;
277 throw(Error("the key supplied is empty!", false));
279 char *value= memcached_get(&memc, key.c_str(), key.length(),
280 &value_length, &flags, &rc);
281 if (value != NULL && ret_val.empty())
283 ret_val.reserve(value_length);
284 ret_val.assign(value, value + value_length);
292 * Fetches an individual from a server which is specified by
293 * the master_key parameter that is used for determining which
294 * server an object was stored in if key partitioning was
297 * @param[in] master_key key that specifies server object is stored on
298 * @param[in] key key of object whose value to get
299 * @param[out] ret_val object that is retrieved is stored in
301 * @return true on success; false otherwise
303 bool getByKey(const std::string &master_key,
304 const std::string &key,
305 std::vector<char> &ret_val) throw(Error)
309 size_t value_length= 0;
311 if (master_key.empty() || key.empty())
313 throw(Error("the master key or key supplied is empty!", false));
315 char *value= memcached_get_by_key(&memc,
316 master_key.c_str(), master_key.length(),
317 key.c_str(), key.length(),
318 &value_length, &flags, &rc);
321 ret_val.reserve(value_length);
322 ret_val.assign(value, value + value_length);
330 * Selects multiple keys at once. This method always
331 * works asynchronously.
333 * @param[in] keys vector of keys to select
334 * @return true if all keys are found
336 bool mget(std::vector<std::string> &keys)
338 std::vector<const char *> real_keys;
339 std::vector<size_t> key_len;
341 * Construct an array which will contain the length
342 * of each of the strings in the input vector. Also, to
343 * interface with the memcached C API, we need to convert
344 * the vector of std::string's to a vector of char *.
346 real_keys.reserve(keys.size());
347 key_len.reserve(keys.size());
349 std::vector<std::string>::iterator it= keys.begin();
351 while (it != keys.end())
353 real_keys.push_back(const_cast<char *>((*it).c_str()));
354 key_len.push_back((*it).length());
359 * If the std::vector of keys is empty then we cannot
360 * call memcached_mget as we will get undefined behavior.
362 if (! real_keys.empty())
364 memcached_return rc= memcached_mget(&memc, &real_keys[0], &key_len[0],
366 return (rc == MEMCACHED_SUCCESS);
373 * Writes an object to the server. If the object already exists, it will
374 * overwrite the existing object. This method always returns true
375 * when using non-blocking mode unless a network error occurs.
377 * @param[in] key key of object to write to server
378 * @param[in] value value of object to write to server
379 * @param[in] expiration time to keep the object stored in the server for
380 * @param[in] flags flags to store with the object
381 * @return true on succcess; false otherwise
383 bool set(const std::string &key,
384 const std::vector<char> &value,
386 uint32_t flags) throw(Error)
388 if (key.empty() || value.empty())
390 throw(Error("the key or value supplied is empty!", false));
392 memcached_return rc= memcached_set(&memc,
393 key.c_str(), key.length(),
394 &value[0], value.size(),
396 return (rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
400 * Writes an object to a server specified by the master_key parameter.
401 * If the object already exists, it will overwrite the existing object.
403 * @param[in] master_key key that specifies server to write to
404 * @param[in] key key of object to write to server
405 * @param[in] value value of object to write to server
406 * @param[in] expiration time to keep the object stored in the server for
407 * @param[in] flags flags to store with the object
408 * @return true on succcess; false otherwise
410 bool setByKey(const std::string &master_key,
411 const std::string &key,
412 const std::vector<char> &value,
414 uint32_t flags) throw(Error)
416 if (master_key.empty() ||
420 throw(Error("the key or value supplied is empty!", false));
422 memcached_return rc= memcached_set_by_key(&memc, master_key.c_str(),
424 key.c_str(), key.length(),
425 &value[0], value.size(),
428 return (rc == MEMCACHED_SUCCESS);
432 * Writes a list of objects to the server. Objects are specified by
433 * 2 vectors - 1 vector of keys and 1 vector of values.
435 * @param[in] keys vector of keys of objects to write to server
436 * @param[in] values vector of values of objects to write to server
437 * @param[in] expiration time to keep the objects stored in server for
438 * @param[in] flags flags to store with the objects
439 * @return true on success; false otherwise
441 bool setAll(std::vector<std::string> &keys,
442 std::vector< std::vector<char> *> &values,
444 uint32_t flags) throw(Error)
446 if (keys.size() != values.size())
448 throw(Error("The number of keys and values do not match!", false));
451 std::vector<std::string>::iterator key_it= keys.begin();
452 std::vector< std::vector<char> *>::iterator val_it= values.begin();
453 while (key_it != keys.end())
455 retval= set((*key_it), *(*val_it), expiration, flags);
467 * Writes a list of objects to the server. Objects are specified by
468 * a map of keys to values.
470 * @param[in] key_value_map map of keys and values to store in server
471 * @param[in] expiration time to keep the objects stored in server for
472 * @param[in] flags flags to store with the objects
473 * @return true on success; false otherwise
475 bool setAll(std::map<const std::string, std::vector<char> > &key_value_map,
477 uint32_t flags) throw(Error)
479 if (key_value_map.empty())
481 throw(Error("The key/values are not properly set!", false));
484 std::map<const std::string, std::vector<char> >::iterator it=
485 key_value_map.begin();
486 while (it != key_value_map.end())
488 retval= set(it->first, it->second, expiration, flags);
491 std::string err_buff("There was an error setting the key ");
492 err_buff.append(it->first);
493 throw(Error(err_buff, false));
501 * Increment the value of the object associated with the specified
502 * key by the offset given. The resulting value is saved in the value
505 * @param[in] key key of object in server whose value to increment
506 * @param[in] offset amount to increment object's value by
507 * @param[out] value store the result of the increment here
508 * @return true on success; false otherwise
510 bool increment(const std::string &key, uint32_t offset, uint64_t *value) throw(Error)
514 throw(Error("the key supplied is empty!", false));
516 memcached_return rc= memcached_increment(&memc, key.c_str(), key.length(),
518 return (rc == MEMCACHED_SUCCESS);
522 * Decrement the value of the object associated with the specified
523 * key by the offset given. The resulting value is saved in the value
526 * @param[in] key key of object in server whose value to decrement
527 * @param[in] offset amount to increment object's value by
528 * @param[out] value store the result of the decrement here
529 * @return true on success; false otherwise
531 bool decrement(const std::string &key, uint32_t offset, uint64_t *value)
536 throw(Error("the key supplied is empty!", false));
538 memcached_return rc= memcached_decrement(&memc, key.c_str(),
541 return (rc == MEMCACHED_SUCCESS);
546 * Add an object with the specified key and value to the server. This
547 * function returns false if the object already exists on the server.
549 * @param[in] key key of object to add
550 * @param[in] value of object to add
551 * @return true on success; false otherwise
553 bool add(const std::string &key, const std::vector<char> &value)
556 if (key.empty() || value.empty())
558 throw(Error("the key or value supplied is empty!", false));
560 memcached_return rc= memcached_add(&memc, key.c_str(), key.length(),
561 &value[0], value.size(), 0, 0);
562 return (rc == MEMCACHED_SUCCESS);
566 * Add an object with the specified key and value to the server. This
567 * function returns false if the object already exists on the server. The
568 * server to add the object to is specified by the master_key parameter.
570 * @param[in[ master_key key of server to add object to
571 * @param[in] key key of object to add
572 * @param[in] value of object to add
573 * @return true on success; false otherwise
575 bool addByKey(const std::string &master_key,
576 const std::string &key,
577 const std::vector<char> &value) throw(Error)
579 if (master_key.empty() ||
583 throw(Error("the master key or key supplied is empty!", false));
585 memcached_return rc= memcached_add_by_key(&memc,
593 return (rc == MEMCACHED_SUCCESS);
597 * Replaces an object on the server. This method only succeeds
598 * if the object is already present on the server.
600 * @param[in] key key of object to replace
601 * @param[in[ value value to replace object with
602 * @return true on success; false otherwise
604 bool replace(const std::string &key, const std::vector<char> &value) throw(Error)
609 throw(Error("the key or value supplied is empty!", false));
611 memcached_return rc= memcached_replace(&memc, key.c_str(), key.length(),
612 &value[0], value.size(),
614 return (rc == MEMCACHED_SUCCESS);
618 * Replaces an object on the server. This method only succeeds
619 * if the object is already present on the server. The server
620 * to replace the object on is specified by the master_key param.
622 * @param[in] master_key key of server to replace object on
623 * @param[in] key key of object to replace
624 * @param[in[ value value to replace object with
625 * @return true on success; false otherwise
627 bool replaceByKey(const std::string &master_key,
628 const std::string &key,
629 const std::vector<char> &value)
631 if (master_key.empty() ||
635 throw(Error("the master key or key supplied is empty!", false));
637 memcached_return rc= memcached_replace_by_key(&memc,
645 return (rc == MEMCACHED_SUCCESS);
649 * Places a segment of data before the last piece of data stored.
651 * @param[in] key key of object whose value we will prepend data to
652 * @param[in] value data to prepend to object's value
653 * @return true on success; false otherwise
655 bool prepend(const std::string &key, const std::vector<char> &value)
658 if (key.empty() || value.empty())
660 throw(Error("the key or value supplied is empty!", false));
662 memcached_return rc= memcached_prepend(&memc, key.c_str(), key.length(),
663 &value[0], value.size(), 0, 0);
664 return (rc == MEMCACHED_SUCCESS);
668 * Places a segment of data before the last piece of data stored. The
669 * server on which the object where we will be prepending data is stored
670 * on is specified by the master_key parameter.
672 * @param[in] master_key key of server where object is stored
673 * @param[in] key key of object whose value we will prepend data to
674 * @param[in] value data to prepend to object's value
675 * @return true on success; false otherwise
677 bool prependByKey(const std::string &master_key,
678 const std::string &key,
679 const std::vector<char> &value)
682 if (master_key.empty() ||
686 throw(Error("the master key or key supplied is empty!", false));
688 memcached_return rc= memcached_prepend_by_key(&memc,
697 return (rc == MEMCACHED_SUCCESS);
701 * Places a segment of data at the end of the last piece of data stored.
703 * @param[in] key key of object whose value we will append data to
704 * @param[in] value data to append to object's value
705 * @return true on success; false otherwise
707 bool append(const std::string &key, const std::vector<char> &value)
710 if (key.empty() || value.empty())
712 throw(Error("the key or value supplied is empty!", false));
714 memcached_return rc= memcached_append(&memc,
720 return (rc == MEMCACHED_SUCCESS);
724 * Places a segment of data at the end of the last piece of data stored. The
725 * server on which the object where we will be appending data is stored
726 * on is specified by the master_key parameter.
728 * @param[in] master_key key of server where object is stored
729 * @param[in] key key of object whose value we will append data to
730 * @param[in] value data to append to object's value
731 * @return true on success; false otherwise
733 bool appendByKey(const std::string &master_key,
734 const std::string &key,
735 const std::vector<char> &value)
738 if (master_key.empty() ||
742 throw(Error("the master key or key supplied is empty!", false));
744 memcached_return rc= memcached_append_by_key(&memc,
752 return (rc == MEMCACHED_SUCCESS);
756 * Overwrite data in the server as long as the cas_arg value
757 * is still the same in the server.
759 * @param[in] key key of object in server
760 * @param[in] value value to store for object in server
761 * @param[in] cas_arg "cas" value
763 bool cas(const std::string &key,
764 const std::vector<char> &value,
765 uint64_t cas_arg) throw(Error)
767 if (key.empty() || value.empty())
769 throw(Error("the key or value supplied is empty!", false));
771 memcached_return rc= memcached_cas(&memc, key.c_str(), key.length(),
772 &value[0], value.size(),
774 return (rc == MEMCACHED_SUCCESS);
778 * Overwrite data in the server as long as the cas_arg value
779 * is still the same in the server. The server to use is
780 * specified by the master_key parameter.
782 * @param[in] master_key specifies server to operate on
783 * @param[in] key key of object in server
784 * @param[in] value value to store for object in server
785 * @param[in] cas_arg "cas" value
787 bool casByKey(const std::string &master_key,
788 const std::string &key,
789 const std::vector<char> &value,
790 uint64_t cas_arg) throw(Error)
792 if (master_key.empty() ||
796 throw(Error("the master key, key or value supplied is empty!", false));
798 memcached_return rc= memcached_cas_by_key(&memc,
806 return (rc == MEMCACHED_SUCCESS);
810 * Delete an object from the server specified by the key given.
812 * @param[in] key key of object to delete
813 * @return true on success; false otherwise
815 bool remove(const std::string &key) throw(Error)
819 throw(Error("the key supplied is empty!", false));
821 memcached_return rc= memcached_delete(&memc, key.c_str(), key.length(), 0);
822 return (rc == MEMCACHED_SUCCESS);
826 * Delete an object from the server specified by the key given.
828 * @param[in] key key of object to delete
829 * @param[in] expiration time to delete the object after
830 * @return true on success; false otherwise
832 bool remove(const std::string &key,
833 time_t expiration) throw(Error)
837 throw(Error("the key supplied is empty!", false));
839 memcached_return rc= memcached_delete(&memc,
843 return (rc == MEMCACHED_SUCCESS);
847 * Delete an object from the server specified by the key given.
849 * @param[in] master_key specifies server to remove object from
850 * @param[in] key key of object to delete
851 * @return true on success; false otherwise
853 bool removeByKey(const std::string &master_key,
854 const std::string &key) throw(Error)
856 if (master_key.empty() || key.empty())
858 throw(Error("the master key or key supplied is empty!", false));
860 memcached_return rc= memcached_delete_by_key(&memc,
866 return (rc == MEMCACHED_SUCCESS);
870 * Delete an object from the server specified by the key given.
872 * @param[in] master_key specifies server to remove object from
873 * @param[in] key key of object to delete
874 * @param[in] expiration time to delete the object after
875 * @return true on success; false otherwise
877 bool removeByKey(const std::string &master_key,
878 const std::string &key,
879 time_t expiration) throw(Error)
881 if (master_key.empty() || key.empty())
883 throw(Error("the master key or key supplied is empty!", false));
885 memcached_return rc= memcached_delete_by_key(&memc,
891 return (rc == MEMCACHED_SUCCESS);
895 * Wipe the contents of memcached servers.
897 * @param[in] expiration time to wait until wiping contents of
899 * @return true on success; false otherwise
901 bool flush(time_t expiration)
903 memcached_return rc= memcached_flush(&memc, expiration);
904 return (rc == MEMCACHED_SUCCESS);
908 * Callback function for result sets. It passes the result
909 * sets to the list of functions provided.
911 * @param[in] callback list of callback functions
912 * @param[in] context pointer to memory reference that is
913 * supplied to the calling function
914 * @param[in] num_of_callbacks number of callback functions
915 * @return true on success; false otherwise
917 bool fetchExecute(memcached_execute_function *callback,
919 unsigned int num_of_callbacks)
921 memcached_return rc= memcached_fetch_execute(&memc,
925 return (rc == MEMCACHED_SUCCESS);
929 * Get the library version string.
930 * @return std::string containing a copy of the library version string.
932 const std::string libVersion() const
934 const char *ver= memcached_lib_version();
935 const std::string version(ver);
940 * Retrieve memcached statistics. Populate a std::map with the retrieved
941 * stats. Each server will map to another std::map of the key:value stats.
943 * @param[out] stats_map a std::map to be populated with the memcached
945 * @return true on success; false otherwise
947 bool getStats(std::map< std::string, std::map<std::string, std::string> >
951 memcached_stat_st *stats= memcached_stat(&memc, NULL, &rc);
953 if (rc != MEMCACHED_SUCCESS &&
954 rc != MEMCACHED_SOME_ERRORS)
959 uint32_t server_count= memcached_server_count(&memc);
962 * For each memcached server, construct a std::map for its stats and add
963 * it to the std::map of overall stats.
965 for (uint32_t x= 0; x < server_count; x++)
967 std::ostringstream strstm;
968 std::string server_name(memcached_server_name(&memc, servers[x]));
969 server_name.append(":");
970 strstm << memcached_server_port(&memc, servers[x]);
971 server_name.append(strstm.str());
973 std::map<std::string, std::string> server_stats;
977 list= memcached_stat_get_keys(&memc, &stats[x], &rc);
978 for (ptr= list; *ptr; ptr++)
980 char *value= memcached_stat_get_value(&memc, &stats[x], *ptr, &rc);
981 server_stats[*ptr]= value;
985 stats_map[server_name]= server_stats;
989 memcached_stat_free(&memc, stats);
995 std::string servers_list;
997 memcached_server_st *servers;
998 memcached_result_st result;
1003 #endif /* LIBMEMCACHEDPP_H */