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).
45 memcached_create(&memc);
48 Memcache(const std::string &in_servers_list)
50 servers_list(in_servers_list),
54 memcached_create(&memc);
58 Memcache(const std::string &hostname,
65 memcached_create(&memc);
67 servers_list.append(hostname);
68 servers_list.append(":");
69 std::ostringstream strsmt;
71 servers_list.append(strsmt.str());
76 Memcache(memcached_st *clone)
82 memcached_clone(&memc, clone);
85 Memcache(const Memcache &rhs)
87 servers_list(rhs.servers_list),
91 memcached_clone(&memc, const_cast<memcached_st *>(&rhs.getImpl()));
95 Memcache &operator=(const Memcache &rhs)
99 memcached_clone(&memc, const_cast<memcached_st *>(&rhs.getImpl()));
108 memcached_free(&memc);
113 memcached_server_st *servers;
114 servers= memcached_servers_parse(servers_list.c_str());
115 memcached_server_push(&memc, servers);
116 memcached_server_free(servers);
120 * Get the internal memcached_st *
122 memcached_st &getImpl()
128 * Get the internal memcached_st *
130 const memcached_st &getImpl() const
136 * Return an error string for the given return structure.
138 * @param[in] rc a memcached_return_t structure
139 * @return error string corresponding to given return code in the library.
141 const std::string getError(memcached_return_t rc) const
143 /* first parameter to strerror is unused */
144 return memcached_strerror(NULL, rc);
148 bool setBehavior(memcached_behavior_t flag, uint64_t data)
150 memcached_return_t rc;
151 rc= memcached_behavior_set(&memc, flag, data);
152 return (rc == MEMCACHED_SUCCESS);
155 uint64_t getBehavior(memcached_behavior_t flag) {
156 return memcached_behavior_get(&memc, flag);
160 * Return the string which contains the list of memcached servers being
163 * @return a std::string containing the list of memcached servers
165 const std::string getServersList() const
171 * Set the list of memcached servers to use.
173 * @param[in] in_servers_list list of servers
174 * @return true on success; false otherwise
176 bool setServers(const std::string &in_servers_list)
178 servers_list.assign(in_servers_list);
181 return (memcached_server_count(&memc));
185 * Add a server to the list of memcached servers to use.
187 * @param[in] server_name name of the server to add
188 * @param[in] port port number of server to add
189 * @return true on success; false otherwise
191 bool addServer(const std::string &server_name, in_port_t port)
193 memcached_return_t rc;
195 rc= memcached_server_add(&memc, server_name.c_str(), port);
197 return (rc == MEMCACHED_SUCCESS);
201 * Remove a server from the list of memcached servers to use.
203 * @param[in] server_name name of the server to remove
204 * @param[in] port port number of server to remove
205 * @return true on success; false otherwise
207 bool removeServer(const std::string &server_name, in_port_t port)
210 std::ostringstream strstm;
212 tmp_str.append(server_name);
215 tmp_str.append(strstm.str());
217 //memcached_return_t rc= memcached_server_remove(server);
223 * Fetches an individual value from the server. mget() must always
224 * be called before using this method.
226 * @param[in] key key of object to fetch
227 * @param[out] ret_val store returned object in this vector
228 * @return a memcached return structure
230 memcached_return_t fetch(std::string &key,
231 std::vector<char> &ret_val)
233 char ret_key[MEMCACHED_MAX_KEY];
234 size_t value_length= 0;
235 size_t key_length= 0;
236 memcached_return_t rc;
238 char *value= memcached_fetch(&memc, ret_key, &key_length,
239 &value_length, &flags, &rc);
240 if (value && ret_val.empty())
242 ret_val.reserve(value_length);
243 ret_val.assign(value, value + value_length);
256 * Fetches an individual value from the server.
258 * @param[in] key key of object whose value to get
259 * @param[out] ret_val object that is retrieved is stored in
261 * @return true on success; false otherwise
263 bool get(const std::string &key,
264 std::vector<char> &ret_val) throw (Error)
267 memcached_return_t rc;
268 size_t value_length= 0;
272 throw(Error("the key supplied is empty!", false));
274 char *value= memcached_get(&memc, key.c_str(), key.length(),
275 &value_length, &flags, &rc);
276 if (value != NULL && ret_val.empty())
278 ret_val.reserve(value_length);
279 ret_val.assign(value, value + value_length);
287 * Fetches an individual from a server which is specified by
288 * the master_key parameter that is used for determining which
289 * server an object was stored in if key partitioning was
292 * @param[in] master_key key that specifies server object is stored on
293 * @param[in] key key of object whose value to get
294 * @param[out] ret_val object that is retrieved is stored in
296 * @return true on success; false otherwise
298 bool getByKey(const std::string &master_key,
299 const std::string &key,
300 std::vector<char> &ret_val) throw(Error)
303 memcached_return_t rc;
304 size_t value_length= 0;
306 if (master_key.empty() || key.empty())
308 throw(Error("the master key or key supplied is empty!", false));
310 char *value= memcached_get_by_key(&memc,
311 master_key.c_str(), master_key.length(),
312 key.c_str(), key.length(),
313 &value_length, &flags, &rc);
316 ret_val.reserve(value_length);
317 ret_val.assign(value, value + value_length);
325 * Selects multiple keys at once. This method always
326 * works asynchronously.
328 * @param[in] keys vector of keys to select
329 * @return true if all keys are found
331 bool mget(std::vector<std::string> &keys)
333 std::vector<const char *> real_keys;
334 std::vector<size_t> key_len;
336 * Construct an array which will contain the length
337 * of each of the strings in the input vector. Also, to
338 * interface with the memcached C API, we need to convert
339 * the vector of std::string's to a vector of char *.
341 real_keys.reserve(keys.size());
342 key_len.reserve(keys.size());
344 std::vector<std::string>::iterator it= keys.begin();
346 while (it != keys.end())
348 real_keys.push_back(const_cast<char *>((*it).c_str()));
349 key_len.push_back((*it).length());
354 * If the std::vector of keys is empty then we cannot
355 * call memcached_mget as we will get undefined behavior.
357 if (! real_keys.empty())
359 memcached_return_t rc= memcached_mget(&memc, &real_keys[0], &key_len[0],
361 return (rc == MEMCACHED_SUCCESS);
368 * Writes an object to the server. If the object already exists, it will
369 * overwrite the existing object. This method always returns true
370 * when using non-blocking mode unless a network error occurs.
372 * @param[in] key key of object to write to server
373 * @param[in] value value of object to write to server
374 * @param[in] expiration time to keep the object stored in the server for
375 * @param[in] flags flags to store with the object
376 * @return true on succcess; false otherwise
378 bool set(const std::string &key,
379 const std::vector<char> &value,
381 uint32_t flags) throw(Error)
383 if (key.empty() || value.empty())
385 throw(Error("the key or value supplied is empty!", false));
387 memcached_return_t rc= memcached_set(&memc,
388 key.c_str(), key.length(),
389 &value[0], value.size(),
391 return (rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
395 * Writes an object to a server specified by the master_key parameter.
396 * If the object already exists, it will overwrite the existing object.
398 * @param[in] master_key key that specifies server to write to
399 * @param[in] key key of object to write to server
400 * @param[in] value value of object to write to server
401 * @param[in] expiration time to keep the object stored in the server for
402 * @param[in] flags flags to store with the object
403 * @return true on succcess; false otherwise
405 bool setByKey(const std::string &master_key,
406 const std::string &key,
407 const std::vector<char> &value,
409 uint32_t flags) throw(Error)
411 if (master_key.empty() ||
415 throw(Error("the key or value supplied is empty!", false));
417 memcached_return_t rc= memcached_set_by_key(&memc, master_key.c_str(),
419 key.c_str(), key.length(),
420 &value[0], value.size(),
423 return (rc == MEMCACHED_SUCCESS);
427 * Writes a list of objects to the server. Objects are specified by
428 * 2 vectors - 1 vector of keys and 1 vector of values.
430 * @param[in] keys vector of keys of objects to write to server
431 * @param[in] values vector of values of objects to write to server
432 * @param[in] expiration time to keep the objects stored in server for
433 * @param[in] flags flags to store with the objects
434 * @return true on success; false otherwise
436 bool setAll(std::vector<std::string> &keys,
437 std::vector< std::vector<char> *> &values,
439 uint32_t flags) throw(Error)
441 if (keys.size() != values.size())
443 throw(Error("The number of keys and values do not match!", false));
446 std::vector<std::string>::iterator key_it= keys.begin();
447 std::vector< std::vector<char> *>::iterator val_it= values.begin();
448 while (key_it != keys.end())
450 retval= set((*key_it), *(*val_it), expiration, flags);
462 * Writes a list of objects to the server. Objects are specified by
463 * a map of keys to values.
465 * @param[in] key_value_map map of keys and values to store in server
466 * @param[in] expiration time to keep the objects stored in server for
467 * @param[in] flags flags to store with the objects
468 * @return true on success; false otherwise
470 bool setAll(std::map<const std::string, std::vector<char> > &key_value_map,
472 uint32_t flags) throw(Error)
474 if (key_value_map.empty())
476 throw(Error("The key/values are not properly set!", false));
479 std::map<const std::string, std::vector<char> >::iterator it=
480 key_value_map.begin();
481 while (it != key_value_map.end())
483 retval= set(it->first, it->second, expiration, flags);
486 std::string err_buff("There was an error setting the key ");
487 err_buff.append(it->first);
488 throw(Error(err_buff, false));
496 * Increment the value of the object associated with the specified
497 * key by the offset given. The resulting value is saved in the value
500 * @param[in] key key of object in server whose value to increment
501 * @param[in] offset amount to increment object's value by
502 * @param[out] value store the result of the increment here
503 * @return true on success; false otherwise
505 bool increment(const std::string &key, uint32_t offset, uint64_t *value) throw(Error)
509 throw(Error("the key supplied is empty!", false));
511 memcached_return_t rc= memcached_increment(&memc, key.c_str(), key.length(),
513 return (rc == MEMCACHED_SUCCESS);
517 * Decrement the value of the object associated with the specified
518 * key by the offset given. The resulting value is saved in the value
521 * @param[in] key key of object in server whose value to decrement
522 * @param[in] offset amount to increment object's value by
523 * @param[out] value store the result of the decrement here
524 * @return true on success; false otherwise
526 bool decrement(const std::string &key, uint32_t offset, uint64_t *value)
531 throw(Error("the key supplied is empty!", false));
533 memcached_return_t rc= memcached_decrement(&memc, key.c_str(),
536 return (rc == MEMCACHED_SUCCESS);
541 * Add an object with the specified key and value to the server. This
542 * function returns false if the object already exists on the server.
544 * @param[in] key key of object to add
545 * @param[in] value of object to add
546 * @return true on success; false otherwise
548 bool add(const std::string &key, const std::vector<char> &value)
551 if (key.empty() || value.empty())
553 throw(Error("the key or value supplied is empty!", false));
555 memcached_return_t rc= memcached_add(&memc, key.c_str(), key.length(),
556 &value[0], value.size(), 0, 0);
557 return (rc == MEMCACHED_SUCCESS);
561 * Add an object with the specified key and value to the server. This
562 * function returns false if the object already exists on the server. The
563 * server to add the object to is specified by the master_key parameter.
565 * @param[in[ master_key key of server to add object to
566 * @param[in] key key of object to add
567 * @param[in] value of object to add
568 * @return true on success; false otherwise
570 bool addByKey(const std::string &master_key,
571 const std::string &key,
572 const std::vector<char> &value) throw(Error)
574 if (master_key.empty() ||
578 throw(Error("the master key or key supplied is empty!", false));
580 memcached_return_t rc= memcached_add_by_key(&memc,
588 return (rc == MEMCACHED_SUCCESS);
592 * Replaces an object on the server. This method only succeeds
593 * if the object is already present on the server.
595 * @param[in] key key of object to replace
596 * @param[in[ value value to replace object with
597 * @return true on success; false otherwise
599 bool replace(const std::string &key, const std::vector<char> &value) throw(Error)
604 throw(Error("the key or value supplied is empty!", false));
606 memcached_return_t rc= memcached_replace(&memc, key.c_str(), key.length(),
607 &value[0], value.size(),
609 return (rc == MEMCACHED_SUCCESS);
613 * Replaces an object on the server. This method only succeeds
614 * if the object is already present on the server. The server
615 * to replace the object on is specified by the master_key param.
617 * @param[in] master_key key of server to replace object on
618 * @param[in] key key of object to replace
619 * @param[in[ value value to replace object with
620 * @return true on success; false otherwise
622 bool replaceByKey(const std::string &master_key,
623 const std::string &key,
624 const std::vector<char> &value)
626 if (master_key.empty() ||
630 throw(Error("the master key or key supplied is empty!", false));
632 memcached_return_t rc= memcached_replace_by_key(&memc,
640 return (rc == MEMCACHED_SUCCESS);
644 * Places a segment of data before the last piece of data stored.
646 * @param[in] key key of object whose value we will prepend data to
647 * @param[in] value data to prepend to object's value
648 * @return true on success; false otherwise
650 bool prepend(const std::string &key, const std::vector<char> &value)
653 if (key.empty() || value.empty())
655 throw(Error("the key or value supplied is empty!", false));
657 memcached_return_t rc= memcached_prepend(&memc, key.c_str(), key.length(),
658 &value[0], value.size(), 0, 0);
659 return (rc == MEMCACHED_SUCCESS);
663 * Places a segment of data before the last piece of data stored. The
664 * server on which the object where we will be prepending data is stored
665 * on is specified by the master_key parameter.
667 * @param[in] master_key key of server where object is stored
668 * @param[in] key key of object whose value we will prepend data to
669 * @param[in] value data to prepend to object's value
670 * @return true on success; false otherwise
672 bool prependByKey(const std::string &master_key,
673 const std::string &key,
674 const std::vector<char> &value)
677 if (master_key.empty() ||
681 throw(Error("the master key or key supplied is empty!", false));
683 memcached_return_t rc= memcached_prepend_by_key(&memc,
692 return (rc == MEMCACHED_SUCCESS);
696 * Places a segment of data at the end of the last piece of data stored.
698 * @param[in] key key of object whose value we will append data to
699 * @param[in] value data to append to object's value
700 * @return true on success; false otherwise
702 bool append(const std::string &key, const std::vector<char> &value)
705 if (key.empty() || value.empty())
707 throw(Error("the key or value supplied is empty!", false));
709 memcached_return_t rc= memcached_append(&memc,
715 return (rc == MEMCACHED_SUCCESS);
719 * Places a segment of data at the end of the last piece of data stored. The
720 * server on which the object where we will be appending data is stored
721 * on is specified by the master_key parameter.
723 * @param[in] master_key key of server where object is stored
724 * @param[in] key key of object whose value we will append data to
725 * @param[in] value data to append to object's value
726 * @return true on success; false otherwise
728 bool appendByKey(const std::string &master_key,
729 const std::string &key,
730 const std::vector<char> &value)
733 if (master_key.empty() ||
737 throw(Error("the master key or key supplied is empty!", false));
739 memcached_return_t rc= memcached_append_by_key(&memc,
747 return (rc == MEMCACHED_SUCCESS);
751 * Overwrite data in the server as long as the cas_arg value
752 * is still the same in the server.
754 * @param[in] key key of object in server
755 * @param[in] value value to store for object in server
756 * @param[in] cas_arg "cas" value
758 bool cas(const std::string &key,
759 const std::vector<char> &value,
760 uint64_t cas_arg) throw(Error)
762 if (key.empty() || value.empty())
764 throw(Error("the key or value supplied is empty!", false));
766 memcached_return_t rc= memcached_cas(&memc, key.c_str(), key.length(),
767 &value[0], value.size(),
769 return (rc == MEMCACHED_SUCCESS);
773 * Overwrite data in the server as long as the cas_arg value
774 * is still the same in the server. The server to use is
775 * specified by the master_key parameter.
777 * @param[in] master_key specifies server to operate on
778 * @param[in] key key of object in server
779 * @param[in] value value to store for object in server
780 * @param[in] cas_arg "cas" value
782 bool casByKey(const std::string &master_key,
783 const std::string &key,
784 const std::vector<char> &value,
785 uint64_t cas_arg) throw(Error)
787 if (master_key.empty() ||
791 throw(Error("the master key, key or value supplied is empty!", false));
793 memcached_return_t rc= memcached_cas_by_key(&memc,
801 return (rc == MEMCACHED_SUCCESS);
805 * Delete an object from the server specified by the key given.
807 * @param[in] key key of object to delete
808 * @return true on success; false otherwise
810 bool remove(const std::string &key) throw(Error)
814 throw(Error("the key supplied is empty!", false));
816 memcached_return_t rc= memcached_delete(&memc, key.c_str(), key.length(), 0);
817 return (rc == MEMCACHED_SUCCESS);
821 * Delete an object from the server specified by the key given.
823 * @param[in] key key of object to delete
824 * @param[in] expiration time to delete the object after
825 * @return true on success; false otherwise
827 bool remove(const std::string &key,
828 time_t expiration) throw(Error)
832 throw(Error("the key supplied is empty!", false));
834 memcached_return_t rc= memcached_delete(&memc,
838 return (rc == MEMCACHED_SUCCESS);
842 * Delete an object from the server specified by the key given.
844 * @param[in] master_key specifies server to remove object from
845 * @param[in] key key of object to delete
846 * @return true on success; false otherwise
848 bool removeByKey(const std::string &master_key,
849 const std::string &key) throw(Error)
851 if (master_key.empty() || key.empty())
853 throw(Error("the master key or key supplied is empty!", false));
855 memcached_return_t rc= memcached_delete_by_key(&memc,
861 return (rc == MEMCACHED_SUCCESS);
865 * Delete an object from the server specified by the key given.
867 * @param[in] master_key specifies server to remove object from
868 * @param[in] key key of object to delete
869 * @param[in] expiration time to delete the object after
870 * @return true on success; false otherwise
872 bool removeByKey(const std::string &master_key,
873 const std::string &key,
874 time_t expiration) throw(Error)
876 if (master_key.empty() || key.empty())
878 throw(Error("the master key or key supplied is empty!", false));
880 memcached_return_t rc= memcached_delete_by_key(&memc,
886 return (rc == MEMCACHED_SUCCESS);
890 * Wipe the contents of memcached servers.
892 * @param[in] expiration time to wait until wiping contents of
894 * @return true on success; false otherwise
896 bool flush(time_t expiration)
898 memcached_return_t rc= memcached_flush(&memc, expiration);
899 return (rc == MEMCACHED_SUCCESS);
903 * Callback function for result sets. It passes the result
904 * sets to the list of functions provided.
906 * @param[in] callback list of callback functions
907 * @param[in] context pointer to memory reference that is
908 * supplied to the calling function
909 * @param[in] num_of_callbacks number of callback functions
910 * @return true on success; false otherwise
912 bool fetchExecute(memcached_execute_fn *callback,
914 uint32_t num_of_callbacks)
916 memcached_return_t rc= memcached_fetch_execute(&memc,
920 return (rc == MEMCACHED_SUCCESS);
924 * Get the library version string.
925 * @return std::string containing a copy of the library version string.
927 const std::string libVersion() const
929 const char *ver= memcached_lib_version();
930 const std::string version(ver);
935 * Retrieve memcached statistics. Populate a std::map with the retrieved
936 * stats. Each server will map to another std::map of the key:value stats.
938 * @param[out] stats_map a std::map to be populated with the memcached
940 * @return true on success; false otherwise
942 bool getStats(std::map< std::string, std::map<std::string, std::string> >
945 memcached_return_t rc;
946 memcached_stat_st *stats= memcached_stat(&memc, NULL, &rc);
948 if (rc != MEMCACHED_SUCCESS &&
949 rc != MEMCACHED_SOME_ERRORS)
954 uint32_t server_count= memcached_server_count(&memc);
957 * For each memcached server, construct a std::map for its stats and add
958 * it to the std::map of overall stats.
960 for (uint32_t x= 0; x < server_count; x++)
962 memcached_server_instance_st instance=
963 memcached_server_instance_by_position(&memc, x);
964 std::ostringstream strstm;
965 std::string server_name(memcached_server_name(instance));
966 server_name.append(":");
967 strstm << memcached_server_port(instance);
968 server_name.append(strstm.str());
970 std::map<std::string, std::string> server_stats;
974 list= memcached_stat_get_keys(&memc, &stats[x], &rc);
975 for (ptr= list; *ptr; ptr++)
977 char *value= memcached_stat_get_value(&memc, &stats[x], *ptr, &rc);
978 server_stats[*ptr]= value;
982 stats_map[server_name]= server_stats;
986 memcached_stat_free(&memc, stats);
992 std::string servers_list;
994 memcached_result_st result;
999 #endif /* LIBMEMCACHEDPP_H */