[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:
tobi 2023-04-06 13:43:13 +02:00 committed by GitHub
commit 3510454768
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 1319 additions and 1365 deletions

View file

@ -21,47 +21,63 @@ import (
"container/list"
)
const (
defaultDesiredIndexedItemsLength = 400
defaultDesiredPreparedItemsLength = 50
)
func (t *timeline) Prune(desiredPreparedItemsLength int, desiredIndexedItemsLength int) int {
t.Lock()
defer t.Unlock()
pruneList := func(pruneTo int, listToPrune *list.List) int {
if listToPrune == nil {
// no need to prune
return 0
}
unprunedLength := listToPrune.Len()
if unprunedLength <= pruneTo {
// no need to prune
return 0
}
// work from the back + assemble a slice of entries that we will prune
amountStillToPrune := unprunedLength - pruneTo
itemsToPrune := make([]*list.Element, 0, amountStillToPrune)
for e := listToPrune.Back(); amountStillToPrune > 0; e = e.Prev() {
itemsToPrune = append(itemsToPrune, e)
amountStillToPrune--
}
// remove the entries we found
var totalPruned int
for _, e := range itemsToPrune {
listToPrune.Remove(e)
totalPruned++
}
return totalPruned
l := t.items.data
if l == nil {
// Nothing to prune.
return 0
}
prunedPrepared := pruneList(desiredPreparedItemsLength, t.preparedItems.data)
prunedIndexed := pruneList(desiredIndexedItemsLength, t.indexedItems.data)
var (
position int
totalPruned int
toRemove *[]*list.Element
)
return prunedPrepared + prunedIndexed
// Only initialize toRemove if we know we're
// going to need it, otherwise skiperino.
if toRemoveLen := t.items.data.Len() - desiredIndexedItemsLength; toRemoveLen > 0 {
toRemove = func() *[]*list.Element { tr := make([]*list.Element, 0, toRemoveLen); return &tr }()
}
// Work from the front of the list until we get
// to the point where we need to start pruning.
for e := l.Front(); e != nil; e = e.Next() {
position++
if position <= desiredPreparedItemsLength {
// We're still within our allotted
// prepped length, nothing to do yet.
continue
}
// We need to *at least* unprepare this entry.
// If we're beyond our indexed length already,
// we can just remove the item completely.
if position > desiredIndexedItemsLength {
*toRemove = append(*toRemove, e)
totalPruned++
continue
}
entry := e.Value.(*indexedItemsEntry) //nolint:forcetypeassert
if entry.prepared == nil {
// It's already unprepared (mood).
continue
}
entry.prepared = nil // <- eat this up please garbage collector nom nom nom
totalPruned++
}
if toRemove != nil {
for _, e := range *toRemove {
l.Remove(e)
}
}
return totalPruned
}