CollectionBE.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 "CollectionBE.h"
00027 #include "OQLBE.h"
00028 #include "BEQueue.h"
00029 #include "kernel.h"
00030 
00031 #include "Attribute_p.h"
00032 
00033 #define COLLBE_BTREE
00034 
00035 namespace eyedb {
00036 
00037   CollectionBE::CollectionBE(Database *_db, DbHandle *_dbh,
00038                              const Oid *_oid,
00039                              Class *_class,
00040                              const Oid& _idx1_oid,
00041                              const Oid& _idx2_oid,
00042                              eyedbsm::Idx *_idx1, eyedbsm::Idx *_idx2,
00043                              int _items_cnt, Bool _locked,
00044                              const Oid& _inv_oid,
00045                              eyedblib::int16 _inv_num_item,
00046                              IndexImpl *_idximpl,
00047                              Data idx_data, Size idx_data_size,
00048                              Bool _is_literal,
00049                              Bool _is_pure_literal) :
00050     cls(_class),
00051     db(_db), dbh(_dbh), oid(*_oid),
00052     idx1_oid(_idx1_oid),
00053     idx2_oid(_idx2_oid), idx1(_idx1), idx2(_idx2),
00054     items_cnt(_items_cnt), locked(_locked),
00055     inv_oid(_inv_oid),
00056     inv_num_item(_inv_num_item),
00057     inv_item(NULL),
00058     idximpl(_idximpl),
00059     is_literal(_is_literal),
00060     is_pure_literal(_is_pure_literal),
00061     inv_item_done(False)
00062   {
00063     status = Success;
00064     if (!cls) {
00065       isref = True;
00066       dim = 1;
00067       item_size = sizeof(eyedbsm::Oid);
00068     }
00069     else
00070       coll_class = cls->asCollectionClass()->getCollClass(&isref, &dim,
00071                                                           &item_size);
00072 
00073     buff = (unsigned char *)malloc(item_size);
00074     idx_ctx = new AttrIdxContext(idx_data, idx_data_size);
00075     /*
00076       printf("CollectionBE_1(size=%d, %s, %s, inv_oid=%s, is_literal=%d)\n",
00077       idx_data_size, _oid->toString(), (const char *)idx_ctx->getString(),
00078       inv_oid.toString(), is_literal);
00079     */
00080 
00081     type = (IteratorAtomType)0;
00082 
00083     if (is_pure_literal) {
00084       assert(inv_oid.isValid());
00085       assert(idx_data_size);
00086     }
00087   }
00088 
00089   CollectionBE::CollectionBE(Database *_db, DbHandle *_dbh,
00090                              const Oid *_oid,
00091                              Bool _locked) :
00092     db(_db), dbh(_dbh), oid(*_oid), locked(_locked), inv_item(NULL), inv_item_done(False)
00093   {
00094     // must load collection and open index!!
00095     static const int _size = IDB_COLL_SIZE_HEAD + sizeof(char) + sizeof(eyedblib::int16);
00096     unsigned char temp[_size];
00097 
00098     buff = 0;
00099     idx_ctx = 0;
00100     idx1 = idx2 = 0;
00101     RPCStatus rpc_status = dataRead(db->getDbHandle(), 0, _size,
00102                                         temp, 0, oid.getOid());
00103     status = StatusMake(rpc_status);
00104     if (status)
00105       return;
00106 
00107     Offset offset;
00108 
00109     eyedbsm::Oid oid_cl = ClassOidDecode(temp);
00110     cls = db->getSchema()->getClass(oid_cl);
00111     if (!cls) {
00112       isref = True;
00113       dim = 1;
00114       item_size = sizeof(eyedbsm::Oid);
00115     }
00116     else
00117       coll_class = ((CollectionClass *)cls)->getCollClass(&isref, &dim, &item_size);
00118 
00119     offset = IDB_COLL_OFF_ITEMS_CNT;
00120     int32_decode(temp, &offset, &items_cnt);
00121   
00122     offset = IDB_COLL_OFF_IDX1_OID;
00123     oid_decode(temp, &offset, idx1_oid.getOid());
00124 
00125     offset = IDB_COLL_OFF_IDX2_OID;
00126     oid_decode(temp, &offset, idx2_oid.getOid());
00127   
00128     offset = IDB_COLL_OFF_INV_OID;
00129     eyedbsm::Oid se_inv_oid;
00130     oid_decode(temp, &offset, &se_inv_oid);
00131     inv_oid.setOid(se_inv_oid);
00132     int16_decode(temp, &offset, &inv_num_item);
00133   
00134     is_literal = False;
00135     is_pure_literal = False;
00136     if (db->getVersionNumber() >= 20414) {
00137       offset = IDB_COLL_OFF_COLL_NAME;
00138       char x;
00139       char_decode(temp, &offset, &x);
00140       Collection::decodeLiteral(x, is_literal, is_pure_literal);
00141       //is_literal = IDBBOOL(x);
00142       eyedblib::int16 idx_data_size;
00143       int16_decode(temp, &offset, &idx_data_size);
00144       assert(offset == sizeof(temp));
00145 
00146       if (is_pure_literal) {
00147         assert(inv_oid.isValid());
00148         assert(idx_data_size);
00149       }
00150 
00151       if (idx_data_size) {
00152         unsigned char *x = (unsigned char*)malloc(idx_data_size);
00153         rpc_status = dataRead(db->getDbHandle(), _size, idx_data_size,
00154                                   x, 0, oid.getOid());
00155         status = StatusMake(rpc_status);
00156         if (status)
00157           return;
00158 
00159         idx_ctx = new AttrIdxContext(x, idx_data_size);
00160         free(x);
00161         /*  printf("CollectionBE_2(%s, %s)\n",
00162             _oid->toString(), (const char *)idx_ctx->getString());
00163         */
00164       }
00165     }
00166 
00167     /*
00168       printf("inv_oid for collection %s is %s [is_literal = %d]\n",
00169       inv_oid.toString(), _oid->toString(), is_literal);
00170     */
00171 
00172     offset = IDB_COLL_OFF_IMPL_BEGIN;
00173     IndexImpl::decode(db, temp, offset, idximpl);
00174     /*
00175       int mag_order;
00176       offset = IDB_COLL_OFF_MAG_ORDER;
00177       int32_decode (temp, &offset, &mag_order);
00178 
00179       // NCOLLIMPL: should be taken from IDB_COLL_OFF_IMPL
00180       is_bidx = IDB_IS_COLL_BIDX(mag_order);
00181     */
00182 
00183     if (isBIdx())
00184       idx1 = new eyedbsm::BIdx
00185         (get_eyedbsm_DbHandle((DbHandle *)db->getDbHandle()->u.dbh),
00186          *idx1_oid.getOid());
00187     else
00188       idx1 = new eyedbsm::HIdx
00189         (get_eyedbsm_DbHandle((DbHandle *)db->getDbHandle()->u.dbh),
00190          idx1_oid.getOid(), 0, 0);
00191 
00192     static const char fmt_error[] = "storage manager error '%s' reported when opening index in back end collection";
00193 
00194     if (idx1->status())
00195       {
00196         status = Exception::make(IDB_COLLECTION_BACK_END_ERROR, fmt_error, eyedbsm::statusGet(idx1->status()));
00197         delete idx1;
00198         idx1 = 0;
00199         idx2 = 0;
00200         return;
00201       }
00202 
00203     if (idx2_oid.isValid()) {
00204 #ifdef COLLBE_BTREE
00205       if (1) 
00206 #else
00207       if (isBIdx())
00208 #endif
00209         idx2 = new eyedbsm::BIdx
00210           (get_eyedbsm_DbHandle((DbHandle *)db->getDbHandle()->u.dbh),
00211            *idx2_oid.getOid());
00212       else
00213         idx2 = new eyedbsm::HIdx
00214           (get_eyedbsm_DbHandle((DbHandle *)db->getDbHandle()->u.dbh),
00215            idx2_oid.getOid(), 0, 0);
00216       
00217       if (idx2->status()) {
00218         status = Exception::make(IDB_COLLECTION_BACK_END_ERROR, fmt_error, eyedbsm::statusGet(idx2->status()));
00219         delete idx1;
00220         delete idx2;
00221         idx1 = 0;
00222         idx2 = 0;
00223         return;
00224       }
00225     }
00226     else
00227       idx2 = 0;
00228 
00229     status = Success;
00230     type = (IteratorAtomType)0;
00231     buff = (unsigned char *)malloc(item_size);
00232   }
00233 
00234   
00235   IteratorAtomType
00236   CollectionBE::getType()
00237   {
00238     if (type)
00239       return type;
00240 
00241     if (isref && dim == 1)
00242       return IteratorAtom_OID;
00243 
00244     if (!cls)
00245       return IteratorAtom_IDR;
00246 
00247     const char *name = cls->asCollectionClass()->getCollClass()->getName();
00248 
00249     if (!strcmp(name, char_class_name) && dim > 1)
00250       return IteratorAtom_STRING;
00251 
00252     assert(dim == 1);
00253 
00254     if (!strcmp(name, char_class_name))
00255       return IteratorAtom_CHAR;
00256 
00257     if (!strcmp(name, int16_class_name))
00258       return IteratorAtom_INT16;
00259 
00260     if (!strcmp(name, int32_class_name))
00261       return IteratorAtom_INT32;
00262 
00263     if (!strcmp(name, int64_class_name))
00264       return IteratorAtom_INT64;
00265 
00266     if (!strcmp(name, float_class_name))
00267       return IteratorAtom_DOUBLE;
00268 
00269     return IteratorAtom_IDR;
00270   }
00271 
00272   void
00273   CollectionBE::decode(const void* k, IteratorAtom &atom)
00274   {
00275     type = getType();
00276 
00277     atom.type = type;
00278 
00279     Offset offset = 0;
00280 
00281     if (type == IteratorAtom_OID)
00282       oid_decode((Data)k, &offset, &atom.oid);
00283 
00284     else if (type == IteratorAtom_INT16)
00285       int16_decode((Data)k, &offset, &atom.i16);
00286 
00287     else if (type == IteratorAtom_INT32)
00288       int32_decode((Data)k, &offset, &atom.i32);
00289 
00290     else if (type == IteratorAtom_INT64)
00291       int64_decode((Data)k, &offset, &atom.i64);
00292 
00293     else if (type == IteratorAtom_DOUBLE)
00294       double_decode((Data)k, &offset, &atom.d);
00295 
00296     else if (type == IteratorAtom_CHAR)
00297       memcpy(&atom.c, k, item_size);
00298 
00299     else if (type == IteratorAtom_STRING)
00300       atom.str = strdup((char *)k);
00301 
00302     else if (type == IteratorAtom_IDR) {
00303       atom.data.size = item_size;
00304       atom.data.idr = (unsigned char *)malloc(item_size);
00305       memcpy(atom.data.idr, k, item_size);
00306     }
00307 
00308     else
00309       assert(0);
00310   }
00311 
00312   void
00313   CollectionBE::decode(const void* k, Data idr)
00314   {
00315     IteratorAtom atom;
00316     decode(k, atom);
00317 
00318     if (type == IteratorAtom_OID)
00319       memcpy(idr, &atom.oid, item_size);
00320 
00321     else if (type == IteratorAtom_INT16)
00322       memcpy(idr, &atom.i16, item_size);
00323 
00324     else if (type == IteratorAtom_INT32)
00325       memcpy(idr, &atom.i32, item_size);
00326 
00327     else if (type == IteratorAtom_INT64)
00328       memcpy(idr, &atom.i64, item_size);
00329 
00330     else if (type == IteratorAtom_DOUBLE)
00331       memcpy(idr, &atom.d, item_size);
00332 
00333     else if (type == IteratorAtom_CHAR)
00334       memcpy(idr, &atom.c, item_size);
00335 
00336     else if (type == IteratorAtom_STRING)
00337       memcpy(idr, atom.str, item_size);
00338 
00339     else if (type == IteratorAtom_IDR)
00340       memcpy(idr, atom.data.idr, item_size);
00341 
00342     else
00343       assert(0);
00344   }
00345 
00346   Status
00347   CollectionBE::getInvItem(Database *_db,
00348                            const Attribute *&_inv_item,
00349                            Oid& _inv_oid, eyedbsm::Idx *&se_idx) const
00350   {
00351     _inv_oid = inv_oid;
00352 
00353     if (!inv_oid.isValid()) {
00354       _inv_item = 0;
00355       assert(!is_pure_literal);
00356       return Success;
00357     }
00358   
00359     Index *idx = 0;
00360     Status s;
00361     if (inv_item_done) {
00362       _inv_item = inv_item;
00363       if (inv_item && idx_ctx) {
00364         s = const_cast<Attribute *>(inv_item)->indexPrologue(db, *idx_ctx, idx, True);
00365         if (s) return s;
00366       }
00367     
00368       se_idx = (idx ? idx->idx : 0);
00369       return Success;
00370     }
00371 
00372     // 31/08/05 : for class removal
00373     Oid inv_cls_oid;
00374     //printf("inv_oid %s\n", inv_oid.getString());
00375     if (s = _db->getObjectClass(inv_oid, inv_cls_oid))
00376       return s;
00377 
00378     Bool removed;
00379     if (s = _db->isRemoved(inv_cls_oid, removed)) 
00380       return s;
00381 
00382     if (removed) {
00383       const_cast<CollectionBE *>(this)->inv_item = 0;
00384       const_cast<CollectionBE *>(this)->inv_item_done = True;
00385       _inv_item = inv_item;
00386       se_idx = 0;
00387       return Success;
00388     }
00389     // ...
00390 
00391     Class *inv_class;
00392 
00393     if (s = _db->getObjectClass(inv_oid, inv_class))
00394       return s;
00395 
00396     const_cast<CollectionBE *>(this)->inv_item =
00397       (idx_ctx && idx_ctx->getClassOwner() ? idx_ctx->getAttribute(inv_class) :
00398        inv_class->getAttributes()[inv_num_item]);
00399 
00400     const_cast<CollectionBE *>(this)->inv_item_done = True;
00401     assert(inv_item);
00402 
00403     _inv_item = inv_item;
00404 
00405     if (idx_ctx) {
00406       s = const_cast<Attribute *>(inv_item)->indexPrologue(db, *idx_ctx, idx, True);
00407       if (s) return s;
00408     }
00409 
00410     se_idx = (idx ? idx->idx : 0);
00411 
00412     return Success;
00413   }
00414 
00415   CollectionBE::~CollectionBE()
00416   {
00417     //printf("removing collbe: %p %d\n", this, locked);
00418     db->getBEQueue()->removeCollection(this, dbh);
00419     if (idximpl)
00420       idximpl->release();
00421     idximpl = 0;
00422     free(buff);
00423     delete idx1;
00424     delete idx2;
00425     delete idx_ctx;
00426     idx1 = idx2 = 0;
00427     idx_ctx = 0;
00428   }
00429 
00430   Class *CollectionBE::getClass(Bool &_isref,
00431                                 int &_dim,
00432                                 eyedblib::int16 &_item_size) const
00433   {
00434     _isref = isref;
00435     _dim = dim;
00436     _item_size = item_size;
00437     return cls;
00438   }
00439 
00440   void CollectionBE::getIdx(eyedbsm::Idx **ridx1, eyedbsm::Idx **ridx2)
00441   {
00442     if (ridx1)
00443       *ridx1 = idx1;
00444     if (ridx2)
00445       *ridx2 = idx2;
00446   }
00447 
00448   Data CollectionBE::getTempBuff()
00449   {
00450     return buff;
00451   }
00452 
00453   eyedblib::int16 CollectionBE::getItemSize() const
00454   {
00455     return item_size;
00456   }
00457 
00458   Bool CollectionBE::getIsRef() const
00459   {
00460     return isref;
00461   }
00462 
00463   const Oid& CollectionBE::getOid() const
00464   {
00465     return oid;
00466   }
00467 
00468   Database *CollectionBE::getDatabase()
00469   {
00470     return db;
00471   }
00472 
00473   DbHandle *CollectionBE::getDbHandle()
00474   {
00475     return dbh;
00476   }
00477 
00478   Status CollectionBE::getStatus() const
00479   {
00480     return status;
00481   }
00482 }

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