lib/watchaggregator: Replace counter map by two integers (#7856)

This commit is contained in:
greatroar 2021-08-01 12:30:20 +02:00 committed by GitHub
parent 734c2fc870
commit 37d0ba1660
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 28 additions and 22 deletions

View File

@ -104,18 +104,32 @@ type aggregator struct {
notifyTimer *time.Timer
notifyTimerNeedsReset bool
notifyTimerResetChan chan time.Duration
counts map[fs.EventType]int
counts eventCounter
root *eventDir
ctx context.Context
}
type eventCounter struct {
removes int // Includes mixed events.
nonRemoves int
}
func (c *eventCounter) add(typ fs.EventType, n int) {
if typ&fs.Remove != 0 {
c.removes += n
} else {
c.nonRemoves += n
}
}
func (c *eventCounter) total() int { return c.removes + c.nonRemoves }
func newAggregator(ctx context.Context, folderCfg config.FolderConfiguration) *aggregator {
a := &aggregator{
folderID: folderCfg.ID,
folderCfgUpdate: make(chan config.FolderConfiguration),
notifyTimerNeedsReset: false,
notifyTimerResetChan: make(chan time.Duration),
counts: make(map[fs.EventType]int),
root: newEventDir(),
ctx: ctx,
}
@ -176,7 +190,7 @@ func (a *aggregator) newEvent(event fs.Event, inProgress map[string]struct{}) {
}
func (a *aggregator) aggregateEvent(event fs.Event, evTime time.Time) {
if event.Name == "." || a.eventCount() == maxFiles {
if event.Name == "." || a.counts.total() == maxFiles {
l.Debugln(a, "Scan entire folder")
firstModTime := evTime
if a.root.childCount() != 0 {
@ -190,8 +204,8 @@ func (a *aggregator) aggregateEvent(event fs.Event, evTime time.Time) {
lastModTime: evTime,
evType: event.Type,
}
a.counts = make(map[fs.EventType]int)
a.counts[event.Type]++
a.counts = eventCounter{}
a.counts.add(event.Type, 1)
a.resetNotifyTimerIfNeeded()
return
}
@ -212,9 +226,9 @@ func (a *aggregator) aggregateEvent(event fs.Event, evTime time.Time) {
if ev, ok := parentDir.events[name]; ok {
ev.lastModTime = evTime
if merged := event.Type.Merge(ev.evType); ev.evType != merged {
a.counts[ev.evType]--
a.counts.add(ev.evType, -1)
a.counts.add(merged, 1)
ev.evType = merged
a.counts[ev.evType]++
}
l.Debugf("%v Parent %s (type %s) already tracked: %s", a, currPath, ev.evType, event.Name)
return
@ -249,9 +263,9 @@ func (a *aggregator) aggregateEvent(event fs.Event, evTime time.Time) {
if ev, ok := parentDir.events[name]; ok {
ev.lastModTime = evTime
if merged := event.Type.Merge(ev.evType); ev.evType != merged {
a.counts[ev.evType]--
a.counts.add(ev.evType, -1)
a.counts.add(merged, 1)
ev.evType = merged
a.counts[ev.evType]++
}
l.Debugf("%v Already tracked (type %v): %s", a, ev.evType, event.Name)
return
@ -272,7 +286,7 @@ func (a *aggregator) aggregateEvent(event fs.Event, evTime time.Time) {
if ok {
firstModTime = childDir.firstModTime()
if merged := event.Type.Merge(childDir.eventType()); event.Type != merged {
a.counts[event.Type]--
a.counts.add(event.Type, -1)
event.Type = merged
}
delete(parentDir.dirs, name)
@ -283,7 +297,7 @@ func (a *aggregator) aggregateEvent(event fs.Event, evTime time.Time) {
lastModTime: evTime,
evType: event.Type,
}
a.counts[event.Type]++
a.counts.add(event.Type, 1)
a.resetNotifyTimerIfNeeded()
}
@ -302,7 +316,7 @@ func (a *aggregator) resetNotifyTimer(duration time.Duration) {
}
func (a *aggregator) actOnTimer(out chan<- []string) {
c := a.eventCount()
c := a.counts.total()
if c == 0 {
l.Debugln(a, "No tracked events, waiting for new event.")
a.notifyTimerNeedsReset = true
@ -310,7 +324,7 @@ func (a *aggregator) actOnTimer(out chan<- []string) {
}
oldEvents := make(map[string]*aggregatedEvent, c)
a.popOldEventsTo(oldEvents, a.root, ".", time.Now(), true)
if a.notifyDelay != a.notifyTimeout && a.counts[fs.NonRemove] == 0 && a.counts[fs.Remove]+a.counts[fs.Mixed] != 0 {
if a.notifyDelay != a.notifyTimeout && a.counts.nonRemoves == 0 && a.counts.removes != 0 {
// Only delayed events remaining, no need to delay them additionally
a.popOldEventsTo(oldEvents, a.root, ".", time.Now(), false)
}
@ -376,7 +390,7 @@ func (a *aggregator) popOldEventsTo(to map[string]*aggregatedEvent, dir *eventDi
if a.isOld(event, currTime, delayRem) {
to[filepath.Join(dirPath, name)] = event
delete(dir.events, name)
a.counts[event.evType]--
a.counts.add(event.evType, -1)
}
}
}
@ -401,14 +415,6 @@ func (a *aggregator) isOld(ev *aggregatedEvent, currTime time.Time, delayRem boo
return currTime.Sub(ev.firstModTime) > a.notifyTimeout
}
func (a *aggregator) eventCount() int {
c := 0
for _, v := range a.counts {
c += v
}
return c
}
func (a *aggregator) String() string {
return fmt.Sprintf("aggregator/%s:", a.folderCfg.Description())
}