// helper func to merge, dedupe, and sort strings
760645
func dedupeStrings(s1, s2 []string) (r []string) {
	dedupe := make(map[string]bool)

	if len(s1) > 0 && len(s2) > 0 {
		for _, i := range s1 {
			dedupe[i] = true
		}
		for _, i := range s2 {
			dedupe[i] = true
		}

		for i := range dedupe {
			r = append(r, i)
		}
		// And then re-sort them
		sort.Strings(r)
	} else if len(s1) > 0 {
		r = s1
	} else if len(s2) > 0 {
		r = s2
	}

	return
}
868928
func (c ConversionFuncs) Merge(other ConversionFuncs) ConversionFuncs {
	merged := NewConversionFuncs()
	for k, v := range c.fns {
		merged.fns[k] = v
	}
	for k, v := range other.fns {
		merged.fns[k] = v
	}
	for k, v := range c.untyped {
		merged.untyped[k] = v
	}
	for k, v := range other.untyped {
		merged.untyped[k] = v
	}
	return merged
}
456777
func cleanRetryJoin(a string) string {
	var fields []string
	for _, f := range strings.Fields(a) {
		if isSecret(f) {
			kv := strings.SplitN(f, "=", 2)
			fields = append(fields, kv[0]+"=hidden")
		} else {
			fields = append(fields, f)
		}
	}
	return strings.Join(fields, " ")
}
394743
func (t *Tags) MergeFromStringSlice(slice []string) error {
	for _, s := range slice {
		err := t.Add(s)
		if err != nil && !e.Equal(err, ErrTagExist) {
			return e.Forward(err)
		}
	}
	return nil
}
570662
func (h *Histogram) Merge(from *Histogram) (dropped int64) {
	i := from.rIterator()
	for i.next() {
		v := i.valueFromIdx
		c := i.countAtIdx

		if h.RecordValues(v, c) != nil {
			dropped += c
		}
	}

	return
}
254919
func mergeOptions(options ...map[int]interface{}) map[int]interface{} {
	rst := make(map[int]interface{})

	for _, m := range options {
		for k, v := range m {
			rst[k] = v
		}
	}

	return rst
}
1306814
func MergeMaps(a, b map[string]string) map[string]string {
	if a == nil && b == nil {
		return nil
	}

	res := make(map[string]string)

	for k, v := range a {
		res[k] = v
	}

	for k, v := range b {
		res[k] = v
	}

	return res
}
131223
func (p *SortKeys) AsStringSliceComparator() StringSliceComparator {
	numeric := utils.NewIndex(p.Numeric)
	reverseIndex := utils.NewIndex(p.Reversed)
	comparators := make([]StringComparator, len(p.Keys))
	for i, k := range p.Keys {
		if numeric.Contains(k) {
			comparators[i] = LessNumericStrings
		} else {
			comparators[i] = LessStrings
		}
		if reverseIndex.Contains(k) {
			f := comparators[i]
			comparators[i] = func(l, r string) bool {
				return !f(l, r)
			}
		}
	}
	return AsStringSliceComparator(comparators)
}
34788
func SortFormKeys(strs []string) {
	sort.Slice(strs, func(i, j int) bool { // true for first
		str1 := strs[i]
		str2 := strs[j]
		matched1 := replaceIdxRegexp.FindAllStringIndex(str1, -1)
		matched2 := replaceIdxRegexp.FindAllStringIndex(str2, -1)

		for x := 0; x < len(matched1); x++ {
			prefix1 := str1[:matched1[x][0]]
			prefix2 := str2

			if len(matched2) >= x+1 {
				prefix2 = str2[:matched2[x][0]]
			}

			if prefix1 != prefix2 {
				return strings.Compare(prefix1, prefix2) < 0
			}

			if len(matched2) < x+1 {
				return false
			}

			number1 := str1[matched1[x][0]:matched1[x][1]]
			number2 := str2[matched2[x][0]:matched2[x][1]]

			if number1 != number2 {
				if len(number1) != len(number2) {
					return len(number1) < len(number2)
				}
				return strings.Compare(number1, number2) < 0
			}
		}

		return strings.Compare(str1, str2) < 0
	})
}
909358
func (td *MergingDigest) Merge(other *MergingDigest) {
	oldReciprocalSum := td.reciprocalSum
	shuffledIndices := rand.Perm(len(other.mainCentroids))

	for _, i := range shuffledIndices {
		td.Add(other.mainCentroids[i].Mean, other.mainCentroids[i].Weight)
	}

	// we did not merge other's temps, so we need to add those too
	// they're unsorted so there's no need to shuffle them
	for i := range other.tempCentroids {
		td.Add(other.tempCentroids[i].Mean, other.tempCentroids[i].Weight)
	}

	td.reciprocalSum = oldReciprocalSum + other.reciprocalSum
}
40862
func Strings(data []string) []string {
	sort.Strings(data)
	n := Uniq(sort.StringSlice(data))
	return data[:n]
}
807295
func (a *BooleanArray) Merge(b *BooleanArray) {
	if a.Len() == 0 {
		*a = *b
		return
	}

	if b.Len() == 0 {
		return
	}

	// Normally, both a and b should not contain duplicates.  Due to a bug in older versions, it's
	// possible stored blocks might contain duplicate values.  Remove them if they exists before
	// merging.
	// a = a.Deduplicate()
	// b = b.Deduplicate()

	if a.MaxTime() < b.MinTime() {
		a.Timestamps = append(a.Timestamps, b.Timestamps...)
		a.Values = append(a.Values, b.Values...)
		return
	}

	if b.MaxTime() < a.MinTime() {
		var tmp BooleanArray
		tmp.Timestamps = append(b.Timestamps, a.Timestamps...)
		tmp.Values = append(b.Values, a.Values...)
		*a = tmp
		return
	}

	out := NewBooleanArrayLen(a.Len() + b.Len())
	i, j, k := 0, 0, 0
	for i < len(a.Timestamps) && j < len(b.Timestamps) {
		if a.Timestamps[i] < b.Timestamps[j] {
			out.Timestamps[k] = a.Timestamps[i]
			out.Values[k] = a.Values[i]
			i++
		} else if a.Timestamps[i] == b.Timestamps[j] {
			out.Timestamps[k] = b.Timestamps[j]
			out.Values[k] = b.Values[j]
			i++
			j++
		} else {
			out.Timestamps[k] = b.Timestamps[j]
			out.Values[k] = b.Values[j]
			j++
		}
		k++
	}

	if i < len(a.Timestamps) {
		n := copy(out.Timestamps[k:], a.Timestamps[i:])
		copy(out.Values[k:], a.Values[i:])
		k += n
	} else if j < len(b.Timestamps) {
		n := copy(out.Timestamps[k:], b.Timestamps[j:])
		copy(out.Values[k:], b.Values[j:])
		k += n
	}

	a.Timestamps = out.Timestamps[:k]
	a.Values = out.Values[:k]
}
720748
func (s *StringValue) Merge(onto *string) {
	if s.v != nil {
		*onto = *(s.v)
	}
}
225909
func DedupLiterals(v []*Literal) ([]*Literal, error) {
	proxies, err := buildSortProxies(v)
	if err != nil {
		return nil, err
	}

	sort.Sort(byKey(proxies))

	var deduped []*Literal
	for i, p := range proxies {
		if i != 0 && proxies[i-1].key == proxies[i].key {
			continue
		}
		deduped = append(deduped, p.literal)
	}

	return deduped, nil
}
1179288
func uniqueMergeSortedStrings(ls, rs []string) []string {
	varSet := make([]string, len(ls)+len(rs))
	for i := 0; ; i++ {
		if len(ls) == 0 {
			rs, ls = ls, rs
		}
		if len(rs) == 0 {
			i += copy(varSet[i:], ls)
			return varSet[:i]
		}
		assert(i < len(varSet))
		assert(len(rs) > 0 && len(ls) > 0)
		if ls[0] > rs[0] {
			ls, rs = rs, ls
		}
		if ls[0] < rs[0] {
			varSet[i] = ls[0]
			ls = ls[1:]
		} else {
			varSet[i] = ls[0]
			ls, rs = ls[1:], rs[1:]
		}
	}
}
953235
func Join(separator string, items ...Stringable) *StringExpr {
	return JoinFunc{Separator: separator, Items: *StringList(items...)}.String()
}
1163329
func Join(os string, elem ...string) string {
	sep := Separator(os)
	return Clean(os, strings.Join(elem, string(sep)))
}