summaryrefslogtreecommitdiff
path: root/internal/timeline/index.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/timeline/index.go')
-rw-r--r--internal/timeline/index.go283
1 files changed, 0 insertions, 283 deletions
diff --git a/internal/timeline/index.go b/internal/timeline/index.go
deleted file mode 100644
index 6abb6d28d..000000000
--- a/internal/timeline/index.go
+++ /dev/null
@@ -1,283 +0,0 @@
-// 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 timeline
-
-import (
- "container/list"
- "context"
- "errors"
-
- "codeberg.org/gruf/go-kv"
- "github.com/superseriousbusiness/gotosocial/internal/db"
- "github.com/superseriousbusiness/gotosocial/internal/gtserror"
- "github.com/superseriousbusiness/gotosocial/internal/log"
-)
-
-func (t *timeline) indexXBetweenIDs(ctx context.Context, amount int, behindID string, beforeID string, frontToBack bool) error {
- l := log.
- WithContext(ctx).
- WithFields(kv.Fields{
- {"amount", amount},
- {"behindID", behindID},
- {"beforeID", beforeID},
- {"frontToBack", frontToBack},
- }...)
- l.Trace("entering indexXBetweenIDs")
-
- if beforeID >= behindID {
- // This is an impossible situation, we
- // can't index anything between these.
- return nil
- }
-
- t.Lock()
- defer t.Unlock()
-
- // Lazily init indexed items.
- if t.items.data == nil {
- t.items.data = &list.List{}
- t.items.data.Init()
- }
-
- // Start by mapping out the list so we know what
- // we have to do. Depending on the current state
- // of the list we might not have to do *anything*.
- var (
- position int
- listLen = t.items.data.Len()
- behindIDPosition int
- beforeIDPosition int
- )
-
- for e := t.items.data.Front(); e != nil; e = e.Next() {
- entry := e.Value.(*indexedItemsEntry)
-
- position++
-
- if entry.itemID > behindID {
- l.Trace("item is too new, continuing")
- continue
- }
-
- if behindIDPosition == 0 {
- // Gone far enough through the list
- // and found our behindID mark.
- // We only need to set this once.
- l.Tracef("found behindID mark %s at position %d", entry.itemID, position)
- behindIDPosition = position
- }
-
- if entry.itemID >= beforeID {
- // Push the beforeID mark back
- // one place every iteration.
- l.Tracef("setting beforeID mark %s at position %d", entry.itemID, position)
- beforeIDPosition = position
- }
-
- if entry.itemID <= beforeID {
- // We've gone beyond the bounds of
- // items we're interested in; stop.
- l.Trace("reached older items, breaking")
- break
- }
- }
-
- // We can now figure out if we need to make db calls.
- var grabMore bool
- switch {
- case listLen < amount:
- // The whole list is shorter than the
- // amount we're being asked to return,
- // make up the difference.
- grabMore = true
- amount -= listLen
- case beforeIDPosition-behindIDPosition < amount:
- // Not enough items between behindID and
- // beforeID to return amount required,
- // try to get more.
- grabMore = true
- }
-
- if !grabMore {
- // We're good!
- return nil
- }
-
- // Fetch additional items.
- items, err := t.grab(ctx, amount, behindID, beforeID, frontToBack)
- if err != nil {
- return err
- }
-
- // Index all the items we got. We already have
- // a lock on the timeline, so don't call IndexOne
- // here, since that will also try to get a lock!
- for _, item := range items {
- entry := &indexedItemsEntry{
- itemID: item.GetID(),
- boostOfID: item.GetBoostOfID(),
- accountID: item.GetAccountID(),
- boostOfAccountID: item.GetBoostOfAccountID(),
- }
-
- if _, err := t.items.insertIndexed(ctx, entry); err != nil {
- return gtserror.Newf("error inserting entry with itemID %s into index: %w", entry.itemID, err)
- }
- }
-
- return nil
-}
-
-// grab wraps the timeline's grabFunction in paging + filtering logic.
-func (t *timeline) grab(ctx context.Context, amount int, behindID string, beforeID string, frontToBack bool) ([]Timelineable, error) {
- var (
- sinceID string
- minID string
- grabbed int
- maxID = behindID
- filtered = make([]Timelineable, 0, amount)
- )
-
- if frontToBack {
- sinceID = beforeID
- } else {
- minID = beforeID
- }
-
- for attempts := 0; attempts < 5; attempts++ {
- if grabbed >= amount {
- // We got everything we needed.
- break
- }
-
- items, stop, err := t.grabFunction(
- ctx,
- t.timelineID,
- maxID,
- sinceID,
- minID,
- // Don't grab more than we need to.
- amount-grabbed,
- )
- if err != nil {
- // Grab function already checks for
- // db.ErrNoEntries, so if an error
- // is returned then it's a real one.
- return nil, err
- }
-
- if stop || len(items) == 0 {
- // No items left.
- break
- }
-
- // Set next query parameters.
- if frontToBack {
- // Page down.
- maxID = items[len(items)-1].GetID()
- if maxID <= beforeID {
- // Can't go any further.
- break
- }
- } else {
- // Page up.
- minID = items[0].GetID()
- if minID >= behindID {
- // Can't go any further.
- break
- }
- }
-
- for _, item := range items {
- ok, err := t.filterFunction(ctx, t.timelineID, item)
- if err != nil {
- if !errors.Is(err, db.ErrNoEntries) {
- // Real error here.
- return nil, err
- }
- log.Warnf(ctx, "errNoEntries while filtering item %s: %s", item.GetID(), err)
- continue
- }
-
- if ok {
- filtered = append(filtered, item)
- grabbed++ // count this as grabbed
- }
- }
- }
-
- return filtered, nil
-}
-
-func (t *timeline) IndexAndPrepareOne(ctx context.Context, statusID string, boostOfID string, accountID string, boostOfAccountID string) (bool, error) {
- t.Lock()
- defer t.Unlock()
-
- postIndexEntry := &indexedItemsEntry{
- itemID: statusID,
- boostOfID: boostOfID,
- accountID: accountID,
- boostOfAccountID: boostOfAccountID,
- }
-
- if inserted, err := t.items.insertIndexed(ctx, postIndexEntry); err != nil {
- return false, gtserror.Newf("error inserting indexed: %w", err)
- } else if !inserted {
- // Entry wasn't inserted, so
- // don't bother preparing it.
- return false, nil
- }
-
- preparable, err := t.prepareFunction(ctx, t.timelineID, statusID)
- if err != nil {
- return true, gtserror.Newf("error preparing: %w", err)
- }
- postIndexEntry.prepared = preparable
-
- return true, nil
-}
-
-func (t *timeline) Len() int {
- t.Lock()
- defer t.Unlock()
-
- if t.items == nil || t.items.data == nil {
- // indexedItems hasnt been initialized yet.
- return 0
- }
-
- return t.items.data.Len()
-}
-
-func (t *timeline) OldestIndexedItemID() string {
- t.Lock()
- defer t.Unlock()
-
- if t.items == nil || t.items.data == nil {
- // indexedItems hasnt been initialized yet.
- return ""
- }
-
- e := t.items.data.Back()
- if e == nil {
- // List was empty.
- return ""
- }
-
- return e.Value.(*indexedItemsEntry).itemID
-}