influxdb/pkg/slices/merge.gen.go.tmpl

104 lines
2.6 KiB
Cheetah

package slices
import "bytes"
{{with $types := .}}{{range $k := $types}}
// Merge uses a k-way merge to merge n collections of sorted byte slices.
//
// The resulting slice is returned in ascending order, with any duplicate values
// removed.
func MergeSorted{{$k.Name}}(n ...[]{{$k.Type}}) []{{$k.Type}} {
var result []{{$k.Type}}
if len(n) == 0 {
return nil
} else if len(n) == 1 {
// Special case. Merge single slice with a nil slice, to remove any
// duplicates from the single slice.
return MergeSorted{{$k.Name}}(n[0], nil)
}
var maxSize int
for _, a := range n {
if len(a) > maxSize {
maxSize = len(a)
}
}
result = make([]{{$k.Type}}, 0, maxSize) // This will likely be too small but it's a start.
idxs := make([]int, len(n)) // Indexes we've processed.
var j int // Index we currently think is minimum.
{{if eq $k.Name "Bytes" }}
var cmp int // Result of comparing most recent value.
{{end}}
for {
j = -1
// Find the smallest minimum in all slices.
for i := 0; i < len(n); i++ {
if idxs[i] >= len(n[i]) {
continue // We have completely drained all values in this slice.
} else if j == -1 {
// We haven't picked the minimum value yet. Pick this one.
j = i
continue
}
// It this value key is lower than the candidate.
{{if eq $k.Name "Bytes" }}
cmp = bytes.Compare(n[i][idxs[i]], n[j][idxs[j]])
if cmp == -1 {
j = i
} else if cmp == 0 {
// Duplicate value. Throw it away.
idxs[i]++
}
{{else}}
if n[i][idxs[i]] < n[j][idxs[j]] {
j = i
} else if n[i][idxs[i]] == n[j][idxs[j]] {
// Duplicate value. Throw it away.
idxs[i]++
}
{{end}}
}
// We could have drained all of the values and be done...
if j == -1 {
break
}
// First value to just append it and move on.
if len(result) == 0 {
result = append(result, n[j][idxs[j]])
idxs[j]++
continue
}
// Append the minimum value to results if it's not a duplicate of
// the existing one.
{{if eq $k.Name "Bytes" }}
cmp = bytes.Compare(result[len(result)-1], n[j][idxs[j]])
if cmp == -1 {
result = append(result, n[j][idxs[j]])
} else if cmp == 0 {
// Duplicate so drop it.
} else {
panic("value being merged out of order.")
}
{{else}}
if result[len(result)-1] < n[j][idxs[j]] {
result = append(result, n[j][idxs[j]])
} else if result[len(result)-1] == n[j][idxs[j]] {
// Duplicate so drop it.
} else {
panic("value being merged out of order.")
}
{{end}}
idxs[j]++
}
return result
}
{{end}}{{end}}