Merge branch 'pool_allocate' of https://github.com/LK4D4/bolt into LK4D4-pool_allocate

master
Ben Johnson 2016-04-22 14:16:02 -06:00
commit 9145d586f2
No known key found for this signature in database
GPG Key ID: 780E98C6BEDA0915
2 changed files with 30 additions and 4 deletions

18
db.go
View File

@ -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.
@ -321,7 +324,7 @@ func (db *DB) mmapSize(size int) (int, error) {
// init creates a new database file and initializes its meta pages.
func (db *DB) init() error {
// Set the page size to the OS page size.
db.pageSize = os.Getpagesize()
db.pageSize = defaultPageSize
// Create two meta pages on a buffer.
buf := make([]byte, db.pageSize*4)
@ -784,10 +787,21 @@ func (db *DB) meta() *meta {
return db.meta1
}
var pagePool = sync.Pool{
New: func() interface{} {
return make([]byte, defaultPageSize)
},
}
// 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 && db.pageSize == defaultPageSize {
buf = pagePool.Get().([]byte)
} else {
buf = make([]byte, count*db.pageSize)
}
p := (*page)(unsafe.Pointer(&buf[0]))
p.overflow = uint32(count - 1)

16
tx.go
View File

@ -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,18 @@ func (tx *Tx) write() error {
}
}
// Clear out page cache.
tx.pages = make(map[pgid]*page)
// put small pages back to sync.Pool
for _, p := range pages {
if int(p.overflow) != 0 || tx.db.pageSize != defaultPageSize {
continue
}
buf := (*[maxAllocSize]byte)(unsafe.Pointer(p))[:defaultPageSize]
// See https://go.googlesource.com/go/+/f03c9202c43e0abb130669852082117ca50aa9b1
for i := range buf {
buf[i] = 0
}
pagePool.Put(buf)
}
return nil
}