MergeDataFiles.java
Go to the documentation of this file.00001 package edu.rice.cs.hpc.data.util;
00002
00003 import java.io.DataInputStream;
00004 import java.io.DataOutputStream;
00005 import java.io.File;
00006 import java.io.FileInputStream;
00007 import java.io.FileNotFoundException;
00008 import java.io.FileOutputStream;
00009 import java.io.IOException;
00010 import java.io.RandomAccessFile;
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 public class MergeDataFiles {
00031
00032 private static final int PAGE_SIZE_GUESS = 4096;
00033
00034 private static final int PROC_POS = 5;
00035 private static final int THREAD_POS = 4;
00036
00037 public enum MergeDataAttribute {SUCCESS_MERGED, SUCCESS_ALREADY_CREATED, FAIL_NO_DATA};
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 static public MergeDataAttribute merge(File directory, String globInputFile, String outputFile, IProgressReport progress)
00050 throws IOException, FileNotFoundException {
00051
00052 final int last_dot = globInputFile.lastIndexOf('.');
00053 final String suffix = globInputFile.substring(last_dot);
00054
00055 final File fout = new File(outputFile);
00056
00057
00058 if (fout.canRead() )
00059 {
00060 if (isMergedFileCorrect(outputFile))
00061 return MergeDataAttribute.SUCCESS_ALREADY_CREATED;
00062
00063 throw new RuntimeException("MT file corrupted.");
00064 }
00065
00066
00067 File[] file_metric = directory.listFiles( new Util.FileThreadsMetricFilter(globInputFile) );
00068 if (file_metric == null || file_metric.length<1)
00069 return MergeDataAttribute.FAIL_NO_DATA;
00070
00071 FileOutputStream fos = new FileOutputStream(outputFile);
00072 DataOutputStream dos = new DataOutputStream(fos);
00073
00074
00075
00076
00077
00078
00079
00080 int type = 0;
00081 dos.writeInt(type);
00082
00083 progress.begin("Merging data files ...", file_metric.length);
00084
00085
00086 java.util.Arrays.sort(file_metric);
00087
00088 dos.writeInt(file_metric.length);
00089
00090 final long num_metric_header = 2 * Constants.SIZEOF_INT;
00091 final long num_metric_index = file_metric.length * (Constants.SIZEOF_LONG + 2 * Constants.SIZEOF_INT );
00092 long offset = num_metric_header + num_metric_index;
00093
00094 int name_format = 0;
00095
00096
00097
00098
00099
00100
00101
00102
00103 for(int i = 0; i < file_metric.length; ++i)
00104 {
00105
00106 final String filename = file_metric[i].getName();
00107 final int last_pos_basic_name = filename.length() - suffix.length();
00108 final String basic_name = file_metric[i].getName().substring(0, last_pos_basic_name);
00109 String []tokens = basic_name.split("-");
00110
00111 final int num_tokens = tokens.length;
00112 if (num_tokens < PROC_POS)
00113
00114 continue;
00115
00116 int proc ;
00117 try {
00118 proc = Integer.parseInt(tokens[name_format + num_tokens-PROC_POS]);
00119 } catch (NumberFormatException e) {
00120
00121 name_format = 1;
00122 proc = Integer.parseInt(tokens[name_format + num_tokens-PROC_POS]);
00123 }
00124 dos.writeInt(proc);
00125 if (proc != 0)
00126 type |= Constants.MULTI_PROCESSES;
00127
00128 final int thread = Integer.parseInt(tokens[name_format + num_tokens-THREAD_POS]);
00129 dos.writeInt(thread);
00130 if (thread != 0)
00131 type |= Constants.MULTI_THREADING;
00132
00133
00134 dos.writeLong(offset);
00135 offset += file_metric[i].length();
00136
00137 }
00138
00139
00140
00141
00142 for(int i = 0; i < file_metric.length; ++i) {
00143 DataInputStream dis = new DataInputStream(new FileInputStream(file_metric[i]));
00144 byte[] data = new byte[PAGE_SIZE_GUESS];
00145
00146 int numRead = dis.read(data);
00147 while(numRead > 0) {
00148 dos.write(data, 0, numRead);
00149 numRead = dis.read(data);
00150 }
00151 dis.close();
00152
00153 progress.advance();
00154 }
00155 insertMarker(dos);
00156
00157 dos.close();
00158
00159
00160
00161
00162
00163
00164 RandomAccessFile f = new RandomAccessFile(outputFile, "rw");
00165 f.writeInt(type);
00166 f.close();
00167
00168
00169
00170
00171 removeFiles(file_metric);
00172
00173 progress.end();
00174
00175 return MergeDataAttribute.SUCCESS_MERGED;
00176
00177 }
00178
00179
00180
00181
00182
00183
00184
00186 static private long MARKER_END_MERGED_FILE = 0xFFFFFFFFDEADF00Dl;
00187
00188
00189
00190
00191
00192
00193 static private void insertMarker(DataOutputStream dos) throws IOException
00194 {
00195 dos.writeLong(MARKER_END_MERGED_FILE);
00196 }
00197
00198
00199
00200
00201
00202
00203
00204
00205 static private boolean isMergedFileCorrect(String filename) throws IOException
00206 {
00207 final RandomAccessFile f = new RandomAccessFile(filename, "r");
00208 boolean isCorrect = false;
00209
00210 final long pos = f.length() - Constants.SIZEOF_LONG;
00211 if (pos>0) {
00212 f.seek(pos);
00213 final long marker = f.readLong();
00214 isCorrect = (marker == MARKER_END_MERGED_FILE);
00215 }
00216 f.close();
00217 return isCorrect;
00218 }
00219
00220 static private boolean removeFiles(File files[])
00221 {
00222 boolean success = true;
00223
00224 for(File file: files) {
00225 success &= file.delete();
00226 }
00227
00228 return success;
00229 }
00230 }