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());
225 memcached_return_t rc= memcached_server_remove(server);
227 return (rc == MEMCACHED_SUCCESS);
231 * Fetches an individual value from the server. mget() must always
232 * be called before using this method.
234 * @param[in] key key of object to fetch
235 * @param[out] ret_val store returned object in this vector
236 * @return a memcached return structure
238 memcached_return_t fetch(std::string &key,
239 std::vector<char> &ret_val)
241 char ret_key[MEMCACHED_MAX_KEY];
242 size_t value_length= 0;
243 size_t key_length= 0;
244 memcached_return_t rc;
246 char *value= memcached_fetch(&memc, ret_key, &key_length,
247 &value_length, &flags, &rc);
248 if (value && ret_val.empty())
250 ret_val.reserve(value_length);
251 ret_val.assign(value, value + value_length);
264 * Fetches an individual value from the server.
266 * @param[in] key key of object whose value to get
267 * @param[out] ret_val object that is retrieved is stored in
269 * @return true on success; false otherwise
271 bool get(const std::string &key,
272 std::vector<char> &ret_val) throw (Error)
275 memcached_return_t rc;
276 size_t value_length= 0;
280 throw(Error("the key supplied is empty!", false));
282 char *value= memcached_get(&memc, key.c_str(), key.length(),
283 &value_length, &flags, &rc);
284 if (value != NULL && ret_val.empty())
286 ret_val.reserve(value_length);
287 ret_val.assign(value, value + value_length);
295 * Fetches an individual from a server which is specified by
296 * the master_key parameter that is used for determining which
297 * server an object was stored in if key partitioning was
300 * @param[in] master_key key that specifies server object is stored on
301 * @param[in] key key of object whose value to get
302 * @param[out] ret_val object that is retrieved is stored in
304 * @return true on success; false otherwise
306 bool getByKey(const std::string &master_key,
307 const std::string &key,
308 std::vector<char> &ret_val) throw(Error)
311 memcached_return_t rc;
312 size_t value_length= 0;
314 if (master_key.empty() || key.empty())
316 throw(Error("the master key or key supplied is empty!", false));
318 char *value= memcached_get_by_key(&memc,
319 master_key.c_str(), master_key.length(),
320 key.c_str(), key.length(),
321 &value_length, &flags, &rc);
324 ret_val.reserve(value_length);
325 ret_val.assign(value, value + value_length);
333 * Selects multiple keys at once. This method always
334 * works asynchronously.
336 * @param[in] keys vector of keys to select
337 * @return true if all keys are found
339 bool mget(std::vector<std::string> &keys)
341 std::vector<const char *> real_keys;
342 std::vector<size_t> key_len;
344 * Construct an array which will contain the length
345 * of each of the strings in the input vector. Also, to
346 * interface with the memcached C API, we need to convert
347 * the vector of std::string's to a vector of char *.
349 real_keys.reserve(keys.size());
350 key_len.reserve(keys.size());
352 std::vector<std::string>::iterator it= keys.begin();
354 while (it != keys.end())
356 real_keys.push_back(const_cast<char *>((*it).c_str()));
357 key_len.push_back((*it).length());
362 * If the std::vector of keys is empty then we cannot
363 * call memcached_mget as we will get undefined behavior.
365 if (! real_keys.empty())
367 memcached_return_t rc= memcached_mget(&memc, &real_keys[0], &key_len[0],
369 return (rc == MEMCACHED_SUCCESS);
376 * Writes an object to the server. If the object already exists, it will
377 * overwrite the existing object. This method always returns true
378 * when using non-blocking mode unless a network error occurs.
380 * @param[in] key key of object to write to server
381 * @param[in] value value of object to write to server
382 * @param[in] expiration time to keep the object stored in the server for
383 * @param[in] flags flags to store with the object
384 * @return true on succcess; false otherwise
386 bool set(const std::string &key,
387 const std::vector<char> &value,
389 uint32_t flags) throw(Error)
391 if (key.empty() || value.empty())
393 throw(Error("the key or value supplied is empty!", false));
395 memcached_return_t rc= memcached_set(&memc,
396 key.c_str(), key.length(),
397 &value[0], value.size(),
399 return (rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
403 * Writes an object to a server specified by the master_key parameter.
404 * If the object already exists, it will overwrite the existing object.
406 * @param[in] master_key key that specifies server to write to
407 * @param[in] key key of object to write to server
408 * @param[in] value value of object to write to server
409 * @param[in] expiration time to keep the object stored in the server for
410 * @param[in] flags flags to store with the object
411 * @return true on succcess; false otherwise
413 bool setByKey(const std::string &master_key,
414 const std::string &key,
415 const std::vector<char> &value,
417 uint32_t flags) throw(Error)
419 if (master_key.empty() ||
423 throw(Error("the key or value supplied is empty!", false));
425 memcached_return_t rc= memcached_set_by_key(&memc, master_key.c_str(),
427 key.c_str(), key.length(),
428 &value[0], value.size(),
431 return (rc == MEMCACHED_SUCCESS);
435 * Writes a list of objects to the server. Objects are specified by
436 * 2 vectors - 1 vector of keys and 1 vector of values.
438 * @param[in] keys vector of keys of objects to write to server
439 * @param[in] values vector of values of objects to write to server
440 * @param[in] expiration time to keep the objects stored in server for
441 * @param[in] flags flags to store with the objects
442 * @return true on success; false otherwise
444 bool setAll(std::vector<std::string> &keys,
445 std::vector< std::vector<char> *> &values,
447 uint32_t flags) throw(Error)
449 if (keys.size() != values.size())
451 throw(Error("The number of keys and values do not match!", false));
454 std::vector<std::string>::iterator key_it= keys.begin();
455 std::vector< std::vector<char> *>::iterator val_it= values.begin();
456 while (key_it != keys.end())
458 retval= set((*key_it), *(*val_it), expiration, flags);
470 * Writes a list of objects to the server. Objects are specified by
471 * a map of keys to values.
473 * @param[in] key_value_map map of keys and values to store in server
474 * @param[in] expiration time to keep the objects stored in server for
475 * @param[in] flags flags to store with the objects
476 * @return true on success; false otherwise
478 bool setAll(std::map<const std::string, std::vector<char> > &key_value_map,
480 uint32_t flags) throw(Error)
482 if (key_value_map.empty())
484 throw(Error("The key/values are not properly set!", false));
487 std::map<const std::string, std::vector<char> >::iterator it=
488 key_value_map.begin();
489 while (it != key_value_map.end())
491 retval= set(it->first, it->second, expiration, flags);
494 std::string err_buff("There was an error setting the key ");
495 err_buff.append(it->first);
496 throw(Error(err_buff, false));
504 * Increment the value of the object associated with the specified
505 * key by the offset given. The resulting value is saved in the value
508 * @param[in] key key of object in server whose value to increment
509 * @param[in] offset amount to increment object's value by
510 * @param[out] value store the result of the increment here
511 * @return true on success; false otherwise
513 bool increment(const std::string &key, uint32_t offset, uint64_t *value) throw(Error)
517 throw(Error("the key supplied is empty!", false));
519 memcached_return_t rc= memcached_increment(&memc, key.c_str(), key.length(),
521 return (rc == MEMCACHED_SUCCESS);
525 * Decrement the value of the object associated with the specified
526 * key by the offset given. The resulting value is saved in the value
529 * @param[in] key key of object in server whose value to decrement
530 * @param[in] offset amount to increment object's value by
531 * @param[out] value store the result of the decrement here
532 * @return true on success; false otherwise
534 bool decrement(const std::string &key, uint32_t offset, uint64_t *value)
539 throw(Error("the key supplied is empty!", false));
541 memcached_return_t rc= memcached_decrement(&memc, key.c_str(),
544 return (rc == MEMCACHED_SUCCESS);
549 * Add an object with the specified key and value to the server. This
550 * function returns false if the object already exists on the server.
552 * @param[in] key key of object to add
553 * @param[in] value of object to add
554 * @return true on success; false otherwise
556 bool add(const std::string &key, const std::vector<char> &value)
559 if (key.empty() || value.empty())
561 throw(Error("the key or value supplied is empty!", false));
563 memcached_return_t rc= memcached_add(&memc, key.c_str(), key.length(),
564 &value[0], value.size(), 0, 0);
565 return (rc == MEMCACHED_SUCCESS);
569 * Add an object with the specified key and value to the server. This
570 * function returns false if the object already exists on the server. The
571 * server to add the object to is specified by the master_key parameter.
573 * @param[in[ master_key key of server to add object to
574 * @param[in] key key of object to add
575 * @param[in] value of object to add
576 * @return true on success; false otherwise
578 bool addByKey(const std::string &master_key,
579 const std::string &key,
580 const std::vector<char> &value) throw(Error)
582 if (master_key.empty() ||
586 throw(Error("the master key or key supplied is empty!", false));
588 memcached_return_t rc= memcached_add_by_key(&memc,
596 return (rc == MEMCACHED_SUCCESS);
600 * Replaces an object on the server. This method only succeeds
601 * if the object is already present on the server.
603 * @param[in] key key of object to replace
604 * @param[in[ value value to replace object with
605 * @return true on success; false otherwise
607 bool replace(const std::string &key, const std::vector<char> &value) throw(Error)
612 throw(Error("the key or value supplied is empty!", false));
614 memcached_return_t rc= memcached_replace(&memc, key.c_str(), key.length(),
615 &value[0], value.size(),
617 return (rc == MEMCACHED_SUCCESS);
621 * Replaces an object on the server. This method only succeeds
622 * if the object is already present on the server. The server
623 * to replace the object on is specified by the master_key param.
625 * @param[in] master_key key of server to replace object on
626 * @param[in] key key of object to replace
627 * @param[in[ value value to replace object with
628 * @return true on success; false otherwise
630 bool replaceByKey(const std::string &master_key,
631 const std::string &key,
632 const std::vector<char> &value)
634 if (master_key.empty() ||
638 throw(Error("the master key or key supplied is empty!", false));
640 memcached_return_t rc= memcached_replace_by_key(&memc,
648 return (rc == MEMCACHED_SUCCESS);
652 * Places a segment of data before the last piece of data stored.
654 * @param[in] key key of object whose value we will prepend data to
655 * @param[in] value data to prepend to object's value
656 * @return true on success; false otherwise
658 bool prepend(const std::string &key, const std::vector<char> &value)
661 if (key.empty() || value.empty())
663 throw(Error("the key or value supplied is empty!", false));
665 memcached_return_t rc= memcached_prepend(&memc, key.c_str(), key.length(),
666 &value[0], value.size(), 0, 0);
667 return (rc == MEMCACHED_SUCCESS);
671 * Places a segment of data before the last piece of data stored. The
672 * server on which the object where we will be prepending data is stored
673 * on is specified by the master_key parameter.
675 * @param[in] master_key key of server where object is stored
676 * @param[in] key key of object whose value we will prepend data to
677 * @param[in] value data to prepend to object's value
678 * @return true on success; false otherwise
680 bool prependByKey(const std::string &master_key,
681 const std::string &key,
682 const std::vector<char> &value)
685 if (master_key.empty() ||
689 throw(Error("the master key or key supplied is empty!", false));
691 memcached_return_t rc= memcached_prepend_by_key(&memc,
700 return (rc == MEMCACHED_SUCCESS);
704 * Places a segment of data at the end of the last piece of data stored.
706 * @param[in] key key of object whose value we will append data to
707 * @param[in] value data to append to object's value
708 * @return true on success; false otherwise
710 bool append(const std::string &key, const std::vector<char> &value)
713 if (key.empty() || value.empty())
715 throw(Error("the key or value supplied is empty!", false));
717 memcached_return_t rc= memcached_append(&memc,
723 return (rc == MEMCACHED_SUCCESS);
727 * Places a segment of data at the end of the last piece of data stored. The
728 * server on which the object where we will be appending data is stored
729 * on is specified by the master_key parameter.
731 * @param[in] master_key key of server where object is stored
732 * @param[in] key key of object whose value we will append data to
733 * @param[in] value data to append to object's value
734 * @return true on success; false otherwise
736 bool appendByKey(const std::string &master_key,
737 const std::string &key,
738 const std::vector<char> &value)
741 if (master_key.empty() ||
745 throw(Error("the master key or key supplied is empty!", false));
747 memcached_return_t rc= memcached_append_by_key(&memc,
755 return (rc == MEMCACHED_SUCCESS);
759 * Overwrite data in the server as long as the cas_arg value
760 * is still the same in the server.
762 * @param[in] key key of object in server
763 * @param[in] value value to store for object in server
764 * @param[in] cas_arg "cas" value
766 bool cas(const std::string &key,
767 const std::vector<char> &value,
768 uint64_t cas_arg) throw(Error)
770 if (key.empty() || value.empty())
772 throw(Error("the key or value supplied is empty!", false));
774 memcached_return_t rc= memcached_cas(&memc, key.c_str(), key.length(),
775 &value[0], value.size(),
777 return (rc == MEMCACHED_SUCCESS);
781 * Overwrite data in the server as long as the cas_arg value
782 * is still the same in the server. The server to use is
783 * specified by the master_key parameter.
785 * @param[in] master_key specifies server to operate on
786 * @param[in] key key of object in server
787 * @param[in] value value to store for object in server
788 * @param[in] cas_arg "cas" value
790 bool casByKey(const std::string &master_key,
791 const std::string &key,
792 const std::vector<char> &value,
793 uint64_t cas_arg) throw(Error)
795 if (master_key.empty() ||
799 throw(Error("the master key, key or value supplied is empty!", false));
801 memcached_return_t rc= memcached_cas_by_key(&memc,
809 return (rc == MEMCACHED_SUCCESS);
813 * Delete an object from the server specified by the key given.
815 * @param[in] key key of object to delete
816 * @return true on success; false otherwise
818 bool remove(const std::string &key) throw(Error)
822 throw(Error("the key supplied is empty!", false));
824 memcached_return_t rc= memcached_delete(&memc, key.c_str(), key.length(), 0);
825 return (rc == MEMCACHED_SUCCESS);
829 * Delete an object from the server specified by the key given.
831 * @param[in] key key of object to delete
832 * @param[in] expiration time to delete the object after
833 * @return true on success; false otherwise
835 bool remove(const std::string &key,
836 time_t expiration) throw(Error)
840 throw(Error("the key supplied is empty!", false));
842 memcached_return_t rc= memcached_delete(&memc,
846 return (rc == MEMCACHED_SUCCESS);
850 * Delete an object from the server specified by the key given.
852 * @param[in] master_key specifies server to remove object from
853 * @param[in] key key of object to delete
854 * @return true on success; false otherwise
856 bool removeByKey(const std::string &master_key,
857 const std::string &key) throw(Error)
859 if (master_key.empty() || key.empty())
861 throw(Error("the master key or key supplied is empty!", false));
863 memcached_return_t rc= memcached_delete_by_key(&memc,
869 return (rc == MEMCACHED_SUCCESS);
873 * Delete an object from the server specified by the key given.
875 * @param[in] master_key specifies server to remove object from
876 * @param[in] key key of object to delete
877 * @param[in] expiration time to delete the object after
878 * @return true on success; false otherwise
880 bool removeByKey(const std::string &master_key,
881 const std::string &key,
882 time_t expiration) throw(Error)
884 if (master_key.empty() || key.empty())
886 throw(Error("the master key or key supplied is empty!", false));
888 memcached_return_t rc= memcached_delete_by_key(&memc,
894 return (rc == MEMCACHED_SUCCESS);
898 * Wipe the contents of memcached servers.
900 * @param[in] expiration time to wait until wiping contents of
902 * @return true on success; false otherwise
904 bool flush(time_t expiration)
906 memcached_return_t rc= memcached_flush(&memc, expiration);
907 return (rc == MEMCACHED_SUCCESS);
911 * Callback function for result sets. It passes the result
912 * sets to the list of functions provided.
914 * @param[in] callback list of callback functions
915 * @param[in] context pointer to memory reference that is
916 * supplied to the calling function
917 * @param[in] num_of_callbacks number of callback functions
918 * @return true on success; false otherwise
920 bool fetchExecute(memcached_execute_fn *callback,
922 uint32_t num_of_callbacks)
924 memcached_return_t rc= memcached_fetch_execute(&memc,
928 return (rc == MEMCACHED_SUCCESS);
932 * Get the library version string.
933 * @return std::string containing a copy of the library version string.
935 const std::string libVersion() const
937 const char *ver= memcached_lib_version();
938 const std::string version(ver);
943 * Retrieve memcached statistics. Populate a std::map with the retrieved
944 * stats. Each server will map to another std::map of the key:value stats.
946 * @param[out] stats_map a std::map to be populated with the memcached
948 * @return true on success; false otherwise
950 bool getStats(std::map< std::string, std::map<std::string, std::string> >
953 memcached_return_t rc;
954 memcached_stat_st *stats= memcached_stat(&memc, NULL, &rc);
956 if (rc != MEMCACHED_SUCCESS &&
957 rc != MEMCACHED_SOME_ERRORS)
962 uint32_t server_count= memcached_server_count(&memc);
965 * For each memcached server, construct a std::map for its stats and add
966 * it to the std::map of overall stats.
968 for (uint32_t x= 0; x < server_count; x++)
970 std::ostringstream strstm;
971 std::string server_name(memcached_server_name(&memc, servers[x]));
972 server_name.append(":");
973 strstm << memcached_server_port(&memc, servers[x]);
974 server_name.append(strstm.str());
976 std::map<std::string, std::string> server_stats;
980 list= memcached_stat_get_keys(&memc, &stats[x], &rc);
981 for (ptr= list; *ptr; ptr++)
983 char *value= memcached_stat_get_value(&memc, &stats[x], *ptr, &rc);
984 server_stats[*ptr]= value;
988 stats_map[server_name]= server_stats;
992 memcached_stat_free(&memc, stats);
998 std::string servers_list;
1000 memcached_server_st *servers;
1001 memcached_result_st result;
1006 #endif /* LIBMEMCACHEDPP_H */