mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 01:12:24 -05:00 
			
		
		
		
	[performance] update go-cache library (#1917)
* update go-cache library Signed-off-by: kim <grufwub@gmail.com> * fix broken test after cache library upgrade Signed-off-by: kim <grufwub@gmail.com> * fix the webfinger test Signed-off-by: kim <grufwub@gmail.com> --------- Signed-off-by: kim <grufwub@gmail.com>
This commit is contained in:
		
					parent
					
						
							
								831ae09f8b
							
						
					
				
			
			
				commit
				
					
						8e0043104d
					
				
			
		
					 6 changed files with 58 additions and 28 deletions
				
			
		
							
								
								
									
										2
									
								
								go.mod
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								go.mod
									
										
									
									
									
								
							|  | @ -5,7 +5,7 @@ go 1.20 | ||||||
| require ( | require ( | ||||||
| 	codeberg.org/gruf/go-bytesize v1.0.2 | 	codeberg.org/gruf/go-bytesize v1.0.2 | ||||||
| 	codeberg.org/gruf/go-byteutil v1.1.2 | 	codeberg.org/gruf/go-byteutil v1.1.2 | ||||||
| 	codeberg.org/gruf/go-cache/v3 v3.3.3 | 	codeberg.org/gruf/go-cache/v3 v3.4.1 | ||||||
| 	codeberg.org/gruf/go-debug v1.3.0 | 	codeberg.org/gruf/go-debug v1.3.0 | ||||||
| 	codeberg.org/gruf/go-errors/v2 v2.2.0 | 	codeberg.org/gruf/go-errors/v2 v2.2.0 | ||||||
| 	codeberg.org/gruf/go-fastcopy v1.1.2 | 	codeberg.org/gruf/go-fastcopy v1.1.2 | ||||||
|  |  | ||||||
							
								
								
									
										4
									
								
								go.sum
									
										
									
									
									
								
							
							
						
						
									
										4
									
								
								go.sum
									
										
									
									
									
								
							|  | @ -48,8 +48,8 @@ codeberg.org/gruf/go-bytesize v1.0.2/go.mod h1:n/GU8HzL9f3UNp/mUKyr1qVmTlj7+xacp | ||||||
| codeberg.org/gruf/go-byteutil v1.0.0/go.mod h1:cWM3tgMCroSzqoBXUXMhvxTxYJp+TbCr6ioISRY5vSU= | codeberg.org/gruf/go-byteutil v1.0.0/go.mod h1:cWM3tgMCroSzqoBXUXMhvxTxYJp+TbCr6ioISRY5vSU= | ||||||
| codeberg.org/gruf/go-byteutil v1.1.2 h1:TQLZtTxTNca9xEfDIndmo7nBYxeS94nrv/9DS3Nk5Tw= | codeberg.org/gruf/go-byteutil v1.1.2 h1:TQLZtTxTNca9xEfDIndmo7nBYxeS94nrv/9DS3Nk5Tw= | ||||||
| codeberg.org/gruf/go-byteutil v1.1.2/go.mod h1:cWM3tgMCroSzqoBXUXMhvxTxYJp+TbCr6ioISRY5vSU= | codeberg.org/gruf/go-byteutil v1.1.2/go.mod h1:cWM3tgMCroSzqoBXUXMhvxTxYJp+TbCr6ioISRY5vSU= | ||||||
| codeberg.org/gruf/go-cache/v3 v3.3.3 h1:CzOFg6JV+typ8Jst1rrYDbZjxEV7bUxKggkbfN5Y79o= | codeberg.org/gruf/go-cache/v3 v3.4.1 h1:dejl5nJC7wEsmbcU8D4EgZlo/tZgVO6iwPdrLBAa7eQ= | ||||||
| codeberg.org/gruf/go-cache/v3 v3.3.3/go.mod h1:pTeVPEb9DshXUkd8Dg76UcsLpU6EC/tXQ2qb+JrmxEc= | codeberg.org/gruf/go-cache/v3 v3.4.1/go.mod h1:pTeVPEb9DshXUkd8Dg76UcsLpU6EC/tXQ2qb+JrmxEc= | ||||||
| codeberg.org/gruf/go-debug v1.3.0 h1:PIRxQiWUFKtGOGZFdZ3Y0pqyfI0Xr87j224IYe2snZs= | codeberg.org/gruf/go-debug v1.3.0 h1:PIRxQiWUFKtGOGZFdZ3Y0pqyfI0Xr87j224IYe2snZs= | ||||||
| codeberg.org/gruf/go-debug v1.3.0/go.mod h1:N+vSy9uJBQgpQcJUqjctvqFz7tBHJf+S/PIjLILzpLg= | codeberg.org/gruf/go-debug v1.3.0/go.mod h1:N+vSy9uJBQgpQcJUqjctvqFz7tBHJf+S/PIjLILzpLg= | ||||||
| codeberg.org/gruf/go-errors/v2 v2.0.0/go.mod h1:ZRhbdhvgoUA3Yw6e56kd9Ox984RrvbEFC2pOXyHDJP4= | codeberg.org/gruf/go-errors/v2 v2.0.0/go.mod h1:ZRhbdhvgoUA3Yw6e56kd9Ox984RrvbEFC2pOXyHDJP4= | ||||||
|  |  | ||||||
|  | @ -87,11 +87,9 @@ func (suite *FingerTestSuite) TestFingerWithHostMetaCacheStrategy() { | ||||||
| 
 | 
 | ||||||
| 	// the TTL of the entry should have extended because we did a second | 	// the TTL of the entry should have extended because we did a second | ||||||
| 	// successful finger | 	// successful finger | ||||||
| 	if repeatTime.Equal(initialTime) { | 	if repeatTime == initialTime { | ||||||
| 		suite.FailNowf("expected webfinger cache entry to have different expiry times", "initial: '%s', repeat: '%s'", initialTime, repeatTime) | 		suite.FailNowf("expected webfinger cache entry to have different expiry times", "initial: '%s', repeat: '%s'", initialTime, repeatTime) | ||||||
| 	} | 	} else if repeatTime < initialTime { | ||||||
| 
 |  | ||||||
| 	if repeatTime.Before(initialTime) { |  | ||||||
| 		suite.FailNowf("expected webfinger cache entry to not be a time traveller", "initial: '%s', repeat: '%s'", initialTime, repeatTime) | 		suite.FailNowf("expected webfinger cache entry to not be a time traveller", "initial: '%s', repeat: '%s'", initialTime, repeatTime) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										16
									
								
								vendor/codeberg.org/gruf/go-cache/v3/result/cache.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										16
									
								
								vendor/codeberg.org/gruf/go-cache/v3/result/cache.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -4,6 +4,7 @@ import ( | ||||||
| 	"context" | 	"context" | ||||||
| 	"reflect" | 	"reflect" | ||||||
| 	"time" | 	"time" | ||||||
|  | 	_ "unsafe" | ||||||
| 
 | 
 | ||||||
| 	"codeberg.org/gruf/go-cache/v3/ttl" | 	"codeberg.org/gruf/go-cache/v3/ttl" | ||||||
| 	"codeberg.org/gruf/go-errors/v2" | 	"codeberg.org/gruf/go-errors/v2" | ||||||
|  | @ -385,7 +386,7 @@ func (c *Cache[Value]) store(res result[Value]) (evict func()) { | ||||||
| 
 | 
 | ||||||
| 	// Store main entry under primary key, using evict hook if needed | 	// Store main entry under primary key, using evict hook if needed | ||||||
| 	c.cache.Cache.SetWithHook(pnext, &ttl.Entry[int64, result[Value]]{ | 	c.cache.Cache.SetWithHook(pnext, &ttl.Entry[int64, result[Value]]{ | ||||||
| 		Expiry: time.Now().Add(c.cache.TTL), | 		Expiry: c.expiry(), | ||||||
| 		Key:    pnext, | 		Key:    pnext, | ||||||
| 		Value:  res, | 		Value:  res, | ||||||
| 	}, func(_ int64, item *ttl.Entry[int64, result[Value]]) { | 	}, func(_ int64, item *ttl.Entry[int64, result[Value]]) { | ||||||
|  | @ -395,6 +396,19 @@ func (c *Cache[Value]) store(res result[Value]) (evict func()) { | ||||||
| 	return evict | 	return evict | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | //go:linkname runtime_nanotime runtime.nanotime | ||||||
|  | func runtime_nanotime() uint64 | ||||||
|  | 
 | ||||||
|  | // expiry returns an the next expiry time to use for an entry, | ||||||
|  | // which is equivalent to time.Now().Add(ttl), or zero if disabled. | ||||||
|  | func (c *Cache[Value]) expiry() uint64 { | ||||||
|  | 	if ttl := c.cache.TTL; ttl > 0 { | ||||||
|  | 		return runtime_nanotime() + | ||||||
|  | 			uint64(c.cache.TTL) | ||||||
|  | 	} | ||||||
|  | 	return 0 | ||||||
|  | } | ||||||
|  | 
 | ||||||
| type result[Value any] struct { | type result[Value any] struct { | ||||||
| 	// keys accessible under | 	// keys accessible under | ||||||
| 	Keys cacheKeys | 	Keys cacheKeys | ||||||
|  |  | ||||||
							
								
								
									
										56
									
								
								vendor/codeberg.org/gruf/go-cache/v3/ttl/ttl.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										56
									
								
								vendor/codeberg.org/gruf/go-cache/v3/ttl/ttl.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -3,6 +3,7 @@ package ttl | ||||||
| import ( | import ( | ||||||
| 	"sync" | 	"sync" | ||||||
| 	"time" | 	"time" | ||||||
|  | 	_ "unsafe" | ||||||
| 
 | 
 | ||||||
| 	"codeberg.org/gruf/go-maps" | 	"codeberg.org/gruf/go-maps" | ||||||
| ) | ) | ||||||
|  | @ -11,7 +12,7 @@ import ( | ||||||
| type Entry[Key comparable, Value any] struct { | type Entry[Key comparable, Value any] struct { | ||||||
| 	Key    Key | 	Key    Key | ||||||
| 	Value  Value | 	Value  Value | ||||||
| 	Expiry time.Time | 	Expiry uint64 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Cache is the underlying Cache implementation, providing both the base Cache interface and unsafe access to underlying map to allow flexibility in building your own. | // Cache is the underlying Cache implementation, providing both the base Cache interface and unsafe access to underlying map to allow flexibility in building your own. | ||||||
|  | @ -67,7 +68,7 @@ func (c *Cache[K, V]) Start(freq time.Duration) (ok bool) { | ||||||
| 	// Safely start | 	// Safely start | ||||||
| 	c.Lock() | 	c.Lock() | ||||||
| 
 | 
 | ||||||
| 	if ok = c.stop == nil; ok { | 	if ok = (c.stop == nil); ok { | ||||||
| 		// Not yet running, schedule us | 		// Not yet running, schedule us | ||||||
| 		c.stop = schedule(c.Sweep, freq) | 		c.stop = schedule(c.Sweep, freq) | ||||||
| 	} | 	} | ||||||
|  | @ -83,7 +84,7 @@ func (c *Cache[K, V]) Stop() (ok bool) { | ||||||
| 	// Safely stop | 	// Safely stop | ||||||
| 	c.Lock() | 	c.Lock() | ||||||
| 
 | 
 | ||||||
| 	if ok = c.stop != nil; ok { | 	if ok = (c.stop != nil); ok { | ||||||
| 		// We're running, cancel evicts | 		// We're running, cancel evicts | ||||||
| 		c.stop() | 		c.stop() | ||||||
| 		c.stop = nil | 		c.stop = nil | ||||||
|  | @ -96,23 +97,32 @@ func (c *Cache[K, V]) Stop() (ok bool) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Sweep attempts to evict expired items (with callback!) from cache. | // Sweep attempts to evict expired items (with callback!) from cache. | ||||||
| func (c *Cache[K, V]) Sweep(now time.Time) { | func (c *Cache[K, V]) Sweep(_ time.Time) { | ||||||
| 	var ( | 	var ( | ||||||
| 		// evicted key-values. | 		// evicted key-values. | ||||||
| 		kvs []kv[K, V] | 		kvs []kv[K, V] | ||||||
| 
 | 
 | ||||||
| 		// hook func ptrs. | 		// hook func ptrs. | ||||||
| 		evict func(K, V) | 		evict func(K, V) | ||||||
|  | 
 | ||||||
|  | 		// get current nanoseconds. | ||||||
|  | 		now = runtime_nanotime() | ||||||
| 	) | 	) | ||||||
| 
 | 
 | ||||||
| 	c.locked(func() { | 	c.locked(func() { | ||||||
|  | 		if c.TTL <= 0 { | ||||||
|  | 			// sweep is | ||||||
|  | 			// disabled | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		// Sentinel value | 		// Sentinel value | ||||||
| 		after := -1 | 		after := -1 | ||||||
| 
 | 
 | ||||||
| 		// The cache will be ordered by expiry date, we iterate until we reach the index of | 		// The cache will be ordered by expiry date, we iterate until we reach the index of | ||||||
| 		// the youngest item that hsa expired, as all succeeding items will also be expired. | 		// the youngest item that hsa expired, as all succeeding items will also be expired. | ||||||
| 		c.Cache.RangeIf(0, c.Cache.Len(), func(i int, _ K, item *Entry[K, V]) bool { | 		c.Cache.RangeIf(0, c.Cache.Len(), func(i int, _ K, item *Entry[K, V]) bool { | ||||||
| 			if now.After(item.Expiry) { | 			if now > item.Expiry { | ||||||
| 				after = i | 				after = i | ||||||
| 
 | 
 | ||||||
| 				// evict all older items | 				// evict all older items | ||||||
|  | @ -161,10 +171,6 @@ func (c *Cache[K, V]) SetInvalidateCallback(hook func(K, V)) { | ||||||
| 
 | 
 | ||||||
| // SetTTL: implements cache.Cache's SetTTL(). | // SetTTL: implements cache.Cache's SetTTL(). | ||||||
| func (c *Cache[K, V]) SetTTL(ttl time.Duration, update bool) { | func (c *Cache[K, V]) SetTTL(ttl time.Duration, update bool) { | ||||||
| 	if ttl < 0 { |  | ||||||
| 		panic("ttl must be greater than zero") |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	c.locked(func() { | 	c.locked(func() { | ||||||
| 		// Set updated TTL | 		// Set updated TTL | ||||||
| 		diff := ttl - c.TTL | 		diff := ttl - c.TTL | ||||||
|  | @ -173,7 +179,7 @@ func (c *Cache[K, V]) SetTTL(ttl time.Duration, update bool) { | ||||||
| 		if update { | 		if update { | ||||||
| 			// Update existing cache entries with new expiry time | 			// Update existing cache entries with new expiry time | ||||||
| 			c.Cache.Range(0, c.Cache.Len(), func(i int, _ K, item *Entry[K, V]) { | 			c.Cache.Range(0, c.Cache.Len(), func(i int, _ K, item *Entry[K, V]) { | ||||||
| 				item.Expiry = item.Expiry.Add(diff) | 				item.Expiry += uint64(diff) | ||||||
| 			}) | 			}) | ||||||
| 		} | 		} | ||||||
| 	}) | 	}) | ||||||
|  | @ -198,8 +204,8 @@ func (c *Cache[K, V]) Get(key K) (V, bool) { | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		// Update fetched item's expiry | 		// Update fetched's expiry | ||||||
| 		item.Expiry = time.Now().Add(c.TTL) | 		item.Expiry = c.expiry() | ||||||
| 
 | 
 | ||||||
| 		// Set value. | 		// Set value. | ||||||
| 		v = item.Value | 		v = item.Value | ||||||
|  | @ -234,7 +240,7 @@ func (c *Cache[K, V]) Add(key K, value V) bool { | ||||||
| 
 | 
 | ||||||
| 		// Alloc new entry. | 		// Alloc new entry. | ||||||
| 		new := c.alloc() | 		new := c.alloc() | ||||||
| 		new.Expiry = time.Now().Add(c.TTL) | 		new.Expiry = c.expiry() | ||||||
| 		new.Key = key | 		new.Key = key | ||||||
| 		new.Value = value | 		new.Value = value | ||||||
| 
 | 
 | ||||||
|  | @ -290,12 +296,12 @@ func (c *Cache[K, V]) Set(key K, value V) { | ||||||
| 			oldV = item.Value | 			oldV = item.Value | ||||||
| 
 | 
 | ||||||
| 			// Update the existing item. | 			// Update the existing item. | ||||||
| 			item.Expiry = time.Now().Add(c.TTL) | 			item.Expiry = c.expiry() | ||||||
| 			item.Value = value | 			item.Value = value | ||||||
| 		} else { | 		} else { | ||||||
| 			// Alloc new entry. | 			// Alloc new entry. | ||||||
| 			new := c.alloc() | 			new := c.alloc() | ||||||
| 			new.Expiry = time.Now().Add(c.TTL) | 			new.Expiry = c.expiry() | ||||||
| 			new.Key = key | 			new.Key = key | ||||||
| 			new.Value = value | 			new.Value = value | ||||||
| 
 | 
 | ||||||
|  | @ -355,7 +361,7 @@ func (c *Cache[K, V]) CAS(key K, old V, new V, cmp func(V, V) bool) bool { | ||||||
| 		oldV = item.Value | 		oldV = item.Value | ||||||
| 
 | 
 | ||||||
| 		// Update value + expiry. | 		// Update value + expiry. | ||||||
| 		item.Expiry = time.Now().Add(c.TTL) | 		item.Expiry = c.expiry() | ||||||
| 		item.Value = new | 		item.Value = new | ||||||
| 
 | 
 | ||||||
| 		// Set hook func ptr. | 		// Set hook func ptr. | ||||||
|  | @ -396,7 +402,7 @@ func (c *Cache[K, V]) Swap(key K, swp V) V { | ||||||
| 		oldV = item.Value | 		oldV = item.Value | ||||||
| 
 | 
 | ||||||
| 		// Update value + expiry. | 		// Update value + expiry. | ||||||
| 		item.Expiry = time.Now().Add(c.TTL) | 		item.Expiry = c.expiry() | ||||||
| 		item.Value = swp | 		item.Value = swp | ||||||
| 
 | 
 | ||||||
| 		// Set hook func ptr. | 		// Set hook func ptr. | ||||||
|  | @ -603,14 +609,26 @@ func (c *Cache[K, V]) free(e *Entry[K, V]) { | ||||||
| 	var ( | 	var ( | ||||||
| 		zk K | 		zk K | ||||||
| 		zv V | 		zv V | ||||||
| 		zt time.Time |  | ||||||
| 	) | 	) | ||||||
| 	e.Expiry = zt | 	e.Expiry = 0 | ||||||
| 	e.Key = zk | 	e.Key = zk | ||||||
| 	e.Value = zv | 	e.Value = zv | ||||||
| 	c.pool = append(c.pool, e) | 	c.pool = append(c.pool, e) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | //go:linkname runtime_nanotime runtime.nanotime | ||||||
|  | func runtime_nanotime() uint64 | ||||||
|  | 
 | ||||||
|  | // expiry returns an the next expiry time to use for an entry, | ||||||
|  | // which is equivalent to time.Now().Add(ttl), or zero if disabled. | ||||||
|  | func (c *Cache[K, V]) expiry() uint64 { | ||||||
|  | 	if ttl := c.TTL; ttl > 0 { | ||||||
|  | 		return runtime_nanotime() + | ||||||
|  | 			uint64(c.TTL) | ||||||
|  | 	} | ||||||
|  | 	return 0 | ||||||
|  | } | ||||||
|  | 
 | ||||||
| type kv[K comparable, V any] struct { | type kv[K comparable, V any] struct { | ||||||
| 	K K | 	K K | ||||||
| 	V V | 	V V | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								vendor/modules.txt
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/modules.txt
									
										
									
									
										vendored
									
									
								
							|  | @ -13,7 +13,7 @@ codeberg.org/gruf/go-bytesize | ||||||
| # codeberg.org/gruf/go-byteutil v1.1.2 | # codeberg.org/gruf/go-byteutil v1.1.2 | ||||||
| ## explicit; go 1.16 | ## explicit; go 1.16 | ||||||
| codeberg.org/gruf/go-byteutil | codeberg.org/gruf/go-byteutil | ||||||
| # codeberg.org/gruf/go-cache/v3 v3.3.3 | # codeberg.org/gruf/go-cache/v3 v3.4.1 | ||||||
| ## explicit; go 1.19 | ## explicit; go 1.19 | ||||||
| codeberg.org/gruf/go-cache/v3 | codeberg.org/gruf/go-cache/v3 | ||||||
| codeberg.org/gruf/go-cache/v3/result | codeberg.org/gruf/go-cache/v3/result | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue