/** write out the data from the profile to the stream */ public void writeProfile(PeerProfile profile) { if (isExpired(profile.getLastSendSuccessful())) return; File f = pickFile(profile); long before = _context.clock().now(); OutputStream fos = null; try { fos = new BufferedOutputStream(new GZIPOutputStream(new SecureFileOutputStream(f))); writeProfile(profile, fos); } catch (IOException ioe) { _log.error("Error writing profile to " + f); } finally { if (fos != null) try { fos.close(); } catch (IOException ioe) { } } long delay = _context.clock().now() - before; if (_log.shouldLog(Log.DEBUG)) _log.debug("Writing the profile to " + f.getName() + " took " + delay + "ms"); }
/** write out the data from the profile to the stream */ public void writeProfile(PeerProfile profile, OutputStream out) throws IOException { String groups = null; if (_context.profileOrganizer().isFailing(profile.getPeer())) { groups = "Failing"; } else if (!_context.profileOrganizer().isHighCapacity(profile.getPeer())) { groups = "Standard"; } else { if (_context.profileOrganizer().isFast(profile.getPeer())) groups = "Fast, High Capacity"; else groups = "High Capacity"; if (_context.profileOrganizer().isWellIntegrated(profile.getPeer())) groups = groups + ", Integrated"; } StringBuilder buf = new StringBuilder(512); buf.append("########################################################################") .append(NL); buf.append("# Profile for peer ").append(profile.getPeer().toBase64()).append(NL); if (_us != null) buf.append("# as calculated by ").append(_us.toBase64()).append(NL); buf.append("#").append(NL); buf.append("# Speed: ").append(profile.getSpeedValue()).append(NL); buf.append("# Capacity: ").append(profile.getCapacityValue()).append(NL); buf.append("# Integration: ").append(profile.getIntegrationValue()).append(NL); buf.append("# Groups: ").append(groups).append(NL); buf.append("#").append(NL); buf.append("########################################################################") .append(NL); buf.append("##").append(NL); add(buf, "speedBonus", profile.getSpeedBonus(), "Manual adjustment to the speed score"); add( buf, "capacityBonus", profile.getCapacityBonus(), "Manual adjustment to the capacity score"); add( buf, "integrationBonus", profile.getIntegrationBonus(), "Manual adjustment to the integration score"); addDate( buf, "firstHeardAbout", profile.getFirstHeardAbout(), "When did we first get a reference to this peer?"); addDate( buf, "lastHeardAbout", profile.getLastHeardAbout(), "When did we last get a reference to this peer?"); addDate( buf, "lastHeardFrom", profile.getLastHeardFrom(), "When did we last get a message from the peer?"); addDate( buf, "lastSentToSuccessfully", profile.getLastSendSuccessful(), "When did we last send the peer a message successfully?"); addDate( buf, "lastFailedSend", profile.getLastSendFailed(), "When did we last fail to send a message to the peer?"); add( buf, "tunnelTestTimeAverage", profile.getTunnelTestTimeAverage(), "Moving average as to how fast the peer replies"); add(buf, "tunnelPeakThroughput", profile.getPeakThroughputKBps(), "KBytes/sec"); add(buf, "tunnelPeakTunnelThroughput", profile.getPeakTunnelThroughputKBps(), "KBytes/sec"); add(buf, "tunnelPeakTunnel1mThroughput", profile.getPeakTunnel1mThroughputKBps(), "KBytes/sec"); buf.append(NL); out.write(buf.toString().getBytes()); if (profile.getIsExpanded()) { // only write out expanded data if, uh, we've got it profile.getTunnelHistory().store(out); // profile.getReceiveSize().store(out, "receiveSize"); // profile.getSendSuccessSize().store(out, "sendSuccessSize"); profile.getTunnelCreateResponseTime().store(out, "tunnelCreateResponseTime"); profile.getTunnelTestResponseTime().store(out, "tunnelTestResponseTime"); } if (profile.getIsExpandedDB()) { profile.getDBHistory().store(out); profile.getDbIntroduction().store(out, "dbIntroduction"); profile.getDbResponseTime().store(out, "dbResponseTime"); } }
private File pickFile(PeerProfile profile) { String hash = profile.getPeer().toBase64(); File dir = new File(_profileDir, DIR_PREFIX + hash.charAt(0)); return new File(dir, PREFIX + hash + SUFFIX); }
public PeerProfile readProfile(File file) { Hash peer = getHash(file.getName()); try { if (peer == null) { _log.error("The file " + file.getName() + " is not a valid hash"); return null; } PeerProfile profile = new PeerProfile(_context, peer); Properties props = new Properties(); loadProps(props, file); long lastSentToSuccessfully = getLong(props, "lastSentToSuccessfully"); if (isExpired(lastSentToSuccessfully)) { if (_log.shouldLog(Log.INFO)) _log.info( "Dropping old profile " + file.getName() + ", since we haven't heard from them in a long time"); file.delete(); return null; } else if (file.getName().endsWith(OLD_SUFFIX)) { // migrate to new file name, ignore failure String newName = file.getAbsolutePath(); newName = newName.substring(0, newName.length() - OLD_SUFFIX.length()) + SUFFIX; boolean success = file.renameTo(new File(newName)); if (!success) // new file exists and on Windows? file.delete(); } profile.setCapacityBonus(getLong(props, "capacityBonus")); profile.setIntegrationBonus(getLong(props, "integrationBonus")); profile.setSpeedBonus(getLong(props, "speedBonus")); profile.setLastHeardAbout(getLong(props, "lastHeardAbout")); profile.setFirstHeardAbout(getLong(props, "firstHeardAbout")); profile.setLastSendSuccessful(getLong(props, "lastSentToSuccessfully")); profile.setLastSendFailed(getLong(props, "lastFailedSend")); profile.setLastHeardFrom(getLong(props, "lastHeardFrom")); profile.setTunnelTestTimeAverage(getDouble(props, "tunnelTestTimeAverage")); profile.setPeakThroughputKBps(getDouble(props, "tunnelPeakThroughput")); profile.setPeakTunnelThroughputKBps(getDouble(props, "tunnelPeakTunnelThroughput")); profile.setPeakTunnel1mThroughputKBps(getDouble(props, "tunnelPeakTunnel1mThroughput")); profile.getTunnelHistory().load(props); // In the interest of keeping the in-memory profiles small, // don't load the DB info at all unless there is something interesting there // (i.e. floodfills) // It seems like we do one or two lookups as a part of handshaking? // Not sure, to be researched. if (getLong(props, "dbHistory.successfulLookups") > 1 || getLong(props, "dbHistory.failedlLokups") > 1) { profile.expandDBProfile(); profile.getDBHistory().load(props); profile.getDbIntroduction().load(props, "dbIntroduction", true); profile.getDbResponseTime().load(props, "dbResponseTime", true); } // profile.getReceiveSize().load(props, "receiveSize", true); // profile.getSendSuccessSize().load(props, "sendSuccessSize", true); profile.getTunnelCreateResponseTime().load(props, "tunnelCreateResponseTime", true); profile.getTunnelTestResponseTime().load(props, "tunnelTestResponseTime", true); if (_log.shouldLog(Log.DEBUG)) _log.debug("Loaded the profile for " + peer.toBase64() + " from " + file.getName()); return profile; } catch (Exception e) { if (_log.shouldLog(Log.WARN)) _log.warn("Error loading properties from " + file.getAbsolutePath(), e); file.delete(); return null; } }