github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/cdc/puller/frontier/heap_test.go (about) 1 // Copyright 2020 PingCAP, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package frontier 15 16 import ( 17 "math" 18 "math/rand" 19 "testing" 20 "time" 21 22 "github.com/stretchr/testify/require" 23 ) 24 25 func TestInsert(t *testing.T) { 26 t.Parallel() 27 var heap fibonacciHeap 28 target := uint64(15000) 29 30 for i := 0; i < 5000; i++ { 31 heap.Insert(uint64(10001) + target + 1) 32 } 33 heap.Insert(target) 34 35 require.Equal(t, target, heap.GetMinKey()) 36 } 37 38 func TestUpdateTs(t *testing.T) { 39 t.Parallel() 40 seed := time.Now().Unix() 41 rand.Seed(seed) 42 var heap fibonacciHeap 43 nodes := make([]*fibonacciHeapNode, 2000) 44 expectedMin := uint64(math.MaxUint64) 45 for i := range nodes { 46 key := 10000 + uint64(rand.Intn(len(nodes)/2)) 47 nodes[i] = heap.Insert(key) 48 if expectedMin > key { 49 expectedMin = key 50 } 51 } 52 53 var key uint64 54 for i := range nodes { 55 min := heap.GetMinKey() 56 require.Equal(t, expectedMin, min, "seed:%d", seed) 57 if rand.Intn(2) == 0 { 58 key = nodes[i].key + uint64(10000) 59 heap.UpdateKey(nodes[i], key) 60 } else { 61 key = nodes[i].key - uint64(10000) 62 heap.UpdateKey(nodes[i], key) 63 } 64 if expectedMin > key { 65 expectedMin = key 66 } 67 } 68 } 69 70 func TestRemoveNode(t *testing.T) { 71 t.Parallel() 72 seed := time.Now().Unix() 73 rand.Seed(seed) 74 var heap fibonacciHeap 75 nodes := make([]*fibonacciHeapNode, 2000) 76 expectedMin := uint64(math.MaxUint64) 77 for i := range nodes { 78 nodes[i] = heap.Insert(10000 + uint64(rand.Intn(len(nodes)/2))) 79 if nodes[i].key < expectedMin { 80 expectedMin = nodes[i].key 81 } 82 } 83 84 preKey := expectedMin + 1 85 for i := range nodes { 86 min := heap.GetMinKey() 87 if preKey == expectedMin { 88 expectedMin = uint64(math.MaxUint64) 89 for _, n := range nodes { 90 if isRemoved(n) { 91 continue 92 } 93 if expectedMin > n.key { 94 expectedMin = n.key 95 } 96 } 97 } 98 require.Equal(t, expectedMin, min, "seed:%d", seed) 99 preKey = nodes[i].key 100 heap.Remove(nodes[i]) 101 } 102 for _, n := range nodes { 103 if !isRemoved(n) { 104 t.Fatal("all of the node shoule be removed") 105 } 106 } 107 } 108 109 func isRemoved(n *fibonacciHeapNode) bool { 110 return n.left == nil && n.right == nil && n.children == nil && n.parent == nil 111 } 112 113 func (x *fibonacciHeap) Entries(fn func(n *fibonacciHeapNode) bool) { 114 heapNodeIterator(x.root, fn) 115 } 116 117 func heapNodeIterator(n *fibonacciHeapNode, fn func(n *fibonacciHeapNode) bool) { 118 firstStep := true 119 120 for next := n; next != nil && (next != n || firstStep); next = next.right { 121 firstStep = false 122 if !fn(next) { 123 return 124 } 125 if next.children != nil { 126 heapNodeIterator(next.children, fn) 127 } 128 } 129 }