I2P Address: [http://git.idk.i2p]

Skip to content
Snippets Groups Projects
Commit c8f2effc authored by zzz's avatar zzz
Browse files

* Profiles: Split up files into subdirectories

parent 74f4859e
No related branches found
No related tags found
No related merge requests found
...@@ -8,8 +8,10 @@ import java.io.FilenameFilter; ...@@ -8,8 +8,10 @@ import java.io.FilenameFilter;
import java.io.InputStream; import java.io.InputStream;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Properties; import java.util.Properties;
import java.util.Set; import java.util.Set;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
...@@ -19,6 +21,7 @@ import net.i2p.data.Base64; ...@@ -19,6 +21,7 @@ import net.i2p.data.Base64;
import net.i2p.data.DataHelper; import net.i2p.data.DataHelper;
import net.i2p.data.Hash; import net.i2p.data.Hash;
import net.i2p.router.RouterContext; import net.i2p.router.RouterContext;
import net.i2p.util.FileUtil;
import net.i2p.util.Log; import net.i2p.util.Log;
import net.i2p.util.SecureDirectory; import net.i2p.util.SecureDirectory;
import net.i2p.util.SecureFileOutputStream; import net.i2p.util.SecureFileOutputStream;
...@@ -41,6 +44,8 @@ class ProfilePersistenceHelper { ...@@ -41,6 +44,8 @@ class ProfilePersistenceHelper {
private static final String SUFFIX = ".txt.gz"; private static final String SUFFIX = ".txt.gz";
private static final String UNCOMPRESSED_SUFFIX = ".txt"; private static final String UNCOMPRESSED_SUFFIX = ".txt";
private static final String OLD_SUFFIX = ".dat"; private static final String OLD_SUFFIX = ".dat";
private static final String DIR_PREFIX = "p";
private static final String B64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-~";
/** /**
* If we haven't been able to get a message through to the peer in 3 days, * If we haven't been able to get a message through to the peer in 3 days,
...@@ -48,19 +53,22 @@ class ProfilePersistenceHelper { ...@@ -48,19 +53,22 @@ class ProfilePersistenceHelper {
* have changed (etc). * have changed (etc).
* *
*/ */
public static final long EXPIRE_AGE = 3*24*60*60*1000; private static final long EXPIRE_AGE = 3*24*60*60*1000;
private File _profileDir = null; private final File _profileDir;
private Hash _us; private Hash _us;
public ProfilePersistenceHelper(RouterContext ctx) { public ProfilePersistenceHelper(RouterContext ctx) {
_context = ctx; _context = ctx;
_log = ctx.logManager().getLog(ProfilePersistenceHelper.class); _log = ctx.logManager().getLog(ProfilePersistenceHelper.class);
File profileDir = getProfileDir(); String dir = _context.getProperty(PROP_PEER_PROFILE_DIR, DEFAULT_PEER_PROFILE_DIR);
_us = null; _profileDir = new SecureDirectory(_context.getRouterDir(), dir);
if (!profileDir.exists()) { if (!_profileDir.exists())
profileDir.mkdirs(); _profileDir.mkdirs();
_log.info("Profile directory " + profileDir.getAbsolutePath() + " created"); for (int j = 0; j < B64.length(); j++) {
File subdir = new SecureDirectory(_profileDir, DIR_PREFIX + B64.charAt(j));
if (!subdir.exists())
subdir.mkdir();
} }
} }
...@@ -169,7 +177,7 @@ class ProfilePersistenceHelper { ...@@ -169,7 +177,7 @@ class ProfilePersistenceHelper {
public Set<PeerProfile> readProfiles() { public Set<PeerProfile> readProfiles() {
long start = _context.clock().now(); long start = _context.clock().now();
Set<File> files = selectFiles(); List<File> files = selectFiles();
Set<PeerProfile> profiles = new HashSet(files.size()); Set<PeerProfile> profiles = new HashSet(files.size());
for (File f : files) { for (File f : files) {
PeerProfile profile = readProfile(f); PeerProfile profile = readProfile(f);
...@@ -182,18 +190,44 @@ class ProfilePersistenceHelper { ...@@ -182,18 +190,44 @@ class ProfilePersistenceHelper {
return profiles; return profiles;
} }
private Set<File> selectFiles() { private static class ProfileFilter implements FilenameFilter {
File files[] = getProfileDir().listFiles(new FilenameFilter() { public boolean accept(File dir, String filename) {
public boolean accept(File dir, String filename) { return (filename.startsWith(PREFIX) &&
return (filename.startsWith(PREFIX) && (filename.endsWith(SUFFIX) || filename.endsWith(OLD_SUFFIX) || filename.endsWith(UNCOMPRESSED_SUFFIX)));
(filename.endsWith(SUFFIX) || filename.endsWith(OLD_SUFFIX) || filename.endsWith(UNCOMPRESSED_SUFFIX))); }
} }
});
Set rv = new HashSet(files.length); private List<File> selectFiles() {
for (int i = 0; i < files.length; i++) FilenameFilter filter = new ProfileFilter();
rv.add(files[i]); File files[] = _profileDir.listFiles(filter);
if (files != null && files.length > 0)
migrate(files);
List rv = new ArrayList(1024);
for (int j = 0; j < B64.length(); j++) {
File subdir = new File(_profileDir, DIR_PREFIX + B64.charAt(j));
files = subdir.listFiles(filter);
if (files == null)
continue;
for (int i = 0; i < files.length; i++)
rv.add(files[i]);
}
return rv; return rv;
} }
/**
* Migrate from one-level to two-level directory structure
* @since 0.9.4
*/
private void migrate(File[] files) {
for (int i = 0; i < files.length; i++) {
File from = files[i];
if (!from.isFile())
continue;
File dir = new File(_profileDir, DIR_PREFIX + from.getName().charAt(PREFIX.length()));
File to = new File(dir, from.getName());
FileUtil.rename(from, to);
}
}
private boolean isExpired(long lastSentToSuccessfully) { private boolean isExpired(long lastSentToSuccessfully) {
long timeSince = _context.clock().now() - lastSentToSuccessfully; long timeSince = _context.clock().now() - lastSentToSuccessfully;
...@@ -342,16 +376,11 @@ class ProfilePersistenceHelper { ...@@ -342,16 +376,11 @@ class ProfilePersistenceHelper {
} }
private File pickFile(PeerProfile profile) { private File pickFile(PeerProfile profile) {
return new File(getProfileDir(), PREFIX + profile.getPeer().toBase64() + SUFFIX); String hash = profile.getPeer().toBase64();
File dir = new File(_profileDir, DIR_PREFIX + hash.charAt(0));
return new File(dir, PREFIX + hash + SUFFIX);
} }
private File getProfileDir() {
if (_profileDir == null) {
String dir = _context.getProperty(PROP_PEER_PROFILE_DIR, DEFAULT_PEER_PROFILE_DIR);
_profileDir = new SecureDirectory(_context.getRouterDir(), dir);
}
return _profileDir;
}
/** generate 1000 profiles */ /** generate 1000 profiles */
/**** /****
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment