github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/util/encoding/encoding_test.go (about) 1 // Copyright 2014 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 encoding 12 13 import ( 14 "bytes" 15 "fmt" 16 "math" 17 "math/rand" 18 "regexp" 19 "testing" 20 "time" 21 22 "github.com/cockroachdb/apd" 23 "github.com/cockroachdb/cockroach/pkg/geo" 24 "github.com/cockroachdb/cockroach/pkg/geo/geopb" 25 "github.com/cockroachdb/cockroach/pkg/util/bitarray" 26 "github.com/cockroachdb/cockroach/pkg/util/duration" 27 "github.com/cockroachdb/cockroach/pkg/util/ipaddr" 28 "github.com/cockroachdb/cockroach/pkg/util/randutil" 29 "github.com/cockroachdb/cockroach/pkg/util/timeofday" 30 "github.com/cockroachdb/cockroach/pkg/util/timetz" 31 "github.com/cockroachdb/cockroach/pkg/util/timeutil" 32 "github.com/cockroachdb/cockroach/pkg/util/uuid" 33 "github.com/cockroachdb/errors" 34 "github.com/stretchr/testify/assert" 35 "github.com/stretchr/testify/require" 36 ) 37 38 func testBasicEncodeDecode32( 39 encFunc func([]byte, uint32) []byte, 40 decFunc func([]byte) ([]byte, uint32, error), 41 descending bool, 42 t *testing.T, 43 ) { 44 testCases := []uint32{ 45 0, 1, 46 1<<8 - 1, 1 << 8, 47 1<<16 - 1, 1 << 16, 48 1<<24 - 1, 1 << 24, 49 math.MaxUint32 - 1, math.MaxUint32, 50 } 51 52 var lastEnc []byte 53 for i, v := range testCases { 54 enc := encFunc(nil, v) 55 if i > 0 { 56 if (descending && bytes.Compare(enc, lastEnc) >= 0) || 57 (!descending && bytes.Compare(enc, lastEnc) < 0) { 58 t.Errorf("ordered constraint violated for %d: [% x] vs. [% x]", v, enc, lastEnc) 59 } 60 } 61 b, decode, err := decFunc(enc) 62 if err != nil { 63 t.Error(err) 64 continue 65 } 66 if len(b) != 0 { 67 t.Errorf("leftover bytes: [% x]", b) 68 } 69 if decode != v { 70 t.Errorf("decode yielded different value than input: %d vs. %d", decode, v) 71 } 72 lastEnc = enc 73 } 74 } 75 76 type testCaseUint32 struct { 77 value uint32 78 expEnc []byte 79 } 80 81 func testCustomEncodeUint32( 82 testCases []testCaseUint32, encFunc func([]byte, uint32) []byte, t *testing.T, 83 ) { 84 for _, test := range testCases { 85 enc := encFunc(nil, test.value) 86 if !bytes.Equal(enc, test.expEnc) { 87 t.Errorf("expected [% x]; got [% x]", test.expEnc, enc) 88 } 89 } 90 } 91 92 func TestEncodeDecodeUint32(t *testing.T) { 93 testBasicEncodeDecode32(EncodeUint32Ascending, DecodeUint32Ascending, false, t) 94 testCases := []testCaseUint32{ 95 {0, []byte{0x00, 0x00, 0x00, 0x00}}, 96 {1, []byte{0x00, 0x00, 0x00, 0x01}}, 97 {1 << 8, []byte{0x00, 0x00, 0x01, 0x00}}, 98 {math.MaxUint32, []byte{0xff, 0xff, 0xff, 0xff}}, 99 } 100 testCustomEncodeUint32(testCases, EncodeUint32Ascending, t) 101 } 102 103 func TestEncodeDecodeUint32Descending(t *testing.T) { 104 testBasicEncodeDecode32(EncodeUint32Descending, DecodeUint32Descending, true, t) 105 testCases := []testCaseUint32{ 106 {0, []byte{0xff, 0xff, 0xff, 0xff}}, 107 {1, []byte{0xff, 0xff, 0xff, 0xfe}}, 108 {1 << 8, []byte{0xff, 0xff, 0xfe, 0xff}}, 109 {math.MaxUint32, []byte{0x00, 0x00, 0x00, 0x00}}, 110 } 111 testCustomEncodeUint32(testCases, EncodeUint32Descending, t) 112 } 113 114 func testBasicEncodeDecodeUint64( 115 encFunc func([]byte, uint64) []byte, 116 decFunc func([]byte) ([]byte, uint64, error), 117 descending, testPeekLen, testUvarintEncLen bool, 118 t *testing.T, 119 ) { 120 testCases := []uint64{ 121 0, 1, 122 1<<8 - 1, 1 << 8, 123 1<<16 - 1, 1 << 16, 124 1<<24 - 1, 1 << 24, 125 1<<32 - 1, 1 << 32, 126 1<<40 - 1, 1 << 40, 127 1<<48 - 1, 1 << 48, 128 1<<56 - 1, 1 << 56, 129 math.MaxUint64 - 1, math.MaxUint64, 130 } 131 132 var lastEnc []byte 133 for i, v := range testCases { 134 enc := encFunc(nil, v) 135 if i > 0 { 136 if (descending && bytes.Compare(enc, lastEnc) >= 0) || 137 (!descending && bytes.Compare(enc, lastEnc) < 0) { 138 t.Errorf("ordered constraint violated for %d: [% x] vs. [% x]", v, enc, lastEnc) 139 } 140 } 141 b, decode, err := decFunc(enc) 142 if err != nil { 143 t.Error(err) 144 continue 145 } 146 if len(b) != 0 { 147 t.Errorf("leftover bytes: [% x]", b) 148 } 149 if decode != v { 150 t.Errorf("decode yielded different value than input: %d vs. %d", decode, v) 151 } 152 if testPeekLen { 153 testPeekLength(t, enc) 154 } 155 if testUvarintEncLen { 156 var encLen int 157 if descending { 158 encLen = EncLenUvarintDescending(v) 159 } else { 160 encLen = EncLenUvarintAscending(v) 161 } 162 if encLen != len(enc) { 163 t.Errorf("EncLenUvarint for %d returned incorrect length %d, should be %d", 164 v, encLen, len(enc)) 165 } 166 } 167 lastEnc = enc 168 } 169 } 170 171 var int64TestCases = [...]int64{ 172 math.MinInt64, math.MinInt64 + 1, 173 -1<<56 - 1, -1 << 56, 174 -1<<48 - 1, -1 << 48, 175 -1<<40 - 1, -1 << 40, 176 -1<<32 - 1, -1 << 32, 177 -1<<24 - 1, -1 << 24, 178 -1<<16 - 1, -1 << 16, 179 -1<<8 - 1, -1 << 8, 180 -1, 0, 1, 181 1<<8 - 1, 1 << 8, 182 1<<16 - 1, 1 << 16, 183 1<<24 - 1, 1 << 24, 184 1<<32 - 1, 1 << 32, 185 1<<40 - 1, 1 << 40, 186 1<<48 - 1, 1 << 48, 187 1<<56 - 1, 1 << 56, 188 math.MaxInt64 - 1, math.MaxInt64, 189 } 190 191 func testBasicEncodeDecodeInt64( 192 encFunc func([]byte, int64) []byte, 193 decFunc func([]byte) ([]byte, int64, error), 194 descending, testPeekLen bool, 195 t *testing.T, 196 ) { 197 var lastEnc []byte 198 for i, v := range int64TestCases { 199 enc := encFunc(nil, v) 200 if i > 0 { 201 if (descending && bytes.Compare(enc, lastEnc) >= 0) || 202 (!descending && bytes.Compare(enc, lastEnc) < 0) { 203 t.Errorf("ordered constraint violated for %d: [% x] vs. [% x]", v, enc, lastEnc) 204 } 205 } 206 b, decode, err := decFunc(enc) 207 if err != nil { 208 t.Errorf("%v: %d [%x]", err, v, enc) 209 continue 210 } 211 if len(b) != 0 { 212 t.Errorf("leftover bytes: [% x]", b) 213 } 214 if decode != v { 215 t.Errorf("decode yielded different value than input: %d vs. %d [%x]", decode, v, enc) 216 } 217 if testPeekLen { 218 testPeekLength(t, enc) 219 } 220 lastEnc = enc 221 } 222 } 223 224 type testCaseInt64 struct { 225 value int64 226 expEnc []byte 227 } 228 229 func testCustomEncodeInt64( 230 testCases []testCaseInt64, encFunc func([]byte, int64) []byte, t *testing.T, 231 ) { 232 for _, test := range testCases { 233 enc := encFunc(nil, test.value) 234 if !bytes.Equal(enc, test.expEnc) { 235 t.Errorf("expected [% x]; got [% x] (value: %d)", test.expEnc, enc, test.value) 236 } 237 } 238 } 239 240 type testCaseUint64 struct { 241 value uint64 242 expEnc []byte 243 } 244 245 func testCustomEncodeUint64( 246 testCases []testCaseUint64, encFunc func([]byte, uint64) []byte, t *testing.T, 247 ) { 248 for _, test := range testCases { 249 enc := encFunc(nil, test.value) 250 if !bytes.Equal(enc, test.expEnc) { 251 t.Errorf("expected [% x]; got [% x] (value: %d)", test.expEnc, enc, test.value) 252 } 253 } 254 } 255 256 func TestEncodeDecodeUint64(t *testing.T) { 257 testBasicEncodeDecodeUint64(EncodeUint64Ascending, DecodeUint64Ascending, false, false, false, t) 258 testCases := []testCaseUint64{ 259 {0, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 260 {1, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}}, 261 {1 << 8, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00}}, 262 {math.MaxUint64, []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}, 263 } 264 testCustomEncodeUint64(testCases, EncodeUint64Ascending, t) 265 } 266 267 func TestEncodeDecodeUint64Descending(t *testing.T) { 268 testBasicEncodeDecodeUint64(EncodeUint64Descending, DecodeUint64Descending, true, false, false, t) 269 testCases := []testCaseUint64{ 270 {0, []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}, 271 {1, []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe}}, 272 {1 << 8, []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff}}, 273 {math.MaxUint64, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 274 } 275 testCustomEncodeUint64(testCases, EncodeUint64Descending, t) 276 } 277 278 func TestEncodeDecodeVarint(t *testing.T) { 279 testBasicEncodeDecodeInt64(EncodeVarintAscending, DecodeVarintAscending, false, true, t) 280 testCases := []testCaseInt64{ 281 {math.MinInt64, []byte{0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 282 {math.MinInt64 + 1, []byte{0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}}, 283 {-1 << 8, []byte{0x86, 0xff, 0x00}}, 284 {-1, []byte{0x87, 0xff}}, 285 {0, []byte{0x88}}, 286 {1, []byte{0x89}}, 287 {109, []byte{0xf5}}, 288 {112, []byte{0xf6, 0x70}}, 289 {1 << 8, []byte{0xf7, 0x01, 0x00}}, 290 {math.MaxInt64, []byte{0xfd, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}, 291 } 292 testCustomEncodeInt64(testCases, EncodeVarintAscending, t) 293 } 294 295 func TestEncodeDecodeVarintDescending(t *testing.T) { 296 testBasicEncodeDecodeInt64(EncodeVarintDescending, DecodeVarintDescending, true, true, t) 297 testCases := []testCaseInt64{ 298 {math.MinInt64, []byte{0xfd, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}, 299 {math.MinInt64 + 1, []byte{0xfd, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe}}, 300 {-1 << 8, []byte{0xf6, 0xff}}, 301 {-110, []byte{0xf5}}, 302 {-1, []byte{0x88}}, 303 {0, []byte{0x87, 0xff}}, 304 {1, []byte{0x87, 0xfe}}, 305 {1 << 8, []byte{0x86, 0xfe, 0xff}}, 306 {math.MaxInt64, []byte{0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 307 } 308 testCustomEncodeInt64(testCases, EncodeVarintDescending, t) 309 } 310 311 func TestEncodeDecodeUvarint(t *testing.T) { 312 testBasicEncodeDecodeUint64(EncodeUvarintAscending, DecodeUvarintAscending, false, true, true, t) 313 testCases := []testCaseUint64{ 314 {0, []byte{0x88}}, 315 {1, []byte{0x89}}, 316 {109, []byte{0xf5}}, 317 {110, []byte{0xf6, 0x6e}}, 318 {1 << 8, []byte{0xf7, 0x01, 0x00}}, 319 {math.MaxUint64, []byte{0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}, 320 } 321 testCustomEncodeUint64(testCases, EncodeUvarintAscending, t) 322 } 323 324 func TestEncodeDecodeUvarintDescending(t *testing.T) { 325 testBasicEncodeDecodeUint64(EncodeUvarintDescending, DecodeUvarintDescending, true, true, true, t) 326 testCases := []testCaseUint64{ 327 {0, []byte{0x88}}, 328 {1, []byte{0x87, 0xfe}}, 329 {1 << 8, []byte{0x86, 0xfe, 0xff}}, 330 {math.MaxUint64 - 1, []byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}}, 331 {math.MaxUint64, []byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 332 } 333 testCustomEncodeUint64(testCases, EncodeUvarintDescending, t) 334 } 335 336 // TestDecodeInvalid tests that decoding invalid bytes panics. 337 func TestDecodeInvalid(t *testing.T) { 338 tests := []struct { 339 name string // name printed with errors. 340 buf []byte // buf contains an invalid uvarint to decode. 341 pattern string // pattern matches the panic string. 342 decode func([]byte) error // decode is called with buf. 343 }{ 344 { 345 name: "DecodeVarint, overflows int64", 346 buf: []byte{IntMax, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, 347 pattern: "varint [0-9]+ overflows int64", 348 decode: func(b []byte) error { _, _, err := DecodeVarintAscending(b); return err }, 349 }, 350 { 351 name: "Bytes, no marker", 352 buf: []byte{'a'}, 353 pattern: "did not find marker", 354 decode: func(b []byte) error { _, _, err := DecodeBytesAscending(b, nil); return err }, 355 }, 356 { 357 name: "Bytes, no terminator", 358 buf: []byte{bytesMarker, 'a'}, 359 pattern: "did not find terminator", 360 decode: func(b []byte) error { _, _, err := DecodeBytesAscending(b, nil); return err }, 361 }, 362 { 363 name: "Bytes, malformed escape", 364 buf: []byte{bytesMarker, 'a', 0x00}, 365 pattern: "malformed escape", 366 decode: func(b []byte) error { _, _, err := DecodeBytesAscending(b, nil); return err }, 367 }, 368 { 369 name: "Bytes, invalid escape 1", 370 buf: []byte{bytesMarker, 'a', 0x00, 0x00}, 371 pattern: "unknown escape", 372 decode: func(b []byte) error { _, _, err := DecodeBytesAscending(b, nil); return err }, 373 }, 374 { 375 name: "Bytes, invalid escape 2", 376 buf: []byte{bytesMarker, 'a', 0x00, 0x02}, 377 pattern: "unknown escape", 378 decode: func(b []byte) error { _, _, err := DecodeBytesAscending(b, nil); return err }, 379 }, 380 { 381 name: "BytesDescending, no marker", 382 buf: []byte{'a'}, 383 pattern: "did not find marker", 384 decode: func(b []byte) error { _, _, err := DecodeBytesAscending(b, nil); return err }, 385 }, 386 { 387 name: "BytesDescending, no terminator", 388 buf: []byte{bytesDescMarker, ^byte('a')}, 389 pattern: "did not find terminator", 390 decode: func(b []byte) error { _, _, err := DecodeBytesDescending(b, nil); return err }, 391 }, 392 { 393 name: "BytesDescending, malformed escape", 394 buf: []byte{bytesDescMarker, ^byte('a'), 0xff}, 395 pattern: "malformed escape", 396 decode: func(b []byte) error { _, _, err := DecodeBytesDescending(b, nil); return err }, 397 }, 398 { 399 name: "BytesDescending, invalid escape 1", 400 buf: []byte{bytesDescMarker, ^byte('a'), 0xff, 0xff}, 401 pattern: "unknown escape", 402 decode: func(b []byte) error { _, _, err := DecodeBytesDescending(b, nil); return err }, 403 }, 404 { 405 name: "BytesDescending, invalid escape 2", 406 buf: []byte{bytesDescMarker, ^byte('a'), 0xff, 0xfd}, 407 pattern: "unknown escape", 408 decode: func(b []byte) error { _, _, err := DecodeBytesDescending(b, nil); return err }, 409 }, 410 { 411 name: "Decimal, malformed uvarint", 412 buf: []byte{decimalPosLarge}, 413 pattern: "insufficient bytes to decode uvarint value", 414 decode: func(b []byte) error { _, _, err := DecodeDecimalAscending(b, nil); return err }, 415 }, 416 { 417 name: "DecimalDescending, malformed uvarint", 418 buf: []byte{decimalPosLarge}, 419 pattern: "insufficient bytes to decode uvarint value", 420 decode: func(b []byte) error { _, _, err := DecodeDecimalDescending(b, nil); return err }, 421 }, 422 } 423 for _, test := range tests { 424 err := test.decode(test.buf) 425 if !regexp.MustCompile(test.pattern).MatchString(err.Error()) { 426 t.Errorf("%q, pattern %q doesn't match %q", test.name, test.pattern, err) 427 } 428 } 429 } 430 431 // testPeekLength appends some random garbage to an encoding and verifies 432 // that PeekLength returns the correct length. 433 func testPeekLength(t *testing.T, encoded []byte) { 434 gLen := rand.Intn(10) 435 garbage := make([]byte, gLen) 436 _, _ = rand.Read(garbage) 437 438 var buf []byte 439 buf = append(buf, encoded...) 440 buf = append(buf, garbage...) 441 442 if l, err := PeekLength(buf); err != nil { 443 t.Fatal(err) 444 } else if l != len(encoded) { 445 t.Errorf("PeekLength returned incorrect length: %d, expected %d", l, len(encoded)) 446 } 447 } 448 449 func TestEncodeDecodeBytes(t *testing.T) { 450 testCases := []struct { 451 value []byte 452 encoded []byte 453 }{ 454 {[]byte{0, 1, 'a'}, []byte{0x12, 0x00, 0xff, 1, 'a', 0x00, 0x01}}, 455 {[]byte{0, 'a'}, []byte{0x12, 0x00, 0xff, 'a', 0x00, 0x01}}, 456 {[]byte{0, 0xff, 'a'}, []byte{0x12, 0x00, 0xff, 0xff, 'a', 0x00, 0x01}}, 457 {[]byte{'a'}, []byte{0x12, 'a', 0x00, 0x01}}, 458 {[]byte{'b'}, []byte{0x12, 'b', 0x00, 0x01}}, 459 {[]byte{'b', 0}, []byte{0x12, 'b', 0x00, 0xff, 0x00, 0x01}}, 460 {[]byte{'b', 0, 0}, []byte{0x12, 'b', 0x00, 0xff, 0x00, 0xff, 0x00, 0x01}}, 461 {[]byte{'b', 0, 0, 'a'}, []byte{0x12, 'b', 0x00, 0xff, 0x00, 0xff, 'a', 0x00, 0x01}}, 462 {[]byte{'b', 0xff}, []byte{0x12, 'b', 0xff, 0x00, 0x01}}, 463 {[]byte("hello"), []byte{0x12, 'h', 'e', 'l', 'l', 'o', 0x00, 0x01}}, 464 } 465 for i, c := range testCases { 466 enc := EncodeBytesAscending(nil, c.value) 467 if !bytes.Equal(enc, c.encoded) { 468 t.Errorf("unexpected encoding mismatch for %v. expected [% x], got [% x]", 469 c.value, c.encoded, enc) 470 } 471 if i > 0 { 472 if bytes.Compare(testCases[i-1].encoded, enc) >= 0 { 473 t.Errorf("%v: expected [% x] to be less than [% x]", 474 c.value, testCases[i-1].encoded, enc) 475 } 476 } 477 remainder, dec, err := DecodeBytesAscending(enc, nil) 478 if err != nil { 479 t.Error(err) 480 continue 481 } 482 if !bytes.Equal(c.value, dec) { 483 t.Errorf("unexpected decoding mismatch for %v. got %v", c.value, dec) 484 } 485 if len(remainder) != 0 { 486 t.Errorf("unexpected remaining bytes: %v", remainder) 487 } 488 489 testPeekLength(t, enc) 490 491 enc = append(enc, []byte("remainder")...) 492 remainder, _, err = DecodeBytesAscending(enc, nil) 493 if err != nil { 494 t.Error(err) 495 continue 496 } 497 if string(remainder) != "remainder" { 498 t.Errorf("unexpected remaining bytes: %v", remainder) 499 } 500 } 501 } 502 503 func TestEncodeDecodeBytesDescending(t *testing.T) { 504 testCases := []struct { 505 value []byte 506 encoded []byte 507 }{ 508 {[]byte("hello"), []byte{0x13, ^byte('h'), ^byte('e'), ^byte('l'), ^byte('l'), ^byte('o'), 0xff, 0xfe}}, 509 {[]byte{'b', 0xff}, []byte{0x13, ^byte('b'), 0x00, 0xff, 0xfe}}, 510 {[]byte{'b', 0, 0, 'a'}, []byte{0x13, ^byte('b'), 0xff, 0x00, 0xff, 0x00, ^byte('a'), 0xff, 0xfe}}, 511 {[]byte{'b', 0, 0}, []byte{0x13, ^byte('b'), 0xff, 0x00, 0xff, 0x00, 0xff, 0xfe}}, 512 {[]byte{'b', 0}, []byte{0x13, ^byte('b'), 0xff, 0x00, 0xff, 0xfe}}, 513 {[]byte{'b'}, []byte{0x13, ^byte('b'), 0xff, 0xfe}}, 514 {[]byte{'a'}, []byte{0x13, ^byte('a'), 0xff, 0xfe}}, 515 {[]byte{0, 0xff, 'a'}, []byte{0x13, 0xff, 0x00, 0x00, ^byte('a'), 0xff, 0xfe}}, 516 {[]byte{0, 'a'}, []byte{0x13, 0xff, 0x00, ^byte('a'), 0xff, 0xfe}}, 517 {[]byte{0, 1, 'a'}, []byte{0x13, 0xff, 0x00, 0xfe, ^byte('a'), 0xff, 0xfe}}, 518 } 519 for i, c := range testCases { 520 enc := EncodeBytesDescending(nil, c.value) 521 if !bytes.Equal(enc, c.encoded) { 522 t.Errorf("%d: unexpected encoding mismatch for %v ([% x]). expected [% x], got [% x]", 523 i, c.value, c.value, c.encoded, enc) 524 } 525 if i > 0 { 526 if bytes.Compare(testCases[i-1].encoded, enc) >= 0 { 527 t.Errorf("%v: expected [% x] to be less than [% x]", 528 c.value, testCases[i-1].encoded, enc) 529 } 530 } 531 remainder, dec, err := DecodeBytesDescending(enc, nil) 532 if err != nil { 533 t.Error(err) 534 continue 535 } 536 if !bytes.Equal(c.value, dec) { 537 t.Errorf("unexpected decoding mismatch for %v. got %v", c.value, dec) 538 } 539 if len(remainder) != 0 { 540 t.Errorf("unexpected remaining bytes: %v", remainder) 541 } 542 543 testPeekLength(t, enc) 544 545 enc = append(enc, []byte("remainder")...) 546 remainder, _, err = DecodeBytesDescending(enc, nil) 547 if err != nil { 548 t.Error(err) 549 continue 550 } 551 if string(remainder) != "remainder" { 552 t.Errorf("unexpected remaining bytes: %v", remainder) 553 } 554 } 555 } 556 557 func TestEncodeDecodeUnsafeString(t *testing.T) { 558 testCases := []struct { 559 value string 560 encoded []byte 561 }{ 562 {"\x00\x01a", []byte{0x12, 0x00, 0xff, 1, 'a', 0x00, 0x01}}, 563 {"\x00a", []byte{0x12, 0x00, 0xff, 'a', 0x00, 0x01}}, 564 {"\x00\xffa", []byte{0x12, 0x00, 0xff, 0xff, 'a', 0x00, 0x01}}, 565 {"a", []byte{0x12, 'a', 0x00, 0x01}}, 566 {"b", []byte{0x12, 'b', 0x00, 0x01}}, 567 {"b\x00", []byte{0x12, 'b', 0x00, 0xff, 0x00, 0x01}}, 568 {"b\x00\x00", []byte{0x12, 'b', 0x00, 0xff, 0x00, 0xff, 0x00, 0x01}}, 569 {"b\x00\x00a", []byte{0x12, 'b', 0x00, 0xff, 0x00, 0xff, 'a', 0x00, 0x01}}, 570 {"b\xff", []byte{0x12, 'b', 0xff, 0x00, 0x01}}, 571 {"hello", []byte{0x12, 'h', 'e', 'l', 'l', 'o', 0x00, 0x01}}, 572 } 573 for i, c := range testCases { 574 enc := EncodeStringAscending(nil, c.value) 575 if !bytes.Equal(enc, c.encoded) { 576 t.Errorf("unexpected encoding mismatch for %v. expected [% x], got [% x]", 577 c.value, c.encoded, enc) 578 } 579 if i > 0 { 580 if bytes.Compare(testCases[i-1].encoded, enc) >= 0 { 581 t.Errorf("%v: expected [% x] to be less than [% x]", 582 c.value, testCases[i-1].encoded, enc) 583 } 584 } 585 remainder, dec, err := DecodeUnsafeStringAscending(enc, nil) 586 if err != nil { 587 t.Error(err) 588 continue 589 } 590 if c.value != dec { 591 t.Errorf("unexpected decoding mismatch for %v. got %v", c.value, dec) 592 } 593 if len(remainder) != 0 { 594 t.Errorf("unexpected remaining bytes: %v", remainder) 595 } 596 597 testPeekLength(t, enc) 598 599 enc = append(enc, "remainder"...) 600 remainder, _, err = DecodeUnsafeStringAscending(enc, nil) 601 if err != nil { 602 t.Error(err) 603 continue 604 } 605 if string(remainder) != "remainder" { 606 t.Errorf("unexpected remaining bytes: %v", remainder) 607 } 608 } 609 } 610 611 func encodeBitArrayWithDir(dir Direction, buf []byte, d bitarray.BitArray) []byte { 612 if dir == Ascending { 613 return EncodeBitArrayAscending(buf, d) 614 } 615 return EncodeBitArrayDescending(buf, d) 616 } 617 618 func decodeBitArrayWithDir( 619 t *testing.T, dir Direction, buf []byte, tmp []byte, 620 ) ([]byte, bitarray.BitArray) { 621 var err error 622 var resBuf []byte 623 var res bitarray.BitArray 624 if dir == Ascending { 625 resBuf, res, err = DecodeBitArrayAscending(buf) 626 } else { 627 resBuf, res, err = DecodeBitArrayDescending(buf) 628 } 629 if err != nil { 630 t.Fatal(err) 631 } 632 return resBuf, res 633 } 634 635 func TestEncodeBitArray(t *testing.T) { 636 ba := func(s string) bitarray.BitArray { 637 res, _ := bitarray.Parse(s) 638 return res 639 } 640 641 testCases := []struct { 642 Value bitarray.BitArray 643 Encoding []byte 644 }{ 645 {ba(""), 646 []byte{0x3a, 0 /* no words */, 0x88}}, 647 {ba("0"), 648 []byte{0x3a, 0x88 /* word 0 */, 0, 0x89}}, 649 {ba("1"), 650 []byte{0x3a, 651 0xfd, 0x80, 0, 0, 0, 0, 0, 0, 0, // word 0 652 0, 0x89}}, 653 {ba("00"), 654 []byte{0x3a, 0x88 /* word 0 */, 0, 0x8a}}, 655 {ba("01"), 656 []byte{0x3a, 657 0xfd, 0x40, 0, 0, 0, 0, 0, 0, 0, // word 0 658 0, 0x8a}}, 659 {ba("10"), 660 []byte{0x3a, 661 0xfd, 0x80, 0, 0, 0, 0, 0, 0, 0, // word 0 662 0, 0x8a}}, 663 {ba("11"), 664 []byte{0x3a, 665 0xfd, 0xc0, 0, 0, 0, 0, 0, 0, 0, // word 0 666 0, 0x8a}}, 667 {bitarray.MakeZeroBitArray(32), 668 []byte{0x3a, 0x88 /* word 0*/, 0, 0xa8}}, 669 {bitarray.Not(bitarray.MakeZeroBitArray(32)), 670 []byte{0x3a, 671 0xfd, 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, // word 0 672 0, 0xa8}}, 673 {bitarray.Concat(bitarray.MakeZeroBitArray(32), ba("00")), 674 []byte{0x3a, 0x88 /* word 0 */, 0, 0xaa}}, 675 {bitarray.Concat(bitarray.MakeZeroBitArray(32), ba("01")), 676 []byte{0x3a, 677 0xf9, 0x40, 0, 0, 0, // word 0 678 0, 0xaa}}, 679 {bitarray.Concat(bitarray.MakeZeroBitArray(32), ba("10")), 680 []byte{0x3a, 681 0xf9, 0x80, 0, 0, 0, // word 0 682 0, 0xaa}}, 683 {bitarray.Concat(bitarray.MakeZeroBitArray(32), ba("11")), 684 []byte{0x3a, 685 0xf9, 0xc0, 0, 0, 0, // word 0 686 0, 0xaa}}, 687 {bitarray.MakeZeroBitArray(48), 688 []byte{0x3a, 0x88 /* word 0 */, 0, 0xb8}}, 689 {bitarray.Not(bitarray.MakeZeroBitArray(48)), 690 []byte{0x3a, 691 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, // word 0 692 0, 0xb8}}, 693 {bitarray.Concat(bitarray.MakeZeroBitArray(48), ba("00")), 694 []byte{0x3a, 0x88 /* word 0 */, 0, 0xba}}, 695 {bitarray.Concat(bitarray.MakeZeroBitArray(48), ba("01")), 696 []byte{0x3a, 697 0xf7, 0x40, 0, // word 0 698 0, 0xba}}, 699 {bitarray.Concat(bitarray.MakeZeroBitArray(48), ba("10")), 700 []byte{0x3a, 701 0xf7, 0x80, 0, // word 0 702 0, 0xba}}, 703 {bitarray.Concat(bitarray.MakeZeroBitArray(48), ba("11")), 704 []byte{0x3a, 705 0xf7, 0xc0, 0, // word 0 706 0, 0xba}}, 707 {bitarray.MakeZeroBitArray(62), 708 []byte{0x3a, 709 0x88, //word 0 710 0, 0xc6}}, 711 {bitarray.Not(bitarray.MakeZeroBitArray(62)), 712 []byte{0x3a, 713 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, // word 0 714 0, 0xc6}}, 715 {bitarray.Concat(bitarray.MakeZeroBitArray(62), ba("00")), 716 []byte{0x3a, 0x88 /* word 0*/, 0, 0xc8}}, 717 {bitarray.Concat(bitarray.MakeZeroBitArray(62), ba("01")), 718 []byte{0x3a, 0x89 /* word 0*/, 0, 0xc8}}, 719 {bitarray.Concat(bitarray.MakeZeroBitArray(62), ba("10")), 720 []byte{0x3a, 0x8a /* word 0*/, 0, 0xc8}}, 721 {bitarray.Concat(bitarray.MakeZeroBitArray(62), ba("11")), 722 []byte{0x3a, 0x8b /* word 0*/, 0, 0xc8}}, 723 {bitarray.Not(bitarray.MakeZeroBitArray(64)), 724 []byte{0x3a, 725 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // word 0 726 0, 0xc8}}, 727 {bitarray.MakeZeroBitArray(65), 728 []byte{0x3a, 729 0x88, // word 0 730 0x88, // word 1 731 0, 0x89}}, 732 {bitarray.Not(bitarray.MakeZeroBitArray(65)), 733 []byte{0x3a, 734 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // word 0 735 0xfd, 0x80, 0, 0, 0, 0, 0, 0, 0, // word 1 736 0, 0x89}}, 737 {bitarray.MakeZeroBitArray(66), 738 []byte{0x3a, 739 0x88, // word 0 740 0x88, // word 1 741 0, 0x8a}}, 742 {bitarray.MakeZeroBitArray(128), 743 []byte{0x3a, 744 0x88, // word 0 745 0x88, // word 1 746 0, 0xc8}}, 747 {bitarray.Not(bitarray.MakeZeroBitArray(128)), 748 []byte{0x3a, 749 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // word 0 750 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // word 1 751 0, 0xc8}}, 752 } 753 754 rng, _ := randutil.NewPseudoRand() 755 756 var lastEncoded []byte 757 dirNames := []string{"", "asc", "desc"} 758 for _, dir := range []Direction{Ascending, Descending} { 759 for _, tmp := range [][]byte{nil, make([]byte, 0, 100)} { 760 for i, c := range testCases { 761 t.Run(fmt.Sprintf("%s/%d/%d/%s", dirNames[dir], cap(tmp), i, c.Value), func(t *testing.T) { 762 enc := encodeBitArrayWithDir(dir, nil, c.Value) 763 _, dec := decodeBitArrayWithDir(t, dir, enc, tmp) 764 if dir == Ascending && !bytes.Equal(enc, c.Encoding) { 765 t.Errorf("unexpected mismatch for %s. expected [% x], got [% x]", 766 c.Value, c.Encoding, enc) 767 } 768 if i > 0 { 769 valCompare := bitarray.Compare(testCases[i-1].Value, testCases[i].Value) 770 expCompare := valCompare 771 if dir == Descending { 772 expCompare = -expCompare 773 } 774 const compareSigns = "<=>" 775 gotCompare := bytes.Compare(lastEncoded, enc) 776 if gotCompare != expCompare { 777 t.Errorf("%q %c %q, however their %s encodings are %v %c %v", 778 testCases[i-1].Value, compareSigns[valCompare+1], testCases[i].Value, 779 dirNames[dir], 780 lastEncoded, compareSigns[gotCompare+1], enc) 781 } 782 } 783 testPeekLength(t, enc) 784 if bitarray.Compare(dec, c.Value) != 0 { 785 t.Errorf("%d unexpected mismatch for %v. got %v", i, c.Value, dec) 786 } 787 lastEncoded = enc 788 789 // Test that appending the bitarray to an existing buffer works. It 790 // is important to test with various values, slice lengths, and 791 // capacities because the various encoding paths try to use any 792 // spare capacity to avoid allocations. 793 for trials := 0; trials < 5; trials++ { 794 orig := randBuf(rng, 30) 795 origLen := len(orig) 796 797 bufCap := origLen + rng.Intn(30) 798 buf := make([]byte, origLen, bufCap) 799 copy(buf, orig) 800 801 enc := encodeBitArrayWithDir(dir, buf, c.Value) 802 // Append some random bytes 803 enc = append(enc, randBuf(rng, 20)...) 804 _, dec := decodeBitArrayWithDir(t, dir, enc[origLen:], tmp) 805 806 if bitarray.Compare(dec, c.Value) != 0 { 807 t.Errorf("unexpected mismatch for %v. got %v", c.Value, dec) 808 } 809 // Verify the existing values weren't modified. 810 for i := range orig { 811 if enc[i] != orig[i] { 812 t.Errorf("existing byte %d changed after encoding (from %d to %d)", 813 i, orig[i], enc[i]) 814 } 815 } 816 } 817 }) 818 } 819 } 820 } 821 } 822 823 func TestKeyEncodeDecodeBitArrayRand(t *testing.T) { 824 rng, seed := randutil.NewPseudoRand() 825 rd := randData{rng} 826 tests := make([]bitarray.BitArray, 1000) 827 for i := range tests { 828 tests[i] = rd.bitArray() 829 } 830 for i, test := range tests { 831 for _, dir := range []Direction{Ascending, Descending} { 832 var remainder, buf []byte 833 var err error 834 var x bitarray.BitArray 835 if dir == Ascending { 836 buf = EncodeBitArrayAscending(nil, test) 837 remainder, x, err = DecodeBitArrayAscending(buf) 838 } else { 839 buf = EncodeBitArrayAscending(nil, test) 840 remainder, x, err = DecodeBitArrayAscending(buf) 841 } 842 if err != nil { 843 t.Fatalf("%+v", err) 844 } 845 if bitarray.Compare(x, tests[i]) != 0 { 846 t.Errorf("seed %d: expected %v got %v (buf: %+v)", seed, &tests[i], &x, buf) 847 } 848 if len(remainder) > 0 { 849 t.Errorf("seed %d: decoding %v tailing bytes: %+v", seed, &tests[i], remainder) 850 } 851 } 852 } 853 } 854 855 func TestPrettyPrintValue(t *testing.T) { 856 ba := bitarray.MakeBitArrayFromInt64(8, 58, 7) 857 858 testData := []struct { 859 dir Direction 860 key []byte 861 exp string 862 }{ 863 {Ascending, EncodeFloatAscending(nil, float64(233.221112)), "/233.221112"}, 864 {Descending, EncodeFloatDescending(nil, float64(233.221112)), "/233.221112"}, 865 {Ascending, EncodeBitArrayAscending(nil, ba), "/B00111010"}, 866 {Descending, EncodeBitArrayDescending(nil, ba), "/B00111010"}, 867 } 868 869 for _, test := range testData { 870 dirStr := "Asc" 871 if test.dir != Ascending { 872 dirStr = "Desc" 873 } 874 t.Run(test.exp[1:]+"/"+dirStr, func(t *testing.T) { 875 got := PrettyPrintValue([]Direction{test.dir}, test.key, "/") 876 if got != test.exp { 877 t.Errorf("expected %q, got %q", test.exp, got) 878 } 879 }) 880 } 881 } 882 883 func TestEncodeDecodeUnsafeStringDescending(t *testing.T) { 884 testCases := []struct { 885 value string 886 encoded []byte 887 }{ 888 {"hello", []byte{0x13, ^byte('h'), ^byte('e'), ^byte('l'), ^byte('l'), ^byte('o'), 0xff, 0xfe}}, 889 {"b\xff", []byte{0x13, ^byte('b'), 0x00, 0xff, 0xfe}}, 890 {"b\x00\x00a", []byte{0x13, ^byte('b'), 0xff, 0x00, 0xff, 0x00, ^byte('a'), 0xff, 0xfe}}, 891 {"b\x00\x00", []byte{0x13, ^byte('b'), 0xff, 0x00, 0xff, 0x00, 0xff, 0xfe}}, 892 {"b\x00", []byte{0x13, ^byte('b'), 0xff, 0x00, 0xff, 0xfe}}, 893 {"b", []byte{0x13, ^byte('b'), 0xff, 0xfe}}, 894 {"a", []byte{0x13, ^byte('a'), 0xff, 0xfe}}, 895 {"\x00\xffa", []byte{0x13, 0xff, 0x00, 0x00, ^byte('a'), 0xff, 0xfe}}, 896 {"\x00a", []byte{0x13, 0xff, 0x00, ^byte('a'), 0xff, 0xfe}}, 897 {"\x00\x01a", []byte{0x13, 0xff, 0x00, 0xfe, ^byte('a'), 0xff, 0xfe}}, 898 } 899 for i, c := range testCases { 900 enc := EncodeStringDescending(nil, c.value) 901 if !bytes.Equal(enc, c.encoded) { 902 t.Errorf("unexpected encoding mismatch for %v. expected [% x], got [% x]", 903 c.value, c.encoded, enc) 904 } 905 if i > 0 { 906 if bytes.Compare(testCases[i-1].encoded, enc) >= 0 { 907 t.Errorf("%v: expected [% x] to be less than [% x]", 908 c.value, testCases[i-1].encoded, enc) 909 } 910 } 911 remainder, dec, err := DecodeUnsafeStringDescending(enc, nil) 912 if err != nil { 913 t.Error(err) 914 continue 915 } 916 if c.value != dec { 917 t.Errorf("unexpected decoding mismatch for %v. got [% x]", c.value, dec) 918 } 919 if len(remainder) != 0 { 920 t.Errorf("unexpected remaining bytes: %v", remainder) 921 } 922 923 testPeekLength(t, enc) 924 925 enc = append(enc, "remainder"...) 926 remainder, _, err = DecodeUnsafeStringDescending(enc, nil) 927 if err != nil { 928 t.Error(err) 929 continue 930 } 931 if string(remainder) != "remainder" { 932 t.Errorf("unexpected remaining bytes: %v", remainder) 933 } 934 } 935 } 936 937 func TestEncodeDecodeNull(t *testing.T) { 938 const hello = "hello" 939 940 buf := EncodeNullAscending([]byte(hello)) 941 expected := []byte(hello + "\x00") 942 if !bytes.Equal(expected, buf) { 943 t.Fatalf("expected %q, but found %q", expected, buf) 944 } 945 946 if remaining, isNull := DecodeIfNull([]byte(hello)); isNull { 947 t.Fatalf("expected isNull=false, but found isNull=%v", isNull) 948 } else if hello != string(remaining) { 949 t.Fatalf("expected %q, but found %q", hello, remaining) 950 } 951 952 if remaining, isNull := DecodeIfNull([]byte("\x00" + hello)); !isNull { 953 t.Fatalf("expected isNull=true, but found isNull=%v", isNull) 954 } else if hello != string(remaining) { 955 t.Fatalf("expected %q, but found %q", hello, remaining) 956 } 957 } 958 959 func TestEncodeDecodeInterleavedSentinel(t *testing.T) { 960 const hello = "hello" 961 962 buf := EncodeInterleavedSentinel([]byte(hello)) 963 expected := []byte(hello + "\xfe") 964 if !bytes.Equal(expected, buf) { 965 t.Fatalf("expected %q, but found %q", expected, buf) 966 } 967 968 if remaining, isSentinel := DecodeIfInterleavedSentinel([]byte(hello)); isSentinel { 969 t.Fatalf("expected isSentinel=false, but found isSentinel=%v", isSentinel) 970 } else if hello != string(remaining) { 971 t.Fatalf("expected %q, but found %q", hello, remaining) 972 } 973 974 if remaining, isSentinel := DecodeIfNull([]byte("\x00" + hello)); !isSentinel { 975 t.Fatalf("expected isSentinel=true, but found isSentinel=%v", isSentinel) 976 } else if hello != string(remaining) { 977 t.Fatalf("expected %q, but found %q", hello, remaining) 978 } 979 } 980 981 func TestEncodeDecodeTime(t *testing.T) { 982 zeroTime := timeutil.Unix(0, 0) 983 984 // test cases are negative, increasing, duration offsets from the 985 // zeroTime. The positive, increasing, duration offsets are automatically 986 // genarated below. 987 testCases := []string{ 988 "-1345600h45m34s234ms", 989 "-600h45m34s234ms", 990 "-590h47m34s234ms", 991 "-310h45m34s234ms", 992 "-310h45m34s233ms", 993 "-25h45m34s234ms", 994 "-23h45m35s", 995 "-23h45m34s999999999ns", 996 "-23h45m34s234ms", 997 "-23h45m34s101ms", 998 "-23h45m34s1ns", 999 "-23h45m34s", 1000 "-23h45m33s901ms", 1001 "-23h45m", 1002 "-23h", 1003 "-23612ms", 1004 "-345ms", 1005 "-1ms", 1006 "-201us", 1007 "-1us", 1008 "-201ns", 1009 "-1ns", 1010 "0", 1011 } 1012 1013 // Append all the positive values in ascending order, excluding zero. 1014 for i := len(testCases) - 2; i >= 0; i-- { 1015 testCases = append(testCases, testCases[i][1:]) 1016 } 1017 1018 var last time.Time 1019 var lastEncoded []byte 1020 for _, dir := range []Direction{Ascending, Descending} { 1021 for i := range testCases { 1022 d, err := time.ParseDuration(testCases[i]) 1023 if err != nil { 1024 t.Fatal(err) 1025 } 1026 current := zeroTime.Add(d) 1027 var b []byte 1028 var decodedCurrent time.Time 1029 if !last.IsZero() { 1030 if dir == Ascending { 1031 b = EncodeTimeAscending(b, current) 1032 _, decodedCurrent, err = DecodeTimeAscending(b) 1033 } else { 1034 b = EncodeTimeDescending(b, current) 1035 _, decodedCurrent, err = DecodeTimeDescending(b) 1036 } 1037 if err != nil { 1038 t.Error(err) 1039 continue 1040 } 1041 if !decodedCurrent.Equal(current) { 1042 t.Fatalf("lossy transport: before (%v) vs after (%v)", current, decodedCurrent) 1043 } 1044 testPeekLength(t, b) 1045 if i > 0 { 1046 if (bytes.Compare(lastEncoded, b) >= 0 && dir == Ascending) || 1047 (bytes.Compare(lastEncoded, b) <= 0 && dir == Descending) { 1048 t.Fatalf("encodings %s, %s not increasing", testCases[i-1], testCases[i]) 1049 } 1050 } 1051 } 1052 last = current 1053 lastEncoded = b 1054 } 1055 1056 // Check that the encoding hasn't changed. 1057 if dir == Ascending { 1058 a, e := lastEncoded, []byte("\x14\xfa\x01 \xbc\x0e\xae\xf9\r\xf2\x8e\x80") 1059 if !bytes.Equal(a, e) { 1060 t.Errorf("encoding has changed:\nexpected [% x]\nactual [% x]", e, a) 1061 } 1062 } 1063 } 1064 } 1065 1066 func TestEncodeDecodeTimeTZ(t *testing.T) { 1067 // Test cases are in ascending order for TimeTZ, which means: 1068 // * UTC timestamp first preference 1069 // * Negative Zone Offset second preference 1070 // 1071 // Tests these UTC times: 1072 // 05:06:07 1073 // 10:11:12 1074 // 15:16:17 1075 // 20:21:22 1076 // Over time zones (if not overflowing): 1077 // -12 1078 // -08 1079 // -04 1080 // 0 1081 // +04 1082 // +08 1083 // +12 1084 testCases := []string{ 1085 "00:00:00+1559", // minimum 1086 1087 "17:06:07+12", 1088 "13:06:07+8", 1089 "09:06:07+4", 1090 "05:06:07+0", 1091 "01:06:07-4", 1092 1093 "22:11:12+12", 1094 "18:11:12+8", 1095 "14:11:12+4", 1096 "10:41:12+0030", // special check of .5 hour offsets 1097 "10:11:12+0", 1098 "06:11:12-4", 1099 "04:11:12-8", 1100 1101 "23:16:17+8", 1102 "19:16:17+4", 1103 "15:16:17+0", 1104 "11:16:17-4", 1105 "09:16:17-8", 1106 "05:16:17-12", 1107 1108 "20:21:22+0", 1109 "16:21:22-4", 1110 "12:21:22-8", 1111 "08:21:22-12", 1112 1113 "24:00:00-1559", // maximum 1114 } 1115 1116 var lastEncoded []byte 1117 for _, dir := range []Direction{Ascending, Descending} { 1118 t.Run(fmt.Sprintf("dir:%d", dir), func(t *testing.T) { 1119 for i := range testCases { 1120 t.Run(fmt.Sprintf("tc:%d", i), func(t *testing.T) { 1121 current, err := timetz.ParseTimeTZ(timeutil.Now(), testCases[i], time.Microsecond) 1122 assert.NoError(t, err) 1123 1124 var b []byte 1125 var decodedCurrent timetz.TimeTZ 1126 if dir == Ascending { 1127 b = EncodeTimeTZAscending(b, current) 1128 _, decodedCurrent, err = DecodeTimeTZAscending(b) 1129 } else { 1130 b = EncodeTimeTZDescending(b, current) 1131 _, decodedCurrent, err = DecodeTimeTZDescending(b) 1132 } 1133 assert.NoError(t, err) 1134 assert.Equal(t, current, decodedCurrent) 1135 testPeekLength(t, b) 1136 if i > 0 { 1137 if dir == Ascending { 1138 assert.True(t, bytes.Compare(lastEncoded, b) < 0, "encodings %s, %s not increasing", testCases[i-1], testCases[i]) 1139 } else { 1140 assert.True(t, bytes.Compare(lastEncoded, b) > 0, "encodings %s, %s not decreasing", testCases[i-1], testCases[i]) 1141 } 1142 } 1143 lastEncoded = b 1144 }) 1145 } 1146 }) 1147 } 1148 } 1149 1150 func TestEncodeDecodeGeo(t *testing.T) { 1151 testCases := []string{ 1152 "SRID=4326;POINT(1.0 1.0)", 1153 "POINT(2.0 2.0)", 1154 } 1155 for _, tc := range testCases { 1156 t.Run(tc, func(t *testing.T) { 1157 for _, dir := range []Direction{Ascending, Descending} { 1158 t.Run(fmt.Sprintf("dir:%d", dir), func(t *testing.T) { 1159 parsed, err := geo.ParseGeometry(tc) 1160 require.NoError(t, err) 1161 spatialObject := parsed.SpatialObject 1162 1163 var b []byte 1164 var decoded geopb.SpatialObject 1165 if dir == Ascending { 1166 b, err = EncodeGeoAscending(b, &spatialObject) 1167 require.NoError(t, err) 1168 _, decoded, err = DecodeGeoAscending(b) 1169 require.NoError(t, err) 1170 } else { 1171 b, err = EncodeGeoDescending(b, &spatialObject) 1172 require.NoError(t, err) 1173 _, decoded, err = DecodeGeoDescending(b) 1174 require.NoError(t, err) 1175 } 1176 require.Equal(t, spatialObject, decoded) 1177 testPeekLength(t, b) 1178 }) 1179 } 1180 }) 1181 } 1182 } 1183 1184 type testCaseDuration struct { 1185 value duration.Duration 1186 expEnc []byte 1187 } 1188 1189 func testBasicEncodeDuration( 1190 testCases []testCaseDuration, 1191 encFunc func([]byte, duration.Duration) ([]byte, error), 1192 t *testing.T, 1193 ) { 1194 var lastEnc []byte 1195 for i, test := range testCases { 1196 enc, err := encFunc(nil, test.value) 1197 if err != nil { 1198 t.Fatal(err) 1199 } 1200 if bytes.Compare(lastEnc, enc) != -1 { 1201 t.Errorf("%d ordered constraint violated for %s: [% x] vs. [% x]", i, test.value, enc, lastEnc) 1202 } 1203 testPeekLength(t, enc) 1204 lastEnc = enc 1205 } 1206 } 1207 1208 func testCustomEncodeDuration( 1209 testCases []testCaseDuration, 1210 encFunc func([]byte, duration.Duration) ([]byte, error), 1211 decFunc func([]byte) ([]byte, duration.Duration, error), 1212 t *testing.T, 1213 ) { 1214 for i, test := range testCases { 1215 enc, err := encFunc(nil, test.value) 1216 if err != nil { 1217 t.Fatal(err) 1218 } 1219 if !bytes.Equal(enc, test.expEnc) { 1220 t.Errorf("%d expected [% x]; got [% x] (value: %d)", i, test.expEnc, enc, test.value) 1221 } 1222 _, decoded, err := decFunc(enc) 1223 if err != nil { 1224 t.Fatal(err) 1225 } 1226 if test.value != decoded { 1227 t.Errorf("%d duration changed during roundtrip [%s] vs [%s]", i, test.value, decoded) 1228 } 1229 testPeekLength(t, enc) 1230 } 1231 } 1232 1233 func TestEncodeDecodeDuration(t *testing.T) { 1234 testCases := []testCaseDuration{ 1235 {duration.DecodeDuration(0, 0, 0), []byte{0x16, 0x88, 0x88, 0x88}}, 1236 {duration.DecodeDuration(0, 0, 1), []byte{0x16, 0x89, 0x88, 0x88}}, 1237 {duration.DecodeDuration(0, 1, 0), []byte{0x16, 0xfb, 0x4e, 0x94, 0x91, 0x4f, 0x00, 0x00, 0x88, 0x89}}, 1238 {duration.DecodeDuration(1, 0, 0), []byte{0x16, 0xfc, 0x09, 0x35, 0x69, 0x07, 0x42, 0x00, 0x00, 0x89, 0x88}}, 1239 {duration.DecodeDuration(0, 40, 0), []byte{0x16, 0xfc, 0x0c, 0x47, 0x36, 0xb4, 0x58, 0x00, 0x00, 0x88, 0xb0}}, 1240 } 1241 testBasicEncodeDuration(testCases, EncodeDurationAscending, t) 1242 testCustomEncodeDuration(testCases, EncodeDurationAscending, DecodeDurationAscending, t) 1243 } 1244 1245 func TestEncodeDecodeDescending(t *testing.T) { 1246 testCases := []testCaseDuration{ 1247 {duration.DecodeDuration(0, 40, 0), []byte{0x16, 0x81, 0xf3, 0xb8, 0xc9, 0x4b, 0xa7, 0xff, 0xff, 0x87, 0xff, 0x87, 0xd7}}, 1248 {duration.DecodeDuration(1, 0, 0), []byte{0x16, 0x81, 0xf6, 0xca, 0x96, 0xf8, 0xbd, 0xff, 0xff, 0x87, 0xfe, 0x87, 0xff}}, 1249 {duration.DecodeDuration(0, 1, 0), []byte{0x16, 0x82, 0xb1, 0x6b, 0x6e, 0xb0, 0xff, 0xff, 0x87, 0xff, 0x87, 0xfe}}, 1250 {duration.DecodeDuration(0, 0, 1), []byte{0x16, 0x87, 0xfe, 0x87, 0xff, 0x87, 0xff}}, 1251 {duration.DecodeDuration(0, 0, 0), []byte{0x16, 0x87, 0xff, 0x87, 0xff, 0x87, 0xff}}, 1252 } 1253 testBasicEncodeDuration(testCases, EncodeDurationDescending, t) 1254 testCustomEncodeDuration(testCases, EncodeDurationDescending, DecodeDurationDescending, t) 1255 } 1256 1257 func TestPeekType(t *testing.T) { 1258 encodedDurationAscending, err := EncodeDurationAscending(nil, duration.Duration{}) 1259 require.NoError(t, err) 1260 encodedDurationDescending, err := EncodeDurationDescending(nil, duration.Duration{}) 1261 require.NoError(t, err) 1262 encodedGeoAscending, err := EncodeGeoAscending(nil, &geopb.SpatialObject{}) 1263 require.NoError(t, err) 1264 encodedGeoDescending, err := EncodeGeoDescending(nil, &geopb.SpatialObject{}) 1265 require.NoError(t, err) 1266 testCases := []struct { 1267 enc []byte 1268 typ Type 1269 }{ 1270 {EncodeNullAscending(nil), Null}, 1271 {EncodeNotNullAscending(nil), NotNull}, 1272 {EncodeNullDescending(nil), Null}, 1273 {EncodeNotNullDescending(nil), NotNull}, 1274 {EncodeInterleavedSentinel(nil), NotNull}, 1275 {EncodeVarintAscending(nil, 0), Int}, 1276 {EncodeVarintDescending(nil, 0), Int}, 1277 {EncodeUvarintAscending(nil, 0), Int}, 1278 {EncodeUvarintDescending(nil, 0), Int}, 1279 {EncodeFloatAscending(nil, 0), Float}, 1280 {EncodeFloatDescending(nil, 0), Float}, 1281 {EncodeDecimalAscending(nil, apd.New(0, 0)), Decimal}, 1282 {EncodeDecimalDescending(nil, apd.New(0, 0)), Decimal}, 1283 {EncodeBytesAscending(nil, []byte("")), Bytes}, 1284 {EncodeBytesDescending(nil, []byte("")), BytesDesc}, 1285 {EncodeTimeAscending(nil, timeutil.Now()), Time}, 1286 {EncodeTimeDescending(nil, timeutil.Now()), Time}, 1287 {EncodeTimeTZAscending(nil, timetz.Now()), TimeTZ}, 1288 {EncodeTimeTZDescending(nil, timetz.Now()), TimeTZ}, 1289 {encodedGeoAscending, Geo}, 1290 {encodedGeoDescending, GeoDesc}, 1291 {encodedDurationAscending, Duration}, 1292 {encodedDurationDescending, Duration}, 1293 {EncodeBitArrayAscending(nil, bitarray.BitArray{}), BitArray}, 1294 {EncodeBitArrayDescending(nil, bitarray.BitArray{}), BitArrayDesc}, 1295 } 1296 for i, c := range testCases { 1297 typ := PeekType(c.enc) 1298 if c.typ != typ { 1299 t.Fatalf("%d: expected %d, but found %d", i, c.typ, typ) 1300 } 1301 } 1302 } 1303 1304 var sink string 1305 1306 func BenchmarkPeekType(b *testing.B) { 1307 buf := EncodeVarintAscending(nil, 0) 1308 var typ Type 1309 for i := 0; i < b.N; i++ { 1310 typ = PeekType(buf) 1311 } 1312 sink = string(typ) 1313 } 1314 1315 type randData struct { 1316 *rand.Rand 1317 } 1318 1319 func (rd randData) bool() bool { 1320 return rd.Intn(2) == 1 1321 } 1322 1323 func (rd randData) decimal() *apd.Decimal { 1324 return apd.New(rd.Int63(), int32(rd.Intn(40)-20)) 1325 } 1326 1327 func (rd randData) time() time.Time { 1328 return timeutil.Unix(rd.Int63n(1000000), rd.Int63n(1000000)) 1329 } 1330 1331 func (rd randData) timetz() timetz.TimeTZ { 1332 return timetz.MakeTimeTZ( 1333 timeofday.FromInt(rd.Int63n(int64(timeofday.Max))), 1334 rd.Int31n(timetz.MaxTimeTZOffsetSecs*2)-timetz.MaxTimeTZOffsetSecs, 1335 ) 1336 } 1337 1338 func (rd randData) bitArray() bitarray.BitArray { 1339 return bitarray.Rand(rd.Rand, uint(rd.Int31n(140))) 1340 } 1341 1342 func (rd randData) duration() duration.Duration { 1343 return duration.DecodeDuration( 1344 rd.Int63n(1000), 1345 rd.Int63n(1000), 1346 rd.Int63n(1000000), 1347 ) 1348 } 1349 1350 func (rd randData) ipAddr() ipaddr.IPAddr { 1351 return ipaddr.RandIPAddr(rd.Rand) 1352 } 1353 1354 func BenchmarkEncodeUint32(b *testing.B) { 1355 rng, _ := randutil.NewPseudoRand() 1356 1357 vals := make([]uint32, 10000) 1358 for i := range vals { 1359 vals[i] = uint32(rng.Int31()) 1360 } 1361 1362 buf := make([]byte, 0, 16) 1363 1364 b.ResetTimer() 1365 for i := 0; i < b.N; i++ { 1366 _ = EncodeUint32Ascending(buf, vals[i%len(vals)]) 1367 } 1368 } 1369 1370 func BenchmarkDecodeUint32(b *testing.B) { 1371 rng, _ := randutil.NewPseudoRand() 1372 1373 vals := make([][]byte, 10000) 1374 for i := range vals { 1375 vals[i] = EncodeUint32Ascending(nil, uint32(rng.Int31())) 1376 } 1377 1378 b.ResetTimer() 1379 for i := 0; i < b.N; i++ { 1380 _, _, _ = DecodeUint32Ascending(vals[i%len(vals)]) 1381 } 1382 } 1383 1384 func BenchmarkEncodeUint64(b *testing.B) { 1385 rng, _ := randutil.NewPseudoRand() 1386 1387 vals := make([]uint64, 10000) 1388 for i := range vals { 1389 vals[i] = uint64(rng.Int63()) 1390 } 1391 1392 buf := make([]byte, 0, 16) 1393 1394 b.ResetTimer() 1395 for i := 0; i < b.N; i++ { 1396 _ = EncodeUint64Ascending(buf, vals[i%len(vals)]) 1397 } 1398 } 1399 1400 func BenchmarkDecodeUint64(b *testing.B) { 1401 rng, _ := randutil.NewPseudoRand() 1402 1403 vals := make([][]byte, 10000) 1404 for i := range vals { 1405 vals[i] = EncodeUint64Ascending(nil, uint64(rng.Int63())) 1406 } 1407 1408 b.ResetTimer() 1409 for i := 0; i < b.N; i++ { 1410 _, _, _ = DecodeUint64Ascending(vals[i%len(vals)]) 1411 } 1412 } 1413 1414 func BenchmarkEncodeVarint(b *testing.B) { 1415 rng, _ := randutil.NewPseudoRand() 1416 1417 vals := make([]int64, 10000) 1418 for i := range vals { 1419 vals[i] = rng.Int63() 1420 } 1421 1422 buf := make([]byte, 0, 16) 1423 1424 b.ResetTimer() 1425 for i := 0; i < b.N; i++ { 1426 _ = EncodeVarintAscending(buf, vals[i%len(vals)]) 1427 } 1428 } 1429 1430 func BenchmarkDecodeVarint(b *testing.B) { 1431 rng, _ := randutil.NewPseudoRand() 1432 1433 vals := make([][]byte, 10000) 1434 for i := range vals { 1435 vals[i] = EncodeVarintAscending(nil, rng.Int63()) 1436 } 1437 1438 b.ResetTimer() 1439 for i := 0; i < b.N; i++ { 1440 _, _, _ = DecodeVarintAscending(vals[i%len(vals)]) 1441 } 1442 } 1443 1444 func BenchmarkPeekLengthVarint(b *testing.B) { 1445 rng, _ := randutil.NewPseudoRand() 1446 1447 vals := make([][]byte, 10000) 1448 for i := range vals { 1449 vals[i] = EncodeVarintAscending(nil, rng.Int63()) 1450 } 1451 1452 b.ResetTimer() 1453 for i := 0; i < b.N; i++ { 1454 _, _ = PeekLength(vals[i%len(vals)]) 1455 } 1456 } 1457 1458 func BenchmarkEncodeUvarint(b *testing.B) { 1459 rng, _ := randutil.NewPseudoRand() 1460 1461 vals := make([]uint64, 10000) 1462 for i := range vals { 1463 vals[i] = uint64(rng.Int63()) 1464 } 1465 1466 buf := make([]byte, 0, 16) 1467 1468 b.ResetTimer() 1469 for i := 0; i < b.N; i++ { 1470 _ = EncodeUvarintAscending(buf, vals[i%len(vals)]) 1471 } 1472 } 1473 1474 func BenchmarkDecodeUvarint(b *testing.B) { 1475 rng, _ := randutil.NewPseudoRand() 1476 1477 vals := make([][]byte, 10000) 1478 for i := range vals { 1479 vals[i] = EncodeUvarintAscending(nil, uint64(rng.Int63())) 1480 } 1481 1482 b.ResetTimer() 1483 for i := 0; i < b.N; i++ { 1484 _, _, _ = DecodeUvarintAscending(vals[i%len(vals)]) 1485 } 1486 } 1487 1488 func BenchmarkPeekLengthUvarint(b *testing.B) { 1489 rng, _ := randutil.NewPseudoRand() 1490 1491 vals := make([][]byte, 10000) 1492 for i := range vals { 1493 vals[i] = EncodeUvarintAscending(nil, uint64(rng.Int63())) 1494 } 1495 1496 b.ResetTimer() 1497 for i := 0; i < b.N; i++ { 1498 _, _ = PeekLength(vals[i%len(vals)]) 1499 } 1500 } 1501 1502 func BenchmarkEncodeBytes(b *testing.B) { 1503 rng, _ := randutil.NewPseudoRand() 1504 1505 vals := make([][]byte, 10000) 1506 for i := range vals { 1507 vals[i] = randutil.RandBytes(rng, 100) 1508 } 1509 1510 buf := make([]byte, 0, 1000) 1511 1512 b.ResetTimer() 1513 for i := 0; i < b.N; i++ { 1514 _ = EncodeBytesAscending(buf, vals[i%len(vals)]) 1515 } 1516 } 1517 1518 func BenchmarkEncodeBytesDescending(b *testing.B) { 1519 rng, _ := randutil.NewPseudoRand() 1520 1521 vals := make([][]byte, 10000) 1522 for i := range vals { 1523 vals[i] = randutil.RandBytes(rng, 100) 1524 } 1525 1526 buf := make([]byte, 0, 1000) 1527 1528 b.ResetTimer() 1529 for i := 0; i < b.N; i++ { 1530 _ = EncodeBytesDescending(buf, vals[i%len(vals)]) 1531 } 1532 } 1533 1534 func BenchmarkDecodeBytes(b *testing.B) { 1535 rng, _ := randutil.NewPseudoRand() 1536 1537 vals := make([][]byte, 10000) 1538 for i := range vals { 1539 vals[i] = EncodeBytesAscending(nil, randutil.RandBytes(rng, 100)) 1540 } 1541 1542 buf := make([]byte, 0, 1000) 1543 1544 b.ResetTimer() 1545 for i := 0; i < b.N; i++ { 1546 _, _, _ = DecodeBytesAscending(vals[i%len(vals)], buf) 1547 } 1548 } 1549 1550 func BenchmarkPeekLengthBytes(b *testing.B) { 1551 rng, _ := randutil.NewPseudoRand() 1552 1553 vals := make([][]byte, 10000) 1554 for i := range vals { 1555 vals[i] = EncodeBytesAscending(nil, randutil.RandBytes(rng, 100)) 1556 } 1557 1558 b.ResetTimer() 1559 for i := 0; i < b.N; i++ { 1560 _, _ = PeekLength(vals[i%len(vals)]) 1561 } 1562 } 1563 1564 func BenchmarkDecodeBytesDescending(b *testing.B) { 1565 rng, _ := randutil.NewPseudoRand() 1566 1567 vals := make([][]byte, 10000) 1568 for i := range vals { 1569 vals[i] = EncodeBytesDescending(nil, randutil.RandBytes(rng, 100)) 1570 } 1571 1572 buf := make([]byte, 0, 1000) 1573 1574 b.ResetTimer() 1575 for i := 0; i < b.N; i++ { 1576 _, _, _ = DecodeBytesDescending(vals[i%len(vals)], buf) 1577 } 1578 } 1579 1580 func BenchmarkPeekLengthBytesDescending(b *testing.B) { 1581 rng, _ := randutil.NewPseudoRand() 1582 1583 vals := make([][]byte, 10000) 1584 for i := range vals { 1585 vals[i] = EncodeBytesDescending(nil, randutil.RandBytes(rng, 100)) 1586 } 1587 1588 b.ResetTimer() 1589 for i := 0; i < b.N; i++ { 1590 _, _ = PeekLength(vals[i%len(vals)]) 1591 } 1592 } 1593 1594 func BenchmarkEncodeString(b *testing.B) { 1595 rng, _ := randutil.NewPseudoRand() 1596 1597 vals := make([]string, 10000) 1598 for i := range vals { 1599 vals[i] = string(randutil.RandBytes(rng, 100)) 1600 } 1601 1602 buf := make([]byte, 0, 1000) 1603 1604 b.ResetTimer() 1605 for i := 0; i < b.N; i++ { 1606 _ = EncodeStringAscending(buf, vals[i%len(vals)]) 1607 } 1608 } 1609 1610 func BenchmarkEncodeStringDescending(b *testing.B) { 1611 rng, _ := randutil.NewPseudoRand() 1612 1613 vals := make([]string, 10000) 1614 for i := range vals { 1615 vals[i] = string(randutil.RandBytes(rng, 100)) 1616 } 1617 1618 buf := make([]byte, 0, 1000) 1619 1620 b.ResetTimer() 1621 for i := 0; i < b.N; i++ { 1622 _ = EncodeStringDescending(buf, vals[i%len(vals)]) 1623 } 1624 } 1625 1626 func BenchmarkDecodeUnsafeString(b *testing.B) { 1627 rng, _ := randutil.NewPseudoRand() 1628 1629 vals := make([][]byte, 10000) 1630 for i := range vals { 1631 vals[i] = EncodeStringAscending(nil, string(randutil.RandBytes(rng, 100))) 1632 } 1633 1634 buf := make([]byte, 0, 1000) 1635 1636 b.ResetTimer() 1637 for i := 0; i < b.N; i++ { 1638 _, _, _ = DecodeUnsafeStringAscending(vals[i%len(vals)], buf) 1639 } 1640 } 1641 1642 func BenchmarkDecodeUnsafeStringDescending(b *testing.B) { 1643 rng, _ := randutil.NewPseudoRand() 1644 1645 vals := make([][]byte, 10000) 1646 for i := range vals { 1647 vals[i] = EncodeStringDescending(nil, string(randutil.RandBytes(rng, 100))) 1648 } 1649 1650 buf := make([]byte, 0, 1000) 1651 1652 b.ResetTimer() 1653 for i := 0; i < b.N; i++ { 1654 _, _, _ = DecodeUnsafeStringDescending(vals[i%len(vals)], buf) 1655 } 1656 } 1657 1658 func BenchmarkEncodeDuration(b *testing.B) { 1659 rng, _ := randutil.NewPseudoRand() 1660 rd := randData{rng} 1661 1662 vals := make([]duration.Duration, 10000) 1663 for i := range vals { 1664 vals[i] = rd.duration() 1665 } 1666 1667 buf := make([]byte, 0, 1000) 1668 1669 b.ResetTimer() 1670 for i := 0; i < b.N; i++ { 1671 if _, err := EncodeDurationAscending(buf, vals[i%len(vals)]); err != nil { 1672 b.Fatal(err) 1673 } 1674 } 1675 } 1676 1677 func BenchmarkDecodeDuration(b *testing.B) { 1678 rng, _ := randutil.NewPseudoRand() 1679 rd := randData{rng} 1680 1681 vals := make([][]byte, 10000) 1682 for i := range vals { 1683 var err error 1684 if vals[i], err = EncodeDurationAscending(nil, rd.duration()); err != nil { 1685 b.Fatal(err) 1686 } 1687 } 1688 1689 b.ResetTimer() 1690 for i := 0; i < b.N; i++ { 1691 if _, _, err := DecodeDurationAscending(vals[i%len(vals)]); err != nil { 1692 b.Fatal(err) 1693 } 1694 } 1695 } 1696 1697 func BenchmarkPeekLengthDuration(b *testing.B) { 1698 rng, _ := randutil.NewPseudoRand() 1699 rd := randData{rng} 1700 1701 vals := make([][]byte, 10000) 1702 for i := range vals { 1703 d := rd.duration() 1704 var err error 1705 vals[i], err = EncodeDurationAscending(nil, d) 1706 if err != nil { 1707 b.Fatal(err) 1708 } 1709 } 1710 1711 b.ResetTimer() 1712 for i := 0; i < b.N; i++ { 1713 _, _ = PeekLength(vals[i%len(vals)]) 1714 } 1715 } 1716 1717 func TestValueEncodeDecodeBool(t *testing.T) { 1718 tests := []bool{true, false} 1719 for _, test := range tests { 1720 buf := EncodeBoolValue(nil, NoColumnID, test) 1721 _, x, err := DecodeBoolValue(buf) 1722 if err != nil { 1723 t.Fatal(err) 1724 } 1725 if x != test { 1726 t.Errorf("expected %v got %v", test, x) 1727 } 1728 } 1729 } 1730 1731 func TestValueEncodeDecodeInt(t *testing.T) { 1732 rng, seed := randutil.NewPseudoRand() 1733 tests := append(int64TestCases[0:], randPowDistributedInt63s(rng, 1000)...) 1734 for _, test := range tests { 1735 buf := EncodeIntValue(nil, NoColumnID, test) 1736 _, x, err := DecodeIntValue(buf) 1737 if err != nil { 1738 t.Fatal(err) 1739 } 1740 if x != test { 1741 t.Errorf("seed %d: expected %v got %v", seed, test, x) 1742 } 1743 } 1744 } 1745 1746 func TestValueEncodeDecodeFloat(t *testing.T) { 1747 rng, seed := randutil.NewPseudoRand() 1748 tests := make([]float64, 1000) 1749 for i := range tests { 1750 tests[i] = rng.NormFloat64() 1751 } 1752 for _, test := range tests { 1753 buf := EncodeFloatValue(nil, NoColumnID, test) 1754 _, x, err := DecodeFloatValue(buf) 1755 if err != nil { 1756 t.Fatal(err) 1757 } 1758 if x != test { 1759 t.Errorf("seed %d: expected %v got %v", seed, test, x) 1760 } 1761 } 1762 } 1763 1764 func TestValueEncodeDecodeBytes(t *testing.T) { 1765 rng, seed := randutil.NewPseudoRand() 1766 tests := make([][]byte, 1000) 1767 for i := range tests { 1768 tests[i] = randutil.RandBytes(rng, 100) 1769 } 1770 for _, test := range tests { 1771 buf := EncodeBytesValue(nil, NoColumnID, test) 1772 _, x, err := DecodeBytesValue(buf) 1773 if err != nil { 1774 t.Fatal(err) 1775 } 1776 if !bytes.Equal(x, test) { 1777 t.Errorf("seed %d: expected %v got %v", seed, test, x) 1778 } 1779 } 1780 } 1781 1782 func TestValueEncodeDecodeDecimal(t *testing.T) { 1783 rng, seed := randutil.NewPseudoRand() 1784 rd := randData{rng} 1785 tests := make([]*apd.Decimal, 1000) 1786 for i := range tests { 1787 tests[i] = rd.decimal() 1788 } 1789 for _, test := range tests { 1790 buf := EncodeDecimalValue(nil, NoColumnID, test) 1791 _, x, err := DecodeDecimalValue(buf) 1792 if err != nil { 1793 t.Fatal(err) 1794 } 1795 if x.Cmp(test) != 0 { 1796 t.Errorf("seed %d: expected %v got %v", seed, test, x) 1797 } 1798 } 1799 } 1800 1801 func TestValueEncodeDecodeTime(t *testing.T) { 1802 rng, seed := randutil.NewPseudoRand() 1803 rd := randData{rng} 1804 tests := make([]time.Time, 1000) 1805 for i := range tests { 1806 tests[i] = rd.time() 1807 } 1808 for _, test := range tests { 1809 buf := EncodeTimeValue(nil, NoColumnID, test) 1810 _, x, err := DecodeTimeValue(buf) 1811 if err != nil { 1812 t.Fatal(err) 1813 } 1814 if x != test { 1815 t.Errorf("seed %d: expected %v got %v", seed, test, x) 1816 } 1817 } 1818 } 1819 1820 func TestValueEncodeDecodeTimeTZ(t *testing.T) { 1821 rng, seed := randutil.NewPseudoRand() 1822 rd := randData{rng} 1823 tests := make([]timetz.TimeTZ, 1000) 1824 for i := range tests { 1825 tests[i] = rd.timetz() 1826 } 1827 for _, test := range tests { 1828 buf := EncodeTimeTZValue(nil, NoColumnID, test) 1829 _, x, err := DecodeTimeTZValue(buf) 1830 if err != nil { 1831 t.Fatal(err) 1832 } 1833 if x != test { 1834 t.Errorf("seed %d: expected %v got %v", seed, test, x) 1835 } 1836 } 1837 } 1838 1839 func TestValueEncodeDecodeBitArray(t *testing.T) { 1840 rng, seed := randutil.NewPseudoRand() 1841 rd := randData{rng} 1842 tests := make([]bitarray.BitArray, 1000) 1843 for i := range tests { 1844 tests[i] = rd.bitArray() 1845 } 1846 for i, test := range tests { 1847 buf := EncodeBitArrayValue(nil, NoColumnID, test) 1848 remainder, x, err := DecodeBitArrayValue(buf) 1849 if err != nil { 1850 t.Fatal(err) 1851 } 1852 if bitarray.Compare(x, tests[i]) != 0 { 1853 t.Errorf("seed %d: expected %v got %v (buf: %+v)", seed, &tests[i], &x, buf) 1854 } 1855 if len(remainder) > 0 { 1856 t.Errorf("seed %d: decoding %v tailing bytes: %+v", seed, &tests[i], remainder) 1857 } 1858 } 1859 } 1860 1861 func TestValueEncodeDecodeDuration(t *testing.T) { 1862 rng, seed := randutil.NewPseudoRand() 1863 rd := randData{rng} 1864 tests := make([]duration.Duration, 1000) 1865 for i := range tests { 1866 tests[i] = rd.duration() 1867 } 1868 for _, test := range tests { 1869 buf := EncodeDurationValue(nil, NoColumnID, test) 1870 _, x, err := DecodeDurationValue(buf) 1871 if err != nil { 1872 t.Fatal(err) 1873 } 1874 if x != test { 1875 t.Errorf("seed %d: expected %v got %v", seed, test, x) 1876 } 1877 } 1878 } 1879 1880 func BenchmarkEncodeNonsortingVarint(b *testing.B) { 1881 bytes := make([]byte, 0, b.N*NonsortingVarintMaxLen) 1882 rng, _ := randutil.NewPseudoRand() 1883 b.ResetTimer() 1884 for i := 0; i < b.N; i++ { 1885 bytes = EncodeNonsortingStdlibVarint(bytes, rng.Int63()) 1886 } 1887 } 1888 1889 func BenchmarkDecodeNonsortingVarint(b *testing.B) { 1890 buf := make([]byte, 0, b.N*NonsortingVarintMaxLen) 1891 rng, _ := randutil.NewPseudoRand() 1892 for i := 0; i < b.N; i++ { 1893 buf = EncodeNonsortingStdlibVarint(buf, rng.Int63()) 1894 } 1895 var err error 1896 b.ResetTimer() 1897 for i := 0; i < b.N; i++ { 1898 buf, _, _, err = DecodeNonsortingStdlibVarint(buf) 1899 if err != nil { 1900 b.Fatal(err) 1901 } 1902 } 1903 } 1904 1905 // edgeCaseUint64s returns some uint64 edge cases for encodings. Currently: 1906 // - every power of two 1907 // - every power of two -1 and +1 1908 func edgeCaseUint64s() []uint64 { 1909 values := []uint64{0, 1, 2} 1910 for i := uint(2); i < 64; i++ { 1911 x := uint64(1) << i 1912 values = append(values, x-1, x, x+1) 1913 } 1914 values = append(values, math.MaxUint64) 1915 return values 1916 } 1917 1918 // randPowDistributedInt63s returns the requested number of int63s such that the 1919 // logarithm of the results is evenly distributed. 1920 func randPowDistributedInt63s(rng *rand.Rand, count int) []int64 { 1921 values := make([]int64, count) 1922 for i := range values { 1923 // 1 << 62 is the largest number that fits in an int63 and 0 digits is 1924 // not meaningful. 1925 digits := uint(rng.Intn(61)) + 1 1926 x := rng.Int63n(int64(1) << digits) 1927 for x>>(digits-1) == 0 { 1928 // If shifting off digits-1 digits is 0, then we didn't get a big enough 1929 // number. 1930 x = rng.Int63n(1 << digits) 1931 } 1932 values[i] = x 1933 } 1934 return values 1935 } 1936 1937 func testNonsortingUvarint(t *testing.T, i uint64) { 1938 buf := EncodeNonsortingUvarint(nil, i) 1939 rem, n, x, err := DecodeNonsortingUvarint(buf) 1940 if err != nil { 1941 t.Fatal(err) 1942 } 1943 if x != i { 1944 t.Fatalf("expected %d got %d", i, x) 1945 } 1946 if n != len(buf) { 1947 t.Fatalf("expected length %d got %d", len(buf), n) 1948 } 1949 if len(rem) != 0 { 1950 t.Fatalf("expected no remaining bytes got %d", len(rem)) 1951 } 1952 } 1953 1954 func TestNonsortingUVarint(t *testing.T) { 1955 rng, _ := randutil.NewPseudoRand() 1956 1957 for _, test := range edgeCaseUint64s() { 1958 testNonsortingUvarint(t, test) 1959 } 1960 for _, test := range randPowDistributedInt63s(rng, 1000) { 1961 testNonsortingUvarint(t, uint64(test)) 1962 } 1963 } 1964 1965 func TestPeekLengthNonsortingUVarint(t *testing.T) { 1966 rng, seed := randutil.NewPseudoRand() 1967 1968 var buf []byte 1969 var lengths []int 1970 for _, test := range edgeCaseUint64s() { 1971 length := len(buf) 1972 buf = EncodeNonsortingUvarint(buf, test) 1973 lengths = append(lengths, len(buf)-length) 1974 } 1975 for _, test := range randPowDistributedInt63s(rng, 1000) { 1976 length := len(buf) 1977 buf = EncodeNonsortingUvarint(buf, uint64(test)) 1978 lengths = append(lengths, len(buf)-length) 1979 } 1980 1981 for _, length := range lengths { 1982 l := PeekLengthNonsortingUvarint(buf) 1983 if l != length { 1984 t.Fatalf("seed %d: got %d expected %d: %x", seed, l, length, buf[:length]) 1985 } 1986 buf = buf[l:] 1987 } 1988 if l := PeekLengthNonsortingUvarint(buf); l != 0 { 1989 t.Fatalf("expected 0 for empty buffer got %d", l) 1990 } 1991 } 1992 1993 func BenchmarkEncodeNonsortingUvarint(b *testing.B) { 1994 buf := make([]byte, 0, b.N*NonsortingUvarintMaxLen) 1995 rng, _ := randutil.NewPseudoRand() 1996 b.ResetTimer() 1997 for i := 0; i < b.N; i++ { 1998 buf = EncodeNonsortingUvarint(buf, uint64(rng.Int63())) 1999 } 2000 } 2001 2002 func BenchmarkDecodeNonsortingUvarint(b *testing.B) { 2003 buf := make([]byte, 0, b.N*NonsortingUvarintMaxLen) 2004 rng, _ := randutil.NewPseudoRand() 2005 for i := 0; i < b.N; i++ { 2006 buf = EncodeNonsortingUvarint(buf, uint64(rng.Int63())) 2007 } 2008 var err error 2009 b.ResetTimer() 2010 for i := 0; i < b.N; i++ { 2011 buf, _, _, err = DecodeNonsortingUvarint(buf) 2012 if err != nil { 2013 b.Fatal(err) 2014 } 2015 } 2016 } 2017 2018 func BenchmarkDecodeOneByteNonsortingUvarint(b *testing.B) { 2019 buf := make([]byte, 0, b.N*NonsortingUvarintMaxLen) 2020 rng, _ := randutil.NewPseudoRand() 2021 for i := 0; i < b.N; i++ { 2022 buf = EncodeNonsortingUvarint(buf, uint64(rng.Int63()%(1<<7))) 2023 } 2024 var err error 2025 b.ResetTimer() 2026 for i := 0; i < b.N; i++ { 2027 buf, _, _, err = DecodeNonsortingUvarint(buf) 2028 if err != nil { 2029 b.Fatal(err) 2030 } 2031 } 2032 } 2033 2034 func BenchmarkPeekLengthNonsortingUvarint(b *testing.B) { 2035 buf := make([]byte, 0, b.N*NonsortingUvarintMaxLen) 2036 rng, _ := randutil.NewPseudoRand() 2037 for i := 0; i < b.N; i++ { 2038 buf = EncodeNonsortingUvarint(buf, uint64(rng.Int63())) 2039 } 2040 b.ResetTimer() 2041 for i := 0; i < b.N; i++ { 2042 l := PeekLengthNonsortingUvarint(buf) 2043 buf = buf[l:] 2044 } 2045 } 2046 2047 // randValueEncode "value" encodes a random value for the specified Type into 2048 // buf. It returns true if there was a matching encode method and false if there 2049 // wasn't, in which case buf is left unchanged. 2050 func randValueEncode(rd randData, buf []byte, colID uint32, typ Type) ([]byte, interface{}, bool) { 2051 switch typ { 2052 case Null: 2053 return EncodeNullValue(buf, colID), nil, true 2054 case True: 2055 return EncodeBoolValue(buf, colID, true), true, true 2056 case False: 2057 return EncodeBoolValue(buf, colID, false), false, true 2058 case Int: 2059 x := rd.Int63() 2060 return EncodeIntValue(buf, colID, x), x, true 2061 case Float: 2062 x := rd.NormFloat64() 2063 return EncodeFloatValue(buf, colID, x), x, true 2064 case Decimal: 2065 x := rd.decimal() 2066 return EncodeDecimalValue(buf, colID, x), *x, true 2067 case Bytes: 2068 x := randutil.RandBytes(rd.Rand, 100) 2069 return EncodeBytesValue(buf, colID, x), x, true 2070 case Time: 2071 x := rd.time() 2072 return EncodeTimeValue(buf, colID, x), x, true 2073 case TimeTZ: 2074 x := rd.timetz() 2075 return EncodeTimeTZValue(buf, colID, x), x, true 2076 case Duration: 2077 x := rd.duration() 2078 return EncodeDurationValue(buf, colID, x), x, true 2079 case BitArray: 2080 x := rd.bitArray() 2081 return EncodeBitArrayValue(buf, colID, x), x, true 2082 case IPAddr: 2083 x := rd.ipAddr() 2084 return EncodeIPAddrValue(buf, colID, x), x, true 2085 default: 2086 return buf, nil, false 2087 } 2088 } 2089 2090 func TestValueEncodingPeekLength(t *testing.T) { 2091 rng, seed := randutil.NewPseudoRand() 2092 rd := randData{rng} 2093 2094 var buf []byte 2095 var lengths []int 2096 for i := 0; i < 1000; { 2097 lastLen := len(buf) 2098 var ok bool 2099 buf, _, ok = randValueEncode(rd, buf, uint32(rng.Int63()), Type(rng.Intn(int(SentinelType)))) 2100 if ok { 2101 lengths = append(lengths, len(buf)-lastLen) 2102 i++ 2103 } 2104 } 2105 for _, length := range lengths { 2106 typeOffset, _, _, _, err := DecodeValueTag(buf) 2107 if err != nil { 2108 t.Fatal(err) 2109 } 2110 2111 _, l, err := PeekValueLength(buf) 2112 if err != nil { 2113 t.Fatal(err) 2114 } 2115 if l != length { 2116 t.Fatalf("seed %d: got %d expected %d: %x", seed, l, length, buf[:length]) 2117 } 2118 2119 // Check that typeOffset bytes can be dropped from the beginning and 2120 // PeekValueLength still works. 2121 _, l, err = PeekValueLength(buf[typeOffset:]) 2122 l += typeOffset 2123 if err != nil { 2124 t.Fatal(err) 2125 } 2126 if l != length { 2127 t.Fatalf("seed %d: got %d expected %d: %x", seed, l, length, buf[:length]) 2128 } 2129 2130 buf = buf[l:] 2131 } 2132 _, l, err := PeekValueLength(buf) 2133 if err != nil { 2134 t.Fatal(err) 2135 } 2136 if l != 0 { 2137 t.Fatalf("expected 0 for empty buffer got %d", l) 2138 } 2139 } 2140 2141 func TestValueEncodingTags(t *testing.T) { 2142 rng, seed := randutil.NewPseudoRand() 2143 2144 tests := make([]struct { 2145 colID uint32 2146 typ Type 2147 length int 2148 }, 10) 2149 2150 var buf []byte 2151 var lastLen int 2152 for i := 0; i < len(tests); i++ { 2153 tests[i].colID = uint32(rng.Int63()) 2154 tests[i].typ = Type(rng.Intn(1000)) 2155 buf = EncodeValueTag(buf, tests[i].colID, tests[i].typ) 2156 tests[i].length = len(buf) - lastLen 2157 lastLen = len(buf) 2158 } 2159 2160 for i, test := range tests { 2161 typeOffset, dataOffset, colID, typ, err := DecodeValueTag(buf) 2162 if err != nil { 2163 t.Fatal(err) 2164 } 2165 if colID != test.colID { 2166 t.Fatalf("%d seed %d: expected colID %d got %d", i, seed, test.colID, colID) 2167 } 2168 if typ != test.typ { 2169 t.Fatalf("%d seed %d: expected type %s got %s", i, seed, test.typ, typ) 2170 } 2171 if dataOffset != test.length { 2172 t.Fatalf("%d seed %d: expected length %d got %d", i, seed, test.length, dataOffset) 2173 } 2174 2175 // Check that typeOffset bytes can be dropped from the beginning and 2176 // everything but colID still works. 2177 _, dataOffset, _, typ, err = DecodeValueTag(buf[typeOffset:]) 2178 dataOffset += typeOffset 2179 if err != nil { 2180 t.Fatal(err) 2181 } 2182 if typ != test.typ { 2183 t.Fatalf("%d seed %d: expected type %s got %s", i, seed, test.typ, typ) 2184 } 2185 if dataOffset != test.length { 2186 t.Fatalf("%d seed %d: expected length %d got %d", i, seed, test.length, dataOffset) 2187 } 2188 2189 buf = buf[dataOffset:] 2190 } 2191 } 2192 2193 func TestValueEncodingRand(t *testing.T) { 2194 rng, seed := randutil.NewPseudoRand() 2195 rd := randData{rng} 2196 2197 var buf []byte 2198 var values []interface{} 2199 for i := 0; i < 1000; { 2200 var value interface{} 2201 var ok bool 2202 buf, value, ok = randValueEncode(rd, buf, uint32(rng.Int63()), Type(rng.Intn(int(SentinelType)))) 2203 if ok { 2204 values = append(values, value) 2205 i++ 2206 } 2207 } 2208 for _, value := range values { 2209 _, dataOffset, _, typ, err := DecodeValueTag(buf) 2210 if err != nil { 2211 t.Fatal(err) 2212 } 2213 2214 var decoded interface{} 2215 switch typ { 2216 case Null: 2217 buf = buf[dataOffset:] 2218 case True: 2219 buf, decoded, err = DecodeBoolValue(buf) 2220 case False: 2221 buf, decoded, err = DecodeBoolValue(buf) 2222 case Int: 2223 buf, decoded, err = DecodeIntValue(buf) 2224 case Float: 2225 buf, decoded, err = DecodeFloatValue(buf) 2226 case Decimal: 2227 buf, decoded, err = DecodeDecimalValue(buf) 2228 case Bytes: 2229 buf, decoded, err = DecodeBytesValue(buf) 2230 case Time: 2231 buf, decoded, err = DecodeTimeValue(buf) 2232 case TimeTZ: 2233 buf, decoded, err = DecodeTimeTZValue(buf) 2234 case Duration: 2235 buf, decoded, err = DecodeDurationValue(buf) 2236 case BitArray: 2237 buf, decoded, err = DecodeBitArrayValue(buf) 2238 case IPAddr: 2239 buf, decoded, err = DecodeIPAddrValue(buf) 2240 default: 2241 err = errors.Errorf("unknown type %s", typ) 2242 } 2243 if err != nil { 2244 t.Fatal(err) 2245 } 2246 2247 switch typ { 2248 case Bytes: 2249 if !bytes.Equal(decoded.([]byte), value.([]byte)) { 2250 t.Fatalf("seed %d: %s got %x expected %x", seed, typ, decoded.([]byte), value.([]byte)) 2251 } 2252 case Decimal: 2253 d := decoded.(apd.Decimal) 2254 val := value.(apd.Decimal) 2255 if d.Cmp(&val) != 0 { 2256 t.Fatalf("seed %d: %s got %v expected %v", seed, typ, decoded, value) 2257 } 2258 case IPAddr: 2259 d := decoded.(ipaddr.IPAddr) 2260 val := value.(ipaddr.IPAddr) 2261 if !d.Equal(&val) { 2262 t.Fatalf("seed %d: %s got %v expected %v", seed, typ, decoded, value) 2263 } 2264 case BitArray: 2265 d := decoded.(bitarray.BitArray) 2266 val := value.(bitarray.BitArray) 2267 if bitarray.Compare(d, val) != 0 { 2268 t.Fatalf("seed %d: %s got %v expected %v", seed, typ, decoded, value) 2269 } 2270 default: 2271 if decoded != value { 2272 t.Fatalf("seed %d: %s got %v expected %v", seed, typ, decoded, value) 2273 } 2274 } 2275 } 2276 } 2277 2278 func TestPrettyPrintValueEncoded(t *testing.T) { 2279 uuidStr := "63616665-6630-3064-6465-616462656562" 2280 u, err := uuid.FromString(uuidStr) 2281 if err != nil { 2282 t.Fatalf("Bad test case. Attempted uuid.FromString(%q) got err: %d", uuidStr, err) 2283 } 2284 ip := "192.168.0.1/10" 2285 var ipAddr ipaddr.IPAddr 2286 err = ipaddr.ParseINet(ip, &ipAddr) 2287 if err != nil { 2288 t.Fatalf("Bad test case. Attempted ipaddr.ParseINet(%q) got err: %d", ip, err) 2289 } 2290 ba := bitarray.MakeBitArrayFromInt64(6, 9, 5) 2291 tests := []struct { 2292 buf []byte 2293 expected string 2294 }{ 2295 {EncodeNullValue(nil, NoColumnID), "NULL"}, 2296 {EncodeBoolValue(nil, NoColumnID, true), "true"}, 2297 {EncodeBoolValue(nil, NoColumnID, false), "false"}, 2298 {EncodeIntValue(nil, NoColumnID, 7), "7"}, 2299 {EncodeFloatValue(nil, NoColumnID, 6.28), "6.28"}, 2300 {EncodeDecimalValue(nil, NoColumnID, apd.New(628, -2)), "6.28"}, 2301 {EncodeTimeValue(nil, NoColumnID, 2302 time.Date(2016, 6, 29, 16, 2, 50, 5, time.UTC)), "2016-06-29T16:02:50.000000005Z"}, 2303 {EncodeTimeTZValue(nil, NoColumnID, 2304 timetz.MakeTimeTZ(timeofday.New(10, 11, 12, 0), 5*60*60+24)), "10:11:12-05:00:24"}, 2305 {EncodeDurationValue(nil, NoColumnID, 2306 duration.DecodeDuration(1, 2, 3)), "1 mon 2 days 00:00:00+3ns"}, 2307 {EncodeBytesValue(nil, NoColumnID, []byte{0x1, 0x2, 0xF, 0xFF}), "0x01020fff"}, 2308 {EncodeBytesValue(nil, NoColumnID, []byte("foo")), "foo"}, // printable bytes 2309 {EncodeBytesValue(nil, NoColumnID, []byte{0x89}), "0x89"}, // non-printable bytes 2310 {EncodeIPAddrValue(nil, NoColumnID, ipAddr), ip}, 2311 {EncodeUUIDValue(nil, NoColumnID, u), uuidStr}, 2312 {EncodeBitArrayValue(nil, NoColumnID, ba), "B001001"}, 2313 } 2314 for i, test := range tests { 2315 remaining, str, err := PrettyPrintValueEncoded(test.buf) 2316 if err != nil { 2317 t.Fatal(err) 2318 } 2319 if len(remaining) != 0 { 2320 t.Errorf("%d: expected all bytes to be consumed but was left with %s", i, remaining) 2321 } 2322 if str != test.expected { 2323 t.Errorf("%d: got %q expected %q", i, str, test.expected) 2324 } 2325 } 2326 } 2327 2328 func BenchmarkEncodeBoolValue(b *testing.B) { 2329 rng, _ := randutil.NewPseudoRand() 2330 rd := randData{rng} 2331 2332 vals := make([]bool, 10000) 2333 for i := range vals { 2334 vals[i] = rd.bool() 2335 } 2336 2337 buf := make([]byte, 0, 1000) 2338 2339 b.ResetTimer() 2340 for i := 0; i < b.N; i++ { 2341 _ = EncodeBoolValue(buf, NoColumnID, vals[i%len(vals)]) 2342 } 2343 } 2344 2345 func BenchmarkDecodeBoolValue(b *testing.B) { 2346 rng, _ := randutil.NewPseudoRand() 2347 rd := randData{rng} 2348 2349 vals := make([][]byte, 10000) 2350 for i := range vals { 2351 vals[i] = EncodeBoolValue(nil, uint32(rng.Intn(100)), rd.bool()) 2352 } 2353 2354 b.ResetTimer() 2355 for i := 0; i < b.N; i++ { 2356 if _, _, err := DecodeBoolValue(vals[i%len(vals)]); err != nil { 2357 b.Fatal(err) 2358 } 2359 } 2360 } 2361 2362 func BenchmarkEncodeIntValue(b *testing.B) { 2363 rng, _ := randutil.NewPseudoRand() 2364 2365 vals := make([]int64, 10000) 2366 for i := range vals { 2367 vals[i] = rng.Int63() 2368 } 2369 2370 buf := make([]byte, 0, 1000) 2371 2372 b.ResetTimer() 2373 for i := 0; i < b.N; i++ { 2374 _ = EncodeIntValue(buf, NoColumnID, vals[i%len(vals)]) 2375 } 2376 } 2377 2378 func BenchmarkDecodeIntValue(b *testing.B) { 2379 rng, _ := randutil.NewPseudoRand() 2380 2381 vals := make([][]byte, 10000) 2382 for i := range vals { 2383 vals[i] = EncodeIntValue(nil, uint32(rng.Intn(100)), rng.Int63()) 2384 } 2385 2386 b.ResetTimer() 2387 for i := 0; i < b.N; i++ { 2388 if _, _, err := DecodeIntValue(vals[i%len(vals)]); err != nil { 2389 b.Fatal(err) 2390 } 2391 } 2392 } 2393 2394 func BenchmarkEncodeFloatValue(b *testing.B) { 2395 rng, _ := randutil.NewPseudoRand() 2396 2397 vals := make([]float64, 10000) 2398 for i := range vals { 2399 vals[i] = rng.NormFloat64() 2400 } 2401 2402 buf := make([]byte, 0, 1000) 2403 2404 b.ResetTimer() 2405 for i := 0; i < b.N; i++ { 2406 _ = EncodeFloatValue(buf, NoColumnID, vals[i%len(vals)]) 2407 } 2408 } 2409 2410 func BenchmarkDecodeFloatValue(b *testing.B) { 2411 rng, _ := randutil.NewPseudoRand() 2412 2413 vals := make([][]byte, 10000) 2414 for i := range vals { 2415 vals[i] = EncodeFloatValue(nil, uint32(rng.Intn(100)), rng.NormFloat64()) 2416 } 2417 2418 b.ResetTimer() 2419 for i := 0; i < b.N; i++ { 2420 if _, _, err := DecodeFloatValue(vals[i%len(vals)]); err != nil { 2421 b.Fatal(err) 2422 } 2423 } 2424 } 2425 2426 func BenchmarkEncodeBytesValue(b *testing.B) { 2427 rng, _ := randutil.NewPseudoRand() 2428 2429 vals := make([][]byte, 10000) 2430 for i := range vals { 2431 vals[i] = randutil.RandBytes(rng, 100) 2432 } 2433 2434 buf := make([]byte, 0, 1000) 2435 2436 b.ResetTimer() 2437 for i := 0; i < b.N; i++ { 2438 _ = EncodeBytesValue(buf, NoColumnID, vals[i%len(vals)]) 2439 } 2440 } 2441 2442 func BenchmarkDecodeBytesValue(b *testing.B) { 2443 rng, _ := randutil.NewPseudoRand() 2444 2445 vals := make([][]byte, 10000) 2446 for i := range vals { 2447 vals[i] = EncodeBytesValue(nil, uint32(rng.Intn(100)), randutil.RandBytes(rng, 100)) 2448 } 2449 2450 b.ResetTimer() 2451 for i := 0; i < b.N; i++ { 2452 if _, _, err := DecodeBytesValue(vals[i%len(vals)]); err != nil { 2453 b.Fatal(err) 2454 } 2455 } 2456 } 2457 2458 func BenchmarkEncodeTimeValue(b *testing.B) { 2459 rng, _ := randutil.NewPseudoRand() 2460 rd := randData{rng} 2461 2462 vals := make([]time.Time, 10000) 2463 for i := range vals { 2464 vals[i] = rd.time() 2465 } 2466 2467 buf := make([]byte, 0, 1000) 2468 2469 b.ResetTimer() 2470 for i := 0; i < b.N; i++ { 2471 _ = EncodeTimeValue(buf, NoColumnID, vals[i%len(vals)]) 2472 } 2473 } 2474 2475 func BenchmarkDecodeTimeValue(b *testing.B) { 2476 rng, _ := randutil.NewPseudoRand() 2477 rd := randData{rng} 2478 2479 vals := make([][]byte, 10000) 2480 for i := range vals { 2481 vals[i] = EncodeTimeValue(nil, uint32(rng.Intn(100)), rd.time()) 2482 } 2483 2484 b.ResetTimer() 2485 for i := 0; i < b.N; i++ { 2486 if _, _, err := DecodeTimeValue(vals[i%len(vals)]); err != nil { 2487 b.Fatal(err) 2488 } 2489 } 2490 } 2491 2492 func BenchmarkEncodeTimeTZValue(b *testing.B) { 2493 rng, _ := randutil.NewPseudoRand() 2494 rd := randData{rng} 2495 2496 vals := make([]timetz.TimeTZ, 10000) 2497 for i := range vals { 2498 vals[i] = rd.timetz() 2499 } 2500 2501 buf := make([]byte, 0, 1000) 2502 2503 b.ResetTimer() 2504 for i := 0; i < b.N; i++ { 2505 _ = EncodeTimeTZValue(buf, NoColumnID, vals[i%len(vals)]) 2506 } 2507 } 2508 2509 func BenchmarkDecodeTimeTZValue(b *testing.B) { 2510 rng, _ := randutil.NewPseudoRand() 2511 rd := randData{rng} 2512 2513 vals := make([][]byte, 10000) 2514 for i := range vals { 2515 vals[i] = EncodeTimeTZValue(nil, uint32(rng.Intn(100)), rd.timetz()) 2516 } 2517 2518 b.ResetTimer() 2519 for i := 0; i < b.N; i++ { 2520 if _, _, err := DecodeTimeTZValue(vals[i%len(vals)]); err != nil { 2521 b.Fatal(err) 2522 } 2523 } 2524 } 2525 2526 func BenchmarkEncodeIPAddrValue(b *testing.B) { 2527 rng, _ := randutil.NewPseudoRand() 2528 rd := randData{rng} 2529 2530 vals := make([]ipaddr.IPAddr, 10000) 2531 for i := range vals { 2532 vals[i] = rd.ipAddr() 2533 } 2534 2535 buf := make([]byte, 0, 1000) 2536 2537 b.ResetTimer() 2538 for i := 0; i < b.N; i++ { 2539 _ = EncodeIPAddrValue(buf, NoColumnID, vals[i%len(vals)]) 2540 } 2541 } 2542 2543 func BenchmarkDecodeIPAddrValue(b *testing.B) { 2544 rng, _ := randutil.NewPseudoRand() 2545 rd := randData{rng} 2546 2547 vals := make([][]byte, 10000) 2548 for i := range vals { 2549 vals[i] = EncodeIPAddrValue(nil, uint32(rng.Intn(100)), rd.ipAddr()) 2550 } 2551 2552 b.ResetTimer() 2553 for i := 0; i < b.N; i++ { 2554 if _, _, err := DecodeIPAddrValue(vals[i%len(vals)]); err != nil { 2555 b.Fatal(err) 2556 } 2557 } 2558 } 2559 2560 func BenchmarkEncodeDecimalValue(b *testing.B) { 2561 rng, _ := randutil.NewPseudoRand() 2562 rd := randData{rng} 2563 2564 vals := make([]*apd.Decimal, 10000) 2565 for i := range vals { 2566 vals[i] = rd.decimal() 2567 } 2568 2569 buf := make([]byte, 0, 1000) 2570 2571 b.ResetTimer() 2572 for i := 0; i < b.N; i++ { 2573 _ = EncodeDecimalValue(buf, NoColumnID, vals[i%len(vals)]) 2574 } 2575 } 2576 2577 func BenchmarkDecodeDecimalValue(b *testing.B) { 2578 rng, _ := randutil.NewPseudoRand() 2579 rd := randData{rng} 2580 2581 vals := make([][]byte, 10000) 2582 for i := range vals { 2583 vals[i] = EncodeDecimalValue(nil, uint32(rng.Intn(100)), rd.decimal()) 2584 } 2585 2586 b.ResetTimer() 2587 for i := 0; i < b.N; i++ { 2588 if _, _, err := DecodeDecimalValue(vals[i%len(vals)]); err != nil { 2589 b.Fatal(err) 2590 } 2591 } 2592 } 2593 2594 func BenchmarkEncodeDurationValue(b *testing.B) { 2595 rng, _ := randutil.NewPseudoRand() 2596 rd := randData{rng} 2597 2598 vals := make([]duration.Duration, 10000) 2599 for i := range vals { 2600 vals[i] = rd.duration() 2601 } 2602 2603 buf := make([]byte, 0, 1000) 2604 2605 b.ResetTimer() 2606 for i := 0; i < b.N; i++ { 2607 _ = EncodeDurationValue(buf, NoColumnID, vals[i%len(vals)]) 2608 } 2609 } 2610 2611 func BenchmarkDecodeDurationValue(b *testing.B) { 2612 rng, _ := randutil.NewPseudoRand() 2613 rd := randData{rng} 2614 2615 vals := make([][]byte, 10000) 2616 for i := range vals { 2617 vals[i] = EncodeDurationValue(nil, uint32(rng.Intn(100)), rd.duration()) 2618 } 2619 2620 b.ResetTimer() 2621 for i := 0; i < b.N; i++ { 2622 if _, _, err := DecodeDurationValue(vals[i%len(vals)]); err != nil { 2623 b.Fatal(err) 2624 } 2625 } 2626 }