Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize series key parsing on startup #6743

Merged
merged 5 commits into from
May 27, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
- [#6599](https://github.com/influxdata/influxdb/issues/6599): Ensure that future points considered in SHOW queries.
- [#6720](https://github.com/influxdata/influxdb/issues/6720): Concurrent map read write panic. Thanks @arussellsaw
- [#6727](https://github.com/influxdata/influxdb/issues/6727): queries with strings that look like dates end up with date types, not string types
- [#6250](https://github.com/influxdata/influxdb/issues/6250): Slow startup time

## v0.13.0 [2016-05-12]

Expand Down
13 changes: 11 additions & 2 deletions models/points.go
Original file line number Diff line number Diff line change
Expand Up @@ -1040,6 +1040,10 @@ func escapeTag(in []byte) []byte {
}

func unescapeTag(in []byte) []byte {
if bytes.IndexByte(in, '\\') == -1 {
return in
}

for b, esc := range tagEscapeCodes {
if bytes.IndexByte(in, b) != -1 {
in = bytes.Replace(in, esc, []byte{b}, -1)
Expand Down Expand Up @@ -1216,7 +1220,8 @@ func (p *point) Tags() Tags {
}

func parseTags(buf []byte) Tags {
tags := map[string]string{}
tags := make(map[string]string, bytes.Count(buf, []byte(",")))
hasEscape := bytes.IndexByte(buf, '\\') != -1

if len(buf) != 0 {
pos, name := scanTo(buf, 0, ',')
Expand All @@ -1239,7 +1244,11 @@ func parseTags(buf []byte) Tags {
continue
}

tags[string(unescapeTag(key))] = string(unescapeTag(value))
if hasEscape {
tags[string(unescapeTag(key))] = string(unescapeTag(value))
} else {
tags[string(key)] = string(value)
}

i++
}
Expand Down
7 changes: 7 additions & 0 deletions models/points_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,13 @@ func BenchmarkParsePointsTagsUnSorted10(b *testing.B) {
}
}

func BenchmarkParseKey(b *testing.B) {
line := `cpu,region=us-west,host=serverA,env=prod,target=servers,zone=1c,tag1=value1,tag2=value2,tag3=value3,tag4=value4,tag5=value5`
for i := 0; i < b.N; i++ {
models.ParseKey(line)
}
}

// TestPoint wraps a models.Point but also makes available the raw
// arguments to the Point.
//
Expand Down
4 changes: 4 additions & 0 deletions pkg/escape/strings.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ func init() {
}

func UnescapeString(in string) string {
if strings.IndexByte(in, '\\') == -1 {
return in
}

for b, esc := range codesStr {
in = strings.Replace(in, esc, b, -1)
}
Expand Down
16 changes: 11 additions & 5 deletions tsdb/meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,14 +133,13 @@ func (d *DatabaseIndex) CreateSeriesIndexIfNotExists(measurementName string, ser
m := d.CreateMeasurementIndexIfNotExists(measurementName)

d.mu.Lock()
defer d.mu.Unlock()

// set the in memory ID for query processing on this shard
series.id = d.lastID + 1
d.lastID++

series.measurement = m
d.series[series.Key] = series
d.mu.Unlock()

m.AddSeries(series)

Expand Down Expand Up @@ -502,8 +501,7 @@ type Measurement struct {
fieldNames map[string]struct{}

// in-memory index fields
seriesByID map[uint64]*Series // lookup table for series by their id
measurement *Measurement
seriesByID map[uint64]*Series // lookup table for series by their id
seriesByTagKeyValue map[string]map[string]SeriesIDs // map from tag key to value to sorted set of series ids
seriesIDs SeriesIDs // sorted list of series IDs in this measurement
}
Expand All @@ -516,7 +514,7 @@ func NewMeasurement(name string) *Measurement {

seriesByID: make(map[uint64]*Series),
seriesByTagKeyValue: make(map[string]map[string]SeriesIDs),
seriesIDs: make(SeriesIDs, 0),
seriesIDs: make(SeriesIDs, 0, 1),
}
}

Expand Down Expand Up @@ -591,12 +589,20 @@ func (m *Measurement) HasSeries() bool {

// AddSeries will add a series to the measurementIndex. Returns false if already present
func (m *Measurement) AddSeries(s *Series) bool {
m.mu.RLock()
if _, ok := m.seriesByID[s.id]; ok {
m.mu.RUnlock()
return false
}
m.mu.RUnlock()

m.mu.Lock()
defer m.mu.Unlock()

if _, ok := m.seriesByID[s.id]; ok {
return false
}

m.seriesByID[s.id] = s
m.seriesIDs = append(m.seriesIDs, s.id)

Expand Down