code: func (c *Cacher) startDispatching(event *watchCacheEvent) {
  	triggerValues, supported := c.triggerValues(event)
  
  	c.Lock()
  	defer c.Unlock()
  
  	c.dispatching = true
  	// We are reusing the slice to avoid memory reallocations in every
  	// dispatchEvent() call. That may prevent Go GC from freeing items
  	// from previous phases that are sitting behind the current length
  	// of the slice, but there is only a limited number of those and the
  	// gain from avoiding memory allocations is much bigger.
  	c.watchersBuffer = c.watchersBuffer[:0]
  
  	if event.Type == watch.Bookmark {
  		c.startDispatchingBookmarkEvents()
  		// return here to reduce following code indentation and diff
  		return
  	}
  
  	// Iterate over "allWatchers" no matter what the trigger function is.
  	for _, watcher := range c.watchers.allWatchers {
  		c.watchersBuffer = append(c.watchersBuffer, watcher)
  	}
  	if supported {
  		// Iterate over watchers interested in the given values of the trigger.
  		for _, triggerValue := range triggerValues {
  			for _, watcher := range c.watchers.valueWatchers[triggerValue] {
  				c.watchersBuffer = append(c.watchersBuffer, watcher)
  			}
  		}
  	} else {
  		// supported equal to false generally means that trigger function
  		// is not defined (or not aware of any indexes). In this case,
  		// watchers filters should generally also don't generate any
  		// trigger values, but can cause problems in case of some
  		// misconfiguration. Thus we paranoidly leave this branch.
  
  		// Iterate over watchers interested in exact values for all values.
  		for _, watchers := range c.watchers.valueWatchers {
  			for _, watcher := range watchers {
  				c.watchersBuffer = append(c.watchersBuffer, watcher)
  			}
  		}
  	}
  }
docs: // startDispatching chooses watchers potentially interested in a given event
  // a marks dispatching as true.