forked from influxdata/influx-stress
-
Notifications
You must be signed in to change notification settings - Fork 0
/
field.go
115 lines (97 loc) · 2.83 KB
/
field.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package lineprotocol
import (
"io"
"strconv"
"sync/atomic"
)
var equalSign = byte('=')
var comma = byte(',')
var quotes = byte('"')
// Field is an aliased io.WriterTo.
type Field io.WriterTo
// Verify that *Int and *Float implement Field.
var (
_ Field = &Int{}
_ Field = &Float{}
)
// Int implements the Field interface. Key is the line protocol
// field key as a byte slice. Value is the integer key value for
// the field.
//
// Not that Value occurs before Key in the Int struct. The reason for this
// is that on both ARM and x86-32, it is the caller's responsibility to arrange
// for 64-bit alignment of 64-bit words accessed atomically. The first word in a
// global variable or in an allocated struct or slice can be relied upon to be
// 64-bit aligned.
type Int struct {
Value int64
Key []byte
}
// WriteTo writes the field key value pair to an io.Writer.
// For example if i.Key = []byte("value") and i.Value = 1
// then `value=1i` is written.
func (i *Int) WriteTo(w io.Writer) (int64, error) {
n, err := w.Write(i.Key)
if err != nil {
return int64(n), err
}
// Max int64 fits in 19 base-10 digits,
// plus 1 for the leading =, plus 1 for the trailing i required for ints.
buf := make([]byte, 0, 21)
buf = append(buf, equalSign)
buf = strconv.AppendInt(buf, atomic.LoadInt64(&i.Value), 10)
buf = append(buf, 'i')
m, err := w.Write(buf)
return int64(n + m), err
}
// Float implements the Field interface. Key is the line protocol
// field key as a byte slice. Value is the float key value for
// the field.
type Float struct {
Key []byte
Value float64
}
// WriteTo writes the field key value pair to an io.Writer
// For example if i.Key = []byte("value") and i.Value = 1
// then `value=1` is written.
func (f *Float) WriteTo(w io.Writer) (int64, error) {
n, err := w.Write(f.Key)
if err != nil {
return int64(n), err
}
// Taking a total guess here at what size a float might fit in
buf := make([]byte, 0, 32)
buf = append(buf, equalSign)
// There will be a data race here with *point.Update for floats
buf = strconv.AppendFloat(buf, f.Value, 'f', -1, 64)
m, err := w.Write(buf)
return int64(n + m), err
}
// String implements the Field interface.
// - Key is the line protocol field key as a byte slice.
// - Value is the string value for the field.
type String struct {
Key []byte
Value string
}
// WriteTo writes the field key value pair to an io.Writer
func (s *String) WriteTo(w io.Writer) (int64, error) {
n, err := w.Write(s.Key)
if err != nil {
return int64(n), err
}
e, err := w.Write([]byte{equalSign})
if err != nil {
return int64(n + e), err
}
strByte := []byte(s.Value)
buf := make([]byte, 0, len(strByte)+2)
buf = append(buf, quotes)
buf = append(buf, strByte...)
buf = append(buf, quotes)
m, err := w.Write(buf)
if err != nil {
return int64(n + e + m), err
}
return int64(n + e + m), err
}