forked from cerc-io/ipld-eth-server
201 lines
4.8 KiB
Go
201 lines
4.8 KiB
Go
|
// CookieJar - A contestant's algorithm toolbox
|
||
|
// Copyright (c) 2013 Peter Szilagyi. All rights reserved.
|
||
|
//
|
||
|
// CookieJar is dual licensed: use of this source code is governed by a BSD
|
||
|
// license that can be found in the LICENSE file. Alternatively, the CookieJar
|
||
|
// toolbox may be used in accordance with the terms and conditions contained
|
||
|
// in a signed written agreement between you and the author(s).
|
||
|
|
||
|
package deque
|
||
|
|
||
|
import (
|
||
|
"math/rand"
|
||
|
"testing"
|
||
|
)
|
||
|
|
||
|
func TestDeque(t *testing.T) {
|
||
|
// Create some initial data
|
||
|
size := 16 * blockSize
|
||
|
data := make([]int, size)
|
||
|
for i := 0; i < size; i++ {
|
||
|
data[i] = rand.Int()
|
||
|
}
|
||
|
deque := New()
|
||
|
for rep := 0; rep < 2; rep++ {
|
||
|
// Push all the data into the deque, each one on a different side
|
||
|
outs := []int{}
|
||
|
for i := 0; i < size; i++ {
|
||
|
if i%2 == 0 {
|
||
|
deque.PushLeft(data[i])
|
||
|
if deque.Left() != data[i] {
|
||
|
t.Errorf("push/left mismatch: have %v, want %v.", deque.Left(), data[i])
|
||
|
}
|
||
|
} else {
|
||
|
deque.PushRight(data[i])
|
||
|
if deque.Right() != data[i] {
|
||
|
t.Errorf("push/right mismatch: have %v, want %v.", deque.Right(), data[i])
|
||
|
}
|
||
|
}
|
||
|
// Pop out every third and fourth (inversely than inserted)
|
||
|
if i%4 == 2 {
|
||
|
outs = append(outs, deque.PopRight().(int))
|
||
|
} else if i%4 == 3 {
|
||
|
outs = append(outs, deque.PopLeft().(int))
|
||
|
}
|
||
|
// Make sure size is consistent
|
||
|
if deque.Size() != i/2+i%2+1-(i%4)/3 {
|
||
|
t.Errorf("size mismatch: have %v, want %v.", deque.Size(), i/2+i%2+1-(i%4)/3)
|
||
|
}
|
||
|
}
|
||
|
rest := []int{}
|
||
|
for !deque.Empty() {
|
||
|
if len(rest)%2 == 0 {
|
||
|
rest = append(rest, deque.PopRight().(int))
|
||
|
} else {
|
||
|
rest = append(rest, deque.PopLeft().(int))
|
||
|
}
|
||
|
}
|
||
|
// Make sure the contents of the resulting slices are ok
|
||
|
for i := 1; i < size; i += 4 {
|
||
|
if data[i] != outs[i/2] {
|
||
|
t.Errorf("push/pop mismatch: have %v, want %v.", outs[i/2], data[i])
|
||
|
}
|
||
|
if data[i+1] != outs[i/2+1] {
|
||
|
t.Errorf("push/pop mismatch: have %v, want %v.", outs[i/2+1], data[i+1])
|
||
|
}
|
||
|
}
|
||
|
for i := 0; i < size; i += 4 {
|
||
|
if data[i] != rest[len(rest)-1-i/2] {
|
||
|
t.Errorf("push/pop mismatch: have %v, want %v.", rest[len(rest)-1-i/2], data[i])
|
||
|
}
|
||
|
if data[i+3] != rest[len(rest)-1-i/2-1] {
|
||
|
t.Errorf("push/pop mismatch: have %v, want %v.", rest[len(rest)-1-i/2-1], data[i+1])
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestQueue(t *testing.T) {
|
||
|
// Create some initial data
|
||
|
size := 16 * blockSize
|
||
|
data := make([]int, size)
|
||
|
for i := 0; i < size; i++ {
|
||
|
data[i] = rand.Int()
|
||
|
}
|
||
|
// Simulate a queue in both directions
|
||
|
deque := New()
|
||
|
for rep := 0; rep < 2; rep++ {
|
||
|
for _, val := range data {
|
||
|
deque.PushLeft(val)
|
||
|
}
|
||
|
outs := []int{}
|
||
|
for !deque.Empty() {
|
||
|
outs = append(outs, deque.PopRight().(int))
|
||
|
}
|
||
|
for i := 0; i < len(data); i++ {
|
||
|
if data[i] != outs[i] {
|
||
|
t.Errorf("push/pop mismatch: have %v, want %v.", outs[i], data[i])
|
||
|
}
|
||
|
}
|
||
|
for _, val := range data {
|
||
|
deque.PushRight(val)
|
||
|
}
|
||
|
outs = []int{}
|
||
|
for !deque.Empty() {
|
||
|
outs = append(outs, deque.PopLeft().(int))
|
||
|
}
|
||
|
for i := 0; i < len(data); i++ {
|
||
|
if data[i] != outs[i] {
|
||
|
t.Errorf("push/pop mismatch: have %v, want %v.", outs[i], data[i])
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestStack(t *testing.T) {
|
||
|
// Create some initial data
|
||
|
size := 16 * blockSize
|
||
|
data := make([]int, size)
|
||
|
for i := 0; i < size; i++ {
|
||
|
data[i] = rand.Int()
|
||
|
}
|
||
|
// Simulate a stack in both directions
|
||
|
deque := New()
|
||
|
for rep := 0; rep < 2; rep++ {
|
||
|
for _, val := range data {
|
||
|
deque.PushLeft(val)
|
||
|
}
|
||
|
outs := []int{}
|
||
|
for !deque.Empty() {
|
||
|
outs = append(outs, deque.PopLeft().(int))
|
||
|
}
|
||
|
for i := 0; i < len(data); i++ {
|
||
|
if data[i] != outs[len(outs)-i-1] {
|
||
|
t.Errorf("push/pop mismatch: have %v, want %v.", outs[len(outs)-i-1], data[i])
|
||
|
}
|
||
|
}
|
||
|
for _, val := range data {
|
||
|
deque.PushRight(val)
|
||
|
}
|
||
|
outs = []int{}
|
||
|
for !deque.Empty() {
|
||
|
outs = append(outs, deque.PopRight().(int))
|
||
|
}
|
||
|
for i := 0; i < len(data); i++ {
|
||
|
if data[i] != outs[len(outs)-i-1] {
|
||
|
t.Errorf("push/pop mismatch: have %v, want %v.", outs[len(outs)-i-1], data[i])
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestReset(t *testing.T) {
|
||
|
size := 16 * blockSize
|
||
|
deque := New()
|
||
|
for rep := 0; rep < 2; rep++ {
|
||
|
// Push some stuff into the deque
|
||
|
for i := 0; i < size; i++ {
|
||
|
deque.PushLeft(i)
|
||
|
}
|
||
|
// Clear and verify
|
||
|
deque.Reset()
|
||
|
if !deque.Empty() {
|
||
|
t.Errorf("deque not empty after reset: %v", deque)
|
||
|
}
|
||
|
// Push again and verify
|
||
|
for i := 0; i < size; i++ {
|
||
|
deque.PushLeft(i)
|
||
|
if deque.Right() != i {
|
||
|
t.Errorf("corrupt state after reset: have %v, want %v.", deque.Right(), i)
|
||
|
}
|
||
|
deque.PopRight()
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func BenchmarkPush(b *testing.B) {
|
||
|
deque := New()
|
||
|
for i := 0; i < b.N; i++ {
|
||
|
if i%2 == 0 {
|
||
|
deque.PushLeft(i)
|
||
|
} else {
|
||
|
deque.PushRight(i)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func BenchmarkPop(b *testing.B) {
|
||
|
deque := New()
|
||
|
for i := 0; i < b.N; i++ {
|
||
|
deque.PushLeft(i)
|
||
|
}
|
||
|
b.ResetTimer()
|
||
|
for i := 0; i < b.N; i++ {
|
||
|
if i%2 == 0 {
|
||
|
deque.PopLeft()
|
||
|
} else {
|
||
|
deque.PopRight()
|
||
|
}
|
||
|
}
|
||
|
}
|