libmoost
/home/mhx/git/github/libmoost/include/moost/kvstore/kyoto_tycoon_client.hpp
Go to the documentation of this file.
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