mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-29 04:22:24 -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.List.Trim(threshold) | ||||
| 	c.Timelines.Public.Trim(threshold) | ||||
| 	c.Timelines.Local.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 timeline.StatusTimeline | ||||
| 
 | ||||
| 	// Local ... | ||||
| 	Local timeline.StatusTimeline | ||||
| } | ||||
| 
 | ||||
| func (c *Caches) initHomeTimelines() { | ||||
|  | @ -57,3 +60,11 @@ func (c *Caches) initPublicTimeline() { | |||
| 
 | ||||
| 	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/log" | ||||
| 	"github.com/superseriousbusiness/gotosocial/internal/paging" | ||||
| 	"github.com/superseriousbusiness/gotosocial/internal/util" | ||||
| 	"github.com/superseriousbusiness/gotosocial/internal/util/xslices" | ||||
| ) | ||||
| 
 | ||||
|  | @ -247,6 +248,12 @@ type StatusTimeline struct { | |||
| 	idx_AccountID        *structr.Index //nolint:revive | ||||
| 	idx_BoostOfID        *structr.Index //nolint:revive | ||||
| 	idx_BoostOfAccountID *structr.Index //nolint:revive | ||||
| 
 | ||||
| 	// ... | ||||
| 	last atomic.Pointer[structr.Direction] | ||||
| 
 | ||||
| 	// ... | ||||
| 	max int | ||||
| } | ||||
| 
 | ||||
| // Init ... | ||||
|  | @ -330,9 +337,15 @@ func (t *StatusTimeline) Load( | |||
| 	ord := page.Order() | ||||
| 	dir := toDirection(ord) | ||||
| 
 | ||||
| 	// First we attempt to load status metadata | ||||
| 	// entries from the timeline cache, up to lim. | ||||
| 	metas := t.cache.Select(min, max, lim, dir) | ||||
| 	// First we attempt to load status | ||||
| 	// metadata entries from the timeline | ||||
| 	// 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 | ||||
| 	// values. We continually update these | ||||
|  | @ -584,11 +597,24 @@ func (t *StatusTimeline) UnprepareByAccountIDs(accountIDs ...string) { | |||
| 
 | ||||
| // Trim ... | ||||
| 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. | ||||
| func (t *StatusTimeline) Clear() { t.cache.Clear() } | ||||
| // Clear will remove all cached entries from underlying timeline. | ||||
| func (t *StatusTimeline) Clear() { t.cache.Trim(0, structr.Desc) } | ||||
| 
 | ||||
| // prepare will take a slice of cached (or, freshly loaded!) StatusMeta{} | ||||
| // models, and use given functions to return prepared frontend API models. | ||||
|  |  | |||
|  | @ -21,11 +21,13 @@ import ( | |||
| 	"context" | ||||
| 	"errors" | ||||
| 	"slices" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/superseriousbusiness/gotosocial/internal/db" | ||||
| 	"github.com/superseriousbusiness/gotosocial/internal/gtscontext" | ||||
| 	"github.com/superseriousbusiness/gotosocial/internal/gtserror" | ||||
| 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | ||||
| 	"github.com/superseriousbusiness/gotosocial/internal/id" | ||||
| 	"github.com/superseriousbusiness/gotosocial/internal/paging" | ||||
| 	"github.com/superseriousbusiness/gotosocial/internal/state" | ||||
| 	"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) { | ||||
| 	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")) | ||||
| 
 | ||||
| 			// 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 | ||||
| 		}, | ||||
| 	) | ||||
| >>>>>>> 6f0abe7fb (start work rewriting timeline cache type) | ||||
| } | ||||
| 
 | ||||
| func (t *timelineDB) getLocalTimeline( | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue