Skip to content

Commit

Permalink
Merge pull request #20 from arnecls/mutex_performance
Browse files Browse the repository at this point in the history
Improve performance of parallel operations
  • Loading branch information
vjeantet authored Jul 11, 2017
2 parents d73e972 + e4222b3 commit ce01e59
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 15 deletions.
37 changes: 22 additions & 15 deletions grok.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ type Grok struct {
config *Config
compiledPatterns map[string]*gRegexp
patterns map[string]*gPattern
serviceMu sync.Mutex
patternsGuard *sync.RWMutex
compiledGuard *sync.RWMutex
}

type gPattern struct {
Expand Down Expand Up @@ -61,6 +62,8 @@ func NewWithConfig(config *Config) (*Grok, error) {
compiledPatterns: map[string]*gRegexp{},
patterns: map[string]*gPattern{},
rawPattern: map[string]string{},
patternsGuard: new(sync.RWMutex),
compiledGuard: new(sync.RWMutex),
}

if !config.SkipDefaultPatterns {
Expand Down Expand Up @@ -97,17 +100,18 @@ func (g *Grok) addPattern(name, pattern string) error {

// AddPattern adds a named pattern to grok
func (g *Grok) AddPattern(name, pattern string) error {
g.serviceMu.Lock()
g.patternsGuard.Lock()
defer g.patternsGuard.Unlock()

g.rawPattern[name] = pattern
g.buildPatterns()
g.serviceMu.Unlock()
return nil
}

// AddPatternsFromMap loads a map of named patterns
func (g *Grok) AddPatternsFromMap(m map[string]string) error {
g.serviceMu.Lock()
defer g.serviceMu.Unlock()
g.patternsGuard.Lock()
defer g.patternsGuard.Unlock()

for name, pattern := range m {
g.rawPattern[name] = pattern
Expand Down Expand Up @@ -196,19 +200,16 @@ func (g *Grok) Match(pattern, text string) (bool, error) {
// compiledParse parses the specified text and returns a map with the results.
func (g *Grok) compiledParse(gr *gRegexp, text string) (map[string]string, error) {
captures := make(map[string]string)
g.serviceMu.Lock()
if match := gr.regexp.FindStringSubmatch(text); len(match) > 0 {
for i, name := range gr.regexp.SubexpNames() {
if name != "" {
if g.config.RemoveEmptyValues && match[i] == "" {
continue
}
captures[name] = match[i]

}
}
}
g.serviceMu.Unlock()

return captures, nil
}
Expand Down Expand Up @@ -287,15 +288,17 @@ func (g *Grok) buildPatterns() error {
}

func (g *Grok) compile(pattern string) (*gRegexp, error) {
g.serviceMu.Lock()
defer g.serviceMu.Unlock()
if g.compiledPatterns == nil {
g.compiledPatterns = map[string]*gRegexp{}
}
if gr, ok := g.compiledPatterns[pattern]; ok {
g.compiledGuard.RLock()
gr, ok := g.compiledPatterns[pattern]
g.compiledGuard.RUnlock()

if ok {
return gr, nil
}

g.patternsGuard.RLock()
newPattern, ti, err := g.denormalizePattern(pattern, g.patterns)
g.patternsGuard.RUnlock()
if err != nil {
return nil, err
}
Expand All @@ -304,8 +307,12 @@ func (g *Grok) compile(pattern string) (*gRegexp, error) {
if err != nil {
return nil, err
}
gr := &gRegexp{regexp: compiledRegex, typeInfo: ti}
gr = &gRegexp{regexp: compiledRegex, typeInfo: ti}

g.compiledGuard.Lock()
g.compiledPatterns[pattern] = gr
g.compiledGuard.Unlock()

return gr, nil
}

Expand Down
12 changes: 12 additions & 0 deletions grok_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,18 @@ func BenchmarkCapturesTypedReal(b *testing.B) {
}
}

func BenchmarkParallelCaptures(b *testing.B) {
g, _ := NewWithConfig(&Config{NamedCapturesOnly: true})
b.ReportAllocs()
b.ResetTimer()

b.RunParallel(func(b *testing.PB) {
for b.Next() {
g.Parse(`%{IPORHOST:clientip} %{USER:ident} %{USER:auth} \[%{HTTPDATE:timestamp}\] "(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest})" %{NUMBER:response} (?:%{NUMBER:bytes}|-)`, `127.0.0.1 - - [23/Apr/2014:22:58:32 +0200] "GET /index.php HTTP/1.1" 404 207`)
}
})
}

func TestGrok_AddPatternsFromMap_not_exist(t *testing.T) {
defer func() {
if r := recover(); r != nil {
Expand Down

0 comments on commit ce01e59

Please sign in to comment.