ValueCache.cc

00001 /* 
00002    EyeDB Object Database Management System
00003    Copyright (C) 1994-2008 SYSRA
00004    
00005    EyeDB is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009    
00010    EyeDB is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014    
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with this library; if not, write to the Free Software
00017    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA 
00018 */
00019 
00020 /*
00021    Author: Eric Viara <viara@sysra.com>
00022 */
00023 
00024 
00025 #include "eyedb_p.h"
00026 #include "ValueCache.h"
00027 #include <assert.h>
00028 #include <iostream>
00029 
00030 namespace eyedb {
00031 
00032   Collection::ItemId ValueCache::DefaultItemID = ~0;
00033 
00034   ValueItem::ValueItem(Object *o, const Value &v,
00035                        Collection::ItemId id, int state) :
00036     o(o), state(state), v(v), id(id), refcnt(1)
00037   {
00038 
00039     if (v.type == Value::tObject) {
00040       //printf("construct: refcnt: %p=%d\n", v.o, v.o->getRefCount());
00041       ObjectPeer::incrRefCount(v.o);
00042     }
00043   }
00044 
00045   void ValueItem::release()
00046   {
00047     if (!--refcnt) {
00048       if (v.type == Value::tObject) {
00049         //printf("release: refcnt: %p=%d\n", v.o, v.o->getRefCount());
00050         v.o->release();
00051       }
00052       delete this;
00053     }
00054   }
00055 
00056   void ValueItem::setState(int _state)
00057   {
00058     printf("setting state %d of %s\n", _state, v.getString());
00059     if (state == _state)
00060       return;
00061 
00062     state = _state;
00063 
00064     if (o->asCollection())
00065       o->asCollection()->unvalidReadCache();
00066 
00067     o->touch();
00068   }
00069 
00070   ValueItem::~ValueItem()
00071   {
00072   }
00073 
00074   ValueCache::ValueCache(Object *o) : o(o) 
00075   {
00076     current_id = 0;
00077   }
00078 
00079   Status
00080   ValueCache::insert(const Value &v, Collection::ItemId id, int state) 
00081   {
00082     if (id == DefaultItemID)
00083       id = current_id++;
00084 
00085     ValueItem *item = new ValueItem(o, v, id, state);
00086     item->incRef();
00087 
00088     if (val_map.find(v) != val_map.end())
00089       val_map[v]->release();
00090 
00091     val_map[v] = item;
00092 
00093     if (id_map.find(id) != id_map.end())
00094       id_map[id]->release();
00095 
00096     id_map[id] = item;
00097 
00098     if (o->asCollection())
00099       o->asCollection()->unvalidReadCache();
00100 
00101     o->touch();
00102     return Success;
00103   }
00104 
00105   Status ValueCache::suppress(ValueItem *item)
00106   {
00107     if (val_map.find(item->getValue()) != val_map.end()) {
00108       val_map[item->getValue()]->release();
00109       val_map.erase(val_map.find(item->getValue()));
00110     }
00111     else
00112       assert(0);
00113 
00114     if (id_map.find(item->getId()) != id_map.end()) {
00115       id_map[item->getId()]->release();
00116       id_map.erase(id_map.find(item->getId()));
00117     }
00118     else
00119       assert(0);
00120       
00121     if (o->asCollection())
00122       o->asCollection()->unvalidReadCache();
00123 
00124     o->touch();
00125     return Success;
00126   }
00127 
00128   ValueItem *ValueCache::get(Collection::ItemId id)
00129   {
00130     if (id_map.find(id) != id_map.end())
00131       return id_map[id];
00132     return 0;
00133   }
00134 
00135   ValueItem *ValueCache::get(const Value &v)
00136   {
00137     if (val_map.find(v) != val_map.end())
00138       return val_map[v];
00139     return 0;
00140   }
00141 
00142   void ValueCache::empty()
00143   {
00144     std::map<Value, ValueItem *>::iterator val_begin = val_map.begin();
00145     std::map<Value, ValueItem *>::iterator val_end = val_map.end();
00146 
00147     std::map<Value, ValueItem *>::iterator val_i = val_begin;
00148 
00149     while (val_i != val_end) {
00150       if ((*val_i).second)
00151         (*val_i).second->release();
00152       ++val_i;
00153     }
00154 
00155     val_map.erase(val_begin, val_end);
00156 
00157     std::map<Collection::ItemId, ValueItem *>::iterator id_begin = id_map.begin();
00158     std::map<Collection::ItemId, ValueItem *>::iterator id_end = id_map.end();
00159 
00160     std::map<Collection::ItemId, ValueItem *>::iterator id_i = id_begin;
00161 
00162     while (id_i != id_end) {
00163       if ((*id_i).second)
00164         (*id_i).second->release();
00165       ++id_i;
00166     }
00167 
00168     id_map.erase(id_begin, id_end);
00169   }
00170 
00171   ValueCache::~ValueCache()
00172   {
00173     empty();
00174   }
00175 
00176   Status
00177   ValueCache::setState(int state)
00178   {
00179     /*
00180     std::map<Value, ValueItem *>::iterator val_begin = val_map.begin();
00181     std::map<Value, ValueItem *>::iterator val_end = val_map.end();
00182 
00183     while (val_begin != val_end) {
00184       (*val_begin).second->setState(state);
00185       ++val_begin;
00186     }
00187     */
00188 
00189     std::map<Collection::ItemId, ValueItem *>::iterator id_begin = id_map.begin();
00190     std::map<Collection::ItemId, ValueItem *>::iterator id_end = id_map.end();
00191 
00192     while (id_begin != id_end) {
00193       if (state == Collection::removed &&
00194           (*id_begin).second->getState() == Collection::added) {
00195         id_map.erase(id_begin);
00196       }
00197       else
00198         (*id_begin).second->setState(state);
00199       ++id_begin;
00200     }
00201 
00202     return Success;
00203   }
00204 
00205   void
00206   ValueCache::trace()
00207   {
00208     std::cout << "ValueMap (" << val_map.size() << "):\n";
00209     /*
00210     std::map<Value, ValueItem *>::iterator val_begin = val_map.begin();
00211     std::map<Value, ValueItem *>::iterator val_end = val_map.end();
00212 
00213     while (val_begin != val_end) {
00214       std::cout << (*val_begin).second->getValue()
00215                 << " (" << (*val_begin).second->getState()
00216                 << ")\n";
00217       ++val_begin;
00218     }
00219     */
00220 
00221     std::map<Collection::ItemId, ValueItem *>::iterator id_begin = id_map.begin();
00222     std::map<Collection::ItemId, ValueItem *>::iterator id_end = id_map.end();
00223 
00224     std::cout << "IdMap (" << id_map.size() << "):\n";
00225     while (id_begin != id_end) {
00226       std::cout << "[" << (*id_begin).first << "] "
00227                 << (*id_begin).second->getValue()
00228                 << " {state=" << (*id_begin).second->getState()
00229                 << "}\n";
00230       ++id_begin;
00231     }
00232   }
00233 
00234   ValueItem *ValueCache::get(Data data, Size item_size)
00235   {
00236     return get(Value(data, item_size));
00237   }
00238 }

Generated on Mon Dec 22 18:16:14 2008 for eyedb by  doxygen 1.5.3