| // 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 |
| } |