blob: caf447d27ee50351b1b414af3b93f6aef99b02e6 [file] [log] [blame]
// Copyright (C) MongoDB, Inc. 2017-present.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
package description
import (
"sort"
"strings"
"github.com/mongodb/mongo-go-driver/x/network/address"
)
// Topology represents a description of a mongodb topology
type Topology struct {
Servers []Server
Kind TopologyKind
SessionTimeoutMinutes uint32
}
// Server returns the server for the given address. Returns false if the server
// could not be found.
func (t Topology) Server(addr address.Address) (Server, bool) {
for _, server := range t.Servers {
if server.Addr.String() == addr.String() {
return server, true
}
}
return Server{}, false
}
// TopologyDiff is the difference between two different topology descriptions.
type TopologyDiff struct {
Added []Server
Removed []Server
}
// DiffTopology compares the two topology descriptions and returns the difference.
func DiffTopology(old, new Topology) TopologyDiff {
var diff TopologyDiff
// TODO: do this without sorting...
oldServers := serverSorter(old.Servers)
newServers := serverSorter(new.Servers)
sort.Sort(oldServers)
sort.Sort(newServers)
i := 0
j := 0
for {
if i < len(oldServers) && j < len(newServers) {
comp := strings.Compare(oldServers[i].Addr.String(), newServers[j].Addr.String())
switch comp {
case 1:
//left is bigger than
diff.Added = append(diff.Added, newServers[j])
j++
case -1:
// right is bigger
diff.Removed = append(diff.Removed, oldServers[i])
i++
case 0:
i++
j++
}
} else if i < len(oldServers) {
diff.Removed = append(diff.Removed, oldServers[i])
i++
} else if j < len(newServers) {
diff.Added = append(diff.Added, newServers[j])
j++
} else {
break
}
}
return diff
}
type serverSorter []Server
func (ss serverSorter) Len() int { return len(ss) }
func (ss serverSorter) Swap(i, j int) { ss[i], ss[j] = ss[j], ss[i] }
func (ss serverSorter) Less(i, j int) bool {
return strings.Compare(ss[i].Addr.String(), ss[j].Addr.String()) < 0
}