diff --git a/pkg/zones/scan.go b/pkg/zones/scan.go index 07b8127..8faf8a8 100644 --- a/pkg/zones/scan.go +++ b/pkg/zones/scan.go @@ -93,12 +93,7 @@ func (m *Zones) scanSort() error { }) m.ForEachZone(func(z *Zone) bool { - sort.SliceStable(z.Machines, func(i, j int) bool { - id1 := z.Machines[i].ID - id2 := z.Machines[j].ID - return id1 < id2 - }) - + sort.Sort(z) return false }) diff --git a/pkg/zones/zones.go b/pkg/zones/zones.go index f6924c7..7601919 100644 --- a/pkg/zones/zones.go +++ b/pkg/zones/zones.go @@ -4,6 +4,7 @@ package zones import ( "io/fs" "path/filepath" + "sort" "github.com/hack-pad/hackpadfs/os" @@ -11,6 +12,9 @@ import ( ) var ( + _ MachineIterator = Machines(nil) + _ sort.Interface = Machines(nil) + _ MachineIterator = (*Zone)(nil) _ MachineIterator = (*Zones)(nil) _ ZoneIterator = (*Zones)(nil) @@ -26,6 +30,42 @@ type ZoneIterator interface { ForEachZone(func(*Zone) bool) } +// Machines is a list of Machine objects +type Machines []*Machine + +// ForEachMachine calls a function for each Machine in the list +// until instructed to terminate the loop +func (m Machines) ForEachMachine(fn func(*Machine) bool) { + for _, p := range m { + if fn(p) { + return + } + } +} + +// Len returns the number of machines in the list +func (m Machines) Len() int { + return len(m) +} + +// Less implements sort.Interface to sort the list +func (m Machines) Less(i, j int) bool { + a, b := m[i], m[j] + za, zb := a.Zone(), b.Zone() + + switch { + case za == zb: + return a.ID < b.ID + default: + return za < zb + } +} + +// Swap implements sort.Interface to sort the list +func (m Machines) Swap(i, j int) { + m[i], m[j] = m[j], m[i] +} + // Zone represents one zone in a cluster type Zone struct { zones *Zones @@ -33,23 +73,13 @@ type Zone struct { ID int `toml:"id"` Name string `toml:"name"` - Machines []*Machine `toml:"machines"` + Machines `toml:"machines"` } func (z *Zone) String() string { return z.Name } -// ForEachMachine calls a function for each Machine in the zone -// until instructed to terminate the loop -func (z *Zone) ForEachMachine(fn func(*Machine) bool) { - for _, p := range z.Machines { - if fn(p) { - return - } - } -} - // SetGateway configures a machine to be the zone's ring0 gateway func (z *Zone) SetGateway(gatewayID int, enabled bool) error { var err error