diff options
author | Ben Johnson <benbjohnson@yahoo.com> | 2014-05-27 08:28:06 -0600 |
---|---|---|
committer | Ben Johnson <benbjohnson@yahoo.com> | 2014-05-27 08:28:06 -0600 |
commit | 746dbb35662b9509675e5fcaef16da0f6a50bb6b (patch) | |
tree | b4babe3723366ced308e32782b1235165fbac8f1 /bucket.go | |
parent | Avoid trashing page cache on Tx.Copy(). (diff) | |
parent | Merge pull request #172 from benbjohnson/allocation (diff) | |
download | dedo-746dbb35662b9509675e5fcaef16da0f6a50bb6b.tar.gz dedo-746dbb35662b9509675e5fcaef16da0f6a50bb6b.tar.xz |
Merge branch 'master' of https://github.com/boltdb/bolt
Diffstat (limited to 'bucket.go')
-rw-r--r-- | bucket.go | 23 |
1 files changed, 17 insertions, 6 deletions
@@ -76,8 +76,8 @@ type bucket struct { // newBucket returns a new bucket associated with a transaction. func newBucket(tx *Tx) Bucket { var b = Bucket{tx: tx} - b.buckets = make(map[string]*Bucket) if tx.writable { + b.buckets = make(map[string]*Bucket) b.nodes = make(map[pgid]*node) } return b @@ -115,8 +115,10 @@ func (b *Bucket) Cursor() *Cursor { // Bucket retrieves a nested bucket by name. // Returns nil if the bucket does not exist. func (b *Bucket) Bucket(name []byte) *Bucket { - if child := b.buckets[string(name)]; child != nil { - return child + if b.buckets != nil { + if child := b.buckets[string(name)]; child != nil { + return child + } } // Move cursor to key. @@ -130,7 +132,9 @@ func (b *Bucket) Bucket(name []byte) *Bucket { // Otherwise create a bucket and cache it. var child = b.openBucket(v) - b.buckets[string(name)] = child + if b.buckets != nil { + b.buckets[string(name)] = child + } return child } @@ -139,8 +143,15 @@ func (b *Bucket) Bucket(name []byte) *Bucket { // from a parent into a Bucket func (b *Bucket) openBucket(value []byte) *Bucket { var child = newBucket(b.tx) - child.bucket = &bucket{} - *child.bucket = *(*bucket)(unsafe.Pointer(&value[0])) + + // If this is a writable transaction then we need to copy the bucket entry. + // Read-only transactions can point directly at the mmap entry. + if b.tx.writable { + child.bucket = &bucket{} + *child.bucket = *(*bucket)(unsafe.Pointer(&value[0])) + } else { + child.bucket = (*bucket)(unsafe.Pointer(&value[0])) + } // Save a reference to the inline page if the bucket is inline. if child.root == 0 { |