Skip to content

Commit

Permalink
rtp: cache regexes in memory for reuse
Browse files Browse the repository at this point in the history
Fixes: #45
  • Loading branch information
adamdecaf committed Nov 27, 2023
1 parent 957ae88 commit 36c4c28
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 4 deletions.
25 changes: 21 additions & 4 deletions pkg/rtp/restrictions.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"regexp"
"strings"
"sync"
"unicode/utf8"

"github.com/moov-io/base"
Expand All @@ -21,12 +22,28 @@ func AddError(errs *base.ErrorList, err error) {
}
}

var (
compiledRegexeLock sync.RWMutex
compiledRegexes = make(map[string]*regexp.Regexp)
)

func ValidatePattern(value string, regex string) error {
pat, err := regexp.Compile(regex)
if err != nil {
return err
compiledRegexeLock.RLock()
rr, exists := compiledRegexes[regex]
compiledRegexeLock.RUnlock()
if !exists {
r, err := regexp.Compile(regex)
if err != nil {
return err
}

compiledRegexeLock.Lock()
compiledRegexes[regex] = r
compiledRegexeLock.Unlock()

rr = r
}
if !pat.MatchString(value) {
if !rr.MatchString(value) {
return fmt.Errorf("%s fails validation with pattern %s", value, regex)
}
return nil
Expand Down
20 changes: 20 additions & 0 deletions pkg/rtp/restrictions_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package rtp_test

import (
"fmt"
"sync"
"testing"

"github.com/stretchr/testify/require"
Expand All @@ -20,6 +22,24 @@ func TestValidatePattern(t *testing.T) {
pattern := `[0-9]{4}(((01|03|05|07|08|10|12)((0[1-9])|([1-2][0-9])|(3[0-1])))|((04|06|09|11)((0[1-9])|([1-2][0-9])|30))|((02)((0[1-9])|([1-2][0-9]))))((([0-1][0-9])|(2[0-3]))(([0-5][0-9])){2})[A-Z0-9]{11}.*`
require.NoError(t, rtp.ValidatePattern("20230713145322200000057A11712044729", pattern))
require.Error(t, rtp.ValidatePattern("20230931145322200000057A11712044729", pattern)) // invalid MMDD

t.Run("concurrent", func(t *testing.T) {
iterations := 1000

var wg sync.WaitGroup
wg.Add(iterations)

for i := 0; i < iterations; i++ {
go func(idx int) {
wg.Done()

patern := fmt.Sprintf("[0-9]{0,%d}", idx/5) // add/get regexes from cache
require.NoError(t, rtp.ValidatePattern("4", patern))
}(i)
}

wg.Wait()
})
}

func TestValidateEnumeration(t *testing.T) {
Expand Down

0 comments on commit 36c4c28

Please sign in to comment.