00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
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
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
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
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