(primaryMods []string, groupMap map[string][]string, targetCount int)
| 218 | } |
| 219 | |
| 220 | func (a *App) binarySearch(primaryMods []string, groupMap map[string][]string, targetCount int) string { |
| 221 | current := make([]string, len(primaryMods)) |
| 222 | copy(current, primaryMods) |
| 223 | |
| 224 | for len(current) > targetCount && !a.getScanCancelled() { |
| 225 | mid := len(current) / 2 |
| 226 | groupA := current[:mid] |
| 227 | groupB := current[mid:] |
| 228 | |
| 229 | modsAList := flattenGroup(groupA, groupMap) |
| 230 | a.emitLog(fmt.Sprintf("Testing Group A (%d mods from %d primary groups)...", len(modsAList), len(groupA)), LogInfo) |
| 231 | result := a.testGroup(modsAList) |
| 232 | |
| 233 | if a.getScanCancelled() { |
| 234 | return "" |
| 235 | } |
| 236 | |
| 237 | if result { |
| 238 | a.emitLog("Group A passed - focusing on Group B", LogSuccess) |
| 239 | current = groupB |
| 240 | } else { |
| 241 | a.emitLog("Group A failed - focusing on Group A", LogError) |
| 242 | current = groupA |
| 243 | } |
| 244 | } |
| 245 | |
| 246 | if a.getScanCancelled() || len(current) > targetCount { |
| 247 | return "" |
| 248 | } |
| 249 | |
| 250 | finalList := flattenGroup(current, groupMap) |
| 251 | a.emitLog(fmt.Sprintf("Final test on suspected culprit(s) (%d mods from %d groups)...", len(finalList), len(current)), LogInfo) |
| 252 | finalResult := a.testGroup(finalList) |
| 253 | |
| 254 | if a.getScanCancelled() { |
| 255 | return "" |
| 256 | } |
| 257 | |
| 258 | if !finalResult { |
| 259 | sort.Strings(finalList) |
| 260 | return joinStrings(finalList, ", ") |
| 261 | } |
| 262 | |
| 263 | a.emitLog("Final test passed. Could not isolate the issue.", LogWarning) |
| 264 | return "" |
| 265 | } |
| 266 | |
| 267 | func flattenGroup(primaryMods []string, groupMap map[string][]string) []string { |
| 268 | modSet := make(map[string]bool) |
no test coverage detected