github.com/gagliardetto/golang-go@v0.0.0-20201020153340-53909ea70814/cmd/compile/internal/ssa/redblack32_test.go (about) 1 // Copyright 2016 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package ssa 6 7 import ( 8 "fmt" 9 "testing" 10 ) 11 12 type sstring string 13 14 func (s sstring) String() string { 15 return string(s) 16 } 17 18 // wellFormed ensures that a red-black tree meets 19 // all of its invariants and returns a string identifying 20 // the first problem encountered. If there is no problem 21 // then the returned string is empty. The size is also 22 // returned to allow comparison of calculated tree size 23 // with expected. 24 func (t *RBTint32) wellFormed() (s string, i int) { 25 if t.root == nil { 26 s = "" 27 i = 0 28 return 29 } 30 return t.root.wellFormedSubtree(nil, -0x80000000, 0x7fffffff) 31 } 32 33 // wellFormedSubtree ensures that a red-black subtree meets 34 // all of its invariants and returns a string identifying 35 // the first problem encountered. If there is no problem 36 // then the returned string is empty. The size is also 37 // returned to allow comparison of calculated tree size 38 // with expected. 39 func (t *node32) wellFormedSubtree(parent *node32, min, max int32) (s string, i int) { 40 i = -1 // initialize to a failing value 41 s = "" // s is the reason for failure; empty means okay. 42 43 if t.parent != parent { 44 s = "t.parent != parent" 45 return 46 } 47 48 if min >= t.key { 49 s = "min >= t.key" 50 return 51 } 52 53 if max <= t.key { 54 s = "max <= t.key" 55 return 56 } 57 58 l := t.left 59 r := t.right 60 if l == nil && r == nil { 61 if t.rank != rankLeaf { 62 s = "leaf rank wrong" 63 return 64 } 65 } 66 if l != nil { 67 if t.rank < l.rank { 68 s = "t.rank < l.rank" 69 } else if t.rank > 1+l.rank { 70 s = "t.rank > 1+l.rank" 71 } else if t.rank <= l.maxChildRank() { 72 s = "t.rank <= l.maxChildRank()" 73 } else if t.key <= l.key { 74 s = "t.key <= l.key" 75 } 76 if s != "" { 77 return 78 } 79 } else { 80 if t.rank != 1 { 81 s = "t w/ left nil has rank != 1" 82 return 83 } 84 } 85 if r != nil { 86 if t.rank < r.rank { 87 s = "t.rank < r.rank" 88 } else if t.rank > 1+r.rank { 89 s = "t.rank > 1+r.rank" 90 } else if t.rank <= r.maxChildRank() { 91 s = "t.rank <= r.maxChildRank()" 92 } else if t.key >= r.key { 93 s = "t.key >= r.key" 94 } 95 if s != "" { 96 return 97 } 98 } else { 99 if t.rank != 1 { 100 s = "t w/ right nil has rank != 1" 101 return 102 } 103 } 104 ii := 1 105 if l != nil { 106 res, il := l.wellFormedSubtree(t, min, t.key) 107 if res != "" { 108 s = "L." + res 109 return 110 } 111 ii += il 112 } 113 if r != nil { 114 res, ir := r.wellFormedSubtree(t, t.key, max) 115 if res != "" { 116 s = "R." + res 117 return 118 } 119 ii += ir 120 } 121 i = ii 122 return 123 } 124 125 func (t *RBTint32) DebugString() string { 126 if t.root == nil { 127 return "" 128 } 129 return t.root.DebugString() 130 } 131 132 // DebugString prints the tree with nested information 133 // to allow an eyeball check on the tree balance. 134 func (t *node32) DebugString() string { 135 s := "" 136 if t.left != nil { 137 s += "[" 138 s += t.left.DebugString() 139 s += "]" 140 } 141 s += fmt.Sprintf("%v=%v:%d", t.key, t.data, t.rank) 142 if t.right != nil { 143 s += "[" 144 s += t.right.DebugString() 145 s += "]" 146 } 147 return s 148 } 149 150 func allRBT32Ops(te *testing.T, x []int32) { 151 t := &RBTint32{} 152 for i, d := range x { 153 x[i] = d + d // Double everything for glb/lub testing 154 } 155 156 // fmt.Printf("Inserting double of %v", x) 157 k := 0 158 min := int32(0x7fffffff) 159 max := int32(-0x80000000) 160 for _, d := range x { 161 if d < min { 162 min = d 163 } 164 165 if d > max { 166 max = d 167 } 168 169 t.Insert(d, sstring(fmt.Sprintf("%v", d))) 170 k++ 171 s, i := t.wellFormed() 172 if i != k { 173 te.Errorf("Wrong tree size %v, expected %v for %v", i, k, t.DebugString()) 174 } 175 if s != "" { 176 te.Errorf("Tree consistency problem at %v", s) 177 return 178 } 179 } 180 181 oops := false 182 183 for _, d := range x { 184 s := fmt.Sprintf("%v", d) 185 f := t.Find(d) 186 187 // data 188 if s != fmt.Sprintf("%v", f) { 189 te.Errorf("s(%v) != f(%v)", s, f) 190 oops = true 191 } 192 } 193 194 if !oops { 195 for _, d := range x { 196 s := fmt.Sprintf("%v", d) 197 198 kg, g := t.Glb(d + 1) 199 kge, ge := t.GlbEq(d) 200 kl, l := t.Lub(d - 1) 201 kle, le := t.LubEq(d) 202 203 // keys 204 if d != kg { 205 te.Errorf("d(%v) != kg(%v)", d, kg) 206 } 207 if d != kl { 208 te.Errorf("d(%v) != kl(%v)", d, kl) 209 } 210 if d != kge { 211 te.Errorf("d(%v) != kge(%v)", d, kge) 212 } 213 if d != kle { 214 te.Errorf("d(%v) != kle(%v)", d, kle) 215 } 216 // data 217 if s != fmt.Sprintf("%v", g) { 218 te.Errorf("s(%v) != g(%v)", s, g) 219 } 220 if s != fmt.Sprintf("%v", l) { 221 te.Errorf("s(%v) != l(%v)", s, l) 222 } 223 if s != fmt.Sprintf("%v", ge) { 224 te.Errorf("s(%v) != ge(%v)", s, ge) 225 } 226 if s != fmt.Sprintf("%v", le) { 227 te.Errorf("s(%v) != le(%v)", s, le) 228 } 229 } 230 231 for _, d := range x { 232 s := fmt.Sprintf("%v", d) 233 kge, ge := t.GlbEq(d + 1) 234 kle, le := t.LubEq(d - 1) 235 if d != kge { 236 te.Errorf("d(%v) != kge(%v)", d, kge) 237 } 238 if d != kle { 239 te.Errorf("d(%v) != kle(%v)", d, kle) 240 } 241 if s != fmt.Sprintf("%v", ge) { 242 te.Errorf("s(%v) != ge(%v)", s, ge) 243 } 244 if s != fmt.Sprintf("%v", le) { 245 te.Errorf("s(%v) != le(%v)", s, le) 246 } 247 } 248 249 kg, g := t.Glb(min) 250 kge, ge := t.GlbEq(min - 1) 251 kl, l := t.Lub(max) 252 kle, le := t.LubEq(max + 1) 253 fmin := t.Find(min - 1) 254 fmax := t.Find(min + 11) 255 256 if kg != 0 || kge != 0 || kl != 0 || kle != 0 { 257 te.Errorf("Got non-zero-key for missing query") 258 } 259 260 if g != nil || ge != nil || l != nil || le != nil || fmin != nil || fmax != nil { 261 te.Errorf("Got non-error-data for missing query") 262 } 263 264 } 265 } 266 267 func TestAllRBTreeOps(t *testing.T) { 268 allRBT32Ops(t, []int32{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25}) 269 allRBT32Ops(t, []int32{22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 3, 2, 1, 25, 24, 23, 12, 11, 10, 9, 8, 7, 6, 5, 4}) 270 allRBT32Ops(t, []int32{25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}) 271 allRBT32Ops(t, []int32{1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24}) 272 allRBT32Ops(t, []int32{1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 24, 22, 20, 18, 16, 14, 12, 10, 8, 6, 4, 2}) 273 allRBT32Ops(t, []int32{24, 22, 20, 18, 16, 14, 12, 10, 8, 6, 4, 2, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25}) 274 }