001package daikon.tools; 002 003import daikon.FileIO; 004import daikon.PptMap; 005import daikon.PptTopLevel; 006import daikon.ValueTuple; 007import daikon.VarInfo; 008import java.util.ArrayList; 009import java.util.Arrays; 010import java.util.LinkedHashMap; 011import java.util.List; 012import java.util.Map; 013import org.checkerframework.checker.nullness.qual.Nullable; 014import org.checkerframework.checker.nullness.qual.RequiresNonNull; 015 016/** 017 * A class that gives an example of how to use a FileIO.Processor object to read a trace file. 018 * Invoke it like: 019 * 020 * <pre> 021 * java daikon.tools.ReadTrace file1 file2 ... 022 * </pre> 023 * 024 * A concrete example invocation: 025 * 026 * <pre> 027 * java -cp $DAIKONDIR/daikon.jar daikon.tools.ReadTrace /scratch/$USER/tests/daikon-tests/StackAr/StackAr.dtrace.gz 028 * </pre> 029 * 030 * You probably won't run this program. Instead, you will copy parts of its source code in the 031 * process of writing your own program that reads a dtrace file. 032 */ 033public class ReadTrace { 034 035 /** 036 * The entry point for ReadTrace. 037 * 038 * @param args data trace file names 039 */ 040 public static void main(String[] args) { 041 CollectDataProcessor processor = new CollectDataProcessor(); 042 PptMap ppts = new PptMap(); 043 try { 044 FileIO.read_data_trace_files(Arrays.asList(args), ppts, processor, false); 045 } catch (Exception e) { 046 throw new Error(e); 047 } 048 049 // At this point, the processor has been called on each sample in turn. 050 // Now, we can do whatever we like with the data. 051 052 for (PptTopLevel ppt : processor.samples.keySet()) { 053 for (ValueTuple vt : processor.samples.get(ppt)) { 054 System.out.printf("%nSample for %s :%n", ppt.name()); 055 for (VarInfo vi : ppt.var_infos) { 056 System.out.printf("%s = %s%n", vi.name(), vt.getValueOrNull(vi)); 057 } 058 } 059 } 060 } 061 062 /** 063 * Populates the {@code samples} map with all the data read from the file. This is only reasonable 064 * for small trace files, since all the data will be retained in memory! 065 */ 066 public static class CollectDataProcessor extends FileIO.Processor { 067 068 public Map<PptTopLevel, List<ValueTuple>> samples = new LinkedHashMap<>(); 069 070 /** Process the sample, by adding it to the {@code samples} map. */ 071 @RequiresNonNull("daikon.FileIO.data_trace_state") 072 @Override 073 public void process_sample( 074 PptMap all_ppts, PptTopLevel ppt, ValueTuple vt, @Nullable Integer nonce) { 075 076 // Add orig and derived variables to the ValueTuple 077 FileIO.compute_orig_variables(ppt, vt.vals, vt.mods, nonce); 078 FileIO.compute_derived_variables(ppt, vt.vals, vt.mods); 079 080 // Intern the sample, to save space, since we are storing them all. 081 vt = new ValueTuple(vt.vals, vt.mods); 082 083 // Add the sample to the map 084 if (!samples.containsKey(ppt)) { 085 samples.put(ppt, new ArrayList<ValueTuple>()); 086 } 087 samples.get(ppt).add(vt); 088 } 089 } 090}