1 /* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 package ohos.devtools.services.cpu; 17 18 import ohos.devtools.datasources.utils.profilerlog.ProfilerLogManager; 19 import ohos.devtools.services.LRUCache; 20 import ohos.devtools.views.charts.model.ChartDataModel; 21 import org.apache.logging.log4j.LogManager; 22 import org.apache.logging.log4j.Logger; 23 24 import java.util.HashMap; 25 import java.util.LinkedHashMap; 26 import java.util.List; 27 import java.util.Map; 28 import java.util.concurrent.ConcurrentHashMap; 29 30 /** 31 * CpuDataCache 32 * 33 * @since 2021/5/19 16:39 34 */ 35 public class CpuDataCache { 36 private static final Logger LOGGER = LogManager.getLogger(CpuDataCache.class); 37 private static final float LOAD_FACTOR = 0.75F; 38 private static final int CACHE_MAX_SIZE = 1500; 39 private static CpuDataCache instance = new CpuDataCache(); 40 41 private final Map<Long, LRUCache<List<ChartDataModel>>> cpuDataCacheMap = new ConcurrentHashMap<>(); 42 private final Map<Long, LRUCache<List<ChartDataModel>>> threadDataCacheMap = 43 new ConcurrentHashMap<>(); 44 private final Map<Long, LRUCache<List<ChartDataModel>>> threadDeadCacheMap = 45 new ConcurrentHashMap<>(); 46 private final Map<Long, Long> cpuFirstTsMap = new HashMap<>(); 47 private final Map<Long, Long> threadFirstTsMap = new HashMap<>(); 48 CpuDataCache()49 private CpuDataCache() { 50 } 51 52 /** 53 * Instance getter 54 * 55 * @return MemoryDataCache 56 */ getInstance()57 public static CpuDataCache getInstance() { 58 return instance; 59 } 60 61 /** 62 * Add Cpu data to cache map 63 * 64 * @param sessionId Session id 65 * @param timestamp Timestamp of data 66 * @param dataModels Data model list 67 */ addCpuDataModel(long sessionId, long timestamp, List<ChartDataModel> dataModels)68 public void addCpuDataModel(long sessionId, long timestamp, List<ChartDataModel> dataModels) { 69 if (ProfilerLogManager.isInfoEnabled()) { 70 LOGGER.info("addCpuDataModel"); 71 } 72 LRUCache<List<ChartDataModel>> cache = cpuDataCacheMap.get(sessionId); 73 // If cache map is null, generate the new map and save the current timestamp as first timestamp 74 if (cache == null) { 75 cache = genNewSessionCache(); 76 cpuDataCacheMap.put(sessionId, cache); 77 cpuFirstTsMap.put(sessionId, timestamp); 78 } 79 synchronized (cpuDataCacheMap.get(sessionId)) { 80 // Save relative time 81 int time = (int) (timestamp - cpuFirstTsMap.get(sessionId)); 82 cache.addCaCheData(time, dataModels); 83 // Here we need to sort the map, otherwise the key(timestamp) of the map will be out of order 84 cpuDataCacheMap.put(sessionId, cache); 85 } 86 } 87 88 /** 89 * Add Cpu data to cache map 90 * 91 * @param sessionId Session id 92 * @param timestamp Timestamp of data 93 * @param dataModels Data model list 94 */ addThreadDataModel(long sessionId, long timestamp, List<ChartDataModel> dataModels)95 public void addThreadDataModel(long sessionId, long timestamp, List<ChartDataModel> dataModels) { 96 if (ProfilerLogManager.isInfoEnabled()) { 97 LOGGER.info("addThreadDataModel"); 98 } 99 LRUCache<List<ChartDataModel>> cache = threadDataCacheMap.get(sessionId); 100 // If cache map is null, generate the new map and save the current timestamp as first timestamp 101 if (cache == null) { 102 cache = genNewSessionCache(); 103 threadDataCacheMap.put(sessionId, cache); 104 threadFirstTsMap.put(sessionId, timestamp); 105 } 106 synchronized (threadDataCacheMap.get(sessionId)) { 107 // Save relative time 108 int time = (int) (timestamp - threadFirstTsMap.get(sessionId)); 109 cache.addCaCheData(time, dataModels); 110 threadDataCacheMap.put(sessionId, cache); 111 } 112 } 113 114 /** 115 * Add Cpu data to cache map 116 * 117 * @param sessionId Session id 118 * @param timestamp Timestamp of data 119 * @param dataModels Data model list 120 */ addDeadThreadDataModel(long sessionId, long timestamp, List<ChartDataModel> dataModels)121 public void addDeadThreadDataModel(long sessionId, long timestamp, List<ChartDataModel> dataModels) { 122 if (ProfilerLogManager.isInfoEnabled()) { 123 LOGGER.info("addThreadDataModel"); 124 } 125 LRUCache<List<ChartDataModel>> cache = threadDeadCacheMap.get(sessionId); 126 // If cache map is null, generate the new map and save the current timestamp as first timestamp 127 if (cache == null) { 128 cache = genNewSessionCache(); 129 threadDeadCacheMap.put(sessionId, cache); 130 } 131 synchronized (threadDeadCacheMap.get(sessionId)) { 132 // Save relative time 133 int time = (int) (timestamp - threadFirstTsMap.get(sessionId)); 134 cache.addCaCheData(time, dataModels); 135 threadDeadCacheMap.put(sessionId, cache); 136 } 137 } 138 139 /** 140 * Generate new session cache map 141 * 142 * @return LRUCache <List<ChartDataModel>> 143 */ genNewSessionCache()144 private LRUCache<List<ChartDataModel>> genNewSessionCache() { 145 if (ProfilerLogManager.isInfoEnabled()) { 146 LOGGER.info("genNewSessionCache"); 147 } 148 return new LRUCache<>(); 149 } 150 151 /** 152 * Get cpu data 153 * 154 * @param sessionId Session id 155 * @param startTime start time 156 * @param endTime end time 157 * @return LinkedHashMap <Integer, List<ChartDataModel>> getCpuData 158 */ getCpuData(long sessionId, int startTime, int endTime)159 public LinkedHashMap<Integer, List<ChartDataModel>> getCpuData(long sessionId, int startTime, int endTime) { 160 if (ProfilerLogManager.isInfoEnabled()) { 161 LOGGER.info("getCpuData"); 162 } 163 LinkedHashMap<Integer, List<ChartDataModel>> result = new LinkedHashMap<>(); 164 LRUCache<List<ChartDataModel>> cache = cpuDataCacheMap.get(sessionId); 165 if (cache == null) { 166 return result; 167 } 168 synchronized (cpuDataCacheMap.get(sessionId)) { 169 result = cache.getCaCheData(startTime, endTime); 170 } 171 return result; 172 } 173 174 /** 175 * Get thread data 176 * 177 * @param sessionId Session id 178 * @param startTime start time 179 * @param endTime end time 180 * @return LinkedHashMap <Integer, List<ChartDataModel>> getCpuData 181 */ getThreadData(long sessionId, int startTime, int endTime)182 public LinkedHashMap<Integer, List<ChartDataModel>> getThreadData(long sessionId, int startTime, int endTime) { 183 if (ProfilerLogManager.isInfoEnabled()) { 184 LOGGER.info("getThreadData"); 185 } 186 LinkedHashMap<Integer, List<ChartDataModel>> result = new LinkedHashMap<>(); 187 LRUCache<List<ChartDataModel>> cache = threadDataCacheMap.get(sessionId); 188 if (cache == null) { 189 return result; 190 } 191 synchronized (threadDataCacheMap.get(sessionId)) { 192 result = cache.getCaCheData(startTime, endTime); 193 } 194 return result; 195 } 196 197 198 /** 199 * Get thread data 200 * 201 * @param sessionId Session id 202 * @param startTime start time 203 * @param endTime end time 204 * @return LinkedHashMap <Integer, List<ChartDataModel>> getCpuData 205 */ getDeadThreadData(long sessionId, int startTime, int endTime)206 public LinkedHashMap<Integer, List<ChartDataModel>> getDeadThreadData(long sessionId, int startTime, int endTime) { 207 if (ProfilerLogManager.isInfoEnabled()) { 208 LOGGER.info("getThreadData"); 209 } 210 LinkedHashMap<Integer, List<ChartDataModel>> result = new LinkedHashMap<>(); 211 LRUCache<List<ChartDataModel>> cache = threadDeadCacheMap.get(sessionId); 212 if (cache == null) { 213 return result; 214 } 215 synchronized (threadDeadCacheMap.get(sessionId)) { 216 result = cache.getCaCheData(startTime, endTime); 217 } 218 return result; 219 } 220 221 /** 222 * Clear cache by session id when the session was deleted 223 * 224 * @param sessionId Session id 225 */ clearCacheBySession(long sessionId)226 public void clearCacheBySession(long sessionId) { 227 if (ProfilerLogManager.isInfoEnabled()) { 228 LOGGER.info("clearCacheBySession"); 229 } 230 cpuDataCacheMap.remove(sessionId); 231 cpuFirstTsMap.remove(sessionId); 232 threadDataCacheMap.remove(sessionId); 233 threadFirstTsMap.remove(sessionId); 234 } 235 } 236