From 686b6a334173c40ae91d3cdd7d7d759bf8851df6 Mon Sep 17 00:00:00 2001 From: Ben Johnson Date: Wed, 2 Apr 2014 15:36:53 -0600 Subject: Add performance counters. This commit adds performance counters for each transaction which are rolled up to the database level on each commit/rollback. Counters are meant to be a very fast way to track what is going on in the database. A few timers are also added in areas where the time.Now() overhead is not noticible. The DB.Stat() function is now deprecated since the `bolt` CLI now performs similar functions. Fixes #108. --- db.go | 67 +++++++++++++++++++++++-------------------------------------------- 1 file changed, 23 insertions(+), 44 deletions(-) (limited to 'db.go') diff --git a/db.go b/db.go index e4a4f9c..c43eb5c 100644 --- a/db.go +++ b/db.go @@ -40,6 +40,7 @@ type DB struct { rwtx *Tx txs []*Tx freelist *freelist + stats Stats rwlock sync.Mutex // Allows only one writer at a time. metalock sync.Mutex // Protects meta page access. @@ -374,6 +375,9 @@ func (db *DB) removeTx(t *Tx) { break } } + + // Merge statistics. + db.stats.TxStats.add(&t.stats) } // Update executes a function within the context of a read-write managed transaction. @@ -490,32 +494,12 @@ func (db *DB) CopyFile(path string, mode os.FileMode) error { return f.Close() } -// Stat retrieves stats on the database and its page usage. -// Returns an error if the database is not open. -func (db *DB) Stat() (*Stat, error) { - // Obtain meta & mmap locks. +// Stats retrieves ongoing performance stats for the database. +// This is only updated when a transaction closes. +func (db *DB) Stats() Stats { db.metalock.Lock() - db.mmaplock.RLock() - - var s = &Stat{ - MmapSize: len(db.data), - TxCount: len(db.txs), - } - - // Release locks. - db.mmaplock.RUnlock() - db.metalock.Unlock() - - err := db.Update(func(t *Tx) error { - s.PageCount = int(t.meta.pgid) - s.FreePageCount = len(db.freelist.all()) - s.PageSize = db.pageSize - return nil - }) - if err != nil { - return nil, err - } - return s, nil + defer db.metalock.Unlock() + return db.stats } // Check performs several consistency checks on the database. @@ -625,25 +609,20 @@ func (db *DB) allocate(count int) (*page, error) { return p, nil } -// Stat represents stats on the database such as free pages and sizes. -type Stat struct { - // PageCount is the total number of allocated pages. This is a high water - // mark in the database that represents how many pages have actually been - // used. This will be smaller than the MmapSize / PageSize. - PageCount int - - // FreePageCount is the total number of pages which have been previously - // allocated but are no longer used. - FreePageCount int - - // PageSize is the size, in bytes, of individual database pages. - PageSize int +// Stats represents statistics about the database. +type Stats struct { + TxStats TxStats // global, ongoing stats. +} - // MmapSize is the mmap-allocated size of the data file. When the data file - // grows beyond this size, the database will obtain a lock on the mmap and - // resize it. - MmapSize int +// Sub calculates and returns the difference between two sets of database stats. +// This is useful when obtaining stats at two different points and time and +// you need the performance counters that occurred within that time span. +func (s *Stats) Sub(other *Stats) Stats { + var diff Stats + diff.TxStats = s.TxStats.Sub(&other.TxStats) + return diff +} - // TxCount is the total number of reader transactions. - TxCount int +func (s *Stats) add(other *Stats) { + s.TxStats.add(&other.TxStats) } -- cgit v1.2.3