ObjectLocation.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 #include <eyedbconfig.h>
00025 
00026 #include "eyedb/eyedb.h"
00027 #include <assert.h>
00028 #include "eyedbsm/eyedbsm_p.h"
00029 
00030 using namespace std;
00031 
00032 namespace eyedbsm {
00033   extern int power2(int);
00034 }
00035 
00036 namespace eyedb {
00037 
00038   ObjectLocationArray::ObjectLocationArray(ObjectLocation *_locs,
00039                                            unsigned int _cnt)
00040   {
00041     locs = 0;
00042     set(_locs, _cnt);
00043   }
00044 
00045   void
00046   ObjectLocationArray::set(ObjectLocation *_locs, unsigned int _cnt)
00047   {
00048     garbage();
00049     locs = _locs;
00050     cnt = _cnt;
00051   }
00052 
00053   ObjectLocationArray::~ObjectLocationArray()
00054   {
00055     garbage();
00056   }
00057 
00058   void
00059   ObjectLocationArray::garbage()
00060   {
00061     delete [] locs;
00062   }
00063 
00064   PageStats *
00065   ObjectLocationArray::computePageStats(Database *_db)
00066   {
00067     if (_db)
00068       db = _db;
00069 
00070     if (!db) return 0;
00071 
00072     PageStats *pgs = new PageStats(db);
00073     for (int i = 0; i < cnt; i++)
00074       pgs->add(locs[i]);
00075     return pgs;
00076   }
00077 
00078   ostream &operator<<(ostream &os, const ObjectLocationArray &locarr)
00079   {
00080     os << "Object number: " << locarr.cnt << endl;
00081     for (int i = 0; i < locarr.cnt; i++) {
00082       ObjectLocation &loc = const_cast<ObjectLocation &>(locarr.getLocation(i));
00083       if (i) os << '\n';
00084       os << loc(locarr.db);
00085     }
00086 
00087     return os;
00088   }
00089 
00090   ostream &operator<<(ostream &os, const ObjectLocation &loc)
00091   {
00092     os << "Object: " << loc.oid << '\n';
00093     if (loc.db) {
00094       os << "  Dspid: #" << loc.dspid << " ";
00095       const Dataspace *dataspace = 0;
00096       if (!loc.db->getDataspace(loc.dspid, dataspace))
00097         os  << dataspace->getName();
00098       os << '\n';
00099       os << "  Datid: #" << loc.datid << " ";
00100       const Datafile *datafile = 0;
00101       if (!loc.db->getDatafile(loc.dspid, datafile)) {
00102         if (*datafile->getName())
00103           os << datafile->getName();
00104         else
00105           os << datafile->getFile();
00106       }
00107       os << '\n';
00108     }
00109     else {
00110       os << "  Dspid: #" << loc.dspid << '\n';
00111       os << "  Datid: #" << loc.datid << '\n';
00112     }
00113 
00114     os << "  Size: " << loc.info.size << '\n';
00115     os << "  SlotStartNum: " << loc.info.slot_start_num << '\n';
00116     os << "  SlotEndNum: " << loc.info.slot_end_num << '\n';
00117     os << "  DatStartPagenum: " << loc.info.dat_start_pagenum << '\n';
00118     os << "  DatEndPagenum: " << loc.info.dat_end_pagenum << '\n';
00119     if (loc.info.omp_start_pagenum != ~0) {
00120       os << "  OmpStartPagenum: " << loc.info.omp_start_pagenum << '\n';
00121       os << "  OmpEndPagenum: " << loc.info.omp_end_pagenum << '\n';
00122     }
00123     os << "  DmpStartPagenum: " << loc.info.dmp_start_pagenum << '\n';
00124     os << "  DmpEndPagenum: " << loc.info.dmp_end_pagenum << '\n';
00125 
00126     return os;
00127   }
00128 
00129 
00130   //
00131   // PageStats
00132   //
00133 
00134   PageStats::PageStats(Database *db)
00135   {
00136     Status s = db->getDatafiles(datafiles, datafile_cnt);
00137     if (s) {
00138       cerr << "Exception catcher in PageStats::PageStats: " << s;
00139       throw *s;
00140     }
00141 
00142     pgs = new PGS[datafile_cnt];
00143     for (int i = 0; i < datafile_cnt; i++)
00144       pgs[i].init(datafiles[i]);
00145   }
00146 
00147   void
00148   PageStats::add(const ObjectLocation &loc)
00149   {
00150     pgs[loc.getDatid()].add(loc);
00151   }
00152 
00153   PageStats::~PageStats()
00154   {
00155     delete [] pgs;
00156   }
00157 
00158   ostream &operator<<(ostream &os, const PageStats::PGS &pgs);
00159 
00160   ostream &operator<<(ostream &os, const PageStats &pgs)
00161   {
00162     os << ">>>> Page Statistics <<<<\n";
00163     for (int i = 0; i < pgs.datafile_cnt; i++)
00164       if (pgs.pgs[i].oid_cnt)
00165         os << '\n' << pgs.pgs[i];
00166     return os;
00167   }
00168 
00169   //
00170   // PageStats::PGS
00171   //
00172 
00173   static int pgsize_pow2 = eyedbsm::power2(getpagesize());
00174 
00175   inline unsigned int
00176   size2slot(unsigned int sz, unsigned int pow2)
00177   {
00178     return ((sz-1) >> pow2) + 1;
00179   }
00180 
00181   inline unsigned int
00182   ideal(unsigned int sz)
00183   {
00184     return sz ? (((sz-1) >> pgsize_pow2) + 1) :  0;
00185   }
00186 
00187 #define ONE_K 1024
00188 
00189   void
00190   PageStats::PGS::init(const Datafile *_datafile)
00191   {
00192     if (!_datafile->isValid()) {
00193       oid_cnt = 0;
00194       datafile = 0;
00195       return;
00196     }
00197 
00198     datafile = _datafile;
00199     slotsize = datafile->getSlotsize();
00200     slotpow2 = eyedbsm::power2(slotsize);
00201     unsigned long long maxsize =
00202       ((unsigned long long)datafile->getMaxsize()) * ONE_K;
00203 
00204     totalsize = 0;
00205     totalsize_align = 0;
00206 
00207     totaldatpages_max = (maxsize >> pgsize_pow2) + 1;
00208     totaldatpages = (char *)calloc(totaldatpages_max, 1);
00209     totaldatpages_cnt = 0;
00210 
00211     totalomppages_max = 0;
00212     totalomppages = 0;
00213     totalomppages_cnt = 0;
00214 
00215     totaldmppages_max = ((maxsize / slotsize * 8) >> pgsize_pow2) + 1;
00216     totaldmppages = (char *)calloc(totaldmppages_max, 1);
00217     totaldmppages_cnt = 0;
00218 
00219     oid_cnt = 0;
00220   }
00221 
00222   void
00223   PageStats::PGS::add(const ObjectLocation &loc)
00224   {
00225     const ObjectLocation::Info &info = loc.getInfo();
00226     unsigned int size = loc.getSize() + sizeof(eyedbsm::ObjectHeader);
00227     totalsize += size;
00228     totalsize_align += size2slot(size, slotpow2) * slotsize;
00229 
00230     assert (info.dat_start_pagenum < totaldatpages_max);
00231     assert (info.dat_end_pagenum < totaldatpages_max);
00232 
00233     for (int n = info.dat_start_pagenum; n <= info.dat_end_pagenum; n++)
00234       if (!totaldatpages[n]) {
00235         totaldatpages[n] = 1;
00236         totaldatpages_cnt++;
00237       }
00238 
00239     assert (info.dmp_start_pagenum < totaldmppages_max);
00240     assert (info.dmp_end_pagenum < totaldmppages_max);
00241 
00242     for (int n = info.dmp_start_pagenum; n <= info.dmp_end_pagenum; n++)
00243       if (!totaldmppages[n]) {
00244         totaldmppages[n] = 1;
00245         totaldmppages_cnt++;
00246       }
00247 
00248     if (info.omp_end_pagenum >= totalomppages_max) {
00249       totalomppages_max = info.omp_end_pagenum + 64;
00250       totalomppages = (char *)realloc(totalomppages, totalomppages_max);
00251     }
00252 
00253     if (info.omp_start_pagenum != ~0)
00254       for (int n = info.omp_start_pagenum; n <= info.omp_end_pagenum; n++)
00255         if (!totalomppages[n]) {
00256           totalomppages[n] = 1;
00257           totalomppages_cnt++;
00258         }
00259 
00260     oid_cnt++;
00261   }
00262 
00263   extern void
00264   display_datsize(ostream &os, unsigned long long _sz);
00265 
00266   /*
00267     void
00268     display_datsize(ostream &os, unsigned long long sz)
00269     {
00270     os << sz << "b";
00271     sz /= ONE_K;
00272     if (sz)
00273     {
00274     os << ", " << sz << "Kb";
00275     sz /= ONE_K;
00276     if (sz)
00277     {
00278     os << ", " << sz << "~Mb";
00279     sz /= ONE_K;
00280     if (sz)
00281     os << ", " << sz << "~Gb";
00282     }
00283     }
00284 
00285     os << '\n';
00286     }
00287   */
00288 
00289   ostream &operator<<(ostream &os, const PageStats::PGS &pgs)
00290   {
00291     os << "Datafile #" << pgs.datafile->getId();
00292     if (*pgs.datafile->getName())
00293       os << " " << pgs.datafile->getName();
00294     else
00295       os << " File: " << pgs.datafile->getFile();
00296     os << '\n';
00297     os << "  Oid Type: " <<
00298       (pgs.datafile->isPhysical() ? "Physical" : "Logical") << '\n';
00299     if (pgs.datafile->getDataspace())
00300       os << "  Dataspace: " << pgs.datafile->getDataspace()->getName() << '\n';
00301     os << "  Object Count: " << pgs.oid_cnt << '\n';
00302     os << "  Size: ";
00303     display_datsize(os, pgs.totalsize);
00304     os << "  .dat Page Count:\n";
00305     os << "      Effective: " << pgs.totaldatpages_cnt << '\n';
00306     os << "      Ideal:  " << ideal(pgs.totalsize) <<
00307       " (slot based: " << ideal(pgs.totalsize_align) << ")\n";
00308     if (pgs.totalomppages_cnt) {
00309       os << "  .omp Page Count:\n";
00310       os << "      Effective: " << pgs.totalomppages_cnt << '\n';
00311       os << "      Ideal: " << 
00312         (pgs.oid_cnt ? ((pgs.oid_cnt * OIDLOCSIZE) >> pgsize_pow2) + 1 : 0) <<
00313         '\n';
00314     }
00315 
00316     os << "  .dmp Page Count:\n";
00317     os << "      Effective: " << pgs.totaldmppages_cnt << '\n';
00318     os << "      Ideal: " << 
00319       (pgs.totalsize_align ?
00320        ((((pgs.totalsize_align-1)/(pgs.slotsize*8))>>pgsize_pow2)+1) : 0) <<
00321       '\n';
00322     return os;
00323   }
00324 
00325 }
00326 
00327 

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