code: func (c *Client) GetMulti(keys []string) (map[string]*Item, error) {
  	keyMap := make(map[*Addr][]string)
  	for _, key := range keys {
  		addr, err := c.servers.PickServer(key)
  		if err != nil {
  			return nil, err
  		}
  		keyMap[addr] = append(keyMap[addr], key)
  	}
  
  	var chs []chan *Item
  	for addr, keys := range keyMap {
  		ch := make(chan *Item)
  		chs = append(chs, ch)
  		go func(addr *Addr, keys []string, ch chan *Item) {
  			defer close(ch)
  			cn, err := c.getConn(addr)
  			if err != nil {
  				return
  			}
  			defer c.condRelease(cn, &err)
  			for _, k := range keys {
  				if err = c.sendConnCommand(cn, k, cmdGetKQ, nil, 0, nil); err != nil {
  					return
  				}
  			}
  			if err = c.sendConnCommand(cn, "", cmdNoop, nil, 0, nil); err != nil {
  				return
  			}
  			var item *Item
  			for {
  				item, err = c.parseItemResponse("", cn, false)
  				if item == nil || item.Key == "" {
  					// Noop response
  					break
  				}
  				ch <- item
  			}
  		}(addr, keys, ch)
  	}
  
  	m := make(map[string]*Item)
  	for _, ch := range chs {
  		for item := range ch {
  			m[item.Key] = item
  		}
  	}
  	return m, nil
  }
docs: // GetMulti is a batch version of Get. The returned map from keys to
  // items may have fewer elements than the input slice, due to memcache
  // cache misses. Each key must be at most 250 bytes in length.
  // If no error is returned, the returned map will also be non-nil.