libmoost
|
00001 /* vim:set ts=3 sw=3 sts=3 et: */ 00028 00029 #include <cassert> 00030 #include <stdexcept> 00031 #include <vector> 00032 00033 #include <boost/shared_ptr.hpp> 00034 00035 #include "ikvds.hpp" 00036 #include "kvds_integral_type.hpp" 00037 00038 #ifndef MOOST_KVDS_KVDS_HPP__ 00039 #define MOOST_KVDS_KVDS_HPP__ 00040 00041 namespace moost { namespace kvds { 00042 00043 typedef boost::shared_ptr<IKvds> ikvds_ptr_t; 00044 00050 00052 00054 00055 template < 00056 typename keyT, // the type of the key 00057 typename valT, // the type of the value 00058 00059 // policy for serialising the key -- default is to treat it as an integeral type 00060 template <typename> class KvdsTypeKey = KvdsIntegralType, 00061 00062 // policy for serialising the value -- default is to treat it as an integeral type 00063 template <typename> class KvdsTypeVal = KvdsIntegralType 00064 > 00065 class Kvds 00066 { 00067 template <typename kvdsT> friend class KvdsKeyIterator; 00068 00069 public: 00070 typedef keyT key_type; 00071 typedef valT val_type; 00072 typedef std::vector<val_type> kvds_values_t; 00073 00075 typedef std::pair<key_type, val_type> value_type; 00076 typedef val_type data_type; 00077 00078 private: 00079 typedef KvdsTypeKey<key_type> kvds_key_t; 00080 typedef KvdsTypeVal<val_type> kvds_val_t; 00081 typedef KvdsTypeKey<key_type const> kvds_key_const_t; 00082 typedef KvdsTypeVal<val_type const> kvds_val_const_t; 00083 00084 public: 00085 Kvds(ikvds_ptr_t ikvds_ptr) : 00086 ikvds_ptr_(ikvds_ptr) 00087 { 00088 assert(ikvds_ptr_); // catch it in debug! 00089 if(!ikvds_ptr_) { throw std::runtime_error("Datastore cannot be initialised with a null ikvds"); } 00090 } 00091 00092 bool put(kvds_key_const_t const & key, kvds_val_const_t const & val) const 00093 { 00094 return ikvds_ptr_->put( 00095 &key, key.size(), 00096 &val, val.size() 00097 ); 00098 } 00099 00100 bool put(kvds_key_const_t const & key, kvds_values_t const & vals) const 00101 { 00102 typename kvds_val_const_t::vector_type kvds_val_vector(vals); 00103 00104 return ikvds_ptr_->put( 00105 &key, key.size(), 00106 &kvds_val_vector, kvds_val_vector.size() 00107 ); 00108 } 00109 00110 bool get(kvds_key_const_t const & key, kvds_val_t val) const 00111 { 00112 bool found = ikvds_ptr_->get( 00113 &key, key.size(), 00114 &val, val.size() 00115 ); 00116 00117 *val; // Reassemble val 00118 00119 return found; 00120 } 00121 00122 bool get(kvds_key_const_t const & key, kvds_values_t & vals, size_t const count) const 00123 { 00124 vals.resize(count); 00125 typename kvds_val_t::vector_type kvds_val_vector(vals); 00126 00127 size_t esize = kvds_val_vector.size(); 00128 00129 bool found = esize > 0 ? ikvds_ptr_->get(&key, key.size(), &kvds_val_vector, esize) : false; 00130 00131 if(found) 00132 { 00133 if(esize < kvds_val_vector.size()) 00134 { 00135 // read less than the buffer size so before we must resize buffer 00136 kvds_val_vector.resize(esize); 00137 } 00138 00139 *kvds_val_vector; // Reassemble vals 00140 } 00141 00142 return found; 00143 } 00144 00145 bool get(kvds_key_const_t const & key, kvds_values_t & vals) const 00146 { 00147 typename kvds_val_t::vector_type kvds_val_vector(vals); 00148 00149 bool found = false; 00150 size_t esize = 0; 00151 00152 if(ikvds_ptr_->siz(&key, key.size(), esize)) 00153 { 00154 kvds_val_vector.resize(esize); 00155 00156 found = ikvds_ptr_->all(&key, key.size(), &kvds_val_vector, esize); 00157 00158 if(found) 00159 { 00160 *kvds_val_vector; // Reassemble vals 00161 } 00162 } 00163 00164 return found; 00165 } 00166 00167 bool insert(value_type const & kvp) // Just to be more STL map like 00168 { 00169 return put(kvp.first, kvp.second); 00170 } 00171 00172 bool add(kvds_key_const_t const & key, kvds_val_const_t const & val) const 00173 { 00174 return ikvds_ptr_->add( 00175 &key, key.size(), 00176 &val, val.size() 00177 ); 00178 } 00179 00180 bool exists(kvds_key_const_t const & key) const 00181 { 00182 return ikvds_ptr_->xst(&key, key.size()); 00183 } 00184 00185 bool erase(kvds_key_const_t const & key) const 00186 { 00187 return ikvds_ptr_->del(&key, key.size()); 00188 } 00189 00190 bool clear() const 00191 { 00192 return ikvds_ptr_->clr(); 00193 } 00194 00195 bool size(kvds_key_const_t const & key, size_t & size) const 00196 { 00197 bool found = ikvds_ptr_->siz(&key, key.size(), size); 00198 00199 if(found && (0 != (size % sizeof(typename kvds_values_t::value_type)))) 00200 { 00201 throw std::runtime_error("value type boundary error"); 00202 } 00203 00204 size /= sizeof(typename kvds_values_t::value_type); 00205 00206 return found; 00207 } 00208 00209 size_t size(kvds_key_const_t const & key) const 00210 { 00211 size_t size = 0; 00212 00213 if(!this->size(key, size)) 00214 { 00215 throw std::runtime_error("item not found"); 00216 } 00217 00218 return size; 00219 } 00220 00221 bool count(boost::uint64_t & cnt) const 00222 { 00223 return ikvds_ptr_->cnt(cnt); 00224 } 00225 00226 boost::uint64_t size() const // Just to be more STL like 00227 { 00228 boost::uint64_t cnt = 0; 00229 00230 if(!count(cnt)) 00231 { 00232 throw std::runtime_error("size not available"); 00233 } 00234 00235 return cnt; 00236 } 00237 00238 bool empty() const 00239 { 00240 bool isnil = false; 00241 00242 if(!ikvds_ptr_->nil(isnil)) 00243 { 00244 throw std::runtime_error("empty state is not available"); 00245 } 00246 00247 return isnil; 00248 } 00249 00251 IKvds & get_ikvds() const 00252 { 00254 if(!ikvds_ptr_) { throw std::runtime_error("Invalid kvds interface"); } 00255 return *ikvds_ptr_; 00256 } 00257 00258 ikvds_ptr_t get_ikvds_ptr() const 00259 { 00261 return ikvds_ptr_; 00262 } 00263 00264 private: 00278 00279 class Iow // Indexed object wrapper (needs no external visibility!) 00280 { 00281 public: 00282 Iow( 00283 Kvds & kvds, 00284 kvds_key_const_t const & key 00285 ) : kvds_(kvds), key_(key), val_(val_type()) {} 00286 00287 Iow & operator = (val_type const & val) 00288 { 00289 val_ = val; 00290 00291 if(!kvds_.put(key_, val_)) 00292 { 00293 throw std::runtime_error("Write to datastore failed"); 00294 } 00295 00296 return *this; 00297 } 00298 00299 val_type & operator * () { return val_; } 00300 00301 operator val_type const () { return val_; } 00302 00303 private: 00304 Kvds & kvds_; 00305 kvds_key_const_t const & key_; 00306 val_type val_; 00307 }; 00308 public: 00311 Iow operator [](kvds_key_const_t const & key) 00312 { 00313 Iow iow(*this, key); 00314 00315 if(!get(key, *iow)) 00316 { 00317 // It doesn't exist, create one 00318 iow = val_type(); 00319 } 00320 00321 return iow; 00322 } 00323 00324 private: 00325 ikvds_ptr_t ikvds_ptr_; 00326 }; 00327 00328 }} 00329 00330 #endif /// MOOST_KVDS_KVDS_HPP__