code: func (dr *DirReader) Readdir(ctx context.Context, n int) (entries []DirectoryEntry, err error) {
  	sts, err := dr.StaticSet(ctx)
  	if err != nil {
  		return nil, fmt.Errorf("schema/dirreader: can't get StaticSet: %v", err)
  	}
  	up := dr.current + n
  	if n <= 0 {
  		dr.current = 0
  		up = len(sts)
  	} else {
  		if n > (len(sts) - dr.current) {
  			err = io.EOF
  			up = len(sts)
  		}
  	}
  
  	// TODO(bradfitz): push down information to the fetcher
  	// (e.g. cachingfetcher -> remote client http) that we're
  	// going to load a bunch, so the HTTP client (if not using
  	// SPDY) can do discovery and see if the server supports a
  	// batch handler, then get them all in one round-trip, rather
  	// than attacking the server with hundreds of parallel TLS
  	// setups.
  
  	type res struct {
  		ent DirectoryEntry
  		err error
  	}
  	var cs []chan res
  
  	// Kick off all directory entry loads.
  	gate := syncutil.NewGate(20) // Limit IO concurrency
  	for _, entRef := range sts[dr.current:up] {
  		c := make(chan res, 1)
  		cs = append(cs, c)
  		gate.Start()
  		go func(entRef blob.Ref) {
  			defer gate.Done()
  			entry, err := NewDirectoryEntryFromBlobRef(ctx, dr.fetcher, entRef)
  			c <- res{entry, err}
  		}(entRef)
  	}
  
  	for _, c := range cs {
  		res := <-c
  		if res.err != nil {
  			return nil, fmt.Errorf("schema/dirreader: can't create dirEntry: %v", res.err)
  		}
  		entries = append(entries, res.ent)
  	}
  	return entries, nil
  }
docs: // Readdir implements the Directory interface.