blob: 6d72a3eee5f8001b79ed128768749c571655e7fd [file] [log] [blame]
David Chase6b99fb52016-04-21 13:24:58 -04001// 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
5package ssa
6
7import (
8 "fmt"
9 "testing"
10)
11
12type sstring string
13
14func (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.
24func (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.
39func (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
125func (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.
134func (t *node32) DebugString() string {
135 s := ""
136 if t.left != nil {
137 s = s + "["
138 s = s + t.left.DebugString()
139 s = s + "]"
140 }
141 s = s + fmt.Sprintf("%v=%v:%d", t.key, t.data, t.rank)
142 if t.right != nil {
143 s = s + "["
144 s = s + t.right.DebugString()
145 s = s + "]"
146 }
147 return s
148}
149
150func 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 } else {
179 // fmt.Printf("%s", t.DebugString())
180 }
181 }
182
183 oops := false
184
185 for _, d := range x {
186 s := fmt.Sprintf("%v", d)
187 f := t.Find(d)
188
189 // data
190 if s != fmt.Sprintf("%v", f) {
191 te.Errorf("s(%v) != f(%v)", s, f)
192 oops = true
193 }
194 }
195
196 if !oops {
197 for _, d := range x {
198 s := fmt.Sprintf("%v", d)
199
200 kg, g := t.Glb(d + 1)
201 kge, ge := t.GlbEq(d)
202 kl, l := t.Lub(d - 1)
203 kle, le := t.LubEq(d)
204
205 // keys
206 if d != kg {
207 te.Errorf("d(%v) != kg(%v)", d, kg)
208 }
209 if d != kl {
210 te.Errorf("d(%v) != kl(%v)", d, kl)
211 }
212 if d != kge {
213 te.Errorf("d(%v) != kge(%v)", d, kge)
214 }
215 if d != kle {
216 te.Errorf("d(%v) != kle(%v)", d, kle)
217 }
218 // data
219 if s != fmt.Sprintf("%v", g) {
220 te.Errorf("s(%v) != g(%v)", s, g)
221 }
222 if s != fmt.Sprintf("%v", l) {
223 te.Errorf("s(%v) != l(%v)", s, l)
224 }
225 if s != fmt.Sprintf("%v", ge) {
226 te.Errorf("s(%v) != ge(%v)", s, ge)
227 }
228 if s != fmt.Sprintf("%v", le) {
229 te.Errorf("s(%v) != le(%v)", s, le)
230 }
231 }
232
233 for _, d := range x {
234 s := fmt.Sprintf("%v", d)
235 kge, ge := t.GlbEq(d + 1)
236 kle, le := t.LubEq(d - 1)
237 if d != kge {
238 te.Errorf("d(%v) != kge(%v)", d, kge)
239 }
240 if d != kle {
241 te.Errorf("d(%v) != kle(%v)", d, kle)
242 }
243 if s != fmt.Sprintf("%v", ge) {
244 te.Errorf("s(%v) != ge(%v)", s, ge)
245 }
246 if s != fmt.Sprintf("%v", le) {
247 te.Errorf("s(%v) != le(%v)", s, le)
248 }
249 }
250
251 kg, g := t.Glb(min)
252 kge, ge := t.GlbEq(min - 1)
253 kl, l := t.Lub(max)
254 kle, le := t.LubEq(max + 1)
255 fmin := t.Find(min - 1)
256 fmax := t.Find(min + 11)
257
258 if kg != 0 || kge != 0 || kl != 0 || kle != 0 {
259 te.Errorf("Got non-zero-key for missing query")
260 }
261
262 if g != nil || ge != nil || l != nil || le != nil || fmin != nil || fmax != nil {
263 te.Errorf("Got non-error-data for missing query")
264 }
265
266 }
267}
268
269func TestAllRBTreeOps(t *testing.T) {
270 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})
271 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})
272 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})
273 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})
274 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})
275 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})
276}