@Test public void analyze_() { List<PacketInfo> packets = new ArrayList<PacketInfo>(); pktInfo01 = Mockito.mock(PacketInfo.class); pktInfo02 = Mockito.mock(PacketInfo.class); for (int i = 0; i < 60; i++) { httpRequestInfoArray[i] = mock(HttpRequestResponseInfo.class); } for (int i = 0; i < 20; i++) { when(httpRequestInfoArray[i].isNoStore()).thenReturn(true); if (i % 2 == 1) { when(httpRequestInfoArray[i].getDirection()).thenReturn(HttpDirection.REQUEST); when(httpRequestInfoArray[i].getHostName()).thenReturn("www.google.com"); when(httpRequestInfoArray[i].getObjName()).thenReturn(Util.getCurrentRunningDir()); } else { when(httpRequestInfoArray[i].getDirection()).thenReturn(HttpDirection.RESPONSE); when(httpRequestInfoArray[18].getStatusCode()).thenReturn(304); } } for (int i = 20; i < 60; i++) { when(httpRequestInfoArray[i].isNoStore()).thenReturn(false); when(httpRequestInfoArray[i].getHostName()).thenReturn("www.google.com" + i); when(httpRequestInfoArray[i].getObjName()).thenReturn(Util.getCurrentRunningDir()); when(httpRequestInfoArray[i - 2].isRangeResponse()).thenReturn(true); if ((i - 20) % 2 == 1) { when(httpRequestInfoArray[i].getDirection()).thenReturn(HttpDirection.REQUEST); } else { when(httpRequestInfoArray[i].getDirection()).thenReturn(HttpDirection.RESPONSE); when(httpRequestInfoArray[i].getStatusCode()).thenReturn(206); } } when(httpRequestInfoArray[2].getAssocReqResp()).thenReturn(httpRequestInfoArray[1]); when(httpRequestInfoArray[4].getAssocReqResp()).thenReturn(httpRequestInfoArray[3]); when(httpRequestInfoArray[6].getAssocReqResp()).thenReturn(httpRequestInfoArray[5]); when(httpRequestInfoArray[8].getAssocReqResp()).thenReturn(httpRequestInfoArray[7]); when(httpRequestInfoArray[10].getAssocReqResp()).thenReturn(httpRequestInfoArray[9]); when(httpRequestInfoArray[12].getAssocReqResp()).thenReturn(httpRequestInfoArray[11]); when(httpRequestInfoArray[14].getAssocReqResp()).thenReturn(httpRequestInfoArray[13]); for (int i = 18; i < 60; i++) { when(httpRequestInfoArray[i].getAssocReqResp()).thenReturn(httpRequestInfoArray[i - 1]); } for (int i = 50; i < 60; i++) { when(httpRequestInfoArray[i].isRangeResponse()).thenReturn(false); when(httpRequestInfoArray[i].isChunked()).thenReturn(true); } for (int i = 0; i < 50; i++) { when(httpRequestInfoArray[i].isRangeResponse()).thenReturn(true); } when(httpRequestInfoArray[7].getHostName()).thenReturn(null); when(httpRequestInfoArray[7].getObjName()).thenReturn(null); when(httpRequestInfoArray[0].getStatusCode()).thenReturn(400); when(httpRequestInfoArray[2].getStatusCode()).thenReturn(200); when(httpRequestInfoArray[4].getStatusCode()).thenReturn(200); when(httpRequestInfoArray[6].getStatusCode()).thenReturn(200); when(httpRequestInfoArray[8].getStatusCode()).thenReturn(206); when(httpRequestInfoArray[10].getStatusCode()).thenReturn(206); when(httpRequestInfoArray[12].getStatusCode()).thenReturn(206); when(httpRequestInfoArray[14].getStatusCode()).thenReturn(304); when(httpRequestInfoArray[16].getStatusCode()).thenReturn(304); when(httpRequestInfoArray[18].getStatusCode()).thenReturn(304); when(httpRequestInfoArray[1].getRequestType()).thenReturn(HttpRequestResponseInfo.UTF8); when(httpRequestInfoArray[3].getRequestType()).thenReturn(HttpRequestResponseInfo.HTTP_POST); when(httpRequestInfoArray[5].getRequestType()).thenReturn(HttpRequestResponseInfo.HTTP_PUT); when(httpRequestInfoArray[7].getRequestType()).thenReturn(HttpRequestResponseInfo.HTTP_GET); when(httpRequestInfoArray[9].getRequestType()).thenReturn(HttpRequestResponseInfo.HTTP_POST); when(httpRequestInfoArray[11].getRequestType()).thenReturn(HttpRequestResponseInfo.HTTP_GET); when(httpRequestInfoArray[13].getRequestType()).thenReturn(HttpRequestResponseInfo.HTTP_GET); when(httpRequestInfoArray[15].getRequestType()).thenReturn(HttpRequestResponseInfo.HTTP_POST); when(httpRequestInfoArray[17].getRequestType()).thenReturn(HttpRequestResponseInfo.HTTP_PUT); when(httpRequestInfoArray[19].getRequestType()).thenReturn(HttpRequestResponseInfo.HTTP_PUT); when(httpRequestInfoArray[20].getRequestType()).thenReturn(HttpRequestResponseInfo.HTTP_GET); when(httpRequestInfoArray[21].getRequestType()).thenReturn(HttpRequestResponseInfo.HTTP_GET); for (int i = 22; i < 60; i++) { if (i % 2 == 1) { when(httpRequestInfoArray[i].getRequestType()).thenReturn(HttpRequestResponseInfo.HTTP_GET); } } Date date01 = new Date(1421384400000L); Date date02 = new Date(1421384400000L - 76400000L); Date date03 = new Date(1421384400000L - 86400000L); Date date04 = new Date(1421383400000L - 176400000L); for (int i = 0; i < 60; i++) { when(httpRequestInfoArray[i].getMaxAge()).thenReturn(86400000L); } for (int i = 0; i < 60; i++) { if (i % 2 == 1) { when(httpRequestInfoArray[i].getExpires()).thenReturn(date03); when(httpRequestInfoArray[i].getDate()).thenReturn(date02); when(httpRequestInfoArray[i].getAbsTimeStamp()).thenReturn(date02); when(httpRequestInfoArray[i].getLastModified()).thenReturn(date); } else { if (i < 40) { when(httpRequestInfoArray[i].getLastModified()).thenReturn(date01); when(httpRequestInfoArray[i].getRangeFirst()).thenReturn(0); when(httpRequestInfoArray[i].getRangeLast()).thenReturn(5); when(httpRequestInfoArray[i].getAbsTimeStamp()).thenReturn(date02); when(httpRequestInfoArray[i].getExpires()).thenReturn(date); when(httpRequestInfoArray[i].getDate()).thenReturn(date03); } else { when(httpRequestInfoArray[i].getLastModified()).thenReturn(date02); when(httpRequestInfoArray[i].getExpires()).thenReturn(date04); when(httpRequestInfoArray[i].getDate()).thenReturn(date); when(httpRequestInfoArray[i].getAbsTimeStamp()).thenReturn(date); when(httpRequestInfoArray[i].getRangeFirst()).thenReturn(0); when(httpRequestInfoArray[i].getRangeLast()).thenReturn(13); } } } when(httpRequestInfoArray[30].isRangeResponse()).thenReturn(false); when(httpRequestInfoArray[31].isRangeResponse()).thenReturn(false); when(rrhelper.getActualByteCount(any(HttpRequestResponseInfo.class), any(Session.class))).thenReturn(2L); List<HttpRequestResponseInfo> value = new ArrayList<HttpRequestResponseInfo>(); for (int i = 0; i < 60; i++) { value.add(httpRequestInfoArray[i]); } packets.add(pktInfo01); packets.add(pktInfo02); session01.setPackets(packets); session02.setPackets(packets); when(session01.getRequestResponseInfo()).thenReturn(value); when(session01.isUdpOnly()).thenReturn(false); when(session01.getPackets()).thenReturn(packets); when(session02.isUdpOnly()).thenReturn(false); when(session02.getRequestResponseInfo()).thenReturn(value); when(session02.getPackets()).thenReturn(packets); List<Session> sessionList = new ArrayList<Session>(); sessionList.add(session01); sessionList.add(session02); CacheAnalysis testResult = cacheAnalysis.analyze(sessionList); assertEquals(4, testResult.getCacheExpirationResponses().size()); assertEquals(60, testResult.getDiagnosisResults().size()); assertEquals(0, testResult.getDuplicateContentBytes()); assertEquals(0, testResult.getDuplicateContentBytesRatio(), 0.0); assertEquals(0, testResult.getDuplicateContentWithOriginals().size()); }
@Override public CacheAnalysis analyze(List<Session> sessionlist) { long analysisStartTime = System.currentTimeMillis(); CacheAnalysis result = new CacheAnalysis(); long totalRequestResponseBytes = 0; long totalRequestResponseDupBytes = 0; double duplicateContentBytesRatio = 0.0; Map<String, CacheEntry> cacheEntries = new HashMap<String, CacheEntry>(); Map<String, CacheEntry> dupEntries = new HashMap<String, CacheEntry>(); Map<String, SortedSet<Range>> rangeEntries = new HashMap<String, SortedSet<Range>>(); List<CacheEntry> diagnosisResults = new ArrayList<CacheEntry>(); List<CacheEntry> duplicateContent = new ArrayList<CacheEntry>(); List<CacheEntry> duplicateContentWithOriginals = new ArrayList<CacheEntry>(); Map<CacheExpiration, List<CacheEntry>> cacheExpirationResponses = result.getCacheExpirationResponses(); dulpicateEntires = new ArrayList<DuplicateEntry>(); for (CacheExpiration expiration : CacheExpiration.values()) { cacheExpirationResponses.put(expiration, new ArrayList<CacheEntry>()); } List<HttpRequestResponseInfoWithSession> rrInfo = new ArrayList<HttpRequestResponseInfoWithSession>(); for (Session session : sessionlist) { if (!session.isUdpOnly()) { for (HttpRequestResponseInfo item : session.getRequestResponseInfo()) { HttpRequestResponseInfoWithSession itemsession = new HttpRequestResponseInfoWithSession(); itemsession.setInfo(item); itemsession.setSession(session); rrInfo.add(itemsession); } } } Collections.sort(rrInfo); for (HttpRequestResponseInfoWithSession httpreqres : rrInfo) { HttpRequestResponseInfo response = httpreqres.getInfo(); Session session = httpreqres.getSession(); PacketInfo firstPacket = session.getPackets().get(0); if (response.getDirection() == HttpDirection.REQUEST) { continue; } int statusCode = response.getStatusCode(); if (statusCode == 0) { diagnosisResults .add(new CacheEntry(null, response, Diagnosis.CACHING_DIAG_INVALID_RESPONSE, 0, firstPacket)); continue; } if (statusCode != 200 && statusCode != 206) { diagnosisResults .add(new CacheEntry(null, response, Diagnosis.CACHING_DIAG_INVALID_REQUEST, 0, firstPacket)); continue; } HttpRequestResponseInfo request = response.getAssocReqResp(); if (request == null) { diagnosisResults.add( new CacheEntry(request, response, Diagnosis.CACHING_DIAG_REQUEST_NOT_FOUND, 0, firstPacket)); continue; } totalRequestResponseBytes += response.getContentLength(); String requestType = request.getRequestType(); if (!HttpRequestResponseInfo.HTTP_GET.equals(requestType) && !HttpRequestResponseInfo.HTTP_PUT.equals(requestType) && !HttpRequestResponseInfo.HTTP_POST.equals(requestType)) { diagnosisResults .add(new CacheEntry(request, response, Diagnosis.CACHING_DIAG_INVALID_REQUEST, 0, firstPacket)); continue; } if (request.getHostName() == null || request.getObjName() == null) { diagnosisResults.add( new CacheEntry(request, response, Diagnosis.CACHING_DIAG_INVALID_OBJ_NAME, 0, firstPacket)); continue; } if (response.isNoStore() || request.isNoStore() || HttpRequestResponseInfo.HTTP_POST.equals(requestType) || HttpRequestResponseInfo.HTTP_PUT.equals(requestType)) { cacheEntries.remove(getObjFullName(request, response)); dupEntries.remove(getObjDuplicateName(request, response)); diagnosisResults .add(new CacheEntry(request, response, Diagnosis.CACHING_DIAG_NOT_CACHABLE, 0, firstPacket)); continue; } CacheEntry cacheEntry = cacheEntries.get(getObjFullName(request, response)); CacheEntry cacheDuplicateEntry = dupEntries.get(getObjDuplicateName(request, response)); CacheEntry newCacheEntry; if (cacheEntry == null) { Diagnosis diagnosis = Diagnosis.CACHING_DIAG_CACHE_MISSED; newCacheEntry = new CacheEntry(request, response, diagnosis, firstPacket); newCacheEntry.setSession(session); addToCache(newCacheEntry, rangeEntries, cacheEntries, dupEntries, session); newCacheEntry.setCacheCount(1); diagnosisResults.add(newCacheEntry); if (cacheDuplicateEntry != null) { diagnosis = Diagnosis.CACHING_DIAG_ETAG_DUPLICATE; } dulpicateEntires.add(new DuplicateEntry(request, response, diagnosis, firstPacket, session, getContent(response, session))); continue; } else { int oldCount = cacheEntry.getCacheCount(); cacheEntry.setCacheCount(oldCount + 1); } CacheExpiration expStatus = cacheExpired(cacheEntry, request.getAbsTimeStamp()); SortedSet<Range> ranges = rangeEntries .get(getObjFullName(cacheEntry.getRequest(), cacheEntry.getResponse())); boolean isfullcachehit = isFullCacheHit(response, ranges); if (isfullcachehit) { switch (expStatus) { case CACHE_EXPIRED: case CACHE_EXPIRED_HEURISTIC: newCacheEntry = handleCacheExpired(session, response, request, firstPacket, cacheEntry); diagnosisResults.add(newCacheEntry); break; case CACHE_NOT_EXPIRED: case CACHE_NOT_EXPIRED_HEURISTIC: newCacheEntry = new CacheEntry(request, response, Diagnosis.CACHING_DIAG_NOT_EXPIRED_DUP, firstPacket); dulpicateEntires.add(new DuplicateEntry(request, response, Diagnosis.CACHING_DIAG_NOT_EXPIRED_DUP, firstPacket, session, getContent(response, session))); diagnosisResults.add(newCacheEntry); break; default: newCacheEntry = null; } } else { long bytesInCache = getBytesInCache(response, ranges); switch (expStatus) { case CACHE_EXPIRED: case CACHE_EXPIRED_HEURISTIC: newCacheEntry = handleCacheExpiredWithByteInCache(session, response, request, firstPacket, cacheEntry, bytesInCache); diagnosisResults.add(newCacheEntry); break; case CACHE_NOT_EXPIRED: case CACHE_NOT_EXPIRED_HEURISTIC: newCacheEntry = new CacheEntry(request, response, Diagnosis.CACHING_DIAG_NOT_EXPIRED_DUP_PARTIALHIT, bytesInCache, firstPacket); dulpicateEntires.add(new DuplicateEntry(request, response, Diagnosis.CACHING_DIAG_NOT_EXPIRED_DUP, firstPacket, session, getContent(response, session))); diagnosisResults.add(newCacheEntry); break; default: newCacheEntry = null; } } cacheExpirationResponses.get(expStatus).add(newCacheEntry); if (newCacheEntry != null) { newCacheEntry.setCacheHit(cacheEntry); } } Set<CacheEntry> dupsWithOrig = new HashSet<CacheEntry>(); Map<String, DuplicateEntry> dulpicateEntiresMap = new HashMap<String, DuplicateEntry>(); CacheEntry cache; for (DuplicateEntry dupEntry : dulpicateEntires) { if (dupEntry.getContentLength() > 0) { String key = dupEntry.getRequest().getHostName() + dupEntry.getHttpObjectName() + dupEntry.getContentLength(); if (dupEntry.getHttpObjectName() != null) { if (!dulpicateEntiresMap.containsKey(key)) { dupEntry.setCount(1); dulpicateEntiresMap.put(key, dupEntry); } else { if (Arrays.equals(dulpicateEntiresMap.get(key).getContent(), dupEntry.getContent())) { int count = dulpicateEntiresMap.get(key).getCount(); if (count == 1) { cache = new CacheEntry(dulpicateEntiresMap.get(key).getRequest(), dulpicateEntiresMap.get(key).getResponse(), dulpicateEntiresMap.get(key).getDiagnosis(), dulpicateEntiresMap.get(key).getSessionFirstPacket()); cache.setSession(dupEntry.getSession()); dupsWithOrig.add(cache); } cache = new CacheEntry(dupEntry.getRequest(), dupEntry.getResponse(), dupEntry.getDiagnosis(), dupEntry.getSessionFirstPacket()); dupsWithOrig.add(cache); dupEntry = new DuplicateEntry(dupEntry.getRequest(), dupEntry.getResponse(), dupEntry.getDiagnosis(), dupEntry.getSessionFirstPacket(), dupEntry.getSession(), dupEntry.getContent()); dupEntry.setCount(count + 1); dulpicateEntiresMap.replace(key, dupEntry); } } } } } for (Entry<String, DuplicateEntry> cacheEntry2 : dulpicateEntiresMap.entrySet()) { if (cacheEntry2.getValue().getCount() > 1) { int count = cacheEntry2.getValue().getCount(); cache = new CacheEntry(cacheEntry2.getValue().getRequest(), cacheEntry2.getValue().getResponse(), cacheEntry2.getValue().getDiagnosis(), cacheEntry2.getValue().getSessionFirstPacket()); cache.setHitCount(count); if (count > 2) { totalRequestResponseDupBytes += (cacheEntry2.getValue().getHttpRequestResponse().getContentLength() * (count - 1)); } else { totalRequestResponseDupBytes += cacheEntry2.getValue().getHttpRequestResponse().getContentLength(); } duplicateContent.add(cache); } } duplicateContentWithOriginals.addAll(dupsWithOrig); Collections.sort(duplicateContentWithOriginals); duplicateContentBytesRatio = totalRequestResponseBytes != 0 ? (double) totalRequestResponseDupBytes / totalRequestResponseBytes : 0.0; result.setCacheExpirationResponses(cacheExpirationResponses); result.setDiagnosisResults(diagnosisResults); result.setDuplicateContent(duplicateContent); result.setDuplicateContentBytesRatio(duplicateContentBytesRatio); result.setDuplicateContentWithOriginals(duplicateContentWithOriginals); result.setTotalRequestResponseBytes(totalRequestResponseBytes); result.setTotalRequestResponseDupBytes(totalRequestResponseDupBytes); GoogleAnalyticsUtil.getGoogleAnalyticsInstance().sendAnalyticsTimings(cacheAnalysisTitle, System.currentTimeMillis() - analysisStartTime, analysisCategory); return result; }
CacheAnalysisImpl implements ICacheAnalysis { @Override public CacheAnalysis analyze(List<Session> sessionlist) { long analysisStartTime = System.currentTimeMillis(); CacheAnalysis result = new CacheAnalysis(); long totalRequestResponseBytes = 0; long totalRequestResponseDupBytes = 0; double duplicateContentBytesRatio = 0.0; Map<String, CacheEntry> cacheEntries = new HashMap<String, CacheEntry>(); Map<String, CacheEntry> dupEntries = new HashMap<String, CacheEntry>(); Map<String, SortedSet<Range>> rangeEntries = new HashMap<String, SortedSet<Range>>(); List<CacheEntry> diagnosisResults = new ArrayList<CacheEntry>(); List<CacheEntry> duplicateContent = new ArrayList<CacheEntry>(); List<CacheEntry> duplicateContentWithOriginals = new ArrayList<CacheEntry>(); Map<CacheExpiration, List<CacheEntry>> cacheExpirationResponses = result.getCacheExpirationResponses(); dulpicateEntires = new ArrayList<DuplicateEntry>(); for (CacheExpiration expiration : CacheExpiration.values()) { cacheExpirationResponses.put(expiration, new ArrayList<CacheEntry>()); } List<HttpRequestResponseInfoWithSession> rrInfo = new ArrayList<HttpRequestResponseInfoWithSession>(); for (Session session : sessionlist) { if (!session.isUdpOnly()) { for (HttpRequestResponseInfo item : session.getRequestResponseInfo()) { HttpRequestResponseInfoWithSession itemsession = new HttpRequestResponseInfoWithSession(); itemsession.setInfo(item); itemsession.setSession(session); rrInfo.add(itemsession); } } } Collections.sort(rrInfo); for (HttpRequestResponseInfoWithSession httpreqres : rrInfo) { HttpRequestResponseInfo response = httpreqres.getInfo(); Session session = httpreqres.getSession(); PacketInfo firstPacket = session.getPackets().get(0); if (response.getDirection() == HttpDirection.REQUEST) { continue; } int statusCode = response.getStatusCode(); if (statusCode == 0) { diagnosisResults .add(new CacheEntry(null, response, Diagnosis.CACHING_DIAG_INVALID_RESPONSE, 0, firstPacket)); continue; } if (statusCode != 200 && statusCode != 206) { diagnosisResults .add(new CacheEntry(null, response, Diagnosis.CACHING_DIAG_INVALID_REQUEST, 0, firstPacket)); continue; } HttpRequestResponseInfo request = response.getAssocReqResp(); if (request == null) { diagnosisResults.add( new CacheEntry(request, response, Diagnosis.CACHING_DIAG_REQUEST_NOT_FOUND, 0, firstPacket)); continue; } totalRequestResponseBytes += response.getContentLength(); String requestType = request.getRequestType(); if (!HttpRequestResponseInfo.HTTP_GET.equals(requestType) && !HttpRequestResponseInfo.HTTP_PUT.equals(requestType) && !HttpRequestResponseInfo.HTTP_POST.equals(requestType)) { diagnosisResults .add(new CacheEntry(request, response, Diagnosis.CACHING_DIAG_INVALID_REQUEST, 0, firstPacket)); continue; } if (request.getHostName() == null || request.getObjName() == null) { diagnosisResults.add( new CacheEntry(request, response, Diagnosis.CACHING_DIAG_INVALID_OBJ_NAME, 0, firstPacket)); continue; } if (response.isNoStore() || request.isNoStore() || HttpRequestResponseInfo.HTTP_POST.equals(requestType) || HttpRequestResponseInfo.HTTP_PUT.equals(requestType)) { cacheEntries.remove(getObjFullName(request, response)); dupEntries.remove(getObjDuplicateName(request, response)); diagnosisResults .add(new CacheEntry(request, response, Diagnosis.CACHING_DIAG_NOT_CACHABLE, 0, firstPacket)); continue; } CacheEntry cacheEntry = cacheEntries.get(getObjFullName(request, response)); CacheEntry cacheDuplicateEntry = dupEntries.get(getObjDuplicateName(request, response)); CacheEntry newCacheEntry; if (cacheEntry == null) { Diagnosis diagnosis = Diagnosis.CACHING_DIAG_CACHE_MISSED; newCacheEntry = new CacheEntry(request, response, diagnosis, firstPacket); newCacheEntry.setSession(session); addToCache(newCacheEntry, rangeEntries, cacheEntries, dupEntries, session); newCacheEntry.setCacheCount(1); diagnosisResults.add(newCacheEntry); if (cacheDuplicateEntry != null) { diagnosis = Diagnosis.CACHING_DIAG_ETAG_DUPLICATE; } dulpicateEntires.add(new DuplicateEntry(request, response, diagnosis, firstPacket, session, getContent(response, session))); continue; } else { int oldCount = cacheEntry.getCacheCount(); cacheEntry.setCacheCount(oldCount + 1); } CacheExpiration expStatus = cacheExpired(cacheEntry, request.getAbsTimeStamp()); SortedSet<Range> ranges = rangeEntries .get(getObjFullName(cacheEntry.getRequest(), cacheEntry.getResponse())); boolean isfullcachehit = isFullCacheHit(response, ranges); if (isfullcachehit) { switch (expStatus) { case CACHE_EXPIRED: case CACHE_EXPIRED_HEURISTIC: newCacheEntry = handleCacheExpired(session, response, request, firstPacket, cacheEntry); diagnosisResults.add(newCacheEntry); break; case CACHE_NOT_EXPIRED: case CACHE_NOT_EXPIRED_HEURISTIC: newCacheEntry = new CacheEntry(request, response, Diagnosis.CACHING_DIAG_NOT_EXPIRED_DUP, firstPacket); dulpicateEntires.add(new DuplicateEntry(request, response, Diagnosis.CACHING_DIAG_NOT_EXPIRED_DUP, firstPacket, session, getContent(response, session))); diagnosisResults.add(newCacheEntry); break; default: newCacheEntry = null; } } else { long bytesInCache = getBytesInCache(response, ranges); switch (expStatus) { case CACHE_EXPIRED: case CACHE_EXPIRED_HEURISTIC: newCacheEntry = handleCacheExpiredWithByteInCache(session, response, request, firstPacket, cacheEntry, bytesInCache); diagnosisResults.add(newCacheEntry); break; case CACHE_NOT_EXPIRED: case CACHE_NOT_EXPIRED_HEURISTIC: newCacheEntry = new CacheEntry(request, response, Diagnosis.CACHING_DIAG_NOT_EXPIRED_DUP_PARTIALHIT, bytesInCache, firstPacket); dulpicateEntires.add(new DuplicateEntry(request, response, Diagnosis.CACHING_DIAG_NOT_EXPIRED_DUP, firstPacket, session, getContent(response, session))); diagnosisResults.add(newCacheEntry); break; default: newCacheEntry = null; } } cacheExpirationResponses.get(expStatus).add(newCacheEntry); if (newCacheEntry != null) { newCacheEntry.setCacheHit(cacheEntry); } } Set<CacheEntry> dupsWithOrig = new HashSet<CacheEntry>(); Map<String, DuplicateEntry> dulpicateEntiresMap = new HashMap<String, DuplicateEntry>(); CacheEntry cache; for (DuplicateEntry dupEntry : dulpicateEntires) { if (dupEntry.getContentLength() > 0) { String key = dupEntry.getRequest().getHostName() + dupEntry.getHttpObjectName() + dupEntry.getContentLength(); if (dupEntry.getHttpObjectName() != null) { if (!dulpicateEntiresMap.containsKey(key)) { dupEntry.setCount(1); dulpicateEntiresMap.put(key, dupEntry); } else { if (Arrays.equals(dulpicateEntiresMap.get(key).getContent(), dupEntry.getContent())) { int count = dulpicateEntiresMap.get(key).getCount(); if (count == 1) { cache = new CacheEntry(dulpicateEntiresMap.get(key).getRequest(), dulpicateEntiresMap.get(key).getResponse(), dulpicateEntiresMap.get(key).getDiagnosis(), dulpicateEntiresMap.get(key).getSessionFirstPacket()); cache.setSession(dupEntry.getSession()); dupsWithOrig.add(cache); } cache = new CacheEntry(dupEntry.getRequest(), dupEntry.getResponse(), dupEntry.getDiagnosis(), dupEntry.getSessionFirstPacket()); dupsWithOrig.add(cache); dupEntry = new DuplicateEntry(dupEntry.getRequest(), dupEntry.getResponse(), dupEntry.getDiagnosis(), dupEntry.getSessionFirstPacket(), dupEntry.getSession(), dupEntry.getContent()); dupEntry.setCount(count + 1); dulpicateEntiresMap.replace(key, dupEntry); } } } } } for (Entry<String, DuplicateEntry> cacheEntry2 : dulpicateEntiresMap.entrySet()) { if (cacheEntry2.getValue().getCount() > 1) { int count = cacheEntry2.getValue().getCount(); cache = new CacheEntry(cacheEntry2.getValue().getRequest(), cacheEntry2.getValue().getResponse(), cacheEntry2.getValue().getDiagnosis(), cacheEntry2.getValue().getSessionFirstPacket()); cache.setHitCount(count); if (count > 2) { totalRequestResponseDupBytes += (cacheEntry2.getValue().getHttpRequestResponse().getContentLength() * (count - 1)); } else { totalRequestResponseDupBytes += cacheEntry2.getValue().getHttpRequestResponse().getContentLength(); } duplicateContent.add(cache); } } duplicateContentWithOriginals.addAll(dupsWithOrig); Collections.sort(duplicateContentWithOriginals); duplicateContentBytesRatio = totalRequestResponseBytes != 0 ? (double) totalRequestResponseDupBytes / totalRequestResponseBytes : 0.0; result.setCacheExpirationResponses(cacheExpirationResponses); result.setDiagnosisResults(diagnosisResults); result.setDuplicateContent(duplicateContent); result.setDuplicateContentBytesRatio(duplicateContentBytesRatio); result.setDuplicateContentWithOriginals(duplicateContentWithOriginals); result.setTotalRequestResponseBytes(totalRequestResponseBytes); result.setTotalRequestResponseDupBytes(totalRequestResponseDupBytes); GoogleAnalyticsUtil.getGoogleAnalyticsInstance().sendAnalyticsTimings(cacheAnalysisTitle, System.currentTimeMillis() - analysisStartTime, analysisCategory); return result; } }
CacheAnalysisImpl implements ICacheAnalysis { @Override public CacheAnalysis analyze(List<Session> sessionlist) { long analysisStartTime = System.currentTimeMillis(); CacheAnalysis result = new CacheAnalysis(); long totalRequestResponseBytes = 0; long totalRequestResponseDupBytes = 0; double duplicateContentBytesRatio = 0.0; Map<String, CacheEntry> cacheEntries = new HashMap<String, CacheEntry>(); Map<String, CacheEntry> dupEntries = new HashMap<String, CacheEntry>(); Map<String, SortedSet<Range>> rangeEntries = new HashMap<String, SortedSet<Range>>(); List<CacheEntry> diagnosisResults = new ArrayList<CacheEntry>(); List<CacheEntry> duplicateContent = new ArrayList<CacheEntry>(); List<CacheEntry> duplicateContentWithOriginals = new ArrayList<CacheEntry>(); Map<CacheExpiration, List<CacheEntry>> cacheExpirationResponses = result.getCacheExpirationResponses(); dulpicateEntires = new ArrayList<DuplicateEntry>(); for (CacheExpiration expiration : CacheExpiration.values()) { cacheExpirationResponses.put(expiration, new ArrayList<CacheEntry>()); } List<HttpRequestResponseInfoWithSession> rrInfo = new ArrayList<HttpRequestResponseInfoWithSession>(); for (Session session : sessionlist) { if (!session.isUdpOnly()) { for (HttpRequestResponseInfo item : session.getRequestResponseInfo()) { HttpRequestResponseInfoWithSession itemsession = new HttpRequestResponseInfoWithSession(); itemsession.setInfo(item); itemsession.setSession(session); rrInfo.add(itemsession); } } } Collections.sort(rrInfo); for (HttpRequestResponseInfoWithSession httpreqres : rrInfo) { HttpRequestResponseInfo response = httpreqres.getInfo(); Session session = httpreqres.getSession(); PacketInfo firstPacket = session.getPackets().get(0); if (response.getDirection() == HttpDirection.REQUEST) { continue; } int statusCode = response.getStatusCode(); if (statusCode == 0) { diagnosisResults .add(new CacheEntry(null, response, Diagnosis.CACHING_DIAG_INVALID_RESPONSE, 0, firstPacket)); continue; } if (statusCode != 200 && statusCode != 206) { diagnosisResults .add(new CacheEntry(null, response, Diagnosis.CACHING_DIAG_INVALID_REQUEST, 0, firstPacket)); continue; } HttpRequestResponseInfo request = response.getAssocReqResp(); if (request == null) { diagnosisResults.add( new CacheEntry(request, response, Diagnosis.CACHING_DIAG_REQUEST_NOT_FOUND, 0, firstPacket)); continue; } totalRequestResponseBytes += response.getContentLength(); String requestType = request.getRequestType(); if (!HttpRequestResponseInfo.HTTP_GET.equals(requestType) && !HttpRequestResponseInfo.HTTP_PUT.equals(requestType) && !HttpRequestResponseInfo.HTTP_POST.equals(requestType)) { diagnosisResults .add(new CacheEntry(request, response, Diagnosis.CACHING_DIAG_INVALID_REQUEST, 0, firstPacket)); continue; } if (request.getHostName() == null || request.getObjName() == null) { diagnosisResults.add( new CacheEntry(request, response, Diagnosis.CACHING_DIAG_INVALID_OBJ_NAME, 0, firstPacket)); continue; } if (response.isNoStore() || request.isNoStore() || HttpRequestResponseInfo.HTTP_POST.equals(requestType) || HttpRequestResponseInfo.HTTP_PUT.equals(requestType)) { cacheEntries.remove(getObjFullName(request, response)); dupEntries.remove(getObjDuplicateName(request, response)); diagnosisResults .add(new CacheEntry(request, response, Diagnosis.CACHING_DIAG_NOT_CACHABLE, 0, firstPacket)); continue; } CacheEntry cacheEntry = cacheEntries.get(getObjFullName(request, response)); CacheEntry cacheDuplicateEntry = dupEntries.get(getObjDuplicateName(request, response)); CacheEntry newCacheEntry; if (cacheEntry == null) { Diagnosis diagnosis = Diagnosis.CACHING_DIAG_CACHE_MISSED; newCacheEntry = new CacheEntry(request, response, diagnosis, firstPacket); newCacheEntry.setSession(session); addToCache(newCacheEntry, rangeEntries, cacheEntries, dupEntries, session); newCacheEntry.setCacheCount(1); diagnosisResults.add(newCacheEntry); if (cacheDuplicateEntry != null) { diagnosis = Diagnosis.CACHING_DIAG_ETAG_DUPLICATE; } dulpicateEntires.add(new DuplicateEntry(request, response, diagnosis, firstPacket, session, getContent(response, session))); continue; } else { int oldCount = cacheEntry.getCacheCount(); cacheEntry.setCacheCount(oldCount + 1); } CacheExpiration expStatus = cacheExpired(cacheEntry, request.getAbsTimeStamp()); SortedSet<Range> ranges = rangeEntries .get(getObjFullName(cacheEntry.getRequest(), cacheEntry.getResponse())); boolean isfullcachehit = isFullCacheHit(response, ranges); if (isfullcachehit) { switch (expStatus) { case CACHE_EXPIRED: case CACHE_EXPIRED_HEURISTIC: newCacheEntry = handleCacheExpired(session, response, request, firstPacket, cacheEntry); diagnosisResults.add(newCacheEntry); break; case CACHE_NOT_EXPIRED: case CACHE_NOT_EXPIRED_HEURISTIC: newCacheEntry = new CacheEntry(request, response, Diagnosis.CACHING_DIAG_NOT_EXPIRED_DUP, firstPacket); dulpicateEntires.add(new DuplicateEntry(request, response, Diagnosis.CACHING_DIAG_NOT_EXPIRED_DUP, firstPacket, session, getContent(response, session))); diagnosisResults.add(newCacheEntry); break; default: newCacheEntry = null; } } else { long bytesInCache = getBytesInCache(response, ranges); switch (expStatus) { case CACHE_EXPIRED: case CACHE_EXPIRED_HEURISTIC: newCacheEntry = handleCacheExpiredWithByteInCache(session, response, request, firstPacket, cacheEntry, bytesInCache); diagnosisResults.add(newCacheEntry); break; case CACHE_NOT_EXPIRED: case CACHE_NOT_EXPIRED_HEURISTIC: newCacheEntry = new CacheEntry(request, response, Diagnosis.CACHING_DIAG_NOT_EXPIRED_DUP_PARTIALHIT, bytesInCache, firstPacket); dulpicateEntires.add(new DuplicateEntry(request, response, Diagnosis.CACHING_DIAG_NOT_EXPIRED_DUP, firstPacket, session, getContent(response, session))); diagnosisResults.add(newCacheEntry); break; default: newCacheEntry = null; } } cacheExpirationResponses.get(expStatus).add(newCacheEntry); if (newCacheEntry != null) { newCacheEntry.setCacheHit(cacheEntry); } } Set<CacheEntry> dupsWithOrig = new HashSet<CacheEntry>(); Map<String, DuplicateEntry> dulpicateEntiresMap = new HashMap<String, DuplicateEntry>(); CacheEntry cache; for (DuplicateEntry dupEntry : dulpicateEntires) { if (dupEntry.getContentLength() > 0) { String key = dupEntry.getRequest().getHostName() + dupEntry.getHttpObjectName() + dupEntry.getContentLength(); if (dupEntry.getHttpObjectName() != null) { if (!dulpicateEntiresMap.containsKey(key)) { dupEntry.setCount(1); dulpicateEntiresMap.put(key, dupEntry); } else { if (Arrays.equals(dulpicateEntiresMap.get(key).getContent(), dupEntry.getContent())) { int count = dulpicateEntiresMap.get(key).getCount(); if (count == 1) { cache = new CacheEntry(dulpicateEntiresMap.get(key).getRequest(), dulpicateEntiresMap.get(key).getResponse(), dulpicateEntiresMap.get(key).getDiagnosis(), dulpicateEntiresMap.get(key).getSessionFirstPacket()); cache.setSession(dupEntry.getSession()); dupsWithOrig.add(cache); } cache = new CacheEntry(dupEntry.getRequest(), dupEntry.getResponse(), dupEntry.getDiagnosis(), dupEntry.getSessionFirstPacket()); dupsWithOrig.add(cache); dupEntry = new DuplicateEntry(dupEntry.getRequest(), dupEntry.getResponse(), dupEntry.getDiagnosis(), dupEntry.getSessionFirstPacket(), dupEntry.getSession(), dupEntry.getContent()); dupEntry.setCount(count + 1); dulpicateEntiresMap.replace(key, dupEntry); } } } } } for (Entry<String, DuplicateEntry> cacheEntry2 : dulpicateEntiresMap.entrySet()) { if (cacheEntry2.getValue().getCount() > 1) { int count = cacheEntry2.getValue().getCount(); cache = new CacheEntry(cacheEntry2.getValue().getRequest(), cacheEntry2.getValue().getResponse(), cacheEntry2.getValue().getDiagnosis(), cacheEntry2.getValue().getSessionFirstPacket()); cache.setHitCount(count); if (count > 2) { totalRequestResponseDupBytes += (cacheEntry2.getValue().getHttpRequestResponse().getContentLength() * (count - 1)); } else { totalRequestResponseDupBytes += cacheEntry2.getValue().getHttpRequestResponse().getContentLength(); } duplicateContent.add(cache); } } duplicateContentWithOriginals.addAll(dupsWithOrig); Collections.sort(duplicateContentWithOriginals); duplicateContentBytesRatio = totalRequestResponseBytes != 0 ? (double) totalRequestResponseDupBytes / totalRequestResponseBytes : 0.0; result.setCacheExpirationResponses(cacheExpirationResponses); result.setDiagnosisResults(diagnosisResults); result.setDuplicateContent(duplicateContent); result.setDuplicateContentBytesRatio(duplicateContentBytesRatio); result.setDuplicateContentWithOriginals(duplicateContentWithOriginals); result.setTotalRequestResponseBytes(totalRequestResponseBytes); result.setTotalRequestResponseDupBytes(totalRequestResponseDupBytes); GoogleAnalyticsUtil.getGoogleAnalyticsInstance().sendAnalyticsTimings(cacheAnalysisTitle, System.currentTimeMillis() - analysisStartTime, analysisCategory); return result; }  }
CacheAnalysisImpl implements ICacheAnalysis { @Override public CacheAnalysis analyze(List<Session> sessionlist) { long analysisStartTime = System.currentTimeMillis(); CacheAnalysis result = new CacheAnalysis(); long totalRequestResponseBytes = 0; long totalRequestResponseDupBytes = 0; double duplicateContentBytesRatio = 0.0; Map<String, CacheEntry> cacheEntries = new HashMap<String, CacheEntry>(); Map<String, CacheEntry> dupEntries = new HashMap<String, CacheEntry>(); Map<String, SortedSet<Range>> rangeEntries = new HashMap<String, SortedSet<Range>>(); List<CacheEntry> diagnosisResults = new ArrayList<CacheEntry>(); List<CacheEntry> duplicateContent = new ArrayList<CacheEntry>(); List<CacheEntry> duplicateContentWithOriginals = new ArrayList<CacheEntry>(); Map<CacheExpiration, List<CacheEntry>> cacheExpirationResponses = result.getCacheExpirationResponses(); dulpicateEntires = new ArrayList<DuplicateEntry>(); for (CacheExpiration expiration : CacheExpiration.values()) { cacheExpirationResponses.put(expiration, new ArrayList<CacheEntry>()); } List<HttpRequestResponseInfoWithSession> rrInfo = new ArrayList<HttpRequestResponseInfoWithSession>(); for (Session session : sessionlist) { if (!session.isUdpOnly()) { for (HttpRequestResponseInfo item : session.getRequestResponseInfo()) { HttpRequestResponseInfoWithSession itemsession = new HttpRequestResponseInfoWithSession(); itemsession.setInfo(item); itemsession.setSession(session); rrInfo.add(itemsession); } } } Collections.sort(rrInfo); for (HttpRequestResponseInfoWithSession httpreqres : rrInfo) { HttpRequestResponseInfo response = httpreqres.getInfo(); Session session = httpreqres.getSession(); PacketInfo firstPacket = session.getPackets().get(0); if (response.getDirection() == HttpDirection.REQUEST) { continue; } int statusCode = response.getStatusCode(); if (statusCode == 0) { diagnosisResults .add(new CacheEntry(null, response, Diagnosis.CACHING_DIAG_INVALID_RESPONSE, 0, firstPacket)); continue; } if (statusCode != 200 && statusCode != 206) { diagnosisResults .add(new CacheEntry(null, response, Diagnosis.CACHING_DIAG_INVALID_REQUEST, 0, firstPacket)); continue; } HttpRequestResponseInfo request = response.getAssocReqResp(); if (request == null) { diagnosisResults.add( new CacheEntry(request, response, Diagnosis.CACHING_DIAG_REQUEST_NOT_FOUND, 0, firstPacket)); continue; } totalRequestResponseBytes += response.getContentLength(); String requestType = request.getRequestType(); if (!HttpRequestResponseInfo.HTTP_GET.equals(requestType) && !HttpRequestResponseInfo.HTTP_PUT.equals(requestType) && !HttpRequestResponseInfo.HTTP_POST.equals(requestType)) { diagnosisResults .add(new CacheEntry(request, response, Diagnosis.CACHING_DIAG_INVALID_REQUEST, 0, firstPacket)); continue; } if (request.getHostName() == null || request.getObjName() == null) { diagnosisResults.add( new CacheEntry(request, response, Diagnosis.CACHING_DIAG_INVALID_OBJ_NAME, 0, firstPacket)); continue; } if (response.isNoStore() || request.isNoStore() || HttpRequestResponseInfo.HTTP_POST.equals(requestType) || HttpRequestResponseInfo.HTTP_PUT.equals(requestType)) { cacheEntries.remove(getObjFullName(request, response)); dupEntries.remove(getObjDuplicateName(request, response)); diagnosisResults .add(new CacheEntry(request, response, Diagnosis.CACHING_DIAG_NOT_CACHABLE, 0, firstPacket)); continue; } CacheEntry cacheEntry = cacheEntries.get(getObjFullName(request, response)); CacheEntry cacheDuplicateEntry = dupEntries.get(getObjDuplicateName(request, response)); CacheEntry newCacheEntry; if (cacheEntry == null) { Diagnosis diagnosis = Diagnosis.CACHING_DIAG_CACHE_MISSED; newCacheEntry = new CacheEntry(request, response, diagnosis, firstPacket); newCacheEntry.setSession(session); addToCache(newCacheEntry, rangeEntries, cacheEntries, dupEntries, session); newCacheEntry.setCacheCount(1); diagnosisResults.add(newCacheEntry); if (cacheDuplicateEntry != null) { diagnosis = Diagnosis.CACHING_DIAG_ETAG_DUPLICATE; } dulpicateEntires.add(new DuplicateEntry(request, response, diagnosis, firstPacket, session, getContent(response, session))); continue; } else { int oldCount = cacheEntry.getCacheCount(); cacheEntry.setCacheCount(oldCount + 1); } CacheExpiration expStatus = cacheExpired(cacheEntry, request.getAbsTimeStamp()); SortedSet<Range> ranges = rangeEntries .get(getObjFullName(cacheEntry.getRequest(), cacheEntry.getResponse())); boolean isfullcachehit = isFullCacheHit(response, ranges); if (isfullcachehit) { switch (expStatus) { case CACHE_EXPIRED: case CACHE_EXPIRED_HEURISTIC: newCacheEntry = handleCacheExpired(session, response, request, firstPacket, cacheEntry); diagnosisResults.add(newCacheEntry); break; case CACHE_NOT_EXPIRED: case CACHE_NOT_EXPIRED_HEURISTIC: newCacheEntry = new CacheEntry(request, response, Diagnosis.CACHING_DIAG_NOT_EXPIRED_DUP, firstPacket); dulpicateEntires.add(new DuplicateEntry(request, response, Diagnosis.CACHING_DIAG_NOT_EXPIRED_DUP, firstPacket, session, getContent(response, session))); diagnosisResults.add(newCacheEntry); break; default: newCacheEntry = null; } } else { long bytesInCache = getBytesInCache(response, ranges); switch (expStatus) { case CACHE_EXPIRED: case CACHE_EXPIRED_HEURISTIC: newCacheEntry = handleCacheExpiredWithByteInCache(session, response, request, firstPacket, cacheEntry, bytesInCache); diagnosisResults.add(newCacheEntry); break; case CACHE_NOT_EXPIRED: case CACHE_NOT_EXPIRED_HEURISTIC: newCacheEntry = new CacheEntry(request, response, Diagnosis.CACHING_DIAG_NOT_EXPIRED_DUP_PARTIALHIT, bytesInCache, firstPacket); dulpicateEntires.add(new DuplicateEntry(request, response, Diagnosis.CACHING_DIAG_NOT_EXPIRED_DUP, firstPacket, session, getContent(response, session))); diagnosisResults.add(newCacheEntry); break; default: newCacheEntry = null; } } cacheExpirationResponses.get(expStatus).add(newCacheEntry); if (newCacheEntry != null) { newCacheEntry.setCacheHit(cacheEntry); } } Set<CacheEntry> dupsWithOrig = new HashSet<CacheEntry>(); Map<String, DuplicateEntry> dulpicateEntiresMap = new HashMap<String, DuplicateEntry>(); CacheEntry cache; for (DuplicateEntry dupEntry : dulpicateEntires) { if (dupEntry.getContentLength() > 0) { String key = dupEntry.getRequest().getHostName() + dupEntry.getHttpObjectName() + dupEntry.getContentLength(); if (dupEntry.getHttpObjectName() != null) { if (!dulpicateEntiresMap.containsKey(key)) { dupEntry.setCount(1); dulpicateEntiresMap.put(key, dupEntry); } else { if (Arrays.equals(dulpicateEntiresMap.get(key).getContent(), dupEntry.getContent())) { int count = dulpicateEntiresMap.get(key).getCount(); if (count == 1) { cache = new CacheEntry(dulpicateEntiresMap.get(key).getRequest(), dulpicateEntiresMap.get(key).getResponse(), dulpicateEntiresMap.get(key).getDiagnosis(), dulpicateEntiresMap.get(key).getSessionFirstPacket()); cache.setSession(dupEntry.getSession()); dupsWithOrig.add(cache); } cache = new CacheEntry(dupEntry.getRequest(), dupEntry.getResponse(), dupEntry.getDiagnosis(), dupEntry.getSessionFirstPacket()); dupsWithOrig.add(cache); dupEntry = new DuplicateEntry(dupEntry.getRequest(), dupEntry.getResponse(), dupEntry.getDiagnosis(), dupEntry.getSessionFirstPacket(), dupEntry.getSession(), dupEntry.getContent()); dupEntry.setCount(count + 1); dulpicateEntiresMap.replace(key, dupEntry); } } } } } for (Entry<String, DuplicateEntry> cacheEntry2 : dulpicateEntiresMap.entrySet()) { if (cacheEntry2.getValue().getCount() > 1) { int count = cacheEntry2.getValue().getCount(); cache = new CacheEntry(cacheEntry2.getValue().getRequest(), cacheEntry2.getValue().getResponse(), cacheEntry2.getValue().getDiagnosis(), cacheEntry2.getValue().getSessionFirstPacket()); cache.setHitCount(count); if (count > 2) { totalRequestResponseDupBytes += (cacheEntry2.getValue().getHttpRequestResponse().getContentLength() * (count - 1)); } else { totalRequestResponseDupBytes += cacheEntry2.getValue().getHttpRequestResponse().getContentLength(); } duplicateContent.add(cache); } } duplicateContentWithOriginals.addAll(dupsWithOrig); Collections.sort(duplicateContentWithOriginals); duplicateContentBytesRatio = totalRequestResponseBytes != 0 ? (double) totalRequestResponseDupBytes / totalRequestResponseBytes : 0.0; result.setCacheExpirationResponses(cacheExpirationResponses); result.setDiagnosisResults(diagnosisResults); result.setDuplicateContent(duplicateContent); result.setDuplicateContentBytesRatio(duplicateContentBytesRatio); result.setDuplicateContentWithOriginals(duplicateContentWithOriginals); result.setTotalRequestResponseBytes(totalRequestResponseBytes); result.setTotalRequestResponseDupBytes(totalRequestResponseDupBytes); GoogleAnalyticsUtil.getGoogleAnalyticsInstance().sendAnalyticsTimings(cacheAnalysisTitle, System.currentTimeMillis() - analysisStartTime, analysisCategory); return result; }  @Override CacheAnalysis analyze(List<Session> sessionlist); byte[] getContent(HttpRequestResponseInfo response, Session session); }
CacheAnalysisImpl implements ICacheAnalysis { @Override public CacheAnalysis analyze(List<Session> sessionlist) { long analysisStartTime = System.currentTimeMillis(); CacheAnalysis result = new CacheAnalysis(); long totalRequestResponseBytes = 0; long totalRequestResponseDupBytes = 0; double duplicateContentBytesRatio = 0.0; Map<String, CacheEntry> cacheEntries = new HashMap<String, CacheEntry>(); Map<String, CacheEntry> dupEntries = new HashMap<String, CacheEntry>(); Map<String, SortedSet<Range>> rangeEntries = new HashMap<String, SortedSet<Range>>(); List<CacheEntry> diagnosisResults = new ArrayList<CacheEntry>(); List<CacheEntry> duplicateContent = new ArrayList<CacheEntry>(); List<CacheEntry> duplicateContentWithOriginals = new ArrayList<CacheEntry>(); Map<CacheExpiration, List<CacheEntry>> cacheExpirationResponses = result.getCacheExpirationResponses(); dulpicateEntires = new ArrayList<DuplicateEntry>(); for (CacheExpiration expiration : CacheExpiration.values()) { cacheExpirationResponses.put(expiration, new ArrayList<CacheEntry>()); } List<HttpRequestResponseInfoWithSession> rrInfo = new ArrayList<HttpRequestResponseInfoWithSession>(); for (Session session : sessionlist) { if (!session.isUdpOnly()) { for (HttpRequestResponseInfo item : session.getRequestResponseInfo()) { HttpRequestResponseInfoWithSession itemsession = new HttpRequestResponseInfoWithSession(); itemsession.setInfo(item); itemsession.setSession(session); rrInfo.add(itemsession); } } } Collections.sort(rrInfo); for (HttpRequestResponseInfoWithSession httpreqres : rrInfo) { HttpRequestResponseInfo response = httpreqres.getInfo(); Session session = httpreqres.getSession(); PacketInfo firstPacket = session.getPackets().get(0); if (response.getDirection() == HttpDirection.REQUEST) { continue; } int statusCode = response.getStatusCode(); if (statusCode == 0) { diagnosisResults .add(new CacheEntry(null, response, Diagnosis.CACHING_DIAG_INVALID_RESPONSE, 0, firstPacket)); continue; } if (statusCode != 200 && statusCode != 206) { diagnosisResults .add(new CacheEntry(null, response, Diagnosis.CACHING_DIAG_INVALID_REQUEST, 0, firstPacket)); continue; } HttpRequestResponseInfo request = response.getAssocReqResp(); if (request == null) { diagnosisResults.add( new CacheEntry(request, response, Diagnosis.CACHING_DIAG_REQUEST_NOT_FOUND, 0, firstPacket)); continue; } totalRequestResponseBytes += response.getContentLength(); String requestType = request.getRequestType(); if (!HttpRequestResponseInfo.HTTP_GET.equals(requestType) && !HttpRequestResponseInfo.HTTP_PUT.equals(requestType) && !HttpRequestResponseInfo.HTTP_POST.equals(requestType)) { diagnosisResults .add(new CacheEntry(request, response, Diagnosis.CACHING_DIAG_INVALID_REQUEST, 0, firstPacket)); continue; } if (request.getHostName() == null || request.getObjName() == null) { diagnosisResults.add( new CacheEntry(request, response, Diagnosis.CACHING_DIAG_INVALID_OBJ_NAME, 0, firstPacket)); continue; } if (response.isNoStore() || request.isNoStore() || HttpRequestResponseInfo.HTTP_POST.equals(requestType) || HttpRequestResponseInfo.HTTP_PUT.equals(requestType)) { cacheEntries.remove(getObjFullName(request, response)); dupEntries.remove(getObjDuplicateName(request, response)); diagnosisResults .add(new CacheEntry(request, response, Diagnosis.CACHING_DIAG_NOT_CACHABLE, 0, firstPacket)); continue; } CacheEntry cacheEntry = cacheEntries.get(getObjFullName(request, response)); CacheEntry cacheDuplicateEntry = dupEntries.get(getObjDuplicateName(request, response)); CacheEntry newCacheEntry; if (cacheEntry == null) { Diagnosis diagnosis = Diagnosis.CACHING_DIAG_CACHE_MISSED; newCacheEntry = new CacheEntry(request, response, diagnosis, firstPacket); newCacheEntry.setSession(session); addToCache(newCacheEntry, rangeEntries, cacheEntries, dupEntries, session); newCacheEntry.setCacheCount(1); diagnosisResults.add(newCacheEntry); if (cacheDuplicateEntry != null) { diagnosis = Diagnosis.CACHING_DIAG_ETAG_DUPLICATE; } dulpicateEntires.add(new DuplicateEntry(request, response, diagnosis, firstPacket, session, getContent(response, session))); continue; } else { int oldCount = cacheEntry.getCacheCount(); cacheEntry.setCacheCount(oldCount + 1); } CacheExpiration expStatus = cacheExpired(cacheEntry, request.getAbsTimeStamp()); SortedSet<Range> ranges = rangeEntries .get(getObjFullName(cacheEntry.getRequest(), cacheEntry.getResponse())); boolean isfullcachehit = isFullCacheHit(response, ranges); if (isfullcachehit) { switch (expStatus) { case CACHE_EXPIRED: case CACHE_EXPIRED_HEURISTIC: newCacheEntry = handleCacheExpired(session, response, request, firstPacket, cacheEntry); diagnosisResults.add(newCacheEntry); break; case CACHE_NOT_EXPIRED: case CACHE_NOT_EXPIRED_HEURISTIC: newCacheEntry = new CacheEntry(request, response, Diagnosis.CACHING_DIAG_NOT_EXPIRED_DUP, firstPacket); dulpicateEntires.add(new DuplicateEntry(request, response, Diagnosis.CACHING_DIAG_NOT_EXPIRED_DUP, firstPacket, session, getContent(response, session))); diagnosisResults.add(newCacheEntry); break; default: newCacheEntry = null; } } else { long bytesInCache = getBytesInCache(response, ranges); switch (expStatus) { case CACHE_EXPIRED: case CACHE_EXPIRED_HEURISTIC: newCacheEntry = handleCacheExpiredWithByteInCache(session, response, request, firstPacket, cacheEntry, bytesInCache); diagnosisResults.add(newCacheEntry); break; case CACHE_NOT_EXPIRED: case CACHE_NOT_EXPIRED_HEURISTIC: newCacheEntry = new CacheEntry(request, response, Diagnosis.CACHING_DIAG_NOT_EXPIRED_DUP_PARTIALHIT, bytesInCache, firstPacket); dulpicateEntires.add(new DuplicateEntry(request, response, Diagnosis.CACHING_DIAG_NOT_EXPIRED_DUP, firstPacket, session, getContent(response, session))); diagnosisResults.add(newCacheEntry); break; default: newCacheEntry = null; } } cacheExpirationResponses.get(expStatus).add(newCacheEntry); if (newCacheEntry != null) { newCacheEntry.setCacheHit(cacheEntry); } } Set<CacheEntry> dupsWithOrig = new HashSet<CacheEntry>(); Map<String, DuplicateEntry> dulpicateEntiresMap = new HashMap<String, DuplicateEntry>(); CacheEntry cache; for (DuplicateEntry dupEntry : dulpicateEntires) { if (dupEntry.getContentLength() > 0) { String key = dupEntry.getRequest().getHostName() + dupEntry.getHttpObjectName() + dupEntry.getContentLength(); if (dupEntry.getHttpObjectName() != null) { if (!dulpicateEntiresMap.containsKey(key)) { dupEntry.setCount(1); dulpicateEntiresMap.put(key, dupEntry); } else { if (Arrays.equals(dulpicateEntiresMap.get(key).getContent(), dupEntry.getContent())) { int count = dulpicateEntiresMap.get(key).getCount(); if (count == 1) { cache = new CacheEntry(dulpicateEntiresMap.get(key).getRequest(), dulpicateEntiresMap.get(key).getResponse(), dulpicateEntiresMap.get(key).getDiagnosis(), dulpicateEntiresMap.get(key).getSessionFirstPacket()); cache.setSession(dupEntry.getSession()); dupsWithOrig.add(cache); } cache = new CacheEntry(dupEntry.getRequest(), dupEntry.getResponse(), dupEntry.getDiagnosis(), dupEntry.getSessionFirstPacket()); dupsWithOrig.add(cache); dupEntry = new DuplicateEntry(dupEntry.getRequest(), dupEntry.getResponse(), dupEntry.getDiagnosis(), dupEntry.getSessionFirstPacket(), dupEntry.getSession(), dupEntry.getContent()); dupEntry.setCount(count + 1); dulpicateEntiresMap.replace(key, dupEntry); } } } } } for (Entry<String, DuplicateEntry> cacheEntry2 : dulpicateEntiresMap.entrySet()) { if (cacheEntry2.getValue().getCount() > 1) { int count = cacheEntry2.getValue().getCount(); cache = new CacheEntry(cacheEntry2.getValue().getRequest(), cacheEntry2.getValue().getResponse(), cacheEntry2.getValue().getDiagnosis(), cacheEntry2.getValue().getSessionFirstPacket()); cache.setHitCount(count); if (count > 2) { totalRequestResponseDupBytes += (cacheEntry2.getValue().getHttpRequestResponse().getContentLength() * (count - 1)); } else { totalRequestResponseDupBytes += cacheEntry2.getValue().getHttpRequestResponse().getContentLength(); } duplicateContent.add(cache); } } duplicateContentWithOriginals.addAll(dupsWithOrig); Collections.sort(duplicateContentWithOriginals); duplicateContentBytesRatio = totalRequestResponseBytes != 0 ? (double) totalRequestResponseDupBytes / totalRequestResponseBytes : 0.0; result.setCacheExpirationResponses(cacheExpirationResponses); result.setDiagnosisResults(diagnosisResults); result.setDuplicateContent(duplicateContent); result.setDuplicateContentBytesRatio(duplicateContentBytesRatio); result.setDuplicateContentWithOriginals(duplicateContentWithOriginals); result.setTotalRequestResponseBytes(totalRequestResponseBytes); result.setTotalRequestResponseDupBytes(totalRequestResponseDupBytes); GoogleAnalyticsUtil.getGoogleAnalyticsInstance().sendAnalyticsTimings(cacheAnalysisTitle, System.currentTimeMillis() - analysisStartTime, analysisCategory); return result; }  @Override CacheAnalysis analyze(List<Session> sessionlist); byte[] getContent(HttpRequestResponseInfo response, Session session);  }