/** Method to assign the burst states. */ private void analyzeBursts() { List<UserEvent> userEvents = analysis.getUserEvents(); List<CpuActivity> cpuEvents = analysis.getCpuActivityList(); int userEventsSize = userEvents.size(); int cpuEventsSize = cpuEvents.size(); int userEventPointer = 0; int cpuPointer = 0; // Analyze each burst Burst b = null; Burst lastBurst; for (Iterator<Burst> i = burstCollection.iterator(); i.hasNext(); ) { lastBurst = b; b = i.next(); // Step 1: Remove background packets List<PacketInfo> pktIdx = new ArrayList<PacketInfo>(b.getPackets().size()); int payloadLen = 0; Set<TcpInfo> tcpInfo = new HashSet<TcpInfo>(); for (PacketInfo p : b.getPackets()) { if (p.getAppName() != null) { payloadLen += p.getPayloadLen(); pktIdx.add(p); TcpInfo tcp = p.getTcpInfo(); if (tcp != null) { tcpInfo.add(tcp); } } } if (pktIdx.size() == 0) { assert (payloadLen == 0); b.addBurstInfo(BurstInfo.BURST_BKG); continue; } PacketInfo pkt0 = pktIdx.get(0); TcpInfo info0 = pkt0.getTcpInfo(); double time0 = pkt0.getTimeStamp(); // Step 2: a long burst? if (b.getEndTime() - b.getBeginTime() > profile.getLargeBurstDuration() && payloadLen > profile.getLargeBurstSize()) { b.addBurstInfo(BurstInfo.BURST_LONG); ++longBurstCount; continue; } // Step 3: Contains no payload? if (payloadLen == 0) { if (tcpInfo.contains(TcpInfo.TCP_CLOSE)) { b.addBurstInfo(BurstInfo.BURST_FIN); } if (tcpInfo.contains(TcpInfo.TCP_ESTABLISH)) { b.addBurstInfo(BurstInfo.BURST_SYN); } if (tcpInfo.contains(TcpInfo.TCP_RESET)) { b.addBurstInfo(BurstInfo.BURST_RST); } if (tcpInfo.contains(TcpInfo.TCP_KEEP_ALIVE) || tcpInfo.contains(TcpInfo.TCP_KEEP_ALIVE_ACK)) { b.addBurstInfo(BurstInfo.BURST_KEEPALIVE); } if (tcpInfo.contains(TcpInfo.TCP_ZERO_WINDOW)) { b.addBurstInfo(BurstInfo.BURST_ZEROWIN); } if (tcpInfo.contains(TcpInfo.TCP_WINDOW_UPDATE)) { b.addBurstInfo(BurstInfo.BURST_WINUPDATE); } if (b.getBurstInfos().size() == 0 && (info0 == TcpInfo.TCP_ACK_RECOVER || info0 == TcpInfo.TCP_ACK_DUP)) { b.addBurstInfo(BurstInfo.BURST_LOSS_RECOVER); } if (b.getBurstInfos().size() > 0) continue; } // Step 4: Server delay if (pkt0.getDir() == PacketInfo.Direction.DOWNLINK && (info0 == TcpInfo.TCP_DATA || info0 == TcpInfo.TCP_ACK)) { b.addBurstInfo(BurstInfo.BURST_SERVER_DELAY); continue; } // Step 5: Loss recover if (info0 == TcpInfo.TCP_ACK_DUP || info0 == TcpInfo.TCP_DATA_DUP) { b.addBurstInfo(BurstInfo.BURST_LOSS_DUP); continue; } if (info0 == TcpInfo.TCP_DATA_RECOVER || info0 == TcpInfo.TCP_ACK_RECOVER) { b.addBurstInfo(BurstInfo.BURST_LOSS_RECOVER); continue; } // Step 6: User triggered final double USER_EVENT_SMALL_TOLERATE = profile.getUserInputTh(); if (payloadLen > 0) { UserEvent ue = null; while ((userEventPointer < userEventsSize) && ((ue = userEvents.get(userEventPointer)).getReleaseTime() < (time0 - USER_EVENT_TOLERATE))) ++userEventPointer; BurstInfo bi = ue != null ? ((ue.getEventType() == UserEventType.SCREEN_LANDSCAPE || ue.getEventType() == UserEventType.SCREEN_PORTRAIT) ? BurstInfo.BURST_SCREEN_ROTATION_INPUT : BurstInfo.BURST_USER_INPUT) : null; int j = userEventPointer; double minGap = Double.MAX_VALUE; while (j < userEventsSize) { UserEvent uEvent = userEvents.get(j); if (withinTolerate(uEvent.getPressTime(), time0)) { double gap = time0 - uEvent.getPressTime(); if (gap < minGap) { minGap = gap; } } if (withinTolerate(uEvent.getReleaseTime(), time0)) { double gap = time0 - uEvent.getReleaseTime(); if (gap < minGap) { minGap = gap; } } if (uEvent.getPressTime() > time0) { break; } j++; } if (minGap < USER_EVENT_SMALL_TOLERATE) { b.addBurstInfo(bi); continue; } else if (minGap < USER_EVENT_TOLERATE && (lastBurst == null || lastBurst.getEndTime() < b.getBeginTime() - minGap)) { double cpuBegin = time0 - minGap; double cpuEnd = time0; // Check CPU usage while (cpuPointer < cpuEventsSize) { double t = cpuEvents.get(cpuPointer).getBeginTimeStamp(); if (t < b.getBeginTime() - USER_EVENT_TOLERATE) { ++cpuPointer; } else { break; } } int k = cpuPointer; double s = 0.0f; int ns = 0; while (k < cpuEventsSize) { CpuActivity cpuAct = cpuEvents.get(k); double t = cpuAct.getBeginTimeStamp(); if (t > cpuBegin && t < cpuEnd) { s += cpuAct.getUsage(); ns++; } if (t >= cpuEnd) { break; } k++; } if (ns > 0 && (s / ns) > AVG_CPU_USAGE_THRESHOLD) { b.addBurstInfo(bi); b.addBurstInfo(BurstInfo.BURST_CPU_BUSY); continue; } } } // Step 7: Client delay if (b.getBurstInfos().size() == 0 && payloadLen == 0) { b.addBurstInfo(BurstInfo.BURST_UNKNOWN); } else { b.addBurstInfo(BurstInfo.BURST_CLIENT_DELAY); } } }