Пример #1
0
func TestNonsortingEncodeDecimalRand(t *testing.T) {
	// Test with and without tmp buffer.
	for _, tmp := range [][]byte{nil, make([]byte, 0, 100)} {
		// Test with and without appending buffer.
		for _, append := range [][]byte{nil, []byte("hello")} {
			const randomTrials = 200000
			for i := 0; i < randomTrials; i++ {
				cur := decimal.NewDecFromFloat(rand.Float64())

				enc := EncodeNonsortingDecimal(append, cur)
				enc = enc[len(append):]
				res, err := DecodeNonsortingDecimal(enc, tmp)
				if err != nil {
					t.Fatal(err)
				}

				// Make sure we decode the same value we encoded.
				if cur.Cmp(res) != 0 {
					t.Fatalf("unexpected mismatch for %v, got %v", cur, res)
				}

				// Make sure we would have overestimated the value.
				if est := UpperBoundNonsortingDecimalSize(cur); est < len(enc) {
					t.Fatalf("expected estimate of %d for %v to be greater than or equal to the encoded length, found [% x]", est, cur, enc)
				}
			}
		}
	}
}
Пример #2
0
func TestEncodeDecimalRand(t *testing.T) {
	// Test both directions.
	for _, dir := range []Direction{Ascending, Descending} {
		var prev *inf.Dec
		var prevEnc []byte
		// Test with and without tmp buffer.
		for _, tmp := range [][]byte{nil, make([]byte, 0, 100)} {
			// Test with and without appending buffer.
			for _, append := range [][]byte{nil, []byte("hello")} {
				const randomTrials = 50000
				for i := 0; i < randomTrials; i++ {
					cur := decimal.NewDecFromFloat(rand.Float64())

					var enc []byte
					var res *inf.Dec
					var err error
					if dir == Ascending {
						enc = EncodeDecimalAscending(append, cur)
						enc = enc[len(append):]
						_, res, err = DecodeDecimalAscending(enc, tmp)
					} else {
						enc = EncodeDecimalDescending(append, cur)
						enc = enc[len(append):]
						_, res, err = DecodeDecimalDescending(enc, tmp)
					}
					if err != nil {
						t.Fatal(err)
					}

					// Make sure we decode the same value we encoded.
					if cur.Cmp(res) != 0 {
						t.Fatalf("unexpected mismatch for %v, got %v", cur, res)
					}

					// Make sure lexicographical sorting is consistent.
					if prev != nil {
						bytesCmp := bytes.Compare(prevEnc, enc)
						cmpType := "same"
						if dir == Descending {
							bytesCmp *= -1
							cmpType = "inverse"
						}
						if decCmp := prev.Cmp(cur); decCmp != bytesCmp {
							t.Fatalf("expected [% x] to compare to [% x] the %s way that %v compares to %v",
								prevEnc, enc, cmpType, prev, cur)
						}
					}
					prev = cur
					prevEnc = enc
				}
			}
		}
	}
}
Пример #3
0
func BenchmarkEncodeDecimal(b *testing.B) {
	rng, _ := randutil.NewPseudoRand()

	vals := make([]*inf.Dec, 10000)
	for i := range vals {
		vals[i] = decimal.NewDecFromFloat(rng.Float64())
	}

	buf := make([]byte, 0, 100)

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		_ = EncodeDecimalAscending(buf, vals[i%len(vals)])
	}
}
Пример #4
0
func BenchmarkDecodeDecimal(b *testing.B) {
	rng, _ := randutil.NewPseudoRand()

	vals := make([][]byte, 10000)
	for i := range vals {
		d := decimal.NewDecFromFloat(rng.Float64())
		vals[i] = EncodeDecimalAscending(nil, d)
	}

	buf := make([]byte, 0, 100)

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		_, _, _ = DecodeDecimalAscending(vals[i%len(vals)], buf)
	}
}
Пример #5
0
			l := left.(*DDecimal).Dec
			r := inf.NewDec(int64(right.(DInt)), 0)
			return DBool(l.Cmp(r) == 0), nil
		},
	},
	cmpArgs{EQ, intType, decimalType}: {
		fn: func(_ EvalContext, left Datum, right Datum) (DBool, error) {
			l := inf.NewDec(int64(left.(DInt)), 0)
			r := right.(*DDecimal).Dec
			return DBool(l.Cmp(&r) == 0), nil
		},
	},
	cmpArgs{EQ, decimalType, floatType}: {
		fn: func(_ EvalContext, left Datum, right Datum) (DBool, error) {
			l := left.(*DDecimal).Dec
			r := decimal.NewDecFromFloat(float64(right.(DFloat)))
			return DBool(l.Cmp(r) == 0), nil
		},
	},
	cmpArgs{EQ, floatType, decimalType}: {
		fn: func(_ EvalContext, left Datum, right Datum) (DBool, error) {
			l := decimal.NewDecFromFloat(float64(left.(DFloat)))
			r := right.(*DDecimal).Dec
			return DBool(l.Cmp(&r) == 0), nil
		},
	},
	cmpArgs{EQ, dateType, dateType}: {
		fn: func(_ EvalContext, left Datum, right Datum) (DBool, error) {
			return DBool(left.(DDate) == right.(DDate)), nil
		},
	},
