diff --git a/common/bitutil/bitutil.go b/common/bitutil/bitutil.go index 6756d04be5..9342c02ecf 100644 --- a/common/bitutil/bitutil.go +++ b/common/bitutil/bitutil.go @@ -134,21 +134,32 @@ func ORBytes(dst, a, b []byte) int { // fastORBytes ors in bulk. It only works on architectures that support // unaligned read/writes. func fastORBytes(dst, a, b []byte) int { - n := len(a) - if len(b) < n { - n = len(b) - } + n := min(len(b), len(a)) w := n / wordSize if w > 0 { dw := *(*[]uintptr)(unsafe.Pointer(&dst)) aw := *(*[]uintptr)(unsafe.Pointer(&a)) bw := *(*[]uintptr)(unsafe.Pointer(&b)) - for i := 0; i < w; i++ { + + i := 0 + for i <= w-4 { dw[i] = aw[i] | bw[i] + dw[i+1] = aw[i+1] | bw[i+1] + dw[i+2] = aw[i+2] | bw[i+2] + dw[i+3] = aw[i+3] | bw[i+3] + i += 4 + } + // Handle remaining words + for i < w { + dw[i] = aw[i] | bw[i] + i++ } } - for i := n - n%wordSize; i < n; i++ { - dst[i] = a[i] | b[i] + + // Handle remaining bytes + start := w * wordSize + for i := 0; i < n&(wordSize-1); i++ { + dst[start+i] = a[start+i] | b[start+i] } return n } @@ -156,10 +167,7 @@ func fastORBytes(dst, a, b []byte) int { // safeORBytes ors one by one. It works on all architectures, independent if // it supports unaligned read/writes or not. func safeORBytes(dst, a, b []byte) int { - n := len(a) - if len(b) < n { - n = len(b) - } + n := min(len(b), len(a)) for i := 0; i < n; i++ { dst[i] = a[i] | b[i] } @@ -198,7 +206,7 @@ func fastTestBytes(p []byte) bool { // safeTestBytes tests for set bits one byte at a time. It works on all // architectures, independent if it supports unaligned read/writes or not. func safeTestBytes(p []byte) bool { - for i := 0; i < len(p); i++ { + for i := range p { if p[i] != 0 { return true }