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 #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
00041 ObjectPeer::incrRefCount(v.o);
00042 }
00043 }
00044
00045 void ValueItem::release()
00046 {
00047 if (!--refcnt) {
00048 if (v.type == Value::tObject) {
00049
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
00181
00182
00183
00184
00185
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
00211
00212
00213
00214
00215
00216
00217
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 }