Преглед на файлове

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

greatroar преди 4 години
родител
ревизия
37d0ba1660
променени са 1 файла, в които са добавени 28 реда и са изтрити 22 реда
  1. 28 22
      lib/watchaggregator/aggregator.go

+ 28 - 22
lib/watchaggregator/aggregator.go

@@ -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())
 }