diff --git a/README.md b/README.md index b5c135525..14f309be5 100644 --- a/README.md +++ b/README.md @@ -224,6 +224,7 @@ The following open source libraries, frameworks, and tools are used by GoToSocia - [buckket/go-blurhash](https://github.com/buckket/go-blurhash); used for generating image blurhashes. [GPL-3.0 License](https://spdx.org/licenses/GPL-3.0-only.html). - [coreos/go-oidc](https://github.com/coreos/go-oidc); OIDC client library. [Apache-2.0 License](https://spdx.org/licenses/Apache-2.0.html). - [disintegration/imaging](https://github.com/disintegration/imaging); image resizing. [MIT License](https://spdx.org/licenses/MIT.html). +- [DmitriyVTitov/size](https://github.com/DmitriyVTitov/size); runtime model memory size calculations. [MIT License](https://spdx.org/licenses/MIT.html). - Gin: - [gin-contrib/cors](https://github.com/gin-contrib/cors); Gin CORS middleware. [MIT License](https://spdx.org/licenses/MIT.html). - [gin-contrib/gzip](https://github.com/gin-contrib/gzip); Gin gzip middleware. [MIT License](https://spdx.org/licenses/MIT.html). diff --git a/cmd/gotosocial/action/server/server.go b/cmd/gotosocial/action/server/server.go index ad1fe5763..8dd6a026d 100644 --- a/cmd/gotosocial/action/server/server.go +++ b/cmd/gotosocial/action/server/server.go @@ -25,7 +25,9 @@ "os" "os/signal" "syscall" + "time" + "codeberg.org/gruf/go-sched" "github.com/gin-gonic/gin" "github.com/superseriousbusiness/gotosocial/cmd/gotosocial/action" "github.com/superseriousbusiness/gotosocial/internal/api" @@ -117,6 +119,13 @@ state.Workers.Start() defer state.Workers.Stop() + // Add a task to the scheduler to sweep caches. + // Frequency = 1 * minute + // Threshold = 80% capacity + sweep := func(time.Time) { state.Caches.Sweep(80) } + job := sched.NewJob(sweep).Every(time.Minute) + _ = state.Workers.Scheduler.Schedule(job) + // Build handlers used in later initializations. mediaManager := media.NewManager(&state) oauthServer := oauth.New(ctx, dbService) diff --git a/example/config.yaml b/example/config.yaml index b09561470..ddcea38d4 100644 --- a/example/config.yaml +++ b/example/config.yaml @@ -231,111 +231,13 @@ db-sqlite-cache-size: "8MiB" db-sqlite-busy-timeout: "30m" cache: - # Cache configuration options: - # - # max-size = maximum cached objects count - # ttl = cached object lifetime - # sweep-freq = frequency to look for stale cache objects - # (zero will disable cache sweeping) - - ############################# - #### VISIBILITY CACHES ###### - ############################# - # - # Configure Status and account - # visibility cache. - - visibility-max-size: 2000 - visibility-ttl: "30m" - visibility-sweep-freq: "1m" - - gts: - ########################### - #### DATABASE CACHES ###### - ########################### - # - # Configure GTS database - # model caches. - - account-max-size: 2000 - account-ttl: "30m" - account-sweep-freq: "1m" - - block-max-size: 1000 - block-ttl: "30m" - block-sweep-freq: "1m" - - domain-block-max-size: 2000 - domain-block-ttl: "24h" - domain-block-sweep-freq: "1m" - - emoji-max-size: 2000 - emoji-ttl: "30m" - emoji-sweep-freq: "1m" - - emoji-category-max-size: 100 - emoji-category-ttl: "30m" - emoji-category-sweep-freq: "1m" - - follow-max-size: 2000 - follow-ttl: "30m" - follow-sweep-freq: "1m" - - follow-request-max-size: 2000 - follow-request-ttl: "30m" - follow-request-sweep-freq: "1m" - - instance-max-size: 2000 - instance-ttl: "30m" - instance-sweep-freq: "1m" - - list-max-size: 2000 - list-ttl: "30m" - list-sweep-freq: "1m" - - list-entry-max-size: 2000 - list-entry-ttl: "30m" - list-entry-sweep-freq: "1m" - - media-max-size: 1000 - media-ttl: "30m" - media-sweep-freq: "1m" - - mention-max-size: 2000 - mention-ttl: "30m" - mention-sweep-freq: "1m" - - notification-max-size: 1000 - notification-ttl: "30m" - notification-sweep-freq: "1m" - - report-max-size: 100 - report-ttl: "30m" - report-sweep-freq: "1m" - - status-max-size: 2000 - status-ttl: "30m" - status-sweep-freq: "1m" - - status-fave-max-size: 2000 - status-fave-ttl: "30m" - status-fave-sweep-freq: "1m" - - tag-max-size: 2000 - tag-ttl: "30m" - tag-sweep-freq: "1m" - - tombstone-max-size: 500 - tombstone-ttl: "30m" - tombstone-sweep-freq: "1m" - - user-max-size: 500 - user-ttl: "30m" - user-sweep-freq: "1m" - - webfinger-max-size: 250 - webfinger-ttl: "24h" - webfinger-sweep-freq: "15m" + # cache.memory-target sets a target limit that + # the application will try to keep it's caches + # within. This is based on estimated sizes of + # in-memory objects, and so NOT AT ALL EXACT. + # Examples: ["100MiB", "200MiB", "500MiB", "1GiB"] + # Default: "200MiB" + memory-target: "200MiB" ###################### ##### WEB CONFIG ##### diff --git a/go.mod b/go.mod index 98abc64ee..0b8021710 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.20 require ( codeberg.org/gruf/go-bytesize v1.0.2 codeberg.org/gruf/go-byteutil v1.1.2 - codeberg.org/gruf/go-cache/v3 v3.4.4 + codeberg.org/gruf/go-cache/v3 v3.5.3 codeberg.org/gruf/go-debug v1.3.0 codeberg.org/gruf/go-errors/v2 v2.2.0 codeberg.org/gruf/go-fastcopy v1.1.2 @@ -16,6 +16,7 @@ require ( codeberg.org/gruf/go-runners v1.6.1 codeberg.org/gruf/go-sched v1.2.3 codeberg.org/gruf/go-store/v2 v2.2.2 + github.com/DmitriyVTitov/size v1.5.0 github.com/KimMachineGun/automemlimit v0.2.6 github.com/abema/go-mp4 v0.11.0 github.com/buckket/go-blurhash v1.1.0 diff --git a/go.sum b/go.sum index 19964f9f1..6a5bce0ee 100644 --- a/go.sum +++ b/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.1.2 h1:TQLZtTxTNca9xEfDIndmo7nBYxeS94nrv/9DS3Nk5Tw= codeberg.org/gruf/go-byteutil v1.1.2/go.mod h1:cWM3tgMCroSzqoBXUXMhvxTxYJp+TbCr6ioISRY5vSU= -codeberg.org/gruf/go-cache/v3 v3.4.4 h1:V0A3EzjhzhULOydD16pwa2DRDwF67OuuP4ORnm//7p8= -codeberg.org/gruf/go-cache/v3 v3.4.4/go.mod h1:pTeVPEb9DshXUkd8Dg76UcsLpU6EC/tXQ2qb+JrmxEc= +codeberg.org/gruf/go-cache/v3 v3.5.3 h1:CRO2syVQxT/JbqDnUxzjeJkLInihEmTlJOkrOgkTmqI= +codeberg.org/gruf/go-cache/v3 v3.5.3/go.mod h1:NbsGQUgEdNFd631WSasvCHIVAaY9ovuiSeoBwtsIeDc= 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-errors/v2 v2.0.0/go.mod h1:ZRhbdhvgoUA3Yw6e56kd9Ox984RrvbEFC2pOXyHDJP4= @@ -87,6 +87,8 @@ codeberg.org/gruf/go-store/v2 v2.2.2/go.mod h1:QRM3LUAfYyoGMWLTqA1WzohxQgYqPFiVv dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/DmitriyVTitov/size v1.5.0 h1:/PzqxYrOyOUX1BXj6J9OuVRVGe+66VL4D9FlUaW515g= +github.com/DmitriyVTitov/size v1.5.0/go.mod h1:le6rNI4CoLQV1b9gzp1+3d7hMAD/uu2QcJ+aYbNgiU0= github.com/KimMachineGun/automemlimit v0.2.6 h1:tQFriVTcIteUkV5EgU9iz03eDY36T8JU5RAjP2r6Kt0= github.com/KimMachineGun/automemlimit v0.2.6/go.mod h1:pJhTW/nWJMj6SnWSU2TEKSlCaM+1N5Mej+IfS/5/Ol0= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= @@ -256,6 +258,8 @@ github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= diff --git a/internal/cache/cache.go b/internal/cache/cache.go index e97dce6f9..cb5503a84 100644 --- a/internal/cache/cache.go +++ b/internal/cache/cache.go @@ -204,3 +204,36 @@ func (c *Caches) setuphooks() { c.Visibility.Invalidate("RequesterID", user.AccountID) }) } + +// Sweep will sweep all the available caches to ensure none +// are above threshold percent full to their total capacity. +// +// This helps with cache performance, as a full cache will +// require an eviction on every single write, which adds +// significant overhead to all cache writes. +func (c *Caches) Sweep(threshold float64) { + c.GTS.Account().Trim(threshold) + c.GTS.AccountNote().Trim(threshold) + c.GTS.Block().Trim(threshold) + c.GTS.BlockIDs().Trim(threshold) + c.GTS.Emoji().Trim(threshold) + c.GTS.EmojiCategory().Trim(threshold) + c.GTS.Follow().Trim(threshold) + c.GTS.FollowIDs().Trim(threshold) + c.GTS.FollowRequest().Trim(threshold) + c.GTS.FollowRequestIDs().Trim(threshold) + c.GTS.Instance().Trim(threshold) + c.GTS.List().Trim(threshold) + c.GTS.ListEntry().Trim(threshold) + c.GTS.Marker().Trim(threshold) + c.GTS.Media().Trim(threshold) + c.GTS.Mention().Trim(threshold) + c.GTS.Notification().Trim(threshold) + c.GTS.Report().Trim(threshold) + c.GTS.Status().Trim(threshold) + c.GTS.StatusFave().Trim(threshold) + c.GTS.Tag().Trim(threshold) + c.GTS.Tombstone().Trim(threshold) + c.GTS.User().Trim(threshold) + c.Visibility.Trim(threshold) +} diff --git a/internal/cache/gts.go b/internal/cache/gts.go index 6014d13d4..3f54d5c52 100644 --- a/internal/cache/gts.go +++ b/internal/cache/gts.go @@ -18,11 +18,15 @@ package cache import ( + "time" + "codeberg.org/gruf/go-cache/v3/result" + "codeberg.org/gruf/go-cache/v3/simple" "codeberg.org/gruf/go-cache/v3/ttl" "github.com/superseriousbusiness/gotosocial/internal/cache/domain" "github.com/superseriousbusiness/gotosocial/internal/config" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" + "github.com/superseriousbusiness/gotosocial/internal/log" ) type GTSCaches struct { @@ -52,7 +56,7 @@ type GTSCaches struct { user *result.Cache[*gtsmodel.User] // TODO: move out of GTS caches since unrelated to DB. - webfinger *ttl.Cache[string, string] + webfinger *ttl.Cache[string, string] // TTL=24hr, sweep=5min } // Init will initialize all the gtsmodel caches in this collection. @@ -87,98 +91,14 @@ func (c *GTSCaches) Init() { // Start will attempt to start all of the gtsmodel caches, or panic. func (c *GTSCaches) Start() { - tryStart(c.account, config.GetCacheGTSAccountSweepFreq()) - tryStart(c.accountNote, config.GetCacheGTSAccountNoteSweepFreq()) - tryStart(c.block, config.GetCacheGTSBlockSweepFreq()) - tryUntil("starting block IDs cache", 5, func() bool { - if sweep := config.GetCacheGTSBlockIDsSweepFreq(); sweep > 0 { - return c.blockIDs.Start(sweep) - } - return true - }) - tryStart(c.emoji, config.GetCacheGTSEmojiSweepFreq()) - tryStart(c.emojiCategory, config.GetCacheGTSEmojiCategorySweepFreq()) - tryStart(c.follow, config.GetCacheGTSFollowSweepFreq()) - tryUntil("starting follow IDs cache", 5, func() bool { - if sweep := config.GetCacheGTSFollowIDsSweepFreq(); sweep > 0 { - return c.followIDs.Start(sweep) - } - return true - }) - tryStart(c.followRequest, config.GetCacheGTSFollowRequestSweepFreq()) - tryUntil("starting follow request IDs cache", 5, func() bool { - if sweep := config.GetCacheGTSFollowRequestIDsSweepFreq(); sweep > 0 { - return c.followRequestIDs.Start(sweep) - } - return true - }) - tryStart(c.instance, config.GetCacheGTSInstanceSweepFreq()) - tryStart(c.list, config.GetCacheGTSListSweepFreq()) - tryStart(c.listEntry, config.GetCacheGTSListEntrySweepFreq()) - tryStart(c.marker, config.GetCacheGTSMarkerSweepFreq()) - tryStart(c.media, config.GetCacheGTSMediaSweepFreq()) - tryStart(c.mention, config.GetCacheGTSMentionSweepFreq()) - tryStart(c.notification, config.GetCacheGTSNotificationSweepFreq()) - tryStart(c.report, config.GetCacheGTSReportSweepFreq()) - tryStart(c.status, config.GetCacheGTSStatusSweepFreq()) - tryStart(c.statusFave, config.GetCacheGTSStatusFaveSweepFreq()) - tryStart(c.tag, config.GetCacheGTSTagSweepFreq()) - tryStart(c.tombstone, config.GetCacheGTSTombstoneSweepFreq()) - tryStart(c.user, config.GetCacheGTSUserSweepFreq()) tryUntil("starting *gtsmodel.Webfinger cache", 5, func() bool { - if sweep := config.GetCacheGTSWebfingerSweepFreq(); sweep > 0 { - return c.webfinger.Start(sweep) - } - return true + return c.webfinger.Start(5 * time.Minute) }) } // Stop will attempt to stop all of the gtsmodel caches, or panic. func (c *GTSCaches) Stop() { - tryStop(c.account, config.GetCacheGTSAccountSweepFreq()) - tryStop(c.accountNote, config.GetCacheGTSAccountNoteSweepFreq()) - tryStop(c.block, config.GetCacheGTSBlockSweepFreq()) - tryUntil("stopping block IDs cache", 5, func() bool { - if config.GetCacheGTSBlockIDsSweepFreq() > 0 { - return c.blockIDs.Stop() - } - return true - }) - tryStop(c.emoji, config.GetCacheGTSEmojiSweepFreq()) - tryStop(c.emojiCategory, config.GetCacheGTSEmojiCategorySweepFreq()) - tryStop(c.follow, config.GetCacheGTSFollowSweepFreq()) - tryUntil("stopping follow IDs cache", 5, func() bool { - if config.GetCacheGTSFollowIDsSweepFreq() > 0 { - return c.followIDs.Stop() - } - return true - }) - tryStop(c.followRequest, config.GetCacheGTSFollowRequestSweepFreq()) - tryUntil("stopping follow request IDs cache", 5, func() bool { - if config.GetCacheGTSFollowRequestIDsSweepFreq() > 0 { - return c.followRequestIDs.Stop() - } - return true - }) - tryStop(c.instance, config.GetCacheGTSInstanceSweepFreq()) - tryStop(c.list, config.GetCacheGTSListSweepFreq()) - tryStop(c.listEntry, config.GetCacheGTSListEntrySweepFreq()) - tryStop(c.marker, config.GetCacheGTSMarkerSweepFreq()) - tryStop(c.media, config.GetCacheGTSMediaSweepFreq()) - tryStop(c.mention, config.GetCacheGTSNotificationSweepFreq()) - tryStop(c.notification, config.GetCacheGTSNotificationSweepFreq()) - tryStop(c.report, config.GetCacheGTSReportSweepFreq()) - tryStop(c.status, config.GetCacheGTSStatusSweepFreq()) - tryStop(c.statusFave, config.GetCacheGTSStatusFaveSweepFreq()) - tryStop(c.tag, config.GetCacheGTSTagSweepFreq()) - tryStop(c.tombstone, config.GetCacheGTSTombstoneSweepFreq()) - tryStop(c.user, config.GetCacheGTSUserSweepFreq()) - tryUntil("stopping *gtsmodel.Webfinger cache", 5, func() bool { - if config.GetCacheGTSWebfingerSweepFreq() > 0 { - return c.webfinger.Stop() - } - return true - }) + tryUntil("stopping *gtsmodel.Webfinger cache", 5, c.webfinger.Stop) } // Account provides access to the gtsmodel Account database cache. @@ -315,6 +235,14 @@ func (c *GTSCaches) Webfinger() *ttl.Cache[string, string] { } func (c *GTSCaches) initAccount() { + // Calculate maximum cache size. + cap := calculateResultCacheMax( + sizeofAccount(), // model in-mem size. + config.GetCacheAccountMemRatio(), + ) + + log.Infof(nil, "Account cache size = %d", cap) + c.account = result.New([]result.Lookup{ {Name: "ID"}, {Name: "URI"}, @@ -329,12 +257,19 @@ func (c *GTSCaches) initAccount() { a2 := new(gtsmodel.Account) *a2 = *a1 return a2 - }, config.GetCacheGTSAccountMaxSize()) - c.account.SetTTL(config.GetCacheGTSAccountTTL(), true) + }, cap) + c.account.IgnoreErrors(ignoreErrors) } func (c *GTSCaches) initAccountNote() { + // Calculate maximum cache size. + cap := calculateResultCacheMax( + sizeofAccountNote(), // model in-mem size. + config.GetCacheAccountNoteMemRatio(), + ) + log.Infof(nil, "AccountNote cache size = %d", cap) + c.accountNote = result.New([]result.Lookup{ {Name: "ID"}, {Name: "AccountID.TargetAccountID"}, @@ -342,12 +277,20 @@ func (c *GTSCaches) initAccountNote() { n2 := new(gtsmodel.AccountNote) *n2 = *n1 return n2 - }, config.GetCacheGTSAccountNoteMaxSize()) - c.accountNote.SetTTL(config.GetCacheGTSAccountNoteTTL(), true) + }, cap) + c.accountNote.IgnoreErrors(ignoreErrors) } func (c *GTSCaches) initBlock() { + // Calculate maximum cache size. + cap := calculateResultCacheMax( + sizeofBlock(), // model in-mem size. + config.GetCacheBlockMemRatio(), + ) + + log.Infof(nil, "Block cache size = %d", cap) + c.block = result.New([]result.Lookup{ {Name: "ID"}, {Name: "URI"}, @@ -358,16 +301,22 @@ func (c *GTSCaches) initBlock() { b2 := new(gtsmodel.Block) *b2 = *b1 return b2 - }, config.GetCacheGTSBlockMaxSize()) - c.block.SetTTL(config.GetCacheGTSBlockTTL(), true) + }, cap) + c.block.IgnoreErrors(ignoreErrors) } func (c *GTSCaches) initBlockIDs() { - c.blockIDs = &SliceCache[string]{Cache: ttl.New[string, []string]( + // Calculate maximum cache size. + cap := calculateSliceCacheMax( + config.GetCacheBlockIDsMemRatio(), + ) + + log.Infof(nil, "Block IDs cache size = %d", cap) + + c.blockIDs = &SliceCache[string]{Cache: simple.New[string, []string]( 0, - config.GetCacheGTSBlockIDsMaxSize(), - config.GetCacheGTSBlockIDsTTL(), + cap, )} } @@ -376,6 +325,14 @@ func (c *GTSCaches) initDomainBlock() { } func (c *GTSCaches) initEmoji() { + // Calculate maximum cache size. + cap := calculateResultCacheMax( + sizeofEmoji(), // model in-mem size. + config.GetCacheEmojiMemRatio(), + ) + + log.Infof(nil, "Emoji cache size = %d", cap) + c.emoji = result.New([]result.Lookup{ {Name: "ID"}, {Name: "URI"}, @@ -386,12 +343,20 @@ func (c *GTSCaches) initEmoji() { e2 := new(gtsmodel.Emoji) *e2 = *e1 return e2 - }, config.GetCacheGTSEmojiMaxSize()) - c.emoji.SetTTL(config.GetCacheGTSEmojiTTL(), true) + }, cap) + c.emoji.IgnoreErrors(ignoreErrors) } func (c *GTSCaches) initEmojiCategory() { + // Calculate maximum cache size. + cap := calculateResultCacheMax( + sizeofEmojiCategory(), // model in-mem size. + config.GetCacheEmojiCategoryMemRatio(), + ) + + log.Infof(nil, "EmojiCategory cache size = %d", cap) + c.emojiCategory = result.New([]result.Lookup{ {Name: "ID"}, {Name: "Name"}, @@ -399,12 +364,20 @@ func (c *GTSCaches) initEmojiCategory() { c2 := new(gtsmodel.EmojiCategory) *c2 = *c1 return c2 - }, config.GetCacheGTSEmojiCategoryMaxSize()) - c.emojiCategory.SetTTL(config.GetCacheGTSEmojiCategoryTTL(), true) + }, cap) + c.emojiCategory.IgnoreErrors(ignoreErrors) } func (c *GTSCaches) initFollow() { + // Calculate maximum cache size. + cap := calculateResultCacheMax( + sizeofFollow(), // model in-mem size. + config.GetCacheFollowMemRatio(), + ) + + log.Infof(nil, "Follow cache size = %d", cap) + c.follow = result.New([]result.Lookup{ {Name: "ID"}, {Name: "URI"}, @@ -415,19 +388,34 @@ func (c *GTSCaches) initFollow() { f2 := new(gtsmodel.Follow) *f2 = *f1 return f2 - }, config.GetCacheGTSFollowMaxSize()) - c.follow.SetTTL(config.GetCacheGTSFollowTTL(), true) + }, cap) + + c.follow.IgnoreErrors(ignoreErrors) } func (c *GTSCaches) initFollowIDs() { - c.followIDs = &SliceCache[string]{Cache: ttl.New[string, []string]( + // Calculate maximum cache size. + cap := calculateSliceCacheMax( + config.GetCacheFollowIDsMemRatio(), + ) + + log.Infof(nil, "Follow IDs cache size = %d", cap) + + c.followIDs = &SliceCache[string]{Cache: simple.New[string, []string]( 0, - config.GetCacheGTSFollowIDsMaxSize(), - config.GetCacheGTSFollowIDsTTL(), + cap, )} } func (c *GTSCaches) initFollowRequest() { + // Calculate maximum cache size. + cap := calculateResultCacheMax( + sizeofFollowRequest(), // model in-mem size. + config.GetCacheFollowRequestMemRatio(), + ) + + log.Infof(nil, "FollowRequest cache size = %d", cap) + c.followRequest = result.New([]result.Lookup{ {Name: "ID"}, {Name: "URI"}, @@ -438,19 +426,34 @@ func (c *GTSCaches) initFollowRequest() { f2 := new(gtsmodel.FollowRequest) *f2 = *f1 return f2 - }, config.GetCacheGTSFollowRequestMaxSize()) - c.followRequest.SetTTL(config.GetCacheGTSFollowRequestTTL(), true) + }, cap) + + c.followRequest.IgnoreErrors(ignoreErrors) } func (c *GTSCaches) initFollowRequestIDs() { - c.followRequestIDs = &SliceCache[string]{Cache: ttl.New[string, []string]( + // Calculate maximum cache size. + cap := calculateSliceCacheMax( + config.GetCacheFollowRequestIDsMemRatio(), + ) + + log.Infof(nil, "Follow Request IDs cache size = %d", cap) + + c.followRequestIDs = &SliceCache[string]{Cache: simple.New[string, []string]( 0, - config.GetCacheGTSFollowRequestIDsMaxSize(), - config.GetCacheGTSFollowRequestIDsTTL(), + cap, )} } func (c *GTSCaches) initInstance() { + // Calculate maximum cache size. + cap := calculateResultCacheMax( + sizeofInstance(), // model in-mem size. + config.GetCacheInstanceMemRatio(), + ) + + log.Infof(nil, "Instance cache size = %d", cap) + c.instance = result.New([]result.Lookup{ {Name: "ID"}, {Name: "Domain"}, @@ -458,24 +461,40 @@ func (c *GTSCaches) initInstance() { i2 := new(gtsmodel.Instance) *i2 = *i1 return i1 - }, config.GetCacheGTSInstanceMaxSize()) - c.instance.SetTTL(config.GetCacheGTSInstanceTTL(), true) - c.emojiCategory.IgnoreErrors(ignoreErrors) + }, cap) + + c.instance.IgnoreErrors(ignoreErrors) } func (c *GTSCaches) initList() { + // Calculate maximum cache size. + cap := calculateResultCacheMax( + sizeofList(), // model in-mem size. + config.GetCacheListMemRatio(), + ) + + log.Infof(nil, "List cache size = %d", cap) + c.list = result.New([]result.Lookup{ {Name: "ID"}, }, func(l1 *gtsmodel.List) *gtsmodel.List { l2 := new(gtsmodel.List) *l2 = *l1 return l2 - }, config.GetCacheGTSListMaxSize()) - c.list.SetTTL(config.GetCacheGTSListTTL(), true) + }, cap) + c.list.IgnoreErrors(ignoreErrors) } func (c *GTSCaches) initListEntry() { + // Calculate maximum cache size. + cap := calculateResultCacheMax( + sizeofListEntry(), // model in-mem size. + config.GetCacheListEntryMemRatio(), + ) + + log.Infof(nil, "ListEntry cache size = %d", cap) + c.listEntry = result.New([]result.Lookup{ {Name: "ID"}, {Name: "ListID", Multi: true}, @@ -484,48 +503,80 @@ func (c *GTSCaches) initListEntry() { l2 := new(gtsmodel.ListEntry) *l2 = *l1 return l2 - }, config.GetCacheGTSListEntryMaxSize()) - c.list.SetTTL(config.GetCacheGTSListEntryTTL(), true) - c.list.IgnoreErrors(ignoreErrors) + }, cap) + + c.listEntry.IgnoreErrors(ignoreErrors) } func (c *GTSCaches) initMarker() { + // Calculate maximum cache size. + cap := calculateResultCacheMax( + sizeofMarker(), // model in-mem size. + config.GetCacheMarkerMemRatio(), + ) + + log.Infof(nil, "Marker cache size = %d", cap) + c.marker = result.New([]result.Lookup{ {Name: "AccountID.Name"}, }, func(m1 *gtsmodel.Marker) *gtsmodel.Marker { m2 := new(gtsmodel.Marker) *m2 = *m1 return m2 - }, config.GetCacheGTSMarkerMaxSize()) - c.marker.SetTTL(config.GetCacheGTSMarkerTTL(), true) + }, cap) + c.marker.IgnoreErrors(ignoreErrors) } func (c *GTSCaches) initMedia() { + // Calculate maximum cache size. + cap := calculateResultCacheMax( + sizeofMedia(), // model in-mem size. + config.GetCacheMediaMemRatio(), + ) + + log.Infof(nil, "Media cache size = %d", cap) + c.media = result.New([]result.Lookup{ {Name: "ID"}, }, func(m1 *gtsmodel.MediaAttachment) *gtsmodel.MediaAttachment { m2 := new(gtsmodel.MediaAttachment) *m2 = *m1 return m2 - }, config.GetCacheGTSMediaMaxSize()) - c.media.SetTTL(config.GetCacheGTSMediaTTL(), true) + }, cap) + c.media.IgnoreErrors(ignoreErrors) } func (c *GTSCaches) initMention() { + // Calculate maximum cache size. + cap := calculateResultCacheMax( + sizeofMention(), // model in-mem size. + config.GetCacheMentionMemRatio(), + ) + + log.Infof(nil, "Mention cache size = %d", cap) + c.mention = result.New([]result.Lookup{ {Name: "ID"}, }, func(m1 *gtsmodel.Mention) *gtsmodel.Mention { m2 := new(gtsmodel.Mention) *m2 = *m1 return m2 - }, config.GetCacheGTSMentionMaxSize()) - c.mention.SetTTL(config.GetCacheGTSMentionTTL(), true) + }, cap) + c.mention.IgnoreErrors(ignoreErrors) } func (c *GTSCaches) initNotification() { + // Calculate maximum cache size. + cap := calculateResultCacheMax( + sizeofNotification(), // model in-mem size. + config.GetCacheNotificationMemRatio(), + ) + + log.Infof(nil, "Notification cache size = %d", cap) + c.notification = result.New([]result.Lookup{ {Name: "ID"}, {Name: "NotificationType.TargetAccountID.OriginAccountID.StatusID"}, @@ -533,24 +584,40 @@ func (c *GTSCaches) initNotification() { n2 := new(gtsmodel.Notification) *n2 = *n1 return n2 - }, config.GetCacheGTSNotificationMaxSize()) - c.notification.SetTTL(config.GetCacheGTSNotificationTTL(), true) + }, cap) + c.notification.IgnoreErrors(ignoreErrors) } func (c *GTSCaches) initReport() { + // Calculate maximum cache size. + cap := calculateResultCacheMax( + sizeofReport(), // model in-mem size. + config.GetCacheReportMemRatio(), + ) + + log.Infof(nil, "Report cache size = %d", cap) + c.report = result.New([]result.Lookup{ {Name: "ID"}, }, func(r1 *gtsmodel.Report) *gtsmodel.Report { r2 := new(gtsmodel.Report) *r2 = *r1 return r2 - }, config.GetCacheGTSReportMaxSize()) - c.report.SetTTL(config.GetCacheGTSReportTTL(), true) + }, cap) + c.report.IgnoreErrors(ignoreErrors) } func (c *GTSCaches) initStatus() { + // Calculate maximum cache size. + cap := calculateResultCacheMax( + sizeofStatus(), // model in-mem size. + config.GetCacheStatusMemRatio(), + ) + + log.Infof(nil, "Status cache size = %d", cap) + c.status = result.New([]result.Lookup{ {Name: "ID"}, {Name: "URI"}, @@ -559,12 +626,20 @@ func (c *GTSCaches) initStatus() { s2 := new(gtsmodel.Status) *s2 = *s1 return s2 - }, config.GetCacheGTSStatusMaxSize()) - c.status.SetTTL(config.GetCacheGTSStatusTTL(), true) + }, cap) + c.status.IgnoreErrors(ignoreErrors) } func (c *GTSCaches) initStatusFave() { + // Calculate maximum cache size. + cap := calculateResultCacheMax( + sizeofStatusFave(), // model in-mem size. + config.GetCacheStatusFaveMemRatio(), + ) + + log.Infof(nil, "StatusFave cache size = %d", cap) + c.statusFave = result.New([]result.Lookup{ {Name: "ID"}, {Name: "AccountID.StatusID"}, @@ -572,12 +647,20 @@ func (c *GTSCaches) initStatusFave() { f2 := new(gtsmodel.StatusFave) *f2 = *f1 return f2 - }, config.GetCacheGTSStatusFaveMaxSize()) - c.status.SetTTL(config.GetCacheGTSStatusFaveTTL(), true) - c.status.IgnoreErrors(ignoreErrors) + }, cap) + + c.statusFave.IgnoreErrors(ignoreErrors) } func (c *GTSCaches) initTag() { + // Calculate maximum cache size. + cap := calculateResultCacheMax( + sizeofTag(), // model in-mem size. + config.GetCacheTagMemRatio(), + ) + + log.Infof(nil, "Tag cache size = %d", cap) + c.tag = result.New([]result.Lookup{ {Name: "ID"}, {Name: "Name"}, @@ -585,12 +668,20 @@ func (c *GTSCaches) initTag() { m2 := new(gtsmodel.Tag) *m2 = *m1 return m2 - }, config.GetCacheGTSTagMaxSize()) - c.tag.SetTTL(config.GetCacheGTSTagTTL(), true) + }, cap) + c.tag.IgnoreErrors(ignoreErrors) } func (c *GTSCaches) initTombstone() { + // Calculate maximum cache size. + cap := calculateResultCacheMax( + sizeofTombstone(), // model in-mem size. + config.GetCacheTombstoneMemRatio(), + ) + + log.Infof(nil, "Tombstone cache size = %d", cap) + c.tombstone = result.New([]result.Lookup{ {Name: "ID"}, {Name: "URI"}, @@ -598,12 +689,20 @@ func (c *GTSCaches) initTombstone() { t2 := new(gtsmodel.Tombstone) *t2 = *t1 return t2 - }, config.GetCacheGTSTombstoneMaxSize()) - c.tombstone.SetTTL(config.GetCacheGTSTombstoneTTL(), true) + }, cap) + c.tombstone.IgnoreErrors(ignoreErrors) } func (c *GTSCaches) initUser() { + // Calculate maximum cache size. + cap := calculateResultCacheMax( + sizeofUser(), // model in-mem size. + config.GetCacheUserMemRatio(), + ) + + log.Infof(nil, "User cache size = %d", cap) + c.user = result.New([]result.Lookup{ {Name: "ID"}, {Name: "AccountID"}, @@ -614,15 +713,23 @@ func (c *GTSCaches) initUser() { u2 := new(gtsmodel.User) *u2 = *u1 return u2 - }, config.GetCacheGTSUserMaxSize()) - c.user.SetTTL(config.GetCacheGTSUserTTL(), true) + }, cap) + c.user.IgnoreErrors(ignoreErrors) } func (c *GTSCaches) initWebfinger() { + // Calculate maximum cache size. + cap := calculateCacheMax( + sizeofURIStr, sizeofURIStr, + config.GetCacheWebfingerMemRatio(), + ) + + log.Infof(nil, "Webfinger cache size = %d", cap) + c.webfinger = ttl.New[string, string]( 0, - config.GetCacheGTSWebfingerMaxSize(), - config.GetCacheGTSWebfingerTTL(), + cap, + 24*time.Hour, ) } diff --git a/internal/cache/size.go b/internal/cache/size.go new file mode 100644 index 000000000..56524575b --- /dev/null +++ b/internal/cache/size.go @@ -0,0 +1,501 @@ +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package cache + +import ( + "crypto/rsa" + "time" + "unsafe" + + "codeberg.org/gruf/go-cache/v3/simple" + "github.com/DmitriyVTitov/size" + "github.com/superseriousbusiness/gotosocial/internal/ap" + "github.com/superseriousbusiness/gotosocial/internal/config" + "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" + "github.com/superseriousbusiness/gotosocial/internal/id" +) + +const ( + // example data values. + exampleID = id.Highest + exampleURI = "https://social.bbc/users/ItsMePrinceCharlesInit" + exampleText = ` +oh no me nan's gone and done it :shocked: + +she fuckin killed the king :regicide: + +nan what have you done :shocked: + +no nan put down the knife, don't go after the landlords next! :knife: + +you'll make society more equitable for all if you're not careful! :hammer_sickle: + +#JustNanProblems #WhatWillSheDoNext #MaybeItWasntSuchABadThingAfterAll +` + + exampleTextSmall = "Small problem lads, me nan's gone on a bit of a rampage" + exampleUsername = "@SexHaver1969" + + // ID string size in memory (is always 26 char ULID). + sizeofIDStr = unsafe.Sizeof(exampleID) + + // URI string size in memory (use some random example URI). + sizeofURIStr = unsafe.Sizeof(exampleURI) + + // ID slice size in memory (using some estimate of length = 250). + sizeofIDSlice = unsafe.Sizeof([]string{}) + 250*sizeofIDStr + + // result cache key size estimate which is tricky. it can + // be a serialized string of almost any type, so we pick a + // nice serialized key size on the upper end of normal. + sizeofResultKey = 2 * sizeofIDStr +) + +// calculateSliceCacheMax calculates the maximum capacity for a slice cache with given individual ratio. +func calculateSliceCacheMax(ratio float64) int { + return calculateCacheMax(sizeofIDStr, sizeofIDSlice, ratio) +} + +// calculateResultCacheMax calculates the maximum cache capacity for a result +// cache's individual ratio number, and the size of the struct model in memory. +func calculateResultCacheMax(structSz uintptr, ratio float64) int { + // Estimate a worse-case scenario of extra lookup hash maps, + // where lookups are the no. "keys" each result can be found under + const lookups = 10 + + // Calculate the extra cache lookup map overheads. + totalLookupKeySz := uintptr(lookups) * sizeofResultKey + totalLookupValSz := uintptr(lookups) * unsafe.Sizeof(uint64(0)) + + // Primary cache sizes. + pkeySz := unsafe.Sizeof(uint64(0)) + pvalSz := structSz + + // The result cache wraps each struct result in a wrapping + // struct with further information, and possible error. This + // also needs to be taken into account when calculating value. + const resultValueOverhead = unsafe.Sizeof(&struct { + _ int64 + _ []any + _ any + _ error + }{}) + + return calculateCacheMax( + pkeySz+totalLookupKeySz, + pvalSz+totalLookupValSz+resultValueOverhead, + ratio, + ) +} + +// calculateCacheMax calculates the maximum cache capacity for a cache's +// individual ratio number, and key + value object sizes in memory. +func calculateCacheMax(keySz, valSz uintptr, ratio float64) int { + if ratio < 0 { + // Negative ratios are a secret little trick + // to manually set the cache capacity sizes. + return int(-1 * ratio) + } + + // see: https://golang.org/src/runtime/map.go + const emptyBucketOverhead = 10.79 + + // This takes into account (roughly) that the underlying simple cache library wraps + // elements within a simple.Entry{}, and the ordered map wraps each in a linked list elem. + const cacheElemOverhead = unsafe.Sizeof(simple.Entry{}) + unsafe.Sizeof(struct { + key, value interface{} + next, prev uintptr + }{}) + + // The inputted memory ratio does not take into account the + // total of all ratios, so divide it here to get perc. ratio. + totalRatio := ratio / totalOfRatios() + + // TODO: we should also further weight this ratio depending + // on the combined keySz + valSz as a ratio of all available + // cache model memories. otherwise you can end up with a + // low-ratio cache of tiny models with larger capacity than + // a high-ratio cache of large models. + + // Get max available cache memory, calculating max for + // this cache by multiplying by this cache's mem ratio. + maxMem := config.GetCacheMemoryTarget() + fMaxMem := float64(maxMem) * totalRatio + + // Cast to useable types. + fKeySz := float64(keySz) + fValSz := float64(valSz) + + // Calculated using the internal cache map size: + // (($keysz + $valsz) * $len) + ($len * $allOverheads) = $memSz + return int(fMaxMem / (fKeySz + fValSz + emptyBucketOverhead + float64(cacheElemOverhead))) +} + +// totalOfRatios returns the total of all cache ratios added together. +func totalOfRatios() float64 { + // NOTE: this is not performant calculating + // this every damn time (mainly the mutex unlocks + // required to access each config var). fortunately + // we only do this on init so fuck it :D + return 0 + + config.GetCacheAccountMemRatio() + + config.GetCacheAccountNoteMemRatio() + + config.GetCacheBlockMemRatio() + + config.GetCacheBlockIDsMemRatio() + + config.GetCacheEmojiMemRatio() + + config.GetCacheEmojiCategoryMemRatio() + + config.GetCacheFollowMemRatio() + + config.GetCacheFollowIDsMemRatio() + + config.GetCacheFollowRequestMemRatio() + + config.GetCacheFollowRequestIDsMemRatio() + + config.GetCacheInstanceMemRatio() + + config.GetCacheListMemRatio() + + config.GetCacheListEntryMemRatio() + + config.GetCacheMarkerMemRatio() + + config.GetCacheMediaMemRatio() + + config.GetCacheMentionMemRatio() + + config.GetCacheNotificationMemRatio() + + config.GetCacheReportMemRatio() + + config.GetCacheStatusMemRatio() + + config.GetCacheStatusFaveMemRatio() + + config.GetCacheTagMemRatio() + + config.GetCacheTombstoneMemRatio() + + config.GetCacheUserMemRatio() + + config.GetCacheWebfingerMemRatio() + + config.GetCacheVisibilityMemRatio() +} + +func sizeofAccount() uintptr { + return uintptr(size.Of(>smodel.Account{ + ID: exampleID, + Username: exampleUsername, + AvatarMediaAttachmentID: exampleID, + HeaderMediaAttachmentID: exampleID, + DisplayName: exampleUsername, + Note: exampleText, + NoteRaw: exampleText, + Memorial: func() *bool { ok := false; return &ok }(), + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + FetchedAt: time.Now(), + Bot: func() *bool { ok := true; return &ok }(), + Locked: func() *bool { ok := true; return &ok }(), + Discoverable: func() *bool { ok := false; return &ok }(), + Privacy: gtsmodel.VisibilityFollowersOnly, + Sensitive: func() *bool { ok := true; return &ok }(), + Language: "fr", + URI: exampleURI, + URL: exampleURI, + InboxURI: exampleURI, + OutboxURI: exampleURI, + FollowersURI: exampleURI, + FollowingURI: exampleURI, + FeaturedCollectionURI: exampleURI, + ActorType: ap.ActorPerson, + PrivateKey: &rsa.PrivateKey{}, + PublicKey: &rsa.PublicKey{}, + PublicKeyURI: exampleURI, + SensitizedAt: time.Time{}, + SilencedAt: time.Now(), + SuspendedAt: time.Now(), + HideCollections: func() *bool { ok := true; return &ok }(), + SuspensionOrigin: "", + EnableRSS: func() *bool { ok := true; return &ok }(), + })) +} + +func sizeofAccountNote() uintptr { + return uintptr(size.Of(>smodel.AccountNote{ + ID: exampleID, + AccountID: exampleID, + TargetAccountID: exampleID, + Comment: exampleTextSmall, + })) +} + +func sizeofBlock() uintptr { + return uintptr(size.Of(>smodel.Block{ + ID: exampleID, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + URI: exampleURI, + AccountID: exampleID, + TargetAccountID: exampleID, + })) +} + +func sizeofEmoji() uintptr { + return uintptr(size.Of(>smodel.Emoji{ + ID: exampleID, + Shortcode: exampleTextSmall, + Domain: exampleURI, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + ImageRemoteURL: exampleURI, + ImageStaticRemoteURL: exampleURI, + ImageURL: exampleURI, + ImagePath: exampleURI, + ImageStaticURL: exampleURI, + ImageStaticPath: exampleURI, + ImageContentType: "image/png", + ImageStaticContentType: "image/png", + ImageUpdatedAt: time.Now(), + Disabled: func() *bool { ok := false; return &ok }(), + URI: "http://localhost:8080/emoji/01F8MH9H8E4VG3KDYJR9EGPXCQ", + VisibleInPicker: func() *bool { ok := true; return &ok }(), + CategoryID: "01GGQ8V4993XK67B2JB396YFB7", + Cached: func() *bool { ok := true; return &ok }(), + })) +} + +func sizeofEmojiCategory() uintptr { + return uintptr(size.Of(>smodel.EmojiCategory{ + ID: exampleID, + Name: exampleUsername, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + })) +} + +func sizeofFollow() uintptr { + return uintptr(size.Of(>smodel.Follow{ + ID: exampleID, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + AccountID: exampleID, + TargetAccountID: exampleID, + ShowReblogs: func() *bool { ok := true; return &ok }(), + URI: exampleURI, + Notify: func() *bool { ok := false; return &ok }(), + })) +} + +func sizeofFollowRequest() uintptr { + return uintptr(size.Of(>smodel.FollowRequest{ + ID: exampleID, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + AccountID: exampleID, + TargetAccountID: exampleID, + ShowReblogs: func() *bool { ok := true; return &ok }(), + URI: exampleURI, + Notify: func() *bool { ok := false; return &ok }(), + })) +} + +func sizeofInstance() uintptr { + return uintptr(size.Of(>smodel.Instance{ + ID: exampleID, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + Domain: exampleURI, + URI: exampleURI, + Title: exampleTextSmall, + ShortDescription: exampleText, + Description: exampleText, + ContactEmail: exampleUsername, + ContactAccountUsername: exampleUsername, + ContactAccountID: exampleID, + })) +} + +func sizeofList() uintptr { + return uintptr(size.Of(>smodel.List{ + ID: exampleID, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + Title: exampleTextSmall, + AccountID: exampleID, + RepliesPolicy: gtsmodel.RepliesPolicyFollowed, + })) +} + +func sizeofListEntry() uintptr { + return uintptr(size.Of(>smodel.ListEntry{ + ID: exampleID, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + ListID: exampleID, + FollowID: exampleID, + })) +} + +func sizeofMarker() uintptr { + return uintptr(size.Of(>smodel.Marker{ + AccountID: exampleID, + Name: gtsmodel.MarkerNameHome, + UpdatedAt: time.Now(), + Version: 0, + LastReadID: exampleID, + })) +} + +func sizeofMedia() uintptr { + return uintptr(size.Of(>smodel.MediaAttachment{ + ID: exampleID, + StatusID: exampleID, + URL: exampleURI, + RemoteURL: exampleURI, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + Type: gtsmodel.FileTypeImage, + AccountID: exampleID, + Description: exampleText, + ScheduledStatusID: exampleID, + Blurhash: exampleTextSmall, + File: gtsmodel.File{ + Path: exampleURI, + ContentType: "image/jpeg", + UpdatedAt: time.Now(), + }, + Thumbnail: gtsmodel.Thumbnail{ + Path: exampleURI, + ContentType: "image/jpeg", + UpdatedAt: time.Now(), + URL: exampleURI, + RemoteURL: exampleURI, + }, + Avatar: func() *bool { ok := false; return &ok }(), + Header: func() *bool { ok := false; return &ok }(), + Cached: func() *bool { ok := true; return &ok }(), + })) +} + +func sizeofMention() uintptr { + return uintptr(size.Of(>smodel.Mention{ + ID: exampleURI, + StatusID: exampleURI, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + OriginAccountID: exampleURI, + OriginAccountURI: exampleURI, + TargetAccountID: exampleID, + NameString: exampleUsername, + TargetAccountURI: exampleURI, + TargetAccountURL: exampleURI, + })) +} + +func sizeofNotification() uintptr { + return uintptr(size.Of(>smodel.Notification{ + ID: exampleID, + NotificationType: gtsmodel.NotificationFave, + CreatedAt: time.Now(), + TargetAccountID: exampleID, + OriginAccountID: exampleID, + StatusID: exampleID, + Read: func() *bool { ok := false; return &ok }(), + })) +} + +func sizeofReport() uintptr { + return uintptr(size.Of(>smodel.Report{ + ID: exampleID, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + URI: exampleURI, + AccountID: exampleID, + TargetAccountID: exampleID, + Comment: exampleText, + StatusIDs: []string{exampleID, exampleID, exampleID}, + Forwarded: func() *bool { ok := true; return &ok }(), + ActionTaken: exampleText, + ActionTakenAt: time.Now(), + ActionTakenByAccountID: exampleID, + })) +} + +func sizeofStatus() uintptr { + return uintptr(size.Of(>smodel.Status{ + ID: exampleURI, + URI: exampleURI, + URL: exampleURI, + Content: exampleText, + Text: exampleText, + AttachmentIDs: []string{exampleID, exampleID, exampleID}, + TagIDs: []string{exampleID, exampleID, exampleID}, + MentionIDs: []string{}, + EmojiIDs: []string{exampleID, exampleID, exampleID}, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + FetchedAt: time.Now(), + Local: func() *bool { ok := false; return &ok }(), + AccountURI: exampleURI, + AccountID: exampleID, + InReplyToID: exampleID, + InReplyToURI: exampleURI, + InReplyToAccountID: exampleID, + BoostOfID: exampleID, + BoostOfAccountID: exampleID, + ContentWarning: exampleUsername, // similar length + Visibility: gtsmodel.VisibilityPublic, + Sensitive: func() *bool { ok := false; return &ok }(), + Language: "en", + CreatedWithApplicationID: exampleID, + Federated: func() *bool { ok := true; return &ok }(), + Boostable: func() *bool { ok := true; return &ok }(), + Replyable: func() *bool { ok := true; return &ok }(), + Likeable: func() *bool { ok := true; return &ok }(), + ActivityStreamsType: ap.ObjectNote, + })) +} + +func sizeofStatusFave() uintptr { + return uintptr(size.Of(>smodel.StatusFave{ + ID: exampleID, + CreatedAt: time.Now(), + AccountID: exampleID, + TargetAccountID: exampleID, + StatusID: exampleID, + URI: exampleURI, + })) +} + +func sizeofTag() uintptr { + return uintptr(size.Of(>smodel.Tag{ + ID: exampleID, + Name: exampleUsername, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + Useable: func() *bool { ok := true; return &ok }(), + Listable: func() *bool { ok := true; return &ok }(), + })) +} + +func sizeofTombstone() uintptr { + return uintptr(size.Of(>smodel.Tombstone{ + ID: exampleID, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + Domain: exampleUsername, + URI: exampleURI, + })) +} + +func sizeofVisibility() uintptr { + return uintptr(size.Of(&CachedVisibility{ + ItemID: exampleID, + RequesterID: exampleID, + Type: VisibilityTypeAccount, + Value: false, + })) +} + +func sizeofUser() uintptr { + return uintptr(size.Of(>smodel.User{})) +} diff --git a/internal/cache/slice.go b/internal/cache/slice.go index 194f20d4b..e296a3b57 100644 --- a/internal/cache/slice.go +++ b/internal/cache/slice.go @@ -18,14 +18,14 @@ package cache import ( - "codeberg.org/gruf/go-cache/v3/ttl" + "codeberg.org/gruf/go-cache/v3/simple" "golang.org/x/exp/slices" ) // SliceCache wraps a ttl.Cache to provide simple loader-callback // functions for fetching + caching slices of objects (e.g. IDs). type SliceCache[T any] struct { - *ttl.Cache[string, []T] + *simple.Cache[string, []T] } // Load will attempt to load an existing slice from the cache for the given key, else calling the provided load function and caching the result. diff --git a/internal/cache/util.go b/internal/cache/util.go index f2357c904..f15922401 100644 --- a/internal/cache/util.go +++ b/internal/cache/util.go @@ -20,10 +20,8 @@ import ( "database/sql" "errors" - "fmt" "time" - "codeberg.org/gruf/go-cache/v3/result" errorsv2 "codeberg.org/gruf/go-errors/v2" "github.com/superseriousbusiness/gotosocial/internal/db" "github.com/superseriousbusiness/gotosocial/internal/log" @@ -56,26 +54,6 @@ func (*nocopy) Lock() {} func (*nocopy) Unlock() {} -// tryStart will attempt to start the given cache only if sweep duration > 0 (sweeping is enabled). -func tryStart[ValueType any](cache *result.Cache[ValueType], sweep time.Duration) { - if sweep > 0 { - var z ValueType - msg := fmt.Sprintf("starting %T cache", z) - tryUntil(msg, 5, func() bool { - return cache.Start(sweep) - }) - } -} - -// tryStop will attempt to stop the given cache only if sweep duration > 0 (sweeping is enabled). -func tryStop[ValueType any](cache *result.Cache[ValueType], sweep time.Duration) { - if sweep > 0 { - var z ValueType - msg := fmt.Sprintf("stopping %T cache", z) - tryUntil(msg, 5, cache.Stop) - } -} - // tryUntil will attempt to call 'do' for 'count' attempts, before panicking with 'msg'. func tryUntil(msg string, count int, do func() bool) { for i := 0; i < count; i++ { diff --git a/internal/cache/visibility.go b/internal/cache/visibility.go index fd481eedc..8c534206b 100644 --- a/internal/cache/visibility.go +++ b/internal/cache/visibility.go @@ -20,6 +20,7 @@ import ( "codeberg.org/gruf/go-cache/v3/result" "github.com/superseriousbusiness/gotosocial/internal/config" + "github.com/superseriousbusiness/gotosocial/internal/log" ) type VisibilityCache struct { @@ -29,6 +30,14 @@ type VisibilityCache struct { // Init will initialize the visibility cache in this collection. // NOTE: the cache MUST NOT be in use anywhere, this is not thread-safe. func (c *VisibilityCache) Init() { + // Calculate maximum cache size. + cap := calculateResultCacheMax( + sizeofVisibility(), // model in-mem size. + config.GetCacheVisibilityMemRatio(), + ) + + log.Infof(nil, "Visibility cache size = %d", cap) + c.Cache = result.New([]result.Lookup{ {Name: "ItemID", Multi: true}, {Name: "RequesterID", Multi: true}, @@ -37,19 +46,17 @@ func (c *VisibilityCache) Init() { v2 := new(CachedVisibility) *v2 = *v1 return v2 - }, config.GetCacheVisibilityMaxSize()) - c.Cache.SetTTL(config.GetCacheVisibilityTTL(), true) + }, cap) + c.Cache.IgnoreErrors(ignoreErrors) } // Start will attempt to start the visibility cache, or panic. func (c *VisibilityCache) Start() { - tryStart(c.Cache, config.GetCacheVisibilitySweepFreq()) } // Stop will attempt to stop the visibility cache, or panic. func (c *VisibilityCache) Stop() { - tryStop(c.Cache, config.GetCacheVisibilitySweepFreq()) } // VisibilityType represents a visibility lookup type. diff --git a/internal/config/config.go b/internal/config/config.go index 7f09b5fc1..50508e40b 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -175,113 +175,32 @@ type HTTPClientConfiguration struct { } type CacheConfiguration struct { - GTS GTSCacheConfiguration `name:"gts"` - - VisibilityMaxSize int `name:"visibility-max-size"` - VisibilityTTL time.Duration `name:"visibility-ttl"` - VisibilitySweepFreq time.Duration `name:"visibility-sweep-freq"` -} - -type GTSCacheConfiguration struct { - AccountMaxSize int `name:"account-max-size"` - AccountTTL time.Duration `name:"account-ttl"` - AccountSweepFreq time.Duration `name:"account-sweep-freq"` - - AccountNoteMaxSize int `name:"account-note-max-size"` - AccountNoteTTL time.Duration `name:"account-note-ttl"` - AccountNoteSweepFreq time.Duration `name:"account-note-sweep-freq"` - - BlockMaxSize int `name:"block-max-size"` - BlockTTL time.Duration `name:"block-ttl"` - BlockSweepFreq time.Duration `name:"block-sweep-freq"` - - BlockIDsMaxSize int `name:"block-ids-max-size"` - BlockIDsTTL time.Duration `name:"block-ids-ttl"` - BlockIDsSweepFreq time.Duration `name:"block-ids-sweep-freq"` - - DomainBlockMaxSize int `name:"domain-block-max-size"` - DomainBlockTTL time.Duration `name:"domain-block-ttl"` - DomainBlockSweepFreq time.Duration `name:"domain-block-sweep-freq"` - - EmojiMaxSize int `name:"emoji-max-size"` - EmojiTTL time.Duration `name:"emoji-ttl"` - EmojiSweepFreq time.Duration `name:"emoji-sweep-freq"` - - EmojiCategoryMaxSize int `name:"emoji-category-max-size"` - EmojiCategoryTTL time.Duration `name:"emoji-category-ttl"` - EmojiCategorySweepFreq time.Duration `name:"emoji-category-sweep-freq"` - - FollowMaxSize int `name:"follow-max-size"` - FollowTTL time.Duration `name:"follow-ttl"` - FollowSweepFreq time.Duration `name:"follow-sweep-freq"` - - FollowIDsMaxSize int `name:"follow-ids-max-size"` - FollowIDsTTL time.Duration `name:"follow-ids-ttl"` - FollowIDsSweepFreq time.Duration `name:"follow-ids-sweep-freq"` - - FollowRequestMaxSize int `name:"follow-request-max-size"` - FollowRequestTTL time.Duration `name:"follow-request-ttl"` - FollowRequestSweepFreq time.Duration `name:"follow-request-sweep-freq"` - - FollowRequestIDsMaxSize int `name:"follow-request-ids-max-size"` - FollowRequestIDsTTL time.Duration `name:"follow-request-ids-ttl"` - FollowRequestIDsSweepFreq time.Duration `name:"follow-request-ids-sweep-freq"` - - InstanceMaxSize int `name:"instance-max-size"` - InstanceTTL time.Duration `name:"instance-ttl"` - InstanceSweepFreq time.Duration `name:"instance-sweep-freq"` - - ListMaxSize int `name:"list-max-size"` - ListTTL time.Duration `name:"list-ttl"` - ListSweepFreq time.Duration `name:"list-sweep-freq"` - - ListEntryMaxSize int `name:"list-entry-max-size"` - ListEntryTTL time.Duration `name:"list-entry-ttl"` - ListEntrySweepFreq time.Duration `name:"list-entry-sweep-freq"` - - MarkerMaxSize int `name:"marker-max-size"` - MarkerTTL time.Duration `name:"marker-ttl"` - MarkerSweepFreq time.Duration `name:"marker-sweep-freq"` - - MediaMaxSize int `name:"media-max-size"` - MediaTTL time.Duration `name:"media-ttl"` - MediaSweepFreq time.Duration `name:"media-sweep-freq"` - - MentionMaxSize int `name:"mention-max-size"` - MentionTTL time.Duration `name:"mention-ttl"` - MentionSweepFreq time.Duration `name:"mention-sweep-freq"` - - NotificationMaxSize int `name:"notification-max-size"` - NotificationTTL time.Duration `name:"notification-ttl"` - NotificationSweepFreq time.Duration `name:"notification-sweep-freq"` - - ReportMaxSize int `name:"report-max-size"` - ReportTTL time.Duration `name:"report-ttl"` - ReportSweepFreq time.Duration `name:"report-sweep-freq"` - - StatusMaxSize int `name:"status-max-size"` - StatusTTL time.Duration `name:"status-ttl"` - StatusSweepFreq time.Duration `name:"status-sweep-freq"` - - StatusFaveMaxSize int `name:"status-fave-max-size"` - StatusFaveTTL time.Duration `name:"status-fave-ttl"` - StatusFaveSweepFreq time.Duration `name:"status-fave-sweep-freq"` - - TagMaxSize int `name:"tag-max-size"` - TagTTL time.Duration `name:"tag-ttl"` - TagSweepFreq time.Duration `name:"tag-sweep-freq"` - - TombstoneMaxSize int `name:"tombstone-max-size"` - TombstoneTTL time.Duration `name:"tombstone-ttl"` - TombstoneSweepFreq time.Duration `name:"tombstone-sweep-freq"` - - UserMaxSize int `name:"user-max-size"` - UserTTL time.Duration `name:"user-ttl"` - UserSweepFreq time.Duration `name:"user-sweep-freq"` - - WebfingerMaxSize int `name:"webfinger-max-size"` - WebfingerTTL time.Duration `name:"webfinger-ttl"` - WebfingerSweepFreq time.Duration `name:"webfinger-sweep-freq"` + MemoryTarget bytesize.Size `name:"memory-target"` + AccountMemRatio float64 `name:"account-mem-ratio"` + AccountNoteMemRatio float64 `name:"account-note-mem-ratio"` + BlockMemRatio float64 `name:"block-mem-ratio"` + BlockIDsMemRatio float64 `name:"block-mem-ratio"` + EmojiMemRatio float64 `name:"emoji-mem-ratio"` + EmojiCategoryMemRatio float64 `name:"emoji-category-mem-ratio"` + FollowMemRatio float64 `name:"follow-mem-ratio"` + FollowIDsMemRatio float64 `name:"follow-ids-mem-ratio"` + FollowRequestMemRatio float64 `name:"follow-request-mem-ratio"` + FollowRequestIDsMemRatio float64 `name:"follow-request-ids-mem-ratio"` + InstanceMemRatio float64 `name:"instance-mem-ratio"` + ListMemRatio float64 `name:"list-mem-ratio"` + ListEntryMemRatio float64 `name:"list-entry-mem-ratio"` + MarkerMemRatio float64 `name:"marker-mem-ratio"` + MediaMemRatio float64 `name:"media-mem-ratio"` + MentionMemRatio float64 `name:"mention-mem-ratio"` + NotificationMemRatio float64 `name:"notification-mem-ratio"` + ReportMemRatio float64 `name:"report-mem-ratio"` + StatusMemRatio float64 `name:"status-mem-ratio"` + StatusFaveMemRatio float64 `name:"status-fave-mem-ratio"` + TagMemRatio float64 `name:"tag-mem-ratio"` + TombstoneMemRatio float64 `name:"tombstone-mem-ratio"` + UserMemRatio float64 `name:"user-mem-ratio"` + WebfingerMemRatio float64 `name:"webfinger-mem-ratio"` + VisibilityMemRatio float64 `name:"visibility-mem-ratio"` } // MarshalMap will marshal current Configuration into a map structure (useful for JSON/TOML/YAML). diff --git a/internal/config/defaults.go b/internal/config/defaults.go index e8cb39325..e740d1c98 100644 --- a/internal/config/defaults.go +++ b/internal/config/defaults.go @@ -126,111 +126,50 @@ AdvancedSenderMultiplier: 2, // 2 senders per CPU Cache: CacheConfiguration{ - GTS: GTSCacheConfiguration{ - AccountMaxSize: 2000, - AccountTTL: time.Minute * 30, - AccountSweepFreq: time.Minute, + // Rough memory target that the total + // size of all State.Caches will attempt + // to remain with. Emphasis on *rough*. + MemoryTarget: 200 * bytesize.MiB, - AccountNoteMaxSize: 1000, - AccountNoteTTL: time.Minute * 30, - AccountNoteSweepFreq: time.Minute, - - BlockMaxSize: 1000, - BlockTTL: time.Minute * 30, - BlockSweepFreq: time.Minute, - - BlockIDsMaxSize: 500, - BlockIDsTTL: time.Minute * 30, - BlockIDsSweepFreq: time.Minute, - - DomainBlockMaxSize: 2000, - DomainBlockTTL: time.Hour * 24, - DomainBlockSweepFreq: time.Minute, - - EmojiMaxSize: 2000, - EmojiTTL: time.Minute * 30, - EmojiSweepFreq: time.Minute, - - EmojiCategoryMaxSize: 100, - EmojiCategoryTTL: time.Minute * 30, - EmojiCategorySweepFreq: time.Minute, - - FollowMaxSize: 2000, - FollowTTL: time.Minute * 30, - FollowSweepFreq: time.Minute, - - FollowIDsMaxSize: 500, - FollowIDsTTL: time.Minute * 30, - FollowIDsSweepFreq: time.Minute, - - FollowRequestMaxSize: 2000, - FollowRequestTTL: time.Minute * 30, - FollowRequestSweepFreq: time.Minute, - - FollowRequestIDsMaxSize: 500, - FollowRequestIDsTTL: time.Minute * 30, - FollowRequestIDsSweepFreq: time.Minute, - - InstanceMaxSize: 2000, - InstanceTTL: time.Minute * 30, - InstanceSweepFreq: time.Minute, - - ListMaxSize: 2000, - ListTTL: time.Minute * 30, - ListSweepFreq: time.Minute, - - ListEntryMaxSize: 2000, - ListEntryTTL: time.Minute * 30, - ListEntrySweepFreq: time.Minute, - - MarkerMaxSize: 2000, - MarkerTTL: time.Hour * 6, - MarkerSweepFreq: time.Minute, - - MediaMaxSize: 1000, - MediaTTL: time.Minute * 30, - MediaSweepFreq: time.Minute, - - MentionMaxSize: 2000, - MentionTTL: time.Minute * 30, - MentionSweepFreq: time.Minute, - - NotificationMaxSize: 1000, - NotificationTTL: time.Minute * 30, - NotificationSweepFreq: time.Minute, - - ReportMaxSize: 100, - ReportTTL: time.Minute * 30, - ReportSweepFreq: time.Minute, - - StatusMaxSize: 2000, - StatusTTL: time.Minute * 30, - StatusSweepFreq: time.Minute, - - StatusFaveMaxSize: 2000, - StatusFaveTTL: time.Minute * 30, - StatusFaveSweepFreq: time.Minute, - - TagMaxSize: 2000, - TagTTL: time.Minute * 30, - TagSweepFreq: time.Minute, - - TombstoneMaxSize: 500, - TombstoneTTL: time.Minute * 30, - TombstoneSweepFreq: time.Minute, - - UserMaxSize: 500, - UserTTL: time.Minute * 30, - UserSweepFreq: time.Minute, - - WebfingerMaxSize: 250, - WebfingerTTL: time.Hour * 24, - WebfingerSweepFreq: time.Minute * 15, - }, - - VisibilityMaxSize: 2000, - VisibilityTTL: time.Minute * 30, - VisibilitySweepFreq: time.Minute, + // These ratios signal what percentage + // of the available cache target memory + // is allocated to each object type's + // cache. + // + // These are weighted by a totally + // assorted mixture of priority, and + // manual twiddling to get the generated + // cache capacity ratios within normal + // amounts dependent size of the models. + // + // when TODO items in the size.go source + // file have been addressed, these should + // be able to make some more sense :D + AccountMemRatio: 18, + AccountNoteMemRatio: 0.1, + BlockMemRatio: 3, + BlockIDsMemRatio: 3, + EmojiMemRatio: 3, + EmojiCategoryMemRatio: 0.1, + FollowMemRatio: 4, + FollowIDsMemRatio: 4, + FollowRequestMemRatio: 2, + FollowRequestIDsMemRatio: 2, + InstanceMemRatio: 1, + ListMemRatio: 3, + ListEntryMemRatio: 3, + MarkerMemRatio: 0.5, + MediaMemRatio: 4, + MentionMemRatio: 5, + NotificationMemRatio: 5, + ReportMemRatio: 1, + StatusMemRatio: 18, + StatusFaveMemRatio: 5, + TagMemRatio: 3, + TombstoneMemRatio: 2, + UserMemRatio: 0.1, + WebfingerMemRatio: 0.1, + VisibilityMemRatio: 2, }, HTTPClient: HTTPClientConfiguration{ diff --git a/internal/config/helpers.gen.go b/internal/config/helpers.gen.go index 4c2f1d059..c29b5c38f 100644 --- a/internal/config/helpers.gen.go +++ b/internal/config/helpers.gen.go @@ -2424,1965 +2424,655 @@ func GetHTTPClientTLSInsecureSkipVerify() bool { return global.GetHTTPClientTLSI // SetHTTPClientTLSInsecureSkipVerify safely sets the value for global configuration 'HTTPClient.TLSInsecureSkipVerify' field func SetHTTPClientTLSInsecureSkipVerify(v bool) { global.SetHTTPClientTLSInsecureSkipVerify(v) } -// GetCacheGTSAccountMaxSize safely fetches the Configuration value for state's 'Cache.GTS.AccountMaxSize' field -func (st *ConfigState) GetCacheGTSAccountMaxSize() (v int) { +// GetCacheMemoryTarget safely fetches the Configuration value for state's 'Cache.MemoryTarget' field +func (st *ConfigState) GetCacheMemoryTarget() (v bytesize.Size) { st.mutex.RLock() - v = st.config.Cache.GTS.AccountMaxSize + v = st.config.Cache.MemoryTarget st.mutex.RUnlock() return } -// SetCacheGTSAccountMaxSize safely sets the Configuration value for state's 'Cache.GTS.AccountMaxSize' field -func (st *ConfigState) SetCacheGTSAccountMaxSize(v int) { +// SetCacheMemoryTarget safely sets the Configuration value for state's 'Cache.MemoryTarget' field +func (st *ConfigState) SetCacheMemoryTarget(v bytesize.Size) { st.mutex.Lock() defer st.mutex.Unlock() - st.config.Cache.GTS.AccountMaxSize = v + st.config.Cache.MemoryTarget = v st.reloadToViper() } -// CacheGTSAccountMaxSizeFlag returns the flag name for the 'Cache.GTS.AccountMaxSize' field -func CacheGTSAccountMaxSizeFlag() string { return "cache-gts-account-max-size" } +// CacheMemoryTargetFlag returns the flag name for the 'Cache.MemoryTarget' field +func CacheMemoryTargetFlag() string { return "cache-memory-target" } -// GetCacheGTSAccountMaxSize safely fetches the value for global configuration 'Cache.GTS.AccountMaxSize' field -func GetCacheGTSAccountMaxSize() int { return global.GetCacheGTSAccountMaxSize() } +// GetCacheMemoryTarget safely fetches the value for global configuration 'Cache.MemoryTarget' field +func GetCacheMemoryTarget() bytesize.Size { return global.GetCacheMemoryTarget() } -// SetCacheGTSAccountMaxSize safely sets the value for global configuration 'Cache.GTS.AccountMaxSize' field -func SetCacheGTSAccountMaxSize(v int) { global.SetCacheGTSAccountMaxSize(v) } +// SetCacheMemoryTarget safely sets the value for global configuration 'Cache.MemoryTarget' field +func SetCacheMemoryTarget(v bytesize.Size) { global.SetCacheMemoryTarget(v) } -// GetCacheGTSAccountTTL safely fetches the Configuration value for state's 'Cache.GTS.AccountTTL' field -func (st *ConfigState) GetCacheGTSAccountTTL() (v time.Duration) { +// GetCacheAccountMemRatio safely fetches the Configuration value for state's 'Cache.AccountMemRatio' field +func (st *ConfigState) GetCacheAccountMemRatio() (v float64) { st.mutex.RLock() - v = st.config.Cache.GTS.AccountTTL + v = st.config.Cache.AccountMemRatio st.mutex.RUnlock() return } -// SetCacheGTSAccountTTL safely sets the Configuration value for state's 'Cache.GTS.AccountTTL' field -func (st *ConfigState) SetCacheGTSAccountTTL(v time.Duration) { +// SetCacheAccountMemRatio safely sets the Configuration value for state's 'Cache.AccountMemRatio' field +func (st *ConfigState) SetCacheAccountMemRatio(v float64) { st.mutex.Lock() defer st.mutex.Unlock() - st.config.Cache.GTS.AccountTTL = v + st.config.Cache.AccountMemRatio = v st.reloadToViper() } -// CacheGTSAccountTTLFlag returns the flag name for the 'Cache.GTS.AccountTTL' field -func CacheGTSAccountTTLFlag() string { return "cache-gts-account-ttl" } +// CacheAccountMemRatioFlag returns the flag name for the 'Cache.AccountMemRatio' field +func CacheAccountMemRatioFlag() string { return "cache-account-mem-ratio" } -// GetCacheGTSAccountTTL safely fetches the value for global configuration 'Cache.GTS.AccountTTL' field -func GetCacheGTSAccountTTL() time.Duration { return global.GetCacheGTSAccountTTL() } +// GetCacheAccountMemRatio safely fetches the value for global configuration 'Cache.AccountMemRatio' field +func GetCacheAccountMemRatio() float64 { return global.GetCacheAccountMemRatio() } -// SetCacheGTSAccountTTL safely sets the value for global configuration 'Cache.GTS.AccountTTL' field -func SetCacheGTSAccountTTL(v time.Duration) { global.SetCacheGTSAccountTTL(v) } +// SetCacheAccountMemRatio safely sets the value for global configuration 'Cache.AccountMemRatio' field +func SetCacheAccountMemRatio(v float64) { global.SetCacheAccountMemRatio(v) } -// GetCacheGTSAccountSweepFreq safely fetches the Configuration value for state's 'Cache.GTS.AccountSweepFreq' field -func (st *ConfigState) GetCacheGTSAccountSweepFreq() (v time.Duration) { +// GetCacheAccountNoteMemRatio safely fetches the Configuration value for state's 'Cache.AccountNoteMemRatio' field +func (st *ConfigState) GetCacheAccountNoteMemRatio() (v float64) { st.mutex.RLock() - v = st.config.Cache.GTS.AccountSweepFreq + v = st.config.Cache.AccountNoteMemRatio st.mutex.RUnlock() return } -// SetCacheGTSAccountSweepFreq safely sets the Configuration value for state's 'Cache.GTS.AccountSweepFreq' field -func (st *ConfigState) SetCacheGTSAccountSweepFreq(v time.Duration) { +// SetCacheAccountNoteMemRatio safely sets the Configuration value for state's 'Cache.AccountNoteMemRatio' field +func (st *ConfigState) SetCacheAccountNoteMemRatio(v float64) { st.mutex.Lock() defer st.mutex.Unlock() - st.config.Cache.GTS.AccountSweepFreq = v + st.config.Cache.AccountNoteMemRatio = v st.reloadToViper() } -// CacheGTSAccountSweepFreqFlag returns the flag name for the 'Cache.GTS.AccountSweepFreq' field -func CacheGTSAccountSweepFreqFlag() string { return "cache-gts-account-sweep-freq" } +// CacheAccountNoteMemRatioFlag returns the flag name for the 'Cache.AccountNoteMemRatio' field +func CacheAccountNoteMemRatioFlag() string { return "cache-account-note-mem-ratio" } -// GetCacheGTSAccountSweepFreq safely fetches the value for global configuration 'Cache.GTS.AccountSweepFreq' field -func GetCacheGTSAccountSweepFreq() time.Duration { return global.GetCacheGTSAccountSweepFreq() } +// GetCacheAccountNoteMemRatio safely fetches the value for global configuration 'Cache.AccountNoteMemRatio' field +func GetCacheAccountNoteMemRatio() float64 { return global.GetCacheAccountNoteMemRatio() } -// SetCacheGTSAccountSweepFreq safely sets the value for global configuration 'Cache.GTS.AccountSweepFreq' field -func SetCacheGTSAccountSweepFreq(v time.Duration) { global.SetCacheGTSAccountSweepFreq(v) } +// SetCacheAccountNoteMemRatio safely sets the value for global configuration 'Cache.AccountNoteMemRatio' field +func SetCacheAccountNoteMemRatio(v float64) { global.SetCacheAccountNoteMemRatio(v) } -// GetCacheGTSAccountNoteMaxSize safely fetches the Configuration value for state's 'Cache.GTS.AccountNoteMaxSize' field -func (st *ConfigState) GetCacheGTSAccountNoteMaxSize() (v int) { +// GetCacheBlockMemRatio safely fetches the Configuration value for state's 'Cache.BlockMemRatio' field +func (st *ConfigState) GetCacheBlockMemRatio() (v float64) { st.mutex.RLock() - v = st.config.Cache.GTS.AccountNoteMaxSize + v = st.config.Cache.BlockMemRatio st.mutex.RUnlock() return } -// SetCacheGTSAccountNoteMaxSize safely sets the Configuration value for state's 'Cache.GTS.AccountNoteMaxSize' field -func (st *ConfigState) SetCacheGTSAccountNoteMaxSize(v int) { +// SetCacheBlockMemRatio safely sets the Configuration value for state's 'Cache.BlockMemRatio' field +func (st *ConfigState) SetCacheBlockMemRatio(v float64) { st.mutex.Lock() defer st.mutex.Unlock() - st.config.Cache.GTS.AccountNoteMaxSize = v + st.config.Cache.BlockMemRatio = v st.reloadToViper() } -// CacheGTSAccountNoteMaxSizeFlag returns the flag name for the 'Cache.GTS.AccountNoteMaxSize' field -func CacheGTSAccountNoteMaxSizeFlag() string { return "cache-gts-account-note-max-size" } +// CacheBlockMemRatioFlag returns the flag name for the 'Cache.BlockMemRatio' field +func CacheBlockMemRatioFlag() string { return "cache-block-mem-ratio" } -// GetCacheGTSAccountNoteMaxSize safely fetches the value for global configuration 'Cache.GTS.AccountNoteMaxSize' field -func GetCacheGTSAccountNoteMaxSize() int { return global.GetCacheGTSAccountNoteMaxSize() } +// GetCacheBlockMemRatio safely fetches the value for global configuration 'Cache.BlockMemRatio' field +func GetCacheBlockMemRatio() float64 { return global.GetCacheBlockMemRatio() } -// SetCacheGTSAccountNoteMaxSize safely sets the value for global configuration 'Cache.GTS.AccountNoteMaxSize' field -func SetCacheGTSAccountNoteMaxSize(v int) { global.SetCacheGTSAccountNoteMaxSize(v) } +// SetCacheBlockMemRatio safely sets the value for global configuration 'Cache.BlockMemRatio' field +func SetCacheBlockMemRatio(v float64) { global.SetCacheBlockMemRatio(v) } -// GetCacheGTSAccountNoteTTL safely fetches the Configuration value for state's 'Cache.GTS.AccountNoteTTL' field -func (st *ConfigState) GetCacheGTSAccountNoteTTL() (v time.Duration) { +// GetCacheBlockIDsMemRatio safely fetches the Configuration value for state's 'Cache.BlockIDsMemRatio' field +func (st *ConfigState) GetCacheBlockIDsMemRatio() (v float64) { st.mutex.RLock() - v = st.config.Cache.GTS.AccountNoteTTL + v = st.config.Cache.BlockIDsMemRatio st.mutex.RUnlock() return } -// SetCacheGTSAccountNoteTTL safely sets the Configuration value for state's 'Cache.GTS.AccountNoteTTL' field -func (st *ConfigState) SetCacheGTSAccountNoteTTL(v time.Duration) { +// SetCacheBlockIDsMemRatio safely sets the Configuration value for state's 'Cache.BlockIDsMemRatio' field +func (st *ConfigState) SetCacheBlockIDsMemRatio(v float64) { st.mutex.Lock() defer st.mutex.Unlock() - st.config.Cache.GTS.AccountNoteTTL = v + st.config.Cache.BlockIDsMemRatio = v st.reloadToViper() } -// CacheGTSAccountNoteTTLFlag returns the flag name for the 'Cache.GTS.AccountNoteTTL' field -func CacheGTSAccountNoteTTLFlag() string { return "cache-gts-account-note-ttl" } +// CacheBlockIDsMemRatioFlag returns the flag name for the 'Cache.BlockIDsMemRatio' field +func CacheBlockIDsMemRatioFlag() string { return "cache-block-mem-ratio" } -// GetCacheGTSAccountNoteTTL safely fetches the value for global configuration 'Cache.GTS.AccountNoteTTL' field -func GetCacheGTSAccountNoteTTL() time.Duration { return global.GetCacheGTSAccountNoteTTL() } +// GetCacheBlockIDsMemRatio safely fetches the value for global configuration 'Cache.BlockIDsMemRatio' field +func GetCacheBlockIDsMemRatio() float64 { return global.GetCacheBlockIDsMemRatio() } -// SetCacheGTSAccountNoteTTL safely sets the value for global configuration 'Cache.GTS.AccountNoteTTL' field -func SetCacheGTSAccountNoteTTL(v time.Duration) { global.SetCacheGTSAccountNoteTTL(v) } +// SetCacheBlockIDsMemRatio safely sets the value for global configuration 'Cache.BlockIDsMemRatio' field +func SetCacheBlockIDsMemRatio(v float64) { global.SetCacheBlockIDsMemRatio(v) } -// GetCacheGTSAccountNoteSweepFreq safely fetches the Configuration value for state's 'Cache.GTS.AccountNoteSweepFreq' field -func (st *ConfigState) GetCacheGTSAccountNoteSweepFreq() (v time.Duration) { +// GetCacheEmojiMemRatio safely fetches the Configuration value for state's 'Cache.EmojiMemRatio' field +func (st *ConfigState) GetCacheEmojiMemRatio() (v float64) { st.mutex.RLock() - v = st.config.Cache.GTS.AccountNoteSweepFreq + v = st.config.Cache.EmojiMemRatio st.mutex.RUnlock() return } -// SetCacheGTSAccountNoteSweepFreq safely sets the Configuration value for state's 'Cache.GTS.AccountNoteSweepFreq' field -func (st *ConfigState) SetCacheGTSAccountNoteSweepFreq(v time.Duration) { +// SetCacheEmojiMemRatio safely sets the Configuration value for state's 'Cache.EmojiMemRatio' field +func (st *ConfigState) SetCacheEmojiMemRatio(v float64) { st.mutex.Lock() defer st.mutex.Unlock() - st.config.Cache.GTS.AccountNoteSweepFreq = v + st.config.Cache.EmojiMemRatio = v st.reloadToViper() } -// CacheGTSAccountNoteSweepFreqFlag returns the flag name for the 'Cache.GTS.AccountNoteSweepFreq' field -func CacheGTSAccountNoteSweepFreqFlag() string { return "cache-gts-account-note-sweep-freq" } +// CacheEmojiMemRatioFlag returns the flag name for the 'Cache.EmojiMemRatio' field +func CacheEmojiMemRatioFlag() string { return "cache-emoji-mem-ratio" } -// GetCacheGTSAccountNoteSweepFreq safely fetches the value for global configuration 'Cache.GTS.AccountNoteSweepFreq' field -func GetCacheGTSAccountNoteSweepFreq() time.Duration { return global.GetCacheGTSAccountNoteSweepFreq() } +// GetCacheEmojiMemRatio safely fetches the value for global configuration 'Cache.EmojiMemRatio' field +func GetCacheEmojiMemRatio() float64 { return global.GetCacheEmojiMemRatio() } -// SetCacheGTSAccountNoteSweepFreq safely sets the value for global configuration 'Cache.GTS.AccountNoteSweepFreq' field -func SetCacheGTSAccountNoteSweepFreq(v time.Duration) { global.SetCacheGTSAccountNoteSweepFreq(v) } +// SetCacheEmojiMemRatio safely sets the value for global configuration 'Cache.EmojiMemRatio' field +func SetCacheEmojiMemRatio(v float64) { global.SetCacheEmojiMemRatio(v) } -// GetCacheGTSBlockMaxSize safely fetches the Configuration value for state's 'Cache.GTS.BlockMaxSize' field -func (st *ConfigState) GetCacheGTSBlockMaxSize() (v int) { +// GetCacheEmojiCategoryMemRatio safely fetches the Configuration value for state's 'Cache.EmojiCategoryMemRatio' field +func (st *ConfigState) GetCacheEmojiCategoryMemRatio() (v float64) { st.mutex.RLock() - v = st.config.Cache.GTS.BlockMaxSize + v = st.config.Cache.EmojiCategoryMemRatio st.mutex.RUnlock() return } -// SetCacheGTSBlockMaxSize safely sets the Configuration value for state's 'Cache.GTS.BlockMaxSize' field -func (st *ConfigState) SetCacheGTSBlockMaxSize(v int) { +// SetCacheEmojiCategoryMemRatio safely sets the Configuration value for state's 'Cache.EmojiCategoryMemRatio' field +func (st *ConfigState) SetCacheEmojiCategoryMemRatio(v float64) { st.mutex.Lock() defer st.mutex.Unlock() - st.config.Cache.GTS.BlockMaxSize = v + st.config.Cache.EmojiCategoryMemRatio = v st.reloadToViper() } -// CacheGTSBlockMaxSizeFlag returns the flag name for the 'Cache.GTS.BlockMaxSize' field -func CacheGTSBlockMaxSizeFlag() string { return "cache-gts-block-max-size" } +// CacheEmojiCategoryMemRatioFlag returns the flag name for the 'Cache.EmojiCategoryMemRatio' field +func CacheEmojiCategoryMemRatioFlag() string { return "cache-emoji-category-mem-ratio" } -// GetCacheGTSBlockMaxSize safely fetches the value for global configuration 'Cache.GTS.BlockMaxSize' field -func GetCacheGTSBlockMaxSize() int { return global.GetCacheGTSBlockMaxSize() } +// GetCacheEmojiCategoryMemRatio safely fetches the value for global configuration 'Cache.EmojiCategoryMemRatio' field +func GetCacheEmojiCategoryMemRatio() float64 { return global.GetCacheEmojiCategoryMemRatio() } -// SetCacheGTSBlockMaxSize safely sets the value for global configuration 'Cache.GTS.BlockMaxSize' field -func SetCacheGTSBlockMaxSize(v int) { global.SetCacheGTSBlockMaxSize(v) } +// SetCacheEmojiCategoryMemRatio safely sets the value for global configuration 'Cache.EmojiCategoryMemRatio' field +func SetCacheEmojiCategoryMemRatio(v float64) { global.SetCacheEmojiCategoryMemRatio(v) } -// GetCacheGTSBlockTTL safely fetches the Configuration value for state's 'Cache.GTS.BlockTTL' field -func (st *ConfigState) GetCacheGTSBlockTTL() (v time.Duration) { +// GetCacheFollowMemRatio safely fetches the Configuration value for state's 'Cache.FollowMemRatio' field +func (st *ConfigState) GetCacheFollowMemRatio() (v float64) { st.mutex.RLock() - v = st.config.Cache.GTS.BlockTTL + v = st.config.Cache.FollowMemRatio st.mutex.RUnlock() return } -// SetCacheGTSBlockTTL safely sets the Configuration value for state's 'Cache.GTS.BlockTTL' field -func (st *ConfigState) SetCacheGTSBlockTTL(v time.Duration) { +// SetCacheFollowMemRatio safely sets the Configuration value for state's 'Cache.FollowMemRatio' field +func (st *ConfigState) SetCacheFollowMemRatio(v float64) { st.mutex.Lock() defer st.mutex.Unlock() - st.config.Cache.GTS.BlockTTL = v + st.config.Cache.FollowMemRatio = v st.reloadToViper() } -// CacheGTSBlockTTLFlag returns the flag name for the 'Cache.GTS.BlockTTL' field -func CacheGTSBlockTTLFlag() string { return "cache-gts-block-ttl" } +// CacheFollowMemRatioFlag returns the flag name for the 'Cache.FollowMemRatio' field +func CacheFollowMemRatioFlag() string { return "cache-follow-mem-ratio" } -// GetCacheGTSBlockTTL safely fetches the value for global configuration 'Cache.GTS.BlockTTL' field -func GetCacheGTSBlockTTL() time.Duration { return global.GetCacheGTSBlockTTL() } +// GetCacheFollowMemRatio safely fetches the value for global configuration 'Cache.FollowMemRatio' field +func GetCacheFollowMemRatio() float64 { return global.GetCacheFollowMemRatio() } -// SetCacheGTSBlockTTL safely sets the value for global configuration 'Cache.GTS.BlockTTL' field -func SetCacheGTSBlockTTL(v time.Duration) { global.SetCacheGTSBlockTTL(v) } +// SetCacheFollowMemRatio safely sets the value for global configuration 'Cache.FollowMemRatio' field +func SetCacheFollowMemRatio(v float64) { global.SetCacheFollowMemRatio(v) } -// GetCacheGTSBlockSweepFreq safely fetches the Configuration value for state's 'Cache.GTS.BlockSweepFreq' field -func (st *ConfigState) GetCacheGTSBlockSweepFreq() (v time.Duration) { +// GetCacheFollowIDsMemRatio safely fetches the Configuration value for state's 'Cache.FollowIDsMemRatio' field +func (st *ConfigState) GetCacheFollowIDsMemRatio() (v float64) { st.mutex.RLock() - v = st.config.Cache.GTS.BlockSweepFreq + v = st.config.Cache.FollowIDsMemRatio st.mutex.RUnlock() return } -// SetCacheGTSBlockSweepFreq safely sets the Configuration value for state's 'Cache.GTS.BlockSweepFreq' field -func (st *ConfigState) SetCacheGTSBlockSweepFreq(v time.Duration) { +// SetCacheFollowIDsMemRatio safely sets the Configuration value for state's 'Cache.FollowIDsMemRatio' field +func (st *ConfigState) SetCacheFollowIDsMemRatio(v float64) { st.mutex.Lock() defer st.mutex.Unlock() - st.config.Cache.GTS.BlockSweepFreq = v + st.config.Cache.FollowIDsMemRatio = v st.reloadToViper() } -// CacheGTSBlockSweepFreqFlag returns the flag name for the 'Cache.GTS.BlockSweepFreq' field -func CacheGTSBlockSweepFreqFlag() string { return "cache-gts-block-sweep-freq" } +// CacheFollowIDsMemRatioFlag returns the flag name for the 'Cache.FollowIDsMemRatio' field +func CacheFollowIDsMemRatioFlag() string { return "cache-follow-ids-mem-ratio" } -// GetCacheGTSBlockSweepFreq safely fetches the value for global configuration 'Cache.GTS.BlockSweepFreq' field -func GetCacheGTSBlockSweepFreq() time.Duration { return global.GetCacheGTSBlockSweepFreq() } +// GetCacheFollowIDsMemRatio safely fetches the value for global configuration 'Cache.FollowIDsMemRatio' field +func GetCacheFollowIDsMemRatio() float64 { return global.GetCacheFollowIDsMemRatio() } -// SetCacheGTSBlockSweepFreq safely sets the value for global configuration 'Cache.GTS.BlockSweepFreq' field -func SetCacheGTSBlockSweepFreq(v time.Duration) { global.SetCacheGTSBlockSweepFreq(v) } +// SetCacheFollowIDsMemRatio safely sets the value for global configuration 'Cache.FollowIDsMemRatio' field +func SetCacheFollowIDsMemRatio(v float64) { global.SetCacheFollowIDsMemRatio(v) } -// GetCacheGTSBlockIDsMaxSize safely fetches the Configuration value for state's 'Cache.GTS.BlockIDsMaxSize' field -func (st *ConfigState) GetCacheGTSBlockIDsMaxSize() (v int) { +// GetCacheFollowRequestMemRatio safely fetches the Configuration value for state's 'Cache.FollowRequestMemRatio' field +func (st *ConfigState) GetCacheFollowRequestMemRatio() (v float64) { st.mutex.RLock() - v = st.config.Cache.GTS.BlockIDsMaxSize + v = st.config.Cache.FollowRequestMemRatio st.mutex.RUnlock() return } -// SetCacheGTSBlockIDsMaxSize safely sets the Configuration value for state's 'Cache.GTS.BlockIDsMaxSize' field -func (st *ConfigState) SetCacheGTSBlockIDsMaxSize(v int) { +// SetCacheFollowRequestMemRatio safely sets the Configuration value for state's 'Cache.FollowRequestMemRatio' field +func (st *ConfigState) SetCacheFollowRequestMemRatio(v float64) { st.mutex.Lock() defer st.mutex.Unlock() - st.config.Cache.GTS.BlockIDsMaxSize = v + st.config.Cache.FollowRequestMemRatio = v st.reloadToViper() } -// CacheGTSBlockIDsMaxSizeFlag returns the flag name for the 'Cache.GTS.BlockIDsMaxSize' field -func CacheGTSBlockIDsMaxSizeFlag() string { return "cache-gts-block-ids-max-size" } +// CacheFollowRequestMemRatioFlag returns the flag name for the 'Cache.FollowRequestMemRatio' field +func CacheFollowRequestMemRatioFlag() string { return "cache-follow-request-mem-ratio" } -// GetCacheGTSBlockIDsMaxSize safely fetches the value for global configuration 'Cache.GTS.BlockIDsMaxSize' field -func GetCacheGTSBlockIDsMaxSize() int { return global.GetCacheGTSBlockIDsMaxSize() } +// GetCacheFollowRequestMemRatio safely fetches the value for global configuration 'Cache.FollowRequestMemRatio' field +func GetCacheFollowRequestMemRatio() float64 { return global.GetCacheFollowRequestMemRatio() } -// SetCacheGTSBlockIDsMaxSize safely sets the value for global configuration 'Cache.GTS.BlockIDsMaxSize' field -func SetCacheGTSBlockIDsMaxSize(v int) { global.SetCacheGTSBlockIDsMaxSize(v) } +// SetCacheFollowRequestMemRatio safely sets the value for global configuration 'Cache.FollowRequestMemRatio' field +func SetCacheFollowRequestMemRatio(v float64) { global.SetCacheFollowRequestMemRatio(v) } -// GetCacheGTSBlockIDsTTL safely fetches the Configuration value for state's 'Cache.GTS.BlockIDsTTL' field -func (st *ConfigState) GetCacheGTSBlockIDsTTL() (v time.Duration) { +// GetCacheFollowRequestIDsMemRatio safely fetches the Configuration value for state's 'Cache.FollowRequestIDsMemRatio' field +func (st *ConfigState) GetCacheFollowRequestIDsMemRatio() (v float64) { st.mutex.RLock() - v = st.config.Cache.GTS.BlockIDsTTL + v = st.config.Cache.FollowRequestIDsMemRatio st.mutex.RUnlock() return } -// SetCacheGTSBlockIDsTTL safely sets the Configuration value for state's 'Cache.GTS.BlockIDsTTL' field -func (st *ConfigState) SetCacheGTSBlockIDsTTL(v time.Duration) { +// SetCacheFollowRequestIDsMemRatio safely sets the Configuration value for state's 'Cache.FollowRequestIDsMemRatio' field +func (st *ConfigState) SetCacheFollowRequestIDsMemRatio(v float64) { st.mutex.Lock() defer st.mutex.Unlock() - st.config.Cache.GTS.BlockIDsTTL = v + st.config.Cache.FollowRequestIDsMemRatio = v st.reloadToViper() } -// CacheGTSBlockIDsTTLFlag returns the flag name for the 'Cache.GTS.BlockIDsTTL' field -func CacheGTSBlockIDsTTLFlag() string { return "cache-gts-block-ids-ttl" } +// CacheFollowRequestIDsMemRatioFlag returns the flag name for the 'Cache.FollowRequestIDsMemRatio' field +func CacheFollowRequestIDsMemRatioFlag() string { return "cache-follow-request-ids-mem-ratio" } -// GetCacheGTSBlockIDsTTL safely fetches the value for global configuration 'Cache.GTS.BlockIDsTTL' field -func GetCacheGTSBlockIDsTTL() time.Duration { return global.GetCacheGTSBlockIDsTTL() } +// GetCacheFollowRequestIDsMemRatio safely fetches the value for global configuration 'Cache.FollowRequestIDsMemRatio' field +func GetCacheFollowRequestIDsMemRatio() float64 { return global.GetCacheFollowRequestIDsMemRatio() } -// SetCacheGTSBlockIDsTTL safely sets the value for global configuration 'Cache.GTS.BlockIDsTTL' field -func SetCacheGTSBlockIDsTTL(v time.Duration) { global.SetCacheGTSBlockIDsTTL(v) } +// SetCacheFollowRequestIDsMemRatio safely sets the value for global configuration 'Cache.FollowRequestIDsMemRatio' field +func SetCacheFollowRequestIDsMemRatio(v float64) { global.SetCacheFollowRequestIDsMemRatio(v) } -// GetCacheGTSBlockIDsSweepFreq safely fetches the Configuration value for state's 'Cache.GTS.BlockIDsSweepFreq' field -func (st *ConfigState) GetCacheGTSBlockIDsSweepFreq() (v time.Duration) { +// GetCacheInstanceMemRatio safely fetches the Configuration value for state's 'Cache.InstanceMemRatio' field +func (st *ConfigState) GetCacheInstanceMemRatio() (v float64) { st.mutex.RLock() - v = st.config.Cache.GTS.BlockIDsSweepFreq + v = st.config.Cache.InstanceMemRatio st.mutex.RUnlock() return } -// SetCacheGTSBlockIDsSweepFreq safely sets the Configuration value for state's 'Cache.GTS.BlockIDsSweepFreq' field -func (st *ConfigState) SetCacheGTSBlockIDsSweepFreq(v time.Duration) { +// SetCacheInstanceMemRatio safely sets the Configuration value for state's 'Cache.InstanceMemRatio' field +func (st *ConfigState) SetCacheInstanceMemRatio(v float64) { st.mutex.Lock() defer st.mutex.Unlock() - st.config.Cache.GTS.BlockIDsSweepFreq = v + st.config.Cache.InstanceMemRatio = v st.reloadToViper() } -// CacheGTSBlockIDsSweepFreqFlag returns the flag name for the 'Cache.GTS.BlockIDsSweepFreq' field -func CacheGTSBlockIDsSweepFreqFlag() string { return "cache-gts-block-ids-sweep-freq" } +// CacheInstanceMemRatioFlag returns the flag name for the 'Cache.InstanceMemRatio' field +func CacheInstanceMemRatioFlag() string { return "cache-instance-mem-ratio" } -// GetCacheGTSBlockIDsSweepFreq safely fetches the value for global configuration 'Cache.GTS.BlockIDsSweepFreq' field -func GetCacheGTSBlockIDsSweepFreq() time.Duration { return global.GetCacheGTSBlockIDsSweepFreq() } +// GetCacheInstanceMemRatio safely fetches the value for global configuration 'Cache.InstanceMemRatio' field +func GetCacheInstanceMemRatio() float64 { return global.GetCacheInstanceMemRatio() } -// SetCacheGTSBlockIDsSweepFreq safely sets the value for global configuration 'Cache.GTS.BlockIDsSweepFreq' field -func SetCacheGTSBlockIDsSweepFreq(v time.Duration) { global.SetCacheGTSBlockIDsSweepFreq(v) } +// SetCacheInstanceMemRatio safely sets the value for global configuration 'Cache.InstanceMemRatio' field +func SetCacheInstanceMemRatio(v float64) { global.SetCacheInstanceMemRatio(v) } -// GetCacheGTSDomainBlockMaxSize safely fetches the Configuration value for state's 'Cache.GTS.DomainBlockMaxSize' field -func (st *ConfigState) GetCacheGTSDomainBlockMaxSize() (v int) { +// GetCacheListMemRatio safely fetches the Configuration value for state's 'Cache.ListMemRatio' field +func (st *ConfigState) GetCacheListMemRatio() (v float64) { st.mutex.RLock() - v = st.config.Cache.GTS.DomainBlockMaxSize + v = st.config.Cache.ListMemRatio st.mutex.RUnlock() return } -// SetCacheGTSDomainBlockMaxSize safely sets the Configuration value for state's 'Cache.GTS.DomainBlockMaxSize' field -func (st *ConfigState) SetCacheGTSDomainBlockMaxSize(v int) { +// SetCacheListMemRatio safely sets the Configuration value for state's 'Cache.ListMemRatio' field +func (st *ConfigState) SetCacheListMemRatio(v float64) { st.mutex.Lock() defer st.mutex.Unlock() - st.config.Cache.GTS.DomainBlockMaxSize = v + st.config.Cache.ListMemRatio = v st.reloadToViper() } -// CacheGTSDomainBlockMaxSizeFlag returns the flag name for the 'Cache.GTS.DomainBlockMaxSize' field -func CacheGTSDomainBlockMaxSizeFlag() string { return "cache-gts-domain-block-max-size" } +// CacheListMemRatioFlag returns the flag name for the 'Cache.ListMemRatio' field +func CacheListMemRatioFlag() string { return "cache-list-mem-ratio" } -// GetCacheGTSDomainBlockMaxSize safely fetches the value for global configuration 'Cache.GTS.DomainBlockMaxSize' field -func GetCacheGTSDomainBlockMaxSize() int { return global.GetCacheGTSDomainBlockMaxSize() } +// GetCacheListMemRatio safely fetches the value for global configuration 'Cache.ListMemRatio' field +func GetCacheListMemRatio() float64 { return global.GetCacheListMemRatio() } -// SetCacheGTSDomainBlockMaxSize safely sets the value for global configuration 'Cache.GTS.DomainBlockMaxSize' field -func SetCacheGTSDomainBlockMaxSize(v int) { global.SetCacheGTSDomainBlockMaxSize(v) } +// SetCacheListMemRatio safely sets the value for global configuration 'Cache.ListMemRatio' field +func SetCacheListMemRatio(v float64) { global.SetCacheListMemRatio(v) } -// GetCacheGTSDomainBlockTTL safely fetches the Configuration value for state's 'Cache.GTS.DomainBlockTTL' field -func (st *ConfigState) GetCacheGTSDomainBlockTTL() (v time.Duration) { +// GetCacheListEntryMemRatio safely fetches the Configuration value for state's 'Cache.ListEntryMemRatio' field +func (st *ConfigState) GetCacheListEntryMemRatio() (v float64) { st.mutex.RLock() - v = st.config.Cache.GTS.DomainBlockTTL + v = st.config.Cache.ListEntryMemRatio st.mutex.RUnlock() return } -// SetCacheGTSDomainBlockTTL safely sets the Configuration value for state's 'Cache.GTS.DomainBlockTTL' field -func (st *ConfigState) SetCacheGTSDomainBlockTTL(v time.Duration) { +// SetCacheListEntryMemRatio safely sets the Configuration value for state's 'Cache.ListEntryMemRatio' field +func (st *ConfigState) SetCacheListEntryMemRatio(v float64) { st.mutex.Lock() defer st.mutex.Unlock() - st.config.Cache.GTS.DomainBlockTTL = v + st.config.Cache.ListEntryMemRatio = v st.reloadToViper() } -// CacheGTSDomainBlockTTLFlag returns the flag name for the 'Cache.GTS.DomainBlockTTL' field -func CacheGTSDomainBlockTTLFlag() string { return "cache-gts-domain-block-ttl" } +// CacheListEntryMemRatioFlag returns the flag name for the 'Cache.ListEntryMemRatio' field +func CacheListEntryMemRatioFlag() string { return "cache-list-entry-mem-ratio" } -// GetCacheGTSDomainBlockTTL safely fetches the value for global configuration 'Cache.GTS.DomainBlockTTL' field -func GetCacheGTSDomainBlockTTL() time.Duration { return global.GetCacheGTSDomainBlockTTL() } +// GetCacheListEntryMemRatio safely fetches the value for global configuration 'Cache.ListEntryMemRatio' field +func GetCacheListEntryMemRatio() float64 { return global.GetCacheListEntryMemRatio() } -// SetCacheGTSDomainBlockTTL safely sets the value for global configuration 'Cache.GTS.DomainBlockTTL' field -func SetCacheGTSDomainBlockTTL(v time.Duration) { global.SetCacheGTSDomainBlockTTL(v) } +// SetCacheListEntryMemRatio safely sets the value for global configuration 'Cache.ListEntryMemRatio' field +func SetCacheListEntryMemRatio(v float64) { global.SetCacheListEntryMemRatio(v) } -// GetCacheGTSDomainBlockSweepFreq safely fetches the Configuration value for state's 'Cache.GTS.DomainBlockSweepFreq' field -func (st *ConfigState) GetCacheGTSDomainBlockSweepFreq() (v time.Duration) { +// GetCacheMarkerMemRatio safely fetches the Configuration value for state's 'Cache.MarkerMemRatio' field +func (st *ConfigState) GetCacheMarkerMemRatio() (v float64) { st.mutex.RLock() - v = st.config.Cache.GTS.DomainBlockSweepFreq + v = st.config.Cache.MarkerMemRatio st.mutex.RUnlock() return } -// SetCacheGTSDomainBlockSweepFreq safely sets the Configuration value for state's 'Cache.GTS.DomainBlockSweepFreq' field -func (st *ConfigState) SetCacheGTSDomainBlockSweepFreq(v time.Duration) { +// SetCacheMarkerMemRatio safely sets the Configuration value for state's 'Cache.MarkerMemRatio' field +func (st *ConfigState) SetCacheMarkerMemRatio(v float64) { st.mutex.Lock() defer st.mutex.Unlock() - st.config.Cache.GTS.DomainBlockSweepFreq = v + st.config.Cache.MarkerMemRatio = v st.reloadToViper() } -// CacheGTSDomainBlockSweepFreqFlag returns the flag name for the 'Cache.GTS.DomainBlockSweepFreq' field -func CacheGTSDomainBlockSweepFreqFlag() string { return "cache-gts-domain-block-sweep-freq" } +// CacheMarkerMemRatioFlag returns the flag name for the 'Cache.MarkerMemRatio' field +func CacheMarkerMemRatioFlag() string { return "cache-marker-mem-ratio" } -// GetCacheGTSDomainBlockSweepFreq safely fetches the value for global configuration 'Cache.GTS.DomainBlockSweepFreq' field -func GetCacheGTSDomainBlockSweepFreq() time.Duration { return global.GetCacheGTSDomainBlockSweepFreq() } +// GetCacheMarkerMemRatio safely fetches the value for global configuration 'Cache.MarkerMemRatio' field +func GetCacheMarkerMemRatio() float64 { return global.GetCacheMarkerMemRatio() } -// SetCacheGTSDomainBlockSweepFreq safely sets the value for global configuration 'Cache.GTS.DomainBlockSweepFreq' field -func SetCacheGTSDomainBlockSweepFreq(v time.Duration) { global.SetCacheGTSDomainBlockSweepFreq(v) } +// SetCacheMarkerMemRatio safely sets the value for global configuration 'Cache.MarkerMemRatio' field +func SetCacheMarkerMemRatio(v float64) { global.SetCacheMarkerMemRatio(v) } -// GetCacheGTSEmojiMaxSize safely fetches the Configuration value for state's 'Cache.GTS.EmojiMaxSize' field -func (st *ConfigState) GetCacheGTSEmojiMaxSize() (v int) { +// GetCacheMediaMemRatio safely fetches the Configuration value for state's 'Cache.MediaMemRatio' field +func (st *ConfigState) GetCacheMediaMemRatio() (v float64) { st.mutex.RLock() - v = st.config.Cache.GTS.EmojiMaxSize + v = st.config.Cache.MediaMemRatio st.mutex.RUnlock() return } -// SetCacheGTSEmojiMaxSize safely sets the Configuration value for state's 'Cache.GTS.EmojiMaxSize' field -func (st *ConfigState) SetCacheGTSEmojiMaxSize(v int) { +// SetCacheMediaMemRatio safely sets the Configuration value for state's 'Cache.MediaMemRatio' field +func (st *ConfigState) SetCacheMediaMemRatio(v float64) { st.mutex.Lock() defer st.mutex.Unlock() - st.config.Cache.GTS.EmojiMaxSize = v + st.config.Cache.MediaMemRatio = v st.reloadToViper() } -// CacheGTSEmojiMaxSizeFlag returns the flag name for the 'Cache.GTS.EmojiMaxSize' field -func CacheGTSEmojiMaxSizeFlag() string { return "cache-gts-emoji-max-size" } +// CacheMediaMemRatioFlag returns the flag name for the 'Cache.MediaMemRatio' field +func CacheMediaMemRatioFlag() string { return "cache-media-mem-ratio" } -// GetCacheGTSEmojiMaxSize safely fetches the value for global configuration 'Cache.GTS.EmojiMaxSize' field -func GetCacheGTSEmojiMaxSize() int { return global.GetCacheGTSEmojiMaxSize() } +// GetCacheMediaMemRatio safely fetches the value for global configuration 'Cache.MediaMemRatio' field +func GetCacheMediaMemRatio() float64 { return global.GetCacheMediaMemRatio() } -// SetCacheGTSEmojiMaxSize safely sets the value for global configuration 'Cache.GTS.EmojiMaxSize' field -func SetCacheGTSEmojiMaxSize(v int) { global.SetCacheGTSEmojiMaxSize(v) } +// SetCacheMediaMemRatio safely sets the value for global configuration 'Cache.MediaMemRatio' field +func SetCacheMediaMemRatio(v float64) { global.SetCacheMediaMemRatio(v) } -// GetCacheGTSEmojiTTL safely fetches the Configuration value for state's 'Cache.GTS.EmojiTTL' field -func (st *ConfigState) GetCacheGTSEmojiTTL() (v time.Duration) { +// GetCacheMentionMemRatio safely fetches the Configuration value for state's 'Cache.MentionMemRatio' field +func (st *ConfigState) GetCacheMentionMemRatio() (v float64) { st.mutex.RLock() - v = st.config.Cache.GTS.EmojiTTL + v = st.config.Cache.MentionMemRatio st.mutex.RUnlock() return } -// SetCacheGTSEmojiTTL safely sets the Configuration value for state's 'Cache.GTS.EmojiTTL' field -func (st *ConfigState) SetCacheGTSEmojiTTL(v time.Duration) { +// SetCacheMentionMemRatio safely sets the Configuration value for state's 'Cache.MentionMemRatio' field +func (st *ConfigState) SetCacheMentionMemRatio(v float64) { st.mutex.Lock() defer st.mutex.Unlock() - st.config.Cache.GTS.EmojiTTL = v + st.config.Cache.MentionMemRatio = v st.reloadToViper() } -// CacheGTSEmojiTTLFlag returns the flag name for the 'Cache.GTS.EmojiTTL' field -func CacheGTSEmojiTTLFlag() string { return "cache-gts-emoji-ttl" } +// CacheMentionMemRatioFlag returns the flag name for the 'Cache.MentionMemRatio' field +func CacheMentionMemRatioFlag() string { return "cache-mention-mem-ratio" } -// GetCacheGTSEmojiTTL safely fetches the value for global configuration 'Cache.GTS.EmojiTTL' field -func GetCacheGTSEmojiTTL() time.Duration { return global.GetCacheGTSEmojiTTL() } +// GetCacheMentionMemRatio safely fetches the value for global configuration 'Cache.MentionMemRatio' field +func GetCacheMentionMemRatio() float64 { return global.GetCacheMentionMemRatio() } -// SetCacheGTSEmojiTTL safely sets the value for global configuration 'Cache.GTS.EmojiTTL' field -func SetCacheGTSEmojiTTL(v time.Duration) { global.SetCacheGTSEmojiTTL(v) } +// SetCacheMentionMemRatio safely sets the value for global configuration 'Cache.MentionMemRatio' field +func SetCacheMentionMemRatio(v float64) { global.SetCacheMentionMemRatio(v) } -// GetCacheGTSEmojiSweepFreq safely fetches the Configuration value for state's 'Cache.GTS.EmojiSweepFreq' field -func (st *ConfigState) GetCacheGTSEmojiSweepFreq() (v time.Duration) { +// GetCacheNotificationMemRatio safely fetches the Configuration value for state's 'Cache.NotificationMemRatio' field +func (st *ConfigState) GetCacheNotificationMemRatio() (v float64) { st.mutex.RLock() - v = st.config.Cache.GTS.EmojiSweepFreq + v = st.config.Cache.NotificationMemRatio st.mutex.RUnlock() return } -// SetCacheGTSEmojiSweepFreq safely sets the Configuration value for state's 'Cache.GTS.EmojiSweepFreq' field -func (st *ConfigState) SetCacheGTSEmojiSweepFreq(v time.Duration) { +// SetCacheNotificationMemRatio safely sets the Configuration value for state's 'Cache.NotificationMemRatio' field +func (st *ConfigState) SetCacheNotificationMemRatio(v float64) { st.mutex.Lock() defer st.mutex.Unlock() - st.config.Cache.GTS.EmojiSweepFreq = v + st.config.Cache.NotificationMemRatio = v st.reloadToViper() } -// CacheGTSEmojiSweepFreqFlag returns the flag name for the 'Cache.GTS.EmojiSweepFreq' field -func CacheGTSEmojiSweepFreqFlag() string { return "cache-gts-emoji-sweep-freq" } +// CacheNotificationMemRatioFlag returns the flag name for the 'Cache.NotificationMemRatio' field +func CacheNotificationMemRatioFlag() string { return "cache-notification-mem-ratio" } -// GetCacheGTSEmojiSweepFreq safely fetches the value for global configuration 'Cache.GTS.EmojiSweepFreq' field -func GetCacheGTSEmojiSweepFreq() time.Duration { return global.GetCacheGTSEmojiSweepFreq() } +// GetCacheNotificationMemRatio safely fetches the value for global configuration 'Cache.NotificationMemRatio' field +func GetCacheNotificationMemRatio() float64 { return global.GetCacheNotificationMemRatio() } -// SetCacheGTSEmojiSweepFreq safely sets the value for global configuration 'Cache.GTS.EmojiSweepFreq' field -func SetCacheGTSEmojiSweepFreq(v time.Duration) { global.SetCacheGTSEmojiSweepFreq(v) } +// SetCacheNotificationMemRatio safely sets the value for global configuration 'Cache.NotificationMemRatio' field +func SetCacheNotificationMemRatio(v float64) { global.SetCacheNotificationMemRatio(v) } -// GetCacheGTSEmojiCategoryMaxSize safely fetches the Configuration value for state's 'Cache.GTS.EmojiCategoryMaxSize' field -func (st *ConfigState) GetCacheGTSEmojiCategoryMaxSize() (v int) { +// GetCacheReportMemRatio safely fetches the Configuration value for state's 'Cache.ReportMemRatio' field +func (st *ConfigState) GetCacheReportMemRatio() (v float64) { st.mutex.RLock() - v = st.config.Cache.GTS.EmojiCategoryMaxSize + v = st.config.Cache.ReportMemRatio st.mutex.RUnlock() return } -// SetCacheGTSEmojiCategoryMaxSize safely sets the Configuration value for state's 'Cache.GTS.EmojiCategoryMaxSize' field -func (st *ConfigState) SetCacheGTSEmojiCategoryMaxSize(v int) { +// SetCacheReportMemRatio safely sets the Configuration value for state's 'Cache.ReportMemRatio' field +func (st *ConfigState) SetCacheReportMemRatio(v float64) { st.mutex.Lock() defer st.mutex.Unlock() - st.config.Cache.GTS.EmojiCategoryMaxSize = v + st.config.Cache.ReportMemRatio = v st.reloadToViper() } -// CacheGTSEmojiCategoryMaxSizeFlag returns the flag name for the 'Cache.GTS.EmojiCategoryMaxSize' field -func CacheGTSEmojiCategoryMaxSizeFlag() string { return "cache-gts-emoji-category-max-size" } +// CacheReportMemRatioFlag returns the flag name for the 'Cache.ReportMemRatio' field +func CacheReportMemRatioFlag() string { return "cache-report-mem-ratio" } -// GetCacheGTSEmojiCategoryMaxSize safely fetches the value for global configuration 'Cache.GTS.EmojiCategoryMaxSize' field -func GetCacheGTSEmojiCategoryMaxSize() int { return global.GetCacheGTSEmojiCategoryMaxSize() } +// GetCacheReportMemRatio safely fetches the value for global configuration 'Cache.ReportMemRatio' field +func GetCacheReportMemRatio() float64 { return global.GetCacheReportMemRatio() } -// SetCacheGTSEmojiCategoryMaxSize safely sets the value for global configuration 'Cache.GTS.EmojiCategoryMaxSize' field -func SetCacheGTSEmojiCategoryMaxSize(v int) { global.SetCacheGTSEmojiCategoryMaxSize(v) } +// SetCacheReportMemRatio safely sets the value for global configuration 'Cache.ReportMemRatio' field +func SetCacheReportMemRatio(v float64) { global.SetCacheReportMemRatio(v) } -// GetCacheGTSEmojiCategoryTTL safely fetches the Configuration value for state's 'Cache.GTS.EmojiCategoryTTL' field -func (st *ConfigState) GetCacheGTSEmojiCategoryTTL() (v time.Duration) { +// GetCacheStatusMemRatio safely fetches the Configuration value for state's 'Cache.StatusMemRatio' field +func (st *ConfigState) GetCacheStatusMemRatio() (v float64) { st.mutex.RLock() - v = st.config.Cache.GTS.EmojiCategoryTTL + v = st.config.Cache.StatusMemRatio st.mutex.RUnlock() return } -// SetCacheGTSEmojiCategoryTTL safely sets the Configuration value for state's 'Cache.GTS.EmojiCategoryTTL' field -func (st *ConfigState) SetCacheGTSEmojiCategoryTTL(v time.Duration) { +// SetCacheStatusMemRatio safely sets the Configuration value for state's 'Cache.StatusMemRatio' field +func (st *ConfigState) SetCacheStatusMemRatio(v float64) { st.mutex.Lock() defer st.mutex.Unlock() - st.config.Cache.GTS.EmojiCategoryTTL = v + st.config.Cache.StatusMemRatio = v st.reloadToViper() } -// CacheGTSEmojiCategoryTTLFlag returns the flag name for the 'Cache.GTS.EmojiCategoryTTL' field -func CacheGTSEmojiCategoryTTLFlag() string { return "cache-gts-emoji-category-ttl" } +// CacheStatusMemRatioFlag returns the flag name for the 'Cache.StatusMemRatio' field +func CacheStatusMemRatioFlag() string { return "cache-status-mem-ratio" } -// GetCacheGTSEmojiCategoryTTL safely fetches the value for global configuration 'Cache.GTS.EmojiCategoryTTL' field -func GetCacheGTSEmojiCategoryTTL() time.Duration { return global.GetCacheGTSEmojiCategoryTTL() } +// GetCacheStatusMemRatio safely fetches the value for global configuration 'Cache.StatusMemRatio' field +func GetCacheStatusMemRatio() float64 { return global.GetCacheStatusMemRatio() } -// SetCacheGTSEmojiCategoryTTL safely sets the value for global configuration 'Cache.GTS.EmojiCategoryTTL' field -func SetCacheGTSEmojiCategoryTTL(v time.Duration) { global.SetCacheGTSEmojiCategoryTTL(v) } +// SetCacheStatusMemRatio safely sets the value for global configuration 'Cache.StatusMemRatio' field +func SetCacheStatusMemRatio(v float64) { global.SetCacheStatusMemRatio(v) } -// GetCacheGTSEmojiCategorySweepFreq safely fetches the Configuration value for state's 'Cache.GTS.EmojiCategorySweepFreq' field -func (st *ConfigState) GetCacheGTSEmojiCategorySweepFreq() (v time.Duration) { +// GetCacheStatusFaveMemRatio safely fetches the Configuration value for state's 'Cache.StatusFaveMemRatio' field +func (st *ConfigState) GetCacheStatusFaveMemRatio() (v float64) { st.mutex.RLock() - v = st.config.Cache.GTS.EmojiCategorySweepFreq + v = st.config.Cache.StatusFaveMemRatio st.mutex.RUnlock() return } -// SetCacheGTSEmojiCategorySweepFreq safely sets the Configuration value for state's 'Cache.GTS.EmojiCategorySweepFreq' field -func (st *ConfigState) SetCacheGTSEmojiCategorySweepFreq(v time.Duration) { +// SetCacheStatusFaveMemRatio safely sets the Configuration value for state's 'Cache.StatusFaveMemRatio' field +func (st *ConfigState) SetCacheStatusFaveMemRatio(v float64) { st.mutex.Lock() defer st.mutex.Unlock() - st.config.Cache.GTS.EmojiCategorySweepFreq = v + st.config.Cache.StatusFaveMemRatio = v st.reloadToViper() } -// CacheGTSEmojiCategorySweepFreqFlag returns the flag name for the 'Cache.GTS.EmojiCategorySweepFreq' field -func CacheGTSEmojiCategorySweepFreqFlag() string { return "cache-gts-emoji-category-sweep-freq" } +// CacheStatusFaveMemRatioFlag returns the flag name for the 'Cache.StatusFaveMemRatio' field +func CacheStatusFaveMemRatioFlag() string { return "cache-status-fave-mem-ratio" } -// GetCacheGTSEmojiCategorySweepFreq safely fetches the value for global configuration 'Cache.GTS.EmojiCategorySweepFreq' field -func GetCacheGTSEmojiCategorySweepFreq() time.Duration { - return global.GetCacheGTSEmojiCategorySweepFreq() -} - -// SetCacheGTSEmojiCategorySweepFreq safely sets the value for global configuration 'Cache.GTS.EmojiCategorySweepFreq' field -func SetCacheGTSEmojiCategorySweepFreq(v time.Duration) { global.SetCacheGTSEmojiCategorySweepFreq(v) } - -// GetCacheGTSFollowMaxSize safely fetches the Configuration value for state's 'Cache.GTS.FollowMaxSize' field -func (st *ConfigState) GetCacheGTSFollowMaxSize() (v int) { - st.mutex.RLock() - v = st.config.Cache.GTS.FollowMaxSize - st.mutex.RUnlock() - return -} - -// SetCacheGTSFollowMaxSize safely sets the Configuration value for state's 'Cache.GTS.FollowMaxSize' field -func (st *ConfigState) SetCacheGTSFollowMaxSize(v int) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.FollowMaxSize = v - st.reloadToViper() -} - -// CacheGTSFollowMaxSizeFlag returns the flag name for the 'Cache.GTS.FollowMaxSize' field -func CacheGTSFollowMaxSizeFlag() string { return "cache-gts-follow-max-size" } - -// GetCacheGTSFollowMaxSize safely fetches the value for global configuration 'Cache.GTS.FollowMaxSize' field -func GetCacheGTSFollowMaxSize() int { return global.GetCacheGTSFollowMaxSize() } - -// SetCacheGTSFollowMaxSize safely sets the value for global configuration 'Cache.GTS.FollowMaxSize' field -func SetCacheGTSFollowMaxSize(v int) { global.SetCacheGTSFollowMaxSize(v) } - -// GetCacheGTSFollowTTL safely fetches the Configuration value for state's 'Cache.GTS.FollowTTL' field -func (st *ConfigState) GetCacheGTSFollowTTL() (v time.Duration) { - st.mutex.RLock() - v = st.config.Cache.GTS.FollowTTL - st.mutex.RUnlock() - return -} - -// SetCacheGTSFollowTTL safely sets the Configuration value for state's 'Cache.GTS.FollowTTL' field -func (st *ConfigState) SetCacheGTSFollowTTL(v time.Duration) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.FollowTTL = v - st.reloadToViper() -} - -// CacheGTSFollowTTLFlag returns the flag name for the 'Cache.GTS.FollowTTL' field -func CacheGTSFollowTTLFlag() string { return "cache-gts-follow-ttl" } - -// GetCacheGTSFollowTTL safely fetches the value for global configuration 'Cache.GTS.FollowTTL' field -func GetCacheGTSFollowTTL() time.Duration { return global.GetCacheGTSFollowTTL() } - -// SetCacheGTSFollowTTL safely sets the value for global configuration 'Cache.GTS.FollowTTL' field -func SetCacheGTSFollowTTL(v time.Duration) { global.SetCacheGTSFollowTTL(v) } - -// GetCacheGTSFollowSweepFreq safely fetches the Configuration value for state's 'Cache.GTS.FollowSweepFreq' field -func (st *ConfigState) GetCacheGTSFollowSweepFreq() (v time.Duration) { - st.mutex.RLock() - v = st.config.Cache.GTS.FollowSweepFreq - st.mutex.RUnlock() - return -} - -// SetCacheGTSFollowSweepFreq safely sets the Configuration value for state's 'Cache.GTS.FollowSweepFreq' field -func (st *ConfigState) SetCacheGTSFollowSweepFreq(v time.Duration) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.FollowSweepFreq = v - st.reloadToViper() -} - -// CacheGTSFollowSweepFreqFlag returns the flag name for the 'Cache.GTS.FollowSweepFreq' field -func CacheGTSFollowSweepFreqFlag() string { return "cache-gts-follow-sweep-freq" } - -// GetCacheGTSFollowSweepFreq safely fetches the value for global configuration 'Cache.GTS.FollowSweepFreq' field -func GetCacheGTSFollowSweepFreq() time.Duration { return global.GetCacheGTSFollowSweepFreq() } - -// SetCacheGTSFollowSweepFreq safely sets the value for global configuration 'Cache.GTS.FollowSweepFreq' field -func SetCacheGTSFollowSweepFreq(v time.Duration) { global.SetCacheGTSFollowSweepFreq(v) } - -// GetCacheGTSFollowIDsMaxSize safely fetches the Configuration value for state's 'Cache.GTS.FollowIDsMaxSize' field -func (st *ConfigState) GetCacheGTSFollowIDsMaxSize() (v int) { - st.mutex.RLock() - v = st.config.Cache.GTS.FollowIDsMaxSize - st.mutex.RUnlock() - return -} - -// SetCacheGTSFollowIDsMaxSize safely sets the Configuration value for state's 'Cache.GTS.FollowIDsMaxSize' field -func (st *ConfigState) SetCacheGTSFollowIDsMaxSize(v int) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.FollowIDsMaxSize = v - st.reloadToViper() -} - -// CacheGTSFollowIDsMaxSizeFlag returns the flag name for the 'Cache.GTS.FollowIDsMaxSize' field -func CacheGTSFollowIDsMaxSizeFlag() string { return "cache-gts-follow-ids-max-size" } - -// GetCacheGTSFollowIDsMaxSize safely fetches the value for global configuration 'Cache.GTS.FollowIDsMaxSize' field -func GetCacheGTSFollowIDsMaxSize() int { return global.GetCacheGTSFollowIDsMaxSize() } - -// SetCacheGTSFollowIDsMaxSize safely sets the value for global configuration 'Cache.GTS.FollowIDsMaxSize' field -func SetCacheGTSFollowIDsMaxSize(v int) { global.SetCacheGTSFollowIDsMaxSize(v) } - -// GetCacheGTSFollowIDsTTL safely fetches the Configuration value for state's 'Cache.GTS.FollowIDsTTL' field -func (st *ConfigState) GetCacheGTSFollowIDsTTL() (v time.Duration) { - st.mutex.RLock() - v = st.config.Cache.GTS.FollowIDsTTL - st.mutex.RUnlock() - return -} - -// SetCacheGTSFollowIDsTTL safely sets the Configuration value for state's 'Cache.GTS.FollowIDsTTL' field -func (st *ConfigState) SetCacheGTSFollowIDsTTL(v time.Duration) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.FollowIDsTTL = v - st.reloadToViper() -} - -// CacheGTSFollowIDsTTLFlag returns the flag name for the 'Cache.GTS.FollowIDsTTL' field -func CacheGTSFollowIDsTTLFlag() string { return "cache-gts-follow-ids-ttl" } - -// GetCacheGTSFollowIDsTTL safely fetches the value for global configuration 'Cache.GTS.FollowIDsTTL' field -func GetCacheGTSFollowIDsTTL() time.Duration { return global.GetCacheGTSFollowIDsTTL() } - -// SetCacheGTSFollowIDsTTL safely sets the value for global configuration 'Cache.GTS.FollowIDsTTL' field -func SetCacheGTSFollowIDsTTL(v time.Duration) { global.SetCacheGTSFollowIDsTTL(v) } - -// GetCacheGTSFollowIDsSweepFreq safely fetches the Configuration value for state's 'Cache.GTS.FollowIDsSweepFreq' field -func (st *ConfigState) GetCacheGTSFollowIDsSweepFreq() (v time.Duration) { - st.mutex.RLock() - v = st.config.Cache.GTS.FollowIDsSweepFreq - st.mutex.RUnlock() - return -} - -// SetCacheGTSFollowIDsSweepFreq safely sets the Configuration value for state's 'Cache.GTS.FollowIDsSweepFreq' field -func (st *ConfigState) SetCacheGTSFollowIDsSweepFreq(v time.Duration) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.FollowIDsSweepFreq = v - st.reloadToViper() -} - -// CacheGTSFollowIDsSweepFreqFlag returns the flag name for the 'Cache.GTS.FollowIDsSweepFreq' field -func CacheGTSFollowIDsSweepFreqFlag() string { return "cache-gts-follow-ids-sweep-freq" } - -// GetCacheGTSFollowIDsSweepFreq safely fetches the value for global configuration 'Cache.GTS.FollowIDsSweepFreq' field -func GetCacheGTSFollowIDsSweepFreq() time.Duration { return global.GetCacheGTSFollowIDsSweepFreq() } - -// SetCacheGTSFollowIDsSweepFreq safely sets the value for global configuration 'Cache.GTS.FollowIDsSweepFreq' field -func SetCacheGTSFollowIDsSweepFreq(v time.Duration) { global.SetCacheGTSFollowIDsSweepFreq(v) } - -// GetCacheGTSFollowRequestMaxSize safely fetches the Configuration value for state's 'Cache.GTS.FollowRequestMaxSize' field -func (st *ConfigState) GetCacheGTSFollowRequestMaxSize() (v int) { - st.mutex.RLock() - v = st.config.Cache.GTS.FollowRequestMaxSize - st.mutex.RUnlock() - return -} - -// SetCacheGTSFollowRequestMaxSize safely sets the Configuration value for state's 'Cache.GTS.FollowRequestMaxSize' field -func (st *ConfigState) SetCacheGTSFollowRequestMaxSize(v int) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.FollowRequestMaxSize = v - st.reloadToViper() -} - -// CacheGTSFollowRequestMaxSizeFlag returns the flag name for the 'Cache.GTS.FollowRequestMaxSize' field -func CacheGTSFollowRequestMaxSizeFlag() string { return "cache-gts-follow-request-max-size" } - -// GetCacheGTSFollowRequestMaxSize safely fetches the value for global configuration 'Cache.GTS.FollowRequestMaxSize' field -func GetCacheGTSFollowRequestMaxSize() int { return global.GetCacheGTSFollowRequestMaxSize() } - -// SetCacheGTSFollowRequestMaxSize safely sets the value for global configuration 'Cache.GTS.FollowRequestMaxSize' field -func SetCacheGTSFollowRequestMaxSize(v int) { global.SetCacheGTSFollowRequestMaxSize(v) } - -// GetCacheGTSFollowRequestTTL safely fetches the Configuration value for state's 'Cache.GTS.FollowRequestTTL' field -func (st *ConfigState) GetCacheGTSFollowRequestTTL() (v time.Duration) { - st.mutex.RLock() - v = st.config.Cache.GTS.FollowRequestTTL - st.mutex.RUnlock() - return -} - -// SetCacheGTSFollowRequestTTL safely sets the Configuration value for state's 'Cache.GTS.FollowRequestTTL' field -func (st *ConfigState) SetCacheGTSFollowRequestTTL(v time.Duration) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.FollowRequestTTL = v - st.reloadToViper() -} - -// CacheGTSFollowRequestTTLFlag returns the flag name for the 'Cache.GTS.FollowRequestTTL' field -func CacheGTSFollowRequestTTLFlag() string { return "cache-gts-follow-request-ttl" } - -// GetCacheGTSFollowRequestTTL safely fetches the value for global configuration 'Cache.GTS.FollowRequestTTL' field -func GetCacheGTSFollowRequestTTL() time.Duration { return global.GetCacheGTSFollowRequestTTL() } - -// SetCacheGTSFollowRequestTTL safely sets the value for global configuration 'Cache.GTS.FollowRequestTTL' field -func SetCacheGTSFollowRequestTTL(v time.Duration) { global.SetCacheGTSFollowRequestTTL(v) } - -// GetCacheGTSFollowRequestSweepFreq safely fetches the Configuration value for state's 'Cache.GTS.FollowRequestSweepFreq' field -func (st *ConfigState) GetCacheGTSFollowRequestSweepFreq() (v time.Duration) { - st.mutex.RLock() - v = st.config.Cache.GTS.FollowRequestSweepFreq - st.mutex.RUnlock() - return -} - -// SetCacheGTSFollowRequestSweepFreq safely sets the Configuration value for state's 'Cache.GTS.FollowRequestSweepFreq' field -func (st *ConfigState) SetCacheGTSFollowRequestSweepFreq(v time.Duration) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.FollowRequestSweepFreq = v - st.reloadToViper() -} - -// CacheGTSFollowRequestSweepFreqFlag returns the flag name for the 'Cache.GTS.FollowRequestSweepFreq' field -func CacheGTSFollowRequestSweepFreqFlag() string { return "cache-gts-follow-request-sweep-freq" } - -// GetCacheGTSFollowRequestSweepFreq safely fetches the value for global configuration 'Cache.GTS.FollowRequestSweepFreq' field -func GetCacheGTSFollowRequestSweepFreq() time.Duration { - return global.GetCacheGTSFollowRequestSweepFreq() -} - -// SetCacheGTSFollowRequestSweepFreq safely sets the value for global configuration 'Cache.GTS.FollowRequestSweepFreq' field -func SetCacheGTSFollowRequestSweepFreq(v time.Duration) { global.SetCacheGTSFollowRequestSweepFreq(v) } - -// GetCacheGTSFollowRequestIDsMaxSize safely fetches the Configuration value for state's 'Cache.GTS.FollowRequestIDsMaxSize' field -func (st *ConfigState) GetCacheGTSFollowRequestIDsMaxSize() (v int) { - st.mutex.RLock() - v = st.config.Cache.GTS.FollowRequestIDsMaxSize - st.mutex.RUnlock() - return -} - -// SetCacheGTSFollowRequestIDsMaxSize safely sets the Configuration value for state's 'Cache.GTS.FollowRequestIDsMaxSize' field -func (st *ConfigState) SetCacheGTSFollowRequestIDsMaxSize(v int) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.FollowRequestIDsMaxSize = v - st.reloadToViper() -} - -// CacheGTSFollowRequestIDsMaxSizeFlag returns the flag name for the 'Cache.GTS.FollowRequestIDsMaxSize' field -func CacheGTSFollowRequestIDsMaxSizeFlag() string { return "cache-gts-follow-request-ids-max-size" } - -// GetCacheGTSFollowRequestIDsMaxSize safely fetches the value for global configuration 'Cache.GTS.FollowRequestIDsMaxSize' field -func GetCacheGTSFollowRequestIDsMaxSize() int { return global.GetCacheGTSFollowRequestIDsMaxSize() } - -// SetCacheGTSFollowRequestIDsMaxSize safely sets the value for global configuration 'Cache.GTS.FollowRequestIDsMaxSize' field -func SetCacheGTSFollowRequestIDsMaxSize(v int) { global.SetCacheGTSFollowRequestIDsMaxSize(v) } - -// GetCacheGTSFollowRequestIDsTTL safely fetches the Configuration value for state's 'Cache.GTS.FollowRequestIDsTTL' field -func (st *ConfigState) GetCacheGTSFollowRequestIDsTTL() (v time.Duration) { - st.mutex.RLock() - v = st.config.Cache.GTS.FollowRequestIDsTTL - st.mutex.RUnlock() - return -} - -// SetCacheGTSFollowRequestIDsTTL safely sets the Configuration value for state's 'Cache.GTS.FollowRequestIDsTTL' field -func (st *ConfigState) SetCacheGTSFollowRequestIDsTTL(v time.Duration) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.FollowRequestIDsTTL = v - st.reloadToViper() -} - -// CacheGTSFollowRequestIDsTTLFlag returns the flag name for the 'Cache.GTS.FollowRequestIDsTTL' field -func CacheGTSFollowRequestIDsTTLFlag() string { return "cache-gts-follow-request-ids-ttl" } - -// GetCacheGTSFollowRequestIDsTTL safely fetches the value for global configuration 'Cache.GTS.FollowRequestIDsTTL' field -func GetCacheGTSFollowRequestIDsTTL() time.Duration { return global.GetCacheGTSFollowRequestIDsTTL() } - -// SetCacheGTSFollowRequestIDsTTL safely sets the value for global configuration 'Cache.GTS.FollowRequestIDsTTL' field -func SetCacheGTSFollowRequestIDsTTL(v time.Duration) { global.SetCacheGTSFollowRequestIDsTTL(v) } - -// GetCacheGTSFollowRequestIDsSweepFreq safely fetches the Configuration value for state's 'Cache.GTS.FollowRequestIDsSweepFreq' field -func (st *ConfigState) GetCacheGTSFollowRequestIDsSweepFreq() (v time.Duration) { - st.mutex.RLock() - v = st.config.Cache.GTS.FollowRequestIDsSweepFreq - st.mutex.RUnlock() - return -} - -// SetCacheGTSFollowRequestIDsSweepFreq safely sets the Configuration value for state's 'Cache.GTS.FollowRequestIDsSweepFreq' field -func (st *ConfigState) SetCacheGTSFollowRequestIDsSweepFreq(v time.Duration) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.FollowRequestIDsSweepFreq = v - st.reloadToViper() -} - -// CacheGTSFollowRequestIDsSweepFreqFlag returns the flag name for the 'Cache.GTS.FollowRequestIDsSweepFreq' field -func CacheGTSFollowRequestIDsSweepFreqFlag() string { return "cache-gts-follow-request-ids-sweep-freq" } - -// GetCacheGTSFollowRequestIDsSweepFreq safely fetches the value for global configuration 'Cache.GTS.FollowRequestIDsSweepFreq' field -func GetCacheGTSFollowRequestIDsSweepFreq() time.Duration { - return global.GetCacheGTSFollowRequestIDsSweepFreq() -} - -// SetCacheGTSFollowRequestIDsSweepFreq safely sets the value for global configuration 'Cache.GTS.FollowRequestIDsSweepFreq' field -func SetCacheGTSFollowRequestIDsSweepFreq(v time.Duration) { - global.SetCacheGTSFollowRequestIDsSweepFreq(v) -} - -// GetCacheGTSInstanceMaxSize safely fetches the Configuration value for state's 'Cache.GTS.InstanceMaxSize' field -func (st *ConfigState) GetCacheGTSInstanceMaxSize() (v int) { - st.mutex.RLock() - v = st.config.Cache.GTS.InstanceMaxSize - st.mutex.RUnlock() - return -} - -// SetCacheGTSInstanceMaxSize safely sets the Configuration value for state's 'Cache.GTS.InstanceMaxSize' field -func (st *ConfigState) SetCacheGTSInstanceMaxSize(v int) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.InstanceMaxSize = v - st.reloadToViper() -} - -// CacheGTSInstanceMaxSizeFlag returns the flag name for the 'Cache.GTS.InstanceMaxSize' field -func CacheGTSInstanceMaxSizeFlag() string { return "cache-gts-instance-max-size" } - -// GetCacheGTSInstanceMaxSize safely fetches the value for global configuration 'Cache.GTS.InstanceMaxSize' field -func GetCacheGTSInstanceMaxSize() int { return global.GetCacheGTSInstanceMaxSize() } - -// SetCacheGTSInstanceMaxSize safely sets the value for global configuration 'Cache.GTS.InstanceMaxSize' field -func SetCacheGTSInstanceMaxSize(v int) { global.SetCacheGTSInstanceMaxSize(v) } - -// GetCacheGTSInstanceTTL safely fetches the Configuration value for state's 'Cache.GTS.InstanceTTL' field -func (st *ConfigState) GetCacheGTSInstanceTTL() (v time.Duration) { - st.mutex.RLock() - v = st.config.Cache.GTS.InstanceTTL - st.mutex.RUnlock() - return -} - -// SetCacheGTSInstanceTTL safely sets the Configuration value for state's 'Cache.GTS.InstanceTTL' field -func (st *ConfigState) SetCacheGTSInstanceTTL(v time.Duration) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.InstanceTTL = v - st.reloadToViper() -} - -// CacheGTSInstanceTTLFlag returns the flag name for the 'Cache.GTS.InstanceTTL' field -func CacheGTSInstanceTTLFlag() string { return "cache-gts-instance-ttl" } - -// GetCacheGTSInstanceTTL safely fetches the value for global configuration 'Cache.GTS.InstanceTTL' field -func GetCacheGTSInstanceTTL() time.Duration { return global.GetCacheGTSInstanceTTL() } - -// SetCacheGTSInstanceTTL safely sets the value for global configuration 'Cache.GTS.InstanceTTL' field -func SetCacheGTSInstanceTTL(v time.Duration) { global.SetCacheGTSInstanceTTL(v) } - -// GetCacheGTSInstanceSweepFreq safely fetches the Configuration value for state's 'Cache.GTS.InstanceSweepFreq' field -func (st *ConfigState) GetCacheGTSInstanceSweepFreq() (v time.Duration) { - st.mutex.RLock() - v = st.config.Cache.GTS.InstanceSweepFreq - st.mutex.RUnlock() - return -} - -// SetCacheGTSInstanceSweepFreq safely sets the Configuration value for state's 'Cache.GTS.InstanceSweepFreq' field -func (st *ConfigState) SetCacheGTSInstanceSweepFreq(v time.Duration) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.InstanceSweepFreq = v - st.reloadToViper() -} - -// CacheGTSInstanceSweepFreqFlag returns the flag name for the 'Cache.GTS.InstanceSweepFreq' field -func CacheGTSInstanceSweepFreqFlag() string { return "cache-gts-instance-sweep-freq" } - -// GetCacheGTSInstanceSweepFreq safely fetches the value for global configuration 'Cache.GTS.InstanceSweepFreq' field -func GetCacheGTSInstanceSweepFreq() time.Duration { return global.GetCacheGTSInstanceSweepFreq() } - -// SetCacheGTSInstanceSweepFreq safely sets the value for global configuration 'Cache.GTS.InstanceSweepFreq' field -func SetCacheGTSInstanceSweepFreq(v time.Duration) { global.SetCacheGTSInstanceSweepFreq(v) } - -// GetCacheGTSListMaxSize safely fetches the Configuration value for state's 'Cache.GTS.ListMaxSize' field -func (st *ConfigState) GetCacheGTSListMaxSize() (v int) { - st.mutex.RLock() - v = st.config.Cache.GTS.ListMaxSize - st.mutex.RUnlock() - return -} - -// SetCacheGTSListMaxSize safely sets the Configuration value for state's 'Cache.GTS.ListMaxSize' field -func (st *ConfigState) SetCacheGTSListMaxSize(v int) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.ListMaxSize = v - st.reloadToViper() -} - -// CacheGTSListMaxSizeFlag returns the flag name for the 'Cache.GTS.ListMaxSize' field -func CacheGTSListMaxSizeFlag() string { return "cache-gts-list-max-size" } - -// GetCacheGTSListMaxSize safely fetches the value for global configuration 'Cache.GTS.ListMaxSize' field -func GetCacheGTSListMaxSize() int { return global.GetCacheGTSListMaxSize() } - -// SetCacheGTSListMaxSize safely sets the value for global configuration 'Cache.GTS.ListMaxSize' field -func SetCacheGTSListMaxSize(v int) { global.SetCacheGTSListMaxSize(v) } - -// GetCacheGTSListTTL safely fetches the Configuration value for state's 'Cache.GTS.ListTTL' field -func (st *ConfigState) GetCacheGTSListTTL() (v time.Duration) { - st.mutex.RLock() - v = st.config.Cache.GTS.ListTTL - st.mutex.RUnlock() - return -} - -// SetCacheGTSListTTL safely sets the Configuration value for state's 'Cache.GTS.ListTTL' field -func (st *ConfigState) SetCacheGTSListTTL(v time.Duration) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.ListTTL = v - st.reloadToViper() -} - -// CacheGTSListTTLFlag returns the flag name for the 'Cache.GTS.ListTTL' field -func CacheGTSListTTLFlag() string { return "cache-gts-list-ttl" } - -// GetCacheGTSListTTL safely fetches the value for global configuration 'Cache.GTS.ListTTL' field -func GetCacheGTSListTTL() time.Duration { return global.GetCacheGTSListTTL() } - -// SetCacheGTSListTTL safely sets the value for global configuration 'Cache.GTS.ListTTL' field -func SetCacheGTSListTTL(v time.Duration) { global.SetCacheGTSListTTL(v) } - -// GetCacheGTSListSweepFreq safely fetches the Configuration value for state's 'Cache.GTS.ListSweepFreq' field -func (st *ConfigState) GetCacheGTSListSweepFreq() (v time.Duration) { - st.mutex.RLock() - v = st.config.Cache.GTS.ListSweepFreq - st.mutex.RUnlock() - return -} - -// SetCacheGTSListSweepFreq safely sets the Configuration value for state's 'Cache.GTS.ListSweepFreq' field -func (st *ConfigState) SetCacheGTSListSweepFreq(v time.Duration) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.ListSweepFreq = v - st.reloadToViper() -} - -// CacheGTSListSweepFreqFlag returns the flag name for the 'Cache.GTS.ListSweepFreq' field -func CacheGTSListSweepFreqFlag() string { return "cache-gts-list-sweep-freq" } - -// GetCacheGTSListSweepFreq safely fetches the value for global configuration 'Cache.GTS.ListSweepFreq' field -func GetCacheGTSListSweepFreq() time.Duration { return global.GetCacheGTSListSweepFreq() } - -// SetCacheGTSListSweepFreq safely sets the value for global configuration 'Cache.GTS.ListSweepFreq' field -func SetCacheGTSListSweepFreq(v time.Duration) { global.SetCacheGTSListSweepFreq(v) } - -// GetCacheGTSListEntryMaxSize safely fetches the Configuration value for state's 'Cache.GTS.ListEntryMaxSize' field -func (st *ConfigState) GetCacheGTSListEntryMaxSize() (v int) { - st.mutex.RLock() - v = st.config.Cache.GTS.ListEntryMaxSize - st.mutex.RUnlock() - return -} - -// SetCacheGTSListEntryMaxSize safely sets the Configuration value for state's 'Cache.GTS.ListEntryMaxSize' field -func (st *ConfigState) SetCacheGTSListEntryMaxSize(v int) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.ListEntryMaxSize = v - st.reloadToViper() -} - -// CacheGTSListEntryMaxSizeFlag returns the flag name for the 'Cache.GTS.ListEntryMaxSize' field -func CacheGTSListEntryMaxSizeFlag() string { return "cache-gts-list-entry-max-size" } - -// GetCacheGTSListEntryMaxSize safely fetches the value for global configuration 'Cache.GTS.ListEntryMaxSize' field -func GetCacheGTSListEntryMaxSize() int { return global.GetCacheGTSListEntryMaxSize() } - -// SetCacheGTSListEntryMaxSize safely sets the value for global configuration 'Cache.GTS.ListEntryMaxSize' field -func SetCacheGTSListEntryMaxSize(v int) { global.SetCacheGTSListEntryMaxSize(v) } - -// GetCacheGTSListEntryTTL safely fetches the Configuration value for state's 'Cache.GTS.ListEntryTTL' field -func (st *ConfigState) GetCacheGTSListEntryTTL() (v time.Duration) { - st.mutex.RLock() - v = st.config.Cache.GTS.ListEntryTTL - st.mutex.RUnlock() - return -} - -// SetCacheGTSListEntryTTL safely sets the Configuration value for state's 'Cache.GTS.ListEntryTTL' field -func (st *ConfigState) SetCacheGTSListEntryTTL(v time.Duration) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.ListEntryTTL = v - st.reloadToViper() -} - -// CacheGTSListEntryTTLFlag returns the flag name for the 'Cache.GTS.ListEntryTTL' field -func CacheGTSListEntryTTLFlag() string { return "cache-gts-list-entry-ttl" } - -// GetCacheGTSListEntryTTL safely fetches the value for global configuration 'Cache.GTS.ListEntryTTL' field -func GetCacheGTSListEntryTTL() time.Duration { return global.GetCacheGTSListEntryTTL() } - -// SetCacheGTSListEntryTTL safely sets the value for global configuration 'Cache.GTS.ListEntryTTL' field -func SetCacheGTSListEntryTTL(v time.Duration) { global.SetCacheGTSListEntryTTL(v) } - -// GetCacheGTSListEntrySweepFreq safely fetches the Configuration value for state's 'Cache.GTS.ListEntrySweepFreq' field -func (st *ConfigState) GetCacheGTSListEntrySweepFreq() (v time.Duration) { - st.mutex.RLock() - v = st.config.Cache.GTS.ListEntrySweepFreq - st.mutex.RUnlock() - return -} - -// SetCacheGTSListEntrySweepFreq safely sets the Configuration value for state's 'Cache.GTS.ListEntrySweepFreq' field -func (st *ConfigState) SetCacheGTSListEntrySweepFreq(v time.Duration) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.ListEntrySweepFreq = v - st.reloadToViper() -} - -// CacheGTSListEntrySweepFreqFlag returns the flag name for the 'Cache.GTS.ListEntrySweepFreq' field -func CacheGTSListEntrySweepFreqFlag() string { return "cache-gts-list-entry-sweep-freq" } - -// GetCacheGTSListEntrySweepFreq safely fetches the value for global configuration 'Cache.GTS.ListEntrySweepFreq' field -func GetCacheGTSListEntrySweepFreq() time.Duration { return global.GetCacheGTSListEntrySweepFreq() } - -// SetCacheGTSListEntrySweepFreq safely sets the value for global configuration 'Cache.GTS.ListEntrySweepFreq' field -func SetCacheGTSListEntrySweepFreq(v time.Duration) { global.SetCacheGTSListEntrySweepFreq(v) } - -// GetCacheGTSMarkerMaxSize safely fetches the Configuration value for state's 'Cache.GTS.MarkerMaxSize' field -func (st *ConfigState) GetCacheGTSMarkerMaxSize() (v int) { - st.mutex.RLock() - v = st.config.Cache.GTS.MarkerMaxSize - st.mutex.RUnlock() - return -} - -// SetCacheGTSMarkerMaxSize safely sets the Configuration value for state's 'Cache.GTS.MarkerMaxSize' field -func (st *ConfigState) SetCacheGTSMarkerMaxSize(v int) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.MarkerMaxSize = v - st.reloadToViper() -} - -// CacheGTSMarkerMaxSizeFlag returns the flag name for the 'Cache.GTS.MarkerMaxSize' field -func CacheGTSMarkerMaxSizeFlag() string { return "cache-gts-marker-max-size" } - -// GetCacheGTSMarkerMaxSize safely fetches the value for global configuration 'Cache.GTS.MarkerMaxSize' field -func GetCacheGTSMarkerMaxSize() int { return global.GetCacheGTSMarkerMaxSize() } - -// SetCacheGTSMarkerMaxSize safely sets the value for global configuration 'Cache.GTS.MarkerMaxSize' field -func SetCacheGTSMarkerMaxSize(v int) { global.SetCacheGTSMarkerMaxSize(v) } - -// GetCacheGTSMarkerTTL safely fetches the Configuration value for state's 'Cache.GTS.MarkerTTL' field -func (st *ConfigState) GetCacheGTSMarkerTTL() (v time.Duration) { - st.mutex.RLock() - v = st.config.Cache.GTS.MarkerTTL - st.mutex.RUnlock() - return -} - -// SetCacheGTSMarkerTTL safely sets the Configuration value for state's 'Cache.GTS.MarkerTTL' field -func (st *ConfigState) SetCacheGTSMarkerTTL(v time.Duration) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.MarkerTTL = v - st.reloadToViper() -} - -// CacheGTSMarkerTTLFlag returns the flag name for the 'Cache.GTS.MarkerTTL' field -func CacheGTSMarkerTTLFlag() string { return "cache-gts-marker-ttl" } - -// GetCacheGTSMarkerTTL safely fetches the value for global configuration 'Cache.GTS.MarkerTTL' field -func GetCacheGTSMarkerTTL() time.Duration { return global.GetCacheGTSMarkerTTL() } - -// SetCacheGTSMarkerTTL safely sets the value for global configuration 'Cache.GTS.MarkerTTL' field -func SetCacheGTSMarkerTTL(v time.Duration) { global.SetCacheGTSMarkerTTL(v) } - -// GetCacheGTSMarkerSweepFreq safely fetches the Configuration value for state's 'Cache.GTS.MarkerSweepFreq' field -func (st *ConfigState) GetCacheGTSMarkerSweepFreq() (v time.Duration) { - st.mutex.RLock() - v = st.config.Cache.GTS.MarkerSweepFreq - st.mutex.RUnlock() - return -} - -// SetCacheGTSMarkerSweepFreq safely sets the Configuration value for state's 'Cache.GTS.MarkerSweepFreq' field -func (st *ConfigState) SetCacheGTSMarkerSweepFreq(v time.Duration) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.MarkerSweepFreq = v - st.reloadToViper() -} - -// CacheGTSMarkerSweepFreqFlag returns the flag name for the 'Cache.GTS.MarkerSweepFreq' field -func CacheGTSMarkerSweepFreqFlag() string { return "cache-gts-marker-sweep-freq" } - -// GetCacheGTSMarkerSweepFreq safely fetches the value for global configuration 'Cache.GTS.MarkerSweepFreq' field -func GetCacheGTSMarkerSweepFreq() time.Duration { return global.GetCacheGTSMarkerSweepFreq() } - -// SetCacheGTSMarkerSweepFreq safely sets the value for global configuration 'Cache.GTS.MarkerSweepFreq' field -func SetCacheGTSMarkerSweepFreq(v time.Duration) { global.SetCacheGTSMarkerSweepFreq(v) } - -// GetCacheGTSMediaMaxSize safely fetches the Configuration value for state's 'Cache.GTS.MediaMaxSize' field -func (st *ConfigState) GetCacheGTSMediaMaxSize() (v int) { - st.mutex.RLock() - v = st.config.Cache.GTS.MediaMaxSize - st.mutex.RUnlock() - return -} - -// SetCacheGTSMediaMaxSize safely sets the Configuration value for state's 'Cache.GTS.MediaMaxSize' field -func (st *ConfigState) SetCacheGTSMediaMaxSize(v int) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.MediaMaxSize = v - st.reloadToViper() -} - -// CacheGTSMediaMaxSizeFlag returns the flag name for the 'Cache.GTS.MediaMaxSize' field -func CacheGTSMediaMaxSizeFlag() string { return "cache-gts-media-max-size" } - -// GetCacheGTSMediaMaxSize safely fetches the value for global configuration 'Cache.GTS.MediaMaxSize' field -func GetCacheGTSMediaMaxSize() int { return global.GetCacheGTSMediaMaxSize() } - -// SetCacheGTSMediaMaxSize safely sets the value for global configuration 'Cache.GTS.MediaMaxSize' field -func SetCacheGTSMediaMaxSize(v int) { global.SetCacheGTSMediaMaxSize(v) } - -// GetCacheGTSMediaTTL safely fetches the Configuration value for state's 'Cache.GTS.MediaTTL' field -func (st *ConfigState) GetCacheGTSMediaTTL() (v time.Duration) { - st.mutex.RLock() - v = st.config.Cache.GTS.MediaTTL - st.mutex.RUnlock() - return -} - -// SetCacheGTSMediaTTL safely sets the Configuration value for state's 'Cache.GTS.MediaTTL' field -func (st *ConfigState) SetCacheGTSMediaTTL(v time.Duration) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.MediaTTL = v - st.reloadToViper() -} - -// CacheGTSMediaTTLFlag returns the flag name for the 'Cache.GTS.MediaTTL' field -func CacheGTSMediaTTLFlag() string { return "cache-gts-media-ttl" } - -// GetCacheGTSMediaTTL safely fetches the value for global configuration 'Cache.GTS.MediaTTL' field -func GetCacheGTSMediaTTL() time.Duration { return global.GetCacheGTSMediaTTL() } - -// SetCacheGTSMediaTTL safely sets the value for global configuration 'Cache.GTS.MediaTTL' field -func SetCacheGTSMediaTTL(v time.Duration) { global.SetCacheGTSMediaTTL(v) } - -// GetCacheGTSMediaSweepFreq safely fetches the Configuration value for state's 'Cache.GTS.MediaSweepFreq' field -func (st *ConfigState) GetCacheGTSMediaSweepFreq() (v time.Duration) { - st.mutex.RLock() - v = st.config.Cache.GTS.MediaSweepFreq - st.mutex.RUnlock() - return -} - -// SetCacheGTSMediaSweepFreq safely sets the Configuration value for state's 'Cache.GTS.MediaSweepFreq' field -func (st *ConfigState) SetCacheGTSMediaSweepFreq(v time.Duration) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.MediaSweepFreq = v - st.reloadToViper() -} - -// CacheGTSMediaSweepFreqFlag returns the flag name for the 'Cache.GTS.MediaSweepFreq' field -func CacheGTSMediaSweepFreqFlag() string { return "cache-gts-media-sweep-freq" } - -// GetCacheGTSMediaSweepFreq safely fetches the value for global configuration 'Cache.GTS.MediaSweepFreq' field -func GetCacheGTSMediaSweepFreq() time.Duration { return global.GetCacheGTSMediaSweepFreq() } - -// SetCacheGTSMediaSweepFreq safely sets the value for global configuration 'Cache.GTS.MediaSweepFreq' field -func SetCacheGTSMediaSweepFreq(v time.Duration) { global.SetCacheGTSMediaSweepFreq(v) } - -// GetCacheGTSMentionMaxSize safely fetches the Configuration value for state's 'Cache.GTS.MentionMaxSize' field -func (st *ConfigState) GetCacheGTSMentionMaxSize() (v int) { - st.mutex.RLock() - v = st.config.Cache.GTS.MentionMaxSize - st.mutex.RUnlock() - return -} - -// SetCacheGTSMentionMaxSize safely sets the Configuration value for state's 'Cache.GTS.MentionMaxSize' field -func (st *ConfigState) SetCacheGTSMentionMaxSize(v int) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.MentionMaxSize = v - st.reloadToViper() -} - -// CacheGTSMentionMaxSizeFlag returns the flag name for the 'Cache.GTS.MentionMaxSize' field -func CacheGTSMentionMaxSizeFlag() string { return "cache-gts-mention-max-size" } - -// GetCacheGTSMentionMaxSize safely fetches the value for global configuration 'Cache.GTS.MentionMaxSize' field -func GetCacheGTSMentionMaxSize() int { return global.GetCacheGTSMentionMaxSize() } - -// SetCacheGTSMentionMaxSize safely sets the value for global configuration 'Cache.GTS.MentionMaxSize' field -func SetCacheGTSMentionMaxSize(v int) { global.SetCacheGTSMentionMaxSize(v) } - -// GetCacheGTSMentionTTL safely fetches the Configuration value for state's 'Cache.GTS.MentionTTL' field -func (st *ConfigState) GetCacheGTSMentionTTL() (v time.Duration) { - st.mutex.RLock() - v = st.config.Cache.GTS.MentionTTL - st.mutex.RUnlock() - return -} - -// SetCacheGTSMentionTTL safely sets the Configuration value for state's 'Cache.GTS.MentionTTL' field -func (st *ConfigState) SetCacheGTSMentionTTL(v time.Duration) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.MentionTTL = v - st.reloadToViper() -} - -// CacheGTSMentionTTLFlag returns the flag name for the 'Cache.GTS.MentionTTL' field -func CacheGTSMentionTTLFlag() string { return "cache-gts-mention-ttl" } - -// GetCacheGTSMentionTTL safely fetches the value for global configuration 'Cache.GTS.MentionTTL' field -func GetCacheGTSMentionTTL() time.Duration { return global.GetCacheGTSMentionTTL() } - -// SetCacheGTSMentionTTL safely sets the value for global configuration 'Cache.GTS.MentionTTL' field -func SetCacheGTSMentionTTL(v time.Duration) { global.SetCacheGTSMentionTTL(v) } - -// GetCacheGTSMentionSweepFreq safely fetches the Configuration value for state's 'Cache.GTS.MentionSweepFreq' field -func (st *ConfigState) GetCacheGTSMentionSweepFreq() (v time.Duration) { - st.mutex.RLock() - v = st.config.Cache.GTS.MentionSweepFreq - st.mutex.RUnlock() - return -} - -// SetCacheGTSMentionSweepFreq safely sets the Configuration value for state's 'Cache.GTS.MentionSweepFreq' field -func (st *ConfigState) SetCacheGTSMentionSweepFreq(v time.Duration) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.MentionSweepFreq = v - st.reloadToViper() -} - -// CacheGTSMentionSweepFreqFlag returns the flag name for the 'Cache.GTS.MentionSweepFreq' field -func CacheGTSMentionSweepFreqFlag() string { return "cache-gts-mention-sweep-freq" } - -// GetCacheGTSMentionSweepFreq safely fetches the value for global configuration 'Cache.GTS.MentionSweepFreq' field -func GetCacheGTSMentionSweepFreq() time.Duration { return global.GetCacheGTSMentionSweepFreq() } - -// SetCacheGTSMentionSweepFreq safely sets the value for global configuration 'Cache.GTS.MentionSweepFreq' field -func SetCacheGTSMentionSweepFreq(v time.Duration) { global.SetCacheGTSMentionSweepFreq(v) } - -// GetCacheGTSNotificationMaxSize safely fetches the Configuration value for state's 'Cache.GTS.NotificationMaxSize' field -func (st *ConfigState) GetCacheGTSNotificationMaxSize() (v int) { - st.mutex.RLock() - v = st.config.Cache.GTS.NotificationMaxSize - st.mutex.RUnlock() - return -} - -// SetCacheGTSNotificationMaxSize safely sets the Configuration value for state's 'Cache.GTS.NotificationMaxSize' field -func (st *ConfigState) SetCacheGTSNotificationMaxSize(v int) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.NotificationMaxSize = v - st.reloadToViper() -} - -// CacheGTSNotificationMaxSizeFlag returns the flag name for the 'Cache.GTS.NotificationMaxSize' field -func CacheGTSNotificationMaxSizeFlag() string { return "cache-gts-notification-max-size" } - -// GetCacheGTSNotificationMaxSize safely fetches the value for global configuration 'Cache.GTS.NotificationMaxSize' field -func GetCacheGTSNotificationMaxSize() int { return global.GetCacheGTSNotificationMaxSize() } - -// SetCacheGTSNotificationMaxSize safely sets the value for global configuration 'Cache.GTS.NotificationMaxSize' field -func SetCacheGTSNotificationMaxSize(v int) { global.SetCacheGTSNotificationMaxSize(v) } - -// GetCacheGTSNotificationTTL safely fetches the Configuration value for state's 'Cache.GTS.NotificationTTL' field -func (st *ConfigState) GetCacheGTSNotificationTTL() (v time.Duration) { - st.mutex.RLock() - v = st.config.Cache.GTS.NotificationTTL - st.mutex.RUnlock() - return -} - -// SetCacheGTSNotificationTTL safely sets the Configuration value for state's 'Cache.GTS.NotificationTTL' field -func (st *ConfigState) SetCacheGTSNotificationTTL(v time.Duration) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.NotificationTTL = v - st.reloadToViper() -} - -// CacheGTSNotificationTTLFlag returns the flag name for the 'Cache.GTS.NotificationTTL' field -func CacheGTSNotificationTTLFlag() string { return "cache-gts-notification-ttl" } - -// GetCacheGTSNotificationTTL safely fetches the value for global configuration 'Cache.GTS.NotificationTTL' field -func GetCacheGTSNotificationTTL() time.Duration { return global.GetCacheGTSNotificationTTL() } - -// SetCacheGTSNotificationTTL safely sets the value for global configuration 'Cache.GTS.NotificationTTL' field -func SetCacheGTSNotificationTTL(v time.Duration) { global.SetCacheGTSNotificationTTL(v) } - -// GetCacheGTSNotificationSweepFreq safely fetches the Configuration value for state's 'Cache.GTS.NotificationSweepFreq' field -func (st *ConfigState) GetCacheGTSNotificationSweepFreq() (v time.Duration) { - st.mutex.RLock() - v = st.config.Cache.GTS.NotificationSweepFreq - st.mutex.RUnlock() - return -} - -// SetCacheGTSNotificationSweepFreq safely sets the Configuration value for state's 'Cache.GTS.NotificationSweepFreq' field -func (st *ConfigState) SetCacheGTSNotificationSweepFreq(v time.Duration) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.NotificationSweepFreq = v - st.reloadToViper() -} - -// CacheGTSNotificationSweepFreqFlag returns the flag name for the 'Cache.GTS.NotificationSweepFreq' field -func CacheGTSNotificationSweepFreqFlag() string { return "cache-gts-notification-sweep-freq" } - -// GetCacheGTSNotificationSweepFreq safely fetches the value for global configuration 'Cache.GTS.NotificationSweepFreq' field -func GetCacheGTSNotificationSweepFreq() time.Duration { - return global.GetCacheGTSNotificationSweepFreq() -} - -// SetCacheGTSNotificationSweepFreq safely sets the value for global configuration 'Cache.GTS.NotificationSweepFreq' field -func SetCacheGTSNotificationSweepFreq(v time.Duration) { global.SetCacheGTSNotificationSweepFreq(v) } - -// GetCacheGTSReportMaxSize safely fetches the Configuration value for state's 'Cache.GTS.ReportMaxSize' field -func (st *ConfigState) GetCacheGTSReportMaxSize() (v int) { - st.mutex.RLock() - v = st.config.Cache.GTS.ReportMaxSize - st.mutex.RUnlock() - return -} - -// SetCacheGTSReportMaxSize safely sets the Configuration value for state's 'Cache.GTS.ReportMaxSize' field -func (st *ConfigState) SetCacheGTSReportMaxSize(v int) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.ReportMaxSize = v - st.reloadToViper() -} - -// CacheGTSReportMaxSizeFlag returns the flag name for the 'Cache.GTS.ReportMaxSize' field -func CacheGTSReportMaxSizeFlag() string { return "cache-gts-report-max-size" } - -// GetCacheGTSReportMaxSize safely fetches the value for global configuration 'Cache.GTS.ReportMaxSize' field -func GetCacheGTSReportMaxSize() int { return global.GetCacheGTSReportMaxSize() } - -// SetCacheGTSReportMaxSize safely sets the value for global configuration 'Cache.GTS.ReportMaxSize' field -func SetCacheGTSReportMaxSize(v int) { global.SetCacheGTSReportMaxSize(v) } - -// GetCacheGTSReportTTL safely fetches the Configuration value for state's 'Cache.GTS.ReportTTL' field -func (st *ConfigState) GetCacheGTSReportTTL() (v time.Duration) { - st.mutex.RLock() - v = st.config.Cache.GTS.ReportTTL - st.mutex.RUnlock() - return -} - -// SetCacheGTSReportTTL safely sets the Configuration value for state's 'Cache.GTS.ReportTTL' field -func (st *ConfigState) SetCacheGTSReportTTL(v time.Duration) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.ReportTTL = v - st.reloadToViper() -} - -// CacheGTSReportTTLFlag returns the flag name for the 'Cache.GTS.ReportTTL' field -func CacheGTSReportTTLFlag() string { return "cache-gts-report-ttl" } - -// GetCacheGTSReportTTL safely fetches the value for global configuration 'Cache.GTS.ReportTTL' field -func GetCacheGTSReportTTL() time.Duration { return global.GetCacheGTSReportTTL() } - -// SetCacheGTSReportTTL safely sets the value for global configuration 'Cache.GTS.ReportTTL' field -func SetCacheGTSReportTTL(v time.Duration) { global.SetCacheGTSReportTTL(v) } - -// GetCacheGTSReportSweepFreq safely fetches the Configuration value for state's 'Cache.GTS.ReportSweepFreq' field -func (st *ConfigState) GetCacheGTSReportSweepFreq() (v time.Duration) { - st.mutex.RLock() - v = st.config.Cache.GTS.ReportSweepFreq - st.mutex.RUnlock() - return -} - -// SetCacheGTSReportSweepFreq safely sets the Configuration value for state's 'Cache.GTS.ReportSweepFreq' field -func (st *ConfigState) SetCacheGTSReportSweepFreq(v time.Duration) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.ReportSweepFreq = v - st.reloadToViper() -} - -// CacheGTSReportSweepFreqFlag returns the flag name for the 'Cache.GTS.ReportSweepFreq' field -func CacheGTSReportSweepFreqFlag() string { return "cache-gts-report-sweep-freq" } - -// GetCacheGTSReportSweepFreq safely fetches the value for global configuration 'Cache.GTS.ReportSweepFreq' field -func GetCacheGTSReportSweepFreq() time.Duration { return global.GetCacheGTSReportSweepFreq() } - -// SetCacheGTSReportSweepFreq safely sets the value for global configuration 'Cache.GTS.ReportSweepFreq' field -func SetCacheGTSReportSweepFreq(v time.Duration) { global.SetCacheGTSReportSweepFreq(v) } - -// GetCacheGTSStatusMaxSize safely fetches the Configuration value for state's 'Cache.GTS.StatusMaxSize' field -func (st *ConfigState) GetCacheGTSStatusMaxSize() (v int) { - st.mutex.RLock() - v = st.config.Cache.GTS.StatusMaxSize - st.mutex.RUnlock() - return -} - -// SetCacheGTSStatusMaxSize safely sets the Configuration value for state's 'Cache.GTS.StatusMaxSize' field -func (st *ConfigState) SetCacheGTSStatusMaxSize(v int) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.StatusMaxSize = v - st.reloadToViper() -} - -// CacheGTSStatusMaxSizeFlag returns the flag name for the 'Cache.GTS.StatusMaxSize' field -func CacheGTSStatusMaxSizeFlag() string { return "cache-gts-status-max-size" } - -// GetCacheGTSStatusMaxSize safely fetches the value for global configuration 'Cache.GTS.StatusMaxSize' field -func GetCacheGTSStatusMaxSize() int { return global.GetCacheGTSStatusMaxSize() } - -// SetCacheGTSStatusMaxSize safely sets the value for global configuration 'Cache.GTS.StatusMaxSize' field -func SetCacheGTSStatusMaxSize(v int) { global.SetCacheGTSStatusMaxSize(v) } - -// GetCacheGTSStatusTTL safely fetches the Configuration value for state's 'Cache.GTS.StatusTTL' field -func (st *ConfigState) GetCacheGTSStatusTTL() (v time.Duration) { - st.mutex.RLock() - v = st.config.Cache.GTS.StatusTTL - st.mutex.RUnlock() - return -} - -// SetCacheGTSStatusTTL safely sets the Configuration value for state's 'Cache.GTS.StatusTTL' field -func (st *ConfigState) SetCacheGTSStatusTTL(v time.Duration) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.StatusTTL = v - st.reloadToViper() -} - -// CacheGTSStatusTTLFlag returns the flag name for the 'Cache.GTS.StatusTTL' field -func CacheGTSStatusTTLFlag() string { return "cache-gts-status-ttl" } - -// GetCacheGTSStatusTTL safely fetches the value for global configuration 'Cache.GTS.StatusTTL' field -func GetCacheGTSStatusTTL() time.Duration { return global.GetCacheGTSStatusTTL() } - -// SetCacheGTSStatusTTL safely sets the value for global configuration 'Cache.GTS.StatusTTL' field -func SetCacheGTSStatusTTL(v time.Duration) { global.SetCacheGTSStatusTTL(v) } - -// GetCacheGTSStatusSweepFreq safely fetches the Configuration value for state's 'Cache.GTS.StatusSweepFreq' field -func (st *ConfigState) GetCacheGTSStatusSweepFreq() (v time.Duration) { - st.mutex.RLock() - v = st.config.Cache.GTS.StatusSweepFreq - st.mutex.RUnlock() - return -} - -// SetCacheGTSStatusSweepFreq safely sets the Configuration value for state's 'Cache.GTS.StatusSweepFreq' field -func (st *ConfigState) SetCacheGTSStatusSweepFreq(v time.Duration) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.StatusSweepFreq = v - st.reloadToViper() -} - -// CacheGTSStatusSweepFreqFlag returns the flag name for the 'Cache.GTS.StatusSweepFreq' field -func CacheGTSStatusSweepFreqFlag() string { return "cache-gts-status-sweep-freq" } - -// GetCacheGTSStatusSweepFreq safely fetches the value for global configuration 'Cache.GTS.StatusSweepFreq' field -func GetCacheGTSStatusSweepFreq() time.Duration { return global.GetCacheGTSStatusSweepFreq() } - -// SetCacheGTSStatusSweepFreq safely sets the value for global configuration 'Cache.GTS.StatusSweepFreq' field -func SetCacheGTSStatusSweepFreq(v time.Duration) { global.SetCacheGTSStatusSweepFreq(v) } - -// GetCacheGTSStatusFaveMaxSize safely fetches the Configuration value for state's 'Cache.GTS.StatusFaveMaxSize' field -func (st *ConfigState) GetCacheGTSStatusFaveMaxSize() (v int) { - st.mutex.RLock() - v = st.config.Cache.GTS.StatusFaveMaxSize - st.mutex.RUnlock() - return -} - -// SetCacheGTSStatusFaveMaxSize safely sets the Configuration value for state's 'Cache.GTS.StatusFaveMaxSize' field -func (st *ConfigState) SetCacheGTSStatusFaveMaxSize(v int) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.StatusFaveMaxSize = v - st.reloadToViper() -} - -// CacheGTSStatusFaveMaxSizeFlag returns the flag name for the 'Cache.GTS.StatusFaveMaxSize' field -func CacheGTSStatusFaveMaxSizeFlag() string { return "cache-gts-status-fave-max-size" } - -// GetCacheGTSStatusFaveMaxSize safely fetches the value for global configuration 'Cache.GTS.StatusFaveMaxSize' field -func GetCacheGTSStatusFaveMaxSize() int { return global.GetCacheGTSStatusFaveMaxSize() } - -// SetCacheGTSStatusFaveMaxSize safely sets the value for global configuration 'Cache.GTS.StatusFaveMaxSize' field -func SetCacheGTSStatusFaveMaxSize(v int) { global.SetCacheGTSStatusFaveMaxSize(v) } - -// GetCacheGTSStatusFaveTTL safely fetches the Configuration value for state's 'Cache.GTS.StatusFaveTTL' field -func (st *ConfigState) GetCacheGTSStatusFaveTTL() (v time.Duration) { - st.mutex.RLock() - v = st.config.Cache.GTS.StatusFaveTTL - st.mutex.RUnlock() - return -} - -// SetCacheGTSStatusFaveTTL safely sets the Configuration value for state's 'Cache.GTS.StatusFaveTTL' field -func (st *ConfigState) SetCacheGTSStatusFaveTTL(v time.Duration) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.StatusFaveTTL = v - st.reloadToViper() -} - -// CacheGTSStatusFaveTTLFlag returns the flag name for the 'Cache.GTS.StatusFaveTTL' field -func CacheGTSStatusFaveTTLFlag() string { return "cache-gts-status-fave-ttl" } - -// GetCacheGTSStatusFaveTTL safely fetches the value for global configuration 'Cache.GTS.StatusFaveTTL' field -func GetCacheGTSStatusFaveTTL() time.Duration { return global.GetCacheGTSStatusFaveTTL() } - -// SetCacheGTSStatusFaveTTL safely sets the value for global configuration 'Cache.GTS.StatusFaveTTL' field -func SetCacheGTSStatusFaveTTL(v time.Duration) { global.SetCacheGTSStatusFaveTTL(v) } - -// GetCacheGTSStatusFaveSweepFreq safely fetches the Configuration value for state's 'Cache.GTS.StatusFaveSweepFreq' field -func (st *ConfigState) GetCacheGTSStatusFaveSweepFreq() (v time.Duration) { - st.mutex.RLock() - v = st.config.Cache.GTS.StatusFaveSweepFreq - st.mutex.RUnlock() - return -} - -// SetCacheGTSStatusFaveSweepFreq safely sets the Configuration value for state's 'Cache.GTS.StatusFaveSweepFreq' field -func (st *ConfigState) SetCacheGTSStatusFaveSweepFreq(v time.Duration) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.StatusFaveSweepFreq = v - st.reloadToViper() -} - -// CacheGTSStatusFaveSweepFreqFlag returns the flag name for the 'Cache.GTS.StatusFaveSweepFreq' field -func CacheGTSStatusFaveSweepFreqFlag() string { return "cache-gts-status-fave-sweep-freq" } - -// GetCacheGTSStatusFaveSweepFreq safely fetches the value for global configuration 'Cache.GTS.StatusFaveSweepFreq' field -func GetCacheGTSStatusFaveSweepFreq() time.Duration { return global.GetCacheGTSStatusFaveSweepFreq() } - -// SetCacheGTSStatusFaveSweepFreq safely sets the value for global configuration 'Cache.GTS.StatusFaveSweepFreq' field -func SetCacheGTSStatusFaveSweepFreq(v time.Duration) { global.SetCacheGTSStatusFaveSweepFreq(v) } - -// GetCacheGTSTagMaxSize safely fetches the Configuration value for state's 'Cache.GTS.TagMaxSize' field -func (st *ConfigState) GetCacheGTSTagMaxSize() (v int) { - st.mutex.RLock() - v = st.config.Cache.GTS.TagMaxSize - st.mutex.RUnlock() - return -} - -// SetCacheGTSTagMaxSize safely sets the Configuration value for state's 'Cache.GTS.TagMaxSize' field -func (st *ConfigState) SetCacheGTSTagMaxSize(v int) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.TagMaxSize = v - st.reloadToViper() -} - -// CacheGTSTagMaxSizeFlag returns the flag name for the 'Cache.GTS.TagMaxSize' field -func CacheGTSTagMaxSizeFlag() string { return "cache-gts-tag-max-size" } - -// GetCacheGTSTagMaxSize safely fetches the value for global configuration 'Cache.GTS.TagMaxSize' field -func GetCacheGTSTagMaxSize() int { return global.GetCacheGTSTagMaxSize() } - -// SetCacheGTSTagMaxSize safely sets the value for global configuration 'Cache.GTS.TagMaxSize' field -func SetCacheGTSTagMaxSize(v int) { global.SetCacheGTSTagMaxSize(v) } - -// GetCacheGTSTagTTL safely fetches the Configuration value for state's 'Cache.GTS.TagTTL' field -func (st *ConfigState) GetCacheGTSTagTTL() (v time.Duration) { - st.mutex.RLock() - v = st.config.Cache.GTS.TagTTL - st.mutex.RUnlock() - return -} - -// SetCacheGTSTagTTL safely sets the Configuration value for state's 'Cache.GTS.TagTTL' field -func (st *ConfigState) SetCacheGTSTagTTL(v time.Duration) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.TagTTL = v - st.reloadToViper() -} - -// CacheGTSTagTTLFlag returns the flag name for the 'Cache.GTS.TagTTL' field -func CacheGTSTagTTLFlag() string { return "cache-gts-tag-ttl" } - -// GetCacheGTSTagTTL safely fetches the value for global configuration 'Cache.GTS.TagTTL' field -func GetCacheGTSTagTTL() time.Duration { return global.GetCacheGTSTagTTL() } - -// SetCacheGTSTagTTL safely sets the value for global configuration 'Cache.GTS.TagTTL' field -func SetCacheGTSTagTTL(v time.Duration) { global.SetCacheGTSTagTTL(v) } - -// GetCacheGTSTagSweepFreq safely fetches the Configuration value for state's 'Cache.GTS.TagSweepFreq' field -func (st *ConfigState) GetCacheGTSTagSweepFreq() (v time.Duration) { - st.mutex.RLock() - v = st.config.Cache.GTS.TagSweepFreq - st.mutex.RUnlock() - return -} - -// SetCacheGTSTagSweepFreq safely sets the Configuration value for state's 'Cache.GTS.TagSweepFreq' field -func (st *ConfigState) SetCacheGTSTagSweepFreq(v time.Duration) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.TagSweepFreq = v - st.reloadToViper() -} - -// CacheGTSTagSweepFreqFlag returns the flag name for the 'Cache.GTS.TagSweepFreq' field -func CacheGTSTagSweepFreqFlag() string { return "cache-gts-tag-sweep-freq" } - -// GetCacheGTSTagSweepFreq safely fetches the value for global configuration 'Cache.GTS.TagSweepFreq' field -func GetCacheGTSTagSweepFreq() time.Duration { return global.GetCacheGTSTagSweepFreq() } - -// SetCacheGTSTagSweepFreq safely sets the value for global configuration 'Cache.GTS.TagSweepFreq' field -func SetCacheGTSTagSweepFreq(v time.Duration) { global.SetCacheGTSTagSweepFreq(v) } - -// GetCacheGTSTombstoneMaxSize safely fetches the Configuration value for state's 'Cache.GTS.TombstoneMaxSize' field -func (st *ConfigState) GetCacheGTSTombstoneMaxSize() (v int) { - st.mutex.RLock() - v = st.config.Cache.GTS.TombstoneMaxSize - st.mutex.RUnlock() - return -} - -// SetCacheGTSTombstoneMaxSize safely sets the Configuration value for state's 'Cache.GTS.TombstoneMaxSize' field -func (st *ConfigState) SetCacheGTSTombstoneMaxSize(v int) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.TombstoneMaxSize = v - st.reloadToViper() -} - -// CacheGTSTombstoneMaxSizeFlag returns the flag name for the 'Cache.GTS.TombstoneMaxSize' field -func CacheGTSTombstoneMaxSizeFlag() string { return "cache-gts-tombstone-max-size" } - -// GetCacheGTSTombstoneMaxSize safely fetches the value for global configuration 'Cache.GTS.TombstoneMaxSize' field -func GetCacheGTSTombstoneMaxSize() int { return global.GetCacheGTSTombstoneMaxSize() } - -// SetCacheGTSTombstoneMaxSize safely sets the value for global configuration 'Cache.GTS.TombstoneMaxSize' field -func SetCacheGTSTombstoneMaxSize(v int) { global.SetCacheGTSTombstoneMaxSize(v) } - -// GetCacheGTSTombstoneTTL safely fetches the Configuration value for state's 'Cache.GTS.TombstoneTTL' field -func (st *ConfigState) GetCacheGTSTombstoneTTL() (v time.Duration) { - st.mutex.RLock() - v = st.config.Cache.GTS.TombstoneTTL - st.mutex.RUnlock() - return -} - -// SetCacheGTSTombstoneTTL safely sets the Configuration value for state's 'Cache.GTS.TombstoneTTL' field -func (st *ConfigState) SetCacheGTSTombstoneTTL(v time.Duration) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.TombstoneTTL = v - st.reloadToViper() -} - -// CacheGTSTombstoneTTLFlag returns the flag name for the 'Cache.GTS.TombstoneTTL' field -func CacheGTSTombstoneTTLFlag() string { return "cache-gts-tombstone-ttl" } - -// GetCacheGTSTombstoneTTL safely fetches the value for global configuration 'Cache.GTS.TombstoneTTL' field -func GetCacheGTSTombstoneTTL() time.Duration { return global.GetCacheGTSTombstoneTTL() } - -// SetCacheGTSTombstoneTTL safely sets the value for global configuration 'Cache.GTS.TombstoneTTL' field -func SetCacheGTSTombstoneTTL(v time.Duration) { global.SetCacheGTSTombstoneTTL(v) } - -// GetCacheGTSTombstoneSweepFreq safely fetches the Configuration value for state's 'Cache.GTS.TombstoneSweepFreq' field -func (st *ConfigState) GetCacheGTSTombstoneSweepFreq() (v time.Duration) { - st.mutex.RLock() - v = st.config.Cache.GTS.TombstoneSweepFreq - st.mutex.RUnlock() - return -} - -// SetCacheGTSTombstoneSweepFreq safely sets the Configuration value for state's 'Cache.GTS.TombstoneSweepFreq' field -func (st *ConfigState) SetCacheGTSTombstoneSweepFreq(v time.Duration) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.TombstoneSweepFreq = v - st.reloadToViper() -} - -// CacheGTSTombstoneSweepFreqFlag returns the flag name for the 'Cache.GTS.TombstoneSweepFreq' field -func CacheGTSTombstoneSweepFreqFlag() string { return "cache-gts-tombstone-sweep-freq" } - -// GetCacheGTSTombstoneSweepFreq safely fetches the value for global configuration 'Cache.GTS.TombstoneSweepFreq' field -func GetCacheGTSTombstoneSweepFreq() time.Duration { return global.GetCacheGTSTombstoneSweepFreq() } - -// SetCacheGTSTombstoneSweepFreq safely sets the value for global configuration 'Cache.GTS.TombstoneSweepFreq' field -func SetCacheGTSTombstoneSweepFreq(v time.Duration) { global.SetCacheGTSTombstoneSweepFreq(v) } - -// GetCacheGTSUserMaxSize safely fetches the Configuration value for state's 'Cache.GTS.UserMaxSize' field -func (st *ConfigState) GetCacheGTSUserMaxSize() (v int) { - st.mutex.RLock() - v = st.config.Cache.GTS.UserMaxSize - st.mutex.RUnlock() - return -} - -// SetCacheGTSUserMaxSize safely sets the Configuration value for state's 'Cache.GTS.UserMaxSize' field -func (st *ConfigState) SetCacheGTSUserMaxSize(v int) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.UserMaxSize = v - st.reloadToViper() -} - -// CacheGTSUserMaxSizeFlag returns the flag name for the 'Cache.GTS.UserMaxSize' field -func CacheGTSUserMaxSizeFlag() string { return "cache-gts-user-max-size" } - -// GetCacheGTSUserMaxSize safely fetches the value for global configuration 'Cache.GTS.UserMaxSize' field -func GetCacheGTSUserMaxSize() int { return global.GetCacheGTSUserMaxSize() } - -// SetCacheGTSUserMaxSize safely sets the value for global configuration 'Cache.GTS.UserMaxSize' field -func SetCacheGTSUserMaxSize(v int) { global.SetCacheGTSUserMaxSize(v) } - -// GetCacheGTSUserTTL safely fetches the Configuration value for state's 'Cache.GTS.UserTTL' field -func (st *ConfigState) GetCacheGTSUserTTL() (v time.Duration) { - st.mutex.RLock() - v = st.config.Cache.GTS.UserTTL - st.mutex.RUnlock() - return -} - -// SetCacheGTSUserTTL safely sets the Configuration value for state's 'Cache.GTS.UserTTL' field -func (st *ConfigState) SetCacheGTSUserTTL(v time.Duration) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.UserTTL = v - st.reloadToViper() -} - -// CacheGTSUserTTLFlag returns the flag name for the 'Cache.GTS.UserTTL' field -func CacheGTSUserTTLFlag() string { return "cache-gts-user-ttl" } - -// GetCacheGTSUserTTL safely fetches the value for global configuration 'Cache.GTS.UserTTL' field -func GetCacheGTSUserTTL() time.Duration { return global.GetCacheGTSUserTTL() } - -// SetCacheGTSUserTTL safely sets the value for global configuration 'Cache.GTS.UserTTL' field -func SetCacheGTSUserTTL(v time.Duration) { global.SetCacheGTSUserTTL(v) } - -// GetCacheGTSUserSweepFreq safely fetches the Configuration value for state's 'Cache.GTS.UserSweepFreq' field -func (st *ConfigState) GetCacheGTSUserSweepFreq() (v time.Duration) { - st.mutex.RLock() - v = st.config.Cache.GTS.UserSweepFreq - st.mutex.RUnlock() - return -} - -// SetCacheGTSUserSweepFreq safely sets the Configuration value for state's 'Cache.GTS.UserSweepFreq' field -func (st *ConfigState) SetCacheGTSUserSweepFreq(v time.Duration) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.UserSweepFreq = v - st.reloadToViper() -} - -// CacheGTSUserSweepFreqFlag returns the flag name for the 'Cache.GTS.UserSweepFreq' field -func CacheGTSUserSweepFreqFlag() string { return "cache-gts-user-sweep-freq" } - -// GetCacheGTSUserSweepFreq safely fetches the value for global configuration 'Cache.GTS.UserSweepFreq' field -func GetCacheGTSUserSweepFreq() time.Duration { return global.GetCacheGTSUserSweepFreq() } - -// SetCacheGTSUserSweepFreq safely sets the value for global configuration 'Cache.GTS.UserSweepFreq' field -func SetCacheGTSUserSweepFreq(v time.Duration) { global.SetCacheGTSUserSweepFreq(v) } - -// GetCacheGTSWebfingerMaxSize safely fetches the Configuration value for state's 'Cache.GTS.WebfingerMaxSize' field -func (st *ConfigState) GetCacheGTSWebfingerMaxSize() (v int) { - st.mutex.RLock() - v = st.config.Cache.GTS.WebfingerMaxSize - st.mutex.RUnlock() - return -} - -// SetCacheGTSWebfingerMaxSize safely sets the Configuration value for state's 'Cache.GTS.WebfingerMaxSize' field -func (st *ConfigState) SetCacheGTSWebfingerMaxSize(v int) { - st.mutex.Lock() - defer st.mutex.Unlock() - st.config.Cache.GTS.WebfingerMaxSize = v - st.reloadToViper() -} - -// CacheGTSWebfingerMaxSizeFlag returns the flag name for the 'Cache.GTS.WebfingerMaxSize' field -func CacheGTSWebfingerMaxSizeFlag() string { return "cache-gts-webfinger-max-size" } - -// GetCacheGTSWebfingerMaxSize safely fetches the value for global configuration 'Cache.GTS.WebfingerMaxSize' field -func GetCacheGTSWebfingerMaxSize() int { return global.GetCacheGTSWebfingerMaxSize() } +// GetCacheStatusFaveMemRatio safely fetches the value for global configuration 'Cache.StatusFaveMemRatio' field +func GetCacheStatusFaveMemRatio() float64 { return global.GetCacheStatusFaveMemRatio() } -// SetCacheGTSWebfingerMaxSize safely sets the value for global configuration 'Cache.GTS.WebfingerMaxSize' field -func SetCacheGTSWebfingerMaxSize(v int) { global.SetCacheGTSWebfingerMaxSize(v) } +// SetCacheStatusFaveMemRatio safely sets the value for global configuration 'Cache.StatusFaveMemRatio' field +func SetCacheStatusFaveMemRatio(v float64) { global.SetCacheStatusFaveMemRatio(v) } -// GetCacheGTSWebfingerTTL safely fetches the Configuration value for state's 'Cache.GTS.WebfingerTTL' field -func (st *ConfigState) GetCacheGTSWebfingerTTL() (v time.Duration) { +// GetCacheTagMemRatio safely fetches the Configuration value for state's 'Cache.TagMemRatio' field +func (st *ConfigState) GetCacheTagMemRatio() (v float64) { st.mutex.RLock() - v = st.config.Cache.GTS.WebfingerTTL + v = st.config.Cache.TagMemRatio st.mutex.RUnlock() return } -// SetCacheGTSWebfingerTTL safely sets the Configuration value for state's 'Cache.GTS.WebfingerTTL' field -func (st *ConfigState) SetCacheGTSWebfingerTTL(v time.Duration) { +// SetCacheTagMemRatio safely sets the Configuration value for state's 'Cache.TagMemRatio' field +func (st *ConfigState) SetCacheTagMemRatio(v float64) { st.mutex.Lock() defer st.mutex.Unlock() - st.config.Cache.GTS.WebfingerTTL = v + st.config.Cache.TagMemRatio = v st.reloadToViper() } -// CacheGTSWebfingerTTLFlag returns the flag name for the 'Cache.GTS.WebfingerTTL' field -func CacheGTSWebfingerTTLFlag() string { return "cache-gts-webfinger-ttl" } +// CacheTagMemRatioFlag returns the flag name for the 'Cache.TagMemRatio' field +func CacheTagMemRatioFlag() string { return "cache-tag-mem-ratio" } -// GetCacheGTSWebfingerTTL safely fetches the value for global configuration 'Cache.GTS.WebfingerTTL' field -func GetCacheGTSWebfingerTTL() time.Duration { return global.GetCacheGTSWebfingerTTL() } +// GetCacheTagMemRatio safely fetches the value for global configuration 'Cache.TagMemRatio' field +func GetCacheTagMemRatio() float64 { return global.GetCacheTagMemRatio() } -// SetCacheGTSWebfingerTTL safely sets the value for global configuration 'Cache.GTS.WebfingerTTL' field -func SetCacheGTSWebfingerTTL(v time.Duration) { global.SetCacheGTSWebfingerTTL(v) } +// SetCacheTagMemRatio safely sets the value for global configuration 'Cache.TagMemRatio' field +func SetCacheTagMemRatio(v float64) { global.SetCacheTagMemRatio(v) } -// GetCacheGTSWebfingerSweepFreq safely fetches the Configuration value for state's 'Cache.GTS.WebfingerSweepFreq' field -func (st *ConfigState) GetCacheGTSWebfingerSweepFreq() (v time.Duration) { +// GetCacheTombstoneMemRatio safely fetches the Configuration value for state's 'Cache.TombstoneMemRatio' field +func (st *ConfigState) GetCacheTombstoneMemRatio() (v float64) { st.mutex.RLock() - v = st.config.Cache.GTS.WebfingerSweepFreq + v = st.config.Cache.TombstoneMemRatio st.mutex.RUnlock() return } -// SetCacheGTSWebfingerSweepFreq safely sets the Configuration value for state's 'Cache.GTS.WebfingerSweepFreq' field -func (st *ConfigState) SetCacheGTSWebfingerSweepFreq(v time.Duration) { +// SetCacheTombstoneMemRatio safely sets the Configuration value for state's 'Cache.TombstoneMemRatio' field +func (st *ConfigState) SetCacheTombstoneMemRatio(v float64) { st.mutex.Lock() defer st.mutex.Unlock() - st.config.Cache.GTS.WebfingerSweepFreq = v + st.config.Cache.TombstoneMemRatio = v st.reloadToViper() } -// CacheGTSWebfingerSweepFreqFlag returns the flag name for the 'Cache.GTS.WebfingerSweepFreq' field -func CacheGTSWebfingerSweepFreqFlag() string { return "cache-gts-webfinger-sweep-freq" } +// CacheTombstoneMemRatioFlag returns the flag name for the 'Cache.TombstoneMemRatio' field +func CacheTombstoneMemRatioFlag() string { return "cache-tombstone-mem-ratio" } -// GetCacheGTSWebfingerSweepFreq safely fetches the value for global configuration 'Cache.GTS.WebfingerSweepFreq' field -func GetCacheGTSWebfingerSweepFreq() time.Duration { return global.GetCacheGTSWebfingerSweepFreq() } +// GetCacheTombstoneMemRatio safely fetches the value for global configuration 'Cache.TombstoneMemRatio' field +func GetCacheTombstoneMemRatio() float64 { return global.GetCacheTombstoneMemRatio() } -// SetCacheGTSWebfingerSweepFreq safely sets the value for global configuration 'Cache.GTS.WebfingerSweepFreq' field -func SetCacheGTSWebfingerSweepFreq(v time.Duration) { global.SetCacheGTSWebfingerSweepFreq(v) } +// SetCacheTombstoneMemRatio safely sets the value for global configuration 'Cache.TombstoneMemRatio' field +func SetCacheTombstoneMemRatio(v float64) { global.SetCacheTombstoneMemRatio(v) } -// GetCacheVisibilityMaxSize safely fetches the Configuration value for state's 'Cache.VisibilityMaxSize' field -func (st *ConfigState) GetCacheVisibilityMaxSize() (v int) { +// GetCacheUserMemRatio safely fetches the Configuration value for state's 'Cache.UserMemRatio' field +func (st *ConfigState) GetCacheUserMemRatio() (v float64) { st.mutex.RLock() - v = st.config.Cache.VisibilityMaxSize + v = st.config.Cache.UserMemRatio st.mutex.RUnlock() return } -// SetCacheVisibilityMaxSize safely sets the Configuration value for state's 'Cache.VisibilityMaxSize' field -func (st *ConfigState) SetCacheVisibilityMaxSize(v int) { +// SetCacheUserMemRatio safely sets the Configuration value for state's 'Cache.UserMemRatio' field +func (st *ConfigState) SetCacheUserMemRatio(v float64) { st.mutex.Lock() defer st.mutex.Unlock() - st.config.Cache.VisibilityMaxSize = v + st.config.Cache.UserMemRatio = v st.reloadToViper() } -// CacheVisibilityMaxSizeFlag returns the flag name for the 'Cache.VisibilityMaxSize' field -func CacheVisibilityMaxSizeFlag() string { return "cache-visibility-max-size" } +// CacheUserMemRatioFlag returns the flag name for the 'Cache.UserMemRatio' field +func CacheUserMemRatioFlag() string { return "cache-user-mem-ratio" } -// GetCacheVisibilityMaxSize safely fetches the value for global configuration 'Cache.VisibilityMaxSize' field -func GetCacheVisibilityMaxSize() int { return global.GetCacheVisibilityMaxSize() } +// GetCacheUserMemRatio safely fetches the value for global configuration 'Cache.UserMemRatio' field +func GetCacheUserMemRatio() float64 { return global.GetCacheUserMemRatio() } -// SetCacheVisibilityMaxSize safely sets the value for global configuration 'Cache.VisibilityMaxSize' field -func SetCacheVisibilityMaxSize(v int) { global.SetCacheVisibilityMaxSize(v) } +// SetCacheUserMemRatio safely sets the value for global configuration 'Cache.UserMemRatio' field +func SetCacheUserMemRatio(v float64) { global.SetCacheUserMemRatio(v) } -// GetCacheVisibilityTTL safely fetches the Configuration value for state's 'Cache.VisibilityTTL' field -func (st *ConfigState) GetCacheVisibilityTTL() (v time.Duration) { +// GetCacheWebfingerMemRatio safely fetches the Configuration value for state's 'Cache.WebfingerMemRatio' field +func (st *ConfigState) GetCacheWebfingerMemRatio() (v float64) { st.mutex.RLock() - v = st.config.Cache.VisibilityTTL + v = st.config.Cache.WebfingerMemRatio st.mutex.RUnlock() return } -// SetCacheVisibilityTTL safely sets the Configuration value for state's 'Cache.VisibilityTTL' field -func (st *ConfigState) SetCacheVisibilityTTL(v time.Duration) { +// SetCacheWebfingerMemRatio safely sets the Configuration value for state's 'Cache.WebfingerMemRatio' field +func (st *ConfigState) SetCacheWebfingerMemRatio(v float64) { st.mutex.Lock() defer st.mutex.Unlock() - st.config.Cache.VisibilityTTL = v + st.config.Cache.WebfingerMemRatio = v st.reloadToViper() } -// CacheVisibilityTTLFlag returns the flag name for the 'Cache.VisibilityTTL' field -func CacheVisibilityTTLFlag() string { return "cache-visibility-ttl" } +// CacheWebfingerMemRatioFlag returns the flag name for the 'Cache.WebfingerMemRatio' field +func CacheWebfingerMemRatioFlag() string { return "cache-webfinger-mem-ratio" } -// GetCacheVisibilityTTL safely fetches the value for global configuration 'Cache.VisibilityTTL' field -func GetCacheVisibilityTTL() time.Duration { return global.GetCacheVisibilityTTL() } +// GetCacheWebfingerMemRatio safely fetches the value for global configuration 'Cache.WebfingerMemRatio' field +func GetCacheWebfingerMemRatio() float64 { return global.GetCacheWebfingerMemRatio() } -// SetCacheVisibilityTTL safely sets the value for global configuration 'Cache.VisibilityTTL' field -func SetCacheVisibilityTTL(v time.Duration) { global.SetCacheVisibilityTTL(v) } +// SetCacheWebfingerMemRatio safely sets the value for global configuration 'Cache.WebfingerMemRatio' field +func SetCacheWebfingerMemRatio(v float64) { global.SetCacheWebfingerMemRatio(v) } -// GetCacheVisibilitySweepFreq safely fetches the Configuration value for state's 'Cache.VisibilitySweepFreq' field -func (st *ConfigState) GetCacheVisibilitySweepFreq() (v time.Duration) { +// GetCacheVisibilityMemRatio safely fetches the Configuration value for state's 'Cache.VisibilityMemRatio' field +func (st *ConfigState) GetCacheVisibilityMemRatio() (v float64) { st.mutex.RLock() - v = st.config.Cache.VisibilitySweepFreq + v = st.config.Cache.VisibilityMemRatio st.mutex.RUnlock() return } -// SetCacheVisibilitySweepFreq safely sets the Configuration value for state's 'Cache.VisibilitySweepFreq' field -func (st *ConfigState) SetCacheVisibilitySweepFreq(v time.Duration) { +// SetCacheVisibilityMemRatio safely sets the Configuration value for state's 'Cache.VisibilityMemRatio' field +func (st *ConfigState) SetCacheVisibilityMemRatio(v float64) { st.mutex.Lock() defer st.mutex.Unlock() - st.config.Cache.VisibilitySweepFreq = v + st.config.Cache.VisibilityMemRatio = v st.reloadToViper() } -// CacheVisibilitySweepFreqFlag returns the flag name for the 'Cache.VisibilitySweepFreq' field -func CacheVisibilitySweepFreqFlag() string { return "cache-visibility-sweep-freq" } +// CacheVisibilityMemRatioFlag returns the flag name for the 'Cache.VisibilityMemRatio' field +func CacheVisibilityMemRatioFlag() string { return "cache-visibility-mem-ratio" } -// GetCacheVisibilitySweepFreq safely fetches the value for global configuration 'Cache.VisibilitySweepFreq' field -func GetCacheVisibilitySweepFreq() time.Duration { return global.GetCacheVisibilitySweepFreq() } +// GetCacheVisibilityMemRatio safely fetches the value for global configuration 'Cache.VisibilityMemRatio' field +func GetCacheVisibilityMemRatio() float64 { return global.GetCacheVisibilityMemRatio() } -// SetCacheVisibilitySweepFreq safely sets the value for global configuration 'Cache.VisibilitySweepFreq' field -func SetCacheVisibilitySweepFreq(v time.Duration) { global.SetCacheVisibilitySweepFreq(v) } +// SetCacheVisibilityMemRatio safely sets the value for global configuration 'Cache.VisibilityMemRatio' field +func SetCacheVisibilityMemRatio(v float64) { global.SetCacheVisibilityMemRatio(v) } // GetAdminAccountUsername safely fetches the Configuration value for state's 'AdminAccountUsername' field func (st *ConfigState) GetAdminAccountUsername() (v string) { diff --git a/internal/httpclient/client.go b/internal/httpclient/client.go index f5701d6fa..ffaf76537 100644 --- a/internal/httpclient/client.go +++ b/internal/httpclient/client.go @@ -108,7 +108,7 @@ type Config struct { // - request logging type Client struct { client http.Client - badHosts cache.Cache[string, struct{}] + badHosts cache.TTLCache[string, struct{}] bodyMax int64 } @@ -178,7 +178,7 @@ func New(cfg Config) *Client { } // Initiate outgoing bad hosts lookup cache. - c.badHosts = cache.New[string, struct{}](0, 1000, 0) + c.badHosts = cache.NewTTL[string, struct{}](0, 1000, 0) c.badHosts.SetTTL(time.Hour, false) if !c.badHosts.Start(time.Minute) { log.Panic(nil, "failed to start transport controller cache") diff --git a/internal/transport/controller.go b/internal/transport/controller.go index 83fad8038..9055b147f 100644 --- a/internal/transport/controller.go +++ b/internal/transport/controller.go @@ -50,7 +50,7 @@ type controller struct { fedDB federatingdb.DB clock pub.Clock client httpclient.SigningClient - trspCache cache.Cache[string, *transport] + trspCache cache.TTLCache[string, *transport] userAgent string senders int // no. concurrent batch delivery routines. } @@ -76,7 +76,7 @@ func NewController(state *state.State, federatingDB federatingdb.DB, clock pub.C fedDB: federatingDB, clock: clock, client: client, - trspCache: cache.New[string, *transport](0, 100, 0), + trspCache: cache.NewTTL[string, *transport](0, 100, 0), userAgent: fmt.Sprintf("%s (+%s://%s) gotosocial/%s", applicationName, proto, host, version), senders: senders, } diff --git a/internal/web/etag.go b/internal/web/etag.go index 0186879d0..a87d9fa3b 100644 --- a/internal/web/etag.go +++ b/internal/web/etag.go @@ -29,8 +29,8 @@ "codeberg.org/gruf/go-cache/v3" ) -func newETagCache() cache.Cache[string, eTagCacheEntry] { - eTagCache := cache.New[string, eTagCacheEntry](0, 1000, 0) +func newETagCache() cache.TTLCache[string, eTagCacheEntry] { + eTagCache := cache.NewTTL[string, eTagCacheEntry](0, 1000, 0) eTagCache.SetTTL(time.Hour, false) if !eTagCache.Start(time.Minute) { log.Panic(nil, "could not start eTagCache") diff --git a/test/envparsing.sh b/test/envparsing.sh index 14b265b32..f75b6fd3f 100755 --- a/test/envparsing.sh +++ b/test/envparsing.sh @@ -2,7 +2,7 @@ set -eu -EXPECT=$(cat <<"EOF" +EXPECT=$(cat << "EOF" { "account-domain": "peepee", "accounts-allow-custom-css": true, @@ -18,86 +18,31 @@ EXPECT=$(cat <<"EOF" "application-name": "gts", "bind-address": "127.0.0.1", "cache": { - "gts": { - "account-max-size": 99, - "account-note-max-size": 1000, - "account-note-sweep-freq": 60000000000, - "account-note-ttl": 1800000000000, - "account-sweep-freq": 1000000000, - "account-ttl": 10800000000000, - "block-ids-max-size": 500, - "block-ids-sweep-freq": 60000000000, - "block-ids-ttl": 1800000000000, - "block-max-size": 1000, - "block-sweep-freq": 60000000000, - "block-ttl": 1800000000000, - "domain-block-max-size": 2000, - "domain-block-sweep-freq": 60000000000, - "domain-block-ttl": 86400000000000, - "emoji-category-max-size": 100, - "emoji-category-sweep-freq": 60000000000, - "emoji-category-ttl": 1800000000000, - "emoji-max-size": 2000, - "emoji-sweep-freq": 60000000000, - "emoji-ttl": 1800000000000, - "follow-ids-max-size": 500, - "follow-ids-sweep-freq": 60000000000, - "follow-ids-ttl": 1800000000000, - "follow-max-size": 2000, - "follow-request-ids-max-size": 500, - "follow-request-ids-sweep-freq": 60000000000, - "follow-request-ids-ttl": 1800000000000, - "follow-request-max-size": 2000, - "follow-request-sweep-freq": 60000000000, - "follow-request-ttl": 1800000000000, - "follow-sweep-freq": 60000000000, - "follow-ttl": 1800000000000, - "instance-max-size": 2000, - "instance-sweep-freq": 60000000000, - "instance-ttl": 1800000000000, - "list-entry-max-size": 2000, - "list-entry-sweep-freq": 60000000000, - "list-entry-ttl": 1800000000000, - "list-max-size": 2000, - "list-sweep-freq": 60000000000, - "list-ttl": 1800000000000, - "marker-max-size": 2000, - "marker-sweep-freq": 60000000000, - "marker-ttl": 21600000000000, - "media-max-size": 1000, - "media-sweep-freq": 60000000000, - "media-ttl": 1800000000000, - "mention-max-size": 2000, - "mention-sweep-freq": 60000000000, - "mention-ttl": 1800000000000, - "notification-max-size": 1000, - "notification-sweep-freq": 60000000000, - "notification-ttl": 1800000000000, - "report-max-size": 100, - "report-sweep-freq": 60000000000, - "report-ttl": 1800000000000, - "status-fave-max-size": 2000, - "status-fave-sweep-freq": 60000000000, - "status-fave-ttl": 1800000000000, - "status-max-size": 2000, - "status-sweep-freq": 60000000000, - "status-ttl": 1800000000000, - "tag-max-size": 2000, - "tag-sweep-freq": 60000000000, - "tag-ttl": 1800000000000, - "tombstone-max-size": 500, - "tombstone-sweep-freq": 60000000000, - "tombstone-ttl": 1800000000000, - "user-max-size": 500, - "user-sweep-freq": 60000000000, - "user-ttl": 1800000000000, - "webfinger-max-size": 250, - "webfinger-sweep-freq": 900000000000, - "webfinger-ttl": 86400000000000 - }, - "visibility-max-size": 2000, - "visibility-sweep-freq": 60000000000, - "visibility-ttl": 1800000000000 + "account-mem-ratio": 18, + "account-note-mem-ratio": 0.1, + "block-mem-ratio": 3, + "emoji-category-mem-ratio": 0.1, + "emoji-mem-ratio": 3, + "follow-ids-mem-ratio": 4, + "follow-mem-ratio": 4, + "follow-request-ids-mem-ratio": 2, + "follow-request-mem-ratio": 2, + "instance-mem-ratio": 1, + "list-entry-mem-ratio": 3, + "list-mem-ratio": 3, + "marker-mem-ratio": 0.5, + "media-mem-ratio": 4, + "memory-target": 209715200, + "mention-mem-ratio": 5, + "notification-mem-ratio": 5, + "report-mem-ratio": 1, + "status-fave-mem-ratio": 5, + "status-mem-ratio": 18, + "tag-mem-ratio": 3, + "tombstone-mem-ratio": 2, + "user-mem-ratio": 0.1, + "visibility-mem-ratio": 2, + "webfinger-mem-ratio": 0.1 }, "config-path": "internal/config/testdata/test.yaml", "db-address": ":memory:", diff --git a/vendor/codeberg.org/gruf/go-cache/v3/LICENSE b/vendor/codeberg.org/gruf/go-cache/v3/LICENSE index e4163ae35..d6f08d0ab 100644 --- a/vendor/codeberg.org/gruf/go-cache/v3/LICENSE +++ b/vendor/codeberg.org/gruf/go-cache/v3/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2022 gruf +Copyright (c) gruf Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/vendor/codeberg.org/gruf/go-cache/v3/README.md b/vendor/codeberg.org/gruf/go-cache/v3/README.md index 43004f3d8..eb298bea4 100644 --- a/vendor/codeberg.org/gruf/go-cache/v3/README.md +++ b/vendor/codeberg.org/gruf/go-cache/v3/README.md @@ -1,14 +1,14 @@ # go-cache -Provides access to a simple yet flexible, performant TTL cache via the `Cache{}` interface and `cache.New()`. Under the hood this is returning a `ttl.Cache{}`. +Provides access to simple, yet flexible, and performant caches (with TTL if required) via the `cache.Cache{}` and `cache.TTLCache{}` interfaces. + +## simple + +A `cache.Cache{}` implementation with much more of the inner workings exposed. Designed to be used as a base for your own customizations, or used as-is. ## ttl -A TTL cache implementation with much of the inner workings exposed, designed to be used as a base for your own customizations, or used as-is. Access via the base package `cache.New()` is recommended in the latter case, to prevent accidental use of unsafe methods. - -## lookup - -`lookup.Cache` is an example of a more complex cache implementation using `ttl.Cache{}` as its underpinning. It provides caching of items under multiple keys. +A `cache.TTLCache{}` implementation with much more of the inner workings exposed. Designed to be used as a base for your own customizations, or used as-is. ## result diff --git a/vendor/codeberg.org/gruf/go-cache/v3/cache.go b/vendor/codeberg.org/gruf/go-cache/v3/cache.go index 1192cf3e8..d96971702 100644 --- a/vendor/codeberg.org/gruf/go-cache/v3/cache.go +++ b/vendor/codeberg.org/gruf/go-cache/v3/cache.go @@ -3,26 +3,33 @@ import ( "time" - ttlcache "codeberg.org/gruf/go-cache/v3/ttl" + "codeberg.org/gruf/go-cache/v3/simple" + "codeberg.org/gruf/go-cache/v3/ttl" ) -// Cache represents a TTL cache with customizable callbacks, it exists here to abstract away the "unsafe" methods in the case that you do not want your own implementation atop ttl.Cache{}. -type Cache[Key comparable, Value any] interface { +// TTLCache represents a TTL cache with customizable callbacks, it exists here to abstract away the "unsafe" methods in the case that you do not want your own implementation atop ttl.Cache{}. +type TTLCache[Key comparable, Value any] interface { // Start will start the cache background eviction routine with given sweep frequency. If already running or a freq <= 0 provided, this is a no-op. This will block until the eviction routine has started. Start(freq time.Duration) bool // Stop will stop cache background eviction routine. If not running this is a no-op. This will block until the eviction routine has stopped. Stop() bool + // SetTTL sets the cache item TTL. Update can be specified to force updates of existing items in the cache, this will simply add the change in TTL to their current expiry time. + SetTTL(ttl time.Duration, update bool) + + // implements base cache. + Cache[Key, Value] +} + +// Cache represents a cache with customizable callbacks, it exists here to abstract away the "unsafe" methods in the case that you do not want your own implementation atop simple.Cache{}. +type Cache[Key comparable, Value any] interface { // SetEvictionCallback sets the eviction callback to the provided hook. SetEvictionCallback(hook func(Key, Value)) // SetInvalidateCallback sets the invalidate callback to the provided hook. SetInvalidateCallback(hook func(Key, Value)) - // SetTTL sets the cache item TTL. Update can be specified to force updates of existing items in the cache, this will simply add the change in TTL to their current expiry time. - SetTTL(ttl time.Duration, update bool) - // Get fetches the value with key from the cache, extending its TTL. Get(key Key) (value Value, ok bool) @@ -57,7 +64,12 @@ type Cache[Key comparable, Value any] interface { Cap() int } -// New returns a new initialized Cache with given initial length, maximum capacity and item TTL. -func New[K comparable, V any](len, cap int, ttl time.Duration) Cache[K, V] { - return ttlcache.New[K, V](len, cap, ttl) +// New returns a new initialized Cache with given initial length, maximum capacity. +func New[K comparable, V any](len, cap int) Cache[K, V] { + return simple.New[K, V](len, cap) +} + +// NewTTL returns a new initialized TTLCache with given initial length, maximum capacity and TTL duration. +func NewTTL[K comparable, V any](len, cap int, _ttl time.Duration) TTLCache[K, V] { + return ttl.New[K, V](len, cap, _ttl) } diff --git a/vendor/codeberg.org/gruf/go-cache/v3/result/cache.go b/vendor/codeberg.org/gruf/go-cache/v3/result/cache.go index a86a72c77..f31e6604a 100644 --- a/vendor/codeberg.org/gruf/go-cache/v3/result/cache.go +++ b/vendor/codeberg.org/gruf/go-cache/v3/result/cache.go @@ -2,14 +2,38 @@ import ( "context" + "fmt" + "os" "reflect" - "time" _ "unsafe" - "codeberg.org/gruf/go-cache/v3/ttl" + "codeberg.org/gruf/go-cache/v3/simple" "codeberg.org/gruf/go-errors/v2" ) +type result struct { + // Result primary key + PKey int64 + + // keys accessible under + Keys cacheKeys + + // cached value + Value any + + // cached error + Error error +} + +// getResultValue is a safe way of casting and fetching result value. +func getResultValue[T any](res *result) T { + v, ok := res.Value.(T) + if !ok { + fmt.Fprintf(os.Stderr, "!! BUG: unexpected value type in result: %T\n", res.Value) + } + return v +} + // Lookup represents a struct object lookup method in the cache. type Lookup struct { // Name is a period ('.') separated string @@ -23,26 +47,23 @@ type Lookup struct { // Multi allows specifying a key capable of storing // multiple results. Note this only supports invalidate. Multi bool - - // TODO: support toggling case sensitive lookups. - // CaseSensitive bool } // Cache provides a means of caching value structures, along with // the results of attempting to load them. An example usecase of this // cache would be in wrapping a database, allowing caching of sql.ErrNoRows. -type Cache[Value any] struct { - cache ttl.Cache[int64, result[Value]] // underlying result cache - invalid func(Value) // store unwrapped invalidate callback. - lookups structKeys // pre-determined struct lookups - ignore func(error) bool // determines cacheable errors - copy func(Value) Value // copies a Value type - next int64 // update key counter +type Cache[T any] struct { + cache simple.Cache[int64, *result] // underlying result cache + lookups structKeys // pre-determined struct lookups + invalid func(T) // store unwrapped invalidate callback. + ignore func(error) bool // determines cacheable errors + copy func(T) T // copies a Value type + next int64 // update key counter } // New returns a new initialized Cache, with given lookups, underlying value copy function and provided capacity. -func New[Value any](lookups []Lookup, copy func(Value) Value, cap int) *Cache[Value] { - var z Value +func New[T any](lookups []Lookup, copy func(T) T, cap int) *Cache[T] { + var z T // Determine generic type t := reflect.TypeOf(z) @@ -58,7 +79,7 @@ func New[Value any](lookups []Lookup, copy func(Value) Value, cap int) *Cache[Va } // Allocate new cache object - c := &Cache[Value]{copy: copy} + c := &Cache[T]{copy: copy} c.lookups = make([]structKey, len(lookups)) for i, lookup := range lookups { @@ -67,38 +88,20 @@ func New[Value any](lookups []Lookup, copy func(Value) Value, cap int) *Cache[Va } // Create and initialize underlying cache - c.cache.Init(0, cap, 0) + c.cache.Init(0, cap) c.SetEvictionCallback(nil) c.SetInvalidateCallback(nil) c.IgnoreErrors(nil) return c } -// Start will start the cache background eviction routine with given sweep frequency. If already -// running or a freq <= 0 provided, this is a no-op. This will block until eviction routine started. -func (c *Cache[Value]) Start(freq time.Duration) bool { - return c.cache.Start(freq) -} - -// Stop will stop cache background eviction routine. If not running this -// is a no-op. This will block until the eviction routine has stopped. -func (c *Cache[Value]) Stop() bool { - return c.cache.Stop() -} - -// SetTTL sets the cache item TTL. Update can be specified to force updates of existing items -// in the cache, this will simply add the change in TTL to their current expiry time. -func (c *Cache[Value]) SetTTL(ttl time.Duration, update bool) { - c.cache.SetTTL(ttl, update) -} - // SetEvictionCallback sets the eviction callback to the provided hook. -func (c *Cache[Value]) SetEvictionCallback(hook func(Value)) { +func (c *Cache[T]) SetEvictionCallback(hook func(T)) { if hook == nil { // Ensure non-nil hook. - hook = func(Value) {} + hook = func(T) {} } - c.cache.SetEvictionCallback(func(pkey int64, res result[Value]) { + c.cache.SetEvictionCallback(func(pkey int64, res *result) { c.cache.Lock() for _, key := range res.Keys { // Delete key->pkey lookup @@ -108,23 +111,25 @@ func (c *Cache[Value]) SetEvictionCallback(hook func(Value)) { c.cache.Unlock() if res.Error != nil { - // Skip error hooks + // Skip value hooks return } - // Call user hook. - hook(res.Value) + // Free result and call hook. + v := getResultValue[T](res) + putResult(res) + hook(v) }) } // SetInvalidateCallback sets the invalidate callback to the provided hook. -func (c *Cache[Value]) SetInvalidateCallback(hook func(Value)) { +func (c *Cache[T]) SetInvalidateCallback(hook func(T)) { if hook == nil { // Ensure non-nil hook. - hook = func(Value) {} + hook = func(T) {} } // store hook. c.invalid = hook - c.cache.SetInvalidateCallback(func(pkey int64, res result[Value]) { + c.cache.SetInvalidateCallback(func(pkey int64, res *result) { c.cache.Lock() for _, key := range res.Keys { // Delete key->pkey lookup @@ -134,17 +139,19 @@ func (c *Cache[Value]) SetInvalidateCallback(hook func(Value)) { c.cache.Unlock() if res.Error != nil { - // Skip error hooks + // Skip value hooks return } - // Call user hook. - hook(res.Value) + // Free result and call hook. + v := getResultValue[T](res) + putResult(res) + hook(v) }) } // IgnoreErrors allows setting a function hook to determine which error types should / not be cached. -func (c *Cache[Value]) IgnoreErrors(ignore func(error) bool) { +func (c *Cache[T]) IgnoreErrors(ignore func(error) bool) { if ignore == nil { ignore = func(err error) bool { return errors.Comparable( @@ -160,11 +167,10 @@ func (c *Cache[Value]) IgnoreErrors(ignore func(error) bool) { } // Load will attempt to load an existing result from the cacche for the given lookup and key parts, else calling the provided load function and caching the result. -func (c *Cache[Value]) Load(lookup string, load func() (Value, error), keyParts ...any) (Value, error) { +func (c *Cache[T]) Load(lookup string, load func() (T, error), keyParts ...any) (T, error) { var ( - zero Value - res result[Value] - ok bool + zero T + res *result ) // Get lookup key info by name. @@ -182,24 +188,22 @@ func (c *Cache[Value]) Load(lookup string, load func() (Value, error), keyParts // Look for primary cache key pkeys := keyInfo.pkeys[ckey] - if ok = (len(pkeys) > 0); ok { - var entry *ttl.Entry[int64, result[Value]] - + if len(pkeys) > 0 { // Fetch the result for primary key - entry, ok = c.cache.Cache.Get(pkeys[0]) + entry, ok := c.cache.Cache.Get(pkeys[0]) if ok { // Since the invalidation / eviction hooks acquire a mutex // lock separately, and only at this point are the pkeys // updated, there is a chance that a primary key may return // no matching entry. Hence we have to check for it here. - res = entry.Value + res = entry.Value.(*result) } } // Done with lock c.cache.Unlock() - if !ok { + if res == nil { // Generate fresh result. value, err := load() @@ -209,6 +213,9 @@ func (c *Cache[Value]) Load(lookup string, load func() (Value, error), keyParts return zero, err } + // Alloc result. + res = getResult() + // Store error result. res.Error = err @@ -219,6 +226,9 @@ func (c *Cache[Value]) Load(lookup string, load func() (Value, error), keyParts key: ckey, }} } else { + // Alloc result. + res = getResult() + // Store value result. res.Value = value @@ -251,22 +261,21 @@ func (c *Cache[Value]) Load(lookup string, load func() (Value, error), keyParts } // Return a copy of value from cache - return c.copy(res.Value), nil + return c.copy(getResultValue[T](res)), nil } // Store will call the given store function, and on success store the value in the cache as a positive result. -func (c *Cache[Value]) Store(value Value, store func() error) error { +func (c *Cache[T]) Store(value T, store func() error) error { // Attempt to store this value. if err := store(); err != nil { return err } // Prepare cached result. - result := result[Value]{ - Keys: c.lookups.generate(value), - Value: c.copy(value), - Error: nil, - } + result := getResult() + result.Keys = c.lookups.generate(value) + result.Value = c.copy(value) + result.Error = nil var evict func() @@ -293,9 +302,8 @@ func (c *Cache[Value]) Store(value Value, store func() error) error { } // Has checks the cache for a positive result under the given lookup and key parts. -func (c *Cache[Value]) Has(lookup string, keyParts ...any) bool { - var res result[Value] - var ok bool +func (c *Cache[T]) Has(lookup string, keyParts ...any) bool { + var res *result // Get lookup key info by name. keyInfo := c.lookups.get(lookup) @@ -312,29 +320,27 @@ func (c *Cache[Value]) Has(lookup string, keyParts ...any) bool { // Look for primary key for cache key pkeys := keyInfo.pkeys[ckey] - if ok = (len(pkeys) > 0); ok { - var entry *ttl.Entry[int64, result[Value]] - + if len(pkeys) > 0 { // Fetch the result for primary key - entry, ok = c.cache.Cache.Get(pkeys[0]) + entry, ok := c.cache.Cache.Get(pkeys[0]) if ok { // Since the invalidation / eviction hooks acquire a mutex // lock separately, and only at this point are the pkeys // updated, there is a chance that a primary key may return // no matching entry. Hence we have to check for it here. - res = entry.Value + res = entry.Value.(*result) } } // Done with lock c.cache.Unlock() - // Check for non-error result. - return ok && (res.Error == nil) + // Check for result AND non-error result. + return (res != nil && res.Error == nil) } // Invalidate will invalidate any result from the cache found under given lookup and key parts. -func (c *Cache[Value]) Invalidate(lookup string, keyParts ...any) { +func (c *Cache[T]) Invalidate(lookup string, keyParts ...any) { // Get lookup key info by name. keyInfo := c.lookups.get(lookup) @@ -351,15 +357,20 @@ func (c *Cache[Value]) Invalidate(lookup string, keyParts ...any) { c.cache.InvalidateAll(pkeys...) } -// Clear empties the cache, calling the invalidate callback. -func (c *Cache[Value]) Clear() { c.cache.Clear() } +// Clear empties the cache, calling the invalidate callback where necessary. +func (c *Cache[T]) Clear() { c.Trim(100) } + +// Trim ensures the cache stays within percentage of total capacity, truncating where necessary. +func (c *Cache[T]) Trim(perc float64) { c.cache.Trim(perc) } // store will cache this result under all of its required cache keys. -func (c *Cache[Value]) store(res result[Value]) (evict func()) { +func (c *Cache[T]) store(res *result) (evict func()) { + var toEvict []*result + // Get primary key - pnext := c.next + res.PKey = c.next c.next++ - if pnext > c.next { + if res.PKey > c.next { panic("cache primary key overflow") } @@ -371,15 +382,19 @@ func (c *Cache[Value]) store(res result[Value]) (evict func()) { for _, conflict := range pkeys { // Get the overlapping result with this key. entry, _ := c.cache.Cache.Get(conflict) + confRes := entry.Value.(*result) // From conflicting entry, drop this key, this // will prevent eviction cleanup key confusion. - entry.Value.Keys.drop(key.info.name) + confRes.Keys.drop(key.info.name) - if len(entry.Value.Keys) == 0 { + if len(res.Keys) == 0 { // We just over-wrote the only lookup key for // this value, so we drop its primary key too. c.cache.Cache.Delete(conflict) + + // Add finished result to evict queue. + toEvict = append(toEvict, confRes) } } @@ -388,42 +403,27 @@ func (c *Cache[Value]) store(res result[Value]) (evict func()) { } // Store primary key lookup. - pkeys = append(pkeys, pnext) + pkeys = append(pkeys, res.PKey) key.info.pkeys[key.key] = pkeys } - // Store main entry under primary key, using evict hook if needed - c.cache.Cache.SetWithHook(pnext, &ttl.Entry[int64, result[Value]]{ - Expiry: c.expiry(), - Key: pnext, - Value: res, - }, func(_ int64, item *ttl.Entry[int64, result[Value]]) { - evict = func() { c.cache.Evict(item.Key, item.Value) } + // Store main entry under primary key, catch evicted. + c.cache.Cache.SetWithHook(res.PKey, &simple.Entry{ + Key: res.PKey, + Value: res, + }, func(_ int64, item *simple.Entry) { + toEvict = append(toEvict, item.Value.(*result)) }) - 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) + if len(toEvict) == 0 { + // none evicted. + return nil + } + + return func() { + for _, res := range toEvict { + // Call evict hook on each entry. + c.cache.Evict(res.PKey, res) + } } - return 0 -} - -type result[Value any] struct { - // keys accessible under - Keys cacheKeys - - // cached value - Value Value - - // cached error - Error error } diff --git a/vendor/codeberg.org/gruf/go-cache/v3/result/key.go b/vendor/codeberg.org/gruf/go-cache/v3/result/key.go index bcf12c3de..cf86c7c30 100644 --- a/vendor/codeberg.org/gruf/go-cache/v3/result/key.go +++ b/vendor/codeberg.org/gruf/go-cache/v3/result/key.go @@ -145,7 +145,7 @@ type structField struct { } // genKey generates a cache key string for given key parts (i.e. serializes them using "go-mangler"). -func (sk structKey) genKey(parts []any) string { +func (sk *structKey) genKey(parts []any) string { // Check this expected no. key parts. if len(parts) != len(sk.fields) { panic(fmt.Sprintf("incorrect no. key parts provided: want=%d received=%d", len(parts), len(sk.fields))) @@ -246,10 +246,12 @@ func isExported(fnName string) bool { }, } +// getBuf ... func getBuf() *byteutil.Buffer { return bufPool.Get().(*byteutil.Buffer) } +// putBuf ... func putBuf(buf *byteutil.Buffer) { if buf.Cap() > int(^uint16(0)) { return // drop large bufs diff --git a/vendor/codeberg.org/gruf/go-cache/v3/result/pool.go b/vendor/codeberg.org/gruf/go-cache/v3/result/pool.go new file mode 100644 index 000000000..c5cbeda57 --- /dev/null +++ b/vendor/codeberg.org/gruf/go-cache/v3/result/pool.go @@ -0,0 +1,24 @@ +package result + +import "sync" + +// resultPool is a global pool for result +// objects, regardless of cache type. +var resultPool sync.Pool + +// getEntry fetches a result from pool, or allocates new. +func getResult() *result { + v := resultPool.Get() + if v == nil { + return new(result) + } + return v.(*result) +} + +// putResult replaces a result in the pool. +func putResult(r *result) { + r.Keys = nil + r.Value = nil + r.Error = nil + resultPool.Put(r) +} diff --git a/vendor/codeberg.org/gruf/go-cache/v3/simple/cache.go b/vendor/codeberg.org/gruf/go-cache/v3/simple/cache.go new file mode 100644 index 000000000..0224871bc --- /dev/null +++ b/vendor/codeberg.org/gruf/go-cache/v3/simple/cache.go @@ -0,0 +1,454 @@ +package simple + +import ( + "sync" + + "codeberg.org/gruf/go-maps" +) + +// Entry represents an item in the cache. +type Entry struct { + Key any + Value any +} + +// 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. +type Cache[Key comparable, Value any] struct { + // Evict is the hook that is called when an item is evicted from the cache. + Evict func(Key, Value) + + // Invalid is the hook that is called when an item's data in the cache is invalidated, includes Add/Set. + Invalid func(Key, Value) + + // Cache is the underlying hashmap used for this cache. + Cache maps.LRUMap[Key, *Entry] + + // Embedded mutex. + sync.Mutex +} + +// New returns a new initialized Cache with given initial length, maximum capacity and item TTL. +func New[K comparable, V any](len, cap int) *Cache[K, V] { + c := new(Cache[K, V]) + c.Init(len, cap) + return c +} + +// Init will initialize this cache with given initial length, maximum capacity and item TTL. +func (c *Cache[K, V]) Init(len, cap int) { + c.SetEvictionCallback(nil) + c.SetInvalidateCallback(nil) + c.Cache.Init(len, cap) +} + +// SetEvictionCallback: implements cache.Cache's SetEvictionCallback(). +func (c *Cache[K, V]) SetEvictionCallback(hook func(K, V)) { + c.locked(func() { c.Evict = hook }) +} + +// SetInvalidateCallback: implements cache.Cache's SetInvalidateCallback(). +func (c *Cache[K, V]) SetInvalidateCallback(hook func(K, V)) { + c.locked(func() { c.Invalid = hook }) +} + +// Get: implements cache.Cache's Get(). +func (c *Cache[K, V]) Get(key K) (V, bool) { + var ( + // did exist in cache? + ok bool + + // cached value. + v V + ) + + c.locked(func() { + var item *Entry + + // Check for item in cache + item, ok = c.Cache.Get(key) + if !ok { + return + } + + // Set item value. + v = item.Value.(V) + }) + + return v, ok +} + +// Add: implements cache.Cache's Add(). +func (c *Cache[K, V]) Add(key K, value V) bool { + var ( + // did exist in cache? + ok bool + + // was entry evicted? + ev bool + + // evicted key values. + evcK K + evcV V + + // hook func ptrs. + evict func(K, V) + ) + + c.locked(func() { + // Check if in cache. + ok = c.Cache.Has(key) + if ok { + return + } + + // Alloc new entry. + new := getEntry() + new.Key = key + new.Value = value + + // Add new entry to cache and catched any evicted item. + c.Cache.SetWithHook(key, new, func(_ K, item *Entry) { + evcK = item.Key.(K) + evcV = item.Value.(V) + ev = true + putEntry(item) + }) + + // Set hook func ptr. + evict = c.Evict + }) + + if ev && evict != nil { + // Pass to eviction hook. + evict(evcK, evcV) + } + + return !ok +} + +// Set: implements cache.Cache's Set(). +func (c *Cache[K, V]) Set(key K, value V) { + var ( + // did exist in cache? + ok bool + + // was entry evicted? + ev bool + + // old value. + oldV V + + // evicted key values. + evcK K + evcV V + + // hook func ptrs. + invalid func(K, V) + evict func(K, V) + ) + + c.locked(func() { + var item *Entry + + // Check for item in cache + item, ok = c.Cache.Get(key) + + if ok { + // Set old value. + oldV = item.Value.(V) + + // Update the existing item. + item.Value = value + } else { + // Alloc new entry. + new := getEntry() + new.Key = key + new.Value = value + + // Add new entry to cache and catched any evicted item. + c.Cache.SetWithHook(key, new, func(_ K, item *Entry) { + evcK = item.Key.(K) + evcV = item.Value.(V) + ev = true + putEntry(item) + }) + } + + // Set hook func ptrs. + invalid = c.Invalid + evict = c.Evict + }) + + if ok && invalid != nil { + // Pass to invalidate hook. + invalid(key, oldV) + } + + if ev && evict != nil { + // Pass to eviction hook. + evict(evcK, evcV) + } +} + +// CAS: implements cache.Cache's CAS(). +func (c *Cache[K, V]) CAS(key K, old V, new V, cmp func(V, V) bool) bool { + var ( + // did exist in cache? + ok bool + + // swapped value. + oldV V + + // hook func ptrs. + invalid func(K, V) + ) + + c.locked(func() { + var item *Entry + + // Check for item in cache + item, ok = c.Cache.Get(key) + if !ok { + return + } + + // Set old value. + oldV = item.Value.(V) + + // Perform the comparison + if !cmp(old, oldV) { + var zero V + oldV = zero + return + } + + // Update value. + item.Value = new + + // Set hook func ptr. + invalid = c.Invalid + }) + + if ok && invalid != nil { + // Pass to invalidate hook. + invalid(key, oldV) + } + + return ok +} + +// Swap: implements cache.Cache's Swap(). +func (c *Cache[K, V]) Swap(key K, swp V) V { + var ( + // did exist in cache? + ok bool + + // swapped value. + oldV V + + // hook func ptrs. + invalid func(K, V) + ) + + c.locked(func() { + var item *Entry + + // Check for item in cache + item, ok = c.Cache.Get(key) + if !ok { + return + } + + // Set old value. + oldV = item.Value.(V) + + // Update value. + item.Value = swp + + // Set hook func ptr. + invalid = c.Invalid + }) + + if ok && invalid != nil { + // Pass to invalidate hook. + invalid(key, oldV) + } + + return oldV +} + +// Has: implements cache.Cache's Has(). +func (c *Cache[K, V]) Has(key K) (ok bool) { + c.locked(func() { + ok = c.Cache.Has(key) + }) + return +} + +// Invalidate: implements cache.Cache's Invalidate(). +func (c *Cache[K, V]) Invalidate(key K) (ok bool) { + var ( + // old value. + oldV V + + // hook func ptrs. + invalid func(K, V) + ) + + c.locked(func() { + var item *Entry + + // Check for item in cache + item, ok = c.Cache.Get(key) + if !ok { + return + } + + // Set old value. + oldV = item.Value.(V) + + // Remove from cache map + _ = c.Cache.Delete(key) + + // Free entry + putEntry(item) + + // Set hook func ptrs. + invalid = c.Invalid + }) + + if ok && invalid != nil { + // Pass to invalidate hook. + invalid(key, oldV) + } + + return +} + +// InvalidateAll: implements cache.Cache's InvalidateAll(). +func (c *Cache[K, V]) InvalidateAll(keys ...K) (ok bool) { + var ( + // deleted items. + items []*Entry + + // hook func ptrs. + invalid func(K, V) + ) + + // Allocate a slice for invalidated. + items = make([]*Entry, 0, len(keys)) + + c.locked(func() { + for x := range keys { + var item *Entry + + // Check for item in cache + item, ok = c.Cache.Get(keys[x]) + if !ok { + continue + } + + // Append this old value. + items = append(items, item) + + // Remove from cache map + _ = c.Cache.Delete(keys[x]) + } + + // Set hook func ptrs. + invalid = c.Invalid + }) + + if invalid != nil { + for x := range items { + // Pass to invalidate hook. + k := items[x].Key.(K) + v := items[x].Value.(V) + invalid(k, v) + + // Free this entry. + putEntry(items[x]) + } + } + + return +} + +// Clear: implements cache.Cache's Clear(). +func (c *Cache[K, V]) Clear() { c.Trim(100) } + +// Trim will truncate the cache to ensure it stays within given percentage of total capacity. +func (c *Cache[K, V]) Trim(perc float64) { + var ( + // deleted items + items []*Entry + + // hook func ptrs. + invalid func(K, V) + ) + + c.locked(func() { + // Calculate number of cache items to truncate. + max := (perc / 100) * float64(c.Cache.Cap()) + diff := c.Cache.Len() - int(max) + if diff <= 0 { + return + } + + // Set hook func ptr. + invalid = c.Invalid + + // Truncate by calculated length. + items = c.truncate(diff, invalid) + }) + + if invalid != nil { + for x := range items { + // Pass to invalidate hook. + k := items[x].Key.(K) + v := items[x].Value.(V) + invalid(k, v) + + // Free this entry. + putEntry(items[x]) + } + } +} + +// Len: implements cache.Cache's Len(). +func (c *Cache[K, V]) Len() (l int) { + c.locked(func() { l = c.Cache.Len() }) + return +} + +// Cap: implements cache.Cache's Cap(). +func (c *Cache[K, V]) Cap() (l int) { + c.locked(func() { l = c.Cache.Cap() }) + return +} + +// locked performs given function within mutex lock (NOTE: UNLOCK IS NOT DEFERRED). +func (c *Cache[K, V]) locked(fn func()) { + c.Lock() + fn() + c.Unlock() +} + +// truncate will truncate the cache by given size, returning deleted items. +func (c *Cache[K, V]) truncate(sz int, hook func(K, V)) []*Entry { + if hook == nil { + // No hook to execute, simply release all truncated entries. + c.Cache.Truncate(sz, func(_ K, item *Entry) { putEntry(item) }) + return nil + } + + // Allocate a slice for deleted. + deleted := make([]*Entry, 0, sz) + + // Truncate and catch all deleted k-v pairs. + c.Cache.Truncate(sz, func(_ K, item *Entry) { + deleted = append(deleted, item) + }) + + return deleted +} diff --git a/vendor/codeberg.org/gruf/go-cache/v3/simple/pool.go b/vendor/codeberg.org/gruf/go-cache/v3/simple/pool.go new file mode 100644 index 000000000..2fc99ab0f --- /dev/null +++ b/vendor/codeberg.org/gruf/go-cache/v3/simple/pool.go @@ -0,0 +1,23 @@ +package simple + +import "sync" + +// entryPool is a global pool for Entry +// objects, regardless of cache type. +var entryPool sync.Pool + +// getEntry fetches an Entry from pool, or allocates new. +func getEntry() *Entry { + v := entryPool.Get() + if v == nil { + return new(Entry) + } + return v.(*Entry) +} + +// putEntry replaces an Entry in the pool. +func putEntry(e *Entry) { + e.Key = nil + e.Value = nil + entryPool.Put(e) +} diff --git a/vendor/codeberg.org/gruf/go-cache/v3/ttl/ttl.go b/vendor/codeberg.org/gruf/go-cache/v3/ttl/ttl.go index af108e336..106d675c8 100644 --- a/vendor/codeberg.org/gruf/go-cache/v3/ttl/ttl.go +++ b/vendor/codeberg.org/gruf/go-cache/v3/ttl/ttl.go @@ -15,7 +15,7 @@ type Entry[Key comparable, Value any] struct { 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 TTLCache implementation, providing both the base Cache interface and unsafe access to underlying map to allow flexibility in building your own. type Cache[Key comparable, Value any] struct { // TTL is the cache item TTL. TTL time.Duration diff --git a/vendor/github.com/DmitriyVTitov/size/.gitignore b/vendor/github.com/DmitriyVTitov/size/.gitignore new file mode 100644 index 000000000..ae4c566d2 --- /dev/null +++ b/vendor/github.com/DmitriyVTitov/size/.gitignore @@ -0,0 +1,19 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Dependency directories (remove the comment below to include it) +# vendor/ + +example +.idea +go.sum \ No newline at end of file diff --git a/vendor/github.com/DmitriyVTitov/size/LICENSE b/vendor/github.com/DmitriyVTitov/size/LICENSE new file mode 100644 index 000000000..507b0b74c --- /dev/null +++ b/vendor/github.com/DmitriyVTitov/size/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Dmitriy Titov (Дмитрий Титов) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/DmitriyVTitov/size/README.md b/vendor/github.com/DmitriyVTitov/size/README.md new file mode 100644 index 000000000..215a749cc --- /dev/null +++ b/vendor/github.com/DmitriyVTitov/size/README.md @@ -0,0 +1,48 @@ +# size - calculates variable's memory consumption at runtime + +### Part of the [Transflow Project](http://transflow.ru/) + +Sometimes you may need a tool to measure the size of object in your Go program at runtime. This package makes an attempt to do so. Package based on `binary.Size()` from Go standard library. + +Features: +- supports non-fixed size variables and struct fields: `struct`, `int`, `slice`, `string`, `map`; +- supports complex types including structs with non-fixed size fields; +- supports all basic types (numbers, bool); +- supports `chan` and `interface`; +- supports pointers; +- implements infinite recursion detection (i.e. pointer inside struct field references to parent struct). + +### Usage example + +``` +package main + +import ( + "fmt" + + // Use latest tag. + "github.com/DmitriyVTitov/size" +) + +func main() { + a := struct { + a int + b string + c bool + d int32 + e []byte + f [3]int64 + }{ + a: 10, // 8 bytes + b: "Text", // 16 (string itself) + 4 = 20 bytes + c: true, // 1 byte + d: 25, // 4 bytes + e: []byte{'c', 'd', 'e'}, // 24 (slice itself) + 3 = 27 bytes + f: [3]int64{1, 2, 3}, // 3 * 8 = 24 bytes + } // 84 + 3 (padding) = 87 bytes + + fmt.Println(size.Of(a)) +} + +// Output: 87 +``` diff --git a/vendor/github.com/DmitriyVTitov/size/size.go b/vendor/github.com/DmitriyVTitov/size/size.go new file mode 100644 index 000000000..b52e2c41d --- /dev/null +++ b/vendor/github.com/DmitriyVTitov/size/size.go @@ -0,0 +1,142 @@ +// Package size implements run-time calculation of size of the variable. +// Source code is based on "binary.Size()" function from Go standard library. +// size.Of() omits size of slices, arrays and maps containers itself (24, 24 and 8 bytes). +// When counting maps separate calculations are done for keys and values. +package size + +import ( + "reflect" + "unsafe" +) + +// Of returns the size of 'v' in bytes. +// If there is an error during calculation, Of returns -1. +func Of(v interface{}) int { + // Cache with every visited pointer so we don't count two pointers + // to the same memory twice. + cache := make(map[uintptr]bool) + return sizeOf(reflect.Indirect(reflect.ValueOf(v)), cache) +} + +// sizeOf returns the number of bytes the actual data represented by v occupies in memory. +// If there is an error, sizeOf returns -1. +func sizeOf(v reflect.Value, cache map[uintptr]bool) int { + switch v.Kind() { + + case reflect.Array: + sum := 0 + for i := 0; i < v.Len(); i++ { + s := sizeOf(v.Index(i), cache) + if s < 0 { + return -1 + } + sum += s + } + + return sum + (v.Cap()-v.Len())*int(v.Type().Elem().Size()) + + case reflect.Slice: + // return 0 if this node has been visited already + if cache[v.Pointer()] { + return 0 + } + cache[v.Pointer()] = true + + sum := 0 + for i := 0; i < v.Len(); i++ { + s := sizeOf(v.Index(i), cache) + if s < 0 { + return -1 + } + sum += s + } + + sum += (v.Cap() - v.Len()) * int(v.Type().Elem().Size()) + + return sum + int(v.Type().Size()) + + case reflect.Struct: + sum := 0 + for i, n := 0, v.NumField(); i < n; i++ { + s := sizeOf(v.Field(i), cache) + if s < 0 { + return -1 + } + sum += s + } + + // Look for struct padding. + padding := int(v.Type().Size()) + for i, n := 0, v.NumField(); i < n; i++ { + padding -= int(v.Field(i).Type().Size()) + } + + return sum + padding + + case reflect.String: + s := v.String() + hdr := (*reflect.StringHeader)(unsafe.Pointer(&s)) + if cache[hdr.Data] { + return int(v.Type().Size()) + } + cache[hdr.Data] = true + return len(s) + int(v.Type().Size()) + + case reflect.Ptr: + // return Ptr size if this node has been visited already (infinite recursion) + if cache[v.Pointer()] { + return int(v.Type().Size()) + } + cache[v.Pointer()] = true + if v.IsNil() { + return int(reflect.New(v.Type()).Type().Size()) + } + s := sizeOf(reflect.Indirect(v), cache) + if s < 0 { + return -1 + } + return s + int(v.Type().Size()) + + case reflect.Bool, + reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, + reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, + reflect.Int, reflect.Uint, + reflect.Chan, + reflect.Uintptr, + reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128, + reflect.Func: + return int(v.Type().Size()) + + case reflect.Map: + // return 0 if this node has been visited already (infinite recursion) + if cache[v.Pointer()] { + return 0 + } + cache[v.Pointer()] = true + sum := 0 + keys := v.MapKeys() + for i := range keys { + val := v.MapIndex(keys[i]) + // calculate size of key and value separately + sv := sizeOf(val, cache) + if sv < 0 { + return -1 + } + sum += sv + sk := sizeOf(keys[i], cache) + if sk < 0 { + return -1 + } + sum += sk + } + // Include overhead due to unused map buckets. 10.79 comes + // from https://golang.org/src/runtime/map.go. + return sum + int(v.Type().Size()) + int(float64(len(keys))*10.79) + + case reflect.Interface: + return sizeOf(v.Elem(), cache) + int(v.Type().Size()) + + } + + return -1 +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 006cc3e5d..a711fcba7 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -13,10 +13,11 @@ codeberg.org/gruf/go-bytesize # codeberg.org/gruf/go-byteutil v1.1.2 ## explicit; go 1.16 codeberg.org/gruf/go-byteutil -# codeberg.org/gruf/go-cache/v3 v3.4.4 +# codeberg.org/gruf/go-cache/v3 v3.5.3 ## explicit; go 1.19 codeberg.org/gruf/go-cache/v3 codeberg.org/gruf/go-cache/v3/result +codeberg.org/gruf/go-cache/v3/simple codeberg.org/gruf/go-cache/v3/ttl # codeberg.org/gruf/go-debug v1.3.0 ## explicit; go 1.16 @@ -69,6 +70,9 @@ codeberg.org/gruf/go-sched codeberg.org/gruf/go-store/v2/kv codeberg.org/gruf/go-store/v2/storage codeberg.org/gruf/go-store/v2/util +# github.com/DmitriyVTitov/size v1.5.0 +## explicit; go 1.14 +github.com/DmitriyVTitov/size # github.com/KimMachineGun/automemlimit v0.2.6 ## explicit; go 1.19 github.com/KimMachineGun/automemlimit