AgregatClass.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 
00026 #include "eyedb_p.h"
00027 #include "IteratorBE.h"
00028 #include "CollectionBE.h"
00029 #include <assert.h>
00030 #include "Attribute_p.h"
00031 #include "eyedb/gbxcyctx.h"
00032 
00033 namespace eyedb {
00034 
00035 #define foreach_item(X) \
00036 { \
00037    int i; \
00038  \
00039    Status status; \
00040  \
00041    for (i = 0; i < items_cnt; i++) \
00042      if (!items[i]->isNative() && ((status = items[i]->X))) \
00043          return status; \
00044 }
00045 
00046   //
00047   // AgregatClass
00048   //
00049 
00050   void AgregatClass::init(void)
00051   {
00052   }
00053 
00054   void AgregatClass::_release(void)
00055   {
00056   }
00057 
00058   Status AgregatClass::getValue(unsigned char**) const
00059   {
00060     return Success;
00061   }
00062 
00063   Status AgregatClass::setValue(unsigned char*)
00064   {
00065     return Success;
00066   }
00067 
00068   Status
00069   AgregatClass::setName(const char *s)
00070   {
00071     return setNameRealize(s);
00072   }
00073 
00074   void
00075   AgregatClass::touch()
00076   {
00077     Class::touch();
00078     LinkedList *cl_list = IteratorBE::getMclList();
00079     if (cl_list)
00080       cl_list->insertObjectLast(this);
00081   }
00082 
00083   Status AgregatClass::trace(FILE *fd, unsigned int flags, const RecMode *rcm) const
00084   {
00085     return trace_realize(fd, INDENT_INC, flags, rcm);
00086   }
00087 
00088   void stop_now1() { }
00089 
00090   void AgregatClass::_init(Class *_parent)
00091   {
00092     setClass(AgregatClass_Class);
00093     parent    = (_parent ? _parent : Agregat_Class);
00094 
00095     AttrNative::copy(ObjectITEMS, items, items_cnt, this);
00096     post_create_offset = 0;
00097   }
00098 
00099   AgregatClass::AgregatClass(const char *s, Class *p) :
00100     Class(s, p)
00101   {
00102     _init(p);
00103   }
00104 
00105   AgregatClass::AgregatClass(const char *s, const Oid *poid) :
00106     Class(s, poid)
00107   {
00108     _init(0);
00109   }
00110 
00111   AgregatClass::AgregatClass(Database *_db, const char *s,
00112                              Class *p) : Class(_db, s, p)
00113   {
00114     _init(p);
00115   }
00116 
00117   AgregatClass::AgregatClass(Database *_db, const char *s,
00118                              const Oid *poid) : Class(_db, s, poid)
00119   {
00120     parent = 0;
00121     setClass( AgregatClass_Class);
00122     post_create_offset = 0;
00123   }
00124 
00125   AgregatClass::AgregatClass(const AgregatClass &cl)
00126     : Class(cl)
00127   {
00128     _init(0);
00129   }
00130 
00131   AgregatClass::AgregatClass(const Oid &_oid, const char *_name)
00132     : Class(_oid, _name)
00133   {
00134     post_create_offset = 0;
00135   }
00136 
00137   AgregatClass &AgregatClass::operator=(const AgregatClass &cl)
00138   {
00139     _init(0);
00140     this->Class::operator=(cl);
00141     return *this;
00142   }
00143 
00144   Status AgregatClass::compile(void)
00145   {
00146     int n;
00147     int offset;
00148     int size, inisize;
00149     Status status;
00150 
00151     offset = IDB_OBJ_HEAD_SIZE;
00152 
00153     if (asUnionClass())
00154       offset += sizeof(eyedblib::int16);
00155 
00156     size = 0;
00157 
00158     for (n = 0; n < items_cnt; n++)
00159       if ((status = items[n]->compile_perst(this, &offset, &size, &inisize)))
00160         return status;
00161 
00162     if (asUnionClass())
00163       {
00164         idr_psize = size + IDB_OBJ_HEAD_SIZE + sizeof(eyedblib::int16);
00165         offset = idr_psize;
00166       }
00167     else
00168       idr_psize = offset;
00169 
00170     size = 0;
00171     idr_inisize = inisize;
00172 
00173     for (n = 0; n < items_cnt; n++)
00174       if ((status = items[n]->compile_volat(this, &offset, &size)))
00175         return status;
00176 
00177     if (asUnionClass())
00178       idr_vsize = size;
00179     else
00180       idr_vsize = offset - idr_psize;
00181 
00182     idr_objsz = idr_psize + idr_vsize;
00183 
00184     /*
00185       printf("\n");
00186       printf("Class %s {\n", name);
00187       printf("   Persistent Size = %d\n",    idr_psize);
00188       printf("   Volatile Size   = %d\n",    idr_vsize);
00189       printf("   Total Size      = %d\n}\n", idr_objsz);
00190     */
00191 
00192     fflush(stdout);
00193 
00194     return Success;
00195   }
00196 
00197   void
00198   AgregatClass::newObjRealize(Object *agr) const
00199   {
00200     if (!attrs_complete)
00201       ((AgregatClass *)this)->attrsComplete();
00202 
00203     for (int n = 0; n < items_cnt; n++)
00204       items[n]->newObjRealize(agr);
00205   }
00206 
00207   Status
00208   AgregatClass::checkInversePath(const Schema *m,
00209                                  const Attribute *item,
00210                                  const Attribute *&invitem,
00211                                  Bool mandatory) const
00212   {
00213     const char *cinvname, *finvname;
00214     invitem = NULL;
00215 
00216     item->getInverse(&cinvname, &finvname, &invitem);
00217 
00218     /*
00219       printf("checkInversePath -> invname %s, finvname %s [mandatory %d] "
00220       "invitem %p\n",
00221       (cinvname ? cinvname : "NULL"),
00222       (finvname ? finvname : "NULL"), mandatory, invitem);
00223     */
00224 
00225     if ((!cinvname || !finvname) && !invitem)
00226       {
00227         if (mandatory)
00228           return Exception::make(IDB_ATTRIBUTE_INVERSE_ERROR,
00229                                  "attribute '%s::%s': "
00230                                  "has no inverse directive",
00231                                  item->getClassOwner()->getName(),
00232                                  item->getName());
00233 
00234         return Success;
00235       }
00236 
00237     if (invitem)
00238       return Success;
00239 
00240     Class *cl = ((Schema *)m)->getClass(cinvname);
00241     if (!cl)
00242       return Exception::make(IDB_ATTRIBUTE_INVERSE_ERROR,
00243                              "attribute '%s::%s': "
00244                              "inverse class '%s' "
00245                              "does not exist.",
00246                              item->getClassOwner()->getName(),
00247                              item->getName(), cinvname);
00248 
00249     invitem = cl->getAttribute(finvname);
00250 
00251     if (!invitem)
00252       return Exception::make(IDB_ATTRIBUTE_INVERSE_ERROR,
00253                              "attribute '%s::%s': "
00254                              "inverse attribute '%s::%s' "
00255                              "does not exist.",
00256                              item->getClassOwner()->getName(),
00257                              item->getName(),
00258                              cinvname, finvname);
00259 
00260     return Success;
00261   }
00262 
00263   Status AgregatClass::checkInverse(const Schema *m) const
00264   {
00265     Status s;
00266 
00267     for (int i = 0; i < items_cnt; i++)
00268       {
00269         const Attribute *item = items[i];
00270         const Attribute *invitem;
00271 
00272         if (s = checkInversePath(m, item, invitem, False))
00273           return s;
00274 
00275         if (!invitem)
00276           continue;
00277 
00278         const Attribute *invinvitem;
00279         if (s = checkInversePath(m, invitem, invinvitem, True))
00280           return s;
00281 
00282         if (!invinvitem->compare(db, item))
00283           return Exception::make(IDB_ATTRIBUTE_INVERSE_ERROR,
00284                                  "attribute '%s::%s': "
00285                                  "inverse directive attribute '%s::%s' "
00286                                  "does not match.",
00287                                  name,
00288                                  item->getName(),
00289                                  invitem->getClassOwner()->getName(),
00290                                  invitem->getName());
00291       }
00292 
00293     return Success;
00294   }
00295 
00296   Status AgregatClass::create()
00297   {
00298     if (oid.isValid())
00299       return Exception::make(IDB_OBJECT_ALREADY_CREATED, "creating agregat_class '%s'", name);
00300 
00301     IDB_CHECK_WRITE(db);
00302 
00303 #ifdef OPTOPEN_TRACE
00304     printf("creating class %s this=%p\n", name, this);
00305 #endif
00306 
00307     RPCStatus rpc_status;
00308     eyedblib::int16 kk;
00309     Size alloc_size;
00310     Offset offset, ioff;
00311     Status status;
00312   
00313     alloc_size = 0;
00314     idr->setIDR((Size)0);
00315     Data data = 0;
00316     offset = IDB_CLASS_IMPL_TYPE;
00317     Status s = IndexImpl::code(data, offset, alloc_size, *idximpl);
00318     if (s) return s;
00319 
00320     offset = IDB_CLASS_MTYPE;
00321     eyedblib::int32 mt = m_type;
00322     int32_code (&data, &offset, &alloc_size, &mt);
00323 
00324     offset = IDB_CLASS_DSPID;
00325     eyedblib::int16 dspid = get_instdspid();
00326     int16_code (&data, &offset, &alloc_size, &dspid);
00327 
00328     offset = IDB_CLASS_HEAD_SIZE;
00329   
00330     status = class_name_code(db->getDbHandle(), getDataspaceID(), &data, &offset,
00331                              &alloc_size, name);
00332     if (status) return status;
00333 
00334     if (parent && !parent->getOid().isValid() && !parent->getDatabase())
00335       parent = db->getSchema()->getClass(parent->getName());
00336 
00337     if (parent && !parent->getOid().isValid()) {
00338       Status status = parent->create();
00339       if (status) return status;
00340     }
00341 
00342     if (parent)
00343       oid_code (&data, &offset, &alloc_size, parent->getOid().getOid());
00344     else
00345       oid_code (&data, &offset, &alloc_size, getInvalidOid());
00346 
00347     int32_code  (&data, &offset, &alloc_size, (eyedblib::int32 *)&idr_psize);
00348     int32_code  (&data, &offset, &alloc_size, (eyedblib::int32 *)&idr_vsize);
00349     int32_code  (&data, &offset, &alloc_size, (eyedblib::int32 *)&idr_objsz);
00350     int32_code  (&data, &offset, &alloc_size, (eyedblib::int32 *)&items_cnt);
00351   
00352     ioff = offset;
00353     post_create_offset = ioff;
00354 
00355     int i;
00356     for (i = 0; i < items_cnt; i++)
00357       items[i]->codeIDR(db, &data, &offset, &alloc_size);
00358 
00359     Size idr_sz = offset;
00360     idr->setIDR(idr_sz, data);
00361     headerCode((asStructClass() ? _StructClass_Type : _UnionClass_Type),
00362                idr_sz, xinfo);
00363 
00364     codeExtentCompOids(alloc_size);
00365 
00366     // added the 21/10/99
00367     if (oid.isValid())
00368       rpc_status = objectWrite(db->getDbHandle(), data, oid.getOid());
00369     else
00370       rpc_status = objectCreate(db->getDbHandle(), getDataspaceID(),
00371                                 data, oid.getOid());
00372   
00373     if (rpc_status == RPCSuccess) {
00374       status = ClassPeer::makeColls(db, this, data, &oid);
00375       if (status)
00376         return status;
00377     }
00378 
00379     if (rpc_status == RPCSuccess) {
00380       offset = ioff;
00381       for (i = 0; i < items_cnt; i++) {
00382         Attribute *item = items[i];
00383         if (item->isNative())
00384           continue;
00385         if (!item->cls->getOid().isValid()) {
00386           if (item->cls->isUnrealizable()) {
00387             item->cls =
00388               db->getSchema()->getClass(item->cls->getName());
00389             assert(item->cls);
00390           }
00391           Status status;
00392           status = const_cast<Class *>(item->cls)->setDatabase(db);
00393           if (status)
00394             return status;
00395 
00396           status = const_cast<Class *>(item->cls)->create();
00397           if (status) {
00398             if (status->getStatus() == IDB_OBJECT_ALREADY_CREATED)
00399               continue;
00400             return status;
00401           }
00402         }
00403       
00404         item->codeClassOid(data, &offset);
00405       
00406         // inverse
00407         status = item->completeInverse(db);
00408         if (status)
00409           return status;
00410       }
00411     
00412       offset = ioff;
00413       for (i = 0; i < items_cnt; i++)
00414         items[i]->codeIDR(db, &data, &offset, &alloc_size);
00415     
00416       rpc_status = objectWrite(db->getDbHandle(), data, oid.getOid());
00417     }
00418 
00419     return StatusMake(rpc_status);
00420   }
00421 
00422   Status AgregatClass::postCreate()
00423   {
00424     if (!post_create_offset)
00425       return Success;
00426 
00427     RPCStatus rpc_status;
00428     Size alloc_size;
00429     Offset offset;
00430     Status status;
00431   
00432     if (!getUserData("eyedb:odl::update") && (status = createIndexes()))
00433       return status;
00434 
00435     offset = post_create_offset;
00436     alloc_size = idr->getSize();
00437     Data data = idr->getIDR();
00438     //printf("AgregatClass::postCreate(%s, offset=%d)\n", name, post_create_offset);
00439     for (int i = 0; i < items_cnt; i++)
00440       items[i]->codeIDR(db, &data, &offset, &alloc_size);
00441 
00442     if (idr->getSize() - post_create_offset > 0)
00443       rpc_status = dataWrite(db->getDbHandle(),
00444                              post_create_offset,
00445                              idr->getSize() - post_create_offset,
00446                              idr->getIDR()+post_create_offset, oid.getOid());
00447     else
00448       rpc_status = RPCSuccess;
00449   
00450     post_create_offset = 0;
00451     mustCreateComps = True;
00452   
00453     /*
00454       if (!rpc_status)
00455       return createComps();
00456     */
00457 
00458     return StatusMake(rpc_status);
00459   }
00460 
00461   Status
00462   AgregatClass::completeInverse(Schema *m)
00463   {
00464     for (int i = 0; i < items_cnt; i++)
00465       {
00466         Status s = items[i]->completeInverse(m);
00467         if (s)
00468           return s;
00469       }
00470 
00471     return Success;
00472   }
00473 
00474   Status AgregatClass::attrsComplete()
00475   {
00476     if (!db)
00477       return Success;
00478 
00479     int err = 0;
00480     Status s = Class::attrsComplete();
00481 
00482     if (s)
00483       err++;
00484 
00485     setSchema(db->getSchema());
00486     BufferString buf;
00487 
00488     for (int i = 0; i < items_cnt; i++)
00489       {
00490         Attribute *item = items[i];
00491         if (item->isNative())
00492           continue;
00493         Bool inv_error = False;
00494 
00495 #if 0
00496         printf("attribute %s {\n", item->getName());
00497         printf("\tclass: %s ", item->oid_cl.toString());
00498         if (item->cls) {
00499           printf("vs. %s", item->cls->getOid().toString());
00500           //assert(item->oid_cl.compare(item->cls->getOid()));
00501           /*
00502             if (!item->oid_cl.isValid() ||
00503             !item->oid_cl.compare(item->cls->getOid()))
00504             item->oid_cl = item->cls->getOid();
00505           */
00506         }
00507         printf("\n\tclass_owner: %s ", item->oid_cl_own.toString());
00508         if (item->class_owner) {
00509           printf("vs. %s", item->class_owner->getOid().toString());
00510           //assert(item->oid_cl_own.compare(item->class_owner->getOid()));
00511           /*
00512             if (!item->oid_cl_own.isValid() ||
00513             !item->oid_cl_own.compare(item->class_owner->getOid()))
00514             item->oid_cl_own = item->class_owner->getOid();
00515           */
00516         }
00517         printf("\n}\n");
00518 #endif
00519         if (!item->cls)
00520           item->cls = getSchema()->getClass(item->oid_cl, True);
00521         assert(!item->cls || !item->cls->isRemoved());
00522         if (!item->class_owner)
00523           item->class_owner = getSchema()->getClass(item->oid_cl_own, True);
00524         assert(!item->class_owner || !item->class_owner->isRemoved());
00525         if (item->inv_spec.oid_cl.isValid())
00526           {
00527             Class *cl_inv;
00528             cl_inv = getSchema()->getClass(item->inv_spec.oid_cl);
00529 
00530             if (cl_inv)
00531               item->inv_spec.item = ((AgregatClass *)cl_inv)->getAttributes()[item->inv_spec.num];
00532             else
00533               inv_error = True;
00534           }
00535 
00536         if (!item->cls || !item->class_owner || inv_error)
00537           {
00538             if (!buf.length())
00539               buf.append((std::string("attributes of agregat_class '") +
00540                           name + "' are incomplete: ").c_str());
00541             else
00542               buf.append(", ");
00543 
00544             buf.append(item->name);
00545             if (!item->cls) buf.append(" (class attribute is missing)");
00546             else if (!item->class_owner) buf.append(" (class owner is missing)");
00547             else if (inv_error) buf.append(" (class of inverse attribute is missing)");
00548             err++;
00549           }
00550 
00551         Status status = item->completeInverse(db);
00552         if (status)
00553           return status;
00554       }
00555 
00556     attrs_complete = (err ? False : True);
00557 
00558     if (err)
00559       return Exception::make(IDB_CLASS_COMPLETION_ERROR, buf.getString());
00560 
00561     return Success;
00562   }
00563 
00564   Status AgregatClass::setDatabase(Database *mdb)
00565   {
00566     Status status = Class::setDatabase(mdb);
00567 
00568     if (status == Success)
00569       {
00570         for (int i = 0; i < items_cnt; i++)
00571           {
00572             Attribute *item = items[i];
00573             if (item->cls && !item->cls->getOid().isValid())
00574               {
00575                 if (item->cls->isUnrealizable())
00576                   {
00577                     item->cls =
00578                       db->getSchema()->getClass(item->cls->getName());
00579                     assert(item->cls);
00580                   }
00581               }
00582           }
00583       }
00584     return status;
00585   }
00586 
00587   Status AgregatClass::update()
00588   {
00589     if (!modify)
00590       return Success;
00591 
00592     Status status;
00593 
00594     status = wholeComplete();
00595     if (status)
00596       return status;
00597 
00598     RPCStatus rpc_status;
00599     eyedblib::int16 kk;
00600     Size alloc_size;
00601     Offset offset, ioff;
00602   
00603     alloc_size = idr->getSize();
00604     Data data = idr->getIDR();
00605     /*
00606       offset = IDB_CLASS_MAG_ORDER;
00607       int32_code (&data, &offset, &alloc_size, (eyedblib::int32 *)&mag_order);
00608     */
00609     offset = IDB_CLASS_IMPL_TYPE;
00610     status = IndexImpl::code(data, offset, alloc_size, *idximpl);
00611     if (status) return status;
00612 
00613     offset = IDB_CLASS_MTYPE;
00614     eyedblib::int32 mt = m_type;
00615     int32_code (&data, &offset, &alloc_size, &mt);
00616 
00617     offset = IDB_CLASS_DSPID;
00618     eyedblib::int16 dspid = get_instdspid();
00619     int16_code (&data, &offset, &alloc_size, &dspid);
00620 
00621     offset = IDB_CLASS_HEAD_SIZE;
00622   
00623     status = class_name_code(db->getDbHandle(), getDataspaceID(), &data,
00624                              &offset, &alloc_size, name);
00625     if (status) return status;
00626 
00627     if (parent && !parent->getOid().isValid())
00628       {
00629         status = parent->create();
00630         if (status) return status;
00631       }
00632 
00633     if (parent)
00634       oid_code (&data, &offset, &alloc_size, parent->getOid().getOid());
00635     else
00636       oid_code (&data, &offset, &alloc_size, getInvalidOid());
00637 
00638     int32_code  (&data, &offset, &alloc_size, (eyedblib::int32 *)&idr_psize);
00639     int32_code  (&data, &offset, &alloc_size, (eyedblib::int32 *)&idr_vsize);
00640     int32_code  (&data, &offset, &alloc_size, (eyedblib::int32 *)&idr_objsz);
00641     int32_code  (&data, &offset, &alloc_size, (eyedblib::int32 *)&items_cnt);
00642   
00643     ioff = offset;
00644 
00645     int i;
00646     for (i = 0; i < items_cnt; i++) {
00647       status = items[i]->completeInverse(db);
00648       if (status) return status;
00649     }
00650 
00651     for (i = 0; i < items_cnt; i++) {
00652       status = items[i]->codeIDR(db, &data, &offset, &alloc_size);
00653       if (status) return status;
00654     }
00655 
00656 #if 1
00657     // added the 4/10/99
00658     Size idr_sz = offset;
00659     // added the 27/12/00 because of a problem in eyedbodl updating process
00660     if (!idr->getSize())
00661       idr->setIDR(idr_sz, data);
00662 
00663     assert(idr_sz == idr->getSize());
00664     if (!getClass()->getOid().isValid())
00665       setClass(db->getSchema()->getClass(getClass()->getName()));
00666     headerCode((asStructClass() ? _StructClass_Type : _UnionClass_Type),
00667                idr_sz, xinfo);
00668 #else
00669     // workaround ...
00670     ObjectHeader hdr;
00671     object_header_decode_head(idr->idr, &hdr);
00672     if (hdr.type != _AgregatClass_Type)
00673       {
00674         hdr.type = _AgregatClass_Type;
00675         object_header_code_head(idr->idr, &hdr);
00676       }
00677     // ...
00678 #endif
00679 
00680     offset = ioff;
00681 
00682     for (i = 0; i < items_cnt; i++)
00683       items[i]->codeIDR(db, &data, &offset, &alloc_size);
00684   
00685     unsigned int objsize = 0;
00686     rpc_status = dataSizeGet(db->getDbHandle(), oid.getOid(), &objsize);
00687     if (!rpc_status) {
00688       if (idr->getSize() != objsize) {
00689         rpc_status = objectSizeModify(db->getDbHandle(), idr->getSize(),
00690                                       oid.getOid());
00691       }
00692 
00693       if (!rpc_status)
00694         rpc_status = objectWrite(db->getDbHandle(), data, oid.getOid());
00695     }
00696 
00697     if (!rpc_status)
00698       modify = False;
00699 
00700     return StatusMake(rpc_status);
00701   }
00702 
00703   void
00704   AgregatClass::revert(Bool rev)
00705   {
00706     for (int i = 0; i < items_cnt; i++)
00707       items[i]->revert(rev);
00708   }
00709 
00710   Status AgregatClass::remove(const RecMode *rcm)
00711   {
00712     return Class::remove(rcm);
00713   }
00714 
00715   Status AgregatClass::trace_realize(FILE *fd, int indent, unsigned int flags, const RecMode *rcm) const
00716   {
00717     return Class::trace_realize(fd, indent, flags, rcm);
00718   }
00719 
00720   /*
00721     Bool
00722     AgregatClass::compare_perform(const Class *cl) const
00723     {
00724     if (!cl->asAgregatClass())
00725     return False;
00726 
00727     const AgregatClass *ma = (AgregatClass *)cl;
00728 
00729     if (asUnionClass() != ma->asUnionClass())
00730     return False;
00731 
00732     if (items_cnt != ma->items_cnt)
00733     return False;
00734 
00735     for (int i = 0; i < items_cnt; i++)
00736     if (!items[i]->compare(db, ma->items[i]))
00737     return False;
00738 
00739     return True;
00740     }
00741   */
00742 
00743   Bool
00744   AgregatClass::compare_perform(const Class *cl,
00745                                 Bool compClassOwner,
00746                                 Bool compNum,
00747                                 Bool compName,
00748                                 Bool inDepth) const
00749   {
00750     if (!cl->asAgregatClass())
00751       return False;
00752 
00753     const AgregatClass *ma = (AgregatClass *)cl;
00754 
00755     if (asUnionClass() != ma->asUnionClass())
00756       return False;
00757 
00758     if (items_cnt != ma->items_cnt)
00759       return False;
00760 
00761     for (int i = 0; i < items_cnt; i++)
00762       if (!items[i]->compare(db, ma->items[i], compClassOwner, compNum,
00763                              compName, inDepth))
00764         return False;
00765 
00766     return True;
00767   }
00768 
00769   Status
00770   agregatClassMake(Database *db, const Oid *oid, Object **o,
00771                    const RecMode *rcm, const ObjectHeader *hdr,
00772                    Data idr, LockMode lockmode, const Class*)
00773   {
00774     RPCStatus rpc_status;
00775     Status status;
00776     Data temp;
00777 
00778     if (ObjectPeer::isRemoved(*hdr))
00779       {
00780         *o = new StructClass("<removed_class>");
00781         return Success;
00782       }
00783 
00784     if (!idr)
00785       {
00786         temp = (unsigned char *)malloc(hdr->size);
00787         object_header_code_head(temp, hdr);
00788 
00789         rpc_status = objectRead(db->getDbHandle(), temp, 0, 0, oid->getOid(),
00790                                 0, lockmode, 0);
00791       }
00792     else
00793       {
00794         temp = idr;
00795         rpc_status = RPCSuccess;
00796       }
00797 
00798     if (rpc_status == RPCSuccess)
00799       {
00800         eyedblib::int16 code;
00801         eyedblib::int32 cnt;
00802         char *s;
00803         AgregatClass *ma;
00804         Offset offset;
00805 
00806         /*
00807           eyedblib::int32 mag_order;
00808           offset = IDB_CLASS_MAG_ORDER;
00809           int32_decode (temp, &offset, &mag_order);
00810         */
00811         IndexImpl *idximpl;
00812         offset = IDB_CLASS_IMPL_TYPE;
00813         Status status = IndexImpl::decode(db, temp, offset, idximpl);
00814         if (status) return status;
00815 
00816         eyedblib::int32 mt;
00817         offset = IDB_CLASS_MTYPE;
00818         int32_decode (temp, &offset, &mt);
00819 
00820         eyedblib::int16 dspid;
00821         offset = IDB_CLASS_DSPID;
00822         int16_decode (temp, &offset, &dspid);
00823 
00824         offset = IDB_CLASS_HEAD_SIZE;
00825         status = class_name_decode(db->getDbHandle(), temp, &offset, &s);
00826         if (status) return status;
00827 
00828         // WARNING: ADDED THE 23/05/01 for test
00829         eyedbsm::Oid parent_oid, *poid;
00830         oid_decode(temp, &offset, &parent_oid);
00831 
00832         if (isOidValid(&parent_oid))
00833           poid = &parent_oid;
00834         else
00835           poid = 0;
00836 
00837         Oid ppoid(poid);
00838         if (hdr->type == _StructClass_Type)
00839           ma = new StructClass(s, &ppoid);
00840         else if (hdr->type == _UnionClass_Type)
00841           ma = new UnionClass(s, &ppoid);
00842         else
00843           return Exception::make(IDB_CLASS_READ, "agregat_class '%s' unknown code `%d'", s, code);
00844 
00845         free(s); s = 0;
00846         ma->setExtentImplementation(idximpl, True);
00847         if (idximpl)
00848           idximpl->release();
00849         ma->setInstanceDspid(dspid);
00850 
00851         ClassPeer::setMType(ma, (Class::MType)mt);
00852         int32_decode(temp, &offset, (eyedblib::int32 *)&ma->idr_psize);
00853         int32_decode(temp, &offset, (eyedblib::int32 *)&ma->idr_vsize);
00854         int32_decode(temp, &offset, (eyedblib::int32 *)&ma->idr_objsz);
00855         int32_decode(temp, &offset, &cnt);
00856 
00857         unsigned int native_cnt;
00858         const Attribute **items_nat = ma->getAttributes(native_cnt);
00859 
00860         ma->items = (Attribute **)malloc(sizeof(Attribute *) * cnt);
00861         ma->items_cnt = cnt;
00862 
00863         int i;
00864         /* disconnected again the 30/04/02 */
00865 #if 1 /* WARNING: this code has been restored on the 14/10/97 because
00866          of memory leaks found with purify! */
00867         for (i = 0; i < native_cnt; i++)
00868           ma->items[i] = (Attribute *)items_nat[i];
00869 #else
00870         for (i = 0; i < native_cnt; i++)
00871           ma->items[i] = new AttrNative((AttrNative *)items_nat[i],
00872                                         items_nat[i]->getClass(),
00873                                         items_nat[i]->getClassOwner(),
00874                                         ma, i);
00875 #endif
00876 
00877         free(items_nat);
00878 
00879         for (i = native_cnt; i < cnt; i++)
00880           ma->items[i] = makeAttribute(db, temp, &offset, ma, i);
00881 
00882         *o = (Object *)ma;
00883 
00884         ObjectPeer::setOid(ma, *oid);
00885         if (!db->isOpeningState() && !db->isBackEnd()) {
00886           status = ma->setDatabase(db);
00887           if (status)
00888             return status;
00889         }
00890 
00891         status = ClassPeer::makeColls(db, (Class *)*o, temp);
00892 
00893         if (status != Success) {
00894           if (!idr)
00895             free(temp);
00896           return status;
00897         }
00898       }
00899 
00900     if (!idr)
00901       {
00902         if (!rpc_status)
00903           ObjectPeer::setIDR(*o, temp, hdr->size);
00904       }
00905 
00906     return StatusMake(rpc_status);
00907   }
00908 
00909   // indexes: Front End methods
00910   Status AgregatClass::createIndexes(void)
00911   {
00912     /*
00913       IDB_LOG(IDB_LOG_IDX_CREATE,
00914       ("AgregatClass::createIndexes(%s, attr_cnt=%d)\n",
00915       name, items_cnt));
00916       //  foreach_item(createIndex(db, this, (const AttrIdxContext *)0, 0));
00917       foreach_item(createIndex(db, this, (const AttrIdxContext *)0, items[i]->getIndexMode()));
00918     */
00919     return Success;
00920   }
00921 
00922 
00923   // indexes: Back End methods
00924 
00925   Status AgregatClass::openIndexes_realize(Database *_db)
00926   {
00927     assert(0);
00928     /*
00929       if (_db->isBackEnd())
00930       foreach_item(openIndex_realize(_db));
00931     */
00932     return Success;
00933   }
00934 
00935   Status
00936   AgregatClass::createNestedIndex(AttrIdxContext &attr_idx_ctx,
00937                                   const AttrIdxContext *tg_idx_ctx,
00938                                   int _mode)
00939   {
00940     assert(0);
00941     /*
00942       foreach_item(createNestedIndex(attr_idx_ctx, tg_idx_ctx, _mode));
00943     */
00944     return Success;
00945   }
00946 
00947   Status
00948   AgregatClass::removeNestedIndex(AttrIdxContext &attr_idx_ctx,
00949                                   const AttrIdxContext *tg_idx_ctx,
00950                                   int _mode)
00951   {
00952     assert(0);
00953     /*
00954       foreach_item(removeNestedIndex(attr_idx_ctx, tg_idx_ctx, _mode));
00955     */
00956     return Success;
00957   }
00958 
00959   static inline Oid
00960   getClassOid(Data idr)
00961   {
00962     eyedbsm::Oid oid;
00963     Oid roid;
00964     Offset offset = IDB_OBJ_HEAD_OID_MCL_INDEX;
00965     oid_decode(idr, &offset, &oid);
00966     roid.setOid(oid);
00967     return roid;
00968   }
00969 
00970   //#define PERF_POOL
00971 
00972 #ifdef PERF_POOL
00973   struct CreateIndexArgs {
00974     Database *db;
00975     Data idr;
00976     const Oid *oid;
00977     AttrIdxContext *idx_ctx;
00978     const Oid *cloid;
00979     int offset;
00980     Bool novd;
00981     int count;
00982     int size;
00983     CreateIndexArgs(Database *_db, Data _idr,
00984                     const Oid *_oid, AttrIdxContext *_idx_ctx,
00985                     const Oid *_cloid, int _offset, Bool _novd,
00986                     int _count, int _size) :
00987       db(_db), idr(_idr), oid(_oid), idx_ctx(_idx_ctx),
00988       cloid(_cloid), offset(_offset), novd(_novd), count(_count),
00989       size(_size) { }
00990   };
00991 
00992   PerformerArg
00993   createIndexEntryWrapper(PerformerArg xarg)
00994   {
00995     Attribute *attr = (Attribute *)xarg.data;
00996     CreateIndexArgs *arg = (CreateIndexArgs *)attr->getUserData();
00997     AttrIdxContext idx_ctx(arg->idx_ctx);
00998     Status s = attr->createIndexEntry_realize(arg->db, arg->idr,
00999                                               arg->oid,
01000                                               arg->cloid, arg->offset,
01001                                               arg->novd, idx_ctx,
01002                                               arg->count, arg->size);
01003     return PerformerArg((void *)s);
01004   }
01005 
01006   Status
01007   AgregatClass::createIndexEntries_realize(Database *_db,
01008                                            Data _idr,
01009                                            const Oid *_oid,
01010                                            AttrIdxContext &idx_ctx,
01011                                            const Oid *cloid,
01012                                            int offset, Bool novd,
01013                                            int count, int size)
01014   {
01015     Oid stoid;
01016     if (!cloid) {stoid = getClassOid(_idr); cloid = &stoid; }
01017 
01018     Performer *perfs[100]; // should be item_cnt
01019     CreateIndexArgs idxargs(_db, _idr, _oid, &idx_ctx, cloid, offset, novd,
01020                             count, size);
01021     PerformerPool *perfpool = idbPerformerPoolManager::getPerfPool();
01022 #ifdef POOL_TRACE
01023     printf("%s: CREATE GETTING performer pool %p #1\n", name, perfpool);
01024 #endif
01025 
01026     for (int i = 0; i < items_cnt; i++)
01027       if (!items[i]->isNative()) {
01028         items[i]->setUserData(&idxargs);
01029         perfs[i] = perfpool->start(createIndexEntryWrapper, items[i]);
01030       }
01031 
01032 #ifdef POOL_TRACE
01033     printf("%s: CREATE GETTING performer pool %p #2\n", name, perfpool);
01034 #endif
01035     for (int i = 0; i < items_cnt; i++)
01036       if (!items[i]->isNative()) {
01037         PerformerArg arg = perfpool->wait(perfs[i]);
01038         if (arg.data) {
01039           perfpool->waitAll();
01040           if (!idx_ctx.getLevel())
01041             idx_ctx.realizeIdxOP(False);
01042           return (Status)arg.data;
01043         }
01044       } 
01045 
01046     if (perfpool->isProfiled()) {
01047       static int prof_cnt = 0;
01048       if (!(++prof_cnt % 20)) {
01049         unsigned int cnt;
01050         eyedblib::Thread::Profile **profiles = perfpool->getProfiles(cnt);
01051         cout << profiles << endl;
01052         //PeformerPool::deleteProfiles(profiles);
01053         for (int i = 0; i < cnt; i++)
01054           delete profiles[i];
01055         delete[] profiles;
01056       }
01057     }
01058 #ifdef POOL_TRACE
01059     printf("%s: CREATE GETTING performer pool %p #3\n", name, perfpool);
01060 #endif
01061     return idx_ctx.getLevel() ? Success : idx_ctx.realizeIdxOP(True);
01062   }
01063 
01064 #else
01065   Status
01066   AgregatClass::createIndexEntries_realize(Database *_db,
01067                                            Data _idr,
01068                                            const Oid *_oid,
01069                                            AttrIdxContext &idx_ctx,
01070                                            const Oid *cloid,
01071                                            int offset, Bool novd,
01072                                            int count, int size)
01073   {
01074     Oid stoid;
01075     if (!cloid) {stoid = getClassOid(_idr); cloid = &stoid; }
01076 
01077     Status status;
01078     for (int i = 0; i < items_cnt; i++)
01079       if (!items[i]->isNative() && ((status = items[i]->createIndexEntry_realize(_db, _idr, _oid, cloid, offset, novd, idx_ctx, count, size))))
01080         {
01081           if (!idx_ctx.getLevel())
01082             idx_ctx.realizeIdxOP(False);
01083           return status;
01084         }
01085         
01086     return idx_ctx.getLevel() ? Success : idx_ctx.realizeIdxOP(True);
01087   }
01088 #endif
01089 
01090 #ifdef PERF_POOL
01091   struct UpdateIndexArgs {
01092     Database *db;
01093     Data idr;
01094     const Oid *oid;
01095     AttrIdxContext *idx_ctx;
01096     const Oid *cloid;
01097     int offset;
01098     Bool novd;
01099     const Oid *data_oid;
01100     int count;
01101     UpdateIndexArgs(Database *_db, Data _idr,
01102                     const Oid *_oid, AttrIdxContext *_idx_ctx,
01103                     const Oid *_cloid, int _offset, Bool _novd,
01104                     const Oid *_data_oid, int _count) :
01105       db(_db), idr(_idr), oid(_oid), idx_ctx(_idx_ctx),
01106       cloid(_cloid), offset(_offset), novd(_novd), data_oid(_data_oid),
01107       count(_count) { }
01108   };
01109 
01110   PerformerArg
01111   updateIndexEntryWrapper(PerformerArg xarg)
01112   {
01113     Attribute *attr = (Attribute *)xarg.data;
01114     UpdateIndexArgs *arg = (UpdateIndexArgs *)attr->getUserData();
01115     AttrIdxContext idx_ctx(arg->idx_ctx);
01116     Status s = attr->updateIndexEntry_realize(arg->db, arg->idr,
01117                                               arg->oid,
01118                                               arg->cloid, arg->offset,
01119                                               arg->novd, arg->data_oid,
01120                                               idx_ctx,
01121                                               arg->count);
01122     return PerformerArg((void *)s);
01123   }
01124 
01125   Status
01126   AgregatClass::updateIndexEntries_realize(Database *_db,
01127                                            Data _idr,
01128                                            const Oid *_oid,
01129                                            AttrIdxContext &idx_ctx,
01130                                            const Oid *cloid,
01131                                            int offset, Bool novd,
01132                                            const Oid *data_oid,
01133                                            int count)
01134   {
01135     Oid stoid;
01136     if (!cloid) {stoid = getClassOid(_idr); cloid = &stoid; }
01137 
01138     Performer *perfs[100]; // should be item_cnt
01139     UpdateIndexArgs idxargs(_db, _idr, _oid, &idx_ctx, cloid, offset, novd,
01140                             data_oid, count);
01141     PerformerPool *perfpool = idbPerformerPoolManager::getPerfPool();
01142 #ifdef POOL_TRACE
01143     printf("%s: UPDATE GETTING performer pool %p #1\n", name, perfpool);
01144 #endif
01145 
01146     for (int i = 0; i < items_cnt; i++)
01147       if (!items[i]->isNative()) {
01148         items[i]->setUserData(&idxargs);
01149         perfs[i] = perfpool->start(updateIndexEntryWrapper, items[i]);
01150       }
01151 
01152 #ifdef POOL_TRACE
01153     printf("%s: UPDATE GETTING performer pool %p #2\n", name, perfpool);
01154 #endif
01155     for (int i = 0; i < items_cnt; i++)
01156       if (!items[i]->isNative()) {
01157         PerformerArg arg = perfpool->wait(perfs[i]);
01158         if (arg.data) {
01159           perfpool->waitAll();
01160           if (!idx_ctx.getLevel())
01161             idx_ctx.realizeIdxOP(False);
01162           return (Status)arg.data;
01163         }
01164       } 
01165 
01166 #ifdef POOL_TRACE
01167     printf("%s: UPDATE GETTING performer pool %p #3\n", name, perfpool);
01168 #endif
01169     return idx_ctx.getLevel() ? Success : idx_ctx.realizeIdxOP(True);
01170   }
01171 #else
01172   Status
01173   AgregatClass::updateIndexEntries_realize(Database *_db,
01174                                            Data _idr,
01175                                            const Oid *_oid,
01176                                            AttrIdxContext &idx_ctx,
01177                                            const Oid *cloid,
01178                                            int offset, Bool novd,
01179                                            const Oid *data_oid,
01180                                            int count)
01181   {
01182     Oid stoid;
01183     if (!cloid) {stoid = getClassOid(_idr); cloid = &stoid; }
01184 
01185     Status status;
01186     for (int i = 0; i < items_cnt; i++)
01187       if (!items[i]->isNative() &&
01188           ((status = items[i]->updateIndexEntry_realize
01189             (_db, _idr, _oid, cloid, offset, novd,
01190              data_oid, idx_ctx, count))))
01191         {
01192           if (!idx_ctx.getLevel())
01193             idx_ctx.realizeIdxOP(False);
01194           return status;
01195         }
01196 
01197     return idx_ctx.getLevel() ? Success : idx_ctx.realizeIdxOP(True);
01198   }
01199 #endif
01200 
01201   Status
01202   AgregatClass::removeIndexEntries_realize(Database *_db,
01203                                            Data _idr,
01204                                            const Oid *_oid,
01205                                            AttrIdxContext &idx_ctx,
01206                                            const Oid *cloid,
01207                                            int offset, Bool novd,
01208                                            const Oid *data_oid,
01209                                            int count)
01210   {
01211     Oid stoid;
01212     if (!cloid) {stoid = getClassOid(_idr); cloid = &stoid; }
01213 
01214     foreach_item(removeIndexEntry_realize(_db, _idr, _oid, cloid, offset, novd,
01215                                           data_oid, idx_ctx, count));
01216 
01217     return idx_ctx.getLevel() ? Success : idx_ctx.realizeIdxOP(True);
01218   }
01219 
01220   //
01221   // inverses
01222   //
01223 
01224   Status AgregatClass::createInverses_realize(Database *_db, Data _idr, const Oid *_oid)
01225   {
01226     if (asUnionClass())
01227       {
01228         Attribute *item = (Attribute *)Union::decodeCurrentItem(this, _idr);
01229         if (item)
01230           item->createInverse_realize(_db, _idr, _oid);
01231       }
01232     else
01233       foreach_item(createInverse_realize(_db, _idr, _oid));
01234     return Success;
01235   }
01236 
01237   Status AgregatClass::updateInverses_realize(Database *_db, Data _idr, const Oid *_oid)
01238   {
01239     if (asUnionClass())
01240       {
01241         Attribute *item = (Attribute *)Union::decodeCurrentItem(this, _idr);
01242         if (item)
01243           item->updateInverse_realize(_db, _idr, _oid);
01244       }
01245     else
01246       foreach_item(updateInverse_realize(_db, _idr, _oid));
01247     return Success;
01248   }
01249 
01250   Status AgregatClass::removeInverses_realize(Database *_db, Data _idr, const Oid *_oid)
01251   {
01252     if (asUnionClass())
01253       {
01254         Attribute *item = (Attribute *)Union::decodeCurrentItem(this, _idr);
01255         if (item)
01256           item->removeInverse_realize(_db, _idr, _oid);
01257       }
01258     else
01259       foreach_item(removeInverse_realize(_db, _idr, _oid));
01260     return Success;
01261   }
01262 
01263   void AgregatClass::garbage()
01264   {
01265     Class::garbage();
01266   }
01267 
01268   AgregatClass::~AgregatClass()
01269   {
01270     garbageRealize();
01271   }
01272 }

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