packing: Bug fix: Extend could create a too big page

Closes #1454
This commit is contained in:
Hajime Hoshi 2020-12-31 17:33:24 +09:00
parent f292594184
commit b6bc683991
2 changed files with 51 additions and 10 deletions

View File

@ -217,13 +217,20 @@ func (p *Page) Extend(count int) bool {
if p.size >= p.maxSize { if p.size >= p.maxSize {
return false return false
} }
newSize := p.size newSize := p.size
for i := 0; i < count; i++ { for i := 0; i < count; i++ {
newSize *= 2 newSize *= 2
} }
if newSize > p.maxSize {
return false
}
edgeNodes := []*Node{} edgeNodes := []*Node{}
abort := errors.New("abort") abort := errors.New("abort")
aborted := false aborted := false
if p.root != nil {
_ = walk(p.root, func(n *Node) error { _ = walk(p.root, func(n *Node) error {
if n.x+n.width < p.size && n.y+n.height < p.size { if n.x+n.width < p.size && n.y+n.height < p.size {
return nil return nil
@ -235,6 +242,8 @@ func (p *Page) Extend(count int) bool {
edgeNodes = append(edgeNodes, n) edgeNodes = append(edgeNodes, n)
return nil return nil
}) })
}
if aborted { if aborted {
origRoot := *p.root origRoot := *p.root
@ -306,6 +315,7 @@ func (p *Page) Extend(count int) bool {
} }
p.size = newSize p.size = newSize
return true return true
} }

View File

@ -328,3 +328,34 @@ func TestExtend2(t *testing.T) {
t.Errorf("p.Alloc(%d, %d) must fail but not", s, s) t.Errorf("p.Alloc(%d, %d) must fail but not", s, s)
} }
} }
// Issue #1454
func TestExtendTooMuch(t *testing.T) {
p := NewPage(1024, 4096)
p.Alloc(1, 1)
if got, want := p.Extend(3), false; got != want {
t.Errorf("got: %t, want: %t", got, want)
}
}
func TestExtendWithoutAllocation(t *testing.T) {
p := NewPage(1024, 4096)
if got, want := p.Extend(2), true; got != want {
t.Errorf("got: %t, want: %t", got, want)
}
p.RollbackExtension()
if got, want := p.Size(), 1024; got != want {
t.Errorf("p.Size(): got: %d, want: %d", got, want)
}
if got, want := p.Extend(2), true; got != want {
t.Errorf("got: %t, want: %t", got, want)
}
p.CommitExtension()
if got, want := p.Size(), 4096; got != want {
t.Errorf("p.Size(): got: %d, want: %d", got, want)
}
}