...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package validate
16
17 import (
18 re "regexp"
19 "sync"
20 "sync/atomic"
21 )
22
23
24 var (
25 cacheMutex = &sync.Mutex{}
26 reDict = atomic.Value{}
27 )
28
29 func compileRegexp(pattern string) (*re.Regexp, error) {
30 if cache, ok := reDict.Load().(map[string]*re.Regexp); ok {
31 if r := cache[pattern]; r != nil {
32 return r, nil
33 }
34 }
35
36 r, err := re.Compile(pattern)
37 if err != nil {
38 return nil, err
39 }
40 cacheRegexp(r)
41 return r, nil
42 }
43
44 func mustCompileRegexp(pattern string) *re.Regexp {
45 if cache, ok := reDict.Load().(map[string]*re.Regexp); ok {
46 if r := cache[pattern]; r != nil {
47 return r
48 }
49 }
50
51 r := re.MustCompile(pattern)
52 cacheRegexp(r)
53 return r
54 }
55
56 func cacheRegexp(r *re.Regexp) {
57 cacheMutex.Lock()
58 defer cacheMutex.Unlock()
59
60 if cache, ok := reDict.Load().(map[string]*re.Regexp); !ok || cache[r.String()] == nil {
61 newCache := map[string]*re.Regexp{
62 r.String(): r,
63 }
64
65 for k, v := range cache {
66 newCache[k] = v
67 }
68
69 reDict.Store(newCache)
70 }
71 }
72
View as plain text