mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-08-28 20:06:14 +00:00
* storage: order VolumeInfo by alignment The struct is held for every volume replica in the cluster, so the padding the compiler inserts is multiplied by however many volumes a master tracks. Two one-byte fields each sat at the head of a word and left the rest of it empty, which was ten of the eighteen wasted bytes. Grouping by size rather than by meaning takes the struct from 152 bytes to 136, and the map holding them shrinks with it, since a Go map's slack scales with the size of the value. 800k volumes registered from a heartbeat that has been over the wire: 211 -> 195 B/volume, 214 -> 198 tiered. * trim the comments on this change to the parts that are not evident
35 lines
924 B
Go
35 lines
924 B
Go
package storage
|
|
|
|
import (
|
|
"reflect"
|
|
"testing"
|
|
"unsafe"
|
|
)
|
|
|
|
// Nothing else in the package would notice if someone grouped the fields by
|
|
// meaning again, and the padding is multiplied by every volume a master holds.
|
|
func TestVolumeInfoHasNoInteriorPadding(t *testing.T) {
|
|
typ := reflect.TypeOf(VolumeInfo{})
|
|
|
|
var used, interior uintptr
|
|
prevEnd := uintptr(0)
|
|
for i := 0; i < typ.NumField(); i++ {
|
|
f := typ.Field(i)
|
|
if gap := f.Offset - prevEnd; gap > 0 {
|
|
t.Errorf("%d bytes of padding before %s, at offset %d: order the fields by size so they pack",
|
|
gap, f.Name, prevEnd)
|
|
interior += gap
|
|
}
|
|
used += f.Type.Size()
|
|
prevEnd = f.Offset + f.Type.Size()
|
|
}
|
|
|
|
size := unsafe.Sizeof(VolumeInfo{})
|
|
if tail := size - prevEnd; tail > 7 {
|
|
t.Errorf("%d bytes of padding at the end, more than alignment requires", tail)
|
|
}
|
|
if interior == 0 {
|
|
t.Logf("%d bytes of fields in a %d byte struct", used, size)
|
|
}
|
|
}
|