github.com/zuoyebang/bitalosdb@v1.1.1-0.20240516111551-79a8c4d8ce20/internal/list2/queue_test.go (about) 1 // Copyright 2021 The Bitalosdb author(hustxrb@163.com) and other contributors. 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 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package list2 16 17 import ( 18 "sync" 19 "sync/atomic" 20 "testing" 21 ) 22 23 func TestQueue(t *testing.T) { 24 queue := NewQueue() 25 queue.Push(1) 26 queue.Push(2) 27 queue.Push(3) 28 queue.Push(4) 29 30 length := queue.Len() 31 if length != 4 { 32 t.Errorf("queue.Len() failed. Got %d, expected 4.", length) 33 } 34 35 value := queue.Peak().(int) 36 if value != 1 { 37 t.Errorf("queue.Peak() failed. Got %d, expected 1.", value) 38 } 39 40 value = queue.Pop().(int) 41 if value != 1 { 42 t.Errorf("queue.Pop() failed. Got %d, expected 1.", value) 43 } 44 45 length = queue.Len() 46 if length != 3 { 47 t.Errorf("queue.Len() failed. Got %d, expected 3.", length) 48 } 49 50 value = queue.Peak().(int) 51 if value != 2 { 52 t.Errorf("queue.Peak() failed. Got %d, expected 2.", value) 53 } 54 55 value = queue.Pop().(int) 56 if value != 2 { 57 t.Errorf("queue.Pop() failed. Got %d, expected 2.", value) 58 } 59 60 value = queue.Pop().(int) 61 if value != 3 { 62 t.Errorf("queue.Pop() failed. Got %d, expected 3.", value) 63 } 64 65 empty := queue.Empty() 66 if empty { 67 t.Errorf("queue.Empty() failed. Got %v, expected false.", empty) 68 } 69 70 value = queue.Pop().(int) 71 if value != 4 { 72 t.Errorf("queue.Pop() failed. Got %d, expected 4.", value) 73 } 74 75 empty = queue.Empty() 76 if !empty { 77 t.Errorf("queue.Empty() failed. Got %v, expected true.", empty) 78 } 79 80 nilValue := queue.Peak() 81 if nilValue != nil { 82 t.Errorf("queue.Peak() failed. Got %d, expected nil.", nilValue) 83 } 84 85 nilValue = queue.Pop() 86 if nilValue != nil { 87 t.Errorf("queue.Pop() failed. Got %d, expected nil.", nilValue) 88 } 89 90 length = queue.Len() 91 if length != 0 { 92 t.Errorf("queue.Len() failed. Got %d, expected 0.", length) 93 } 94 } 95 96 func TestIntQueue(t *testing.T) { 97 size := 2 << 20 98 queue := NewIntQueue(uint32(size)) 99 for i := 0; i < size; i++ { 100 queue.Push(int32(i)) 101 } 102 if queue.Empty() { 103 t.Errorf("queue not empty") 104 } 105 106 succ := 0 107 cursor := 0 108 for { 109 if queue.Len() != size-cursor { 110 t.Errorf("queue len error. expect:%d actual:%d", uint32(size-cursor), queue.Len()) 111 break 112 } 113 114 if val, ok := queue.Pop(); !ok { 115 break 116 } else if val == int32(cursor) { 117 succ++ 118 cursor++ 119 } 120 } 121 if succ != size { 122 t.Errorf("queue pop failed. succ:%d, expected %d", succ, size) 123 } 124 if !queue.Empty() { 125 t.Errorf("queue should be empty") 126 } 127 } 128 129 func TestIntQueue2(t *testing.T) { 130 size := 1 << 20 131 total := 1<<32 + 1<<20 132 queue := NewIntQueue(uint32(size)) 133 for i := 0; i < total; i++ { 134 queue.Push(int32(i % (1 << 30))) 135 if val, ok := queue.Pop(); !ok { 136 t.Errorf("queue pop failed") 137 } else if val != int32(i%(1<<30)) { 138 t.Errorf("queue pop value error") 139 } 140 } 141 if !queue.Empty() { 142 t.Errorf("queue should be empty") 143 } 144 } 145 146 func TestParallelWrite(t *testing.T) { 147 size := 1 << 20 148 queue := NewIntQueue(uint32(size)) 149 150 loop := 100 151 opCount := 10000 152 appearCount := loop 153 var wg sync.WaitGroup 154 var locker sync.RWMutex 155 for i := 0; i < loop; i++ { 156 wg.Add(1) 157 go func() { 158 defer wg.Done() 159 for j := 0; j < opCount; j++ { 160 locker.Lock() 161 queue.Push(int32(j)) 162 locker.Unlock() 163 } 164 }() 165 } 166 wg.Wait() 167 168 valueCount := make([]int32, opCount) 169 for i := 0; i < loop; i++ { 170 wg.Add(1) 171 go func() { 172 defer wg.Done() 173 for j := 0; j < opCount; j++ { 174 locker.Lock() 175 val, _ := queue.Pop() 176 locker.Unlock() 177 atomic.AddInt32(&valueCount[int(val)], 1) 178 } 179 }() 180 } 181 wg.Wait() 182 for i := 0; i < opCount; i++ { 183 if valueCount[i] != int32(appearCount) { 184 t.Errorf("value:%d count(%d)!=%d", i, valueCount[i], appearCount) 185 } 186 } 187 }