github.com/mithrandie/csvq@v1.18.1/lib/json/cache.go (about) 1 package json 2 3 import ( 4 "strings" 5 "sync" 6 ) 7 8 var Path = NewPathMap() 9 var Query = NewQueryMap() 10 11 type PathMap struct { 12 m *sync.Map 13 mtx *sync.Mutex 14 } 15 16 func NewPathMap() PathMap { 17 return PathMap{ 18 m: &sync.Map{}, 19 mtx: &sync.Mutex{}, 20 } 21 } 22 23 func (pmap PathMap) store(key string, value PathExpression) { 24 pmap.m.Store(key, value) 25 } 26 27 func (pmap PathMap) load(key string) (PathExpression, bool) { 28 v, ok := pmap.m.Load(key) 29 if ok && v != nil { 30 return v.(PathExpression), ok 31 } 32 return nil, ok 33 } 34 35 func (pmap PathMap) Parse(s string) (PathExpression, error) { 36 s = strings.TrimSpace(s) 37 38 if e, ok := pmap.load(s); ok { 39 return e, nil 40 } 41 42 pmap.mtx.Lock() 43 defer pmap.mtx.Unlock() 44 45 if e, ok := pmap.load(s); ok { 46 return e, nil 47 } 48 49 e, err := ParsePath(s) 50 if err != nil || e == nil { 51 return nil, err 52 } 53 pmap.store(s, e) 54 return e, nil 55 } 56 57 type QueryMap struct { 58 m *sync.Map 59 mtx *sync.Mutex 60 } 61 62 func NewQueryMap() QueryMap { 63 return QueryMap{ 64 m: &sync.Map{}, 65 mtx: &sync.Mutex{}, 66 } 67 } 68 69 func (qmap QueryMap) store(key string, value QueryExpression) { 70 qmap.m.Store(key, value) 71 } 72 73 func (qmap QueryMap) load(key string) (QueryExpression, bool) { 74 v, ok := qmap.m.Load(key) 75 if ok && v != nil { 76 return v.(QueryExpression), ok 77 } 78 return nil, ok 79 } 80 func (qmap QueryMap) Parse(s string) (QueryExpression, error) { 81 s = strings.TrimSpace(s) 82 if len(s) < 1 { 83 return nil, nil 84 } 85 86 if e, ok := qmap.load(s); ok { 87 return e, nil 88 } 89 90 qmap.mtx.Lock() 91 defer qmap.mtx.Unlock() 92 93 if e, ok := qmap.load(s); ok { 94 return e, nil 95 } 96 97 e, err := ParseQuery(s) 98 if err != nil || e == nil { 99 return nil, err 100 } 101 qmap.store(s, e) 102 return e, nil 103 }