From a4c0d3d6d878da55435cb9d9cc8cff6199644199 Mon Sep 17 00:00:00 2001 From: Peter Palfrader Date: Sun, 19 Oct 2003 15:08:35 +0000 Subject: Support random path creation --- src/org/noreply/fancydress/type3/PathSpec.java | 366 +++++++++++++++++++++---- 1 file changed, 312 insertions(+), 54 deletions(-) (limited to 'src/org/noreply/fancydress/type3/PathSpec.java') diff --git a/src/org/noreply/fancydress/type3/PathSpec.java b/src/org/noreply/fancydress/type3/PathSpec.java index cbc608f..9e975c6 100644 --- a/src/org/noreply/fancydress/type3/PathSpec.java +++ b/src/org/noreply/fancydress/type3/PathSpec.java @@ -11,53 +11,125 @@ import java.util.*; public class PathSpec { - String pathSpec; - Path singlePath; + Directory dir; + PathComponent[] pathComponents; + boolean singleLeg; - private String[] tokenize(String path) throws Mix3Exception { - ArrayList nicks = new ArrayList(); - int indexFrom = 0; - int indexOf; - - while ((indexOf = path.indexOf(',', indexFrom)) != -1) { - String v = path.substring(indexFrom, indexOf).trim(); - if (v.equals("")) - throw new Mix3Exception("Invalid path."); - nicks.add( v ); - indexFrom = indexOf + 1; + private class PathComponent { + public final static double GAUSS_STD_DEV = 1.5; + + public final static int TYPE_NICKNAME = 1; + public final static int TYPE_RANDOM = 2; + public final static int TYPE_RANDOM_GAUSS = 3; + public final static int TYPE_CROSSOVER = 4; + int type; + Server byNickname; + int numRandoms; + + public PathComponent(Directory dir, String component) throws Mix3BadArgumentsIllegalPathSpecException { + String c = component.trim(); + if (c.equals("")) + throw new Mix3BadArgumentsIllegalPathSpecException("Invalid path: empty path component"); + char b = c.charAt(0); + + Integer integer; + switch (b) { + case '*' : + try { + integer = new Integer(c.substring(1)); + } catch (NumberFormatException e) { + throw new Mix3BadArgumentsIllegalPathSpecException("Invalid path: illegal path component '"+c+"'"); + } + type = TYPE_RANDOM; + numRandoms = integer.intValue(); + break; + case '~' : + try { + integer = new Integer(c.substring(1)); + } catch (NumberFormatException e) { + throw new Mix3BadArgumentsIllegalPathSpecException("Invalid path: illegal path component '"+c+"'"); + } + type = TYPE_RANDOM_GAUSS; + numRandoms = integer.intValue(); + break; + case '?' : + if (c.length() > 1) + throw new Mix3BadArgumentsIllegalPathSpecException("Invalid path: illegal path component '"+c+"'"); + type = TYPE_RANDOM; + numRandoms = 1; + break; + case ':' : + if (c.length() > 1) + throw new Mix3BadArgumentsIllegalPathSpecException("Invalid path: illegal path component '"+c+"'"); + type = TYPE_CROSSOVER; + break; + default : + Server server = dir.getServer(c); + if (server == null) + throw new Mix3BadArgumentsIllegalPathSpecException("Invalid path: Nickname '"+c+"' not found"); + if (!server.isUseable()) + throw new Mix3BadArgumentsIllegalPathSpecException("Invalid path: Nickname '"+c+"' is not useable"); + byNickname = server; + type = TYPE_NICKNAME; + break; + } } - String v = path.substring(indexFrom).trim(); - if (v.equals("")) - throw new Mix3Exception("Invalid path."); - nicks.add( v ); - String[] result = new String[nicks.size()]; - for (int i=0; i= 0) + throw new Mix3BadArgumentsIllegalPathSpecException("Path is not a valid path: crossover point specified in single leg path."); + } else { + /* full paths may have up to one specified crossover point */ + int crossover = pathSpec.indexOf(':'); + if (crossover >= 0) + if (pathSpec.indexOf(':', crossover+1) >= 0) + throw new Mix3BadArgumentsIllegalPathSpecException("Path is not a valid path: more than one crossover points specified."); + } + + this.pathComponents = parsePath(dir, pathSpec); + } + + private class ServerWithCrossover { + public Server[] servers; + public int crossoverPoint; + + public Server getLastServer() { + return (servers[servers.length - 1]); + } + + public void setLastServer(Server s) { + servers[servers.length - 1] = s; + } + + public Server getSecondToLastServer() { + return (servers[servers.length - 2]); + } + + private void fillInRandoms() throws Mix3PathProblemException { + Server[] recommended = dir.getRecommendedServers(); + for (int i=servers.length-1; i>=0 ; i--) { + if (servers[i] != null) + continue; + ArrayList s = new ArrayList(); + for (int r=0; rpayload. * - * @param dir a directory - * @return path + * We build as many paths as payload.numPackets() requires. + * + * Also we filter acceptable exit nodes according to the payload's + * constraints. + * + * @param payload the payload + * @return paths constructed from the PathSpec */ - public Path getPath() throws Mix3Exception { - return singlePath; + public Path[] getPath(Payload payload) throws Mix3PathProblemException { + if (singleLeg) + throw new IllegalArgumentException("getPath() may not be called for single leg path specs."); + + + ServerWithCrossover[] paths = new ServerWithCrossover[payload.numPackets()]; + for (int i=0; i