libmoost
|
00001 /* vim:set ts=3 sw=3 sts=3 et: */ 00028 00029 00030 00031 00032 00033 00034 00035 00036 00037 00038 00039 00040 00041 00042 00043 00044 00045 00046 #ifndef MOOST_KVSTORE_KYOTO_TYCOON_CLIENT_HPP 00047 #define MOOST_KVSTORE_KYOTO_TYCOON_CLIENT_HPP 00048 00049 #include <stdexcept> 00050 #include <vector> 00051 00052 #include "i_kyoto_tycoon_connection.h" 00053 00054 #include <boost/static_assert.hpp> 00055 #include <boost/type_traits/is_pod.hpp> 00056 00057 namespace moost { namespace kvstore { 00058 00059 class KyotoTycoonClient 00060 { 00061 public: 00062 typedef IKyotoTycoonConnection connection_type; 00063 00064 private: 00065 connection_type& m_conn; 00066 00067 public: 00068 KyotoTycoonClient(connection_type& conn) 00069 : m_conn(conn) 00070 { 00071 } 00072 00073 // vector values, returns false if key not found, throws if data alignment is wrong 00074 template <typename TKey, typename TVal> 00075 bool get(const TKey& key, std::vector<TVal>& val) const 00076 { 00077 return get(&key, sizeof(TKey), val); 00078 } 00079 00080 // generic values, returns false if key not found, throws if value is wrong size 00081 template <typename TKey, typename TVal> 00082 bool get(const TKey& key, TVal& val) const 00083 { 00084 return get(&key, sizeof(TKey), val); 00085 } 00086 00087 // override for string key 00088 template <typename TVal> 00089 bool get(const std::string& key, TVal& val) const 00090 { 00091 return get(key.data(), key.size(), val); 00092 } 00093 00094 // override for string key 00095 template <typename TVal> 00096 bool get(const std::string& key, std::vector<TVal>& val) const 00097 { 00098 return get(key.data(), key.size(), val); 00099 } 00100 00101 private: 00102 00103 // vector values, returns false if key not found, throws if data alignment is wrong 00104 template <typename TVal> 00105 bool get(const void* pkey, size_t ksize, std::vector<TVal>& val) const 00106 { 00107 size_t vsize; 00108 boost::shared_array<char> sa = m_conn.get(pkey, ksize, vsize); 00109 TVal *pv = reinterpret_cast<TVal *>(sa.get()); 00110 bool found = (0 != pv); 00111 00112 if (found) 00113 { 00114 if (vsize % sizeof(TVal) == 0) 00115 { 00116 val.assign(pv, pv + vsize/sizeof(TVal)); 00117 } 00118 else 00119 { 00120 throw std::runtime_error("Retrieved value has incorrect data alignment"); 00121 } 00122 } 00123 00124 return found; 00125 } 00126 00127 // generic values, returns false if key not found, throws if value is wrong size 00128 template <typename TVal> 00129 bool get(const void* pkey, size_t ksize, TVal& val) const 00130 { 00131 size_t vsize; 00132 boost::shared_array<char> sa = m_conn.get(pkey, ksize, vsize); 00133 TVal *pv = reinterpret_cast<TVal *>(sa.get()); 00134 bool found = (0 != pv); 00135 00136 if (found) 00137 { 00138 if (vsize == sizeof(TVal)) 00139 { 00140 val = *pv; 00141 } 00142 else 00143 { 00144 throw std::runtime_error("Retrieved value has incorrect size"); 00145 } 00146 } 00147 00148 return found; 00149 } 00150 00151 public: 00152 00153 // vector values, throws on failure 00154 template <typename TKey, typename TVal> 00155 void set(const TKey& key, const std::vector<TVal>& val) const 00156 { 00157 BOOST_STATIC_ASSERT((boost::is_pod<TKey>::value)); 00158 BOOST_STATIC_ASSERT((boost::is_pod<TVal>::value)); 00159 00160 m_conn.set(&key, sizeof(key), &val[0], sizeof(TVal) * val.size()); 00161 } 00162 00163 // generic values, throws on failure 00164 template <typename TKey, typename TVal> 00165 void set(const TKey& key, const TVal& val) const 00166 { 00167 BOOST_STATIC_ASSERT((boost::is_pod<TKey>::value)); 00168 BOOST_STATIC_ASSERT((boost::is_pod<TVal>::value)); 00169 00170 m_conn.set(&key, sizeof(key), &val, sizeof(val)); 00171 } 00172 00173 // vector values, throws on failure 00174 template <typename TKey, typename TVal> 00175 void cache(const TKey& key, const std::vector<TVal>& val, boost::int64_t expirySecs) const 00176 { 00177 BOOST_STATIC_ASSERT((boost::is_pod<TKey>::value)); 00178 BOOST_STATIC_ASSERT((boost::is_pod<TVal>::value)); 00179 00180 m_conn.cache(&key, sizeof(key), &val[0], sizeof(TVal) * val.size(), expirySecs); 00181 } 00182 00183 // generic values, throws on failure 00184 template <typename TKey, typename TVal> 00185 void cache(const TKey& key, const TVal& val, boost::int64_t expirySecs) const 00186 { 00187 BOOST_STATIC_ASSERT((boost::is_pod<TKey>::value)); 00188 BOOST_STATIC_ASSERT((boost::is_pod<TVal>::value)); 00189 00190 m_conn.cache(&key, sizeof(key), &val, sizeof(val), expirySecs); 00191 } 00192 00193 // vector values, throws on failure (std::string key override) 00194 template <typename TVal> 00195 void set(const std::string& key, const std::vector<TVal>& val) const 00196 { 00197 BOOST_STATIC_ASSERT((boost::is_pod<TVal>::value)); 00198 00199 m_conn.set(key.data(), key.size(), &val[0], sizeof(TVal) * val.size()); 00200 } 00201 00202 // generic values, throws on failure (std::string key override) 00203 template <typename TVal> 00204 void set(const std::string& key, const TVal& val) const 00205 { 00206 BOOST_STATIC_ASSERT((boost::is_pod<TVal>::value)); 00207 00208 m_conn.set(key.data(), key.size(), &val, sizeof(val)); 00209 } 00210 00211 // vector values, throws on failure (std::string key override) 00212 template <typename TVal> 00213 void cache(const std::string& key, const std::vector<TVal>& val, boost::int64_t expirySecs) const 00214 { 00215 BOOST_STATIC_ASSERT((boost::is_pod<TVal>::value)); 00216 00217 m_conn.cache(key.data(), key.size(), &val[0], sizeof(TVal) * val.size(), expirySecs); 00218 } 00219 00220 // generic values, throws on failure (std::string key override) 00221 template <typename TVal> 00222 void cache(const std::string& key, const TVal& val, boost::int64_t expirySecs) const 00223 { 00224 BOOST_STATIC_ASSERT((boost::is_pod<TVal>::value)); 00225 00226 m_conn.cache(key.data(), key.size(), &val, sizeof(val), expirySecs); 00227 } 00228 }; 00229 00230 }} // end namespace 00231 00232 #endif