mirror of
https://github.com/octoleo/syncthing.git
synced 2024-12-22 02:48:59 +00:00
lib/model: Return index from deviceActivity.leastBusy
This way, we don't need a second loop over the Availabilities to remove the selected item.
This commit is contained in:
parent
b84ee4d240
commit
6a9716e8a1
@ -26,20 +26,19 @@ func newDeviceActivity() *deviceActivity {
|
||||
}
|
||||
}
|
||||
|
||||
func (m *deviceActivity) leastBusy(availability []Availability) (Availability, bool) {
|
||||
// Returns the index of the least busy device, or -1 if all are too busy.
|
||||
func (m *deviceActivity) leastBusy(availability []Availability) int {
|
||||
m.mut.Lock()
|
||||
low := 2<<30 - 1
|
||||
found := false
|
||||
var selected Availability
|
||||
for _, info := range availability {
|
||||
if usage := m.act[info.ID]; usage < low {
|
||||
best := -1
|
||||
for i := range availability {
|
||||
if usage := m.act[availability[i].ID]; usage < low {
|
||||
low = usage
|
||||
selected = info
|
||||
found = true
|
||||
best = i
|
||||
}
|
||||
}
|
||||
m.mut.Unlock()
|
||||
return selected, found
|
||||
return best
|
||||
}
|
||||
|
||||
func (m *deviceActivity) using(availability Availability) {
|
||||
|
@ -19,42 +19,42 @@ func TestDeviceActivity(t *testing.T) {
|
||||
devices := []Availability{n0, n1, n2}
|
||||
na := newDeviceActivity()
|
||||
|
||||
if lb, ok := na.leastBusy(devices); !ok || lb != n0 {
|
||||
if lb := na.leastBusy(devices); lb != 0 {
|
||||
t.Errorf("Least busy device should be n0 (%v) not %v", n0, lb)
|
||||
}
|
||||
if lb, ok := na.leastBusy(devices); !ok || lb != n0 {
|
||||
if lb := na.leastBusy(devices); lb != 0 {
|
||||
t.Errorf("Least busy device should still be n0 (%v) not %v", n0, lb)
|
||||
}
|
||||
|
||||
lb, _ := na.leastBusy(devices)
|
||||
na.using(lb)
|
||||
if lb, ok := na.leastBusy(devices); !ok || lb != n1 {
|
||||
lb := na.leastBusy(devices)
|
||||
na.using(devices[lb])
|
||||
if lb := na.leastBusy(devices); lb != 1 {
|
||||
t.Errorf("Least busy device should be n1 (%v) not %v", n1, lb)
|
||||
}
|
||||
lb, _ = na.leastBusy(devices)
|
||||
na.using(lb)
|
||||
if lb, ok := na.leastBusy(devices); !ok || lb != n2 {
|
||||
lb = na.leastBusy(devices)
|
||||
na.using(devices[lb])
|
||||
if lb := na.leastBusy(devices); lb != 2 {
|
||||
t.Errorf("Least busy device should be n2 (%v) not %v", n2, lb)
|
||||
}
|
||||
|
||||
lb, _ = na.leastBusy(devices)
|
||||
na.using(lb)
|
||||
if lb, ok := na.leastBusy(devices); !ok || lb != n0 {
|
||||
lb = na.leastBusy(devices)
|
||||
na.using(devices[lb])
|
||||
if lb := na.leastBusy(devices); lb != 0 {
|
||||
t.Errorf("Least busy device should be n0 (%v) not %v", n0, lb)
|
||||
}
|
||||
|
||||
na.done(n1)
|
||||
if lb, ok := na.leastBusy(devices); !ok || lb != n1 {
|
||||
if lb := na.leastBusy(devices); lb != 1 {
|
||||
t.Errorf("Least busy device should be n1 (%v) not %v", n1, lb)
|
||||
}
|
||||
|
||||
na.done(n2)
|
||||
if lb, ok := na.leastBusy(devices); !ok || lb != n1 {
|
||||
if lb := na.leastBusy(devices); lb != 1 {
|
||||
t.Errorf("Least busy device should still be n1 (%v) not %v", n1, lb)
|
||||
}
|
||||
|
||||
na.done(n0)
|
||||
if lb, ok := na.leastBusy(devices); !ok || lb != n0 {
|
||||
if lb := na.leastBusy(devices); lb != 0 {
|
||||
t.Errorf("Least busy device should be n0 (%v) not %v", n0, lb)
|
||||
}
|
||||
}
|
||||
|
@ -1532,8 +1532,8 @@ loop:
|
||||
// Select the least busy device to pull the block from. If we found no
|
||||
// feasible device at all, fail the block (and in the long run, the
|
||||
// file).
|
||||
selected, found := activity.leastBusy(candidates)
|
||||
if !found {
|
||||
found := activity.leastBusy(candidates)
|
||||
if found == -1 {
|
||||
if lastError != nil {
|
||||
state.fail(errors.Wrap(lastError, "pull"))
|
||||
} else {
|
||||
@ -1542,7 +1542,9 @@ loop:
|
||||
break
|
||||
}
|
||||
|
||||
candidates = removeAvailability(candidates, selected)
|
||||
selected := candidates[found]
|
||||
candidates[found] = candidates[len(candidates)-1]
|
||||
candidates = candidates[:len(candidates)-1]
|
||||
|
||||
// Fetch the block, while marking the selected device as in use so that
|
||||
// leastBusy can select another device when someone else asks.
|
||||
@ -1804,16 +1806,6 @@ func (f *sendReceiveFolder) inConflict(current, replacement protocol.Vector) boo
|
||||
return false
|
||||
}
|
||||
|
||||
func removeAvailability(availabilities []Availability, availability Availability) []Availability {
|
||||
for i := range availabilities {
|
||||
if availabilities[i] == availability {
|
||||
availabilities[i] = availabilities[len(availabilities)-1]
|
||||
return availabilities[:len(availabilities)-1]
|
||||
}
|
||||
}
|
||||
return availabilities
|
||||
}
|
||||
|
||||
func (f *sendReceiveFolder) moveForConflict(name, lastModBy string, scanChan chan<- string) error {
|
||||
if isConflict(name) {
|
||||
l.Infoln("Conflict for", name, "which is already a conflict copy; not copying again.")
|
||||
|
Loading…
Reference in New Issue
Block a user