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
00027 #ifndef USE_VALUE_CACHE
00028 #include "ValueCache.h"
00029 #include <assert.h>
00030
00031
00032
00033
00034
00035 namespace eyedb {
00036
00037 void CollItem::init(Collection *_coll, Collection::ItemId _id, int _st)
00038 {
00039 id = _id;
00040 state = _st;
00041 coll = _coll;
00042
00043 data = (Data)0;
00044 o = NULL;
00045 is_oid = is_object = is_value = is_data = False;
00046 }
00047
00048 CollItem::CollItem(Collection *_coll, const Oid& _oid, Collection::ItemId _id, int _st)
00049 {
00050 init(_coll, _id, _st);
00051 oid = _oid;
00052 is_oid = True;
00053 }
00054
00055 CollItem::CollItem(Collection *_coll, const Object *_o, Collection::ItemId _id, int _st)
00056 {
00057 init(_coll, _id, _st);
00058 o = _o;
00059 is_object = True;
00060 }
00061
00062 CollItem::CollItem(Collection *_coll, const Value &_value, Collection::ItemId _id, int _st)
00063 {
00064 init(_coll, _id, _st);
00065 value = _value;
00066 is_value = True;
00067 }
00068
00069 CollItem::CollItem(Collection *_coll, Data _data, Collection::ItemId _id, int _st)
00070 {
00071 init(_coll, _id, _st);
00072 data = _data;
00073 is_data = True;
00074 }
00075
00076
00077
00078
00079
00080
00081
00082
00083 const Oid& CollItem::getOid() const
00084 {
00085 if (is_oid)
00086 return oid;
00087 if (is_object)
00088 return o ? o->getOid() : Oid::nullOid;
00089 if (is_value)
00090 return value.oid ? *value.oid : Oid::nullOid;
00091
00092 return Oid::nullOid;
00093 }
00094
00095
00096
00097
00098
00099
00100
00101
00102 const Object *CollItem::getObject() const
00103 {
00104 if (is_object)
00105 return o;
00106 if (is_oid)
00107 return 0;
00108 if (is_value)
00109 return value.o;
00110
00111 return 0;
00112 }
00113
00114
00115
00116
00117
00118
00119
00120
00121 Data CollItem::getData() const
00122 {
00123 if (is_data)
00124 return data;
00125 return 0;
00126 }
00127
00128
00129
00130
00131
00132
00133
00134
00135 const Value &CollItem::getValue() const
00136 {
00137 if (is_oid)
00138 const_cast<CollItem *>(this)->value = Value(oid);
00139 else if (is_object)
00140 const_cast<CollItem *>(this)->value = Value(o);
00141
00142 return value;
00143 }
00144
00145 void
00146 CollItem::setState(int _state)
00147 {
00148 if (state == _state)
00149 return;
00150
00151 coll->unvalidReadCache();
00152 #ifdef IDB_COLLMOD_OPT1
00153 coll->touch();
00154 #endif
00155 state = _state;
00156 }
00157
00158
00159
00160
00161
00162 void CollCache::init()
00163 {
00164 list = new LinkedList();
00165
00166 oid_list = (LinkedList **)calloc(nkeys * sizeof(LinkedList *), 1);
00167 id_list = (LinkedList **)calloc(nkeys * sizeof(LinkedList *), 1);
00168 obj_list = (LinkedList **)calloc(nkeys * sizeof(LinkedList *), 1);
00169 data_list = (LinkedList **)calloc(nkeys * sizeof(LinkedList *), 1);
00170 value_list = (LinkedList **)calloc(nkeys * sizeof(LinkedList *), 1);
00171
00172 nitems = 0;
00173 }
00174
00175 void
00176 CollCache::setColl(Collection *_coll)
00177 {
00178 coll = _coll;
00179 CollItem *item;
00180 LinkedListCursor c(list);
00181 while (c.getNext((void *&)item))
00182 item->setColl(_coll);
00183 }
00184
00185 CollCache::CollCache(Collection *_coll, unsigned int magorder,
00186 Size isz, unsigned int max)
00187 {
00188 mask = 2;
00189 unsigned int h1 = magorder / 128;
00190 if (h1 > 512) h1 = 512;
00191 for (;;) {
00192 if (mask >= h1)
00193 break;
00194 mask <<= 1;
00195 }
00196
00197 nkeys = mask--;
00198
00199 item_size = isz;
00200 max_items = max;
00201 init();
00202 coll = _coll;
00203
00204 }
00205
00206 LinkedList *CollCache::getList()
00207 {
00208 return list;
00209 }
00210
00211 Status CollCache::insert_realize(const void *v, int st,
00212 Collection::ItemId id,
00213 unsigned int key,
00214 LinkedList **tlist)
00215 {
00216 CollItem *item;
00217
00218 if (tlist == oid_list)
00219 item = new CollItem(coll, *(Oid *)v, id, st);
00220 else if (tlist == obj_list)
00221 {
00222 item = new CollItem(coll, (const Object *)v, id, st);
00223 ObjectPeer::incrRefCount((Object *)v);
00224 }
00225 else if (tlist == data_list)
00226 item = new CollItem(coll, (Data)v, id, st);
00227 else if (tlist == value_list)
00228 item = new CollItem(coll, *(Value *)v, id, st);
00229 else
00230 assert(0);
00231
00232
00233 if (!tlist[key])
00234 tlist[key] = new LinkedList();
00235
00236 tlist[key]->insertObject(item);
00237
00238
00239 key = key_id(id);
00240
00241 if (!id_list[key])
00242 id_list[key] = new LinkedList();
00243
00244 id_list[key]->insertObject(item);
00245
00246
00247 list->insertObject(item);
00248
00249 coll->unvalidReadCache();
00250 #ifdef IDB_COLLMOD_OPT1
00251 coll->touch();
00252 #endif
00253 return Success;
00254 }
00255
00256 Status CollCache::insert(const Oid& oid, Collection::ItemId id, int st)
00257 {
00258 return insert_realize((const void *)&oid, st, id, key_oid(oid), oid_list);
00259 }
00260
00261 Status CollCache::insert(const Object *o, Collection::ItemId id, int st)
00262 {
00263 return insert_realize((const void *)o, st, id, key_obj(o), obj_list);
00264 }
00265
00266 Status CollCache::insert(Data data, Collection::ItemId id, int st)
00267 {
00268 return insert_realize((const void *)data, st, id, key_data(data), data_list);
00269 }
00270
00271 Status CollCache::insert(const Value &value, Collection::ItemId id, int st)
00272 {
00273 return insert_realize((const void *)&value, st, id, key_value(value),
00274 value_list);
00275 }
00276
00277 Status
00278 CollCache::suppress(CollItem *item)
00279 {
00280 Collection::ItemId id = item->getId();
00281
00282 int key = key_id(id);
00283
00284 if (id_list[key])
00285 id_list[key]->deleteObject(item);
00286
00287 list->deleteObject(item);
00288
00289 delete item;
00290
00291 coll->unvalidReadCache();
00292 #ifdef IDB_COLLMOD_OPT1
00293 coll->touch();
00294 #endif
00295 return Success;
00296 }
00297
00298 Status CollCache::suppressOid(CollItem *item)
00299 {
00300 Oid item_oid = item->getOid();
00301
00302 unsigned int key = key_oid(item_oid);
00303
00304 if (oid_list[key])
00305 oid_list[key]->deleteObject(item);
00306
00307 return suppress(item);
00308 }
00309
00310 Status CollCache::suppressObject(CollItem *item)
00311 {
00312 const Object *item_o;
00313
00314 if (item_o = item->getObject())
00315 {
00316 int key = key_obj(item_o);
00317
00318 if (obj_list[key])
00319 obj_list[key]->deleteObject(item);
00320 }
00321
00322 return suppress(item);
00323 }
00324
00325 Status CollCache::suppressData(CollItem *item)
00326 {
00327 Data item_data = item->getData();
00328
00329 int key = key_data(item_data);
00330
00331 if (data_list[key])
00332 data_list[key]->deleteObject(item);
00333
00334 return suppress(item);
00335 }
00336
00337 Status CollCache::suppressValue(CollItem *item)
00338 {
00339 Value item_value = item->getValue();
00340
00341 int key = key_value(item_value);
00342
00343 if (value_list[key])
00344 value_list[key]->deleteObject(item);
00345
00346 return suppress(item);
00347 }
00348
00349 CollItem *CollCache::get(Collection::ItemId id)
00350 {
00351 CollItem *item;
00352 int key;
00353
00354 key = key_id(id);
00355
00356 LinkedList *l;
00357 if (l = id_list[key])
00358 {
00359 LinkedListCursor c(l);
00360
00361 while (c.getNext((void* &)item))
00362 if (item->getId() == id)
00363 return item;
00364 }
00365
00366 return 0;
00367 }
00368
00369 CollItem *CollCache::get(const Object *o)
00370 {
00371 CollItem *item;
00372 int key;
00373
00374 key = key_obj(o);
00375
00376 LinkedList *l;
00377 if (l = obj_list[key])
00378 {
00379 LinkedListCursor c(l);
00380
00381 while (c.getNext((void* &)item))
00382 if (item->getObject() == o)
00383 return item;
00384 }
00385
00386 return o->getOid().isValid() ? get(o->getOid()) : 0;
00387 }
00388
00389 CollItem *CollCache::get(const Oid& _oid)
00390 {
00391 CollItem *item;
00392 unsigned int key;
00393
00394 key = key_oid(_oid);
00395
00396 LinkedList *l;
00397 if (l = oid_list[key])
00398 {
00399 LinkedListCursor c(l);
00400
00401 while (c.getNext((void* &)item))
00402 if (item->getOid().compare(_oid))
00403 return item;
00404 }
00405
00406 return 0;
00407 }
00408
00409 CollItem *CollCache::get(Data data)
00410 {
00411 CollItem *item;
00412 int key;
00413
00414 key = key_data(data);
00415
00416 LinkedList *l;
00417 if (l = data_list[key])
00418 {
00419 LinkedListCursor c(l);
00420
00421 while (c.getNext((void* &)item))
00422 if (!memcmp(item->getData(), data, item_size))
00423 return item;
00424 }
00425
00426 return 0;
00427 }
00428
00429 CollItem *CollCache::get(const Value &value)
00430 {
00431 CollItem *item;
00432 int key;
00433
00434 key = key_value(value);
00435
00436 LinkedList *l;
00437 if (l = value_list[key])
00438 {
00439 LinkedListCursor c(l);
00440
00441 while (c.getNext((void* &)item))
00442 if (item->getValue() == value)
00443 return item;
00444 }
00445
00446 return 0;
00447 }
00448
00449 void CollCache::remove(LinkedList **l)
00450 {
00451 for (int i = 0; i < nkeys; i++)
00452 delete l[i];
00453 free(l);
00454 }
00455
00456 void CollCache::empty(Bool r)
00457 {
00458 LinkedListCursor c(list);
00459 int i;
00460 CollItem *item;
00461
00462 while (c.getNext((void* &)item))
00463 {
00464 if (item->getObject())
00465 ((Object *)item->getObject())->release();
00466 delete item;
00467 }
00468
00469 delete list;
00470
00471 remove(id_list);
00472 remove(oid_list);
00473 remove(obj_list);
00474 remove(value_list);
00475 remove(data_list);
00476
00477 if (!r)
00478 init();
00479 }
00480
00481 CollCache::~CollCache()
00482 {
00483
00484 empty(True);
00485 }
00486 }
00487 #endif