GoPLS Viewer

Home|gopls/go/callgraph/vta/internal/trie/bits_test.go
1// Copyright 2021 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//go:build go1.13
6// +build go1.13
7
8package trie
9
10import (
11    "math/rand"
12    "testing"
13)
14
15func TestMask(t *testing.T) {
16    for _c := range []struct {
17        p    prefix
18        b    bitpos
19        want prefix
20    }{
21        {
22            p:    0b00001000,
23            b:    0b00000100,
24            want0b00001011,
25        }, {
26            p:    0b01011011,
27            b:    0b00000000,
28            want: ^prefix(0),
29        }, {
30            p:    0b01011011,
31            b:    0b00000001,
32            want0b01011010,
33        }, {
34            p:    0b01011011,
35            b:    0b00000010,
36            want0b01011001,
37        }, {
38            p:    0b01011011,
39            b:    0b00000100,
40            want0b01011011,
41        }, {
42            p:    0b01011011,
43            b:    0b00001000,
44            want0b01010111,
45        }, {
46            p:    0b01011011,
47            b:    0b00010000,
48            want0b01001111,
49        }, {
50            p:    0b01011011,
51            b:    0b00100000,
52            want0b01011111,
53        }, {
54            p:    0b01011011,
55            b:    0b01000000,
56            want0b00111111,
57        }, {
58            p:    0b01011011,
59            b:    0b01000000,
60            want0b00111111,
61        }, {
62            p:    0b01011011,
63            b:    0b10000000,
64            want0b01111111,
65        },
66    } {
67        if got := mask(c.pc.b); got != c.want {
68            t.Errorf("mask(%#b,%#b) got %#b. want %#b"c.pc.bgotc.want)
69        }
70    }
71}
72
73func TestMaskImpotent(t *testing.T) {
74    // test mask(mask(p, b), b) == mask(p,b)
75    for _p := range []prefix{
76        0b00b10b100, ^prefix(0b0), ^prefix(0b10),
77    } {
78        for _b := range []bitpos{
79            00b11 << 21 << 63,
80        } {
81            once := mask(pb)
82            twice := mask(onceb)
83            if once != twice {
84                t.Errorf("mask(mask(%#b,%#b), %#b) != mask(%#b,%#b) got %#b. want %#b",
85                    pbbpbtwiceonce)
86            }
87        }
88    }
89}
90
91func TestMatchPrefix(t *testing.T) {
92    for _c := range []struct {
93        k prefix
94        p prefix
95        b bitpos
96    }{
97        {
98            k0b1000,
99            p0b1011,
100            b0b0100,
101        }, {
102            k0b1001,
103            p0b1011,
104            b0b0100,
105        }, {
106            k0b1010,
107            p0b1011,
108            b0b0100,
109        }, {
110            k0b1011,
111            p0b1011,
112            b0b0100,
113        }, {
114            k0b1100,
115            p0b1011,
116            b0b0100,
117        }, {
118            k0b1101,
119            p0b1011,
120            b0b0100,
121        }, {
122            k0b1110,
123            p0b1011,
124            b0b0100,
125        }, {
126            k0b1111,
127            p0b1011,
128            b0b0100,
129        },
130    } {
131        if !matchPrefix(c.kc.pc.b) {
132            t.Errorf("matchPrefix(%#b, %#b,%#b) should be true"c.kc.pc.b)
133        }
134    }
135}
136
137func TestNotMatchPrefix(t *testing.T) {
138    for _c := range []struct {
139        k prefix
140        p prefix
141        b bitpos
142    }{
143        {
144            k0b0000,
145            p0b1011,
146            b0b0100,
147        }, {
148            k0b0010,
149            p0b1011,
150            b0b0100,
151        },
152    } {
153        if matchPrefix(c.kc.pc.b) {
154            t.Errorf("matchPrefix(%#b, %#b,%#b) should be false"c.kc.pc.b)
155        }
156    }
157}
158
159func TestBranchingBit(t *testing.T) {
160    for _c := range []struct {
161        x    prefix
162        y    prefix
163        want bitpos
164    }{
165        {
166            x:    0b0000,
167            y:    0b1011,
168            want0b1000,
169        }, {
170            x:    0b1010,
171            y:    0b1011,
172            want0b0001,
173        }, {
174            x:    0b1011,
175            y:    0b1111,
176            want0b0100,
177        }, {
178            x:    0b1011,
179            y:    0b1001,
180            want0b0010,
181        },
182    } {
183        if got := branchingBit(c.xc.y); got != c.want {
184            t.Errorf("branchingBit(%#b, %#b,) is not expected value. got %#b want %#b",
185                c.xc.ygotc.want)
186        }
187    }
188}
189
190func TestZeroBit(t *testing.T) {
191    for _c := range []struct {
192        k prefix
193        b bitpos
194    }{
195        {
196            k0b1000,
197            b0b0100,
198        }, {
199            k0b1001,
200            b0b0100,
201        }, {
202            k0b1010,
203            b0b0100,
204        },
205    } {
206        if !zeroBit(c.kc.b) {
207            t.Errorf("zeroBit(%#b, %#b) should be true"c.kc.b)
208        }
209    }
210}
211func TestZeroBitFails(t *testing.T) {
212    for _c := range []struct {
213        k prefix
214        b bitpos
215    }{
216        {
217            k0b1000,
218            b0b1000,
219        }, {
220            k0b1001,
221            b0b0001,
222        }, {
223            k0b1010,
224            b0b0010,
225        }, {
226            k0b1011,
227            b0b0001,
228        },
229    } {
230        if zeroBit(c.kc.b) {
231            t.Errorf("zeroBit(%#b, %#b) should be false"c.kc.b)
232        }
233    }
234}
235
236func TestOrd(t *testing.T) {
237    a := bitpos(0b0010)
238    b := bitpos(0b1000)
239    if ord(ab) {
240        t.Errorf("ord(%#b, %#b) should be false"ab)
241    }
242    if !ord(ba) {
243        t.Errorf("ord(%#b, %#b) should be true"ba)
244    }
245    if ord(aa) {
246        t.Errorf("ord(%#b, %#b) should be false"aa)
247    }
248    if !ord(a0) {
249        t.Errorf("ord(%#b, %#b) should be true"a0)
250    }
251}
252
253func TestPrefixesOverlapLemma(t *testing.T) {
254    // test
255    //   mask(p, fbb) == mask(q, fbb)
256    // iff
257    //   m > n && matchPrefix(q, p, m) or  (note: big endian encoding)
258    //   m < n && matchPrefix(p, q, n) or  (note: big endian encoding)
259    //   m ==n && p == q
260
261    // Case 1: mask(p, fbb) == mask(q, fbb) => m > n && matchPrefix(q, p, m)
262    mn := bitpos(1<<2), bitpos(1<<1)
263    pq := mask(0b100m), mask(0b010n)
264    if !(prefixesOverlap(pmqn) && m > n && matchPrefix(qpm)) {
265        t.Errorf("prefixesOverlap(%#b, %#b, %#b, %#b) lemma does not hold",
266            pmqn)
267    }
268    // Case 2: mask(p, fbb) == mask(q, fbb) => m < n && matchPrefix(p, q, n)
269    mn = bitpos(1<<2), bitpos(1<<3)
270    pq = mask(0b100m), mask(0b1000n)
271    if !(prefixesOverlap(pmqn) && m < n && matchPrefix(pqn)) {
272        t.Errorf("prefixesOverlap(%#b, %#b, %#b, %#b) lemma does not hold",
273            pmqn)
274    }
275    // Case 3: mask(p, fbb) == mask(q, fbb) => m < n && matchPrefix(p, q, n)
276    mn = bitpos(1<<2), bitpos(1<<2)
277    pq = mask(0b100m), mask(0b001n)
278    if !(prefixesOverlap(pmqn) && m == n && p == q) {
279        t.Errorf("prefixesOverlap(%#b, %#b, %#b, %#b) lemma does not hold",
280            pmqn)
281    }
282    // Case 4: mask(p, fbb) != mask(q, fbb)
283    mn = bitpos(1<<1), bitpos(1<<1)
284    pq = mask(0b100m), mask(0b001n)
285    if prefixesOverlap(pmqn) ||
286        (m > n && matchPrefix(qpm)) ||
287        (m < n && matchPrefix(pqn)) ||
288        (m == n && p == q) {
289        t.Errorf("prefixesOverlap(%#b, %#b, %#b, %#b) lemma does not hold",
290            pmqn)
291    }
292
293    // Do a few more random cases
294    r := rand.New(rand.NewSource(123))
295    N := 2000
296    for i := 0i < Ni++ {
297        m := bitpos(1 << (r.Uint64() % (64 + 1)))
298        n := bitpos(1 << (r.Uint64() % (64 + 1)))
299
300        p := mask(prefix(r.Uint64()), m)
301        q := mask(prefix(r.Uint64()), n)
302
303        lhs := prefixesOverlap(pmqn)
304        rhs := (m > n && matchPrefix(qpm)) ||
305            (m < n && matchPrefix(pqn)) ||
306            (m == n && p == q)
307
308        if lhs != rhs {
309            t.Errorf("prefixesOverlap(%#b, %#b, %#b, %#b) != <lemma> got %v. want %v",
310                pmqnlhsrhs)
311        }
312    }
313}
314
MembersX
TestPrefixesOverlapLemma
TestPrefixesOverlapLemma.n
TestMask.RangeStmt_278.c
TestMaskImpotent.t
TestNotMatchPrefix.t
TestBranchingBit.t
TestZeroBit.RangeStmt_3176.c
TestOrd.b
TestPrefixesOverlapLemma.r
TestPrefixesOverlapLemma.N
TestPrefixesOverlapLemma.BlockStmt.p
TestMask.t
TestMaskImpotent.RangeStmt_1335.BlockStmt.RangeStmt_1418.BlockStmt.once
TestMatchPrefix.RangeStmt_1712.c
TestPrefixesOverlapLemma.t
TestPrefixesOverlapLemma.p
TestMaskImpotent.RangeStmt_1335.BlockStmt.RangeStmt_1418.b
TestNotMatchPrefix.RangeStmt_2334.c
TestZeroBit.t
TestPrefixesOverlapLemma.BlockStmt.q
TestMask
TestMaskImpotent.RangeStmt_1335.BlockStmt.RangeStmt_1418.BlockStmt.twice
TestZeroBit
TestZeroBitFails
TestOrd
TestPrefixesOverlapLemma.q
TestMatchPrefix.t
TestZeroBitFails.RangeStmt_3475.c
TestOrd.t
TestPrefixesOverlapLemma.BlockStmt.n
TestMaskImpotent
TestMaskImpotent.RangeStmt_1335.p
TestBranchingBit.RangeStmt_2660.c
TestBranchingBit.RangeStmt_2660.BlockStmt.got
TestZeroBitFails.t
TestPrefixesOverlapLemma.BlockStmt.lhs
rand
testing
TestMatchPrefix
TestPrefixesOverlapLemma.m
TestPrefixesOverlapLemma.i
TestMask.RangeStmt_278.BlockStmt.got
TestNotMatchPrefix
TestBranchingBit
TestOrd.a
TestPrefixesOverlapLemma.BlockStmt.m
Members
X