diff --git a/CHANGELOG.md b/CHANGELOG.md index e2526b1b436..47e9e73f585 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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] diff --git a/models/points.go b/models/points.go index f4db4c67e20..edaad7a42e5 100644 --- a/models/points.go +++ b/models/points.go @@ -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) @@ -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, ',') @@ -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++ } diff --git a/models/points_test.go b/models/points_test.go index ec6a41eb5fb..60c1097999f 100644 --- a/models/points_test.go +++ b/models/points_test.go @@ -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. // diff --git a/pkg/escape/strings.go b/pkg/escape/strings.go index 330fbf4226a..d391142869f 100644 --- a/pkg/escape/strings.go +++ b/pkg/escape/strings.go @@ -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) } diff --git a/tsdb/meta.go b/tsdb/meta.go index 423e4d8e4ba..1b3a950d673 100644 --- a/tsdb/meta.go +++ b/tsdb/meta.go @@ -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) @@ -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 } @@ -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), } } @@ -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)