MemoryStore.cc

Go to the documentation of this file.
00001 /*
00002  * IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By
00003  * downloading, copying, installing or using the software you agree to
00004  * this license. If you do not agree to this license, do not download,
00005  * install, copy or use the software.
00006  * 
00007  * Intel Open Source License 
00008  * 
00009  * Copyright (c) 2005 Intel Corporation. All rights reserved. 
00010  * 
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions are
00013  * met:
00014  * 
00015  *   Redistributions of source code must retain the above copyright
00016  *   notice, this list of conditions and the following disclaimer.
00017  * 
00018  *   Redistributions in binary form must reproduce the above copyright
00019  *   notice, this list of conditions and the following disclaimer in the
00020  *   documentation and/or other materials provided with the distribution.
00021  * 
00022  *   Neither the name of the Intel Corporation nor the names of its
00023  *   contributors may be used to endorse or promote products derived from
00024  *   this software without specific prior written permission.
00025  *  
00026  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00027  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00028  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00029  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR
00030  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00031  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00032  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00033  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00034  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00035  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00036  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037  */
00038 
00039 #include <sys/types.h>
00040 #include <errno.h>
00041 #include <unistd.h>
00042 
00043 #include <debug/DebugUtils.h>
00044 #include <util/StringBuffer.h>
00045 #include <util/Pointers.h>
00046 #include <serialize/MarshalSerialize.h>
00047 #include <serialize/TypeShims.h>
00048 
00049 #include "MemoryStore.h"
00050 #include "StorageConfig.h"
00051 
00052 namespace oasys {
00053 /******************************************************************************
00054  *
00055  * MemoryStore
00056  *
00057  *****************************************************************************/
00058 
00059 MemoryStore::MemoryStore(const char* logpath) 
00060     : DurableStoreImpl("MemoryStore", logpath),
00061       init_(false)
00062 {}
00063 
00064 MemoryStore::~MemoryStore()
00065 {
00066     log_info("db closed");
00067 }
00068 
00069 int 
00070 MemoryStore::init(const StorageConfig& cfg)
00071 {
00072     if (cfg.tidy_) {
00073         tables_.clear();
00074     }
00075  
00076     init_ = true;
00077 
00078     return 0;
00079 }
00080 
00081 int
00082 MemoryStore::get_table(DurableTableImpl**  table,
00083                        const std::string&  name,
00084                        int                 flags,
00085                        PrototypeVector&    prototypes)
00086 {
00087     (void)prototypes;
00088     
00089     // XXX/bowei -- || access?
00090     TableMap::iterator iter = tables_.find(name);
00091 
00092     MemoryTable::ItemMap* items;
00093     
00094     if (iter == tables_.end()) {
00095         if (! (flags & DS_CREATE)) {
00096             return DS_NOTFOUND;
00097         }
00098         
00099         tables_[name] = MemoryTable::ItemMap();
00100         items = &tables_[name];
00101     } else {
00102         if (flags & DS_EXCL) {
00103             return DS_EXISTS;
00104         }
00105 
00106         items = &iter->second;
00107     }
00108 
00109     *table = new MemoryTable(logpath_, items, name, (flags & DS_MULTITYPE) != 0);
00110 
00111     return DS_OK;
00112 }
00113 
00114 int
00115 MemoryStore::del_table(const std::string& name)
00116 {
00117     // XXX/bowei -- busy tables?
00118     log_info("deleting table %s", name.c_str());
00119     tables_.erase(name);
00120     return 0;
00121 }
00122 
00123 int 
00124 MemoryStore::get_table_names(StringVector* names)
00125 {
00126     names->clear();
00127     for (TableMap::const_iterator itr = tables_.begin();
00128          itr != tables_.end(); ++itr)
00129     {
00130         names->push_back(itr->first);
00131     }
00132 
00133     return 0;
00134 }
00135 
00136 /******************************************************************************
00137  *
00138  * MemoryTable
00139  *
00140  *****************************************************************************/
00141 MemoryTable::MemoryTable(const char* logpath, ItemMap* items,
00142                          const std::string& name, bool multitype)
00143     : DurableTableImpl(name, multitype),
00144       Logger("MemoryTable", "%s/%s", logpath, name.c_str()),
00145       items_(items)
00146 {
00147 }
00148 
00149 MemoryTable::~MemoryTable() 
00150 {
00151 }
00152 
00153 int 
00154 MemoryTable::get(const SerializableObject& key, 
00155                  SerializableObject*       data)
00156 {
00157     ASSERTF(!multitype_, "single-type get called for multi-type table");
00158     
00159     StringSerialize serialize(Serialize::CONTEXT_LOCAL,
00160                               Serialize::DOT_SEPARATED);
00161     if (serialize.action(&key) != 0) {
00162         PANIC("error sizing key");
00163     }
00164     std::string table_key;
00165     table_key.assign(serialize.buf().data(), serialize.buf().length());
00166 
00167     ItemMap::iterator iter = items_->find(table_key);
00168     if (iter == items_->end()) {
00169         return DS_NOTFOUND;
00170     }
00171 
00172     Item* item = iter->second;
00173     Unmarshal unm(Serialize::CONTEXT_LOCAL,
00174                   item->data_.buf(), item->data_.len());
00175 
00176     if (unm.action(data) != 0) {
00177         log_err("error unserializing data object");
00178         return DS_ERR;
00179     }
00180 
00181     return 0;
00182 }
00183 
00184 int
00185 MemoryTable::get(const SerializableObject&   key,
00186                  SerializableObject**        data,
00187                  TypeCollection::Allocator_t allocator)
00188 {
00189     ASSERTF(multitype_, "multi-type get called for single-type table");
00190     
00191     StringSerialize serialize(Serialize::CONTEXT_LOCAL,
00192                               Serialize::DOT_SEPARATED);
00193     if (serialize.action(&key) != 0) {
00194         PANIC("error sizing key");
00195     }
00196     std::string table_key;
00197     table_key.assign(serialize.buf().data(), serialize.buf().length());
00198 
00199     ItemMap::iterator iter = items_->find(table_key);
00200     if (iter == items_->end()) {
00201         return DS_NOTFOUND;
00202     }
00203 
00204     Item* item = iter->second;
00205     
00206     int err = allocator(item->typecode_, data);
00207     if (err != 0) {
00208         return DS_ERR;
00209     }
00210 
00211     Unmarshal unm(Serialize::CONTEXT_LOCAL,
00212                   item->data_.buf(), item->data_.len());
00213 
00214     if (unm.action(*data) != 0) {
00215         log_err("error unserializing data object");
00216         return DS_ERR;
00217     }
00218 
00219     return DS_OK;
00220 }
00221 
00222 int 
00223 MemoryTable::put(const SerializableObject& key,
00224                  TypeCollection::TypeCode_t typecode,
00225                  const SerializableObject* data,
00226                  int                       flags)
00227 {
00228     StringSerialize serialize(Serialize::CONTEXT_LOCAL,
00229                               Serialize::DOT_SEPARATED);
00230     if (serialize.action(&key) != 0) {
00231         PANIC("error sizing key");
00232     }
00233     std::string table_key;
00234     table_key.assign(serialize.buf().data(), serialize.buf().length());
00235 
00236     ItemMap::iterator iter = items_->find(table_key);
00237 
00238     Item* item;
00239     if (iter == items_->end()) {
00240         if (! (flags & DS_CREATE)) {
00241             return DS_NOTFOUND;
00242         }
00243 
00244         item = new Item();
00245         (*items_)[table_key] = item;
00246 
00247     } else {
00248         if (flags & DS_EXCL) {
00249             return DS_EXISTS;
00250         }
00251 
00252         item = iter->second;
00253     }
00254 
00255     item->typecode_ = typecode;
00256 
00257     { // first the key
00258         log_debug("put: serializing key");
00259     
00260         Marshal m(Serialize::CONTEXT_LOCAL, &item->key_);
00261         if (m.action(&key) != 0) {
00262             log_err("error serializing key object");
00263             return DS_ERR;
00264         }
00265     }
00266 
00267     { // then the data
00268         log_debug("put: serializing object");
00269     
00270         Marshal m(Serialize::CONTEXT_LOCAL, &item->data_);
00271         if (m.action(data) != 0) {
00272             log_err("error serializing data object");
00273             return DS_ERR;
00274         }
00275     }
00276 
00277     item->typecode_ = typecode;
00278 
00279     return DS_OK;
00280 }
00281 
00282 int 
00283 MemoryTable::del(const SerializableObject& key)
00284 { 
00285     StringSerialize serialize(Serialize::CONTEXT_LOCAL,
00286                               Serialize::DOT_SEPARATED);
00287     if (serialize.action(&key) != 0) {
00288         PANIC("error sizing key");
00289     }
00290     std::string table_key;
00291     table_key.assign(serialize.buf().data(), serialize.buf().length());
00292 
00293     ItemMap::iterator iter = items_->find(table_key);
00294     if (iter == items_->end()) {
00295         return DS_NOTFOUND;
00296     }
00297 
00298     Item* item = iter->second;
00299     items_->erase(iter);
00300     delete item;
00301     
00302     return DS_OK;
00303 }
00304 
00305 size_t
00306 MemoryTable::size() const
00307 {
00308     return items_->size();
00309 }
00310 
00311 DurableIterator*
00312 MemoryTable::itr()
00313 {
00314     return new MemoryIterator(logpath_, this);
00315 }
00316 
00317 
00318 /******************************************************************************
00319  *
00320  * MemoryIterator
00321  *
00322  *****************************************************************************/
00323 MemoryIterator::MemoryIterator(const char* logpath, MemoryTable* t)
00324     : Logger("MemoryIterator", "%s/iter", logpath)
00325 {
00326     table_ = t;
00327     first_ = true;
00328 }
00329 
00330 MemoryIterator::~MemoryIterator()
00331 {
00332 }
00333 
00334 int
00335 MemoryIterator::next()
00336 {
00337     if (first_) {
00338         first_ = false;
00339         iter_ = table_->items_->begin();
00340     } else {
00341         ++iter_;
00342     }
00343 
00344     if (iter_ == table_->items_->end()) {
00345         return DS_NOTFOUND;
00346     }
00347 
00348     return 0;
00349 }
00350 
00351 int
00352 MemoryIterator::get_key(SerializableObject* key)
00353 {
00354     ASSERT(key != NULL);
00355 
00356     MemoryTable::Item* item = iter_->second;
00357     
00358     oasys::Unmarshal un(oasys::Serialize::CONTEXT_LOCAL,
00359                         item->key_.buf(), item->key_.len());
00360     
00361     if (un.action(key) != 0) {
00362         log_err("error unmarshalling");
00363         return DS_ERR;
00364     }
00365     
00366     return 0;
00367 }
00368 
00369 } // namespace oasys
00370 

Generated on Fri Dec 22 14:47:59 2006 for DTN Reference Implementation by  doxygen 1.5.1