private static void printPatterns( String filename, String header, FractionalMultiset<String> average, FractionalMultiset<String> variance, Multiset<String> count) throws FileNotFoundException { I18N i18n = I18N.instance(); PrintWriter out = new PrintWriter(filename); out.println(header); for (Map.Entry<String, Double> e : average.entriesInDecreasingOrder()) { String key = e.getKey(); BugPattern pattern = i18n.lookupBugPattern(key); if (pattern != null) out.printf( "%1.1f,%1.1f,%d,%d,%s%n", e.getValue(), variance.getValue(key), BugRanker.findRank(pattern, 1), count.getCount(key), key); } out.close(); }
/** * @param i18n * @param d * @return */ private static String getDesignationTitle( I18N i18n, edu.umd.cs.findbugs.cloud.Cloud.UserDesignation d) { String designation; switch (d) { case OBSOLETE_CODE: designation = "obsolete code"; break; case MUST_FIX: designation = "Must fix"; break; case SHOULD_FIX: designation = "Should fix"; break; default: designation = i18n.getUserDesignation(d.name()); } return designation; }
public static void main(String args[]) throws Exception { Map<String, String> officeLocation = new HashMap<String, String>(); URL u = PluginLoader.getCoreResource("offices.properties"); if (u != null) { BufferedReader in = new BufferedReader(new InputStreamReader(u.openStream())); while (true) { String s = in.readLine(); if (s == null) break; if (s.trim().length() == 0) continue; int x = s.indexOf(':'); if (x == -1) continue; String office = s.substring(0, x); for (String person : s.substring(x + 1).split(" ")) officeLocation.put(person, office); } in.close(); } I18N i18n = I18N.instance(); // TODO: this this DBCloud cloud = new DBCloud(null, null, new Properties()); cloud.initialize(); Connection c = cloud.getConnection(); Map<Integer, Rank> bugRank = new HashMap<Integer, Rank>(); Map<Integer, String> bugPattern = new HashMap<Integer, String>(); Map<String, Integer> detailedBugRank = new HashMap<String, Integer>(); PreparedStatement ps = c.prepareStatement("SELECT id, hash, bugPattern, priority FROM findbugs_issue"); ResultSet rs = ps.executeQuery(); while (rs.next()) { int col = 1; int id = rs.getInt(col++); String hash = rs.getString(col++); String bugType = rs.getString(col++); int priority = rs.getInt(col++); BugPattern pattern = i18n.lookupBugPattern(bugType); if (pattern != null) { int rank = BugRanker.findRank(pattern, priority); bugRank.put(id, Rank.getRank(rank)); detailedBugRank.put(hash, rank); bugPattern.put(id, pattern.getType()); } } rs.close(); ps.close(); ps = c.prepareStatement( "SELECT who, jvmLoadTime, findbugsLoadTime, analysisLoadTime, initialSyncTime, timestamp, numIssues" + " FROM findbugs_invocation"); MergeMap.MinMap<String, Timestamp> firstUse = new MergeMap.MinMap<String, Timestamp>(); MergeMap.MinMap<String, Timestamp> reviewers = new MergeMap.MinMap<String, Timestamp>(); MergeMap.MinMap<String, Timestamp> uniqueReviews = new MergeMap.MinMap<String, Timestamp>(); HashSet<String> participants = new HashSet<String>(); Multiset<String> invocations = new Multiset<String>(); Multiset<String> participantsPerOffice = new Multiset<String>(new TreeMap<String, Integer>()); rs = ps.executeQuery(); int invocationCount = 0; long invocationTotal = 0; long loadTotal = 0; while (rs.next()) { int col = 1; String who = rs.getString(col++); int jvmLoad = rs.getInt(col++); int fbLoad = rs.getInt(col++); int analysisLoad = rs.getInt(col++); int dbSync = rs.getInt(col++); Timestamp when = rs.getTimestamp(col++); int numIssues = rs.getInt(col++); invocationCount++; invocationTotal += jvmLoad + fbLoad + analysisLoad + dbSync; loadTotal += fbLoad + analysisLoad + dbSync; firstUse.put(who, when); if (numIssues > 3000) invocations.add(who); if (participants.add(who)) { String office = officeLocation.get(who); if (office == null) office = "unknown"; participantsPerOffice.add(office); } } rs.close(); ps.close(); ps = c.prepareStatement( "SELECT id, issueId, who, designation, timestamp FROM findbugs_evaluation ORDER BY timestamp DESC"); rs = ps.executeQuery(); Multiset<String> issueReviewedBy = new Multiset<String>(); Multiset<String> allIssues = new Multiset<String>(); Multiset<String> scariestIssues = new Multiset<String>(); Multiset<String> scaryIssues = new Multiset<String>(); Multiset<String> troublingIssues = new Multiset<String>(); Multiset<Integer> scoreForIssue = new Multiset<Integer>(); Multiset<Integer> squareScoreForIssue = new Multiset<Integer>(); Multiset<Integer> reviewsForIssue = new Multiset<Integer>(); Multiset<Integer> scoredReviews = new Multiset<Integer>(); HashSet<String> issueReviews = new HashSet<String>(); HashSet<Integer> missingRank = new HashSet<Integer>(); while (rs.next()) { int col = 1; int id = rs.getInt(col++); int issueId = rs.getInt(col++); String who = rs.getString(col++); String designation = rs.getString(col++); UserDesignation d = UserDesignation.valueOf(designation); designation = getDesignationTitle(i18n, d); int score = d.score(); if (d != UserDesignation.OBSOLETE_CODE) { scoreForIssue.add(issueId, score); squareScoreForIssue.add(issueId, score * score); scoredReviews.add(issueId); } reviewsForIssue.add(issueId); Timestamp when = rs.getTimestamp(col++); Rank rank = bugRank.get(issueId); reviewers.put(who, when); String issueReviewer = who + "-" + issueId; if (issueReviews.add(issueReviewer)) { uniqueReviews.put(issueReviewer, when); allIssues.add(designation); issueReviewedBy.add(who); if (rank != null) switch (rank) { case SCARIEST: scariestIssues.add(designation); break; case SCARY: scaryIssues.add(designation); break; case TROUBLING: troublingIssues.add(designation); break; } else { if (missingRank.add(id)) { System.out.println("No rank for " + id); } } } } rs.close(); ps.close(); PrintWriter scariestBugs = new PrintWriter("bugReportsForScariestIssues.csv"); scariestBugs.println("assignedTo,status,rank,note"); Multiset<String> bugStatus = new Multiset<String>(); HashSet<String> bugsSeen = new HashSet<String>(); Multiset<String> bugScore = new Multiset<String>(); FractionalMultiset<String> patternScore = new FractionalMultiset<String>(); Multiset<String> patternCount = new Multiset<String>(); FractionalMultiset<String> patternVariance = new FractionalMultiset<String>(); FractionalMultiset<Integer> issueVariance = new FractionalMultiset<Integer>(); FractionalMultiset<Integer> issueScore = new FractionalMultiset<Integer>(); Multiset<String> bugsFiled = new Multiset<String>(); ps = c.prepareStatement( "SELECT bugReportId,hash,status, whoFiled,assignedTo, postmortem, timestamp FROM findbugs_bugreport ORDER BY timestamp DESC"); rs = ps.executeQuery(); while (rs.next()) { int col = 1; String id = rs.getString(col++); String hash = rs.getString(col++); String status = rs.getString(col++); String who = rs.getString(col++); String assignedTo = rs.getString(col++); String postmortem = rs.getString(col++); Timestamp when = rs.getTimestamp(col++); if (!bugsSeen.add(id)) continue; Integer rank = detailedBugRank.get(hash); if (rank == null) { System.out.println("Could not find hash " + hash + " for " + id); } if (assignedTo != null && !"NEW".equals(status) && (rank != null && rank <= 4 || postmortem != null)) { if (postmortem != null) scariestBugs.printf("%s,%s,%s,%d,POSTMORTEM%n", assignedTo, id, status, rank); else scariestBugs.printf("%s,%s,%s,%d%n", assignedTo, id, status, rank); } if (!id.equals(DBCloud.PENDING) && !id.equals(DBCloud.NONE)) { bugStatus.add(status); bugsFiled.add(who); bugScore.add(who, BUG_STATUS.score(status)); } } rs.close(); ps.close(); c.close(); scariestBugs.close(); Multiset<String> overallEvaluation = new Multiset<String>(); for (Map.Entry<Integer, Integer> e : scoreForIssue.entrySet()) { int value = e.getValue(); Integer issue = e.getKey(); int num = scoredReviews.getCount(issue); if (num == 0) continue; double average = value / (double) num; int score = (int) Math.round(average); double square = squareScoreForIssue.getCount(issue) / (double) num; double variance = square - average * average; String pattern = bugPattern.get(issue); patternCount.add(pattern); patternScore.add(pattern, average); patternVariance.add(pattern, variance); issueVariance.add(issue, variance); issueScore.add(issue, average); // System.out.printf("%s %2d %2d%n", score, value, num); overallEvaluation.add(getDesignationTitle(i18n, getDesignationFromScore(score))); } patternScore.turnTotalIntoAverage(patternCount); patternVariance.turnTotalIntoAverage(patternCount); printPatterns( "patternScore.csv", "average,variance,rank,count,pattern", patternScore, patternVariance, patternCount); issueScore.turnTotalIntoAverage(reviewsForIssue); issueVariance.turnTotalIntoAverage(reviewsForIssue); PrintWriter out1 = new PrintWriter("issueVariance.csv"); out1.println("variance,average,count,key,pattern"); for (Map.Entry<Integer, Double> e1 : issueVariance.entriesInDecreasingOrder()) { Integer key = e1.getKey(); int elementCount = reviewsForIssue.getCount(key); Double v = e1.getValue(); if (elementCount >= 3 && v >= 0.5) out1.printf( "%3.1f,%3.1f,%d,%d,%s%n", v, issueScore.getValue(key), elementCount, key, bugPattern.get(key)); } out1.close(); System.out.printf("%6d invocations%n", invocationCount); System.out.printf("%6d invocations time (secs)%n", invocationTotal / invocationCount / 1000); System.out.printf("%6d load time (secs)%n", loadTotal / invocationCount / 1000); System.out.println(); printTimeSeries("users.csv", "Unique users", firstUse); printTimeSeries("reviewers.csv", "Unique reviewers", reviewers); printTimeSeries("reviews.csv", "Total reviews", uniqueReviews); PrintWriter out = new PrintWriter("bug_status.csv"); out.println("Status,Number of bugs"); printMultiset(out, "Bug status", bugStatus); out.close(); out = new PrintWriter("reviews_by_category.csv"); out.println("Category,Number of reviews"); printMultisetContents(out, "", allIssues); out.close(); out = new PrintWriter("overall_review_of_issue.csv"); out.println("Category,Number of issues"); printMultisetContents(out, "", overallEvaluation); out.close(); out = new PrintWriter("reviews_by_rank_and_category.csv"); out.println("Rank,Category,Number of reviews"); printMultisetContents(out, "Scariest,", scariestIssues); printMultisetContents(out, "Scary,", scaryIssues); printMultisetContents(out, "Troubling,", troublingIssues); out.close(); out = new PrintWriter("bugs_filed.csv"); out.println("rank,bugs filed,who"); AbstractCloud.printLeaderBoard2( out, bugsFiled, 200, null, "%s,%s,%s\n", "participants per office"); out.close(); out = new PrintWriter("bug_score.csv"); out.println("rank,bug score,who"); AbstractCloud.printLeaderBoard2( out, bugScore, 200, null, "%s,%s,%s\n", "participants per office"); out.close(); out = new PrintWriter("most_participants_by_office.csv"); out.println("rank,participants,office"); AbstractCloud.printLeaderBoard2( out, participantsPerOffice, 100, null, "%s,%s,%s\n", "participants per office"); out.close(); out = new PrintWriter("most_issues_reviewed_individual.csv"); out.println("rank,reviews,reviewers"); AbstractCloud.printLeaderBoard2( out, issueReviewedBy, 10000, null, "%s,%s,%s\n", "num issues reviewed"); out.close(); }