Add ScanRightDeleteRandom test; Add GCRandom test
This commit is contained in:
parent
d939cd964b
commit
e3d88d2d79
121
clist_test.go
121
clist_test.go
|
@ -1,6 +1,8 @@
|
||||||
package clist
|
package clist
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
"runtime"
|
"runtime"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
@ -90,3 +92,122 @@ func TestGCFifo(t *testing.T) {
|
||||||
gcCount)
|
gcCount)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
This test is quite hacky because it relies on SetFinalizer
|
||||||
|
which isn't guaranteed to run at all.
|
||||||
|
*/
|
||||||
|
func TestGCRandom(t *testing.T) {
|
||||||
|
|
||||||
|
const numElements = 1000000
|
||||||
|
l := New()
|
||||||
|
gcCount := 0
|
||||||
|
|
||||||
|
// SetFinalizer doesn't work well with circular structures,
|
||||||
|
// so we construct a trivial non-circular structure to
|
||||||
|
// track.
|
||||||
|
type value struct {
|
||||||
|
Int int
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < numElements; i++ {
|
||||||
|
v := new(value)
|
||||||
|
v.Int = i
|
||||||
|
l.PushBack(v)
|
||||||
|
runtime.SetFinalizer(v, func(v *value) {
|
||||||
|
gcCount += 1
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
els := make([]*CElement, 0, numElements)
|
||||||
|
for el := l.Front(); el != nil; el = el.Next() {
|
||||||
|
els = append(els, el)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, i := range rand.Perm(numElements) {
|
||||||
|
el := els[i]
|
||||||
|
l.Remove(el)
|
||||||
|
el = el.Next()
|
||||||
|
}
|
||||||
|
|
||||||
|
runtime.GC()
|
||||||
|
time.Sleep(time.Second * 3)
|
||||||
|
|
||||||
|
if gcCount != numElements {
|
||||||
|
t.Errorf("Expected gcCount to be %v, got %v", numElements,
|
||||||
|
gcCount)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestScanRightDeleteRandom(t *testing.T) {
|
||||||
|
|
||||||
|
const numElements = 10000
|
||||||
|
const numTimes = 10000000
|
||||||
|
const numScanners = 10
|
||||||
|
|
||||||
|
l := New()
|
||||||
|
stop := make(chan struct{})
|
||||||
|
|
||||||
|
els := make([]*CElement, numElements, numElements)
|
||||||
|
for i := 0; i < numElements; i++ {
|
||||||
|
el := l.PushBack(i)
|
||||||
|
els[i] = el
|
||||||
|
}
|
||||||
|
|
||||||
|
// Launch scanner routines that will rapidly iterate over elements.
|
||||||
|
for i := 0; i < numScanners; i++ {
|
||||||
|
go func(scannerID int) {
|
||||||
|
var el *CElement
|
||||||
|
restartCounter := 0
|
||||||
|
counter := 0
|
||||||
|
FOR_LOOP:
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-stop:
|
||||||
|
fmt.Println("stopped")
|
||||||
|
break FOR_LOOP
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
if el == nil {
|
||||||
|
el = l.FrontWait()
|
||||||
|
restartCounter += 1
|
||||||
|
}
|
||||||
|
el = el.Next()
|
||||||
|
counter += 1
|
||||||
|
}
|
||||||
|
fmt.Printf("Scanner %v restartCounter: %v counter: %v\n", scannerID, restartCounter, counter)
|
||||||
|
}(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove an element, push back an element.
|
||||||
|
for i := 0; i < numTimes; i++ {
|
||||||
|
// Pick an element to remove
|
||||||
|
rmElIdx := rand.Intn(len(els))
|
||||||
|
rmEl := els[rmElIdx]
|
||||||
|
|
||||||
|
// Remove it
|
||||||
|
l.Remove(rmEl)
|
||||||
|
//fmt.Print(".")
|
||||||
|
|
||||||
|
// Insert a new element
|
||||||
|
newEl := l.PushBack(-1*i - 1)
|
||||||
|
els[rmElIdx] = newEl
|
||||||
|
|
||||||
|
if i%100000 == 0 {
|
||||||
|
fmt.Printf("Pushed %vK elements so far...\n", i/1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop scanners
|
||||||
|
close(stop)
|
||||||
|
time.Sleep(time.Second * 1)
|
||||||
|
|
||||||
|
// And remove all the elements.
|
||||||
|
for el := l.Front(); el != nil; el = el.Next() {
|
||||||
|
l.Remove(el)
|
||||||
|
}
|
||||||
|
if l.Len() != 0 {
|
||||||
|
t.Fatal("Failed to remove all elements from CList")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue