1 // Simple Wrapper to libMemcached
2 
3 /*  IIP Image Server
4 
5     Copyright (C) 2010-2013 Ruven Pillay.
6 
7     This program is free software; you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation; either version 3 of the License, or
10     (at your option) any later version.
11 
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.
16 
17     You should have received a copy of the GNU General Public License
18     along with this program; if not, write to the Free Software Foundation,
19     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20 */
21 
22 
23 
24 #ifndef _MEMCACHED_H
25 #define _MEMCACHED_H
26 
27 #include <string>
28 #include <libmemcached/memcached.h>
29 
30 #ifdef LIBMEMCACHED_VERSION_STRING
31 typedef memcached_return memcached_return_t;
32 #endif
33 
34 /// Cache to store raw tile data
35 
36 class Memcache {
37 
38 
39  private:
40 
41   /// Memcached structure
42   memcached_st *_memc;
43 
44   /// Memcached return value
45   memcached_return_t _rc;
46 
47   /// Memcached servers
48   memcached_server_st *_servers;
49 
50   /// Cache expiry set to 1 hour
51   time_t _timeout;
52 
53   /// Length of data returned
54   size_t _length;
55 
56   /// Flag whether we are connected
57   bool _connected;
58 
59 
60  public:
61 
62   /// Constructor
63   /** @param servernames list of memcached servers
64       @param timeout memcached timeout - defaults to 1 hour (3600 seconds)
65   */
66   Memcache( const std::string& servernames = "localhost", unsigned int timeout = 3600 ) {
67 
68     _length = 0;
69 
70     // Set our timeout
71     _timeout =  timeout;
72 
73     // Create our memcached object
74     _memc = memcached_create(NULL);
75 
76     // Create a list of servers
77     _servers = memcached_servers_parse( servernames.c_str() );
78 
79     // Try to set some memcached behaviour settings for performance. For example,
80     // using the binary protocol, non-blocking IO, and no reply for add commands
81     _rc =  memcached_behavior_set( _memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1 );
82     _rc =  memcached_behavior_set( _memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 1 );
83     _rc =  memcached_behavior_set( _memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1 );
84     _rc =  memcached_behavior_set( _memc, MEMCACHED_BEHAVIOR_NOREPLY, 1 );
85 
86     // Connect to the servers
87     _rc = memcached_server_push( _memc, _servers );
88     if(_rc == MEMCACHED_SUCCESS ) _connected = true;
89     else _connected = false;
90 
91     if( memcached_server_count(_memc) > 0 ) _connected = true;
92     else _connected = false;
93   };
94 
95 
96   /// Destructor
~Memcache()97   ~Memcache() {
98     // Disconnect from our servers and free our memcached structure
99     if( _servers ) memcached_server_free(_servers);
100     if( _memc ) memcached_free(_memc);
101   }
102 
103 
104   /// Insert data into our cache
105   /** @param key key used for cache
106       @param data pointer to the data to be stored
107       @param length length of data to be stored
108   */
store(const std::string & key,void * data,unsigned int length)109   void store( const std::string& key, void* data, unsigned int length ){
110 
111     if( !_connected ) return;
112 
113     std::string k = "iipsrv::" + key;
114     _rc = memcached_set( _memc, k.c_str(), k.length(),
115                         (char*) data, length,
116                         _timeout, 0 );
117   }
118 
119 
120   /// Retrieve data from our cache
121   /** @param key key for cache data
122       @return pointer to data
123   */
retrieve(const std::string & key)124   char* retrieve( const std::string& key ){
125 
126     if( !_connected ) return NULL;
127 
128     uint32_t flags;
129     std::string k = "iipsrv::" + key;
130     return memcached_get( _memc, k.c_str(), k.length(), &_length, &flags, &_rc );
131   }
132 
133 
134   /// Get error string
error()135   const char* error(){
136     return memcached_strerror( _memc, _rc );
137   };
138 
139 
140   /// Return the number of bytes in the result
length()141   unsigned int length(){ return _length; };
142 
143 
144   /// Tell us whether we are connected to any memcached servers
connected()145   bool connected(){ return _connected; };
146 
147 
148 };
149 
150 
151 
152 #endif
153