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:
parent
86348031c2
commit
fed962f059
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
22
lib/rpmdb.c
22
lib/rpmdb.c
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue