You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
828 lines
26 KiB
828 lines
26 KiB
// 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 <http://www.gnu.org/licenses/>. |
|
|
|
package cache |
|
|
|
import ( |
|
"crypto/rsa" |
|
"strings" |
|
"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" |
|
"github.com/superseriousbusiness/gotosocial/internal/util" |
|
) |
|
|
|
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 |
|
|
|
// exampleWebPushAuth is a Base64-encoded 16-byte random auth secret. |
|
// This secret is consumed as Base64 by webpush-go. |
|
exampleWebPushAuth = "ZVxqlt5fzVgmSz2aqiA2XQ==" |
|
|
|
// exampleWebPushP256dh is a Base64-encoded DH P-256 public key. |
|
// This secret is consumed as Base64 by webpush-go. |
|
exampleWebPushP256dh = "OrpejO16gV97uBXew/T0I7YoUv/CX8fz0z4g8RrQ+edXJqQPjX3XVSo2P0HhcCpCOR1+Dzj5LFcK9jYNqX7SBg==" |
|
) |
|
|
|
var ( |
|
// Example time calculated at ~ 14th August, 2023. Because if |
|
// we use `time.Now()` in our structs below, it populates |
|
// them with locale data which throws-off size calculations. |
|
// |
|
// This is because the locale data is (relatively) very large |
|
// in-memory, but it's global "singletons" ptr'd to by the time |
|
// structs, so inconsequential to our calculated cache size. |
|
// Unfortunately the size.Of() function is not aware of this! |
|
exampleTime = time.Time{}.Add(1692010328 * time.Second) |
|
|
|
// stop trying to collapse this var |
|
// block, gofmt, you motherfucker. |
|
_ = interface{}(nil) |
|
) |
|
|
|
// 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. |
|
resultValueOverhead := uintptr(size.Of(&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.GetCacheAccountSettingsMemRatio() + |
|
config.GetCacheAccountStatsMemRatio() + |
|
config.GetCacheApplicationMemRatio() + |
|
config.GetCacheBlockMemRatio() + |
|
config.GetCacheBlockIDsMemRatio() + |
|
config.GetCacheBoostOfIDsMemRatio() + |
|
config.GetCacheClientMemRatio() + |
|
config.GetCacheEmojiMemRatio() + |
|
config.GetCacheEmojiCategoryMemRatio() + |
|
config.GetCacheFilterMemRatio() + |
|
config.GetCacheFilterKeywordMemRatio() + |
|
config.GetCacheFilterStatusMemRatio() + |
|
config.GetCacheFollowMemRatio() + |
|
config.GetCacheFollowIDsMemRatio() + |
|
config.GetCacheFollowRequestMemRatio() + |
|
config.GetCacheFollowRequestIDsMemRatio() + |
|
config.GetCacheFollowingTagIDsMemRatio() + |
|
config.GetCacheInReplyToIDsMemRatio() + |
|
config.GetCacheInstanceMemRatio() + |
|
config.GetCacheInteractionRequestMemRatio() + |
|
config.GetCacheListMemRatio() + |
|
config.GetCacheListIDsMemRatio() + |
|
config.GetCacheListedIDsMemRatio() + |
|
config.GetCacheMarkerMemRatio() + |
|
config.GetCacheMediaMemRatio() + |
|
config.GetCacheMentionMemRatio() + |
|
config.GetCacheMoveMemRatio() + |
|
config.GetCacheNotificationMemRatio() + |
|
config.GetCachePollMemRatio() + |
|
config.GetCachePollVoteMemRatio() + |
|
config.GetCachePollVoteIDsMemRatio() + |
|
config.GetCacheReportMemRatio() + |
|
config.GetCacheSinBinStatusMemRatio() + |
|
config.GetCacheStatusMemRatio() + |
|
config.GetCacheStatusBookmarkMemRatio() + |
|
config.GetCacheStatusBookmarkIDsMemRatio() + |
|
config.GetCacheStatusFaveMemRatio() + |
|
config.GetCacheStatusFaveIDsMemRatio() + |
|
config.GetCacheTagMemRatio() + |
|
config.GetCacheThreadMuteMemRatio() + |
|
config.GetCacheTokenMemRatio() + |
|
config.GetCacheTombstoneMemRatio() + |
|
config.GetCacheUserMemRatio() + |
|
config.GetCacheUserMuteMemRatio() + |
|
config.GetCacheUserMuteIDsMemRatio() + |
|
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, |
|
MemorializedAt: exampleTime, |
|
CreatedAt: exampleTime, |
|
UpdatedAt: exampleTime, |
|
FetchedAt: exampleTime, |
|
Locked: util.Ptr(true), |
|
Discoverable: util.Ptr(false), |
|
URI: exampleURI, |
|
URL: exampleURI, |
|
InboxURI: exampleURI, |
|
OutboxURI: exampleURI, |
|
FollowersURI: exampleURI, |
|
FollowingURI: exampleURI, |
|
FeaturedCollectionURI: exampleURI, |
|
ActorType: gtsmodel.AccountActorTypePerson, |
|
PrivateKey: &rsa.PrivateKey{}, |
|
PublicKey: &rsa.PublicKey{}, |
|
PublicKeyURI: exampleURI, |
|
SensitizedAt: exampleTime, |
|
SilencedAt: exampleTime, |
|
SuspendedAt: exampleTime, |
|
SuspensionOrigin: exampleID, |
|
})) |
|
} |
|
|
|
func sizeofAccountNote() uintptr { |
|
return uintptr(size.Of(>smodel.AccountNote{ |
|
ID: exampleID, |
|
AccountID: exampleID, |
|
TargetAccountID: exampleID, |
|
Comment: exampleTextSmall, |
|
})) |
|
} |
|
|
|
func sizeofAccountSettings() uintptr { |
|
return uintptr(size.Of(>smodel.AccountSettings{ |
|
AccountID: exampleID, |
|
CreatedAt: exampleTime, |
|
UpdatedAt: exampleTime, |
|
Privacy: gtsmodel.VisibilityFollowersOnly, |
|
Sensitive: util.Ptr(true), |
|
Language: "fr", |
|
StatusContentType: "text/plain", |
|
CustomCSS: exampleText, |
|
EnableRSS: util.Ptr(true), |
|
HideCollections: util.Ptr(false), |
|
})) |
|
} |
|
|
|
func sizeofAccountStats() uintptr { |
|
return uintptr(size.Of(>smodel.AccountStats{ |
|
AccountID: exampleID, |
|
FollowersCount: util.Ptr(100), |
|
FollowingCount: util.Ptr(100), |
|
StatusesCount: util.Ptr(100), |
|
StatusesPinnedCount: util.Ptr(100), |
|
LastStatusAt: exampleTime, |
|
})) |
|
} |
|
|
|
func sizeofApplication() uintptr { |
|
return uintptr(size.Of(>smodel.Application{ |
|
ID: exampleID, |
|
Name: exampleUsername, |
|
Website: exampleURI, |
|
RedirectURIs: []string{exampleURI}, |
|
ClientID: exampleID, |
|
ClientSecret: exampleID, |
|
Scopes: exampleTextSmall, |
|
ManagedByUserID: exampleID, |
|
})) |
|
} |
|
|
|
func sizeofBlock() uintptr { |
|
return uintptr(size.Of(>smodel.Block{ |
|
ID: exampleID, |
|
CreatedAt: exampleTime, |
|
UpdatedAt: exampleTime, |
|
URI: exampleURI, |
|
AccountID: exampleID, |
|
TargetAccountID: exampleID, |
|
})) |
|
} |
|
|
|
func sizeofConversation() uintptr { |
|
return uintptr(size.Of(>smodel.Conversation{ |
|
ID: exampleID, |
|
CreatedAt: exampleTime, |
|
UpdatedAt: exampleTime, |
|
AccountID: exampleID, |
|
OtherAccountIDs: []string{exampleID, exampleID, exampleID}, |
|
OtherAccountsKey: strings.Join([]string{exampleID, exampleID, exampleID}, ","), |
|
ThreadID: exampleID, |
|
LastStatusID: exampleID, |
|
Read: util.Ptr(true), |
|
})) |
|
} |
|
|
|
func sizeofDomainPermissionDraft() uintptr { |
|
return uintptr(size.Of(>smodel.DomainPermissionDraft{ |
|
ID: exampleID, |
|
CreatedAt: exampleTime, |
|
UpdatedAt: exampleTime, |
|
PermissionType: gtsmodel.DomainPermissionBlock, |
|
Domain: "example.org", |
|
CreatedByAccountID: exampleID, |
|
PrivateComment: exampleTextSmall, |
|
PublicComment: exampleTextSmall, |
|
Obfuscate: util.Ptr(false), |
|
SubscriptionID: exampleID, |
|
})) |
|
} |
|
|
|
func sizeofDomainPermissionSubscription() uintptr { |
|
return uintptr(size.Of(>smodel.DomainPermissionSubscription{ |
|
ID: exampleID, |
|
Priority: uint8(255), |
|
Title: exampleTextSmall, |
|
PermissionType: gtsmodel.DomainPermissionBlock, |
|
AsDraft: util.Ptr(true), |
|
CreatedByAccountID: exampleID, |
|
URI: exampleURI, |
|
ContentType: gtsmodel.DomainPermSubContentTypeCSV, |
|
FetchUsername: "username", |
|
FetchPassword: "password", |
|
FetchedAt: exampleTime, |
|
SuccessfullyFetchedAt: exampleTime, |
|
ETag: exampleID, |
|
LastModified: exampleTime, |
|
Error: exampleTextSmall, |
|
})) |
|
} |
|
|
|
func sizeofEmoji() uintptr { |
|
return uintptr(size.Of(>smodel.Emoji{ |
|
ID: exampleID, |
|
Shortcode: exampleTextSmall, |
|
Domain: exampleURI, |
|
CreatedAt: exampleTime, |
|
UpdatedAt: exampleTime, |
|
ImageRemoteURL: exampleURI, |
|
ImageStaticRemoteURL: exampleURI, |
|
ImageURL: exampleURI, |
|
ImagePath: exampleURI, |
|
ImageStaticURL: exampleURI, |
|
ImageStaticPath: exampleURI, |
|
ImageContentType: "image/png", |
|
ImageStaticContentType: "image/png", |
|
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: exampleTime, |
|
UpdatedAt: exampleTime, |
|
})) |
|
} |
|
|
|
func sizeofFilter() uintptr { |
|
return uintptr(size.Of(>smodel.Filter{ |
|
ID: exampleID, |
|
CreatedAt: exampleTime, |
|
UpdatedAt: exampleTime, |
|
ExpiresAt: exampleTime, |
|
AccountID: exampleID, |
|
Title: exampleTextSmall, |
|
Action: gtsmodel.FilterActionHide, |
|
})) |
|
} |
|
|
|
func sizeofFilterKeyword() uintptr { |
|
return uintptr(size.Of(>smodel.FilterKeyword{ |
|
ID: exampleID, |
|
CreatedAt: exampleTime, |
|
UpdatedAt: exampleTime, |
|
FilterID: exampleID, |
|
Keyword: exampleTextSmall, |
|
})) |
|
} |
|
|
|
func sizeofFilterStatus() uintptr { |
|
return uintptr(size.Of(>smodel.FilterStatus{ |
|
ID: exampleID, |
|
CreatedAt: exampleTime, |
|
UpdatedAt: exampleTime, |
|
FilterID: exampleID, |
|
StatusID: exampleID, |
|
})) |
|
} |
|
|
|
func sizeofFollow() uintptr { |
|
return uintptr(size.Of(>smodel.Follow{ |
|
ID: exampleID, |
|
CreatedAt: exampleTime, |
|
UpdatedAt: exampleTime, |
|
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: exampleTime, |
|
UpdatedAt: exampleTime, |
|
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: exampleTime, |
|
UpdatedAt: exampleTime, |
|
Domain: exampleURI, |
|
URI: exampleURI, |
|
Title: exampleTextSmall, |
|
ShortDescription: exampleText, |
|
Description: exampleText, |
|
ContactEmail: exampleUsername, |
|
ContactAccountUsername: exampleUsername, |
|
ContactAccountID: exampleID, |
|
})) |
|
} |
|
|
|
func sizeofInteractionRequest() uintptr { |
|
return uintptr(size.Of(>smodel.InteractionRequest{ |
|
ID: exampleID, |
|
CreatedAt: exampleTime, |
|
StatusID: exampleID, |
|
TargetAccountID: exampleID, |
|
InteractingAccountID: exampleID, |
|
InteractionURI: exampleURI, |
|
InteractionType: gtsmodel.InteractionAnnounce, |
|
ResponseURI: exampleURI, |
|
AcceptedAt: exampleTime, |
|
})) |
|
} |
|
|
|
func sizeofList() uintptr { |
|
return uintptr(size.Of(>smodel.List{ |
|
ID: exampleID, |
|
CreatedAt: exampleTime, |
|
UpdatedAt: exampleTime, |
|
Title: exampleTextSmall, |
|
AccountID: exampleID, |
|
RepliesPolicy: gtsmodel.RepliesPolicyFollowed, |
|
})) |
|
} |
|
|
|
func sizeofMarker() uintptr { |
|
return uintptr(size.Of(>smodel.Marker{ |
|
AccountID: exampleID, |
|
Name: gtsmodel.MarkerNameHome, |
|
UpdatedAt: exampleTime, |
|
Version: 0, |
|
LastReadID: exampleID, |
|
})) |
|
} |
|
|
|
func sizeofMedia() uintptr { |
|
return uintptr(size.Of(>smodel.MediaAttachment{ |
|
ID: exampleID, |
|
StatusID: exampleID, |
|
URL: exampleURI, |
|
RemoteURL: exampleURI, |
|
CreatedAt: exampleTime, |
|
Type: gtsmodel.FileTypeImage, |
|
AccountID: exampleID, |
|
Description: exampleText, |
|
ScheduledStatusID: exampleID, |
|
Blurhash: exampleTextSmall, |
|
File: gtsmodel.File{ |
|
Path: exampleURI, |
|
ContentType: "image/jpeg", |
|
}, |
|
Thumbnail: gtsmodel.Thumbnail{ |
|
Path: exampleURI, |
|
ContentType: "image/jpeg", |
|
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: exampleTime, |
|
OriginAccountID: exampleURI, |
|
OriginAccountURI: exampleURI, |
|
TargetAccountID: exampleID, |
|
NameString: exampleUsername, |
|
TargetAccountURI: exampleURI, |
|
TargetAccountURL: exampleURI, |
|
})) |
|
} |
|
|
|
func sizeofMove() uintptr { |
|
return uintptr(size.Of(>smodel.Move{ |
|
ID: exampleID, |
|
CreatedAt: exampleTime, |
|
UpdatedAt: exampleTime, |
|
AttemptedAt: exampleTime, |
|
SucceededAt: exampleTime, |
|
OriginURI: exampleURI, |
|
TargetURI: exampleURI, |
|
URI: exampleURI, |
|
})) |
|
} |
|
|
|
func sizeofNotification() uintptr { |
|
return uintptr(size.Of(>smodel.Notification{ |
|
ID: exampleID, |
|
NotificationType: gtsmodel.NotificationFavourite, |
|
CreatedAt: exampleTime, |
|
TargetAccountID: exampleID, |
|
OriginAccountID: exampleID, |
|
StatusID: exampleID, |
|
Read: func() *bool { ok := false; return &ok }(), |
|
})) |
|
} |
|
|
|
func sizeofPoll() uintptr { |
|
return uintptr(size.Of(>smodel.Poll{ |
|
ID: exampleID, |
|
Multiple: func() *bool { ok := false; return &ok }(), |
|
HideCounts: func() *bool { ok := false; return &ok }(), |
|
Options: []string{exampleTextSmall, exampleTextSmall, exampleTextSmall, exampleTextSmall}, |
|
StatusID: exampleID, |
|
ExpiresAt: exampleTime, |
|
})) |
|
} |
|
|
|
func sizeofPollVote() uintptr { |
|
return uintptr(size.Of(>smodel.PollVote{ |
|
ID: exampleID, |
|
Choices: []int{69, 420, 1337}, |
|
AccountID: exampleID, |
|
PollID: exampleID, |
|
CreatedAt: exampleTime, |
|
})) |
|
} |
|
|
|
func sizeofReport() uintptr { |
|
return uintptr(size.Of(>smodel.Report{ |
|
ID: exampleID, |
|
CreatedAt: exampleTime, |
|
UpdatedAt: exampleTime, |
|
URI: exampleURI, |
|
AccountID: exampleID, |
|
TargetAccountID: exampleID, |
|
Comment: exampleText, |
|
StatusIDs: []string{exampleID, exampleID, exampleID}, |
|
Forwarded: func() *bool { ok := true; return &ok }(), |
|
ActionTaken: exampleText, |
|
ActionTakenAt: exampleTime, |
|
ActionTakenByAccountID: exampleID, |
|
})) |
|
} |
|
|
|
func sizeofSinBinStatus() uintptr { |
|
return uintptr(size.Of(>smodel.SinBinStatus{ |
|
ID: exampleID, |
|
CreatedAt: exampleTime, |
|
UpdatedAt: exampleTime, |
|
URI: exampleURI, |
|
URL: exampleURI, |
|
Domain: exampleURI, |
|
AccountURI: exampleURI, |
|
InReplyToURI: exampleURI, |
|
Content: exampleText, |
|
AttachmentLinks: []string{exampleURI, exampleURI}, |
|
MentionTargetURIs: []string{exampleURI}, |
|
EmojiLinks: []string{exampleURI}, |
|
PollOptions: []string{exampleTextSmall, exampleTextSmall, exampleTextSmall, exampleTextSmall}, |
|
ContentWarning: exampleTextSmall, |
|
Visibility: gtsmodel.VisibilityPublic, |
|
Sensitive: util.Ptr(false), |
|
Language: "en", |
|
ActivityStreamsType: ap.ObjectNote, |
|
})) |
|
} |
|
|
|
func sizeofStatus() uintptr { |
|
return uintptr(size.Of(>smodel.Status{ |
|
ID: exampleID, |
|
URI: exampleURI, |
|
URL: exampleURI, |
|
Content: exampleText, |
|
Text: exampleText, |
|
ContentType: gtsmodel.StatusContentTypePlain, |
|
AttachmentIDs: []string{exampleID, exampleID, exampleID}, |
|
TagIDs: []string{exampleID, exampleID, exampleID}, |
|
MentionIDs: []string{}, |
|
EmojiIDs: []string{exampleID, exampleID, exampleID}, |
|
CreatedAt: exampleTime, |
|
EditedAt: exampleTime, |
|
FetchedAt: exampleTime, |
|
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 |
|
ContentWarningText: exampleUsername, // similar length |
|
Visibility: gtsmodel.VisibilityPublic, |
|
Sensitive: func() *bool { ok := false; return &ok }(), |
|
Language: "en", |
|
CreatedWithApplicationID: exampleID, |
|
Federated: func() *bool { ok := true; return &ok }(), |
|
ActivityStreamsType: ap.ObjectNote, |
|
})) |
|
} |
|
|
|
func sizeofStatusBookmark() uintptr { |
|
return uintptr(size.Of(>smodel.StatusBookmark{ |
|
ID: exampleID, |
|
AccountID: exampleID, |
|
Account: nil, |
|
TargetAccountID: exampleID, |
|
TargetAccount: nil, |
|
StatusID: exampleID, |
|
Status: nil, |
|
CreatedAt: exampleTime, |
|
UpdatedAt: exampleTime, |
|
})) |
|
} |
|
|
|
func sizeofStatusEdit() uintptr { |
|
return uintptr(size.Of(>smodel.StatusEdit{ |
|
ID: exampleID, |
|
Content: exampleText, |
|
ContentWarning: exampleUsername, // similar length |
|
Text: exampleText, |
|
ContentType: gtsmodel.StatusContentTypePlain, |
|
Language: "en", |
|
Sensitive: func() *bool { ok := false; return &ok }(), |
|
AttachmentIDs: []string{exampleID, exampleID, exampleID}, |
|
Attachments: nil, |
|
PollOptions: []string{exampleTextSmall, exampleTextSmall, exampleTextSmall, exampleTextSmall}, |
|
PollVotes: []int{69, 420, 1337, 1969}, |
|
StatusID: exampleID, |
|
CreatedAt: exampleTime, |
|
})) |
|
} |
|
|
|
func sizeofStatusFave() uintptr { |
|
return uintptr(size.Of(>smodel.StatusFave{ |
|
ID: exampleID, |
|
CreatedAt: exampleTime, |
|
AccountID: exampleID, |
|
TargetAccountID: exampleID, |
|
StatusID: exampleID, |
|
URI: exampleURI, |
|
})) |
|
} |
|
|
|
func sizeofTag() uintptr { |
|
return uintptr(size.Of(>smodel.Tag{ |
|
ID: exampleID, |
|
Name: exampleUsername, |
|
CreatedAt: exampleTime, |
|
UpdatedAt: exampleTime, |
|
Useable: func() *bool { ok := true; return &ok }(), |
|
Listable: func() *bool { ok := true; return &ok }(), |
|
})) |
|
} |
|
|
|
func sizeofThreadMute() uintptr { |
|
return uintptr(size.Of(>smodel.ThreadMute{ |
|
ID: exampleID, |
|
CreatedAt: exampleTime, |
|
UpdatedAt: exampleTime, |
|
ThreadID: exampleID, |
|
AccountID: exampleID, |
|
})) |
|
} |
|
|
|
func sizeofToken() uintptr { |
|
return uintptr(size.Of(>smodel.Token{ |
|
ID: exampleID, |
|
LastUsed: exampleTime, |
|
ClientID: exampleID, |
|
UserID: exampleID, |
|
RedirectURI: exampleURI, |
|
Scope: "r:w", |
|
Code: "", // TODO |
|
CodeChallenge: "", // TODO |
|
CodeChallengeMethod: "", // TODO |
|
CodeCreateAt: exampleTime, |
|
CodeExpiresAt: exampleTime, |
|
Access: exampleID + exampleID, |
|
AccessCreateAt: exampleTime, |
|
AccessExpiresAt: exampleTime, |
|
Refresh: "", // TODO: clients don't really support this very well yet |
|
RefreshCreateAt: exampleTime, |
|
RefreshExpiresAt: exampleTime, |
|
})) |
|
} |
|
|
|
func sizeofTombstone() uintptr { |
|
return uintptr(size.Of(>smodel.Tombstone{ |
|
ID: exampleID, |
|
CreatedAt: exampleTime, |
|
UpdatedAt: exampleTime, |
|
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{ |
|
ID: exampleID, |
|
CreatedAt: exampleTime, |
|
UpdatedAt: exampleTime, |
|
Email: exampleURI, |
|
AccountID: exampleID, |
|
EncryptedPassword: exampleTextSmall, |
|
InviteID: exampleID, |
|
Reason: exampleText, |
|
Locale: "en", |
|
CreatedByApplicationID: exampleID, |
|
LastEmailedAt: exampleTime, |
|
ConfirmationToken: exampleTextSmall, |
|
ConfirmationSentAt: exampleTime, |
|
ConfirmedAt: exampleTime, |
|
UnconfirmedEmail: exampleURI, |
|
Moderator: util.Ptr(false), |
|
Admin: util.Ptr(false), |
|
Disabled: util.Ptr(false), |
|
Approved: util.Ptr(false), |
|
ResetPasswordToken: exampleTextSmall, |
|
ResetPasswordSentAt: exampleTime, |
|
ExternalID: exampleID, |
|
})) |
|
} |
|
|
|
func sizeofUserMute() uintptr { |
|
return uintptr(size.Of(>smodel.UserMute{ |
|
ID: exampleID, |
|
CreatedAt: exampleTime, |
|
UpdatedAt: exampleTime, |
|
ExpiresAt: exampleTime, |
|
AccountID: exampleID, |
|
TargetAccountID: exampleID, |
|
Notifications: util.Ptr(false), |
|
})) |
|
} |
|
|
|
func sizeofWebPushSubscription() uintptr { |
|
return uintptr(size.Of(>smodel.WebPushSubscription{ |
|
TokenID: exampleID, |
|
Auth: exampleWebPushAuth, |
|
P256dh: exampleWebPushP256dh, |
|
})) |
|
}
|
|
|