mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2025-11-30 16:23:34 -06:00
[bugfix/chore] Refactor timeline code (#1656)
* start poking timelines * OK yes we're refactoring, but it's nothing like the last time so don't worry * more fiddling * update tests, simplify Get * thanks linter, you're the best, mwah mwah kisses * do a bit more tidying up * start buggering about with the prepare function * fix little oopsie * start merging lists into 1 * ik heb een heel zwaar leven nee nee echt waar * hey it works we did it reddit * regenerate swagger docs * tidy up a wee bit * adjust paging * fix little error, remove unused functions
This commit is contained in:
parent
c54510bc74
commit
3510454768
22 changed files with 1319 additions and 1365 deletions
|
|
@ -20,7 +20,7 @@ package timeline
|
|||
import (
|
||||
"container/list"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type indexedItems struct {
|
||||
|
|
@ -33,53 +33,87 @@ type indexedItemsEntry struct {
|
|||
boostOfID string
|
||||
accountID string
|
||||
boostOfAccountID string
|
||||
prepared Preparable
|
||||
}
|
||||
|
||||
// WARNING: ONLY CALL THIS FUNCTION IF YOU ALREADY HAVE
|
||||
// A LOCK ON THE TIMELINE CONTAINING THIS INDEXEDITEMS!
|
||||
func (i *indexedItems) insertIndexed(ctx context.Context, newEntry *indexedItemsEntry) (bool, error) {
|
||||
// Lazily init indexed items.
|
||||
if i.data == nil {
|
||||
i.data = &list.List{}
|
||||
i.data.Init()
|
||||
}
|
||||
|
||||
// if we have no entries yet, this is both the newest and oldest entry, so just put it in the front
|
||||
if i.data.Len() == 0 {
|
||||
// We have no entries yet, meaning this is both the
|
||||
// newest + oldest entry, so just put it in the front.
|
||||
i.data.PushFront(newEntry)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
var insertMark *list.Element
|
||||
var position int
|
||||
// We need to iterate through the index to make sure we put this item in the appropriate place according to when it was created.
|
||||
// We also need to make sure we're not inserting a duplicate item -- this can happen sometimes and it's not nice UX (*shudder*).
|
||||
var (
|
||||
insertMark *list.Element
|
||||
currentPosition int
|
||||
)
|
||||
|
||||
// We need to iterate through the index to make sure we put
|
||||
// this item in the appropriate place according to its id.
|
||||
// We also need to make sure we're not inserting a duplicate
|
||||
// item -- this can happen sometimes and it's sucky UX.
|
||||
for e := i.data.Front(); e != nil; e = e.Next() {
|
||||
position++
|
||||
currentPosition++
|
||||
|
||||
entry, ok := e.Value.(*indexedItemsEntry)
|
||||
if !ok {
|
||||
return false, errors.New("insertIndexed: could not parse e as an indexedItemsEntry")
|
||||
}
|
||||
currentEntry := e.Value.(*indexedItemsEntry) //nolint:forcetypeassert
|
||||
|
||||
skip, err := i.skipInsert(ctx, newEntry.itemID, newEntry.accountID, newEntry.boostOfID, newEntry.boostOfAccountID, entry.itemID, entry.accountID, entry.boostOfID, entry.boostOfAccountID, position)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if skip {
|
||||
// Check if we need to skip inserting this item based on
|
||||
// the current item.
|
||||
//
|
||||
// For example, if the new item is a boost, and the current
|
||||
// item is the original, we may not want to insert the boost
|
||||
// if it would appear very shortly after the original.
|
||||
if skip, err := i.skipInsert(
|
||||
ctx,
|
||||
newEntry.itemID,
|
||||
newEntry.accountID,
|
||||
newEntry.boostOfID,
|
||||
newEntry.boostOfAccountID,
|
||||
currentEntry.itemID,
|
||||
currentEntry.accountID,
|
||||
currentEntry.boostOfID,
|
||||
currentEntry.boostOfAccountID,
|
||||
currentPosition,
|
||||
); err != nil {
|
||||
return false, fmt.Errorf("insertIndexed: error calling skipInsert: %w", err)
|
||||
} else if skip {
|
||||
// We don't need to insert this at all,
|
||||
// so we can safely bail.
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// if the item to index is newer than e, insert it before e in the list
|
||||
if insertMark == nil {
|
||||
if newEntry.itemID > entry.itemID {
|
||||
insertMark = e
|
||||
}
|
||||
if insertMark != nil {
|
||||
// We already found our mark.
|
||||
continue
|
||||
}
|
||||
|
||||
if currentEntry.itemID > newEntry.itemID {
|
||||
// We're still in items newer than
|
||||
// the one we're trying to insert.
|
||||
continue
|
||||
}
|
||||
|
||||
// We found our spot!
|
||||
insertMark = e
|
||||
}
|
||||
|
||||
if insertMark != nil {
|
||||
i.data.InsertBefore(newEntry, insertMark)
|
||||
if insertMark == nil {
|
||||
// We looked through the whole timeline and didn't find
|
||||
// a mark, so the new item is the oldest item we've seen;
|
||||
// insert it at the back.
|
||||
i.data.PushBack(newEntry)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// if we reach this point it's the oldest item we've seen so put it at the back
|
||||
i.data.PushBack(newEntry)
|
||||
i.data.InsertBefore(newEntry, insertMark)
|
||||
return true, nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue