Generate package database statistics on close & make use of it on open

- Turn dbiStat() into more useful: return the number of keys in the
  index, hiding away the BDB internal access method stuff into the backend
- Force statistics gathering at Packages db close, take advantage of
  that when its opened to get a fairly accurate count of packages for
  initial "header verified" bitmap allocation. Previously DB_FAST_STAT
  was used on open but it never returns anything when no stats have
  been previously collected, hence the need for the expensive slow stat.
- The performance hit from stat generation is hardly worth it for
  the bitmap allocation alone, but lets see if there are other uses...
- Also gets rid of dbi_stats member, this is not particularly useful
This commit is contained in:
Panu Matilainen 2010-04-01 15:28:45 +03:00
parent 86348031c2
commit fed962f059
4 changed files with 33 additions and 27 deletions

View File

@ -350,21 +350,27 @@ dbiIndexType dbiType(dbiIndex dbi)
return dbi->dbi_type;
}
int dbiStat(dbiIndex dbi, unsigned int flags)
int dbiNumKeys(dbiIndex dbi, int fast)
{
DB * db = dbi->dbi_db;
DB_TXN * txnid = NULL;
int rc = 0;
int rc, nkeys = -1;
void *sp = NULL;
assert(db != NULL);
if (flags)
flags = DB_FAST_STAT;
else
flags = 0;
dbi->dbi_stats = _free(dbi->dbi_stats);
rc = db->stat(db, txnid, &dbi->dbi_stats, flags);
rc = db->stat(db, dbi->dbi_txnid, &sp, fast ? DB_FAST_STAT : 0);
rc = cvtdberr(dbi, "db->stat", rc, _debug);
return rc;
if (rc == 0 && sp) {
if (dbi->dbi_dbtype == DB_HASH) {
DB_HASH_STAT *hash = sp;
nkeys = hash->hash_nkeys;
} else if (dbi->dbi_dbtype == DB_BTREE) {
DB_BTREE_STAT *btree = sp;
nkeys = btree->bt_nkeys;
}
free(sp);
}
return nkeys;
}
int dbiVerify(dbiIndex dbi, unsigned int flags)

View File

@ -119,7 +119,6 @@ static const struct poptOption rdbOptions[] = {
dbiIndex dbiFree(dbiIndex dbi)
{
if (dbi) {
dbi->dbi_stats = _free(dbi->dbi_stats);
dbi = _free(dbi);
}
return dbi;

View File

@ -49,7 +49,6 @@ struct _dbiIndex {
DB * dbi_db; /*!< Berkeley DB * handle */
DB_TXN * dbi_txnid; /*!< Bekerley DB_TXN * transaction id */
void * dbi_stats; /*!< Berkeley db statistics */
};
/** \ingroup dbi
@ -197,13 +196,13 @@ RPM_GNUC_INTERNAL
int dbiByteSwapped(dbiIndex dbi);
/** \ingroup dbi
* Is database byte swapped?
* Return number of keys in index
* @param dbi index database handle
* @param flags DB_FAST_STAT or 0
* @return 0 on success
* @param fast fast, cached estimate or slow but accurate?
* @return number of keys in index, -1 on error
*/
RPM_GNUC_INTERNAL
int dbiStat(dbiIndex dbi, unsigned int flags);
int dbiNumKeys(dbiIndex dbi, int fast);
/** \ingroup dbi
* Type of dbi (primary data / index)

View File

@ -178,20 +178,15 @@ static dbiIndex rpmdbOpenIndex(rpmdb db, rpmTag rpmtag, unsigned int flags)
if (dbi != NULL && rc == 0) {
db->_dbi[dbix] = dbi;
/* Grab a fast estimate of package count for allocation */
if (rpmtag == RPMDBI_PACKAGES && db->db_bits == NULL) {
db->db_nbits = 1024;
if (!dbiStat(dbi, DB_FAST_STAT)) {
DB_HASH_STAT * hash = (DB_HASH_STAT *)dbi->dbi_stats;
if (hash)
db->db_nbits += hash->hash_nkeys;
}
int nkeys = dbiNumKeys(dbi, 1);
db->db_nbits = 1024 + (nkeys > 0 ? nkeys : 0);
db->db_bits = PBM_ALLOC(db->db_nbits);
}
}
#ifdef HAVE_DB_H
else
} else {
dbi = dbiFree(dbi);
#endif
}
/* FIX: db->_dbi may be NULL */
return dbi;
@ -687,6 +682,13 @@ int rpmdbClose(rpmdb db)
int xx;
if (db->_dbi[dbix] == NULL)
continue;
/* Force full statistics generation at package db close */
if (dbiTags[dbix] == RPMDBI_PACKAGES &&
(db->db_mode & O_ACCMODE) != O_RDONLY) {
(void) dbiNumKeys(db->_dbi[dbix], 0);
}
xx = dbiClose(db->_dbi[dbix], 0);
if (xx && rc == 0) rc = xx;
db->_dbi[dbix] = NULL;