diff options
author | Martin Kobetic <mkobetic@gmail.com> | 2014-05-09 20:50:55 +0000 |
---|---|---|
committer | Martin Kobetic <mkobetic@gmail.com> | 2014-05-09 20:50:55 +0000 |
commit | b9899d09ab6c032b54fe4a09e9389dff28d8a7f8 (patch) | |
tree | 30a0bdbcd865fd26bbb268afab23f3f68d3f692a /bucket.go | |
parent | Merge pull request #160 from benbjohnson/fix-deletion (diff) | |
download | dedo-b9899d09ab6c032b54fe4a09e9389dff28d8a7f8.tar.gz dedo-b9899d09ab6c032b54fe4a09e9389dff28d8a7f8.tar.xz |
first part
Diffstat (limited to 'bucket.go')
-rw-r--r-- | bucket.go | 43 |
1 files changed, 38 insertions, 5 deletions
@@ -129,16 +129,23 @@ func (b *Bucket) Bucket(name []byte) *Bucket { } // Otherwise create a bucket and cache it. - var child = newBucket(b.tx) - child.bucket = &bucket{} - *child.bucket = *(*bucket)(unsafe.Pointer(&v[0])) - b.buckets[string(name)] = &child + var child = b.openBucket(v) + b.buckets[string(name)] = child // Save a reference to the inline page if the bucket is inline. if child.root == 0 { child.page = (*page)(unsafe.Pointer(&v[bucketHeaderSize])) } + return child +} + +// Helper method that re-interprets a sub-bucket value +// 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])) return &child } @@ -354,7 +361,7 @@ func (b *Bucket) ForEach(fn func(k, v []byte) error) error { // Stat returns stats on a bucket. func (b *Bucket) Stats() BucketStats { - var s BucketStats + var s, subStats BucketStats pageSize := b.tx.db.pageSize b.forEachPage(func(p *page, depth int) { if (p.flags & leafPageFlag) != 0 { @@ -365,6 +372,13 @@ func (b *Bucket) Stats() BucketStats { used += int(lastElement.pos + lastElement.ksize + lastElement.vsize) s.LeafInuse += used s.LeafOverflowN += int(p.overflow) + + // Recurse into sub-buckets + for _, e := range p.leafPageElements() { + if e.flags&bucketLeafFlag != 0 { + subStats.Add(b.openBucket(e.value()).Stats()) + } + } } else if (p.flags & branchPageFlag) != 0 { s.BranchPageN++ lastElement := p.branchPageElement(p.count - 1) @@ -380,6 +394,10 @@ func (b *Bucket) Stats() BucketStats { }) s.BranchAlloc = (s.BranchPageN + s.BranchOverflowN) * pageSize s.LeafAlloc = (s.LeafPageN + s.LeafOverflowN) * pageSize + + // add the max depth of sub-buckets to get total nested depth + s.Depth += subStats.Depth + s.Add(subStats) return s } @@ -643,6 +661,21 @@ type BucketStats struct { LeafInuse int // bytes actually used for leaf data } +func (s *BucketStats) Add(other BucketStats) { + s.BranchPageN += other.BranchPageN + s.BranchOverflowN += other.BranchOverflowN + s.LeafPageN += other.LeafPageN + s.LeafOverflowN += other.LeafOverflowN + s.KeyN += s.KeyN + if s.Depth < other.Depth { + s.Depth = other.Depth + } + s.BranchAlloc += other.BranchAlloc + s.BranchInuse += other.BranchInuse + s.LeafAlloc += other.LeafAlloc + s.LeafInuse += other.LeafInuse +} + // cloneBytes returns a copy of a given slice. func cloneBytes(v []byte) []byte { var clone = make([]byte, len(v)) |