[performance] convert enum strings to ints (#3558)

* convert statuses.visibility and notifications.notification_type columns from type string -> int for performance / space savings

* fix test trying to compare string to int

* fix instance count query using string literal instead of gtsmodel const type

* ensure a default value is always set

* also migrate the account settings and sin bin status tables

* initialize maps outside loops and place into singular enum mapping creation func

* use int16 for enum types

* update sinbinstatus creation to be from a snapshot at initial creation

* add snapshot of poll type at creation time
This commit is contained in:
kim 2024-11-25 13:48:59 +00:00 committed by GitHub
commit cac9d65029
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
32 changed files with 940 additions and 91 deletions

View file

@ -26,7 +26,7 @@ type AccountSettings struct {
AccountID string `bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // AccountID that owns this settings.
CreatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created.
UpdatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item was last updated.
Privacy Visibility `bun:",nullzero"` // Default post privacy for this account
Privacy Visibility `bun:",nullzero,default:3"` // Default post privacy for this account
Sensitive *bool `bun:",nullzero,notnull,default:false"` // Set posts from this account to sensitive by default?
Language string `bun:",nullzero,notnull,default:'en'"` // What language does this account post in?
StatusContentType string `bun:",nullzero"` // What is the default format for statuses posted by this account (only for local accounts).
@ -34,7 +34,7 @@ type AccountSettings struct {
CustomCSS string `bun:",nullzero"` // Custom CSS that should be displayed for this Account's profile and statuses.
EnableRSS *bool `bun:",nullzero,notnull,default:false"` // enable RSS feed subscription for this account's public posts at [URL]/feed
HideCollections *bool `bun:",nullzero,notnull,default:false"` // Hide this account's followers/following collections.
WebVisibility Visibility `bun:",nullzero,notnull,default:public"` // Visibility level of statuses that visitors can view via the web profile.
WebVisibility Visibility `bun:",nullzero,notnull,default:3"` // Visibility level of statuses that visitors can view via the web profile.
InteractionPolicyDirect *InteractionPolicy `bun:""` // Interaction policy to use for new direct visibility statuses by this account. If null, assume default policy.
InteractionPolicyMutualsOnly *InteractionPolicy `bun:""` // Interaction policy to use for new mutuals only visibility statuses. If null, assume default policy.
InteractionPolicyFollowersOnly *InteractionPolicy `bun:""` // Interaction policy to use for new followers only visibility statuses. If null, assume default policy.

View file

@ -0,0 +1,24 @@
// 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 gtsmodel
// enumType is the type we (at least, should) use
// for database enum types. it is the largest size
// supported by a PostgreSQL SMALLINT, since an
// SQLite SMALLINT is actually variable in size.
type enumType int16

View file

@ -224,7 +224,7 @@ func DefaultInteractionPolicyFor(v Visibility) *InteractionPolicy {
case VisibilityDirect:
return DefaultInteractionPolicyDirect()
default:
panic("visibility " + v + " not recognized")
panic("invalid visibility")
}
}

View file

@ -34,20 +34,51 @@ type Notification struct {
Read *bool `bun:",nullzero,notnull,default:false"` // Notification has been seen/read
}
// NotificationType describes the reason/type of this notification.
type NotificationType string
// NotificationType describes the
// reason/type of this notification.
type NotificationType enumType
// Notification Types
const (
NotificationFollow NotificationType = "follow" // NotificationFollow -- someone followed you
NotificationFollowRequest NotificationType = "follow_request" // NotificationFollowRequest -- someone requested to follow you
NotificationMention NotificationType = "mention" // NotificationMention -- someone mentioned you in their status
NotificationReblog NotificationType = "reblog" // NotificationReblog -- someone boosted one of your statuses
NotificationFave NotificationType = "favourite" // NotificationFave -- someone faved/liked one of your statuses
NotificationPoll NotificationType = "poll" // NotificationPoll -- a poll you voted in or created has ended
NotificationStatus NotificationType = "status" // NotificationStatus -- someone you enabled notifications for has posted a status.
NotificationSignup NotificationType = "admin.sign_up" // NotificationSignup -- someone has submitted a new account sign-up to the instance.
NotificationPendingFave NotificationType = "pending.favourite" // Someone has faved a status of yours, which requires approval by you.
NotificationPendingReply NotificationType = "pending.reply" // Someone has replied to a status of yours, which requires approval by you.
NotificationPendingReblog NotificationType = "pending.reblog" // Someone has boosted a status of yours, which requires approval by you.
// Notification Types
NotificationFollow NotificationType = 1 // NotificationFollow -- someone followed you
NotificationFollowRequest NotificationType = 2 // NotificationFollowRequest -- someone requested to follow you
NotificationMention NotificationType = 3 // NotificationMention -- someone mentioned you in their status
NotificationReblog NotificationType = 4 // NotificationReblog -- someone boosted one of your statuses
NotificationFave NotificationType = 5 // NotificationFave -- someone faved/liked one of your statuses
NotificationPoll NotificationType = 6 // NotificationPoll -- a poll you voted in or created has ended
NotificationStatus NotificationType = 7 // NotificationStatus -- someone you enabled notifications for has posted a status.
NotificationSignup NotificationType = 8 // NotificationSignup -- someone has submitted a new account sign-up to the instance.
NotificationPendingFave NotificationType = 9 // Someone has faved a status of yours, which requires approval by you.
NotificationPendingReply NotificationType = 10 // Someone has replied to a status of yours, which requires approval by you.
NotificationPendingReblog NotificationType = 11 // Someone has boosted a status of yours, which requires approval by you.
)
// String returns a stringified, frontend API compatible form of NotificationType.
func (t NotificationType) String() string {
switch t {
case NotificationFollow:
return "follow"
case NotificationFollowRequest:
return "follow_request"
case NotificationMention:
return "mention"
case NotificationReblog:
return "reblog"
case NotificationFave:
return "favourite"
case NotificationPoll:
return "poll"
case NotificationStatus:
return "status"
case NotificationSignup:
return "admin.sign_up"
case NotificationPendingFave:
return "pending.favourite"
case NotificationPendingReply:
return "pending.reply"
case NotificationPendingReblog:
return "pending.reblog"
default:
panic("invalid notification type")
}
}

View file

@ -263,27 +263,58 @@ type StatusToEmoji struct {
Emoji *Emoji `bun:"rel:belongs-to"`
}
// Visibility represents the visibility granularity of a status.
type Visibility string
// Visibility represents the
// visibility granularity of a status.
type Visibility enumType
const (
// VisibilityNone means nobody can see this.
// It's only used for web status visibility.
VisibilityNone Visibility = "none"
// VisibilityPublic means this status will be visible to everyone on all timelines.
VisibilityPublic Visibility = "public"
// VisibilityUnlocked means this status will be visible to everyone, but will only show on home timeline to followers, and in lists.
VisibilityUnlocked Visibility = "unlocked"
VisibilityNone Visibility = 1
// VisibilityPublic means this status will
// be visible to everyone on all timelines.
VisibilityPublic Visibility = 2
// VisibilityUnlocked means this status will be visible to everyone,
// but will only show on home timeline to followers, and in lists.
VisibilityUnlocked Visibility = 3
// VisibilityFollowersOnly means this status is viewable to followers only.
VisibilityFollowersOnly Visibility = "followers_only"
// VisibilityMutualsOnly means this status is visible to mutual followers only.
VisibilityMutualsOnly Visibility = "mutuals_only"
// VisibilityDirect means this status is visible only to mentioned recipients.
VisibilityDirect Visibility = "direct"
VisibilityFollowersOnly Visibility = 4
// VisibilityMutualsOnly means this status
// is visible to mutual followers only.
VisibilityMutualsOnly Visibility = 5
// VisibilityDirect means this status is
// visible only to mentioned recipients.
VisibilityDirect Visibility = 6
// VisibilityDefault is used when no other setting can be found.
VisibilityDefault Visibility = VisibilityUnlocked
)
// String returns a stringified, frontend API compatible form of Visibility.
func (v Visibility) String() string {
switch v {
case VisibilityNone:
return "none"
case VisibilityPublic:
return "public"
case VisibilityUnlocked:
return "unlocked"
case VisibilityFollowersOnly:
return "followers_only"
case VisibilityMutualsOnly:
return "mutuals_only"
case VisibilityDirect:
return "direct"
default:
panic("invalid visibility")
}
}
// Content models the simple string content
// of a status along with its ContentMap,
// which contains content entries keyed by