Author: nextgens
Date: 2008-08-17 08:45:48 +0000 (Sun, 17 Aug 2008)
New Revision: 21945
Modified:
trunk/freenet/src/freenet/node/PeerManager.java
trunk/freenet/src/freenet/node/PeerNode.java
trunk/freenet/src/freenet/node/TestnetHandler.java
Log:
Improve the way peers are written to disk; profiling has shown that it is
important to release the lock early.
BACK YOUR DATA UP before upgrading.
Modified: trunk/freenet/src/freenet/node/PeerManager.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerManager.java 2008-08-16 23:11:40 UTC
(rev 21944)
+++ trunk/freenet/src/freenet/node/PeerManager.java 2008-08-17 08:45:48 UTC
(rev 21945)
@@ -4,7 +4,6 @@
package freenet.node;
import java.io.BufferedReader;
-import java.io.BufferedWriter;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
@@ -14,7 +13,6 @@
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
-import java.io.Writer;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
@@ -1068,6 +1066,7 @@
return sb.toString();
}
private final Object writePeersSync = new Object();
+ private final Object writePeerFileSync = new Object();
void writePeers() {
node.ps.queueTimedJob(new Runnable() {
@@ -1077,25 +1076,83 @@
}
}, 0);
}
+
+ protected StringBuilder getDarknetPeersString() {
+ StringBuilder sb = new StringBuilder();
+ PeerNode[] peers;
+ synchronized(this) {
+ peers = myPeers;
+ }
+ for(PeerNode pn : peers) {
+ if(pn instanceof DarknetPeerNode)
+ sb.append(pn.exportDiskFieldSet());
+ }
+
+ return sb;
+ }
+
+ protected StringBuilder getOpennetPeersString() {
+ StringBuilder sb = new StringBuilder();
+ PeerNode[] peers;
+ synchronized(this) {
+ peers = myPeers;
+ }
+ for(PeerNode pn : peers) {
+ if(pn instanceof OpennetPeerNode)
+ sb.append(pn.exportDiskFieldSet());
+ }
+
+ return sb;
+ }
+
+ protected StringBuilder getOldOpennetPeersString(OpennetManager om) {
+ StringBuilder sb = new StringBuilder();
+ PeerNode[] peers;
+ synchronized(this) {
+ peers = om.getOldPeers();
+ }
+ for(PeerNode pn : peers) {
+ if(pn instanceof OpennetPeerNode)
+ sb.append(pn.exportDiskFieldSet());
+ }
+
+ return sb;
+ }
private void writePeersInner() {
+ StringBuilder darknet = null;
+ StringBuilder opennet = null;
+ StringBuilder oldOpennetPeers = null;
+ String oldOpennetPeersFilename = null;
+
synchronized(writePeersSync) {
if(darkFilename != null)
- writePeersInner(darkFilename,
getDarknetPeers());
+ darknet = getDarknetPeersString();
OpennetManager om = node.getOpennet();
if(om != null) {
if(openFilename != null)
- writePeersInner(openFilename,
getOpennetPeers());
- writePeersInner(om.getOldPeersFilename(),
om.getOldPeers());
+ opennet = getOpennetPeersString();
+ oldOpennetPeersFilename =
om.getOldPeersFilename();
+ oldOpennetPeers = getOldOpennetPeersString(om);
}
}
+
+ synchronized(writePeerFileSync) {
+ if(darknet != null)
+ writePeersInner(darkFilename, darknet);
+ if(oldOpennetPeers != null) {
+ if(opennet != null)
+ writePeersInner(openFilename, opennet);
+ writePeersInner(oldOpennetPeersFilename,
oldOpennetPeers);
+ }
+ }
}
/**
* Write the peers file to disk
*/
- private void writePeersInner(String filename, PeerNode[] peers) {
- synchronized(writePeersSync) {
+ private void writePeersInner(String filename, StringBuilder sb) {
+ synchronized(writePeerFileSync) {
FileOutputStream fos = null;
String f = filename + ".bak";
try {
@@ -1112,13 +1169,11 @@
Closer.close(w);
throw new Error("Impossible: JVM doesn't
support UTF-8: " + e2, e2);
}
- BufferedWriter bw = new BufferedWriter(w);
try {
- boolean succeeded = writePeers(bw, peers);
- bw.close();
- bw = null;
- if(!succeeded)
- return;
+ w.write(sb.toString());
+ w.flush();
+ w.close();
+ w = null;
File fnam = new File(filename);
FileUtil.renameTo(new File(f), fnam);
@@ -1131,38 +1186,12 @@
Logger.error(this, "Cannot write file: " + e,
e);
return; // don't overwrite old file!
} finally {
- Closer.close(bw);
+ Closer.close(w);
Closer.close(fos);
}
}
}
- public boolean writePeers(Writer bw) {
- if(!writePeers(bw, getDarknetPeers()))
- return false;
- if(!writePeers(bw, getOpennetPeers()))
- return false;
- return true;
- }
-
- public boolean writePeers(Writer bw, PeerNode[] peers) {
- for(int i = 0; i < peers.length; i++) {
- try {
- peers[i].write(bw);
- bw.flush();
- } catch(IOException e) {
- try {
- bw.close();
- } catch(IOException e1) {
- Logger.error(this, "Cannot close file!:
" + e1, e1);
- }
- Logger.error(this, "Cannot write peers to disk:
" + e, e);
- return false;
- }
- }
- return true;
- }
-
/**
* Update the numbers needed by our PeerManagerUserAlert on the UAM.
* Also run the node's onConnectedPeers() method if applicable
Modified: trunk/freenet/src/freenet/node/PeerNode.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerNode.java 2008-08-16 23:11:40 UTC
(rev 21944)
+++ trunk/freenet/src/freenet/node/PeerNode.java 2008-08-17 08:45:48 UTC
(rev 21945)
@@ -2564,6 +2564,17 @@
fs.put("metadata", meta);
fs.writeTo(w);
}
+
+ /**
+ * (both metadata + normal fieldset but atomically)
+ */
+ public synchronized SimpleFieldSet exportDiskFieldSet() {
+ SimpleFieldSet fs = exportFieldSet();
+ SimpleFieldSet meta = exportMetadataFieldSet();
+ if(!meta.isEmpty())
+ fs.put("metadata", meta);
+ return fs;
+ }
/**
* Export metadata about the node as a SimpleFieldSet
Modified: trunk/freenet/src/freenet/node/TestnetHandler.java
===================================================================
--- trunk/freenet/src/freenet/node/TestnetHandler.java 2008-08-16 23:11:40 UTC
(rev 21944)
+++ trunk/freenet/src/freenet/node/TestnetHandler.java 2008-08-17 08:45:48 UTC
(rev 21945)
@@ -182,8 +182,6 @@
fs =
node.exportOpennetPublicFieldSet();
fs.writeTo(bw);
}
- bw.write("\n\nMy peers:\n");
- node.peers.writePeers(bw);
bw.close();
}else {
Logger.error(this, "Unknown testnet
command: "+command);