func BenchmarkDecodeBinaryDecimal(b *testing.B) { wbuf := writeBuffer{bytecount: metric.NewCounter()} expected := new(parser.DDecimal) expected.SetString("-1728718718271827121233.1212121212") wbuf.writeBinaryDatum(expected) rbuf := readBuffer{msg: wbuf.wrapped.Bytes()} plen, err := rbuf.getUint32() if err != nil { b.Fatal(err) } bytes, err := rbuf.getBytes(int(plen)) if err != nil { b.Fatal(err) } b.ResetTimer() for i := 0; i < b.N; i++ { b.StartTimer() got, err := decodeOidDatum(oid.T_numeric, formatBinary, bytes) b.StopTimer() if err != nil { b.Fatal(err) } else if got.Compare(expected) != 0 { b.Fatalf("expected %s, got %s", expected, got) } } }
func datumFromProto(d driver.Datum) parser.Datum { arg := d.Payload if arg == nil { return parser.DNull } switch t := arg.(type) { case *driver.Datum_BoolVal: return parser.DBool(t.BoolVal) case *driver.Datum_IntVal: return parser.DInt(t.IntVal) case *driver.Datum_FloatVal: return parser.DFloat(t.FloatVal) case *driver.Datum_DecimalVal: dd := parser.DDecimal{} if _, ok := dd.SetString(t.DecimalVal); !ok { panic(fmt.Sprintf("could not parse string %q as decimal", t.DecimalVal)) } return dd case *driver.Datum_BytesVal: return parser.DBytes(t.BytesVal) case *driver.Datum_StringVal: return parser.DString(t.StringVal) case *driver.Datum_DateVal: return parser.DDate(t.DateVal) case *driver.Datum_TimeVal: return parser.DTimestamp{Time: t.TimeVal.GoTime()} case *driver.Datum_IntervalVal: return parser.DInterval{Duration: time.Duration(t.IntervalVal)} default: panic(fmt.Sprintf("unexpected type %T", t)) } }
func BenchmarkWriteBinaryDecimal(b *testing.B) { buf := writeBuffer{bytecount: metric.NewCounter()} dec := new(parser.DDecimal) dec.SetString("-1728718718271827121233.1212121212") // Warm up the buffer. buf.writeBinaryDatum(dec) buf.wrapped.Reset() b.ResetTimer() for i := 0; i < b.N; i++ { b.StartTimer() buf.writeBinaryDatum(dec) b.StopTimer() buf.wrapped.Reset() } }
// decodeOidDatum decodes bytes with specified Oid and format code into // a datum. func decodeOidDatum(id oid.Oid, code formatCode, b []byte) (parser.Datum, error) { var d parser.Datum switch id { case oid.T_bool: switch code { case formatText: v, err := strconv.ParseBool(string(b)) if err != nil { return d, err } d = parser.DBool(v) default: return d, fmt.Errorf("unsupported bool format code: %d", code) } case oid.T_int2: switch code { case formatText: i, err := strconv.ParseInt(string(b), 10, 64) if err != nil { return d, err } d = parser.DInt(i) case formatBinary: var i int16 err := binary.Read(bytes.NewReader(b), binary.BigEndian, &i) if err != nil { return d, err } d = parser.DInt(i) default: return d, fmt.Errorf("unsupported int2 format code: %d", code) } case oid.T_int4: switch code { case formatText: i, err := strconv.ParseInt(string(b), 10, 64) if err != nil { return d, err } d = parser.DInt(i) case formatBinary: var i int32 err := binary.Read(bytes.NewReader(b), binary.BigEndian, &i) if err != nil { return d, err } d = parser.DInt(i) default: return d, fmt.Errorf("unsupported int4 format code: %d", code) } case oid.T_int8: switch code { case formatText: i, err := strconv.ParseInt(string(b), 10, 64) if err != nil { return d, err } d = parser.DInt(i) case formatBinary: var i int64 err := binary.Read(bytes.NewReader(b), binary.BigEndian, &i) if err != nil { return d, err } d = parser.DInt(i) default: return d, fmt.Errorf("unsupported int8 format code: %d", code) } case oid.T_float4: switch code { case formatText: f, err := strconv.ParseFloat(string(b), 64) if err != nil { return d, err } d = parser.DFloat(f) case formatBinary: var f float32 err := binary.Read(bytes.NewReader(b), binary.BigEndian, &f) if err != nil { return d, err } d = parser.DFloat(f) default: return d, fmt.Errorf("unsupported float4 format code: %d", code) } case oid.T_float8: switch code { case formatText: f, err := strconv.ParseFloat(string(b), 64) if err != nil { return d, err } d = parser.DFloat(f) case formatBinary: var f float64 err := binary.Read(bytes.NewReader(b), binary.BigEndian, &f) if err != nil { return d, err } d = parser.DFloat(f) default: return d, fmt.Errorf("unsupported float8 format code: %d", code) } case oid.T_numeric: switch code { case formatText: dd := parser.DDecimal{} if _, ok := dd.SetString(string(b)); !ok { return nil, fmt.Errorf("could not parse string %q as decimal", b) } d = dd default: return d, fmt.Errorf("unsupported numeric format code: %d", code) } case oid.T_text: switch code { case formatText: d = parser.DString(b) default: return d, fmt.Errorf("unsupported text format code: %d", code) } // TODO(mjibson): implement date/time types default: return d, fmt.Errorf("unsupported OID: %v", id) } return d, nil }