00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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
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
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
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
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 {
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 {
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
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 }
00358