List of usage examples for java.util SortedSet remove
boolean remove(Object o);
From source file:org.easyrec.plugin.arm.impl.AssocRuleMiningServiceImpl.java
@Override public Collection<SortedSet<ItemAssocVO<Integer, Integer>>> createBestRules(List<TupleVO> tuples, TObjectIntHashMap<ItemVO<Integer, Integer>> L1, ARMConfigurationInt configuration, ARMStatistics stats, Double minConfidence) {/* www . j a v a 2 s .c o m*/ // Integer h1, h2; Double dh1, dh2; Integer sup1, sup2; Double dsup1, dsup2, assocValue1, assocValue2; Double baskets = new Double(stats.getNrBaskets()); stats.setMetricType(configuration.getMetricType()); //Vector<ItemAssocVO<Integer,Integer>> ret = new Vector<ItemAssocVO<Integer,Integer>>(); Map<ItemVO<Integer, Integer>, SortedSet<ItemAssocVO<Integer, Integer>>> ret = new HashMap<>(); for (TupleVO tuple : tuples) { sup1 = L1.get(tuple.getItem1()); dsup1 = new Double(sup1); sup2 = L1.get(tuple.getItem2()); dsup2 = new Double(sup2); if (sup1 == null || sup2 == null) { continue; } // confidence // h1 = (tuple.getSupport() * 100) / sup1; // h2 = (tuple.getSupport() * 100) / sup2; // confidence dh1 = (tuple.getSupport() * 100) / dsup1; dh2 = (tuple.getSupport() * 100) / dsup2; // lift Double lift = tuple.getSupport() / (dsup1 * dsup2); // conviction Double conviction1 = (1 - (dsup2 / baskets)) / (100 - dh1); Double conviction2 = (1 - (dsup1 / baskets)) / (100 - dh2); // ltc Double ltc1 = dsup1 * Math.log10(dsup1 / dsup2); Double ltc2 = dsup2 * Math.log10(dsup2 / dsup1); switch (configuration.getMetricType()) { case CONFIDENCE: assocValue1 = dh1; assocValue2 = dh2; break; case CONVICTION: assocValue1 = conviction1; assocValue2 = conviction2; break; case LIFT: assocValue1 = lift; assocValue2 = lift; break; case LONGTAIL: assocValue1 = ltc1; assocValue2 = ltc2; break; default: assocValue1 = dh1; assocValue2 = dh2; break; } // public ItemAssocVO(T tenant, ItemVO<T, I, IT> itemFrom, AT assocType, // Double assocValue, ItemVO<T, I, IT> itemTo, ST sourceType, // String sourceInfo, VT viewType, Boolean active) if (dh1 >= (minConfidence)) { SortedSet<ItemAssocVO<Integer, Integer>> bestRules = ret.get(tuple.getItem1()); if (bestRules == null) { bestRules = new TreeSet<>(); } if ((bestRules.size() < configuration.getMaxRulesPerItem()) || (assocValue1 > bestRules.first().getAssocValue())) { // no need to create objects if limit already reached and rule shows worse quality String comment1 = null; if (configuration.getStoreAlternativeMetrics()) { comment1 = new StringBuilder("conf=").append(String.format("%04f", dh1)).append(" lift=") .append(String.format("%04f", lift)).append(" convic=") .append(String.format("%04f", conviction1)).append(" ltc=") .append(String.format("%04f", ltc1)).append(" sup1=") .append(String.format("%04f", dsup1)).append(" sup2=") .append(String.format("%04f", dsup2)).append(" tsup=").append(tuple.getSupport()) .toString(); } ItemAssocVO<Integer, Integer> rule = new ItemAssocVO<>(configuration.getTenantId(), tuple.getItem1(), configuration.getAssocType(), assocValue1 /*new Double(h1)*/, tuple.getItem2(), typeMappingService.getIdOfSourceType(configuration.getTenantId(), ARMGenerator.ID.toString() + "/" + ARMGenerator.VERSION), comment1, typeMappingService.getIdOfViewType(configuration.getTenantId(), TypeMappingService.VIEW_TYPE_COMMUNITY), true, stats.getStartDate()); bestRules.add(rule); if (bestRules.size() > configuration.getMaxRulesPerItem()) { bestRules.remove(bestRules.first()); } ret.put(tuple.getItem1(), bestRules); } } if (dh2 >= (minConfidence)) { SortedSet<ItemAssocVO<Integer, Integer>> bestRules = ret.get(tuple.getItem2()); if (bestRules == null) { bestRules = new TreeSet<>(); } if ((bestRules.size() < configuration.getMaxRulesPerItem()) || (assocValue2 > bestRules.first().getAssocValue())) { // no need to create objects if limit already reached and rule shows worse quality String comment2 = null; if (configuration.getStoreAlternativeMetrics()) { comment2 = new StringBuilder("conf=").append(String.format("%04f", dh2)).append(" lift=") .append(String.format("%04f", lift)).append(" convic=") .append(String.format("%04f", conviction2)).append(" ltc=") .append(String.format("%04f", ltc2)).append(" sup2=") .append(String.format("%04f", dsup2)).append(" sup1=") .append(String.format("%04f", dsup1)).append(" tsup=").append(tuple.getSupport()) .toString(); } ItemAssocVO<Integer, Integer> rule = new ItemAssocVO<>(configuration.getTenantId(), tuple.getItem2(), configuration.getAssocType(), assocValue2 /*new Double(h2)*/, tuple.getItem1(), typeMappingService.getIdOfSourceType(configuration.getTenantId(), ARMGenerator.ID.toString() + "/" + ARMGenerator.VERSION), comment2, typeMappingService.getIdOfViewType(configuration.getTenantId(), TypeMappingService.VIEW_TYPE_COMMUNITY), true, stats.getStartDate()); bestRules.add(rule); if (bestRules.size() > configuration.getMaxRulesPerItem()) { bestRules.remove(bestRules.first()); } ret.put(tuple.getItem2(), bestRules); } } } return ret.values(); }
From source file:org.eclipse.gyrex.jobs.internal.storage.CloudPreferncesJobHistoryStorage.java
private void shrinkToSizeLimit(final SortedSet<JobHistoryEntryStorable> entries) { // remove the last entries if over size while (entries.size() > MAX_HISTORY_SIZE) { entries.remove(entries.last()); }/*from w w w .j av a 2 s .c o m*/ }
From source file:org.isatools.tablib.export.graph2tab.LayersBuilder.java
/** * Set the layer for a node, which means all the two internal structures used for that are updated. * // ww w .j a v a2 s .c o m */ private void setLayer(Node node, int layer) { // Remove from the old layer Integer oldLayer = node2Layer.get(node); if (oldLayer != null) { SortedSet<Node> oldLayerNodes = layer2Nodes.get(oldLayer); if (oldLayerNodes.remove(node) && oldLayerNodes.isEmpty() && oldLayer == maxLayer) maxLayer--; } // Add to the new layer SortedSet<Node> lnodes = layer2Nodes.get(layer); if (lnodes == null) { lnodes = new TreeSet<Node>(); layer2Nodes.put(layer, lnodes); } lnodes.add(node); node2Layer.put(node, layer); if (layer > maxLayer) maxLayer = layer; }
From source file:org.jasig.schedassist.model.AvailableBlockBuilderTest.java
/** * Create a set of blocks with createBlocks. * expand, then remove some of the expanded elements. * call combine and verify blocks are created properly. * /*ww w . ja v a 2 s . c o m*/ * @throws Exception */ @Test public void testCombine3() throws Exception { SimpleDateFormat dateFormat = CommonDateOperations.getDateFormat(); Date startDate = dateFormat.parse("20080720"); Date endDate = dateFormat.parse("20080726"); Set<AvailableBlock> blocks = AvailableBlockBuilder.createBlocks("8:00 AM", "4:00 PM", "MWF", startDate, endDate); // Mon/Wed/Fri from July 20 to July 26 // 3 days in this span assertEquals(3, blocks.size()); // 16 blocks per day (8 hours) SortedSet<AvailableBlock> expandedBlocks = AvailableBlockBuilder.expand(blocks, 30); assertEquals(48, expandedBlocks.size()); // remove 12:00 to 12:30 on Wednesday expandedBlocks.remove(AvailableBlockBuilder.createBlock("20080723-1200", "20080723-1230")); assertEquals(47, expandedBlocks.size()); SortedSet<AvailableBlock> recombinedBlocks = AvailableBlockBuilder.combine(expandedBlocks); assertEquals(4, recombinedBlocks.size()); SortedSet<AvailableBlock> reexpandedBlocks = AvailableBlockBuilder.expand(recombinedBlocks, 30); assertEquals(47, reexpandedBlocks.size()); // remove 3:30 to 4:00 on Friday reexpandedBlocks.remove(AvailableBlockBuilder.createBlock("20080725-1530", "20080725-1600")); assertEquals(46, reexpandedBlocks.size()); // recombining shouldn't change the size; we're just trimming the length of the last large block assertEquals(4, AvailableBlockBuilder.combine(reexpandedBlocks).size()); }
From source file:org.jclouds.blobstore.integration.internal.StubAsyncBlobStore.java
public Future<? extends ListContainerResponse<? extends ResourceMetadata>> list(final String name, ListContainerOptions... optionsList) { final ListContainerOptions options = (optionsList.length == 0) ? new ListContainerOptions() : optionsList[0];/* w w w .j a v a 2 s .c o m*/ return new FutureBase<ListContainerResponse<ResourceMetadata>>() { public ListContainerResponse<ResourceMetadata> get() throws InterruptedException, ExecutionException { final Map<String, Blob> realContents = getContainerToBlobs().get(name); if (realContents == null) throw new ContainerNotFoundException(name); SortedSet<ResourceMetadata> contents = Sets.newTreeSet( Iterables.transform(realContents.keySet(), new Function<String, ResourceMetadata>() { public ResourceMetadata apply(String key) { return copy(realContents.get(key).getMetadata()); } })); if (options.getMarker() != null) { final String finalMarker = options.getMarker(); ResourceMetadata lastMarkerMetadata = Iterables.find(contents, new Predicate<ResourceMetadata>() { public boolean apply(ResourceMetadata metadata) { return metadata.getName().equals(finalMarker); } }); contents = contents.tailSet(lastMarkerMetadata); contents.remove(lastMarkerMetadata); } final String prefix = options.getPath(); if (prefix != null) { contents = Sets.newTreeSet(Iterables.filter(contents, new Predicate<ResourceMetadata>() { public boolean apply(ResourceMetadata o) { return (o != null && o.getName().startsWith(prefix)); } })); } int maxResults = contents.size(); boolean truncated = false; String marker = null; if (options.getMaxResults() != null && contents.size() > 0) { SortedSet<ResourceMetadata> contentsSlice = firstSliceOfSize(contents, options.getMaxResults().intValue()); maxResults = options.getMaxResults(); if (!contentsSlice.contains(contents.last())) { // Partial listing truncated = true; marker = contentsSlice.last().getName(); } else { marker = null; } contents = contentsSlice; } final String delimiter = options.isRecursive() ? null : "/"; if (delimiter != null) { SortedSet<String> commonPrefixes = null; Iterable<String> iterable = Iterables.transform(contents, new CommonPrefixes(prefix != null ? prefix : null, delimiter)); commonPrefixes = iterable != null ? Sets.newTreeSet(iterable) : new TreeSet<String>(); commonPrefixes.remove(CommonPrefixes.NO_PREFIX); contents = Sets.newTreeSet(Iterables.filter(contents, new DelimiterFilter(prefix != null ? prefix : null, delimiter))); Iterables.<ResourceMetadata>addAll(contents, Iterables.transform(commonPrefixes, new Function<String, ResourceMetadata>() { public ResourceMetadata apply(String o) { MutableResourceMetadata md = new MutableResourceMetadataImpl(); md.setType(ResourceType.RELATIVE_PATH); md.setName(o); return md; } })); } return new ListContainerResponseImpl<ResourceMetadata>(contents, prefix, marker, maxResults, truncated); } }; }
From source file:org.rapla.storage.impl.server.LocalAbstractCachableOperator.java
private void checkAbandonedAppointments() { Collection<? extends Allocatable> allocatables = cache.getAllocatables(); Logger logger = getLogger().getChildLogger("appointmentcheck"); try {//from www .ja v a 2s.c o m for (Allocatable allocatable : allocatables) { SortedSet<Appointment> appointmentSet = this.appointmentMap.get(allocatable.getId()); if (appointmentSet == null) { continue; } for (Appointment app : appointmentSet) { { SimpleEntity original = (SimpleEntity) app; String id = original.getId(); if (id == null) { logger.error("Empty id for " + original); continue; } Appointment persistant = cache.tryResolve(id, Appointment.class); if (persistant == null) { logger.error("appointment not stored in cache " + original); continue; } } Reservation reservation = app.getReservation(); if (reservation == null) { logger.error("Appointment without a reservation stored in cache " + app); appointmentSet.remove(app); continue; } else if (!reservation.hasAllocated(allocatable, app)) { logger.error("Allocation is not stored correctly for " + reservation + " " + app + " " + allocatable + " removing binding for " + app); appointmentSet.remove(app); continue; } else { { Reservation original = reservation; String id = original.getId(); if (id == null) { logger.error("Empty id for " + original); continue; } Reservation persistant = cache.tryResolve(id, Reservation.class); if (persistant != null) { Date lastChanged = original.getLastChanged(); Date persistantLastChanged = persistant.getLastChanged(); if (persistantLastChanged != null && !persistantLastChanged.equals(lastChanged)) { logger.error( "Reservation stored in cache is not the same as in allocation store " + original); continue; } } else { logger.error("Reservation not stored in cache " + original + " removing binding for " + app); appointmentSet.remove(app); continue; } } } } } } catch (Exception ex) { logger.error(ex.getMessage(), ex); } }
From source file:org.sakaiproject.content.impl.BaseContentService.java
/** * Create the site's dropbox collection and one for each qualified user that the current user can make. * /*from w w w. j a v a2 s.c o m*/ * @param siteId * the Site id. */ public void createDropboxCollection(String siteId) { // make sure we are in a worksite, not a workspace if (m_siteService.isUserSite(siteId) || m_siteService.isSpecialSite(siteId)) { return; } // do our ONE security check to see if the current user can create the // dropbox and all inner folders if (!isDropboxMaintainer(siteId)) { createIndividualDropbox(siteId); return; } // form the site's dropbox collection String dropbox = COLLECTION_DROPBOX + siteId + "/"; try { // try to create if it doesn't exist if (findCollection(dropbox) == null) { ContentCollectionEdit edit = addValidPermittedCollection(dropbox); ResourcePropertiesEdit props = edit.getPropertiesEdit(); try { Site site = m_siteService.getSite(siteId); } catch (IdUnusedException e) { // TODO Auto-generated catch block e.printStackTrace(); } // these need to be moved to language bundle props.addProperty(ResourceProperties.PROP_DISPLAY_NAME, siteId + DROPBOX_ID); props.addProperty(ResourceProperties.PROP_DESCRIPTION, rb.getString("use2")); // props.addProperty(ResourceProperties.PROP_DESCRIPTION, PROP_SITE_DROPBOX_DESCRIPTION); commitCollection(edit); } } catch (TypeException e) { M_log.warn("createDropboxCollection: TypeException: " + dropbox); return; } catch (IdUsedException e) { M_log.warn("createDropboxCollection: IdUsedException: " + dropbox); return; } catch (InconsistentException e) { M_log.warn("createDropboxCollection(): InconsistentException: " + dropbox); M_log.warn("createDropboxCollection(): InconsistentException: " + e.getMessage()); return; } // catch (PermissionException e) // { // M_log.warn("createDropboxCollection(): PermissionException: " + dropbox); // return; // } SortedSet<String> members = new TreeSet<String>(); try { ContentCollection topDropbox = findCollection(dropbox); members.addAll((List<String>) topDropbox.getMembers()); } catch (TypeException e) { M_log.warn("createDropboxCollection(): File exists where dropbox collection is expected: " + dropbox); } // The AUTH_DROPBOX_OWN is granted within the site, so we can ask for all the users who have this ability // using just the dropbox collection List users = m_securityService.unlockUsers(AUTH_DROPBOX_OWN, getReference(dropbox)); for (Iterator it = users.iterator(); it.hasNext();) { User user = (User) it.next(); // the folder id for this user's dropbox in this group String userFolder = dropbox + user.getId() + "/"; // see if it exists - add if it doesn't try { if (!members.remove(userFolder)) { if (findCollection(userFolder) == null) // This check it probably redundant { ContentCollectionEdit edit = addValidPermittedCollection(userFolder); ResourcePropertiesEdit props = edit.getPropertiesEdit(); props.addProperty(ResourceProperties.PROP_DISPLAY_NAME, getDisplayName(user)); props.addProperty(ResourceProperties.PROP_DESCRIPTION, rb.getString("use1")); commitCollection(edit); } } } catch (TypeException e) { M_log.warn("createDropboxCollectionn(): TypeException: " + userFolder); } catch (IdUsedException e) { M_log.warn("createDropboxCollectionn(): idUsedException: " + userFolder); } catch (InconsistentException e) { M_log.warn("createDropboxCollection(): InconsistentException: " + userFolder); } } // Attempt to remove all empty dropboxes that are no longer members of the site. for (String member : members) { try { ContentCollection folder = getCollection(member); if (folder.getMemberCount() == 0) { removeCollection(member); M_log.info("createDropboxCollection(): Removed the empty dropbox collection for member: " + member); } else { M_log.warn("createDropboxCollection(): Could not remove the dropbox collection for member (" + member + ") because the root contains " + folder.getMemberCount() + " members"); } } catch (IdUnusedException e) { M_log.warn("createDropboxCollection(): Could not find collection to delete: " + member); } catch (PermissionException e) { M_log.warn("createDropboxCollection(): Unable to delete collection due to lack of permission: " + member); } catch (InUseException e) { M_log.warn("createDropboxCollection(): Unable to delete collection as collection is in use: " + member); } catch (ServerOverloadException e) { M_log.warn("createDropboxCollection(): Unable to delete collection as server is overloaded: " + member); } catch (TypeException e) { M_log.warn("createDropboxCollection(): Unable to delete as it doesn't appear to be a collection: " + member); } } }
From source file:org.torproject.ernie.db.ArchiveWriter.java
/** * Dump some statistics on the completeness of descriptors to the logs * on level INFO./*from w w w . j av a 2 s . c o m*/ */ public void dumpStats() { StringBuilder sb = new StringBuilder("Finished writing relay " + "descriptors to disk.\n"); sb.append(intermediateStats.toString()); sb.append("Statistics on the completeness of written relay " + "descriptors of the last 3 consensuses (Consensus/Vote, " + "valid-after, votes, server descriptors, extra-infos):"); try { SimpleDateFormat validAfterFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); validAfterFormat.setTimeZone(TimeZone.getTimeZone("UTC")); SimpleDateFormat consensusVoteFormat = new SimpleDateFormat("yyyy/MM/dd/yyyy-MM-dd-HH-mm-ss"); consensusVoteFormat.setTimeZone(TimeZone.getTimeZone("UTC")); SimpleDateFormat descriptorFormat = new SimpleDateFormat("yyyy/MM/"); descriptorFormat.setTimeZone(TimeZone.getTimeZone("UTC")); SortedSet<File> consensuses = new TreeSet<File>(); Stack<File> leftToParse = new Stack<File>(); leftToParse.add(new File(outputDirectory + "/consensus")); while (!leftToParse.isEmpty()) { File pop = leftToParse.pop(); if (pop.isDirectory()) { for (File f : pop.listFiles()) { leftToParse.add(f); } } else if (pop.length() > 0) { consensuses.add(pop); } while (consensuses.size() > 3) { consensuses.remove(consensuses.first()); } } for (File f : consensuses) { BufferedReader br = new BufferedReader(new FileReader(f)); String line = null, validAfterTime = null, voteFilenamePrefix = null, dirSource = null; int allVotes = 0, foundVotes = 0, allServerDescs = 0, foundServerDescs = 0, allExtraInfos = 0, foundExtraInfos = 0; while ((line = br.readLine()) != null) { if (line.startsWith("valid-after ")) { validAfterTime = line.substring("valid-after ".length()); long validAfter = validAfterFormat.parse(validAfterTime).getTime(); voteFilenamePrefix = outputDirectory + "/vote/" + consensusVoteFormat.format(new Date(validAfter)) + "-vote-"; } else if (line.startsWith("dir-source ")) { dirSource = line.split(" ")[2]; } else if (line.startsWith("vote-digest ")) { allVotes++; File voteFile = new File(voteFilenamePrefix + dirSource + "-" + line.split(" ")[1]); if (voteFile.exists()) { foundVotes++; BufferedReader vbr = new BufferedReader(new FileReader(voteFile)); String line3 = null; int voteAllServerDescs = 0, voteFoundServerDescs = 0, voteAllExtraInfos = 0, voteFoundExtraInfos = 0; while ((line3 = vbr.readLine()) != null) { if (line3.startsWith("r ")) { voteAllServerDescs++; String digest = Hex .encodeHexString(Base64.decodeBase64(line3.split(" ")[3] + "=")) .toLowerCase(); long published = validAfterFormat .parse(line3.split(" ")[4] + " " + line3.split(" ")[5]).getTime(); String filename = outputDirectory + "/server-descriptor/" + descriptorFormat.format(new Date(published)) + digest.substring(0, 1) + "/" + digest.substring(1, 2) + "/" + digest; if (new File(filename).exists()) { BufferedReader sbr = new BufferedReader(new FileReader(new File(filename))); String line2 = null; while ((line2 = sbr.readLine()) != null) { if (line2.startsWith("opt extra-info-digest ") || line2.startsWith("extra-info-digest ")) { voteAllExtraInfos++; String extraInfoDigest = line2.startsWith("opt ") ? line2.split(" ")[2].toLowerCase() : line2.split(" ")[1].toLowerCase(); String filename2 = outputDirectory + "/extra-info/" + descriptorFormat.format(new Date(published)) + extraInfoDigest.substring(0, 1) + "/" + extraInfoDigest.substring(1, 2) + "/" + extraInfoDigest; if (new File(filename2).exists()) { voteFoundExtraInfos++; } } } sbr.close(); voteFoundServerDescs++; } } } vbr.close(); sb.append(String.format("%nV, %s, NA, %d/%d (%.1f%%), " + "%d/%d (%.1f%%)", validAfterTime, voteFoundServerDescs, voteAllServerDescs, 100.0D * (double) voteFoundServerDescs / (double) voteAllServerDescs, voteFoundExtraInfos, voteAllExtraInfos, 100.0D * (double) voteFoundExtraInfos / (double) voteAllExtraInfos)); } } else if (line.startsWith("r ")) { allServerDescs++; String digest = Hex.encodeHexString(Base64.decodeBase64(line.split(" ")[3] + "=")) .toLowerCase(); long published = validAfterFormat.parse(line.split(" ")[4] + " " + line.split(" ")[5]) .getTime(); String filename = outputDirectory + "/server-descriptor/" + descriptorFormat.format(new Date(published)) + digest.substring(0, 1) + "/" + digest.substring(1, 2) + "/" + digest; if (new File(filename).exists()) { BufferedReader sbr = new BufferedReader(new FileReader(new File(filename))); String line2 = null; while ((line2 = sbr.readLine()) != null) { if (line2.startsWith("opt extra-info-digest ") || line2.startsWith("extra-info-digest ")) { allExtraInfos++; String extraInfoDigest = line2.startsWith("opt ") ? line2.split(" ")[2].toLowerCase() : line2.split(" ")[1].toLowerCase(); String filename2 = outputDirectory + "/extra-info/" + descriptorFormat.format(new Date(published)) + extraInfoDigest.substring(0, 1) + "/" + extraInfoDigest.substring(1, 2) + "/" + extraInfoDigest; if (new File(filename2).exists()) { foundExtraInfos++; } } } sbr.close(); foundServerDescs++; } } } sb.append(String.format("%nC, %s, %d/%d (%.1f%%), " + "%d/%d (%.1f%%), %d/%d (%.1f%%)", validAfterTime, foundVotes, allVotes, 100.0D * (double) foundVotes / (double) allVotes, foundServerDescs, allServerDescs, 100.0D * (double) foundServerDescs / (double) allServerDescs, foundExtraInfos, allExtraInfos, 100.0D * (double) foundExtraInfos / (double) allExtraInfos)); } this.logger.info(sb.toString()); } catch (IOException e) { this.logger.log(Level.WARNING, "Could not dump statistics to disk.", e); } catch (ParseException e) { this.logger.log(Level.WARNING, "Could not dump statistics to disk.", e); } }
From source file:org.torproject.ernie.db.ConsensusHealthChecker.java
public void writeStatusWebsite() { /* If we don't have any consensus, we cannot write useful consensus * health information to the website. Do not overwrite existing page * with a warning, because we might just not have learned about a new * consensus in this execution. */ if (this.mostRecentConsensus == null) { return;/* w ww .java2s . c o m*/ } /* Prepare parsing dates. */ SimpleDateFormat dateTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); dateTimeFormat.setTimeZone(TimeZone.getTimeZone("UTC")); StringBuilder knownFlagsResults = new StringBuilder(); StringBuilder numRelaysVotesResults = new StringBuilder(); StringBuilder consensusMethodsResults = new StringBuilder(); StringBuilder versionsResults = new StringBuilder(); StringBuilder paramsResults = new StringBuilder(); StringBuilder authorityKeysResults = new StringBuilder(); StringBuilder bandwidthScannersResults = new StringBuilder(); StringBuilder authorityVersionsResults = new StringBuilder(); SortedSet<String> allKnownFlags = new TreeSet<String>(); SortedSet<String> allKnownVotes = new TreeSet<String>(); SortedMap<String, String> consensusAssignedFlags = new TreeMap<String, String>(); SortedMap<String, SortedSet<String>> votesAssignedFlags = new TreeMap<String, SortedSet<String>>(); SortedMap<String, String> votesKnownFlags = new TreeMap<String, String>(); SortedMap<String, SortedMap<String, Integer>> flagsAgree = new TreeMap<String, SortedMap<String, Integer>>(); SortedMap<String, SortedMap<String, Integer>> flagsLost = new TreeMap<String, SortedMap<String, Integer>>(); SortedMap<String, SortedMap<String, Integer>> flagsMissing = new TreeMap<String, SortedMap<String, Integer>>(); /* Read consensus and parse all information that we want to compare to * votes. */ String consensusConsensusMethod = null, consensusKnownFlags = null, consensusClientVersions = null, consensusServerVersions = null, consensusParams = null, rLineTemp = null, sLineTemp = null; int consensusTotalRelays = 0, consensusRunningRelays = 0; try { BufferedReader br = new BufferedReader(new StringReader(new String(this.mostRecentConsensus))); String line = null; while ((line = br.readLine()) != null) { if (line.startsWith("consensus-method ")) { consensusConsensusMethod = line; } else if (line.startsWith("client-versions ")) { consensusClientVersions = line; } else if (line.startsWith("server-versions ")) { consensusServerVersions = line; } else if (line.startsWith("known-flags ")) { consensusKnownFlags = line; } else if (line.startsWith("params ")) { consensusParams = line; } else if (line.startsWith("r ")) { rLineTemp = line; } else if (line.startsWith("s ")) { sLineTemp = line; consensusTotalRelays++; if (line.contains(" Running")) { consensusRunningRelays++; } consensusAssignedFlags.put( Hex.encodeHexString(Base64.decodeBase64(rLineTemp.split(" ")[2] + "=")).toUpperCase() + " " + rLineTemp.split(" ")[1], line); } else if (line.startsWith("v ") && sLineTemp.contains(" Authority")) { authorityVersionsResults .append(" <tr>\n" + " <td>" + rLineTemp.split(" ")[1] + "</td>\n" + " <td>" + line.substring(2) + "</td>\n" + " </tr>\n"); } } br.close(); } catch (IOException e) { /* There should be no I/O taking place when reading a String. */ } /* Read votes and parse all information to compare with the * consensus. */ for (byte[] voteBytes : this.mostRecentVotes.values()) { String voteConsensusMethods = null, voteKnownFlags = null, voteClientVersions = null, voteServerVersions = null, voteParams = null, dirSource = null, voteDirKeyExpires = null; int voteTotalRelays = 0, voteRunningRelays = 0, voteContainsBandwidthWeights = 0; try { BufferedReader br = new BufferedReader(new StringReader(new String(voteBytes))); String line = null; while ((line = br.readLine()) != null) { if (line.startsWith("consensus-methods ")) { voteConsensusMethods = line; } else if (line.startsWith("client-versions ")) { voteClientVersions = line; } else if (line.startsWith("server-versions ")) { voteServerVersions = line; } else if (line.startsWith("known-flags ")) { voteKnownFlags = line; } else if (line.startsWith("params ")) { voteParams = line; } else if (line.startsWith("dir-source ")) { dirSource = line.split(" ")[1]; allKnownVotes.add(dirSource); } else if (line.startsWith("dir-key-expires ")) { voteDirKeyExpires = line; } else if (line.startsWith("r ")) { rLineTemp = line; } else if (line.startsWith("s ")) { voteTotalRelays++; if (line.contains(" Running")) { voteRunningRelays++; } String relayKey = Hex.encodeHexString(Base64.decodeBase64(rLineTemp.split(" ")[2] + "=")) .toUpperCase() + " " + rLineTemp.split(" ")[1]; SortedSet<String> sLines = null; if (votesAssignedFlags.containsKey(relayKey)) { sLines = votesAssignedFlags.get(relayKey); } else { sLines = new TreeSet<String>(); votesAssignedFlags.put(relayKey, sLines); } sLines.add(dirSource + " " + line); } else if (line.startsWith("w ")) { if (line.contains(" Measured")) { voteContainsBandwidthWeights++; } } } br.close(); } catch (IOException e) { /* There should be no I/O taking place when reading a String. */ } /* Write known flags. */ knownFlagsResults.append(" <tr>\n" + " <td>" + dirSource + "</td>\n" + " <td>" + voteKnownFlags + "</td>\n" + " </tr>\n"); votesKnownFlags.put(dirSource, voteKnownFlags); for (String flag : voteKnownFlags.substring("known-flags ".length()).split(" ")) { allKnownFlags.add(flag); } /* Write number of relays voted about. */ numRelaysVotesResults.append(" <tr>\n" + " <td>" + dirSource + "</td>\n" + " <td>" + voteTotalRelays + " total</td>\n" + " <td>" + voteRunningRelays + " Running</td>\n" + " </tr>\n"); /* Write supported consensus methods. */ if (!voteConsensusMethods.contains(consensusConsensusMethod.split(" ")[1])) { consensusMethodsResults.append(" <tr>\n" + " <td><font color=\"red\">" + dirSource + "</font></td>\n" + " <td><font color=\"red\">" + voteConsensusMethods + "</font></td>\n" + " </tr>\n"); this.logger.warning(dirSource + " does not support consensus " + "method " + consensusConsensusMethod.split(" ")[1] + ": " + voteConsensusMethods); } else { consensusMethodsResults.append(" <tr>\n" + " <td>" + dirSource + "</td>\n" + " <td>" + voteConsensusMethods + "</td>\n" + " </tr>\n"); this.logger.fine(dirSource + " supports consensus method " + consensusConsensusMethod.split(" ")[1] + ": " + voteConsensusMethods); } /* Write recommended versions. */ if (voteClientVersions == null) { /* Not a versioning authority. */ } else if (!voteClientVersions.equals(consensusClientVersions)) { versionsResults.append(" <tr>\n" + " <td><font color=\"red\">" + dirSource + "</font></td>\n" + " <td><font color=\"red\">" + voteClientVersions + "</font></td>\n" + " </tr>\n"); this.logger.warning(dirSource + " recommends other client " + "versions than the consensus: " + voteClientVersions); } else { versionsResults.append(" <tr>\n" + " <td>" + dirSource + "</td>\n" + " <td>" + voteClientVersions + "</td>\n" + " </tr>\n"); this.logger.fine(dirSource + " recommends the same client " + "versions as the consensus: " + voteClientVersions); } if (voteServerVersions == null) { /* Not a versioning authority. */ } else if (!voteServerVersions.equals(consensusServerVersions)) { versionsResults.append( " <tr>\n" + " <td></td>\n" + " <td><font color=\"red\">" + voteServerVersions + "</font></td>\n" + " </tr>\n"); this.logger.warning(dirSource + " recommends other server " + "versions than the consensus: " + voteServerVersions); } else { versionsResults.append(" <tr>\n" + " <td></td>\n" + " <td>" + voteServerVersions + "</td>\n" + " </tr>\n"); this.logger.fine(dirSource + " recommends the same server " + "versions as the consensus: " + voteServerVersions); } /* Write consensus parameters. */ boolean conflictOrInvalid = false; Set<String> validParameters = new HashSet<String>( Arrays.asList("circwindow,CircuitPriorityHalflifeMsec,refuseunknownexits".split(","))); if (voteParams == null) { /* Authority doesn't set consensus parameters. */ } else { for (String param : voteParams.split(" ")) { if (!param.equals("params") && (!consensusParams.contains(param) || !validParameters.contains(param.split("=")[0]))) { conflictOrInvalid = true; break; } } } if (conflictOrInvalid) { paramsResults.append(" <tr>\n" + " <td><font color=\"red\">" + dirSource + "</font></td>\n" + " <td><font color=\"red\">" + voteParams + "</font></td>\n" + " </tr>\n"); this.logger.warning( dirSource + " sets conflicting or invalid " + "consensus parameters: " + voteParams); } else { paramsResults.append(" <tr>\n" + " <td>" + dirSource + "</td>\n" + " <td>" + voteParams + "</td>\n" + " </tr>\n"); this.logger.fine(dirSource + " sets only non-conflicting and " + "valid consensus parameters: " + voteParams); } /* Write authority key expiration date. */ if (voteDirKeyExpires != null) { boolean expiresIn14Days = false; try { expiresIn14Days = (System.currentTimeMillis() + 14L * 24L * 60L * 60L * 1000L > dateTimeFormat .parse(voteDirKeyExpires.substring("dir-key-expires ".length())).getTime()); } catch (ParseException e) { /* Can't parse the timestamp? Whatever. */ } if (expiresIn14Days) { authorityKeysResults.append(" <tr>\n" + " <td><font color=\"red\">" + dirSource + "</font></td>\n" + " <td><font color=\"red\">" + voteDirKeyExpires + "</font></td>\n" + " </tr>\n"); this.logger.warning( dirSource + "'s certificate expires in the " + "next 14 days: " + voteDirKeyExpires); } else { authorityKeysResults.append(" <tr>\n" + " <td>" + dirSource + "</td>\n" + " <td>" + voteDirKeyExpires + "</td>\n" + " </tr>\n"); this.logger.fine(dirSource + "'s certificate does not " + "expire in the next 14 days: " + voteDirKeyExpires); } } /* Write results for bandwidth scanner status. */ if (voteContainsBandwidthWeights > 0) { bandwidthScannersResults.append(" <tr>\n" + " <td>" + dirSource + "</td>\n" + " <td>" + voteContainsBandwidthWeights + " Measured values in w lines</td>\n" + " </tr>\n"); } } /* Check if we're missing a vote. TODO make this configurable */ SortedSet<String> knownAuthorities = new TreeSet<String>( Arrays.asList(("dannenberg,dizum,gabelmoo,ides,maatuska,moria1," + "tor26,urras").split(","))); for (String dir : allKnownVotes) { knownAuthorities.remove(dir); } if (!knownAuthorities.isEmpty()) { StringBuilder sb = new StringBuilder(); for (String dir : knownAuthorities) { sb.append(", " + dir); } this.logger.warning("We're missing votes from the following " + "directory authorities: " + sb.toString().substring(2)); } try { /* Keep the past two consensus health statuses. */ File file0 = new File("website/consensus-health.html"); File file1 = new File("website/consensus-health-1.html"); File file2 = new File("website/consensus-health-2.html"); if (file2.exists()) { file2.delete(); } if (file1.exists()) { file1.renameTo(file2); } if (file0.exists()) { file0.renameTo(file1); } /* Start writing web page. */ BufferedWriter bw = new BufferedWriter(new FileWriter("website/consensus-health.html")); bw.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 " + "Transitional//EN\">\n" + "<html>\n" + " <head>\n" + " <title>Tor Metrics Portal: Consensus health</title>\n" + " <meta http-equiv=\"content-type\" content=\"text/html; " + "charset=ISO-8859-1\">\n" + " <link href=\"/css/stylesheet-ltr.css\" type=\"text/css\" " + "rel=\"stylesheet\">\n" + " <link href=\"/images/favicon.ico\" " + "type=\"image/x-icon\" rel=\"shortcut icon\">\n" + " </head>\n" + " <body>\n" + " <div class=\"center\">\n" + " <table class=\"banner\" border=\"0\" " + "cellpadding=\"0\" cellspacing=\"0\" summary=\"\">\n" + " <tr>\n" + " <td class=\"banner-left\"><a " + "href=\"/index.html\"><img src=\"/images/top-left.png\" " + "alt=\"Click to go to home page\" width=\"193\" " + "height=\"79\"></a></td>\n" + " <td class=\"banner-middle\">\n" + " <a href=\"/\">Home</a>\n" + " <a href=\"graphs.html\">Graphs</a>\n" + " <a href=\"research.html\">Research</a>\n" + " <a href=\"status.html\">Status</a>\n" + " <br>\n" + " <font size=\"2\">\n" + " <a href=\"exonerator.html\">ExoneraTor</a>\n" + " <a href=\"relay-search.html\">Relay Search</a>\n" + " <a class=\"current\">Consensus Health</a>\n" + " </font>\n" + " </td>\n" + " <td class=\"banner-right\"></td>\n" + " </tr>\n" + " </table>\n" + " <div class=\"main-column\">\n" + " <h2>Tor Metrics Portal: Consensus Health</h2>\n" + " <br>\n" + " <p>This page shows statistics about the current " + "consensus and votes to facilitate debugging of the " + "directory consensus process.</p>\n"); /* Write valid-after time. */ bw.write(" <br>\n" + " <h3>Valid-after time</h3>\n" + " <br>\n" + " <p>Consensus was published "); boolean consensusIsStale = false; try { consensusIsStale = System.currentTimeMillis() - 3L * 60L * 60L * 1000L > dateTimeFormat .parse(this.mostRecentValidAfterTime).getTime(); } catch (ParseException e) { /* Can't parse the timestamp? Whatever. */ } if (consensusIsStale) { bw.write("<font color=\"red\">" + this.mostRecentValidAfterTime + "</font>"); this.logger.warning("The last consensus published at " + this.mostRecentValidAfterTime + " is more than 3 hours " + "old."); } else { bw.write(this.mostRecentValidAfterTime); this.logger.fine("The last consensus published at " + this.mostRecentValidAfterTime + " is less than 3 hours " + "old."); } bw.write(". <i>Note that it takes " + "15 to 30 minutes for the metrics portal to learn about " + "new consensus and votes and process them.</i></p>\n"); /* Write known flags. */ bw.write(" <br>\n" + " <h3>Known flags</h3>\n" + " <br>\n" + " <table border=\"0\" cellpadding=\"4\" " + "cellspacing=\"0\" summary=\"\">\n" + " <colgroup>\n" + " <col width=\"160\">\n" + " <col width=\"640\">\n" + " </colgroup>\n"); if (knownFlagsResults.length() < 1) { bw.write(" <tr><td>(No votes.)</td><td></td></tr>\n"); } else { bw.write(knownFlagsResults.toString()); } bw.write(" <tr>\n" + " <td><font color=\"blue\">consensus</font>" + "</td>\n" + " <td><font color=\"blue\">" + consensusKnownFlags + "</font></td>\n" + " </tr>\n"); bw.write(" </table>\n"); /* Write number of relays voted about. */ bw.write(" <br>\n" + " <h3>Number of relays voted about</h3>\n" + " <br>\n" + " <table border=\"0\" cellpadding=\"4\" " + "cellspacing=\"0\" summary=\"\">\n" + " <colgroup>\n" + " <col width=\"160\">\n" + " <col width=\"320\">\n" + " <col width=\"320\">\n" + " </colgroup>\n"); if (numRelaysVotesResults.length() < 1) { bw.write(" <tr><td>(No votes.)</td><td></td><td></td></tr>\n"); } else { bw.write(numRelaysVotesResults.toString()); } bw.write(" <tr>\n" + " <td><font color=\"blue\">consensus</font>" + "</td>\n" + " <td><font color=\"blue\">" + consensusTotalRelays + " total</font></td>\n" + " <td><font color=\"blue\">" + consensusRunningRelays + " Running</font></td>\n" + " </tr>\n"); bw.write(" </table>\n"); /* Write consensus methods. */ bw.write(" <br>\n" + " <h3>Consensus methods</h3>\n" + " <br>\n" + " <table border=\"0\" cellpadding=\"4\" " + "cellspacing=\"0\" summary=\"\">\n" + " <colgroup>\n" + " <col width=\"160\">\n" + " <col width=\"640\">\n" + " </colgroup>\n"); if (consensusMethodsResults.length() < 1) { bw.write(" <tr><td>(No votes.)</td><td></td></tr>\n"); } else { bw.write(consensusMethodsResults.toString()); } bw.write(" <tr>\n" + " <td><font color=\"blue\">consensus</font>" + "</td>\n" + " <td><font color=\"blue\">" + consensusConsensusMethod + "</font></td>\n" + " </tr>\n"); bw.write(" </table>\n"); /* Write recommended versions. */ bw.write(" <br>\n" + " <h3>Recommended versions</h3>\n" + " <br>\n" + " <table border=\"0\" cellpadding=\"4\" " + "cellspacing=\"0\" summary=\"\">\n" + " <colgroup>\n" + " <col width=\"160\">\n" + " <col width=\"640\">\n" + " </colgroup>\n"); if (versionsResults.length() < 1) { bw.write(" <tr><td>(No votes.)</td><td></td></tr>\n"); } else { bw.write(versionsResults.toString()); } bw.write(" <tr>\n" + " <td><font color=\"blue\">consensus</font>" + "</td>\n" + " <td><font color=\"blue\">" + consensusClientVersions + "</font></td>\n" + " </tr>\n"); bw.write(" <tr>\n" + " <td></td>\n" + " <td><font color=\"blue\">" + consensusServerVersions + "</font></td>\n" + " </tr>\n"); bw.write(" </table>\n"); /* Write consensus parameters. */ bw.write(" <br>\n" + " <h3>Consensus parameters</h3>\n" + " <br>\n" + " <table border=\"0\" cellpadding=\"4\" " + "cellspacing=\"0\" summary=\"\">\n" + " <colgroup>\n" + " <col width=\"160\">\n" + " <col width=\"640\">\n" + " </colgroup>\n"); if (paramsResults.length() < 1) { bw.write(" <tr><td>(No votes.)</td><td></td></tr>\n"); } else { bw.write(paramsResults.toString()); } bw.write(" <tr>\n" + " <td><font color=\"blue\">consensus</font>" + "</td>\n" + " <td><font color=\"blue\">" + consensusParams + "</font></td>\n" + " </tr>\n"); bw.write(" </table>\n"); /* Write authority keys. */ bw.write(" <br>\n" + " <h3>Authority keys</h3>\n" + " <br>\n" + " <table border=\"0\" cellpadding=\"4\" " + "cellspacing=\"0\" summary=\"\">\n" + " <colgroup>\n" + " <col width=\"160\">\n" + " <col width=\"640\">\n" + " </colgroup>\n"); if (authorityKeysResults.length() < 1) { bw.write(" <tr><td>(No votes.)</td><td></td></tr>\n"); } else { bw.write(authorityKeysResults.toString()); } bw.write(" </table>\n" + " <br>\n" + " <p><i>Note that expiration dates of legacy keys are " + "not included in votes and therefore not listed here!</i>" + "</p>\n"); /* Write bandwidth scanner status. */ bw.write(" <br>\n" + " <h3>Bandwidth scanner status</h3>\n" + " <br>\n" + " <table border=\"0\" cellpadding=\"4\" " + "cellspacing=\"0\" summary=\"\">\n" + " <colgroup>\n" + " <col width=\"160\">\n" + " <col width=\"640\">\n" + " </colgroup>\n"); if (bandwidthScannersResults.length() < 1) { bw.write(" <tr><td>(No votes.)</td><td></td></tr>\n"); } else { bw.write(bandwidthScannersResults.toString()); } bw.write(" </table>\n"); /* Write authority versions. */ bw.write(" <br>\n" + " <h3>Authority versions</h3>\n" + " <br>\n"); if (authorityVersionsResults.length() < 1) { bw.write(" <p>(No relays with Authority flag found.)" + "</p>\n"); } else { bw.write(" <table border=\"0\" cellpadding=\"4\" " + "cellspacing=\"0\" summary=\"\">\n" + " <colgroup>\n" + " <col width=\"160\">\n" + " <col width=\"640\">\n" + " </colgroup>\n"); bw.write(authorityVersionsResults.toString()); bw.write(" </table>\n" + " <br>\n" + " <p><i>Note that this list of relays with the " + "Authority flag may be different from the list of v3 " + "directory authorities!</i></p>\n"); } /* Write (huge) table with all flags. */ bw.write(" <br>\n" + " <h3>Relay flags</h3>\n" + " <br>\n" + " <p>The semantics of flags written in the table is " + "as follows:</p>\n" + " <ul>\n" + " <li><b>In vote and consensus:</b> Flag in vote " + "matches flag in consensus, or relay is not listed in " + "consensus (because it doesn't have the Running " + "flag)</li>\n" + " <li><b><font color=\"red\">Only in " + "vote:</font></b> Flag in vote, but missing in the " + "consensus, because there was no majority for the flag or " + "the flag was invalidated (e.g., Named gets invalidated by " + "Unnamed)</li>\n" + " <li><b><font color=\"gray\"><s>Only in " + "consensus:</s></font></b> Flag in consensus, but missing " + "in a vote of a directory authority voting on this " + "flag</li>\n" + " <li><b><font color=\"blue\">In " + "consensus:</font></b> Flag in consensus</li>\n" + " </ul>\n" + " <br>\n" + " <p>See also the summary below the table.</p>\n" + " <table border=\"0\" cellpadding=\"4\" " + "cellspacing=\"0\" summary=\"\">\n" + " <colgroup>\n" + " <col width=\"120\">\n" + " <col width=\"80\">\n"); for (int i = 0; i < allKnownVotes.size(); i++) { bw.write(" <col width=\"" + (640 / allKnownVotes.size()) + "\">\n"); } bw.write(" </colgroup>\n"); int linesWritten = 0; for (Map.Entry<String, SortedSet<String>> e : votesAssignedFlags.entrySet()) { if (linesWritten++ % 10 == 0) { bw.write(" <tr><td><br><b>Fingerprint</b></td>" + "<td><br><b>Nickname</b></td>\n"); for (String dir : allKnownVotes) { String shortDirName = dir.length() > 6 ? dir.substring(0, 5) + "." : dir; bw.write("<td><br><b>" + shortDirName + "</b></td>"); } bw.write("<td><br><b>consensus</b></td></tr>\n"); } String relayKey = e.getKey(); SortedSet<String> votes = e.getValue(); String fingerprint = relayKey.split(" ")[0].substring(0, 8); String nickname = relayKey.split(" ")[1]; bw.write(" <tr>\n"); if (consensusAssignedFlags.containsKey(relayKey) && consensusAssignedFlags.get(relayKey).contains(" Named") && !Character.isDigit(nickname.charAt(0))) { bw.write(" <td id=\"" + nickname + "\"><a href=\"relay.html?fingerprint=" + relayKey.split(" ")[0] + "\" target=\"_blank\">" + fingerprint + "</a></td>\n"); } else { bw.write(" <td><a href=\"relay.html?fingerprint=" + fingerprint + "\" target=\"_blank\">" + fingerprint + "</a></td>\n"); } bw.write(" <td>" + nickname + "</td>\n"); SortedSet<String> relevantFlags = new TreeSet<String>(); for (String vote : votes) { String[] parts = vote.split(" "); for (int j = 2; j < parts.length; j++) { relevantFlags.add(parts[j]); } } String consensusFlags = null; if (consensusAssignedFlags.containsKey(relayKey)) { consensusFlags = consensusAssignedFlags.get(relayKey); String[] parts = consensusFlags.split(" "); for (int j = 1; j < parts.length; j++) { relevantFlags.add(parts[j]); } } for (String dir : allKnownVotes) { String flags = null; for (String vote : votes) { if (vote.startsWith(dir)) { flags = vote; break; } } if (flags != null) { votes.remove(flags); bw.write(" <td>"); int flagsWritten = 0; for (String flag : relevantFlags) { bw.write(flagsWritten++ > 0 ? "<br>" : ""); SortedMap<String, SortedMap<String, Integer>> sums = null; if (flags.contains(" " + flag)) { if (consensusFlags == null || consensusFlags.contains(" " + flag)) { bw.write(flag); sums = flagsAgree; } else { bw.write("<font color=\"red\">" + flag + "</font>"); sums = flagsLost; } } else if (consensusFlags != null && votesKnownFlags.get(dir).contains(" " + flag) && consensusFlags.contains(" " + flag)) { bw.write("<font color=\"gray\"><s>" + flag + "</s></font>"); sums = flagsMissing; } if (sums != null) { SortedMap<String, Integer> sum = null; if (sums.containsKey(dir)) { sum = sums.get(dir); } else { sum = new TreeMap<String, Integer>(); sums.put(dir, sum); } sum.put(flag, sum.containsKey(flag) ? sum.get(flag) + 1 : 1); } } bw.write("</td>\n"); } else { bw.write(" <td></td>\n"); } } if (consensusFlags != null) { bw.write(" <td>"); int flagsWritten = 0; for (String flag : relevantFlags) { bw.write(flagsWritten++ > 0 ? "<br>" : ""); if (consensusFlags.contains(" " + flag)) { bw.write("<font color=\"blue\">" + flag + "</font>"); } } bw.write("</td>\n"); } else { bw.write(" <td></td>\n"); } bw.write(" </tr>\n"); } bw.write(" </table>\n"); /* Write summary of overlap between votes and consensus. */ bw.write(" <br>\n" + " <h3>Overlap between votes and consensus</h3>\n" + " <br>\n" + " <p>The semantics of columns is similar to the " + "table above:</p>\n" + " <ul>\n" + " <li><b>In vote and consensus:</b> Flag in vote " + "matches flag in consensus, or relay is not listed in " + "consensus (because it doesn't have the Running " + "flag)</li>\n" + " <li><b><font color=\"red\">Only in " + "vote:</font></b> Flag in vote, but missing in the " + "consensus, because there was no majority for the flag or " + "the flag was invalidated (e.g., Named gets invalidated by " + "Unnamed)</li>\n" + " <li><b><font color=\"gray\"><s>Only in " + "consensus:</s></font></b> Flag in consensus, but missing " + "in a vote of a directory authority voting on this " + "flag</li>\n" + " </ul>\n" + " <br>\n" + " <table border=\"0\" cellpadding=\"4\" " + "cellspacing=\"0\" summary=\"\">\n" + " <colgroup>\n" + " <col width=\"160\">\n" + " <col width=\"210\">\n" + " <col width=\"210\">\n" + " <col width=\"210\">\n" + " </colgroup>\n"); bw.write(" <tr><td></td><td><b>Only in vote</b></td>" + "<td><b>In vote and consensus</b></td>" + "<td><b>Only in consensus</b></td>\n"); for (String dir : allKnownVotes) { boolean firstFlagWritten = false; String[] flags = votesKnownFlags.get(dir).substring("known-flags ".length()).split(" "); for (String flag : flags) { bw.write(" <tr>\n"); if (firstFlagWritten) { bw.write(" <td></td>\n"); } else { bw.write(" <td>" + dir + "</td>\n"); firstFlagWritten = true; } if (flagsLost.containsKey(dir) && flagsLost.get(dir).containsKey(flag)) { bw.write(" <td><font color=\"red\"> " + flagsLost.get(dir).get(flag) + " " + flag + "</font></td>\n"); } else { bw.write(" <td></td>\n"); } if (flagsAgree.containsKey(dir) && flagsAgree.get(dir).containsKey(flag)) { bw.write(" <td>" + flagsAgree.get(dir).get(flag) + " " + flag + "</td>\n"); } else { bw.write(" <td></td>\n"); } if (flagsMissing.containsKey(dir) && flagsMissing.get(dir).containsKey(flag)) { bw.write(" <td><font color=\"gray\"><s>" + flagsMissing.get(dir).get(flag) + " " + flag + "</s></font></td>\n"); } else { bw.write(" <td></td>\n"); } bw.write(" </tr>\n"); } } bw.write(" </table>\n"); /* Finish writing. */ bw.write(" </div>\n" + " </div>\n" + " <div class=\"bottom\" id=\"bottom\">\n" + " <p>This material is supported in part by the " + "National Science Foundation under Grant No. " + "CNS-0959138. Any opinions, finding, and conclusions " + "or recommendations expressed in this material are " + "those of the author(s) and do not necessarily reflect " + "the views of the National Science Foundation.</p>\n" + " <p>\"Tor\" and the \"Onion Logo\" are <a " + "href=\"https://www.torproject.org/docs/trademark-faq.html" + ".en\">" + "registered trademarks</a> of The Tor Project, " + "Inc.</p>\n" + " <p>Data on this site is freely available under a " + "<a href=\"http://creativecommons.org/publicdomain/" + "zero/1.0/\">CC0 no copyright declaration</a>: To the " + "extent possible under law, the Tor Project has waived " + "all copyright and related or neighboring rights in " + "the data. Graphs are licensed under a <a " + "href=\"http://creativecommons.org/licenses/by/3.0/" + "us/\">Creative Commons Attribution 3.0 United States " + "License</a>.</p>\n" + " </div>\n" + " </body>\n" + "</html>"); bw.close(); } catch (IOException e) { } }
From source file:pl.edu.agh.samm.metrics.SuggestedMetricsComputationEngineImpl.java
private void addCorrelation(IMetric metricOne, IMetric metricTwo, double correlation) { if (!metricsWithCorrelation.containsKey(metricOne)) { metricsWithCorrelation.put(metricOne, new TreeSet<MetricWithCorrelation>()); }//from w ww.j ava 2 s. c om SortedSet<MetricWithCorrelation> set = metricsWithCorrelation.get(metricOne); set.add(new MetricWithCorrelation(metricOne, metricTwo, correlation)); if (set.size() > SUGGESTED_METRICS_COUNT) { set.remove(set.first()); } }