1package tsm1
2
3import (
4	"fmt"
5	"runtime"
6	"sync"
7	"testing"
8)
9
10func TestRing_newRing(t *testing.T) {
11	examples := []struct {
12		n         int
13		returnErr bool
14	}{
15		{n: 1}, {n: 2}, {n: 4}, {n: 8}, {n: 16}, {n: 32, returnErr: true},
16		{n: 0, returnErr: true}, {n: 3, returnErr: true},
17	}
18
19	for i, example := range examples {
20		r, err := newring(example.n)
21		if err != nil {
22			if example.returnErr {
23				continue // expecting an error.
24			}
25			t.Fatal(err)
26		}
27
28		if got, exp := len(r.partitions), example.n; got != exp {
29			t.Fatalf("[Example %d] got %v, expected %v", i, got, exp)
30		}
31
32		// Check partitions distributed correctly
33		partitions := make([]*partition, 0)
34		for i, partition := range r.partitions {
35			if i == 0 || partition != partitions[len(partitions)-1] {
36				partitions = append(partitions, partition)
37			}
38		}
39
40		if got, exp := len(partitions), example.n; got != exp {
41			t.Fatalf("[Example %d] got %v, expected %v", i, got, exp)
42		}
43	}
44}
45
46var strSliceRes [][]byte
47
48func benchmarkRingkeys(b *testing.B, r *ring, keys int) {
49	// Add some keys
50	for i := 0; i < keys; i++ {
51		r.add([]byte(fmt.Sprintf("cpu,host=server-%d value=1", i)), nil)
52	}
53
54	b.ReportAllocs()
55	b.ResetTimer()
56	for i := 0; i < b.N; i++ {
57		strSliceRes = r.keys(false)
58	}
59}
60
61func BenchmarkRing_keys_100(b *testing.B)    { benchmarkRingkeys(b, MustNewRing(256), 100) }
62func BenchmarkRing_keys_1000(b *testing.B)   { benchmarkRingkeys(b, MustNewRing(256), 1000) }
63func BenchmarkRing_keys_10000(b *testing.B)  { benchmarkRingkeys(b, MustNewRing(256), 10000) }
64func BenchmarkRing_keys_100000(b *testing.B) { benchmarkRingkeys(b, MustNewRing(256), 100000) }
65
66func benchmarkRingGetPartition(b *testing.B, r *ring, keys int) {
67	vals := make([][]byte, keys)
68
69	// Add some keys
70	for i := 0; i < keys; i++ {
71		vals[i] = []byte(fmt.Sprintf("cpu,host=server-%d field1=value1,field2=value2,field4=value4,field5=value5,field6=value6,field7=value7,field8=value1,field9=value2,field10=value4,field11=value5,field12=value6,field13=value7", i))
72		r.add(vals[i], nil)
73	}
74
75	b.ReportAllocs()
76	b.ResetTimer()
77	for i := 0; i < b.N; i++ {
78		r.getPartition(vals[i%keys])
79	}
80}
81
82func BenchmarkRing_getPartition_100(b *testing.B) { benchmarkRingGetPartition(b, MustNewRing(256), 100) }
83func BenchmarkRing_getPartition_1000(b *testing.B) {
84	benchmarkRingGetPartition(b, MustNewRing(256), 1000)
85}
86
87func benchmarkRingWrite(b *testing.B, r *ring, n int) {
88	b.ReportAllocs()
89	for i := 0; i < b.N; i++ {
90		var wg sync.WaitGroup
91		for i := 0; i < runtime.GOMAXPROCS(0); i++ {
92			errC := make(chan error)
93			wg.Add(1)
94			go func() {
95				defer wg.Done()
96				for j := 0; j < n; j++ {
97					if _, err := r.write([]byte(fmt.Sprintf("cpu,host=server-%d value=1", j)), Values{}); err != nil {
98						errC <- err
99					}
100				}
101			}()
102
103			go func() {
104				wg.Wait()
105				close(errC)
106			}()
107
108			for err := range errC {
109				if err != nil {
110					b.Error(err)
111				}
112			}
113		}
114	}
115}
116
117func BenchmarkRing_write_1_100(b *testing.B)      { benchmarkRingWrite(b, MustNewRing(1), 100) }
118func BenchmarkRing_write_1_1000(b *testing.B)     { benchmarkRingWrite(b, MustNewRing(1), 1000) }
119func BenchmarkRing_write_1_10000(b *testing.B)    { benchmarkRingWrite(b, MustNewRing(1), 10000) }
120func BenchmarkRing_write_1_100000(b *testing.B)   { benchmarkRingWrite(b, MustNewRing(1), 100000) }
121func BenchmarkRing_write_4_100(b *testing.B)      { benchmarkRingWrite(b, MustNewRing(4), 100) }
122func BenchmarkRing_write_4_1000(b *testing.B)     { benchmarkRingWrite(b, MustNewRing(4), 1000) }
123func BenchmarkRing_write_4_10000(b *testing.B)    { benchmarkRingWrite(b, MustNewRing(4), 10000) }
124func BenchmarkRing_write_4_100000(b *testing.B)   { benchmarkRingWrite(b, MustNewRing(4), 100000) }
125func BenchmarkRing_write_32_100(b *testing.B)     { benchmarkRingWrite(b, MustNewRing(32), 100) }
126func BenchmarkRing_write_32_1000(b *testing.B)    { benchmarkRingWrite(b, MustNewRing(32), 1000) }
127func BenchmarkRing_write_32_10000(b *testing.B)   { benchmarkRingWrite(b, MustNewRing(32), 10000) }
128func BenchmarkRing_write_32_100000(b *testing.B)  { benchmarkRingWrite(b, MustNewRing(32), 100000) }
129func BenchmarkRing_write_128_100(b *testing.B)    { benchmarkRingWrite(b, MustNewRing(128), 100) }
130func BenchmarkRing_write_128_1000(b *testing.B)   { benchmarkRingWrite(b, MustNewRing(128), 1000) }
131func BenchmarkRing_write_128_10000(b *testing.B)  { benchmarkRingWrite(b, MustNewRing(128), 10000) }
132func BenchmarkRing_write_128_100000(b *testing.B) { benchmarkRingWrite(b, MustNewRing(256), 100000) }
133func BenchmarkRing_write_256_100(b *testing.B)    { benchmarkRingWrite(b, MustNewRing(256), 100) }
134func BenchmarkRing_write_256_1000(b *testing.B)   { benchmarkRingWrite(b, MustNewRing(256), 1000) }
135func BenchmarkRing_write_256_10000(b *testing.B)  { benchmarkRingWrite(b, MustNewRing(256), 10000) }
136func BenchmarkRing_write_256_100000(b *testing.B) { benchmarkRingWrite(b, MustNewRing(256), 100000) }
137
138func MustNewRing(n int) *ring {
139	r, err := newring(n)
140	if err != nil {
141		panic(err)
142	}
143	return r
144}
145