func (d *dirInfoCache) Store(dir string, info directoryPackageInfo) {
	d.mu.Lock()
	_, old := d.dirs[dir]
	d.dirs[dir] = &info
	var listeners []cacheListener
	for _, l := range d.listeners {
		listeners = append(listeners, l)
	}
	d.mu.Unlock()
	if !old {
		for _, l := range listeners {
			l(info)
		}
	}
}
Store stores the package info for dir.
package imports
import (
	"context"
	"fmt"
	"sync"
	"github.com/govim/govim/cmd/govim/internal/golang_org_x_tools/gopathwalk"
)
type directoryPackageStatus int
const (
	_ directoryPackageStatus = iota
	directoryScanned
	nameLoaded
	exportsLoaded
)
type directoryPackageInfo struct {
	status directoryPackageStatus
	err error
	dir      string
	rootType gopathwalk.RootType
	nonCanonicalImportPath string
	moduleDir  string  
	moduleName string  
	packageName string  
	exports []string
}
func (info *directoryPackageInfo) reachedStatus(target directoryPackageStatus) (bool, error) {
	if info.err == nil {
		return info.status >= target, nil
	}
	if info.status == target {
		return true, info.err
	}
	return true, nil
}
type dirInfoCache struct {
	mu sync.Mutex
	dirs      map[string]*directoryPackageInfo
	listeners map[*int]cacheListener
}
type cacheListener func(directoryPackageInfo)
func (d *dirInfoCache) ScanAndListen(ctx context.Context, listener cacheListener) func() {
	ctx, cancel := context.WithCancel(ctx)
	const maxInFlight = 10
	sema := make(chan struct{}, maxInFlight)
	for i := 0; i < maxInFlight; i++ {
		sema <- struct{}{}
	}
	cookie := new(int)  
	d.mu.Lock()
	var keys []string
	for key := range d.dirs {
		keys = append(keys, key)
	}
	d.listeners[cookie] = func(info directoryPackageInfo) {
		select {
		case <-ctx.Done():
			return
		case <-sema:
		}
		listener(info)
		sema <- struct{}{}
	}
	d.mu.Unlock()
	stop := func() {
		cancel()
		d.mu.Lock()
		delete(d.listeners, cookie)
		d.mu.Unlock()
		for i := 0; i < maxInFlight; i++ {
			<-sema
		}
	}
	for _, k := range keys {
		select {
		case <-ctx.Done():
			return stop
		default:
		}
		if v, ok := d.Load(k); ok {
			listener(v)
		}
	}
	return stop
}