github.com/haraldrudell/parl@v0.4.176/pruntime/cached-location.go (about)

     1  /*
     2  © 2021–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/)
     3  ISC License
     4  */
     5  
     6  package pruntime
     7  
     8  const (
     9  	// counts public CachedLocation method, [CachedLocation.get], [CacheMechanic.EnsureInit]
    10  	// [CachedLocation.init]
    11  	cachedLocationFrames = 4
    12  )
    13  
    14  // CachedLocation caches the code location and performantly provides it in string formats. Thread-safe
    15  //   - one top-level CachedLocation variable is required for each code location
    16  //   - code line provided is the location of first getter method
    17  //   - caching saves 1,003 ns, ie. 0.85 parallel mutex Lock/Unlock
    18  //   - cannot use sync.Once.Do because number of frames it consumes is unknown
    19  //   - initialization-free, thread-safe
    20  //
    21  // usage:
    22  //
    23  //	var mycl pruntime.CachedLocation
    24  //	func f() {
    25  //	  println(mycl.PackFunc())
    26  type CachedLocation struct {
    27  	m CacheMechanic
    28  	// payload values written inside lock
    29  	packFunc, short, funcName, funcIdentifier string
    30  }
    31  
    32  // "mains.AddErr" Thread-safe
    33  //   - similar to [perrors.NewPF] or [perrors.ErrorfPF]
    34  func (c *CachedLocation) PackFunc() (packFunc string) { return c.get().packFunc }
    35  
    36  // "myFunc" Thread-safe
    37  func (c *CachedLocation) FuncIdentifier() (funcIdentifier string) { return c.get().funcIdentifier }
    38  
    39  // "mains.(*Executable).AddErr-executable.go:25" Thread-safe
    40  //   - similar to [perrors.Short] location
    41  func (c *CachedLocation) Short() (location string) { return c.get().short }
    42  
    43  // "github.com/haraldrudell/parl/mains.(*Executable).AddErr" Thread-safe
    44  //   - FuncName is the value compared to by [parl.SetRegexp]
    45  func (c *CachedLocation) FuncName() (location string) { return c.get().funcName }
    46  
    47  // get ensures data is loaded exactly once
    48  func (c *CachedLocation) get() (c2 *CachedLocation) {
    49  	c.m.EnsureInit(c.init)
    50  	return c
    51  }
    52  
    53  // init is invoked on the very first invocation inside lock
    54  func (c *CachedLocation) init() {
    55  	var codeLocation = NewCodeLocation(cachedLocationFrames)
    56  	c.packFunc = codeLocation.PackFunc()
    57  	c.short = codeLocation.Short()
    58  	c.funcName = codeLocation.FuncName
    59  	c.funcIdentifier = codeLocation.FuncIdentifier()
    60  }