1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.loganalysis.parser; 17 18 import com.android.loganalysis.item.MemoryHealthItem; 19 20 import java.io.BufferedReader; 21 import java.io.IOException; 22 import java.util.ArrayList; 23 import java.util.Collections; 24 import java.util.HashMap; 25 import java.util.List; 26 import java.util.Map; 27 import java.util.regex.Matcher; 28 import java.util.regex.Pattern; 29 30 /** 31 * Parses the memory health file generated by the tests. 32 */ 33 public class MemoryHealthParser implements IParser { 34 private Map<String, Map<String, Long>> mForeground; 35 private Map<String, Map<String, Long>> mBackground; 36 private static final Map<String, String> SECTION_MAPPINGS; 37 38 static { 39 Map<String, String> mappings = new HashMap<String, String>(); 40 mappings.put("Average Dalvik Heap", MemoryHealthItem.DALVIK_AVG); 41 mappings.put("Average Native Heap", MemoryHealthItem.NATIVE_AVG); 42 mappings.put("Average PSS", MemoryHealthItem.PSS_AVG); 43 mappings.put("Peak Dalvik Heap", MemoryHealthItem.DALVIK_PEAK); 44 mappings.put("Peak Native Heap", MemoryHealthItem.NATIVE_PEAK); 45 mappings.put("Peak PSS", MemoryHealthItem.PSS_PEAK); 46 47 mappings.put("Average Summary Java Heap", MemoryHealthItem.SUMMARY_JAVA_HEAP_AVG); 48 mappings.put("Average Summary Native Heap", MemoryHealthItem.SUMMARY_NATIVE_HEAP_AVG); 49 mappings.put("Average Summary Code", MemoryHealthItem.SUMMARY_CODE_AVG); 50 mappings.put("Average Summary Stack", MemoryHealthItem.SUMMARY_STACK_AVG); 51 mappings.put("Average Summary Graphics", MemoryHealthItem.SUMMARY_GRAPHICS_AVG); 52 mappings.put("Average Summary Other", MemoryHealthItem.SUMMARY_OTHER_AVG); 53 mappings.put("Average Summary System", MemoryHealthItem.SUMMARY_SYSTEM_AVG); 54 mappings.put("Average Summary Overall Pss", MemoryHealthItem.SUMMARY_OVERALL_PSS_AVG); 55 SECTION_MAPPINGS = Collections.unmodifiableMap(mappings); 56 } 57 58 private static final Pattern COUNT_PATTERN = Pattern.compile("^Count (\\d+)$"); 59 private static final Pattern METRIC_PATTERN = Pattern.compile("^([^:]+): (\\d+)$"); 60 private static final Pattern PROCESS_PATTERN = Pattern.compile("^\\S+$"); 61 62 @Override 63 /** 64 * {@inheritDoc} 65 */ parse(List<String> lines)66 public MemoryHealthItem parse(List<String> lines) { 67 Map<String, Map<String, Long>> currentSection = null; 68 Map<String, Long> currentProcess = new HashMap<String, Long>(); 69 String processName = null; 70 for (String line : lines) { 71 if (line.contains("Foreground")) { // switch to parsing foreground 72 mForeground = new HashMap<String, Map<String, Long>>(); 73 currentSection = mForeground; 74 } else if (line.contains("Background")) { //switch to parsing background 75 mBackground= new HashMap<String, Map<String, Long>>(); 76 currentSection = mBackground; 77 } else if (COUNT_PATTERN.matcher(line).matches()) { 78 // commit current process once we get to count 79 currentProcess.put("count", parseLong(line)); 80 currentSection.put(processName, currentProcess); 81 } else if (METRIC_PATTERN.matcher(line).matches()) { 82 Matcher m = METRIC_PATTERN.matcher(line); 83 m.matches(); 84 Long value = parseLong(m.group(2)); 85 String key = SECTION_MAPPINGS.get(m.group(1)); 86 if (key == null) { 87 continue; 88 } 89 currentProcess.put(key, value); 90 } else if (PROCESS_PATTERN.matcher(line).matches()) { 91 processName = line; 92 currentProcess = new HashMap<String, Long>(); 93 } 94 } 95 96 return new MemoryHealthItem(mForeground, mBackground); 97 } 98 parseLong(String str)99 private long parseLong(String str) { 100 try { 101 return Long.parseLong(str); 102 } catch (NumberFormatException e) { 103 return 0; 104 } 105 } 106 parse(BufferedReader reader)107 public MemoryHealthItem parse(BufferedReader reader) throws IOException { 108 List<String> lines = new ArrayList<String>(); 109 String line = reader.readLine(); 110 while (line != null) { 111 lines.add(line); 112 line = reader.readLine(); 113 } 114 return parse(lines); 115 } 116 } 117