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
17 #include <libmemcached/memcached.h>
18 #include <libmemcached/exception.hpp>
31 * This is the core memcached library (if later, other objects
32 * are needed, they will be created from this class).
40 memc= memcached("", 0);
43 Memcache(const std::string &config)
45 memc= memcached(config.c_str(), config.size());
48 Memcache(const std::string &hostname, in_port_t port)
50 memc= memcached("", 0);
52 memcached_server_add(memc, hostname.c_str(), port);
55 Memcache(memcached_st *clone)
57 memc= memcached_clone(NULL, clone);
60 Memcache(const Memcache &rhs)
62 memc= memcached_clone(NULL, rhs.getImpl());
65 Memcache &operator=(const Memcache &rhs)
70 memc= memcached_clone(NULL, rhs.getImpl());
82 * Get the internal memcached_st *
84 const memcached_st *getImpl() const
90 * Return an error string for the given return structure.
92 * @param[in] rc a memcached_return_t structure
93 * @return error string corresponding to given return code in the library.
95 const std::string getError(memcached_return_t rc) const
97 /* first parameter to strerror is unused */
98 return memcached_strerror(NULL, rc);
102 bool setBehavior(memcached_behavior_t flag, uint64_t data)
104 return (memcached_success(memcached_behavior_set(memc, flag, data)));
107 uint64_t getBehavior(memcached_behavior_t flag)
109 return memcached_behavior_get(memc, flag);
113 * Configure the memcache object
115 * @param[in] in_config configuration
116 * @return true on success; false otherwise
118 bool configure(const std::string &configuration)
120 return memcached_success(memcached_parse_configuration(memc, configuration.c_str(), configuration.size()));
124 * Add a server to the list of memcached servers to use.
126 * @param[in] server_name name of the server to add
127 * @param[in] port port number of server to add
128 * @return true on success; false otherwise
130 bool addServer(const std::string &server_name, in_port_t port)
132 return memcached_success(memcached_server_add(memc, server_name.c_str(), port));
136 * Remove a server from the list of memcached servers to use.
138 * @param[in] server_name name of the server to remove
139 * @param[in] port port number of server to remove
140 * @return true on success; false otherwise
142 bool removeServer(const std::string &server_name, in_port_t port)
145 std::ostringstream strstm;
147 tmp_str.append(server_name);
150 tmp_str.append(strstm.str());
152 //memcached_return_t rc= memcached_server_remove(server);
158 * Fetches an individual value from the server. mget() must always
159 * be called before using this method.
161 * @param[in] key key of object to fetch
162 * @param[out] ret_val store returned object in this vector
163 * @return a memcached return structure
165 memcached_return_t fetch(std::string &key,
166 std::vector<char> &ret_val)
168 char ret_key[MEMCACHED_MAX_KEY];
169 size_t value_length= 0;
170 size_t key_length= 0;
171 memcached_return_t rc;
173 char *value= memcached_fetch(memc, ret_key, &key_length,
174 &value_length, &flags, &rc);
175 if (value && ret_val.empty())
177 ret_val.reserve(value_length);
178 ret_val.assign(value, value + value_length);
179 key.assign(ret_key, key_length);
191 * Fetches an individual value from the server.
193 * @param[in] key key of object whose value to get
194 * @param[out] ret_val object that is retrieved is stored in
196 * @return true on success; false otherwise
198 bool get(const std::string &key, std::vector<char> &ret_val)
201 memcached_return_t rc;
202 size_t value_length= 0;
204 char *value= memcached_get(memc, key.c_str(), key.length(),
205 &value_length, &flags, &rc);
206 if (value != NULL && ret_val.empty())
208 ret_val.reserve(value_length);
209 ret_val.assign(value, value + value_length);
217 * Fetches an individual from a server which is specified by
218 * the master_key parameter that is used for determining which
219 * server an object was stored in if key partitioning was
222 * @param[in] master_key key that specifies server object is stored on
223 * @param[in] key key of object whose value to get
224 * @param[out] ret_val object that is retrieved is stored in
226 * @return true on success; false otherwise
228 bool getByKey(const std::string &master_key,
229 const std::string &key,
230 std::vector<char> &ret_val)
233 memcached_return_t rc;
234 size_t value_length= 0;
236 char *value= memcached_get_by_key(memc,
237 master_key.c_str(), master_key.length(),
238 key.c_str(), key.length(),
239 &value_length, &flags, &rc);
242 ret_val.reserve(value_length);
243 ret_val.assign(value, value + value_length);
251 * Selects multiple keys at once. This method always
252 * works asynchronously.
254 * @param[in] keys vector of keys to select
255 * @return true if all keys are found
257 bool mget(std::vector<std::string> &keys)
259 std::vector<const char *> real_keys;
260 std::vector<size_t> key_len;
262 * Construct an array which will contain the length
263 * of each of the strings in the input vector. Also, to
264 * interface with the memcached C API, we need to convert
265 * the vector of std::string's to a vector of char *.
267 real_keys.reserve(keys.size());
268 key_len.reserve(keys.size());
270 std::vector<std::string>::iterator it= keys.begin();
272 while (it != keys.end())
274 real_keys.push_back(const_cast<char *>((*it).c_str()));
275 key_len.push_back((*it).length());
280 * If the std::vector of keys is empty then we cannot
281 * call memcached_mget as we will get undefined behavior.
283 if (not real_keys.empty())
285 return memcached_success(memcached_mget(memc, &real_keys[0], &key_len[0], real_keys.size()));
292 * Writes an object to the server. If the object already exists, it will
293 * overwrite the existing object. This method always returns true
294 * when using non-blocking mode unless a network error occurs.
296 * @param[in] key key of object to write to server
297 * @param[in] value value of object to write to server
298 * @param[in] expiration time to keep the object stored in the server for
299 * @param[in] flags flags to store with the object
300 * @return true on succcess; false otherwise
302 bool set(const std::string &key,
303 const std::vector<char> &value,
307 memcached_return_t rc= memcached_set(memc,
308 key.c_str(), key.length(),
309 &value[0], value.size(),
311 return (rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
315 * Writes an object to a server specified by the master_key parameter.
316 * If the object already exists, it will overwrite the existing object.
318 * @param[in] master_key key that specifies server to write to
319 * @param[in] key key of object to write to server
320 * @param[in] value value of object to write to server
321 * @param[in] expiration time to keep the object stored in the server for
322 * @param[in] flags flags to store with the object
323 * @return true on succcess; false otherwise
325 bool setByKey(const std::string &master_key,
326 const std::string &key,
327 const std::vector<char> &value,
331 return memcached_success(memcached_set_by_key(memc, master_key.c_str(),
333 key.c_str(), key.length(),
334 &value[0], value.size(),
340 * Writes a list of objects to the server. Objects are specified by
341 * 2 vectors - 1 vector of keys and 1 vector of values.
343 * @param[in] keys vector of keys of objects to write to server
344 * @param[in] values vector of values of objects to write to server
345 * @param[in] expiration time to keep the objects stored in server for
346 * @param[in] flags flags to store with the objects
347 * @return true on success; false otherwise
349 bool setAll(std::vector<std::string> &keys,
350 std::vector< std::vector<char> *> &values,
355 std::vector<std::string>::iterator key_it= keys.begin();
356 std::vector< std::vector<char> *>::iterator val_it= values.begin();
357 while (key_it != keys.end())
359 retval= set((*key_it), *(*val_it), expiration, flags);
371 * Writes a list of objects to the server. Objects are specified by
372 * a map of keys to values.
374 * @param[in] key_value_map map of keys and values to store in server
375 * @param[in] expiration time to keep the objects stored in server for
376 * @param[in] flags flags to store with the objects
377 * @return true on success; false otherwise
379 bool setAll(std::map<const std::string, std::vector<char> > &key_value_map,
384 std::map<const std::string, std::vector<char> >::iterator it= key_value_map.begin();
386 while (it != key_value_map.end())
388 retval= set(it->first, it->second, expiration, flags);
391 // We should tell the user what the key that failed was
400 * Increment the value of the object associated with the specified
401 * key by the offset given. The resulting value is saved in the value
404 * @param[in] key key of object in server whose value to increment
405 * @param[in] offset amount to increment object's value by
406 * @param[out] value store the result of the increment here
407 * @return true on success; false otherwise
409 bool increment(const std::string &key, uint32_t offset, uint64_t *value)
411 return memcached_success(memcached_increment(memc, key.c_str(), key.length(), offset, value));
415 * Decrement the value of the object associated with the specified
416 * key by the offset given. The resulting value is saved in the value
419 * @param[in] key key of object in server whose value to decrement
420 * @param[in] offset amount to increment object's value by
421 * @param[out] value store the result of the decrement here
422 * @return true on success; false otherwise
424 bool decrement(const std::string &key, uint32_t offset, uint64_t *value)
426 return memcached_success(memcached_decrement(memc, key.c_str(),
433 * Add an object with the specified key and value to the server. This
434 * function returns false if the object already exists on the server.
436 * @param[in] key key of object to add
437 * @param[in] value of object to add
438 * @return true on success; false otherwise
440 bool add(const std::string &key, const std::vector<char> &value)
442 return memcached_success(memcached_add(memc, key.c_str(), key.length(),
443 &value[0], value.size(), 0, 0));
447 * Add an object with the specified key and value to the server. This
448 * function returns false if the object already exists on the server. The
449 * server to add the object to is specified by the master_key parameter.
451 * @param[in[ master_key key of server to add object to
452 * @param[in] key key of object to add
453 * @param[in] value of object to add
454 * @return true on success; false otherwise
456 bool addByKey(const std::string &master_key,
457 const std::string &key,
458 const std::vector<char> &value)
460 return memcached_success(memcached_add_by_key(memc,
471 * Replaces an object on the server. This method only succeeds
472 * if the object is already present on the server.
474 * @param[in] key key of object to replace
475 * @param[in[ value value to replace object with
476 * @return true on success; false otherwise
478 bool replace(const std::string &key, const std::vector<char> &value)
480 return memcached_success(memcached_replace(memc, key.c_str(), key.length(),
481 &value[0], value.size(),
486 * Replaces an object on the server. This method only succeeds
487 * if the object is already present on the server. The server
488 * to replace the object on is specified by the master_key param.
490 * @param[in] master_key key of server to replace object on
491 * @param[in] key key of object to replace
492 * @param[in[ value value to replace object with
493 * @return true on success; false otherwise
495 bool replaceByKey(const std::string &master_key,
496 const std::string &key,
497 const std::vector<char> &value)
499 return memcached_success(memcached_replace_by_key(memc,
510 * Places a segment of data before the last piece of data stored.
512 * @param[in] key key of object whose value we will prepend data to
513 * @param[in] value data to prepend to object's value
514 * @return true on success; false otherwise
516 bool prepend(const std::string &key, const std::vector<char> &value)
518 return memcached_success(memcached_prepend(memc, key.c_str(), key.length(),
519 &value[0], value.size(), 0, 0));
523 * Places a segment of data before the last piece of data stored. The
524 * server on which the object where we will be prepending data is stored
525 * on is specified by the master_key parameter.
527 * @param[in] master_key key of server where object is stored
528 * @param[in] key key of object whose value we will prepend data to
529 * @param[in] value data to prepend to object's value
530 * @return true on success; false otherwise
532 bool prependByKey(const std::string &master_key,
533 const std::string &key,
534 const std::vector<char> &value)
536 return memcached_success(memcached_prepend_by_key(memc,
548 * Places a segment of data at the end of the last piece of data stored.
550 * @param[in] key key of object whose value we will append data to
551 * @param[in] value data to append to object's value
552 * @return true on success; false otherwise
554 bool append(const std::string &key, const std::vector<char> &value)
556 return memcached_success(memcached_append(memc,
565 * Places a segment of data at the end of the last piece of data stored. The
566 * server on which the object where we will be appending data is stored
567 * on is specified by the master_key parameter.
569 * @param[in] master_key key of server where object is stored
570 * @param[in] key key of object whose value we will append data to
571 * @param[in] value data to append to object's value
572 * @return true on success; false otherwise
574 bool appendByKey(const std::string &master_key,
575 const std::string &key,
576 const std::vector<char> &value)
578 return memcached_success(memcached_append_by_key(memc,
589 * Overwrite data in the server as long as the cas_arg value
590 * is still the same in the server.
592 * @param[in] key key of object in server
593 * @param[in] value value to store for object in server
594 * @param[in] cas_arg "cas" value
596 bool cas(const std::string &key,
597 const std::vector<char> &value,
600 return memcached_success(memcached_cas(memc, key.c_str(), key.length(),
601 &value[0], value.size(),
606 * Overwrite data in the server as long as the cas_arg value
607 * is still the same in the server. The server to use is
608 * specified by the master_key parameter.
610 * @param[in] master_key specifies server to operate on
611 * @param[in] key key of object in server
612 * @param[in] value value to store for object in server
613 * @param[in] cas_arg "cas" value
615 bool casByKey(const std::string &master_key,
616 const std::string &key,
617 const std::vector<char> &value,
620 return memcached_success(memcached_cas_by_key(memc,
631 * Delete an object from the server specified by the key given.
633 * @param[in] key key of object to delete
634 * @return true on success; false otherwise
636 bool remove(const std::string &key)
638 return memcached_success(memcached_delete(memc, key.c_str(), key.length(), 0));
642 * Delete an object from the server specified by the key given.
644 * @param[in] key key of object to delete
645 * @param[in] expiration time to delete the object after
646 * @return true on success; false otherwise
648 bool remove(const std::string &key, time_t expiration)
650 return memcached_success(memcached_delete(memc,
657 * Delete an object from the server specified by the key given.
659 * @param[in] master_key specifies server to remove object from
660 * @param[in] key key of object to delete
661 * @return true on success; false otherwise
663 bool removeByKey(const std::string &master_key,
664 const std::string &key)
666 return memcached_success(memcached_delete_by_key(memc,
675 * Delete an object from the server specified by the key given.
677 * @param[in] master_key specifies server to remove object from
678 * @param[in] key key of object to delete
679 * @param[in] expiration time to delete the object after
680 * @return true on success; false otherwise
682 bool removeByKey(const std::string &master_key,
683 const std::string &key,
686 return memcached_success(memcached_delete_by_key(memc,
695 * Wipe the contents of memcached servers.
697 * @param[in] expiration time to wait until wiping contents of
699 * @return true on success; false otherwise
701 bool flush(time_t expiration)
703 return memcached_success(memcached_flush(memc, expiration));
707 * Get the library version string.
708 * @return std::string containing a copy of the library version string.
710 const std::string libVersion() const
712 const char *ver= memcached_lib_version();
713 const std::string version(ver);
718 * Retrieve memcached statistics. Populate a std::map with the retrieved
719 * stats. Each server will map to another std::map of the key:value stats.
721 * @param[out] stats_map a std::map to be populated with the memcached
723 * @return true on success; false otherwise
725 bool getStats(std::map< std::string, std::map<std::string, std::string> >
728 memcached_return_t rc;
729 memcached_stat_st *stats= memcached_stat(memc, NULL, &rc);
731 if (rc != MEMCACHED_SUCCESS &&
732 rc != MEMCACHED_SOME_ERRORS)
737 uint32_t server_count= memcached_server_count(memc);
740 * For each memcached server, construct a std::map for its stats and add
741 * it to the std::map of overall stats.
743 for (uint32_t x= 0; x < server_count; x++)
745 memcached_server_instance_st instance=
746 memcached_server_instance_by_position(memc, x);
747 std::ostringstream strstm;
748 std::string server_name(memcached_server_name(instance));
749 server_name.append(":");
750 strstm << memcached_server_port(instance);
751 server_name.append(strstm.str());
753 std::map<std::string, std::string> server_stats;
757 list= memcached_stat_get_keys(memc, &stats[x], &rc);
758 for (ptr= list; *ptr; ptr++)
760 char *value= memcached_stat_get_value(memc, &stats[x], *ptr, &rc);
761 server_stats[*ptr]= value;
765 stats_map[server_name]= server_stats;
769 memcached_stat_free(memc, stats);