Commit 2e9e5cab authored by Kirill Smelkov's avatar Kirill Smelkov

go/zodb/btree: Verify that BTree children are always all of the same kind

They are all either BTree or all Buckets.

See https://github.com/zopefoundation/ZODB/blob/3.10.7-4-gb8d7a8567/src/BTrees/Development.txt#L231
for details
parent 50f570c8
......@@ -331,6 +331,7 @@ func (bt *btreeState) PySetState(pystate interface{}) (err error) {
n := (len(t) + 1) / 2
bt.data = make([]_BTreeItem, 0, n)
var kprev int64
var childrenKind int // 1 - BTree, 2 - Bucket
for i, idx := 0, 0; i < n; i++ {
key := int64(math.Min<Key>) // KEY(-) (qualifies for )
if i > 0 {
......@@ -354,12 +355,23 @@ func (bt *btreeState) PySetState(pystate interface{}) (err error) {
}
kprev = key
// check all children are of the same type
var kind int // see childrenKind ^^^
switch child.(type) {
default:
return fmt.Errorf("data: [%d]: child must be BTree|Bucket; got %T", i, child)
case *BTree: // ok
case *Bucket: // ok
case *BTree:
kind = 1
case *Bucket:
kind = 2
}
if i == 0 {
childrenKind = kind
}
if kind != childrenKind {
fmt.Errorf("data: [%d]: children must be of the same type", i)
}
bt.data = append(bt.data, _BTreeItem{key: kkey, child: child})
......
......@@ -333,6 +333,7 @@ func (bt *iobtreeState) PySetState(pystate interface{}) (err error) {
n := (len(t) + 1) / 2
bt.data = make([]_IOBTreeItem, 0, n)
var kprev int64
var childrenKind int // 1 - IOBTree, 2 - IOBucket
for i, idx := 0, 0; i < n; i++ {
key := int64(math.MinInt32) // int32(-∞) (qualifies for ≤)
if i > 0 {
......@@ -356,12 +357,23 @@ func (bt *iobtreeState) PySetState(pystate interface{}) (err error) {
}
kprev = key
// check all children are of the same type
var kind int // see childrenKind ^^^
switch child.(type) {
default:
return fmt.Errorf("data: [%d]: child must be IOBTree|IOBucket; got %T", i, child)
case *IOBTree: // ok
case *IOBucket: // ok
case *IOBTree:
kind = 1
case *IOBucket:
kind = 2
}
if i == 0 {
childrenKind = kind
}
if kind != childrenKind {
fmt.Errorf("data: [%d]: children must be of the same type", i)
}
bt.data = append(bt.data, _IOBTreeItem{key: kkey, child: child})
......
......@@ -333,6 +333,7 @@ func (bt *lobtreeState) PySetState(pystate interface{}) (err error) {
n := (len(t) + 1) / 2
bt.data = make([]_LOBTreeItem, 0, n)
var kprev int64
var childrenKind int // 1 - LOBTree, 2 - LOBucket
for i, idx := 0, 0; i < n; i++ {
key := int64(math.MinInt64) // int64(-∞) (qualifies for ≤)
if i > 0 {
......@@ -356,12 +357,23 @@ func (bt *lobtreeState) PySetState(pystate interface{}) (err error) {
}
kprev = key
// check all children are of the same type
var kind int // see childrenKind ^^^
switch child.(type) {
default:
return fmt.Errorf("data: [%d]: child must be LOBTree|LOBucket; got %T", i, child)
case *LOBTree: // ok
case *LOBucket: // ok
case *LOBTree:
kind = 1
case *LOBucket:
kind = 2
}
if i == 0 {
childrenKind = kind
}
if kind != childrenKind {
fmt.Errorf("data: [%d]: children must be of the same type", i)
}
bt.data = append(bt.data, _LOBTreeItem{key: kkey, child: child})
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment