device: remove code using unsafe
There is no performance impact. name old time/op new time/op delta TrieIPv4Peers100Addresses1000-8 78.6ns ± 1% 79.4ns ± 3% ~ (p=0.604 n=10+9) TrieIPv4Peers10Addresses10-8 29.1ns ± 2% 28.8ns ± 1% -1.12% (p=0.014 n=10+9) TrieIPv6Peers100Addresses1000-8 78.9ns ± 1% 78.6ns ± 1% ~ (p=0.492 n=10+10) TrieIPv6Peers10Addresses10-8 29.3ns ± 2% 28.6ns ± 2% -2.16% (p=0.000 n=10+10) Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
parent
ef8d6804d7
commit
4d87c9e824
|
@ -7,6 +7,7 @@ package device
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"container/list"
|
"container/list"
|
||||||
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"math/bits"
|
"math/bits"
|
||||||
"net"
|
"net"
|
||||||
|
@ -32,45 +33,24 @@ type trieEntry struct {
|
||||||
perPeerElem *list.Element
|
perPeerElem *list.Element
|
||||||
}
|
}
|
||||||
|
|
||||||
func isLittleEndian() bool {
|
|
||||||
one := uint32(1)
|
|
||||||
return *(*byte)(unsafe.Pointer(&one)) != 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func swapU32(i uint32) uint32 {
|
|
||||||
if !isLittleEndian() {
|
|
||||||
return i
|
|
||||||
}
|
|
||||||
|
|
||||||
return bits.ReverseBytes32(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
func swapU64(i uint64) uint64 {
|
|
||||||
if !isLittleEndian() {
|
|
||||||
return i
|
|
||||||
}
|
|
||||||
|
|
||||||
return bits.ReverseBytes64(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
func commonBits(ip1, ip2 []byte) uint8 {
|
func commonBits(ip1, ip2 []byte) uint8 {
|
||||||
size := len(ip1)
|
size := len(ip1)
|
||||||
if size == net.IPv4len {
|
if size == net.IPv4len {
|
||||||
a := (*uint32)(unsafe.Pointer(&ip1[0]))
|
a := binary.BigEndian.Uint32(ip1)
|
||||||
b := (*uint32)(unsafe.Pointer(&ip2[0]))
|
b := binary.BigEndian.Uint32(ip2)
|
||||||
x := *a ^ *b
|
x := a ^ b
|
||||||
return uint8(bits.LeadingZeros32(swapU32(x)))
|
return uint8(bits.LeadingZeros32(x))
|
||||||
} else if size == net.IPv6len {
|
} else if size == net.IPv6len {
|
||||||
a := (*uint64)(unsafe.Pointer(&ip1[0]))
|
a := binary.BigEndian.Uint64(ip1)
|
||||||
b := (*uint64)(unsafe.Pointer(&ip2[0]))
|
b := binary.BigEndian.Uint64(ip2)
|
||||||
x := *a ^ *b
|
x := a ^ b
|
||||||
if x != 0 {
|
if x != 0 {
|
||||||
return uint8(bits.LeadingZeros64(swapU64(x)))
|
return uint8(bits.LeadingZeros64(x))
|
||||||
}
|
}
|
||||||
a = (*uint64)(unsafe.Pointer(&ip1[8]))
|
a = binary.BigEndian.Uint64(ip1[8:])
|
||||||
b = (*uint64)(unsafe.Pointer(&ip2[8]))
|
b = binary.BigEndian.Uint64(ip2[8:])
|
||||||
x = *a ^ *b
|
x = a ^ b
|
||||||
return 64 + uint8(bits.LeadingZeros64(swapU64(x)))
|
return 64 + uint8(bits.LeadingZeros64(x))
|
||||||
} else {
|
} else {
|
||||||
panic("Wrong size bit string")
|
panic("Wrong size bit string")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue