func (tv TagValue) MarshalJSON() ([]byte, error) {
	length := len(tv)
	// Need at least two more bytes than in tv.
	result := bytes.NewBuffer(make([]byte, 0, length+2))
	result.WriteByte('"')
	for i := 0; i < length; i++ {
		b := tv[i]
		switch {
		case (b >= '-' && b <= '9') || // '-', '.', '/', 0-9
			(b >= 'A' && b <= 'Z') ||
			(b >= 'a' && b <= 'z'):
			result.WriteByte(b)
		case b == '_':
			result.WriteString("__")
		case b == ':':
			result.WriteString("_.")
		default:
			result.WriteString(fmt.Sprintf("_%X", b))
		}
	}
	result.WriteByte('"')
	return result.Bytes(), nil
}
func (tv TagValue) MarshalJSON() ([]byte, error) {
	length := len(tv)
	// Need at least two more bytes than in tv.
	result := bytes.NewBuffer(make([]byte, 0, length+2))
	result.WriteByte('"')
	for i := 0; i < length; i++ {
		b := tv[i]
		switch {
		case (b >= '-' && b <= '9') || // '-', '.', '/', 0-9
			(b >= 'A' && b <= 'Z') ||
			(b >= 'a' && b <= 'z'):
			result.WriteByte(b)
		case b == '_':
			result.WriteString("__")
		case b == ':':
			result.WriteString("_.")
		default:
			result.WriteString(fmt.Sprintf("_%X", b))
		}
	}
	result.WriteByte('"')
	return result.Bytes(), nil
}
// MarshalJSON marshals this TagValue into JSON that only contains runes allowed
// in OpenTSDB. It implements json.Marshaler. The runes allowed in OpenTSDB are
// all single-byte. This function encodes the arbitrary byte sequence found in
// this TagValue in the following way:
//
// - The string that underlies TagValue is scanned byte by byte.
//
// - If a byte represents a legal OpenTSDB rune with the exception of '_', that
// byte is directly copied to the resulting JSON byte slice.
//
// - If '_' is encountered, it is replaced by '__'.
//
// - If ':' is encountered, it is replaced by '_.'.
//
// - All other bytes are replaced by '_' followed by two bytes containing the
// uppercase ASCII representation of their hexadecimal value.
//
// This encoding allows to save arbitrary Go strings in OpenTSDB. That's
// required because Prometheus label values can contain anything, and even
// Prometheus metric names may (and often do) contain ':' (which is disallowed
// in OpenTSDB strings). The encoding uses '_' as an escape character and
// renders a ':' more or less recognizable as '_.'
//
// Examples:
//
// "foo-bar-42" -> "foo-bar-42"
//
// "foo_bar_42" -> "foo__bar__42"
//
// "http://example.org:8080" -> "http_.//example.org_.8080"
//
// "Björn's email: bjoern@soundcloud.com" ->
// "Bj_C3_B6rn_27s_20email_._20bjoern_40soundcloud.com"
//
// "日" -> "_E6_97_A5"