1package govarint 2 3import "bytes" 4import "io" 5import "math/rand" 6import "testing" 7 8var fourU32 = []uint32{ 9 0, 10 1, 11 0, 12 256, 13} 14 15var fiveU32 = []uint32{ 16 42, 17 4294967196, 18 384, 19 9716053, 20 1024 + 256 + 3, 21} 22 23var testU32 = []uint32{ 24 0, 25 1, 26 2, 27 10, 28 20, 29 63, 30 64, 31 65, 32 127, 33 128, 34 129, 35 255, 36 256, 37 257, 38} 39 40var testU64 = []uint64{ 41 0, 42 1, 43 2, 44 10, 45 20, 46 63, 47 64, 48 65, 49 127, 50 128, 51 129, 52 255, 53 256, 54 257, 55 /// 56 1<<32 - 1, 57 1 << 32, 58 1 << 33, 59 1 << 42, 60 1<<63 - 1, 61 1 << 63, 62} 63 64func TestEncodeAndDecodeU32(t *testing.T) { 65 for _, expected := range testU32 { 66 var buf bytes.Buffer 67 enc := NewU32Base128Encoder(&buf) 68 enc.PutU32(expected) 69 enc.Close() 70 dec := NewU32Base128Decoder(&buf) 71 x, err := dec.GetU32() 72 if x != expected || err != nil { 73 t.Errorf("ReadUvarint(%v): got x = %d, expected = %d, err = %s", buf, x, expected, err) 74 } 75 } 76 var buf bytes.Buffer 77 enc := NewU32Base128Encoder(&buf) 78 for _, expected := range testU32 { 79 enc.PutU32(expected) 80 } 81 enc.Close() 82 dec := NewU32Base128Decoder(&buf) 83 i := 0 84 for { 85 x, err := dec.GetU32() 86 if err == io.EOF { 87 break 88 } 89 if x != testU32[i] || err != nil { 90 t.Errorf("ReadUvarint(%v): got x = %d, expected = %d, err = %s", buf, x, testU32[i], err) 91 } 92 i += 1 93 } 94 if i != len(testU32) { 95 t.Errorf("Only %d integers were decoded when %d were encoded", i, len(testU32)) 96 } 97} 98 99func TestEncodeAndDecodeU64(t *testing.T) { 100 for _, expected := range testU64 { 101 var buf bytes.Buffer 102 enc := NewU64Base128Encoder(&buf) 103 enc.PutU64(expected) 104 enc.Close() 105 dec := NewU64Base128Decoder(&buf) 106 x, err := dec.GetU64() 107 if x != expected || err != nil { 108 t.Errorf("ReadUvarint(%v): got x = %d, expected = %d, err = %s", buf, x, expected, err) 109 } 110 } 111} 112 113func TestU32GroupVarintFour(t *testing.T) { 114 var buf bytes.Buffer 115 enc := NewU32GroupVarintEncoder(&buf) 116 for _, expected := range fourU32 { 117 enc.PutU32(expected) 118 } 119 enc.Close() 120 dec := NewU32GroupVarintDecoder(&buf) 121 i := 0 122 for { 123 x, err := dec.GetU32() 124 if err == io.EOF { 125 break 126 } 127 if err != nil && x != fourU32[i] { 128 t.Errorf("ReadUvarint(%v): got x = %d, expected = %d, err = %s", buf, x, testU32[i], err) 129 } 130 i += 1 131 } 132 if i != len(fourU32) { 133 t.Errorf("%d integers were decoded when %d were encoded", i, len(fourU32)) 134 } 135} 136 137func TestU32GroupVarintFive(t *testing.T) { 138 var buf bytes.Buffer 139 enc := NewU32GroupVarintEncoder(&buf) 140 for _, expected := range fiveU32 { 141 enc.PutU32(expected) 142 } 143 enc.Close() 144 dec := NewU32GroupVarintDecoder(&buf) 145 i := 0 146 for { 147 x, err := dec.GetU32() 148 if err == io.EOF { 149 break 150 } 151 if err != nil && x != fiveU32[i] { 152 t.Errorf("ReadUvarint(%v): got x = %d, expected = %d, err = %s", buf, x, testU32[i], err) 153 } 154 i += 1 155 } 156 if i != len(fiveU32) { 157 t.Errorf("%d integers were decoded when %d were encoded", i, len(fiveU32)) 158 } 159} 160 161func TestU32GroupVarint14(t *testing.T) { 162 var buf bytes.Buffer 163 for length := 0; length < len(testU32); length++ { 164 subset := testU32[:length] 165 enc := NewU32GroupVarintEncoder(&buf) 166 for _, expected := range subset { 167 enc.PutU32(expected) 168 } 169 enc.Close() 170 dec := NewU32GroupVarintDecoder(&buf) 171 i := 0 172 for { 173 x, err := dec.GetU32() 174 if err == io.EOF { 175 break 176 } 177 if err != nil && x != subset[i] { 178 t.Errorf("ReadUvarint(%v): got x = %d, expected = %d, err = %s", buf, x, subset[i], err) 179 } 180 i += 1 181 } 182 if i != len(subset) { 183 t.Errorf("%d integers were decoded when %d were encoded", i, len(subset)) 184 } 185 } 186} 187 188func generateRandomU14() (uint64, []uint32) { 189 // Need to be aware to make it fair for Base128 190 // Base128 has 7 usable bits per byte 191 rand.Seed(42) 192 testSize := 1000000 193 data := make([]uint32, testSize, testSize) 194 total := uint64(0) 195 for i := range data { 196 data[i] = rand.Uint32() % 16384 197 total += uint64(data[i]) 198 } 199 return total, data 200} 201 202func speedTest(b *testing.B, dec U32VarintDecoder, readBuf *bytes.Reader, expectedTotal uint64) { 203 total := uint64(0) 204 idx := 0 205 for { 206 x, err := dec.GetU32() 207 if err == io.EOF { 208 break 209 } 210 if err != nil { 211 b.Errorf("Hit err: %v", err) 212 } 213 total += uint64(x) 214 idx += 1 215 } 216 if total != expectedTotal { 217 b.Errorf("Total was %d when %d was expected, having read %d integers", total, expectedTotal, idx) 218 } 219} 220 221func BenchmarkBase128(b *testing.B) { 222 b.StopTimer() 223 // 224 var buf bytes.Buffer 225 enc := NewU32Base128Encoder(&buf) 226 expectedTotal, data := generateRandomU14() 227 for _, expected := range data { 228 enc.PutU32(expected) 229 } 230 enc.Close() 231 // 232 readBuf := bytes.NewReader(buf.Bytes()) 233 b.StartTimer() 234 for i := 0; i < b.N; i++ { 235 readBuf.Seek(0, 0) 236 dec := NewU32Base128Decoder(readBuf) 237 speedTest(b, dec, readBuf, expectedTotal) 238 } 239} 240 241func BenchmarkGroupVarint(b *testing.B) { 242 b.StopTimer() 243 // 244 var buf bytes.Buffer 245 enc := NewU32GroupVarintEncoder(&buf) 246 expectedTotal, data := generateRandomU14() 247 for _, expected := range data { 248 enc.PutU32(expected) 249 } 250 enc.Close() 251 // 252 readBuf := bytes.NewReader(buf.Bytes()) 253 b.StartTimer() 254 for i := 0; i < b.N; i++ { 255 readBuf.Seek(0, 0) 256 dec := NewU32GroupVarintDecoder(readBuf) 257 speedTest(b, dec, readBuf, expectedTotal) 258 } 259} 260