patternjavaMinor
Log file processor - Programming Contest
Viewed 0 times
filelogprocessorprogrammingcontest
Problem
Problem Description
A profiler is a tool which provides information about run-time
performance of an application. Lets say. you are given output file
format of a profiler called Jensor. Jensor captures response times of
methods executed by capturing method entry and exit events. The entry
and exit events are written to a log file. The log file is then
processed to form a Call Trace. A Call Trace is a who called whom and
when relationship. For simplicity, let us assume that the application
which is profiled using Jensor is single threaded.
Your task is to create a Call Trace given a Jensor log file.
Sample
Pseudo Code
JensorProfile.txt
where,
Column 1 is name of the event. Possible events {Enter, Exit}
Column 2 is name of the method which is entered into or exited out of
Column 3 is time in
A profiler is a tool which provides information about run-time
performance of an application. Lets say. you are given output file
format of a profiler called Jensor. Jensor captures response times of
methods executed by capturing method entry and exit events. The entry
and exit events are written to a log file. The log file is then
processed to form a Call Trace. A Call Trace is a who called whom and
when relationship. For simplicity, let us assume that the application
which is profiled using Jensor is single threaded.
Your task is to create a Call Trace given a Jensor log file.
Sample
Pseudo Code
main()
{
call A();
call B();
call C();
loop(0 to 3, iterate by 1){
call D();
}
sleep(20);
}
A(){
call B();
sleep(10);
}
B(){
sleep(20);
}
C(){
call A();
}
D(){
call B();
}JensorProfile.txt
Enter,main(),1345482572920,0,2 MB
Enter,A(),1345482572920,0,2 MB
Enter,B(),1345482572920,0,2 MB
Exit,B(),1345482572951,0,2 MB
Exit,A(),1345482572967,0,2 MB
Enter,B(),1345482572967,0,2 MB
Exit,B(),1345482572998,0,2 MB
Enter,C(),1345482572998,0,2 MB
Enter,A(),1345482572998,0,2 MB
Enter,B(),1345482572998,0,2 MB
Exit,B(),1345482573029,0,2 MB
Exit,A(),1345482573045,0,2 MB
Exit,C(),1345482573045,0,2 MB
Enter,D(),1345482573045,0,2 MB
Enter,B(),1345482573045,0,2 MB
Exit,B(),1345482573076,0,2 MB
Exit,D(),1345482573076,0,2 MB
Enter,D(),1345482573076,0,2 MB
Enter,B(),1345482573076,0,2 MB
Exit,B(),1345482573096,0,2 MB
Exit,D(),1345482573096,0,2 MB
Enter,D(),1345482573096,0,2 MB
Enter,B(),1345482573096,0,2 MB
Exit,B(),1345482573116,0,2 MB
Exit,D(),1345482573116,0,2 MB
Enter,D(),1345482573116,0,2 MB
Enter,B(),1345482573116,0,2 MB
Exit,B(),1345482573136,0,2 MB
Exit,D(),1345482573136,0,2 MB
Exit,main(),1345482573156,1,2 MBwhere,
Column 1 is name of the event. Possible events {Enter, Exit}
Column 2 is name of the method which is entered into or exited out of
Column 3 is time in
Solution
Unit testing
It's good to convert that
Now you can add unit tests:
Input validation
On one hand it's "nice" that you validate input. But if it's not part of the specification, I think it's safe to assume that the program will receive correct inputs.
Does the contest environment expect the text "Invalid Input"? If yes, then it you could move this string to a constant, especially because you repeated it twice in the code.
If the problem description doesn't specify error handling, then I think you can omit it, and let all the exceptions just bubble up all the way to
Similarly, in here:
The null check is unnecessary. And if it was, then since you already assigned
Naming
Minor things
Instead of this:
It's better to eliminate the duplicated
The empty constructor of
I don't really understand why you suppress this warning:
Why not just make those static fields final?
You forgot to close the
It's good to convert that
main method to make your implementation testable:public static String perform(Scanner sc) {
try {
String logFileName = sc.nextLine();
int functionNumber = sc.nextInt();
return new JensorLogProcessor().getDetailsOfFunctionFromFile(logFileName, functionNumber);
} catch (NoSuchElementException | InvalidInputException e){
return "Invalid Input";
}
}
public static void main(String[] args) {
System.out.println(perform(new Scanner(System.in)));
}Now you can add unit tests:
public class JensorLogProcessorTest {
@Test
public void testSample1() {
assertEquals("D()\n20\n4", JensorLogProcessor.process(new Scanner("/tmp/JensorProfile.txt\n10")));
}
@Test
public void testSample2() {
assertEquals("C()\n47\n2", JensorLogProcessor.process(new Scanner("/tmp/JensorProfile.txt\n5")));
}
@Test
public void testInvalidInput() throws IOException {
assertEquals("Invalid Input", JensorLogProcessor.process(new Scanner("/tmp/JensorProfile.txt\na")));
}
}Input validation
On one hand it's "nice" that you validate input. But if it's not part of the specification, I think it's safe to assume that the program will receive correct inputs.
Does the contest environment expect the text "Invalid Input"? If yes, then it you could move this string to a constant, especially because you repeated it twice in the code.
If the problem description doesn't specify error handling, then I think you can omit it, and let all the exceptions just bubble up all the way to
main.Similarly, in here:
if(null != functionDesc[0]) switch (enterOrExit) {The null check is unnecessary. And if it was, then since you already assigned
functionDesc[0] to enterOrExit, it would have been better this way:if(null != enterOrExit) switch (enterOrExit) {Naming
numberOfFunctionCalled is not a great name for a mapping of function names to invocation counts. Perhaps functionInvocationCounts would be better.JensorObject is not a great name for function invocation details. Perhaps FunctionInvocationInfo would be better.Minor things
Instead of this:
String line = reader.readLine();
while (line != null) {
parseFunctionAndProcess(line);
line = reader.readLine();
}It's better to eliminate the duplicated
.readLine call:String line;
while ((line = reader.readLine()) != null) {
parseFunctionAndProcess(line);
}The empty constructor of
JensorLogProcessor is pointless, you can delete it.I don't really understand why you suppress this warning:
@SuppressWarnings("FieldMayBeFinal")
private static Deque stack = new ArrayDeque<>();
private static List listOfProcesses = new ArrayList<>();
private static Map numberOfFunctionCalled = new HashMap<>();Why not just make those static fields final?
You forgot to close the
BufferedReader in parseLogFile.Code Snippets
public static String perform(Scanner sc) {
try {
String logFileName = sc.nextLine();
int functionNumber = sc.nextInt();
return new JensorLogProcessor().getDetailsOfFunctionFromFile(logFileName, functionNumber);
} catch (NoSuchElementException | InvalidInputException e){
return "Invalid Input";
}
}
public static void main(String[] args) {
System.out.println(perform(new Scanner(System.in)));
}public class JensorLogProcessorTest {
@Test
public void testSample1() {
assertEquals("D()\n20\n4", JensorLogProcessor.process(new Scanner("/tmp/JensorProfile.txt\n10")));
}
@Test
public void testSample2() {
assertEquals("C()\n47\n2", JensorLogProcessor.process(new Scanner("/tmp/JensorProfile.txt\n5")));
}
@Test
public void testInvalidInput() throws IOException {
assertEquals("Invalid Input", JensorLogProcessor.process(new Scanner("/tmp/JensorProfile.txt\na")));
}
}if(null != functionDesc[0]) switch (enterOrExit) {if(null != enterOrExit) switch (enterOrExit) {String line = reader.readLine();
while (line != null) {
parseFunctionAndProcess(line);
line = reader.readLine();
}Context
StackExchange Code Review Q#58923, answer score: 2
Revisions (0)
No revisions yet.