code: func (fn *FieldNumbers) addOrGet(name string, preferredNumber int, dv DocValuesType) int {
  	fn.Lock()
  	defer fn.Unlock()
  
  	if dv != 0 {
  		currentDv, ok := fn.docValuesType[name]
  		if !ok || currentDv == 0 {
  			fn.docValuesType[name] = dv
  		} else {
  			assert2(currentDv == dv,
  				"cannot change DocValues type from %v to %v for field '%v'",
  				currentDv, dv, name)
  		}
  	}
  	number, ok := fn.nameToNumber[name]
  	if !ok {
  		_, ok = fn.numberToName[preferredNumber]
  		if preferredNumber != -1 && !ok {
  			// cool - we can use this number globally
  			number = preferredNumber
  		} else {
  			// find a new FieldNumber
  			fn.lowestUnassignedFieldNumber++
  			for _, ok = fn.numberToName[fn.lowestUnassignedFieldNumber]; ok; {
  				// might not be up to date - lets do the work once needed
  				fn.lowestUnassignedFieldNumber++
  				_, ok = fn.numberToName[fn.lowestUnassignedFieldNumber]
  			}
  			number = fn.lowestUnassignedFieldNumber
  		}
  
  		fn.numberToName[number] = name
  		fn.nameToNumber[name] = number
  	}
  	return number
  }
docs: /*
  Returns the global field number for the given field name. If the name
  does not exist yet it tries to add it with the given preferred field
  number assigned if possible otherwise the first unassigned field
  number is used as the field number.
  */