Repository: prometheus/prometheus
File: model/labels/labels_dedupelabels.go (Go)

Code before:
			pos = newPos
			continue
		}
		// Do not copy the slice until it's necessary.
		// TODO: could optimise the case where all blanks are at the end.
		// Note: we size the new buffer on the assumption there is exactly one blank value.
		buf := make([]byte, pos, pos+(len(ls.data)-newPos))
		copy(buf, ls.data[:pos]) // copy the initial non-blank labels
		pos = newPos             // move past the first blank value
		for pos < len(ls.data) {
			var newPos int
			_, newPos = decodeVarint(ls.data, pos)
			lValue, newPos = decodeVarint(ls.data, newPos)
			if lValue != blank {
				buf = append(buf, ls.data[pos:newPos]...)
			}
			pos = newPos
		}
		return Labels{syms: ls.syms, data: yoloString(buf)}
	}
	return ls
}

// ByteSize returns the approximate size of the labels in bytes.
// String header size is ignored because it should be amortized to zero.
// SymbolTable size is also not taken into account.
func (ls Labels) ByteSize() int {
	return len(ls.data)
}

// Equal returns whether the two label sets are equal.
func Equal(a, b Labels) bool {
	if a.syms == b.syms {
		return a.data == b.data
	}

	la, lb := len(a.data), len(b.data)
	ia, ib := 0, 0
	for ia < la && ib < lb {
		var aValue, bValue string
		aValue, ia = decodeString(a.syms, a.data, ia)
		bValue, ib = decodeString(b.syms, b.data, ib)
		if aValue != bValue {
			return false
		}
	}
	if ia != la || ib != lb {
		return false
	}
	return true
}

Review comment (performance):
Not taking SymbolTable size is unfortunate, since it could reveal some mistakes / opportunities where the table could be re-used.  However you'd have to redesign this function as taking a whole set of labels in order to get that right.
And it is likely low-value as we didn't get `dedupelabels` sufficiently efficient.

Code after:
			pos = newPos
			continue
		}
		// Do not copy the slice until it's necessary.
		// TODO: could optimise the case where all blanks are at the end.
		// Note: we size the new buffer on the assumption there is exactly one blank value.
		buf := make([]byte, pos, pos+(len(ls.data)-newPos))
		copy(buf, ls.data[:pos]) // copy the initial non-blank labels
		pos = newPos             // move past the first blank value
		for pos < len(ls.data) {
			var newPos int
			_, newPos = decodeVarint(ls.data, pos)
			lValue, newPos = decodeVarint(ls.data, newPos)
			if lValue != blank {
				buf = append(buf, ls.data[pos:newPos]...)
			}
			pos = newPos
		}
		return Labels{syms: ls.syms, data: yoloString(buf)}
	}
	return ls
}

// ByteSize returns the approximate size of the labels in bytes.
// String header size is ignored because it should be amortized to zero.
// SymbolTable size is also not taken into account.
func (ls Labels) ByteSize() uint64 {
	return uint64(len(ls.data))
}

// Equal returns whether the two label sets are equal.
func Equal(a, b Labels) bool {
	if a.syms == b.syms {
		return a.data == b.data
	}

	la, lb := len(a.data), len(b.data)
	ia, ib := 0, 0
	for ia < la && ib < lb {
		var aValue, bValue string
		aValue, ia = decodeString(a.syms, a.data, ia)
		bValue, ib = decodeString(b.syms, b.data, ib)
		if aValue != bValue {
			return false
		}
	}
	if ia != la || ib != lb {
		return false
	}
	return true
}