diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 9c96964..48ab3a3 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -21,7 +21,7 @@ jobs: run: make test - name: Check - run: make code-check + run: make check # - name: Benchmark # run: make benchmark diff --git a/events.go b/events.go index 034ffd8..ac5d643 100644 --- a/events.go +++ b/events.go @@ -8,8 +8,7 @@ import ( // byteToString convert an array of bytes to a string with no-copy strategy. func bytesToString(b []byte) string { // Optimizing space with ordered types. - // perf: no allocation/copy to convert to string. - // instead take the already existing byte slice to create a string struct. + // perf: no allocation/copy to convert to string instead take the already existing byte slice to create a string struct. // WARNING: use this approach with caution and only if we are sure that the bytes slice is not gonna change. return *(*string)(unsafe.Pointer(&b)) } diff --git a/id.go b/id.go index 1c76237..18b107f 100644 --- a/id.go +++ b/id.go @@ -1,7 +1,6 @@ package noise import ( - "reflect" "unsafe" ) @@ -21,14 +20,16 @@ func (i ID) String() string { } // newIDFromString creates a new ID from string. -// ref: https://stackoverflow.com/questions/59209493/how-to-use-unsafe-get-a-byte-slice-from-a-string-without-memory-copy // ref: https://go.dev/ref/spec#Conversions +// https://pkg.go.dev/unsafe#Pointer func newIDFromString(s string) ID { // "no-copy" convert to ID from string. // If the type starts with the operator * or <-, it must be parenthesized when necessary to avoid ambiguity. - return *(*ID)(unsafe.Pointer( - (*reflect.StringHeader)(unsafe.Pointer(&s)).Data), - ) + // 1- unsafe.Pointer(&s) <- create a pointer from string address + // 2- (*ID)(unsafe.Pointer(&s)) <- cast the pointer to *ID pointer + // 3 - *(*ID)(unsafe.Pointer(&s)) <- get the value in memory address + // TODO could by replaced by unsafe.StringData(s) in go >=1.20 + return *(*ID)(unsafe.Pointer(&s)) } // newBlake2ID creates a new id blake2 hash based. diff --git a/metrics.go b/metrics.go index 0d90f88..879251a 100644 --- a/metrics.go +++ b/metrics.go @@ -4,16 +4,25 @@ package noise // We can add any method related to adaptive lookup logic here. // Please see [docs] for more information. // +// !IMPORTANT The order of byte size needed for each type in structs matter and impact the struct size. +// The fields are distributed in a way that ensures their alignment in 8-byte blocks. +// For instance on a 64-bit CPU, alignment blocks are 8 bytes. +// +// 0: [latency, bandwidth, nonce, sent], // 8 bytes +// 1: [recv, handshakeTime, 2bytespadding], // 8 bytes +// 2: [bytesRecv], // 8 bytes +// 3: [bytesSent], // 8 bytes +// // [docs]: https://arxiv.org/pdf/1509.04417.pdf type metrics struct { - bytesRecv uint64 // bytes received - bytesSent uint64 // bytes sent - handshakeTime uint32 // how long took the handshake to complete. - latency uint16 // rtt in ms - bandwidth uint16 // remote peer bandwidth - nonce uint16 // nonce ordering factor - sent uint16 // counter sent messages - recv uint16 // counter received messages + latency uint16 // rtt in ms: 2bytes + bandwidth uint16 // remote peer bandwidth: 2bytes + nonce uint16 // nonce ordering factor: 2bytes + sent uint16 // counter sent messages: 2bytes + recv uint16 // counter received messages: 2bytes + handshakeTime uint32 // how long took the handshake to complete.: 4bytes + bytesRecv uint64 // bytes received: 8bytes + bytesSent uint64 // bytes sent: 8 bytes } // TODO https://community.f5.com/t5/technical-articles/introducing-tcp-analytics/ta-p/290873