github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/util/topk_test.go (about)

     1  // Copyright 2016 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  package util
    12  
    13  import (
    14  	"math/rand"
    15  	"sort"
    16  	"testing"
    17  )
    18  
    19  // testMoveTopKToFront runs MoveTopKToFront for the given k and verifies the
    20  // result.
    21  func testMoveTopKToFront(t *testing.T, k int, data ...int) {
    22  	// Make a copy of the values.
    23  	vals := append([]int(nil), data...)
    24  	MoveTopKToFront(sort.IntSlice(vals), k)
    25  	for l := 0; l < k; l++ {
    26  		for r := k; r < len(data); r++ {
    27  			if vals[l] > vals[r] {
    28  				t.Errorf("Error for k=%d: vals[%d]=%d is greater than vals[%d]=%d",
    29  					k, l, vals[l], r, vals[r])
    30  			}
    31  		}
    32  	}
    33  }
    34  
    35  // testMoveTopKToFront runs MoveTopKToFront for all possible Ks and verifies the
    36  // result.
    37  func testMoveTopKToFrontAllK(t *testing.T, data ...int) {
    38  	for k := 0; k <= len(data); k++ {
    39  		testMoveTopKToFront(t, k, data...)
    40  	}
    41  }
    42  
    43  func TestMoveTopKToFront(t *testing.T) {
    44  	// Test all possible arrays of length up to 4 with values between 0 and 4.
    45  	for a := 0; a <= 4; a++ {
    46  		testMoveTopKToFrontAllK(t, a)
    47  		for b := 0; b <= 4; b++ {
    48  			testMoveTopKToFrontAllK(t, a, b)
    49  			for c := 0; c <= 4; c++ {
    50  				testMoveTopKToFrontAllK(t, a, b, c)
    51  				for d := 0; d <= 4; d++ {
    52  					testMoveTopKToFrontAllK(t, a, b, c, d)
    53  				}
    54  			}
    55  		}
    56  	}
    57  
    58  	// Misc tests.
    59  	tests := [][]int{
    60  		{0, 1, 2, 3, 4, 5, 6, 7},
    61  		{7, 6, 5, 4, 3, 2, 1, 0},
    62  		{7, 0, 6, 1, 5, 2, 4, 3},
    63  		{0, 9, 2, 1, 5, 1, 7, 8, 8, 7},
    64  		{0, 2, 9, 11, 6, 1, 7, 1, 5, 1, 4, 3, 0, 11},
    65  	}
    66  	for _, data := range tests {
    67  		testMoveTopKToFrontAllK(t, data...)
    68  	}
    69  
    70  	// Random tests: data of size N with random values in [0, M).
    71  	Ns := []int{10, 100}
    72  	Ms := []int{2, 10, 100, 1000}
    73  	for _, n := range Ns {
    74  		for _, m := range Ms {
    75  			data := make([]int, n)
    76  			for _, i := range data {
    77  				data[i] = rand.Intn(m)
    78  			}
    79  			testMoveTopKToFrontAllK(t, data...)
    80  		}
    81  	}
    82  }
    83  
    84  func benchmarkMoveTopKToFront(b *testing.B, data []int) {
    85  	tmp := make([]int, len(data))
    86  
    87  	ks := []int{len(data) / 100, len(data) / 10, len(data) / 2}
    88  	b.ResetTimer()
    89  	for i := 0; i < b.N; i++ {
    90  		b.StopTimer()
    91  		copy(tmp, data)
    92  		b.StartTimer()
    93  		MoveTopKToFront(sort.IntSlice(tmp), ks[i%len(ks)])
    94  	}
    95  }
    96  
    97  func BenchmarkMoveTopKToFrontRand(b *testing.B) {
    98  	data := make([]int, 100000)
    99  	for _, i := range data {
   100  		data[i] = rand.Intn(len(data))
   101  	}
   102  	benchmarkMoveTopKToFront(b, data)
   103  }
   104  
   105  func BenchmarkMoveTopKToFrontSorted(b *testing.B) {
   106  	data := make([]int, 100000)
   107  	for _, i := range data {
   108  		data[i] = i
   109  	}
   110  	benchmarkMoveTopKToFront(b, data)
   111  }
   112  
   113  func BenchmarkMoveTopKToFrontRevSorted(b *testing.B) {
   114  	data := make([]int, 100000)
   115  	for _, i := range data {
   116  		data[i] = -i
   117  	}
   118  	benchmarkMoveTopKToFront(b, data)
   119  }