00001 package edu.rice.cs.hpc.data.experiment.extdata;
00002
00003 import java.io.DataOutputStream;
00004 import java.io.IOException;
00005 import java.util.regex.Pattern;
00006
00007
00008 public class Filter {
00009 public static final String PROCESS_THREAD_SEPARATOR = ",";
00010 private final Range process;
00011 private final Range thread;
00012
00013 public Filter(String strForm){
00014 String[] pieces = formattedSplit(strForm);
00015 process = new Range (pieces[0]);
00016 thread = new Range(pieces[1]);
00017
00018 }
00019
00024 private String[] formattedSplit(String strForm) {
00025 String fixing = strForm;
00026
00027
00028 if (fixing.startsWith(PROCESS_THREAD_SEPARATOR))
00029 fixing = "x" + fixing;
00030
00031 if (!fixing.contains(PROCESS_THREAD_SEPARATOR))
00032 fixing = fixing + PROCESS_THREAD_SEPARATOR;
00033
00034 if (fixing.endsWith(PROCESS_THREAD_SEPARATOR))
00035 fixing = fixing + "x";
00036
00037 String[] pieces = fixing.split(Pattern.quote(PROCESS_THREAD_SEPARATOR));
00038 assert pieces.length == 2;
00039 for (int i = 0; i < pieces.length; i++) {
00040
00041 if (pieces[i].startsWith(":"))
00042 pieces[i] = "x" + pieces[i];
00043
00044
00045 if (pieces[i].endsWith(":"))
00046 pieces[i] = pieces[i] + "x";
00047 }
00048
00049 return pieces;
00050 }
00051
00052 Filter(Range process, Range thread){
00053 this.process = process;
00054 this.thread = thread;
00055 }
00056 boolean matches(TraceName name){
00057 return matches(name.process, name.thread);
00058 }
00059 boolean matches (int processNum, int threadNum){
00060 return process.matches(processNum) && thread.matches(threadNum);
00061 }
00062 @Override
00063 public String toString() {
00064 return process + PROCESS_THREAD_SEPARATOR + thread;
00065 }
00066
00067 public static void main(String[] args){
00068 String[] patterns = {"3:7:2,", ",1" ,"1::2,2:4:2", "1:100", ":100", "100:,4"};
00069 String[] messages = {"should match all threads of ranks 3, 5, and 7.",
00070 "will match thread 1 of all processes.",
00071 "will match 1.2, 1.4, 3.2, 3.4, 5.2 ...",
00072 "will match all threads of ranks 1 to 100",
00073 "will match all threads of ranks <=100",
00074 "will match thread 4 of ranks >= 100"};
00075 TraceName[][] tests = {
00076 { new TraceName(2,1), new TraceName(3,2), new TraceName(4,7), new TraceName(10,10)},
00077 { new TraceName(0,1), new TraceName(10,2), new TraceName(999,1), new TraceName(1,7)},
00078 { new TraceName(5,2), new TraceName(3,4), new TraceName(1,1), new TraceName(2,2)},
00079 { new TraceName(0,2), new TraceName(101,4), new TraceName(100,1), new TraceName(201,2)},
00080 { new TraceName(0,2), new TraceName(101,4), new TraceName(100,1), new TraceName(201,2)},
00081 { new TraceName(0,4), new TraceName(101,4), new TraceName(100,1), new TraceName(201,2)}
00082 };
00083 for (int i = 0; i < patterns.length; i++) {
00084 Filter f = new Filter(patterns[i]);
00085 System.out.println(patterns[i] + " decoded to " + f.toString() + " in full form");
00086 System.out.println(messages[i]);
00087 TraceName[] theseTests = tests[i];
00088 for (int j = 0; j < theseTests.length; j++) {
00089 System.out.println(theseTests[j] + (f.matches(theseTests[j])? ": matches" : ": does not match."));
00090 }
00091 }
00092 }
00093
00094 public void serializeSelfToStream(DataOutputStream stream) throws IOException {
00095 process.serializeSelfToStream(stream);
00096 thread.serializeSelfToStream(stream);
00097 }
00098 }
00099
00100 class Range{
00101 private static final int END = Integer.MAX_VALUE;
00102 private static final int START = 0;
00103 final int min, max, stride;
00104 Range(){
00105 min = START;
00106 max = END;
00107 stride = 1;
00108 }
00109 public void serializeSelfToStream(DataOutputStream stream) throws IOException {
00110 stream.writeInt(min);
00111 stream.writeInt(max);
00112 stream.writeInt(stride);
00113 }
00114 Range(int min, int max, int stride){
00115 this.min = min;
00116 this.max = max;
00117 this.stride = stride;
00118 }
00119 public Range(String string) {
00120 String[] pieces =string.split(":");
00121
00122 int min = START;
00123 int max = END;
00124 int stride = 1;
00125 switch (pieces.length){
00126 case 3:
00127 stride = specialParse(pieces[2], stride);
00128 case 2:
00129 max = specialParse(pieces[1], max);
00130 min = specialParse(pieces[0], min);
00131 break;
00132
00133 case 1:
00134 max = specialParse(pieces[0], max);
00135 min = specialParse(pieces[0], min);
00136 break;
00137 }
00138 this.min = min;
00139 this.max = max;
00140 this.stride = stride;
00141 }
00142 private static int specialParse(String string, int defaultValue) {
00143 if (string.length()==0) return defaultValue;
00144 try{
00145 return Integer.parseInt(string);
00146 } catch (NumberFormatException e){
00147 return defaultValue;
00148 }
00149
00150 }
00151 boolean matches (int i){
00152 if (i < min) return false;
00153 if (i > max) return false;
00154 return ((i - min) % stride) == 0;
00155 }
00156 @Override
00157 public String toString() {
00158 return (min == START? "start" : min)+ ":" + (max == END ? "end" : max) + ":"
00159 + stride;
00160 }
00161 }
00162