Author: toad
Date: 2008-06-19 18:49:58 +0000 (Thu, 19 Jun 2008)
New Revision: 20500
Modified:
branches/db4o/freenet/src/freenet/node/NodeClientCore.java
branches/db4o/freenet/src/freenet/support/io/FileUtil.java
branches/db4o/freenet/src/freenet/support/io/FilenameGenerator.java
branches/db4o/freenet/src/freenet/support/io/PersistentTempBucketFactory.java
Log:
Persist the persistent temp bucket factory.
Support moving it from one dir and prefix to another dir and prefix.
Modified: branches/db4o/freenet/src/freenet/node/NodeClientCore.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/NodeClientCore.java 2008-06-19
18:13:56 UTC (rev 20499)
+++ branches/db4o/freenet/src/freenet/node/NodeClientCore.java 2008-06-19
18:49:58 UTC (rev 20500)
@@ -215,7 +215,10 @@
}
});
try {
- persistentTempBucketFactory = new
PersistentTempBucketFactory(new
File(nodeConfig.getString("persistentTempDir")), "freenet-temp-", random,
node.fastWeakRandom);
+ File dir = new
File(nodeConfig.getString("persistentTempDir"));
+ String prefix = "freenet-temp-";
+ persistentTempBucketFactory =
PersistentTempBucketFactory.load(dir, prefix, random, node.fastWeakRandom,
container, node.nodeDBHandle);
+ persistentTempBucketFactory.init(dir, prefix, random,
node.fastWeakRandom);
persistentEncryptedTempBucketFactory = new
PersistentEncryptedTempBucketFactory(persistentTempBucketFactory);
} catch (IOException e2) {
String msg = "Could not find or create persistent
temporary directory";
Modified: branches/db4o/freenet/src/freenet/support/io/FileUtil.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/io/FileUtil.java 2008-06-19
18:13:56 UTC (rev 20499)
+++ branches/db4o/freenet/src/freenet/support/io/FileUtil.java 2008-06-19
18:49:58 UTC (rev 20500)
@@ -182,6 +182,52 @@
return true;
}
+ /**
+ * Like renameTo(), but can move across filesystems, by copying the
data.
+ * @param f
+ * @param file
+ */
+ public static boolean moveTo(File orig, File dest, boolean overwrite) {
+ if(orig.equals(dest))
+ throw new IllegalArgumentException("Huh? the two file
descriptors are the same!");
+ if(!orig.exists()) {
+ throw new IllegalArgumentException("Original doesn't exist!");
+ }
+ if(dest.exists() && overwrite)
+ dest.delete();
+ else {
+ System.err.println("Not overwriting "+dest+" - already
exists moving "+orig);
+ return false;
+ }
+ if(!orig.renameTo(dest)) {
+ // Copy the data
+ InputStream is = null;
+ OutputStream os = null;
+ try {
+ is = new FileInputStream(orig);
+ os = new FileOutputStream(dest);
+ copy(is, os, orig.length());
+ is.close();
+ is = null;
+ os.close();
+ os = null;
+ orig.delete();
+ return true;
+ } catch (IOException e) {
+ dest.delete();
+ Logger.error(FileUtil.class, "Move failed from
"+orig+" to "+dest+" : "+e, e);
+ System.err.println("Move failed from "+orig+"
to "+dest+" : "+e);
+ e.printStackTrace();
+ return false;
+ } finally {
+ Closer.close(is);
+ Closer.close(os);
+ }
+ } else return true;
+ }
+
+
+
public static String sanitize(String s) {
StringBuffer sb = new StringBuffer(s.length());
for(int i=0;i<s.length();i++) {
Modified: branches/db4o/freenet/src/freenet/support/io/FilenameGenerator.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/io/FilenameGenerator.java
2008-06-19 18:13:56 UTC (rev 20499)
+++ branches/db4o/freenet/src/freenet/support/io/FilenameGenerator.java
2008-06-19 18:49:58 UTC (rev 20500)
@@ -12,9 +12,9 @@
public class FilenameGenerator {
- private final Random random;
- private final String prefix;
- private final File tmpDir;
+ private transient Random random;
+ private String prefix;
+ private File tmpDir;
/**
* @param random
@@ -104,4 +104,91 @@
}
}
+ public File getDir() {
+ return tmpDir;
+ }
+
+ /**
+ * Set up the dir and prefix. Note that while we can change the dir and
prefix, we *cannot do so online*,
+ * at least not on Windows.
+ * @param dir
+ * @param prefix
+ */
+ public void init(File dir, String prefix, Random random) throws
IOException {
+ this.random = random;
+ if(tmpDir.equals(dir) && this.prefix.equals(prefix)) {
+ Logger.normal(this, "Initialised FilenameGenerator
successfully - no change in dir and prefix: dir="+dir+" prefix="+prefix);
+ } else if(!tmpDir.equals(dir) && this.prefix.equals(prefix)) {
+ if((!dir.exists()) && tmpDir.renameTo(dir)) {
+ tmpDir = dir;
+ // This will interest the user, since they
changed it.
+ String msg = "Successfully renamed persistent
temporary directory from "+tmpDir+" to "+dir;
+ Logger.error(this, msg);
+ System.err.println(msg);
+ } else {
+ if(!dir.exists()) {
+ if(!dir.mkdir()) {
+ // FIXME localise these errors
somehow??
+ System.err.println("Unable to
create new temporary directory: "+dir);
+ throw new IOException("Unable
to create new temporary directory: "+dir);
+ }
+ }
+ if(!(dir.canRead() && dir.canWrite())) {
+ // FIXME localise these errors somehow??
+ System.err.println("Unable to read and
write new temporary directory: "+dir);
+ throw new IOException("Unable to read
and write new temporary directory: "+dir);
+ }
+ int moved = 0;
+ int failed = 0;
+ // Move each file
+ File[] list = tmpDir.listFiles();
+ for(int i=0;i<list.length;i++) {
+ File f = list[i];
+ String name = f.getName();
+ if(!name.startsWith(prefix)) continue;
+ if(FileUtil.moveTo(f, new File(dir,
name), true))
+ moved++;
+ else
+ failed++;
+ }
+ if(failed > 0) {
+ // FIXME maybe a useralert
+ System.err.println("WARNING: Not all
files successfully moved changing temp dir: "+failed+" failed.");
+ System.err.println("WARNING: Some
persistent downloads etc may fail.");
+ }
+ }
+ } else {
+ if(!dir.exists()) {
+ if(!dir.mkdir()) {
+ // FIXME localise these errors somehow??
+ System.err.println("Unable to create
new temporary directory: "+dir);
+ throw new IOException("Unable to create
new temporary directory: "+dir);
+ }
+ }
+ if(!(dir.canRead() && dir.canWrite())) {
+ // FIXME localise these errors somehow??
+ System.err.println("Unable to read and write
new temporary directory: "+dir);
+ throw new IOException("Unable to read and write
new temporary directory: "+dir);
+ }
+ int moved = 0;
+ int failed = 0;
+ // Move each file
+ File[] list = tmpDir.listFiles();
+ for(int i=0;i<list.length;i++) {
+ File f = list[i];
+ String name = f.getName();
+ if(!name.startsWith(this.prefix)) continue;
+ String newName = prefix +
name.substring(this.prefix.length());
+ if(FileUtil.moveTo(f, new File(dir, newName),
true)) {
+ moved++;
+ }
+ }
+ if(failed > 0) {
+ // FIXME maybe a useralert
+ System.err.println("WARNING: Not all files
successfully moved changing temp dir: "+failed+" failed.");
+ System.err.println("WARNING: Some persistent
downloads etc may fail.");
+ }
+ }
+ }
+
}
Modified:
branches/db4o/freenet/src/freenet/support/io/PersistentTempBucketFactory.java
===================================================================
---
branches/db4o/freenet/src/freenet/support/io/PersistentTempBucketFactory.java
2008-06-19 18:13:56 UTC (rev 20499)
+++
branches/db4o/freenet/src/freenet/support/io/PersistentTempBucketFactory.java
2008-06-19 18:49:58 UTC (rev 20500)
@@ -3,17 +3,20 @@
* http://www.gnu.org/ for further details of the GPL. */
package freenet.support.io;
-import freenet.crypt.RandomSource;
import java.io.File;
import java.io.IOException;
import java.util.HashSet;
-import java.util.Iterator;
import java.util.LinkedList;
+import java.util.Random;
+import com.db4o.ObjectContainer;
+import com.db4o.ObjectSet;
+import com.db4o.query.Predicate;
+
+import freenet.crypt.RandomSource;
import freenet.support.Logger;
import freenet.support.api.Bucket;
import freenet.support.api.BucketFactory;
-import java.util.Random;
/**
* Handles persistent temp files. These are used for e.g. persistent downloads.
@@ -26,9 +29,6 @@
*/
public class PersistentTempBucketFactory implements BucketFactory,
PersistentFileTracker {
- /** Directory containing persistent temporary files */
- private final File dir;
-
/** Original contents of directory */
private HashSet originalFiles;
@@ -36,16 +36,18 @@
private final FilenameGenerator fg;
/** Random number generator */
- private final RandomSource strongPRNG;
- private final Random weakPRNG;
+ private transient RandomSource strongPRNG;
+ private transient Random weakPRNG;
/** Buckets to free */
private LinkedList bucketsToFree;
+
+ private final long nodeDBHandle;
- public PersistentTempBucketFactory(File dir, String prefix,
RandomSource strongPRNG, Random weakPRNG) throws IOException {
+ public PersistentTempBucketFactory(File dir, String prefix,
RandomSource strongPRNG, Random weakPRNG, long nodeDBHandle) throws IOException
{
boolean logMINOR = Logger.shouldLog(Logger.MINOR, this);
- this.dir = dir;
this.strongPRNG = strongPRNG;
+ this.nodeDBHandle = nodeDBHandle;
this.weakPRNG = weakPRNG;
this.fg = new FilenameGenerator(weakPRNG, false, dir, prefix);
if(!dir.exists()) {
@@ -78,6 +80,12 @@
bucketsToFree = new LinkedList();
}
+ public void init(File dir, String prefix, RandomSource strongPRNG,
Random weakPRNG) throws IOException {
+ this.strongPRNG = strongPRNG;
+ this.weakPRNG = weakPRNG;
+ fg.init(dir, prefix, weakPRNG);
+ }
+
public void register(File file) {
synchronized(this) {
if(originalFiles == null)
@@ -139,7 +147,7 @@
}
public File getDir() {
- return dir;
+ return fg.getDir();
}
public FilenameGenerator getGenerator() {
@@ -154,4 +162,19 @@
return fg.getID(file);
}
+ public static PersistentTempBucketFactory load(File dir, String prefix,
RandomSource random, Random fastWeakRandom, ObjectContainer container, final
long nodeDBHandle) throws IOException {
+ ObjectSet results = container.query(new Predicate() {
+ public boolean match(PersistentTempBucketFactory
factory) {
+ if(factory.nodeDBHandle == nodeDBHandle) return
true;
+ return false;
+ }
+ });
+ if(results.hasNext()) {
+ PersistentTempBucketFactory factory =
(PersistentTempBucketFactory) results.next();
+ factory.init(dir, prefix, random, fastWeakRandom);
+ return factory;
+ } else
+ return new PersistentTempBucketFactory(dir, prefix,
random, fastWeakRandom, nodeDBHandle);
+ }
+
}