From 2220e2822d7241cc79ea288a5746003be879dc94 Mon Sep 17 00:00:00 2001 From: Charles Iliya Krempeaux Date: Fri, 21 Jun 2019 13:37:53 -0700 Subject: [PATCH] mutex --- compile.go | 9 ++++----- errors.go | 3 ++- pattern.go | 40 +++++++--------------------------------- pattern_find.go | 6 ++++++ pattern_glob.go | 28 ++++++++++++++++++++++++++++ pattern_init.go | 16 ++++++++++++++++ pattern_load.go | 6 ++++++ 7 files changed, 69 insertions(+), 39 deletions(-) create mode 100644 pattern_glob.go create mode 100644 pattern_init.go diff --git a/compile.go b/compile.go index cb8117c..8e7fca5 100644 --- a/compile.go +++ b/compile.go @@ -1,24 +1,20 @@ package pathmatch - import ( "strings" ) - const ( defaultFieldTagName = "match" wildcardBit = "{}" ) - var ( errMissingEndingRightBraceToMatchBeginningLeftBrace = newPatternSyntaxError(`Missing ending "}" (to match beginning "{").`) errSlashInsideOfBraces = newPatternSyntaxError(`"/" inside of "{...}".`) errLeftBraceInsideOfBraces = newPatternSyntaxError(`"{" inside of "{...}".`) ) - // Compile takes an uncompiled pattern, in the form of a Go string (ex: "/users/{userId}/vehicles/{vehicleId}"), // and returns a compiled pattern. // @@ -66,7 +62,10 @@ func CompileTo(target *Pattern, uncompiledPattern string) error { return errNilTarget } - newPattern(target, defaultFieldTagName) + target.mutex.Lock() + defer target.mutex.Unlock() + + target.init(defaultFieldTagName) s := uncompiledPattern for { diff --git a/errors.go b/errors.go index f5095e4..b20bb0c 100644 --- a/errors.go +++ b/errors.go @@ -5,5 +5,6 @@ import ( ) var ( - errNilTarget = errors.New("pathmatch: Nil Target") + errNilReceiver = errors.New("pathmatch: Nil Receiver") + errNilTarget = errors.New("pathmatch: Nil Target") ) diff --git a/pattern.go b/pattern.go index 43d49a2..16b900f 100644 --- a/pattern.go +++ b/pattern.go @@ -1,7 +1,7 @@ package pathmatch import ( - "bytes" + "sync" ) // Pattern represents a compiled pattern. It is what is returned @@ -31,46 +31,20 @@ import ( // fmt.Println("Did not match.") // } type Pattern struct { + mutex sync.RWMutex bits []string names []string namesSet map[string]struct{} fieldTagName string } -func newPattern(target *Pattern, fieldTagName string) error { - if nil == target { - return errNilTarget +func (pattern *Pattern) MatchNames() []string { + if nil == pattern { + return nil } - bits := []string{} - names := []string{} - namesSet := map[string]struct{}{} - - target.bits = bits - target.names = names - target.namesSet = namesSet - target.fieldTagName = fieldTagName - - return nil -} - -func (pattern *Pattern) MatchNames() []string { + pattern.mutex.RLock() + defer pattern.mutex.RUnlock() return pattern.names } - -func (pattern *Pattern) Glob() string { -//@TODO: This shouldn't be executed every time! - - var buffer bytes.Buffer - - for _, bit := range pattern.bits { - if wildcardBit == bit { - buffer.WriteRune('*') - } else { - buffer.WriteString(bit) - } - } - - return buffer.String() -} diff --git a/pattern_find.go b/pattern_find.go index d3e43aa..d859260 100644 --- a/pattern_find.go +++ b/pattern_find.go @@ -13,6 +13,12 @@ var ( ) func (pattern *Pattern) Find(path string, args ...interface{}) (bool, error) { + if nil == pattern { + return false, errNilReceiver + } + + pattern.mutex.RLock() + defer pattern.mutex.RUnlock() s := path diff --git a/pattern_glob.go b/pattern_glob.go new file mode 100644 index 0000000..8b901f0 --- /dev/null +++ b/pattern_glob.go @@ -0,0 +1,28 @@ +package pathmatch + +import ( + "bytes" +) + +func (pattern *Pattern) Glob() string { + if nil == pattern { + return "" + } + + pattern.mutex.RLock() + defer pattern.mutex.RUnlock() + +//@TODO: This shouldn't be executed every time! + + var buffer bytes.Buffer + + for _, bit := range pattern.bits { + if wildcardBit == bit { + buffer.WriteRune('*') + } else { + buffer.WriteString(bit) + } + } + + return buffer.String() +} diff --git a/pattern_init.go b/pattern_init.go new file mode 100644 index 0000000..c057b82 --- /dev/null +++ b/pattern_init.go @@ -0,0 +1,16 @@ +package pathmatch + +func (receiver *Pattern) init(fieldTagName string) { + if nil == receiver { + return + } + + bits := []string{} + names := []string{} + namesSet := map[string]struct{}{} + + receiver.bits = bits + receiver.names = names + receiver.namesSet = namesSet + receiver.fieldTagName = fieldTagName +} diff --git a/pattern_load.go b/pattern_load.go index dfcc8dc..95d750c 100644 --- a/pattern_load.go +++ b/pattern_load.go @@ -15,6 +15,12 @@ var ( func (pattern *Pattern) FindAndLoad(path string, strct interface{}) (bool, error) { + if nil == pattern { + return false, errNilReceiver + } + + pattern.mutex.RLock() + defer pattern.mutex.RUnlock() //@TODO: Is it a good idea to be dynamically creating this? //@TODO: Also, can the struct fields be put in here directly instead?