code: func (s *attrStore) Attrs(id uint64) (m map[string]interface{}, err error) {
  	s.mu.RLock()
  	defer s.mu.RUnlock()
  
  	// Check cache for map.
  	if m = s.attrCache.Get(id); m != nil {
  		return m, nil
  	}
  
  	// Find attributes from storage.
  	if err = s.db.View(func(tx *bolt.Tx) error {
  		m, err = txAttrs(tx, id)
  		return err
  	}); err != nil {
  		return nil, errors.Wrap(err, "finding attributes")
  	}
  
  	// Add to cache.
  	s.attrCache.Set(id, m)
  
  	return m, nil
  }
docs: // Attrs returns a set of attributes by ID.