Пример #6
0
func TestEncodeDecimal(t *testing.T) {
	testCases := []struct {
		Value    *inf.Dec
		Encoding []byte
	}{
		{decimal.NewDecFromFloat(-math.MaxFloat64), []byte{0x04, 0x64, 0xfc, 0x60, 0x66, 0x44, 0xe4, 0x9e, 0x82, 0xc0, 0x8d, 0x0}},
		{inf.NewDec(-1, -308), []byte{0x04, 0x64, 0xfd, 0x0}},
		// Four duplicates to make sure -1*10^4 <= -10*10^3 <= -100*10^2 <= -1*10^4
		{inf.NewDec(-1, -4), []byte{0x0c, 0xfd, 0x0}},
		{inf.NewDec(-10, -3), []byte{0x0c, 0xfd, 0x0}},
		{inf.NewDec(-100, -2), []byte{0x0c, 0xfd, 0x0}},
		{inf.NewDec(-1, -4), []byte{0x0c, 0xfd, 0x0}},
		{inf.NewDec(-9999, 0), []byte{0x0d, 0x38, 0x39, 0x00}},
		{inf.NewDec(-10, -1), []byte{0x0d, 0xfd, 0x00}},
		{inf.NewDec(-99, 0), []byte{0x0e, 0x39, 0x00}},
		{inf.NewDec(-1, 0), []byte{0x0e, 0xfd, 0x0}},
		{inf.NewDec(-123, 5), []byte{0x10, 0x1, 0xe6, 0xc3, 0x0}},
		{inf.NewDec(-1, 307), []byte{0x10, 0x99, 0xeb, 0x0}},
		{decimal.NewDecFromFloat(-math.SmallestNonzeroFloat64), []byte{0x10, 0xa1, 0xf5, 0x0}},
		{inf.NewDec(0, 0), []byte{0x11}},
		{decimal.NewDecFromFloat(math.SmallestNonzeroFloat64), []byte{0x12, 0x5e, 0xa, 0x0}},
		{inf.NewDec(1, 307), []byte{0x12, 0x66, 0x14, 0x0}},
		{inf.NewDec(123, 5), []byte{0x12, 0xfe, 0x19, 0x3c, 0x0}},
		{inf.NewDec(123, 4), []byte{0x13, 0x03, 0x2e, 0x0}},
		{inf.NewDec(123, 3), []byte{0x13, 0x19, 0x3c, 0x0}},
		{inf.NewDec(1, 0), []byte{0x14, 0x02, 0x0}},
		{inf.NewDec(1, -1), []byte{0x14, 0x14, 0x0}},
		{inf.NewDec(12345, 3), []byte{0x14, 0x19, 0x45, 0x64, 0x0}},
		{inf.NewDec(990, 1), []byte{0x14, 0xc6, 0x0}},
		{inf.NewDec(990001, 4), []byte{0x14, 0xc7, 0x01, 0x02, 0x0}},
		{inf.NewDec(9901, 2), []byte{0x14, 0xc7, 0x02, 0x0}},
		{inf.NewDec(10, -1), []byte{0x15, 0x02, 0x0}},
		{inf.NewDec(10001, 2), []byte{0x15, 0x03, 0x01, 0x02, 0x0}},
		{inf.NewDec(1001, 1), []byte{0x15, 0x03, 0x01, 0x14, 0x0}},
		{inf.NewDec(1234, 0), []byte{0x15, 0x19, 0x44, 0x0}},
		{inf.NewDec(12345, 1), []byte{0x15, 0x19, 0x45, 0x64, 0x0}},
		{inf.NewDec(9999, 0), []byte{0x15, 0xc7, 0xc6, 0x0}},
		{inf.NewDec(9999000001, 6), []byte{0x15, 0xc7, 0xc7, 0x01, 0x01, 0x02, 0x0}},
		{inf.NewDec(9999000009, 6), []byte{0x15, 0xc7, 0xc7, 0x01, 0x01, 0x12, 0x0}},
		{inf.NewDec(9999000010, 6), []byte{0x15, 0xc7, 0xc7, 0x01, 0x01, 0x14, 0x0}},
		{inf.NewDec(9999000090, 6), []byte{0x15, 0xc7, 0xc7, 0x01, 0x01, 0xb4, 0x0}},
		{inf.NewDec(9999000099, 6), []byte{0x15, 0xc7, 0xc7, 0x01, 0x01, 0xc6, 0x0}},
		{inf.NewDec(99990001, 4), []byte{0x15, 0xc7, 0xc7, 0x01, 0x02, 0x0}},
		{inf.NewDec(9999001, 3), []byte{0x15, 0xc7, 0xc7, 0x01, 0x14, 0x0}},
		{inf.NewDec(999901, 2), []byte{0x15, 0xc7, 0xc7, 0x02, 0x0}},
		{inf.NewDec(99991, 1), []byte{0x15, 0xc7, 0xc7, 0x14, 0x0}},
		{inf.NewDec(10000, 0), []byte{0x16, 0x02, 0x0}},
		{inf.NewDec(10001, 0), []byte{0x16, 0x03, 0x01, 0x02, 0x0}},
		{inf.NewDec(12345, 0), []byte{0x16, 0x03, 0x2f, 0x5a, 0x0}},
		{inf.NewDec(123450, 0), []byte{0x16, 0x19, 0x45, 0x64, 0x0}},
		{inf.NewDec(1, -308), []byte{0x1e, 0x9b, 0x2, 0x0}},
		{decimal.NewDecFromFloat(math.MaxFloat64), []byte{0x1e, 0x9b, 0x3, 0x9f, 0x99, 0xbb, 0x1b, 0x61, 0x7d, 0x3f, 0x72, 0x0}},
	}

	var lastEncoded []byte
	for _, tmp := range [][]byte{nil, make([]byte, 0, 100)} {
		tmp = tmp[:0]
		for _, dir := range []Direction{Ascending, Descending} {
			for i, c := range testCases {
				var enc []byte
				var err error
				var dec *inf.Dec
				if dir == Ascending {
					enc = EncodeDecimalAscending(nil, c.Value)
					_, dec, err = DecodeDecimalAscending(enc, tmp)
				} else {
					enc = EncodeDecimalDescending(nil, c.Value)
					_, dec, err = DecodeDecimalDescending(enc, tmp)
				}
				if dir == Ascending && !bytes.Equal(enc, c.Encoding) {
					t.Errorf("unexpected mismatch for %s. expected [% x], got [% x]",
						c.Value, c.Encoding, enc)
				}
				if i > 0 {
					if (bytes.Compare(lastEncoded, enc) > 0 && dir == Ascending) ||
						(bytes.Compare(lastEncoded, enc) < 0 && dir == Descending) {
						t.Errorf("%v: expected [% x] to be less than or equal to [% x]",
							c.Value, testCases[i-1].Encoding, enc)
					}
				}
				if err != nil {
					t.Error(err)
					continue
				}
				if dec.Cmp(c.Value) != 0 {
					t.Errorf("%d unexpected mismatch for %v. got %v", i, c.Value, dec)
				}
				lastEncoded = enc
			}

			// Test that appending the decimal to an existing buffer works.
			var enc []byte
			var dec *inf.Dec
			other := inf.NewDec(123, 2)
			if dir == Ascending {
				enc = EncodeDecimalAscending([]byte("hello"), other)
				_, dec, _ = DecodeDecimalAscending(enc[5:], tmp)
			} else {
				enc = EncodeDecimalDescending([]byte("hello"), other)
				_, dec, _ = DecodeDecimalDescending(enc[5:], tmp)
			}
			if dec.Cmp(other) != 0 {
				t.Errorf("unexpected mismatch for %v. got %v", 1.23, other)
			}
		}
	}
}
Пример #7
0
func TestNonsortingEncodeDecimal(t *testing.T) {
	testCases := []struct {
		Value    *inf.Dec
		Encoding []byte
	}{
		{inf.NewDec(-99122, -99999), []byte{0x1a, 0xf8, 0x01, 0x86, 0xa4, 0x01, 0x83, 0x32}},
		// Three duplicates to make sure -13*10^1000 <= -130*10^999 <= -13*10^1000
		{inf.NewDec(-13, -1000), []byte{0x1a, 0xf7, 0x03, 0xea, 0x0d}},
		{inf.NewDec(-130, -999), []byte{0x1a, 0xf7, 0x03, 0xea, 0x0d}},
		{inf.NewDec(-13, -1000), []byte{0x1a, 0xf7, 0x03, 0xea, 0x0d}},
		{decimal.NewDecFromFloat(-math.MaxFloat64), []byte{0x1a, 0xf7, 0x01, 0x35, 0x3f, 0xdd, 0xec, 0x7f, 0x2f, 0xaf, 0x35}},
		{inf.NewDec(-130, -100), []byte{0x1a, 0xef, 0x0d}},
		{inf.NewDec(-13, 0), []byte{0x1a, 0x8a, 0x0d}},
		{inf.NewDec(-11, 0), []byte{0x1a, 0x8a, 0x0b}},
		{inf.NewDec(-1, 0), []byte{0x1a, 0x89, 0x01}},
		{inf.NewDec(-8, 1), []byte{0x25, 0x08}},
		{inf.NewDec(-1, 1), []byte{0x25, 0x01}},
		{inf.NewDec(-11, 4), []byte{0x26, 0x8a, 0x0b}},
		{inf.NewDec(-11, 6), []byte{0x26, 0x8c, 0x0b}},
		{decimal.NewDecFromFloat(-math.SmallestNonzeroFloat64), []byte{0x26, 0xf7, 0x01, 0x43, 0x05}},
		{inf.NewDec(-11, 66666), []byte{0x26, 0xf8, 0x01, 0x04, 0x68, 0x0b}},
		{inf.NewDec(0, 0), []byte{0x27}},
		{decimal.NewDecFromFloat(math.SmallestNonzeroFloat64), []byte{0x28, 0xf7, 0x01, 0x43, 0x05}},
		{inf.NewDec(11, 6), []byte{0x28, 0x8c, 0x0b}},
		{inf.NewDec(11, 4), []byte{0x28, 0x8a, 0x0b}},
		{inf.NewDec(1, 1), []byte{0x29, 0x01}},
		{inf.NewDec(12345, 5), []byte{0x29, 0x30, 0x39}},
		{inf.NewDec(8, 1), []byte{0x29, 0x08}},
		{inf.NewDec(1, 0), []byte{0x34, 0x89, 0x01}},
		{inf.NewDec(11, 0), []byte{0x34, 0x8a, 0x0b}},
		{inf.NewDec(13, 0), []byte{0x34, 0x8a, 0x0d}},
		// Note that this does not sort correctly!
		{inf.NewDec(255, 0), []byte{0x34, 0x8b, 0xff}},
		{inf.NewDec(256, 0), []byte{0x34, 0x8b, 0x01, 0x00}},
		{decimal.NewDecFromFloat(math.MaxFloat64), []byte{0x34, 0xf7, 0x01, 0x35, 0x3f, 0xdd, 0xec, 0x7f, 0x2f, 0xaf, 0x35}},
		// Four duplicates to make sure 13*10^1000 <= 130*10^999 <= 1300*10^998 <= 13*10^1000
		{inf.NewDec(13, -1000), []byte{0x34, 0xf7, 0x03, 0xea, 0x0d}},
		{inf.NewDec(130, -999), []byte{0x34, 0xf7, 0x03, 0xea, 0x0d}},
		{inf.NewDec(1300, -998), []byte{0x34, 0xf7, 0x03, 0xea, 0x0d}},
		{inf.NewDec(13, -1000), []byte{0x34, 0xf7, 0x03, 0xea, 0x0d}},
		{inf.NewDec(99122, -99999), []byte{0x34, 0xf8, 0x01, 0x86, 0xa4, 0x01, 0x83, 0x32}},
		{inf.NewDec(99122839898321208, -99999), []byte{0x34, 0xf8, 0x01, 0x86, 0xb0, 0x01, 0x60, 0x27, 0xb2, 0x9d, 0x44, 0x71, 0x38}},
	}

	for _, tmp := range [][]byte{nil, make([]byte, 0, 100)} {
		for i, c := range testCases {
			enc := EncodeNonsortingDecimal(nil, c.Value)
			dec, err := DecodeNonsortingDecimal(enc, tmp)
			if err != nil {
				t.Error(err)
				continue
			}
			if !bytes.Equal(enc, c.Encoding) {
				t.Errorf("unexpected mismatch for %s. expected [% x], got [% x]",
					c.Value, c.Encoding, enc)
			}
			if dec.Cmp(c.Value) != 0 {
				t.Errorf("%d unexpected mismatch for %v. got %v", i, c.Value, dec)
			}
		}

		// Test that appending the decimal to an existing buffer works.
		other := inf.NewDec(123, 2)
		enc := EncodeNonsortingDecimal([]byte("hello"), other)
		dec, err := DecodeNonsortingDecimal(enc[5:], tmp)
		if err != nil {
			t.Error(err)
			continue
		}
		if dec.Cmp(other) != 0 {
			t.Errorf("unexpected mismatch for %v. got %v", 1.23, other)
		}
	}
}
Пример #8
0
func TestEncodeDecimal(t *testing.T) {
	testCases := []struct {
		Value    *inf.Dec
		Encoding []byte
	}{
		{inf.NewDec(-99122, -99999), []byte{0x1a, 0x86, 0x3c, 0xad, 0x38, 0xe6, 0xd7, 0x00}},
		// Three duplicates to make sure -13*10^1000 <= -130*10^999 <= -13*10^1000
		{inf.NewDec(-13, -1000), []byte{0x1a, 0x86, 0xfe, 0x0a, 0xe5, 0x00}},
		{inf.NewDec(-130, -999), []byte{0x1a, 0x86, 0xfe, 0x0a, 0xe5, 0x00}},
		{inf.NewDec(-13, -1000), []byte{0x1a, 0x86, 0xfe, 0x0a, 0xe5, 0x00}},
		{decimal.NewDecFromFloat(-math.MaxFloat64), []byte{0x1a, 0x87, 0x64, 0xfc, 0x60, 0x66, 0x44, 0xe4, 0x9e, 0x82, 0xc0, 0x8d, 0x00}},
		{inf.NewDec(-130, -100), []byte{0x1a, 0x87, 0xcb, 0xfc, 0xc3, 0x00}},
		{inf.NewDec(-13, 0), []byte{0x24, 0xe5, 0x00}},
		{inf.NewDec(-11, 0), []byte{0x24, 0xe9, 0x00}},
		{mustDecimal("-10.123456789"), []byte{0x24, 0xea, 0xe6, 0xba, 0x8e, 0x62, 0x4b, 0x00}},
		{mustDecimal("-10"), []byte{0x24, 0xeb, 0x00}},
		{mustDecimal("-9.123456789"), []byte{0x24, 0xec, 0xe6, 0xba, 0x8e, 0x62, 0x4b, 0x00}},
		{mustDecimal("-9"), []byte{0x24, 0xed, 0x00}},
		{mustDecimal("-1.1"), []byte{0x24, 0xfc, 0xeb, 0x00}},
		{inf.NewDec(-1, 0), []byte{0x24, 0xfd, 0x00}},
		{inf.NewDec(-8, 1), []byte{0x25, 0x5f, 0x00}},
		{inf.NewDec(-1, 1), []byte{0x25, 0xeb, 0x00}},
		{mustDecimal("-.09"), []byte{0x25, 0xed, 0x00}},
		{mustDecimal("-.054321"), []byte{0x25, 0xf4, 0xa8, 0xd5, 0x00}},
		{mustDecimal("-.012"), []byte{0x25, 0xfc, 0xd7, 0x00}},
		{inf.NewDec(-11, 4), []byte{0x26, 0x89, 0xe9, 0x00}},
		{inf.NewDec(-11, 6), []byte{0x26, 0x8a, 0xe9, 0x00}},
		{decimal.NewDecFromFloat(-math.SmallestNonzeroFloat64), []byte{0x26, 0xf6, 0xa1, 0xf5, 0x00}},
		{inf.NewDec(-11, 66666), []byte{0x26, 0xf7, 0x82, 0x34, 0xe9, 0x00}},
		{inf.NewDec(0, 0), []byte{0x27}},
		{decimal.NewDecFromFloat(math.SmallestNonzeroFloat64), []byte{0x28, 0x87, 0x5e, 0x0a, 0x00}},
		{inf.NewDec(11, 6), []byte{0x28, 0x87, 0xfd, 0x16, 0x00}},
		{inf.NewDec(11, 4), []byte{0x28, 0x87, 0xfe, 0x16, 0x00}},
		{inf.NewDec(1, 1), []byte{0x29, 0x14, 0x00}},
		{inf.NewDec(8, 1), []byte{0x29, 0xa0, 0x00}},
		{inf.NewDec(1, 0), []byte{0x2a, 0x02, 0x00}},
		{mustDecimal("1.1"), []byte{0x2a, 0x03, 0x14, 0x00}},
		{inf.NewDec(11, 0), []byte{0x2a, 0x16, 0x00}},
		{inf.NewDec(13, 0), []byte{0x2a, 0x1a, 0x00}},
		{decimal.NewDecFromFloat(math.MaxFloat64), []byte{0x34, 0xf6, 0x9b, 0x03, 0x9f, 0x99, 0xbb, 0x1b, 0x61, 0x7d, 0x3f, 0x72, 0x00}},
		// Four duplicates to make sure 13*10^1000 <= 130*10^999 <= 1300*10^998 <= 13*10^1000
		{inf.NewDec(13, -1000), []byte{0x34, 0xf7, 0x01, 0xf5, 0x1a, 0x00}},
		{inf.NewDec(130, -999), []byte{0x34, 0xf7, 0x01, 0xf5, 0x1a, 0x00}},
		{inf.NewDec(1300, -998), []byte{0x34, 0xf7, 0x01, 0xf5, 0x1a, 0x00}},
		{inf.NewDec(13, -1000), []byte{0x34, 0xf7, 0x01, 0xf5, 0x1a, 0x00}},
		{inf.NewDec(99122, -99999), []byte{0x34, 0xf7, 0xc3, 0x52, 0xc7, 0x19, 0x28, 0x00}},
		{inf.NewDec(99122839898321208, -99999), []byte{0x34, 0xf7, 0xc3, 0x58, 0xc7, 0x19, 0x39, 0x4f, 0xb3, 0xa7, 0x2b, 0x29, 0xa0, 0x00}},
	}

	var lastEncoded []byte
	for _, dir := range []Direction{Ascending, Descending} {
		for _, tmp := range [][]byte{nil, make([]byte, 0, 100)} {
			for i, c := range testCases {
				var enc []byte
				var err error
				var dec *inf.Dec
				if dir == Ascending {
					enc = EncodeDecimalAscending(nil, c.Value)
					_, dec, err = DecodeDecimalAscending(enc, tmp)
				} else {
					enc = EncodeDecimalDescending(nil, c.Value)
					_, dec, err = DecodeDecimalDescending(enc, tmp)
				}
				if dir == Ascending && !bytes.Equal(enc, c.Encoding) {
					t.Errorf("unexpected mismatch for %s. expected [% x], got [% x]",
						c.Value, c.Encoding, enc)
				}
				if i > 0 {
					if (bytes.Compare(lastEncoded, enc) > 0 && dir == Ascending) ||
						(bytes.Compare(lastEncoded, enc) < 0 && dir == Descending) {
						t.Errorf("%v: expected [% x] to be less than or equal to [% x]",
							c.Value, testCases[i-1].Encoding, enc)
					}
				}
				if err != nil {
					t.Error(err)
					continue
				}
				if dec.Cmp(c.Value) != 0 {
					t.Errorf("%d unexpected mismatch for %v. got %v", i, c.Value, dec)
				}
				lastEncoded = enc
			}

			// Test that appending the decimal to an existing buffer works.
			var enc []byte
			var dec *inf.Dec
			other := inf.NewDec(123, 2)
			if dir == Ascending {
				enc = EncodeDecimalAscending([]byte("hello"), other)
				_, dec, _ = DecodeDecimalAscending(enc[5:], tmp)
			} else {
				enc = EncodeDecimalDescending([]byte("hello"), other)
				_, dec, _ = DecodeDecimalDescending(enc[5:], tmp)
			}
			if dec.Cmp(other) != 0 {
				t.Errorf("unexpected mismatch for %v. got %v", 1.23, other)
			}
		}
	}
}
Пример #9
0
func TestEncodeDecimal(t *testing.T) {
	testCases := []struct {
		Value    *inf.Dec
		Encoding []byte
	}{
		{inf.NewDec(-99122, -99999), []byte{0x09, 0x05, 0xfe, 0x79, 0x5b, 0xfe, 0x7c, 0xcd, 0x00}},
		// Three duplicates to make sure -13*10^1000 <= -130*10^999 <= -13*10^1000
		{inf.NewDec(-13, -1000), []byte{0x09, 0x0c, 0x05, 0xf2, 0x00}},
		{inf.NewDec(-130, -999), []byte{0x09, 0x0c, 0x05, 0xf2, 0x00}},
		{inf.NewDec(-13, -1000), []byte{0x09, 0x0c, 0x05, 0xf2, 0x00}},
		{decimal.NewDecFromFloat(-math.MaxFloat64), []byte{0x09, 0x0e, 0xba, 0xc0, 0x22, 0x13, 0x80, 0xd0, 0x50, 0xca, 0x00}},
		{inf.NewDec(-130, -100), []byte{0x09, 0x98, 0xf2, 0x00}},
		{inf.NewDec(-13, 0), []byte{0x09, 0xfd, 0xf2, 0x00}},
		{inf.NewDec(-11, 0), []byte{0x09, 0xfd, 0xf4, 0x00}},
		{inf.NewDec(-1, 0), []byte{0x09, 0xfe, 0xfe, 0x00}},
		{inf.NewDec(-8, 1), []byte{0x0a, 0xf7, 0x00}},
		{inf.NewDec(-1, 1), []byte{0x0a, 0xfe, 0x00}},
		{inf.NewDec(-11, 4), []byte{0x0b, 0x02, 0xf4, 0x00}},
		{inf.NewDec(-11, 6), []byte{0x0b, 0x04, 0xf4, 0x00}},
		{decimal.NewDecFromFloat(-math.SmallestNonzeroFloat64), []byte{0x0b, 0xf1, 0x53, 0xfa, 0x00}},
		{inf.NewDec(-11, 66666), []byte{0x0b, 0xf9, 0xfb, 0x78, 0xf4, 0x00}},
		{inf.NewDec(0, 0), []byte{0x0c}},
		{decimal.NewDecFromFloat(math.SmallestNonzeroFloat64), []byte{0x0d, 0x0e, 0xac, 0x05, 0x00}},
		{inf.NewDec(11, 6), []byte{0x0d, 0xfb, 0x0b, 0x00}},
		{inf.NewDec(11, 4), []byte{0x0d, 0xfd, 0x0b, 0x00}},
		{inf.NewDec(1, 1), []byte{0x0e, 0x01, 0x00}},
		{inf.NewDec(8, 1), []byte{0x0e, 0x08, 0x00}},
		{inf.NewDec(1, 0), []byte{0x0f, 0x01, 0x01, 0x00}},
		{inf.NewDec(11, 0), []byte{0x0f, 0x02, 0x0b, 0x00}},
		{inf.NewDec(13, 0), []byte{0x0f, 0x02, 0x0d, 0x00}},
		{decimal.NewDecFromFloat(math.MaxFloat64), []byte{0x0f, 0xf1, 0x45, 0x3f, 0xdd, 0xec, 0x7f, 0x2f, 0xaf, 0x35, 0x00}},
		// Four duplicates to make sure 13*10^1000 <= 130*10^999 <= 1300*10^998 <= 13*10^1000
		{inf.NewDec(13, -1000), []byte{0x0f, 0xf3, 0xfa, 0x0d, 0x00}},
		{inf.NewDec(130, -999), []byte{0x0f, 0xf3, 0xfa, 0x0d, 0x00}},
		{inf.NewDec(1300, -998), []byte{0x0f, 0xf3, 0xfa, 0x0d, 0x00}},
		{inf.NewDec(13, -1000), []byte{0x0f, 0xf3, 0xfa, 0x0d, 0x00}},
		{inf.NewDec(99122, -99999), []byte{0x0f, 0xfa, 0x01, 0x86, 0xa4, 0x01, 0x83, 0x32, 0x00}},
		{inf.NewDec(99122839898321208, -99999), []byte{0x0f, 0xfa, 0x01, 0x86, 0xb0, 0x01, 0x60, 0x27, 0xb2, 0x9d, 0x44, 0x71, 0x38, 0x00}},
	}

	var lastEncoded []byte
	for _, tmp := range [][]byte{nil, make([]byte, 0, 100)} {
		tmp = tmp[:0]
		for _, dir := range []Direction{Ascending, Descending} {
			for i, c := range testCases {
				var enc []byte
				var err error
				var dec *inf.Dec
				if dir == Ascending {
					enc = EncodeDecimalAscending(nil, c.Value)
					_, dec, err = DecodeDecimalAscending(enc, tmp)
				} else {
					enc = EncodeDecimalDescending(nil, c.Value)
					_, dec, err = DecodeDecimalDescending(enc, tmp)
				}
				if dir == Ascending && !bytes.Equal(enc, c.Encoding) {
					t.Errorf("unexpected mismatch for %s. expected [% x], got [% x]",
						c.Value, c.Encoding, enc)
				}
				if i > 0 {
					if (bytes.Compare(lastEncoded, enc) > 0 && dir == Ascending) ||
						(bytes.Compare(lastEncoded, enc) < 0 && dir == Descending) {
						t.Errorf("%v: expected [% x] to be less than or equal to [% x]",
							c.Value, testCases[i-1].Encoding, enc)
					}
				}
				if err != nil {
					t.Error(err)
					continue
				}
				if dec.Cmp(c.Value) != 0 {
					t.Errorf("%d unexpected mismatch for %v. got %v", i, c.Value, dec)
				}
				lastEncoded = enc
			}

			// Test that appending the decimal to an existing buffer works.
			var enc []byte
			var dec *inf.Dec
			other := inf.NewDec(123, 2)
			if dir == Ascending {
				enc = EncodeDecimalAscending([]byte("hello"), other)
				_, dec, _ = DecodeDecimalAscending(enc[5:], tmp)
			} else {
				enc = EncodeDecimalDescending([]byte("hello"), other)
				_, dec, _ = DecodeDecimalDescending(enc[5:], tmp)
			}
			if dec.Cmp(other) != 0 {
				t.Errorf("unexpected mismatch for %v. got %v", 1.23, other)
			}
		}
	}
}
Пример #10
0
// randDecimal generates a random decimal with exponent in the
// range [minExp, maxExp].
func randDecimal(rng *rand.Rand, minExp, maxExp int) *inf.Dec {
	exp := randutil.RandIntInRange(rng, minExp, maxExp+1)
	// Transform random float in [0, 1) to [-1, 1) and multiply by 10^exp.
	floatVal := (rng.Float64()*2 - 1) * math.Pow10(exp)
	return decimal.NewDecFromFloat(floatVal)
}
Пример #11
0
func TestNonsortingEncodeDecimal(t *testing.T) {
	testCases := []struct {
		Value    *inf.Dec
		Encoding []byte
	}{
		{inf.NewDec(-99122, -99999), []byte{0x1a, 0xf8, 0x01, 0x86, 0xa4, 0x01, 0x83, 0x32}},
		// Three duplicates to make sure -13*10^1000 <= -130*10^999 <= -13*10^1000
		{inf.NewDec(-13, -1000), []byte{0x1a, 0xf7, 0x03, 0xea, 0x0d}},
		{inf.NewDec(-130, -999), []byte{0x1a, 0xf7, 0x03, 0xea, 0x0d}},
		{inf.NewDec(-13, -1000), []byte{0x1a, 0xf7, 0x03, 0xea, 0x0d}},
		{decimal.NewDecFromFloat(-math.MaxFloat64), []byte{0x1a, 0xf7, 0x01, 0x35, 0x3f, 0xdd, 0xec, 0x7f, 0x2f, 0xaf, 0x35}},
		{inf.NewDec(-130, -100), []byte{0x1a, 0xef, 0x0d}},
		{inf.NewDec(-13, 0), []byte{0x1a, 0x8a, 0x0d}},
		{inf.NewDec(-11, 0), []byte{0x1a, 0x8a, 0x0b}},
		{inf.NewDec(-1, 0), []byte{0x1a, 0x89, 0x01}},
		{inf.NewDec(-8, 1), []byte{0x25, 0x08}},
		{inf.NewDec(-1, 1), []byte{0x25, 0x01}},
		{inf.NewDec(-11, 4), []byte{0x26, 0x8a, 0x0b}},
		{inf.NewDec(-11, 6), []byte{0x26, 0x8c, 0x0b}},
		{decimal.NewDecFromFloat(-math.SmallestNonzeroFloat64), []byte{0x26, 0xf7, 0x01, 0x43, 0x05}},
		{inf.NewDec(-11, 66666), []byte{0x26, 0xf8, 0x01, 0x04, 0x68, 0x0b}},
		{inf.NewDec(0, 0), []byte{0x27}},
		{decimal.NewDecFromFloat(math.SmallestNonzeroFloat64), []byte{0x28, 0xf7, 0x01, 0x43, 0x05}},
		{inf.NewDec(11, 6), []byte{0x28, 0x8c, 0x0b}},
		{inf.NewDec(11, 4), []byte{0x28, 0x8a, 0x0b}},
		{inf.NewDec(1, 1), []byte{0x29, 0x01}},
		{inf.NewDec(12345, 5), []byte{0x29, 0x30, 0x39}},
		{inf.NewDec(8, 1), []byte{0x29, 0x08}},
		{inf.NewDec(1, 0), []byte{0x34, 0x89, 0x01}},
		{inf.NewDec(11, 0), []byte{0x34, 0x8a, 0x0b}},
		{inf.NewDec(13, 0), []byte{0x34, 0x8a, 0x0d}},
		// Note that this does not sort correctly!
		{inf.NewDec(255, 0), []byte{0x34, 0x8b, 0xff}},
		{inf.NewDec(256, 0), []byte{0x34, 0x8b, 0x01, 0x00}},
		{decimal.NewDecFromFloat(math.MaxFloat64), []byte{0x34, 0xf7, 0x01, 0x35, 0x3f, 0xdd, 0xec, 0x7f, 0x2f, 0xaf, 0x35}},
		// Four duplicates to make sure 13*10^1000 <= 130*10^999 <= 1300*10^998 <= 13*10^1000
		{inf.NewDec(13, -1000), []byte{0x34, 0xf7, 0x03, 0xea, 0x0d}},
		{inf.NewDec(130, -999), []byte{0x34, 0xf7, 0x03, 0xea, 0x0d}},
		{inf.NewDec(1300, -998), []byte{0x34, 0xf7, 0x03, 0xea, 0x0d}},
		{inf.NewDec(13, -1000), []byte{0x34, 0xf7, 0x03, 0xea, 0x0d}},
		{inf.NewDec(99122, -99999), []byte{0x34, 0xf8, 0x01, 0x86, 0xa4, 0x01, 0x83, 0x32}},
		{inf.NewDec(99122839898321208, -99999), []byte{0x34, 0xf8, 0x01, 0x86, 0xb0, 0x01, 0x60, 0x27, 0xb2, 0x9d, 0x44, 0x71, 0x38}},
	}

	rng, _ := randutil.NewPseudoRand()

	for _, tmp := range [][]byte{nil, make([]byte, 0, 100)} {
		for i, c := range testCases {
			enc := EncodeNonsortingDecimal(nil, c.Value)
			dec, err := DecodeNonsortingDecimal(enc, tmp)
			if err != nil {
				t.Error(err)
				continue
			}
			if !bytes.Equal(enc, c.Encoding) {
				t.Errorf("unexpected mismatch for %s. expected [% x], got [% x]",
					c.Value, c.Encoding, enc)
			}
			if dec.Cmp(c.Value) != 0 {
				t.Errorf("%d unexpected mismatch for %v. got %v", i, c.Value, dec)
			}
			// Test that appending the decimal to an existing buffer works. It
			// is important to test with various values, slice lengths, and
			// capacities because the various encoding paths try to use any
			// spare capacity to avoid allocations.
			for trials := 0; trials < 5; trials++ {
				orig := randBuf(rng, 30)
				origLen := len(orig)

				bufCap := origLen + rng.Intn(30)
				buf := make([]byte, origLen, bufCap)
				copy(buf, orig)

				enc := EncodeNonsortingDecimal(buf, c.Value)
				dec, err := DecodeNonsortingDecimal(enc[origLen:], tmp)
				if err != nil {
					t.Fatal(err)
				}

				if dec.Cmp(c.Value) != 0 {
					t.Errorf("unexpected mismatch for %v. got %v", c.Value, dec)
				}
				// Verify the existing values weren't modified.
				for i := range orig {
					if enc[i] != orig[i] {
						t.Errorf("existing byte %d changed after encoding (from %d to %d)",
							i, orig[i], enc[i])
					}
				}
			}
		}
	}
}
Пример #12
0
func TestEncodeDecimal(t *testing.T) {
	testCases := []struct {
		Value    *inf.Dec
		Encoding []byte
	}{
		{inf.NewDec(-99122, -99999), []byte{0x1a, 0x86, 0x3c, 0xad, 0x38, 0xe6, 0xd7, 0x00}},
		// Three duplicates to make sure -13*10^1000 <= -130*10^999 <= -13*10^1000
		{inf.NewDec(-13, -1000), []byte{0x1a, 0x86, 0xfe, 0x0a, 0xe5, 0x00}},
		{inf.NewDec(-130, -999), []byte{0x1a, 0x86, 0xfe, 0x0a, 0xe5, 0x00}},
		{inf.NewDec(-13, -1000), []byte{0x1a, 0x86, 0xfe, 0x0a, 0xe5, 0x00}},
		{decimal.NewDecFromFloat(-math.MaxFloat64), []byte{0x1a, 0x87, 0x64, 0xfc, 0x60, 0x66, 0x44, 0xe4, 0x9e, 0x82, 0xc0, 0x8d, 0x00}},
		{inf.NewDec(-130, -100), []byte{0x1a, 0x87, 0xcb, 0xfc, 0xc3, 0x00}},
		{inf.NewDec(-13, 0), []byte{0x24, 0xe5, 0x00}},
		{inf.NewDec(-11, 0), []byte{0x24, 0xe9, 0x00}},
		{mustDecimal("-10.123456789"), []byte{0x24, 0xea, 0xe6, 0xba, 0x8e, 0x62, 0x4b, 0x00}},
		{mustDecimal("-10"), []byte{0x24, 0xeb, 0x00}},
		{mustDecimal("-9.123456789"), []byte{0x24, 0xec, 0xe6, 0xba, 0x8e, 0x62, 0x4b, 0x00}},
		{mustDecimal("-9"), []byte{0x24, 0xed, 0x00}},
		{mustDecimal("-1.1"), []byte{0x24, 0xfc, 0xeb, 0x00}},
		{inf.NewDec(-1, 0), []byte{0x24, 0xfd, 0x00}},
		{inf.NewDec(-8, 1), []byte{0x25, 0x5f, 0x00}},
		{inf.NewDec(-1, 1), []byte{0x25, 0xeb, 0x00}},
		{mustDecimal("-.09"), []byte{0x25, 0xed, 0x00}},
		{mustDecimal("-.054321"), []byte{0x25, 0xf4, 0xa8, 0xd5, 0x00}},
		{mustDecimal("-.012"), []byte{0x25, 0xfc, 0xd7, 0x00}},
		{inf.NewDec(-11, 4), []byte{0x26, 0x89, 0xe9, 0x00}},
		{inf.NewDec(-11, 6), []byte{0x26, 0x8a, 0xe9, 0x00}},
		{decimal.NewDecFromFloat(-math.SmallestNonzeroFloat64), []byte{0x26, 0xf6, 0xa1, 0xf5, 0x00}},
		{inf.NewDec(-11, 66666), []byte{0x26, 0xf7, 0x82, 0x34, 0xe9, 0x00}},
		{inf.NewDec(0, 0), []byte{0x27}},
		{decimal.NewDecFromFloat(math.SmallestNonzeroFloat64), []byte{0x28, 0x87, 0x5e, 0x0a, 0x00}},
		{inf.NewDec(11, 6), []byte{0x28, 0x87, 0xfd, 0x16, 0x00}},
		{inf.NewDec(11, 4), []byte{0x28, 0x87, 0xfe, 0x16, 0x00}},
		{inf.NewDec(1, 1), []byte{0x29, 0x14, 0x00}},
		{inf.NewDec(8, 1), []byte{0x29, 0xa0, 0x00}},
		{inf.NewDec(1, 0), []byte{0x2a, 0x02, 0x00}},
		{mustDecimal("1.1"), []byte{0x2a, 0x03, 0x14, 0x00}},
		{inf.NewDec(11, 0), []byte{0x2a, 0x16, 0x00}},
		{inf.NewDec(13, 0), []byte{0x2a, 0x1a, 0x00}},
		{decimal.NewDecFromFloat(math.MaxFloat64), []byte{0x34, 0xf6, 0x9b, 0x03, 0x9f, 0x99, 0xbb, 0x1b, 0x61, 0x7d, 0x3f, 0x72, 0x00}},
		// Four duplicates to make sure 13*10^1000 <= 130*10^999 <= 1300*10^998 <= 13*10^1000
		{inf.NewDec(13, -1000), []byte{0x34, 0xf7, 0x01, 0xf5, 0x1a, 0x00}},
		{inf.NewDec(130, -999), []byte{0x34, 0xf7, 0x01, 0xf5, 0x1a, 0x00}},
		{inf.NewDec(1300, -998), []byte{0x34, 0xf7, 0x01, 0xf5, 0x1a, 0x00}},
		{inf.NewDec(13, -1000), []byte{0x34, 0xf7, 0x01, 0xf5, 0x1a, 0x00}},
		{inf.NewDec(99122, -99999), []byte{0x34, 0xf7, 0xc3, 0x52, 0xc7, 0x19, 0x28, 0x00}},
		{inf.NewDec(99122839898321208, -99999), []byte{0x34, 0xf7, 0xc3, 0x58, 0xc7, 0x19, 0x39, 0x4f, 0xb3, 0xa7, 0x2b, 0x29, 0xa0, 0x00}},
	}

	rng, _ := randutil.NewPseudoRand()

	var lastEncoded []byte
	for _, dir := range []Direction{Ascending, Descending} {
		for _, tmp := range [][]byte{nil, make([]byte, 0, 100)} {
			for i, c := range testCases {
				enc := encodeDecimalWithDir(dir, nil, c.Value)
				_, dec := decodeDecimalWithDir(t, dir, enc, tmp)
				if dir == Ascending && !bytes.Equal(enc, c.Encoding) {
					t.Errorf("unexpected mismatch for %s. expected [% x], got [% x]",
						c.Value, c.Encoding, enc)
				}
				if i > 0 {
					if (bytes.Compare(lastEncoded, enc) > 0 && dir == Ascending) ||
						(bytes.Compare(lastEncoded, enc) < 0 && dir == Descending) {
						t.Errorf("%v: expected [% x] to be less than or equal to [% x]",
							c.Value, testCases[i-1].Encoding, enc)
					}
				}
				testPeekLength(t, enc)
				if dec.Cmp(c.Value) != 0 {
					t.Errorf("%d unexpected mismatch for %v. got %v", i, c.Value, dec)
				}
				lastEncoded = enc

				// Test that appending the decimal to an existing buffer works. It
				// is important to test with various values, slice lengths, and
				// capacities because the various encoding paths try to use any
				// spare capacity to avoid allocations.
				for trials := 0; trials < 5; trials++ {
					orig := randBuf(rng, 30)
					origLen := len(orig)

					bufCap := origLen + rng.Intn(30)
					buf := make([]byte, origLen, bufCap)
					copy(buf, orig)

					enc := encodeDecimalWithDir(dir, buf, c.Value)
					// Append some random bytes
					enc = append(enc, randBuf(rng, 20)...)
					_, dec := decodeDecimalWithDir(t, dir, enc[origLen:], tmp)

					if dec.Cmp(c.Value) != 0 {
						t.Errorf("unexpected mismatch for %v. got %v", c.Value, dec)
					}
					// Verify the existing values weren't modified.
					for i := range orig {
						if enc[i] != orig[i] {
							t.Errorf("existing byte %d changed after encoding (from %d to %d)",
								i, orig[i], enc[i])
						}
					}
				}
			}
		}
	}
}