diff --git a/.changes/v2.20.0/532-features.md b/.changes/v2.20.0/532-features.md index 4c4809482..26e5d0222 100644 --- a/.changes/v2.20.0/532-features.md +++ b/.changes/v2.20.0/532-features.md @@ -4,9 +4,9 @@ * Added `NsxtEdgeGateway.GetUsedIpAddressSlice` method to fetch used IP addresses in a slice [GH-532] * Added `NsxtEdgeGateway.GetUnusedExternalIPAddresses` method that can help to find an unused - IP address in an Edge Gateway by given constraints [GH-532] + IP address in an Edge Gateway by given constraints [GH-532,GH-567] * Added `NsxtEdgeGateway.GetAllUnusedExternalIPAddresses` method that can return all unused IP - addresses in an Edge Gateway [GH-532] + addresses in an Edge Gateway [GH-532,GH-567] * Added `NsxtEdgeGateway.GetAllocatedIpCount` method that sums up `TotalIPCount` fields in all subnets [GH-532] * Added `NsxtEdgeGateway.QuickDeallocateIpCount` and `NsxtEdgeGateway.DeallocateIpCount` diff --git a/govcd/nsxt_edgegateway.go b/govcd/nsxt_edgegateway.go index 5fc07f845..7173c1a22 100644 --- a/govcd/nsxt_edgegateway.go +++ b/govcd/nsxt_edgegateway.go @@ -755,6 +755,9 @@ func flattenEdgeGatewayUplinkToIpSlice(uplinks []types.EdgeGatewayUplinks) ([]ne // Special behavior: // * Passing nil minuend results in nil // * Passing nil subtrahend will return minuendSlice +// +// NOTE. This function will mutate minuendSlice to save memory and avoid having a copy of all values +// which can become expensive if there are a lot of items func ipSliceDifference(minuendSlice, subtrahendSlice []netip.Addr) []netip.Addr { if minuendSlice == nil { return nil @@ -773,31 +776,38 @@ func ipSliceDifference(minuendSlice, subtrahendSlice []netip.Addr) []netip.Addr return minuendSlice } - var difference []netip.Addr + resultIpCount := 0 // count of IPs after removing items from subtrahendSlice // Loop over minuend IPs for _, minuendIp := range minuendSlice { // Check if subtrahend has minuend element listed var foundSubtrahend bool - for _, subtrahendIp := range subtrahendSlice { if subtrahendIp == minuendIp { // IP found in subtrahend, therefore breaking inner loop early foundSubtrahend = true break } - } - // Store the IP in difference when subtrahend does not contain IP of minuend + // Store the IP in `minuendSlice` at `resultIpCount` index and increment the index itself if !foundSubtrahend { - // Add IP to the resulting difference slice - difference = append(difference, minuendIp) + // Add IP to the 'resultIpCount' index position + minuendSlice[resultIpCount] = minuendIp + resultIpCount++ } } - return difference + // if all elements are removed - return nil + if resultIpCount == 0 { + return nil + } + + // cut off all values, greater than `resultIpCount` + minuendSlice = minuendSlice[:resultIpCount] + + return minuendSlice } // filterIpSlicesBySubnet accepts 'ipRange' and returns a slice of IPs only that fall into given