Skip to content

Commit 9723942

Browse files
committed
Improved Cache Stability With Concurrency
1 parent 6dce811 commit 9723942

File tree

2 files changed

+50
-2
lines changed

2 files changed

+50
-2
lines changed

regex.go

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"reflect"
66
"strconv"
77
"strings"
8+
"time"
89

910
"github.com/GRbit/go-pcre"
1011
)
@@ -59,6 +60,38 @@ func JoinBytes(bytes ...interface{}) []byte {
5960
return res
6061
}
6162

63+
var writingCache int = 0
64+
65+
func setCache(re string, reg pcre.Regexp){
66+
for writingCache != 0 {
67+
time.Sleep(1000)
68+
}
69+
70+
writingCache++
71+
72+
if writingCache != 1 {
73+
writingCache--
74+
go setCache(re, reg)
75+
return
76+
}
77+
78+
regCache[re] = reg
79+
80+
writingCache--
81+
}
82+
83+
func getCache(re string) (pcre.Regexp, bool) {
84+
if writingCache != 0 {
85+
return pcre.Regexp{}, false
86+
}
87+
88+
if val, ok := regCache[re]; ok {
89+
return val, true
90+
}
91+
92+
return pcre.Regexp{}, false
93+
}
94+
6295
func Compile(re string) Regexp {
6396
if strings.Contains(re, `\'`) {
6497
r := []byte(re)
@@ -79,12 +112,13 @@ func Compile(re string) Regexp {
79112
re = regReReplaceComment.ReplaceAllString(re, ``, 0)
80113
}
81114

82-
if val, ok := regCache[re]; ok {
115+
if val, ok := getCache(re); ok {
83116
return val
84117
} else {
85118
// reg := pcre.MustCompileJIT(re, pcre.UTF8, pcre.CONFIG_JIT)
86119
reg := pcre.MustCompile(re, pcre.UTF8)
87-
regCache[re] = reg
120+
// regCache[re] = reg
121+
go setCache(re, reg)
88122
return reg
89123
}
90124
}

regex_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ package regex
33
import (
44
"bytes"
55
"errors"
6+
"fmt"
67
"testing"
8+
"time"
79
)
810

911
func TestCompile(t *testing.T) {
@@ -29,3 +31,15 @@ func TestReplace(t *testing.T) {
2931
check("string with `block` quotes", `\'.*?\'`, "'single'", "string with 'single' quotes")
3032
}
3133

34+
func TestConcurent(t *testing.T) {
35+
for i := 0; i < 10; i++ {
36+
go (func(){
37+
res := RepFunc([]byte("test"), `(t)`, func(data func(int) []byte) []byte {
38+
return data(1)
39+
})
40+
fmt.Println(string(res))
41+
})()
42+
}
43+
44+
time.Sleep(1000000 * 1000) // 1 second
45+
}

0 commit comments

Comments
 (0)