CollCache.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 
00027 #ifndef USE_VALUE_CACHE
00028 #include "ValueCache.h"
00029 #include <assert.h>
00030 
00031 //
00032 // CollItem methods
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     void CollItem::setOid(const Oid& _oid)
00078     {
00079     oid = _oid;
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     void  CollItem::setObject(const Object *_o)
00097     {
00098     o = _o;
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     void CollItem::setData(Data _data)
00116     {
00117     data = _data;
00118     }
00119   */
00120 
00121   Data CollItem::getData() const
00122   {
00123     if (is_data)
00124       return data;
00125     return 0;
00126   }
00127 
00128   /*
00129     void CollItem::setValue(const Value &_value)
00130     {
00131     value = _value;
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   // CollCache methods
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     //printf("CollCache::CollCache(this=%p, coll=%p, mask=%x, nkeys=%d)\n", this, coll, mask, nkeys);
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     /* insert in the tlist */
00233     if (!tlist[key])
00234       tlist[key] = new LinkedList();
00235 
00236     tlist[key]->insertObject(item);
00237 
00238     /* insert in the id list */
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     /* insert in the global list */
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     //printf("CollCache::~CollCache(this=%p, coll=%p)\n", this, coll);
00484     empty(True);
00485   }
00486 }
00487 #endif

Generated on Mon Dec 22 18:15:52 2008 for eyedb by  doxygen 1.5.3