code: func (s *translateStore) TranslateColumnsToUint64(index string, values []string) ([]uint64, error) {
  	ret := make([]uint64, len(values))
  
  	// Read value under read lock.
  	s.mu.RLock()
  	if idx := s.cols[index]; idx != nil {
  		var writeRequired bool
  		for i := range values {
  			v, ok := idx.lookup[values[i]]
  			if !ok {
  				writeRequired = true
  			}
  			ret[i] = v
  		}
  		if !writeRequired {
  			s.mu.RUnlock()
  			return ret, nil
  		}
  	}
  	s.mu.RUnlock()
  
  	// If any values not found then recheck and then add under a write lock.
  	s.mu.Lock()
  	defer s.mu.Unlock()
  
  	// Recheck if value was created between the read lock and write lock.
  	idx := s.cols[index]
  	if idx != nil {
  		var writeRequired bool
  		for i := range values {
  			if ret[i] != 0 {
  				continue
  			}
  			v, ok := idx.lookup[values[i]]
  			if !ok {
  				writeRequired = true
  				continue
  			}
  			ret[i] = v
  		}
  		if !writeRequired {
  			return ret, nil
  		}
  	}
  
  	// Create index map if it doesn't exists.
  	if idx == nil {
  		idx = newTranslateIndex()
  		s.cols[index] = idx
  	}
  
  	// Add new identifiers.
  	for i := range values {
  		if ret[i] != 0 {
  			continue
  		}
  
  		idx.seq++
  		v := idx.seq
  		ret[i] = v
  		idx.lookup[values[i]] = v
  		idx.reverse[v] = values[i]
  	}
  
  	return ret, nil
  }
docs: // TranslateColumnsToUint64 converts value to a uint64 id.
  // If value does not have an associated id then one is created.