From 573316e3c2ddd91fd0f36d2251f9660b4f98bebc Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Sun, 8 Jan 2023 23:48:37 -0700 Subject: binstruct: Make the cache thread-safe --- lib/binstruct/structs.go | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) (limited to 'lib/binstruct/structs.go') diff --git a/lib/binstruct/structs.go b/lib/binstruct/structs.go index 7eea600..52e5406 100644 --- a/lib/binstruct/structs.go +++ b/lib/binstruct/structs.go @@ -10,6 +10,8 @@ import ( "strconv" "strings" + "git.lukeshu.com/go/typedsync" + "git.lukeshu.com/btrfs-progs-ng/lib/binstruct/binutil" ) @@ -178,21 +180,18 @@ func genStructHandler(structInfo reflect.Type) (structHandler, error) { return ret, nil } -var structCache = make(map[reflect.Type]structHandler) +var structCache typedsync.CacheMap[reflect.Type, structHandler] func getStructHandler(typ reflect.Type) structHandler { - h, ok := structCache[typ] - if ok { + ret, _ := structCache.LoadOrCompute(typ, func(typ reflect.Type) structHandler { + h, err := genStructHandler(typ) + if err != nil { + panic(&InvalidTypeError{ + Type: typ, + Err: err, + }) + } return h - } - - h, err := genStructHandler(typ) - if err != nil { - panic(&InvalidTypeError{ - Type: typ, - Err: err, - }) - } - structCache[typ] = h - return h + }) + return ret } -- cgit v1.2.3-2-g168b From 4f05919a0f2695934df2e67399b507896b52c3bc Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Mon, 9 Jan 2023 03:05:50 -0700 Subject: binstruct: Optimize based on the CPU profiler when running scandevices --- lib/binstruct/structs.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'lib/binstruct/structs.go') diff --git a/lib/binstruct/structs.go b/lib/binstruct/structs.go index 52e5406..91bfec7 100644 --- a/lib/binstruct/structs.go +++ b/lib/binstruct/structs.go @@ -69,7 +69,8 @@ type structHandler struct { } type structField struct { - name string + name string + isUnmarshaler bool tag } @@ -82,7 +83,7 @@ func (sh structHandler) Unmarshal(dat []byte, dst reflect.Value) (int, error) { if field.skip { continue } - _n, err := Unmarshal(dat[n:], dst.Field(i).Addr().Interface()) + _n, err := unmarshal(dat[n:], dst.Field(i), field.isUnmarshaler) if err != nil { if _n >= 0 { n += _n @@ -166,8 +167,9 @@ func genStructHandler(structInfo reflect.Type) (structHandler, error) { curOffset += fieldTag.siz ret.fields = append(ret.fields, structField{ - name: fieldInfo.Name, - tag: fieldTag, + name: fieldInfo.Name, + isUnmarshaler: reflect.PtrTo(fieldInfo.Type).Implements(unmarshalerType), + tag: fieldTag, }) } ret.Size = curOffset -- cgit v1.2.3-2-g168b