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 item = new CollItem(coll, (const Object *)v, id, st);
00222 ObjectPeer::incrRefCount((Object *)v);
00223 }
00224 else if (tlist == data_list)
00225 item = new CollItem(coll, (Data)v, id, st);
00226 else if (tlist == value_list)
00227 item = new CollItem(coll, *(Value *)v, id, st);
00228 else
00229 assert(0);
00230
00231
00232 if (!tlist[key])
00233 tlist[key] = new LinkedList();
00234
00235 tlist[key]->insertObject(item);
00236
00237
00238 key = key_id(id);
00239
00240 if (!id_list[key])
00241 id_list[key] = new LinkedList();
00242
00243 id_list[key]->insertObject(item);
00244
00245
00246 list->insertObject(item);
00247
00248 coll->unvalidReadCache();
00249 #ifdef IDB_COLLMOD_OPT1
00250 coll->touch();
00251 #endif
00252 return Success;
00253 }
00254
00255 Status CollCache::insert(const Oid& oid, Collection::ItemId id, int st)
00256 {
00257 return insert_realize((const void *)&oid, st, id, key_oid(oid), oid_list);
00258 }
00259
00260 Status CollCache::insert(const Object *o, Collection::ItemId id, int st)
00261 {
00262 return insert_realize((const void *)o, st, id, key_obj(o), obj_list);
00263 }
00264
00265 Status CollCache::insert(Data data, Collection::ItemId id, int st)
00266 {
00267 return insert_realize((const void *)data, st, id, key_data(data), data_list);
00268 }
00269
00270 Status CollCache::insert(const Value &value, Collection::ItemId id, int st)
00271 {
00272 return insert_realize((const void *)&value, st, id, key_value(value),
00273 value_list);
00274 }
00275
00276 Status
00277 CollCache::suppress(CollItem *item)
00278 {
00279 Collection::ItemId id = item->getId();
00280
00281 int key = key_id(id);
00282
00283 if (id_list[key])
00284 id_list[key]->deleteObject(item);
00285
00286 list->deleteObject(item);
00287
00288 delete item;
00289
00290 coll->unvalidReadCache();
00291 #ifdef IDB_COLLMOD_OPT1
00292 coll->touch();
00293 #endif
00294 return Success;
00295 }
00296
00297 Status CollCache::suppressOid(CollItem *item)
00298 {
00299 Oid item_oid = item->getOid();
00300
00301 unsigned int key = key_oid(item_oid);
00302
00303 if (oid_list[key])
00304 oid_list[key]->deleteObject(item);
00305
00306 return suppress(item);
00307 }
00308
00309 Status CollCache::suppressObject(CollItem *item)
00310 {
00311 const Object *item_o;
00312
00313 if (item_o = item->getObject())
00314 {
00315 int key = key_obj(item_o);
00316
00317 if (obj_list[key])
00318 obj_list[key]->deleteObject(item);
00319 }
00320
00321 return suppress(item);
00322 }
00323
00324 Status CollCache::suppressData(CollItem *item)
00325 {
00326 Data item_data = item->getData();
00327
00328 int key = key_data(item_data);
00329
00330 if (data_list[key])
00331 data_list[key]->deleteObject(item);
00332
00333 return suppress(item);
00334 }
00335
00336 Status CollCache::suppressValue(CollItem *item)
00337 {
00338 Value item_value = item->getValue();
00339
00340 int key = key_value(item_value);
00341
00342 if (value_list[key])
00343 value_list[key]->deleteObject(item);
00344
00345 return suppress(item);
00346 }
00347
00348 CollItem *CollCache::get(Collection::ItemId id)
00349 {
00350 CollItem *item;
00351 int key;
00352
00353 key = key_id(id);
00354
00355 LinkedList *l;
00356 if (l = id_list[key])
00357 {
00358 LinkedListCursor c(l);
00359
00360 while (c.getNext((void* &)item))
00361 if (item->getId() == id)
00362 return item;
00363 }
00364
00365 return 0;
00366 }
00367
00368 CollItem *CollCache::get(const Object *o)
00369 {
00370 CollItem *item;
00371 int key;
00372
00373 key = key_obj(o);
00374
00375 LinkedList *l;
00376 if (l = obj_list[key])
00377 {
00378 LinkedListCursor c(l);
00379
00380 while (c.getNext((void* &)item))
00381 if (item->getObject() == o)
00382 return item;
00383 }
00384
00385 return o->getOid().isValid() ? get(o->getOid()) : 0;
00386 }
00387
00388 CollItem *CollCache::get(const Oid& _oid)
00389 {
00390 CollItem *item;
00391 unsigned int key;
00392
00393 key = key_oid(_oid);
00394
00395 LinkedList *l;
00396 if (l = oid_list[key])
00397 {
00398 LinkedListCursor c(l);
00399
00400 while (c.getNext((void* &)item))
00401 if (item->getOid().compare(_oid))
00402 return item;
00403 }
00404
00405 return 0;
00406 }
00407
00408 CollItem *CollCache::get(Data data)
00409 {
00410 CollItem *item;
00411 int key;
00412
00413 key = key_data(data);
00414
00415 LinkedList *l;
00416 if (l = data_list[key])
00417 {
00418 LinkedListCursor c(l);
00419
00420 while (c.getNext((void* &)item))
00421 if (!memcmp(item->getData(), data, item_size))
00422 return item;
00423 }
00424
00425 return 0;
00426 }
00427
00428 CollItem *CollCache::get(const Value &value)
00429 {
00430 CollItem *item;
00431 int key;
00432
00433 key = key_value(value);
00434
00435 LinkedList *l;
00436 if (l = value_list[key])
00437 {
00438 LinkedListCursor c(l);
00439
00440 while (c.getNext((void* &)item))
00441 if (item->getValue() == value)
00442 return item;
00443 }
00444
00445 return 0;
00446 }
00447
00448 void CollCache::remove(LinkedList **l)
00449 {
00450 for (int i = 0; i < nkeys; i++)
00451 delete l[i];
00452 free(l);
00453 }
00454
00455 void CollCache::empty(Bool r)
00456 {
00457 LinkedListCursor c(list);
00458 int i;
00459 CollItem *item;
00460
00461 while (c.getNext((void* &)item)) {
00462 if (item->getObject())
00463 ((Object *)item->getObject())->release();
00464 delete item;
00465 }
00466
00467 delete list;
00468
00469 remove(id_list);
00470 remove(oid_list);
00471 remove(obj_list);
00472 remove(value_list);
00473 remove(data_list);
00474
00475 if (!r)
00476 init();
00477 }
00478
00479 CollCache::~CollCache()
00480 {
00481
00482 empty(True);
00483 }
00484 }
00485 #endif