diff --git a/immcheck.go b/immcheck.go index b9744fe..3abd395 100644 --- a/immcheck.go +++ b/immcheck.go @@ -379,7 +379,7 @@ var mapIterPool = &sync.Pool{New: func() interface{} { return &reflect.MapIter{} const maxPoolCacheSizePerGoroutine = 1024 //nolint:gochecknoglobals // reflectValuePoolCache is global to maximise pools re-use -var reflectValuePoolCache = NewPCache(maxPoolCacheSizePerGoroutine) +var reflectValuePoolCache = newPCache(maxPoolCacheSizePerGoroutine) func perEntrySnapshot(snapshot *ValueSnapshot, value reflect.Value, options Options) *ValueSnapshot { iterator := mapIterPool.Get().(*reflect.MapIter) @@ -391,17 +391,9 @@ func perEntrySnapshot(snapshot *ValueSnapshot, value reflect.Value, options Opti mapType := value.Type() mapKeyType := mapType.Key() - mapKeyTypeName := typeName{ - path: mapKeyType.PkgPath(), - name: mapKeyType.Name(), - } mapValueType := mapType.Elem() - mapValueTypeName := typeName{ - path: mapValueType.PkgPath(), - name: mapValueType.Name(), - } - keyProvider, ok := reflectValuePoolCache.Load(mapKeyTypeName) + keyProvider, ok := reflectValuePoolCache.load(mapKeyType) if !ok { keyProvider = &sync.Pool{ New: func() interface{} { @@ -410,12 +402,12 @@ func perEntrySnapshot(snapshot *ValueSnapshot, value reflect.Value, options Opti }, } } - defer reflectValuePoolCache.Store(mapKeyTypeName, keyProvider) + defer reflectValuePoolCache.store(mapKeyType, keyProvider) keyPool := keyProvider.(*sync.Pool) k := keyPool.Get().(*reflect.Value) defer keyPool.Put(k) - valueProvider, ok := reflectValuePoolCache.Load(mapValueTypeName) + valueProvider, ok := reflectValuePoolCache.load(mapValueType) if !ok { valueProvider = &sync.Pool{ New: func() interface{} { @@ -424,7 +416,7 @@ func perEntrySnapshot(snapshot *ValueSnapshot, value reflect.Value, options Opti }, } } - defer reflectValuePoolCache.Store(mapValueTypeName, valueProvider) + defer reflectValuePoolCache.store(mapValueType, valueProvider) valuePool := valueProvider.(*sync.Pool) v := valuePool.Get().(*reflect.Value) defer valuePool.Put(v) diff --git a/immcheck_test.go b/immcheck_test.go index 993a3b6..051a535 100644 --- a/immcheck_test.go +++ b/immcheck_test.go @@ -809,6 +809,12 @@ func expectPanic(t *testing.T, f func(), expectedError error) string { defer func() { actualPanic = recover() if expectedError != nil { + if actualPanic == nil { + t.Fatalf( + "expected error didn't happen. expected %T(%v)", + expectedError, expectedError, + ) + } if !errors.Is(actualPanic.(error), expectedError) { t.Fatalf( "unexpected error type. expected %T(%v); actual: %T(%v)", diff --git a/pcache.go b/pcache.go index 768773d..82bd40b 100644 --- a/pcache.go +++ b/pcache.go @@ -1,15 +1,11 @@ package immcheck import ( + "reflect" "sync" ) -type typeName struct { - path string - name string -} - -type cache map[typeName]interface{} +type cache map[reflect.Type]interface{} type cacheStripe struct { cache cache @@ -27,20 +23,20 @@ type cacheStripe struct { // // All operations run in amortized constant time. // PCache does its best to cache items inside and do as little synchronization as possible -// but since it is cache, there is no guarantee that PCache won't evict your item after Store. +// but since it is cache, there is no guarantee that PCache won't evict your item after store. // // PCache evicts random items if I goroutine local cache achieves maxSizePerGoroutine size. // PCache cleans itself entirely from time to time. // // The zero PCache is invalid. Use NewPCache method to create PCache. -type PCache struct { +type pCache struct { maxSize int pool *sync.Pool } -// NewPCache creates PCache with maxSizePerGoroutine. -func NewPCache(maxSizePerGoroutine uint) *PCache { - return &PCache{ +// newPCache creates PCache with maxSizePerGoroutine. +func newPCache(maxSizePerGoroutine uint) *pCache { + return &pCache{ maxSize: int(maxSizePerGoroutine), pool: &sync.Pool{ New: func() interface{} { @@ -52,16 +48,16 @@ func NewPCache(maxSizePerGoroutine uint) *PCache { } } -// Load fetches (value, true) from cache associated with key or (nil, false) if it is not present. -func (p *PCache) Load(key typeName) (interface{}, bool) { +// load fetches (value, true) from cache associated with key or (nil, false) if it is not present. +func (p *pCache) load(key reflect.Type) (interface{}, bool) { stripe := p.pool.Get().(*cacheStripe) defer p.pool.Put(stripe) value, ok := stripe.cache[key] return value, ok } -// Store stores value for a key in cache. -func (p *PCache) Store(key typeName, value interface{}) { +// store stores value for a key in cache. +func (p *pCache) store(key reflect.Type, value interface{}) { stripe := p.pool.Get().(*cacheStripe) defer p.pool.Put(stripe)