📄 amdb_wkldprofile.cc
字号:
// (don't save TraversalStats.children) TraversalStatsMap& tsMap = statsTotals.traversalStats; TraversalStatsMap::size_type traversalStatsSize = tsMap.size(); s.write((char *) &traversalStatsSize, sizeof(traversalStatsSize)); TraversalStatsMap::iterator it; for (it = tsMap.begin(); it != tsMap.end(); it++) { TraversalStats* ts = (TraversalStats *) (*it).second; s.write((char *) &ts->pageno, TraversalStats::SIZE); } // save statsTotals.stats s.write((char *) &statsTotals.stats, sizeof(statsTotals.stats)); // check for errors if (!s) return(eFILEERROR); return(RCOK);}/////////////////////////////////////////////////////////////////////////// amdb_wkldprofile::read - read binary profile from file//// Description://// Return Values:// RCOK// eFILEERROR/////////////////////////////////////////////////////////////////////////rc_tamdb_wkldprofile::read( istream& s) // in{ cout << "amdb_wkldprofile::read()" << endl; clear(); // delete current data, if there is any // read queries //cout << "read queries" << endl; QueryVect::size_type queriesSize; s.read((char *) &queriesSize, sizeof(queriesSize)); queries.reserve(queriesSize); unsigned queryno; for (queryno = 0; queryno < queriesSize; queryno++) { Query* q = new Query(); queries.push_back((void *) q); // read queries.retrLimit s.read((char *) &q->retrLimit, sizeof(q->retrLimit)); // read queries.qual int len; s.read((char *) &len, sizeof(len)); if (len > 0) { q->qual = new char[len+1]; s.read(q->qual, len); q->qual[len] = '\0'; } // read queries.resultSet s.read((char *) &q->resultSetSize, sizeof(q->resultSetSize)); q->resultSet = new ItemId[q->resultSetSize]; int i; for (i = 0; i < q->resultSetSize; i++) { s.read((char *) &q->resultSet[i], sizeof(q->resultSet[i])); } // read queries.emptyLeaves s.read((char *) &q->numEmptyLeaves, sizeof(q->numEmptyLeaves)); q->emptyLeaves = new shpid_t[q->numEmptyLeaves]; for (i = 0; i < q->numEmptyLeaves; i++) { s.read((char *) &q->emptyLeaves[i], sizeof(q->emptyLeaves[i])); } // read queries.traversalStats s.read((char *) &q->traversalStatsSize, sizeof(q->traversalStatsSize)); q->traversalStats = new InternalTraversalStats[q->traversalStatsSize]; int statno; for (statno = 0; statno < q->traversalStatsSize; statno++) { InternalTraversalStats& ts = q->traversalStats[statno]; s.read((char *) &ts, sizeof(ts)); } // read queries.stats s.read((char *) &q->stats, sizeof(q->stats)); } // read statsTotals.retrievedCnt s.read((char *) &statsTotals.retrievedCnt, sizeof(statsTotals.retrievedCnt)); // read statsTotals.dataCoverage s.read((char *) &statsTotals.dataCoverage, sizeof(statsTotals.dataCoverage)); // read statsTotals.traversalStats //cout << "read statsTotals.traversalStats" << endl; TraversalStatsMap::size_type traversalStatsSize; s.read((char *) &traversalStatsSize, sizeof(traversalStatsSize)); unsigned i; for (i = 0; i < traversalStatsSize; i++) { TraversalStats* ts = new TraversalStats(); s.read((char *) &ts->pageno, TraversalStats::SIZE); statsTotals.traversalStats[ts->pageno] = (void *) ts; } // read statsTotals.stats s.read((char *) &statsTotals.stats, sizeof(statsTotals.stats)); // check for errors if (!s) { return(eFILEERROR); } return(RCOK);}/////////////////////////////////////////////////////////////////////////// amdb_wkldprofile::traversePage - record newly traversed page//// Description:// - create new entry for traversed page and updates its // parent's child info/////////////////////////////////////////////////////////////////////////voidamdb_wkldprofile::traversePage( shpid_t pageno, bool isLeaf, shpid_t parentno){ // create new entry for node TraversalStats* stats = new TraversalStats(pageno); // record in TraversalStats map for currently executing query _traversalStats[pageno] = (void *) stats; stats->traversalCnt = 1; stats->isLeaf = isLeaf; if (pageno != parentno) { // update parent's child info TraversalStats* parent = (TraversalStats *) _traversalStats[parentno]; parent->children.push_back((void *) pageno); }}/////////////////////////////////////////////////////////////////////////// amdb_wkldprofile::countRetrievals -// record # of retrieved items and total size in bytes//// Description://///////////////////////////////////////////////////////////////////////void amdb_wkldprofile::countRetrievals( shpid_t pageno, int numMatches, int matches[]){ TraversalStats* stats = (TraversalStats *) _traversalStats[pageno]; stats->retrievalCnt += numMatches; // for the retrieved data volume, consult the tree map int i; for (i = 0; i < numMatches; i++) { const amdb_treemap::PageInfo *pageInfo = NULL; pageInfo = _treeMap->pageInfo(pageno); assert(pageInfo != NULL); const amdb_treemap::RecInfo *recInfo = NULL; recInfo = _treeMap->itemInfo(pageInfo->itemOffset + matches[i]); stats->retrievalVol += recInfo->size; }}/////////////////////////////////////////////////////////////////////////// amdb_wkldprofile::_finalizeQuery - recursively complete TraversalStats//// Description:// - recursively complete TraversalStats.emptyNode, .emptySubtree and// .retrievalCnt of current query/////////////////////////////////////////////////////////////////////////voidamdb_wkldprofile::_finalizeQuery( shpid_t subtreeRoot){ TraversalStats* stats = (TraversalStats *) _traversalStats[subtreeRoot]; assert(stats != NULL); if (!stats->isLeaf) { // finalize child subtrees and add up this node's retrieval count for (TraversalStats::ChildVector::iterator it = stats->children.begin(); it != stats->children.end(); it++) { _finalizeQuery((shpid_t) *it); TraversalStats* childStats = (TraversalStats *) _traversalStats[(shpid_t) *it]; stats->retrievalCnt += childStats->retrievalCnt; // parent = sum of children } } if (stats->retrievalCnt == 0) { stats->emptySubtree = 1; if (stats->children.size() == 0) { stats->emptyNode = 1; } }}/////////////////////////////////////////////////////////////////////////// amdb_wkldprofile::addQuery - append new query to 'queries'//// Description:// - new query becomes current query/////////////////////////////////////////////////////////////////////////voidamdb_wkldprofile::addQuery(){ Query* query = new Query(); queries.push_back((void *) query);}/////////////////////////////////////////////////////////////////////////// amdb_wkldprofile::addToResultSet - add item to res. set of current query//// Description:///////////////////////////////////////////////////////////////////////////voidamdb_wkldprofile::addToResultSet( shpid_t leaf, unsigned idx){ // update result set of current query unsigned itemNo = _treeMap->itemOffset(leaf) + idx; _resultSet.push_back((void *) itemNo);}/////////////////////////////////////////////////////////////////////////// amdb_wkldprofile::computeTotals - compute statsTotals.*, except for traversalStats//// Description:// - for dataCoverage, first extract result sets, then use those// to compute a map of retrieved items; its size is the data coverage/////////////////////////////////////////////////////////////////////////voidamdb_wkldprofile::computeTotals(){ QueryVect::iterator it; for (it = queries.begin(); it != queries.end(); it++) { Query* query = (Query *) *it; statsTotals.retrievedCnt += query->resultSetSize; // statsTotals.traversalStats updated in finalizeQuery() // update statsTotals.stats statsTotals.stats.leafStats.avgUtil += query->stats.leafStats.avgUtil; statsTotals.stats.leafStats.retrievalVol += query->stats.leafStats.retrievalVol; statsTotals.stats.leafStats.totalIos += query->stats.leafStats.totalIos; statsTotals.stats.internalStats.totalIos += query->stats.internalStats.totalIos; } // finalize avgUtil statsTotals.stats.leafStats.avgUtil /= queries.size(); // compute dataCoverage amdb_clustering::ResultSet* resultSets; extractResultSets(resultSets); Map retrMap; // map<itemno, itemno>: from orig to condensed item no. int dummyInt; amdb_clustering::extractRetrieved(resultSets, queries.size(), retrMap, dummyInt); statsTotals.dataCoverage = retrMap.size(); delete [] resultSets; // not needed any longer}/////////////////////////////////////////////////////////////////////////// amdb_wkldprofile::finalizeQuery - compute query stats after query terminates//// Description:// - compute TraversalStats.retrievalCnt for internal nodes, .emptyNodes// and .emptySubtree for all nodes. Compute QueryStats.// - copy _resultSet and traversalStats to Query struct of finished query and// store empty leaf traversals in emptyLeaves///////////////////////////////////////////////////////////////////////////voidamdb_wkldprofile::finalizeQuery( shpid_t rootNo){ _finalizeQuery(rootNo); // compute part of Query.stats (avgUtil, excCovLoss) Query* query = (Query *) queries.back(); float avgUtil = 0.0; int numNonEmptyLeaves = 0; int numEmptyLeaves = 0; TraversalStatsMap::iterator tsIt; for (tsIt = _traversalStats.begin(); tsIt != _traversalStats.end(); tsIt++) { TraversalStats* ts = (TraversalStats *) (*tsIt).second; // update QueryStats.leafStats and .internalStats (totalIos, excCovLoss, // utilLoss) if (ts->isLeaf) { query->stats.leafStats.totalIos++; if (ts->retrievalCnt != 0) { // determine avg util and retrieval vol. for non-empty leaves // only compute avg util for non-empty leaves avgUtil += _treeMap->util(ts->pageno); numNonEmptyLeaves++; query->stats.leafStats.retrievalVol += ts->retrievalVol; } else { numEmptyLeaves++; } } else { query->stats.internalStats.totalIos++; } } query->stats.leafStats.avgUtil = avgUtil / (float) numNonEmptyLeaves; // copy _resultSet and traversalStats to query and update statsTotals sort(_resultSet.begin(), _resultSet.end()); // needs to be sorted for evalSplit() query->resultSetSize = _resultSet.size(); query->resultSet = new ItemId[query->resultSetSize]; int i = 0; _ResultSet::iterator rsit; for (rsit = _resultSet.begin(); rsit != _resultSet.end(); rsit++, i++) { query->resultSet[i] = (ItemId) *rsit; } // save empty leaves and traversal stats for internal nodes query->numEmptyLeaves = numEmptyLeaves; if (query->numEmptyLeaves > 0) { query->emptyLeaves = new shpid_t[query->numEmptyLeaves]; } query->traversalStatsSize = query->stats.internalStats.totalIos; query->traversalStats = new InternalTraversalStats[query->traversalStatsSize]; i = 0; int j = 0; TraversalStatsMap::iterator tsit; for (tsit = _traversalStats.begin(); tsit != _traversalStats.end(); tsit++) { // update statsTotals.traversalStats TraversalStats* ts = (TraversalStats *) (*tsit).second; TraversalStats* totalsStats = (TraversalStats *) statsTotals.traversalStats[ts->pageno]; // we didn't pre-allocate statsTotals.traversalStats, so there // might not be an entry for 'pageno'; in that case, allocate and // register it now if (totalsStats == NULL) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -