mirror of https://github.com/etcd-io/bbolt.git
Merge branch 'pool_allocate' of https://github.com/LK4D4/bolt into LK4D4-pool_allocate
commit
9145d586f2
18
db.go
18
db.go
|
@ -36,6 +36,9 @@ const (
|
||||||
DefaultAllocSize = 16 * 1024 * 1024
|
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.
|
// 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 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.
|
// 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.
|
// init creates a new database file and initializes its meta pages.
|
||||||
func (db *DB) init() error {
|
func (db *DB) init() error {
|
||||||
// Set the page size to the OS page size.
|
// Set the page size to the OS page size.
|
||||||
db.pageSize = os.Getpagesize()
|
db.pageSize = defaultPageSize
|
||||||
|
|
||||||
// Create two meta pages on a buffer.
|
// Create two meta pages on a buffer.
|
||||||
buf := make([]byte, db.pageSize*4)
|
buf := make([]byte, db.pageSize*4)
|
||||||
|
@ -784,10 +787,21 @@ func (db *DB) meta() *meta {
|
||||||
return db.meta1
|
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.
|
// allocate returns a contiguous block of memory starting at a given page.
|
||||||
func (db *DB) allocate(count int) (*page, error) {
|
func (db *DB) allocate(count int) (*page, error) {
|
||||||
// Allocate a temporary buffer for the page.
|
// 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 := (*page)(unsafe.Pointer(&buf[0]))
|
||||||
p.overflow = uint32(count - 1)
|
p.overflow = uint32(count - 1)
|
||||||
|
|
||||||
|
|
16
tx.go
16
tx.go
|
@ -473,6 +473,8 @@ func (tx *Tx) write() error {
|
||||||
for _, p := range tx.pages {
|
for _, p := range tx.pages {
|
||||||
pages = append(pages, p)
|
pages = append(pages, p)
|
||||||
}
|
}
|
||||||
|
// Clear out page cache early.
|
||||||
|
tx.pages = make(map[pgid]*page)
|
||||||
sort.Sort(pages)
|
sort.Sort(pages)
|
||||||
|
|
||||||
// Write pages to disk in order.
|
// Write pages to disk in order.
|
||||||
|
@ -517,8 +519,18 @@ func (tx *Tx) write() error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear out page cache.
|
// put small pages back to sync.Pool
|
||||||
tx.pages = make(map[pgid]*page)
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue