MemoryStore.cc

Go to the documentation of this file.
00001 /*
00002  *    Copyright 2005-2006 Intel Corporation
00003  * 
00004  *    Licensed under the Apache License, Version 2.0 (the "License");
00005  *    you may not use this file except in compliance with the License.
00006  *    You may obtain a copy of the License at
00007  * 
00008  *        http://www.apache.org/licenses/LICENSE-2.0
00009  * 
00010  *    Unless required by applicable law or agreed to in writing, software
00011  *    distributed under the License is distributed on an "AS IS" BASIS,
00012  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  *    See the License for the specific language governing permissions and
00014  *    limitations under the License.
00015  */
00016 
00017 
00018 #include <sys/types.h>
00019 #include <errno.h>
00020 #include <unistd.h>
00021 
00022 #include <debug/DebugUtils.h>
00023 #include <util/StringBuffer.h>
00024 #include <util/Pointers.h>
00025 #include <serialize/MarshalSerialize.h>
00026 #include <serialize/TypeShims.h>
00027 
00028 #include "MemoryStore.h"
00029 #include "StorageConfig.h"
00030 
00031 namespace oasys {
00032 /******************************************************************************
00033  *
00034  * MemoryStore
00035  *
00036  *****************************************************************************/
00037 
00038 MemoryStore::MemoryStore(const char* logpath) 
00039     : DurableStoreImpl("MemoryStore", logpath),
00040       init_(false)
00041 {}
00042 
00043 MemoryStore::~MemoryStore()
00044 {
00045     log_info("db closed");
00046 }
00047 
00048 int 
00049 MemoryStore::init(const StorageConfig& cfg)
00050 {
00051     if (cfg.tidy_) {
00052         tables_.clear();
00053     }
00054  
00055     init_ = true;
00056 
00057     return 0;
00058 }
00059 
00060 int
00061 MemoryStore::get_table(DurableTableImpl**  table,
00062                        const std::string&  name,
00063                        int                 flags,
00064                        PrototypeVector&    prototypes)
00065 {
00066     (void)prototypes;
00067     
00068     // XXX/bowei -- || access?
00069     TableMap::iterator iter = tables_.find(name);
00070 
00071     MemoryTable::ItemMap* items;
00072     
00073     if (iter == tables_.end()) {
00074         if (! (flags & DS_CREATE)) {
00075             return DS_NOTFOUND;
00076         }
00077         
00078         tables_[name] = MemoryTable::ItemMap();
00079         items = &tables_[name];
00080     } else {
00081         if (flags & DS_EXCL) {
00082             return DS_EXISTS;
00083         }
00084 
00085         items = &iter->second;
00086     }
00087 
00088     *table = new MemoryTable(logpath_, items, name, (flags & DS_MULTITYPE) != 0);
00089 
00090     return DS_OK;
00091 }
00092 
00093 int
00094 MemoryStore::del_table(const std::string& name)
00095 {
00096     // XXX/bowei -- busy tables?
00097     log_info("deleting table %s", name.c_str());
00098     tables_.erase(name);
00099     return 0;
00100 }
00101 
00102 int 
00103 MemoryStore::get_table_names(StringVector* names)
00104 {
00105     names->clear();
00106     for (TableMap::const_iterator itr = tables_.begin();
00107          itr != tables_.end(); ++itr)
00108     {
00109         names->push_back(itr->first);
00110     }
00111 
00112     return 0;
00113 }
00114 
00115 //----------------------------------------------------------------------------
00116 std::string 
00117 MemoryStore::get_info() const
00118 {
00119     StringBuffer desc;
00120 
00121     return "Memory";
00122 }
00123 
00124 /******************************************************************************
00125  *
00126  * MemoryTable
00127  *
00128  *****************************************************************************/
00129 MemoryTable::MemoryTable(const char* logpath, ItemMap* items,
00130                          const std::string& name, bool multitype)
00131     : DurableTableImpl(name, multitype),
00132       Logger("MemoryTable", "%s/%s", logpath, name.c_str()),
00133       items_(items)
00134 {
00135 }
00136 
00137 MemoryTable::~MemoryTable() 
00138 {
00139 }
00140 
00141 int 
00142 MemoryTable::get(const SerializableObject& key, 
00143                  SerializableObject*       data)
00144 {
00145     ASSERTF(!multitype_, "single-type get called for multi-type table");
00146     
00147     StringSerialize serialize(Serialize::CONTEXT_LOCAL,
00148                               StringSerialize::DOT_SEPARATED);
00149     if (serialize.action(&key) != 0) {
00150         PANIC("error sizing key");
00151     }
00152     std::string table_key;
00153     table_key.assign(serialize.buf().data(), serialize.buf().length());
00154 
00155     ItemMap::iterator iter = items_->find(table_key);
00156     if (iter == items_->end()) {
00157         return DS_NOTFOUND;
00158     }
00159 
00160     Item* item = iter->second;
00161     Unmarshal unm(Serialize::CONTEXT_LOCAL,
00162                   item->data_.buf(), item->data_.len());
00163 
00164     if (unm.action(data) != 0) {
00165         log_err("error unserializing data object");
00166         return DS_ERR;
00167     }
00168 
00169     return 0;
00170 }
00171 
00172 int
00173 MemoryTable::get(const SerializableObject&   key,
00174                  SerializableObject**        data,
00175                  TypeCollection::Allocator_t allocator)
00176 {
00177     ASSERTF(multitype_, "multi-type get called for single-type table");
00178     
00179     StringSerialize serialize(Serialize::CONTEXT_LOCAL,
00180                               StringSerialize::DOT_SEPARATED);
00181     if (serialize.action(&key) != 0) {
00182         PANIC("error sizing key");
00183     }
00184     std::string table_key;
00185     table_key.assign(serialize.buf().data(), serialize.buf().length());
00186 
00187     ItemMap::iterator iter = items_->find(table_key);
00188     if (iter == items_->end()) {
00189         return DS_NOTFOUND;
00190     }
00191 
00192     Item* item = iter->second;
00193     
00194     int err = allocator(item->typecode_, data);
00195     if (err != 0) {
00196         return DS_ERR;
00197     }
00198 
00199     Unmarshal unm(Serialize::CONTEXT_LOCAL,
00200                   item->data_.buf(), item->data_.len());
00201 
00202     if (unm.action(*data) != 0) {
00203         log_err("error unserializing data object");
00204         return DS_ERR;
00205     }
00206 
00207     return DS_OK;
00208 }
00209 
00210 int 
00211 MemoryTable::put(const SerializableObject& key,
00212                  TypeCollection::TypeCode_t typecode,
00213                  const SerializableObject* data,
00214                  int                       flags)
00215 {
00216     StringSerialize serialize(Serialize::CONTEXT_LOCAL,
00217                               StringSerialize::DOT_SEPARATED);
00218     if (serialize.action(&key) != 0) {
00219         PANIC("error sizing key");
00220     }
00221     std::string table_key;
00222     table_key.assign(serialize.buf().data(), serialize.buf().length());
00223 
00224     ItemMap::iterator iter = items_->find(table_key);
00225 
00226     Item* item;
00227     if (iter == items_->end()) {
00228         if (! (flags & DS_CREATE)) {
00229             return DS_NOTFOUND;
00230         }
00231 
00232         item = new Item();
00233         (*items_)[table_key] = item;
00234 
00235     } else {
00236         if (flags & DS_EXCL) {
00237             return DS_EXISTS;
00238         }
00239 
00240         item = iter->second;
00241     }
00242 
00243     item->typecode_ = typecode;
00244 
00245     { // first the key
00246         log_debug("put: serializing key");
00247     
00248         Marshal m(Serialize::CONTEXT_LOCAL, &item->key_);
00249         if (m.action(&key) != 0) {
00250             log_err("error serializing key object");
00251             return DS_ERR;
00252         }
00253     }
00254 
00255     { // then the data
00256         log_debug("put: serializing object");
00257     
00258         Marshal m(Serialize::CONTEXT_LOCAL, &item->data_);
00259         if (m.action(data) != 0) {
00260             log_err("error serializing data object");
00261             return DS_ERR;
00262         }
00263     }
00264 
00265     item->typecode_ = typecode;
00266 
00267     return DS_OK;
00268 }
00269 
00270 int 
00271 MemoryTable::del(const SerializableObject& key)
00272 { 
00273     StringSerialize serialize(Serialize::CONTEXT_LOCAL,
00274                               StringSerialize::DOT_SEPARATED);
00275     if (serialize.action(&key) != 0) {
00276         PANIC("error sizing key");
00277     }
00278     std::string table_key;
00279     table_key.assign(serialize.buf().data(), serialize.buf().length());
00280 
00281     ItemMap::iterator iter = items_->find(table_key);
00282     if (iter == items_->end()) {
00283         return DS_NOTFOUND;
00284     }
00285 
00286     Item* item = iter->second;
00287     items_->erase(iter);
00288     delete item;
00289     
00290     return DS_OK;
00291 }
00292 
00293 size_t
00294 MemoryTable::size() const
00295 {
00296     return items_->size();
00297 }
00298 
00299 DurableIterator*
00300 MemoryTable::itr()
00301 {
00302     return new MemoryIterator(logpath_, this);
00303 }
00304 
00305 
00306 /******************************************************************************
00307  *
00308  * MemoryIterator
00309  *
00310  *****************************************************************************/
00311 MemoryIterator::MemoryIterator(const char* logpath, MemoryTable* t)
00312     : Logger("MemoryIterator", "%s/iter", logpath)
00313 {
00314     table_ = t;
00315     first_ = true;
00316 }
00317 
00318 MemoryIterator::~MemoryIterator()
00319 {
00320 }
00321 
00322 int
00323 MemoryIterator::next()
00324 {
00325     if (first_) {
00326         first_ = false;
00327         iter_ = table_->items_->begin();
00328     } else {
00329         ++iter_;
00330     }
00331 
00332     if (iter_ == table_->items_->end()) {
00333         return DS_NOTFOUND;
00334     }
00335 
00336     return 0;
00337 }
00338 
00339 int
00340 MemoryIterator::get_key(SerializableObject* key)
00341 {
00342     ASSERT(key != NULL);
00343 
00344     MemoryTable::Item* item = iter_->second;
00345     
00346     oasys::Unmarshal un(oasys::Serialize::CONTEXT_LOCAL,
00347                         item->key_.buf(), item->key_.len());
00348     
00349     if (un.action(key) != 0) {
00350         log_err("error unmarshalling");
00351         return DS_ERR;
00352     }
00353     
00354     return 0;
00355 }
00356 
00357 } // namespace oasys
00358 

Generated on Sat Sep 8 08:43:30 2007 for DTN Reference Implementation by  doxygen 1.5.3