<commit_before>package window

import (
	"fmt"
	"sync"
	"time"

	"go.skia.org/infra/go/git/repograph"
)

// Window is a struct used for managing time windows based on a duration and
// a minimum number of commits in zero or more repositories.
type Window struct {
	duration      time.Duration
	earliestStart time.Time
	mtx           sync.RWMutex
	numCommits    int
	repos         repograph.Map
	start         map[string]time.Time
}

// New returns a Window instance.
func New(duration time.Duration, numCommits int, repos repograph.Map) (*Window, error) {
	w := &Window{
		duration:   duration,
		numCommits: numCommits,
		repos:      repos,
		start:      map[string]time.Time{},
	}
	if err := w.Update(); err != nil {
		return nil, err
	}
	return w, nil
}

// Update updates the start time of the Window.
func (w *Window) Update() error {
	return w.UpdateWithTime(time.Now())
}

// UpdateWithTime updates the start time of the Window, using the given current time.
func (w *Window) UpdateWithTime(now time.Time) error {
	// Take the maximum of (time period, last N commits)
	earliest := now.Add(-w.duration)
	start := map[string]time.Time{}
	baseStart := now.Add(-w.duration)

	for repoUrl, r := range w.repos {
		s := baseStart

		// Just trace the first parent of each commit on the master
		// branch. In practice this can include more than N commits, but
		// it's better than some alternatives.
		c := r.Get("master")
		for i := 1; i < w.numCommits; i++ {
			p := c.GetParents()
			if len(p) < 1 {
				break
			}
			c = p[0]
		}
		if c.Timestamp.Before(s) {
			s = c.Timestamp
		}
		start[repoUrl] = s<commit_msg>[task scheduler] Fix Window: use most recent N commits from any branch<commit_after>package window

import (
	"fmt"
	"sync"
	"time"

	"go.skia.org/infra/go/git/repograph"
	"go.skia.org/infra/go/util"
)

// Window is a struct used for managing time windows based on a duration and
// a minimum number of commits in zero or more repositories.
type Window struct {
	duration      time.Duration
	earliestStart time.Time
	mtx           sync.RWMutex
	numCommits    int
	repos         repograph.Map
	start         map[string]time.Time
}

// New returns a Window instance.
func New(duration time.Duration, numCommits int, repos repograph.Map) (*Window, error) {
	w := &Window{
		duration:   duration,
		numCommits: numCommits,
		repos:      repos,
		start:      map[string]time.Time{},
	}
	if err := w.Update(); err != nil {
		return nil, err
	}
	return w, nil
}

// Update updates the start time of the Window.
func (w *Window) Update() error {
	return w.UpdateWithTime(time.Now())
}

// UpdateWithTime updates the start time of the Window, using the given current time.
func (w *Window) UpdateWithTime(now time.Time) error {
	// Take the maximum of (time period, last N commits)
	earliest := now.Add(-w.duration)
	start := map[string]time.Time{}
	baseStart := now.Add(-w.duration)

	for repoUrl, r := range w.repos {
		// Find the most recent N commits.
		// TODO(borenet): We should probably respect a branch blacklist.
		latest := time.Time{}
		for _, b := range r.Branches() {
			c := r.Get(b)
			for i := 1; i < w.numCommits; i++ {
				p := c.GetParents()
				if len(p) < 1 {
					break
				}
				c = p[0]
			}
			if c.Timestamp.After(latest) {
				latest = c.Timestamp
			}
		}

		// Take the earlier of the most recent N commits or baseStart.
		s := baseStart
		if !util.TimeIsZero(latest) && latest.Before(s) {
			s = latest
		}
		start[repoUrl] = s
{'fraction_non_alphanumeric': 0.1190544825598155, 'fraction_numerical': 0.0017296050735082155, 'mean_word_length': 2.925339366515837, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4497387', 'n_tokens_mistral': 1264, 'n_tokens_neox': 1156, 'n_words': 392}