mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-30 15:42:25 -05:00 
			
		
		
		
	add local timeline, fix up merge conflicts
This commit is contained in:
		
					parent
					
						
							
								d3484b9e8f
							
						
					
				
			
			
				commit
				
					
						dc1cf2c7b0
					
				
			
		
					 4 changed files with 47 additions and 106 deletions
				
			
		
							
								
								
									
										1
									
								
								internal/cache/cache.go
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								internal/cache/cache.go
									
										
									
									
										vendored
									
									
								
							|  | @ -216,6 +216,7 @@ func (c *Caches) Sweep(threshold float64) { | ||||||
| 	c.Timelines.Home.Trim(threshold) | 	c.Timelines.Home.Trim(threshold) | ||||||
| 	c.Timelines.List.Trim(threshold) | 	c.Timelines.List.Trim(threshold) | ||||||
| 	c.Timelines.Public.Trim(threshold) | 	c.Timelines.Public.Trim(threshold) | ||||||
|  | 	c.Timelines.Local.Trim(threshold) | ||||||
| 	c.Visibility.Trim(threshold) | 	c.Visibility.Trim(threshold) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										11
									
								
								internal/cache/timeline.go
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										11
									
								
								internal/cache/timeline.go
									
										
									
									
										vendored
									
									
								
							|  | @ -32,6 +32,9 @@ type TimelineCaches struct { | ||||||
| 
 | 
 | ||||||
| 	// Public ... | 	// Public ... | ||||||
| 	Public timeline.StatusTimeline | 	Public timeline.StatusTimeline | ||||||
|  | 
 | ||||||
|  | 	// Local ... | ||||||
|  | 	Local timeline.StatusTimeline | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (c *Caches) initHomeTimelines() { | func (c *Caches) initHomeTimelines() { | ||||||
|  | @ -57,3 +60,11 @@ func (c *Caches) initPublicTimeline() { | ||||||
| 
 | 
 | ||||||
| 	c.Timelines.Public.Init(cap) | 	c.Timelines.Public.Init(cap) | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | func (c *Caches) initLocalTimeline() { | ||||||
|  | 	cap := 1000 | ||||||
|  | 
 | ||||||
|  | 	log.Infof(nil, "cache size = %d", cap) | ||||||
|  | 
 | ||||||
|  | 	c.Timelines.Local.Init(cap) | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										38
									
								
								internal/cache/timeline/status.go
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										38
									
								
								internal/cache/timeline/status.go
									
										
									
									
										vendored
									
									
								
							|  | @ -30,6 +30,7 @@ import ( | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/log" | 	"github.com/superseriousbusiness/gotosocial/internal/log" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/paging" | 	"github.com/superseriousbusiness/gotosocial/internal/paging" | ||||||
|  | 	"github.com/superseriousbusiness/gotosocial/internal/util" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/util/xslices" | 	"github.com/superseriousbusiness/gotosocial/internal/util/xslices" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | @ -247,6 +248,12 @@ type StatusTimeline struct { | ||||||
| 	idx_AccountID        *structr.Index //nolint:revive | 	idx_AccountID        *structr.Index //nolint:revive | ||||||
| 	idx_BoostOfID        *structr.Index //nolint:revive | 	idx_BoostOfID        *structr.Index //nolint:revive | ||||||
| 	idx_BoostOfAccountID *structr.Index //nolint:revive | 	idx_BoostOfAccountID *structr.Index //nolint:revive | ||||||
|  | 
 | ||||||
|  | 	// ... | ||||||
|  | 	last atomic.Pointer[structr.Direction] | ||||||
|  | 
 | ||||||
|  | 	// ... | ||||||
|  | 	max int | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Init ... | // Init ... | ||||||
|  | @ -330,9 +337,15 @@ func (t *StatusTimeline) Load( | ||||||
| 	ord := page.Order() | 	ord := page.Order() | ||||||
| 	dir := toDirection(ord) | 	dir := toDirection(ord) | ||||||
| 
 | 
 | ||||||
| 	// First we attempt to load status metadata | 	// First we attempt to load status | ||||||
| 	// entries from the timeline cache, up to lim. | 	// metadata entries from the timeline | ||||||
| 	metas := t.cache.Select(min, max, lim, dir) | 	// cache, up to given limit. | ||||||
|  | 	metas := t.cache.Select( | ||||||
|  | 		util.PtrIf(min), | ||||||
|  | 		util.PtrIf(max), | ||||||
|  | 		util.PtrIf(lim), | ||||||
|  | 		dir, | ||||||
|  | 	) | ||||||
| 
 | 
 | ||||||
| 	// Set the starting lo / hi ID paging | 	// Set the starting lo / hi ID paging | ||||||
| 	// values. We continually update these | 	// values. We continually update these | ||||||
|  | @ -584,11 +597,24 @@ func (t *StatusTimeline) UnprepareByAccountIDs(accountIDs ...string) { | ||||||
| 
 | 
 | ||||||
| // Trim ... | // Trim ... | ||||||
| func (t *StatusTimeline) Trim(threshold float64) { | func (t *StatusTimeline) Trim(threshold float64) { | ||||||
| 	panic("TODO") | 
 | ||||||
|  | 	// ... | ||||||
|  | 	dir := structr.Asc | ||||||
|  | 
 | ||||||
|  | 	// ... | ||||||
|  | 	max := threshold * float64(t.max) | ||||||
|  | 
 | ||||||
|  | 	// ... | ||||||
|  | 	if p := t.last.Load(); p != nil { | ||||||
|  | 		dir = !(*p) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// ... | ||||||
|  | 	t.cache.Trim(int(max), dir) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Clear will remove all cached entries from timeline. | // Clear will remove all cached entries from underlying timeline. | ||||||
| func (t *StatusTimeline) Clear() { t.cache.Clear() } | func (t *StatusTimeline) Clear() { t.cache.Trim(0, structr.Desc) } | ||||||
| 
 | 
 | ||||||
| // prepare will take a slice of cached (or, freshly loaded!) StatusMeta{} | // prepare will take a slice of cached (or, freshly loaded!) StatusMeta{} | ||||||
| // models, and use given functions to return prepared frontend API models. | // models, and use given functions to return prepared frontend API models. | ||||||
|  |  | ||||||
|  | @ -21,11 +21,13 @@ import ( | ||||||
| 	"context" | 	"context" | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"slices" | 	"slices" | ||||||
|  | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/db" | 	"github.com/superseriousbusiness/gotosocial/internal/db" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/gtscontext" | 	"github.com/superseriousbusiness/gotosocial/internal/gtscontext" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/gtserror" | 	"github.com/superseriousbusiness/gotosocial/internal/gtserror" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | ||||||
|  | 	"github.com/superseriousbusiness/gotosocial/internal/id" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/paging" | 	"github.com/superseriousbusiness/gotosocial/internal/paging" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/state" | 	"github.com/superseriousbusiness/gotosocial/internal/state" | ||||||
| 	"github.com/uptrace/bun" | 	"github.com/uptrace/bun" | ||||||
|  | @ -126,104 +128,6 @@ func (t *timelineDB) GetHomeTimeline(ctx context.Context, accountID string, page | ||||||
| 	) | 	) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| <<<<<<< HEAD |  | ||||||
| func (t *timelineDB) GetPublicTimeline( |  | ||||||
| 	ctx context.Context, |  | ||||||
| 	maxID string, |  | ||||||
| 	sinceID string, |  | ||||||
| 	minID string, |  | ||||||
| 	limit int, |  | ||||||
| 	local bool, |  | ||||||
| ) ([]*gtsmodel.Status, error) { |  | ||||||
| 	// Ensure reasonable |  | ||||||
| 	if limit < 0 { |  | ||||||
| 		limit = 0 |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if local { |  | ||||||
| 		return t.getLocalTimeline( |  | ||||||
| 			ctx, |  | ||||||
| 			maxID, |  | ||||||
| 			sinceID, |  | ||||||
| 			minID, |  | ||||||
| 			limit, |  | ||||||
| 		) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// Make educated guess for slice size |  | ||||||
| 	var ( |  | ||||||
| 		statusIDs   = make([]string, 0, limit) |  | ||||||
| 		frontToBack = true |  | ||||||
| 	) |  | ||||||
| 
 |  | ||||||
| 	q := t.db. |  | ||||||
| 		NewSelect(). |  | ||||||
| 		TableExpr("? AS ?", bun.Ident("statuses"), bun.Ident("status")). |  | ||||||
| 		// Public only. |  | ||||||
| 		Where("? = ?", bun.Ident("status.visibility"), gtsmodel.VisibilityPublic). |  | ||||||
| 		// Ignore boosts. |  | ||||||
| 		Where("? IS NULL", bun.Ident("status.boost_of_id")). |  | ||||||
| 		// Only include statuses that aren't pending approval. |  | ||||||
| 		Where("? = ?", bun.Ident("status.pending_approval"), false). |  | ||||||
| 		// Select only IDs from table |  | ||||||
| 		Column("status.id") |  | ||||||
| 
 |  | ||||||
| 	if maxID == "" || maxID >= id.Highest { |  | ||||||
| 		const future = 24 * time.Hour |  | ||||||
| 
 |  | ||||||
| 		// don't return statuses more than 24hr in the future |  | ||||||
| 		maxID = id.NewULIDFromTime(time.Now().Add(future)) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// return only statuses LOWER (ie., older) than maxID |  | ||||||
| 	q = q.Where("? < ?", bun.Ident("status.id"), maxID) |  | ||||||
| 
 |  | ||||||
| 	if sinceID != "" { |  | ||||||
| 		// return only statuses HIGHER (ie., newer) than sinceID |  | ||||||
| 		q = q.Where("? > ?", bun.Ident("status.id"), sinceID) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if minID != "" { |  | ||||||
| 		// return only statuses HIGHER (ie., newer) than minID |  | ||||||
| 		q = q.Where("? > ?", bun.Ident("status.id"), minID) |  | ||||||
| 
 |  | ||||||
| 		// page up |  | ||||||
| 		frontToBack = false |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if limit > 0 { |  | ||||||
| 		// limit amount of statuses returned |  | ||||||
| 		q = q.Limit(limit) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if frontToBack { |  | ||||||
| 		// Page down. |  | ||||||
| 		q = q.Order("status.id DESC") |  | ||||||
| 	} else { |  | ||||||
| 		// Page up. |  | ||||||
| 		q = q.Order("status.id ASC") |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if err := q.Scan(ctx, &statusIDs); err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if len(statusIDs) == 0 { |  | ||||||
| 		return nil, nil |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// If we're paging up, we still want statuses |  | ||||||
| 	// to be sorted by ID desc, so reverse ids slice. |  | ||||||
| 	// https://zchee.github.io/golang-wiki/SliceTricks/#reversing |  | ||||||
| 	if !frontToBack { |  | ||||||
| 		for l, r := 0, len(statusIDs)-1; l < r; l, r = l+1, r-1 { |  | ||||||
| 			statusIDs[l], statusIDs[r] = statusIDs[r], statusIDs[l] |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// Return status IDs loaded from cache + db. |  | ||||||
| 	return t.state.DB.GetStatusesByIDs(ctx, statusIDs) |  | ||||||
| ======= |  | ||||||
| func (t *timelineDB) GetPublicTimeline(ctx context.Context, page *paging.Page) ([]*gtsmodel.Status, error) { | func (t *timelineDB) GetPublicTimeline(ctx context.Context, page *paging.Page) ([]*gtsmodel.Status, error) { | ||||||
| 	return loadStatusTimelinePage(ctx, t.db, t.state, | 	return loadStatusTimelinePage(ctx, t.db, t.state, | ||||||
| 
 | 
 | ||||||
|  | @ -239,12 +143,11 @@ func (t *timelineDB) GetPublicTimeline(ctx context.Context, page *paging.Page) ( | ||||||
| 			q = q.Where("? IS NULL", bun.Ident("boost_of_id")) | 			q = q.Where("? IS NULL", bun.Ident("boost_of_id")) | ||||||
| 
 | 
 | ||||||
| 			// Only include statuses that aren't pending approval. | 			// Only include statuses that aren't pending approval. | ||||||
| 			q = q.Where("NOT ? = ?", bun.Ident("pending_approval"), true) | 			q = q.Where("? = ?", bun.Ident("pending_approval"), false) | ||||||
| 
 | 
 | ||||||
| 			return q, nil | 			return q, nil | ||||||
| 		}, | 		}, | ||||||
| 	) | 	) | ||||||
| >>>>>>> 6f0abe7fb (start work rewriting timeline cache type) |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (t *timelineDB) getLocalTimeline( | func (t *timelineDB) getLocalTimeline( | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue