diff options
author | Ben Johnson <benbjohnson@yahoo.com> | 2016-04-22 14:33:50 -0600 |
---|---|---|
committer | Ben Johnson <benbjohnson@yahoo.com> | 2016-04-22 14:33:50 -0600 |
commit | e8ca7db0e78d9513478d5c833410a5921495ca13 (patch) | |
tree | 71b7cc794ba1601f68fa49a508efa72e2eb6e915 | |
parent | Merge pull request #550 from ChrisHines/windows-remove-lock (diff) | |
parent | move page pool to db (diff) | |
download | dedo-e8ca7db0e78d9513478d5c833410a5921495ca13.tar.gz dedo-e8ca7db0e78d9513478d5c833410a5921495ca13.tar.xz |
Merge branch 'LK4D4-pool_allocate'
-rw-r--r-- | db.go | 19 | ||||
-rw-r--r-- | tx.go | 20 |
2 files changed, 36 insertions, 3 deletions
@@ -36,6 +36,9 @@ const ( DefaultAllocSize = 16 * 1024 * 1024 ) +// default page size for db is set to the OS page size. +var defaultPageSize = os.Getpagesize() + // DB represents a collection of buckets persisted to a file on disk. // All data access is performed through transactions which can be obtained through the DB. // All the functions on DB will return a ErrDatabaseNotOpen if accessed before Open() is called. @@ -107,6 +110,8 @@ type DB struct { freelist *freelist stats Stats + pagePool sync.Pool + batchMu sync.Mutex batch *batch @@ -206,6 +211,13 @@ func Open(path string, mode os.FileMode, options *Options) (*DB, error) { } } + // Initialize page pool. + db.pagePool = sync.Pool{ + New: func() interface{} { + return make([]byte, db.pageSize) + }, + } + // Memory map the data file. if err := db.mmap(options.InitialMmapSize); err != nil { _ = db.close() @@ -787,7 +799,12 @@ func (db *DB) meta() *meta { // allocate returns a contiguous block of memory starting at a given page. func (db *DB) allocate(count int) (*page, error) { // Allocate a temporary buffer for the page. - buf := make([]byte, count*db.pageSize) + var buf []byte + if count == 1 { + buf = db.pagePool.Get().([]byte) + } else { + buf = make([]byte, count*db.pageSize) + } p := (*page)(unsafe.Pointer(&buf[0])) p.overflow = uint32(count - 1) @@ -473,6 +473,8 @@ func (tx *Tx) write() error { for _, p := range tx.pages { pages = append(pages, p) } + // Clear out page cache early. + tx.pages = make(map[pgid]*page) sort.Sort(pages) // Write pages to disk in order. @@ -517,8 +519,22 @@ func (tx *Tx) write() error { } } - // Clear out page cache. - tx.pages = make(map[pgid]*page) + // Put small pages back to page pool. + for _, p := range pages { + // Ignore page sizes over 1 page. + // These are allocated using make() instead of the page pool. + if int(p.overflow) != 0 { + continue + } + + buf := (*[maxAllocSize]byte)(unsafe.Pointer(p))[:tx.db.pageSize] + + // See https://go.googlesource.com/go/+/f03c9202c43e0abb130669852082117ca50aa9b1 + for i := range buf { + buf[i] = 0 + } + tx.db.pagePool.Put(buf) + } return nil } |