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  }