TraceReader.java

155 lines | 5.845 kB Blame History Raw Download
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package br.ufrgs.inf.prosoft.approachescomparison.adapter;

import br.ufrgs.inf.prosoft.memoizeit.Method;
import br.ufrgs.inf.prosoft.memoizeit.Occurrence;
import br.ufrgs.inf.prosoft.memoizeit.OccurrenceConcrete;
import br.ufrgs.inf.prosoft.memoizeit.OccurrenceReference;
import br.ufrgs.inf.prosoft.memoizeit.Parameter;
import br.ufrgs.inf.prosoft.trace.Trace;
import br.ufrgs.inf.prosoft.trace.TraceConcrete;
import br.ufrgs.inf.prosoft.trace.TraceReference;
import br.ufrgs.inf.prosoft.trace.Traces;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Stream;

/**
 *
 * @author romulo
 */
public class TraceReader {

    private static final Logger logger = Logger.getLogger(TraceReader.class.getName());

    public static List<Trace> partiallyParseFile(String path) {
        Traces.PATH = path;
        return parseFile(path, true);
    }

    public static List<Trace> parseFile(String path) {
        return parseFile(path, false);
    }

    public static String getLineCount(String path) throws IOException {
        try {
            Process process = Runtime.getRuntime().exec("wc -l " + path);
            Thread.sleep(2000);
            if (process.isAlive()) {
                return "-2";
            }
            InputStream inputStream = process.getInputStream();
            StringBuilder count = new StringBuilder();
            int c;
            while (true) {
                c = inputStream.read();
                if (c == 32 || c == -1 || c == 10) {
                    break;
                }
                count.append((char) c);
            }
            return count.toString();
        } catch (Exception ex) {
        }
        return "-1";
    }

    private static List<Trace> parseFile(String path, boolean partial) {
        List<Trace> traces = new ArrayList<>();
        try {
            logger.log(Level.INFO, "Parsing {0} traces", getLineCount(path));
            Stream<String> lines = Files.lines(Paths.get(path));
            Gson gson = new Gson();
            lines.forEach(new Consumer<String>() {
                int i = 0;

                @Override
                public void accept(String line) {
                    try {
                        Trace trace;
                        if (partial) {
                            trace = gson.fromJson(line, TraceReference.class);
                            ((TraceReference) trace).setIndex(i);
                        } else {
                            trace = gson.fromJson(line, TraceConcrete.class);
                        }
                        traces.add(trace);
                        System.out.print(".");
                        if (i != 0 && i % 100 == 0) {
                            System.out.println();
                        }
                        i++;
                    } catch (JsonSyntaxException e) {
                        if (line.length() > 2000) {
                            line = line.substring(0, 2000);
                        }
                        logger.log(Level.INFO, "\nMalformed Trace {0}: {1}", new Object[]{i, line});
                    }
                }
            });
            System.out.println();
        } catch (IOException ex) {
            logger.log(Level.SEVERE, null, ex);
        }
        return traces;
    }

    public static List<Method> groupByMethods(List<Trace> traces) {
        Map<String, List<Occurrence>> methodNameHasOccurrences = new HashMap<>();
        Set<String> staticMethods = new HashSet<>();
        while (!traces.isEmpty()) {
            Trace trace = traces.remove(0);
            try {
                Occurrence occurrence;
                if (trace instanceof TraceReference) {
                    TraceReference traceReference = (TraceReference) trace;
                    occurrence = new OccurrenceReference(traceReference.getIndex(), trace.getInstance(), trace.getStartTime(), trace.getEndTime());
                } else {
                    List<Parameter> parameters = new ArrayList<>();
                    trace.getParameters().forEach((parameter) -> {
                        parameters.add(new Parameter(parameter.getType(), parameter.getData()));
                    });
                    occurrence = new OccurrenceConcrete(trace.getInstance(), trace.getReturn().getData(), parameters, trace.getStartTime(), trace.getEndTime());
                }
                try {
                    methodNameHasOccurrences.get(trace.getName()).add(occurrence);
                } catch (Exception ex) {
                    List<Occurrence> occurrences = new ArrayList<>();
                    occurrences.add(occurrence);
                    methodNameHasOccurrences.put(trace.getName(), occurrences);
                    if (trace.getModifiers().contains("static")) {
                        staticMethods.add(trace.getName());
                    }
                }
            } catch (Exception e) {
                logger.log(Level.INFO, "Trace discarted: {0}", trace);
            }
        }
        List<Method> methods = new ArrayList<>();
        methodNameHasOccurrences.entrySet().forEach((entry) -> {
            boolean isStatic = staticMethods.contains(entry.getKey());
            methods.add(new Method(entry.getKey(), isStatic, entry.getValue()));
        });
        return methods;
    }
}