00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
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
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
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
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
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 {
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 {
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
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 }
00370