Merge remote-tracking branch 'origin/tizen' into da-setup 32/39032/1 da-setup
authorheeyoung <heeyoung1008.hwang@samsung.com>
Thu, 7 May 2015 10:36:06 +0000 (19:36 +0900)
committerheeyoung <heeyoung1008.hwang@samsung.com>
Thu, 7 May 2015 10:36:06 +0000 (19:36 +0900)
Conflicts:
org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/communicator/Communicator30.java
org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/logparser/SWAPLogParser.java

Change-Id: I4ce84a6d5b11904955f34596a839cc26405fecf9
Signed-off-by: heeyoung <heeyoung1008.hwang@samsung.com>
1  2 
org.tizen.dynamicanalyzer.common/src/org/tizen/dynamicanalyzer/util/ByteUtil.java
org.tizen.dynamicanalyzer.workbench/dynamic-analyzer/config/setting
org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/common/AnalyzerConstants.java
org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/channel/data/DataChannelConstants.java
org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/communicator/Communicator30.java
org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/logparser/LogParser.java
org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/logparser/MessageParser.java
org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/model/data/AppStartupData.java
org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/model/data/LogDataFactory.java
org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/info/appStartup/AppStartupDataManager.java

@@@ -406,20 -414,8 +414,20 @@@ public class ByteUtil 
                                line = -1;
                        }
                }
-               // System.out.println(" ====---- print byte array end----====");
+               // Logger.debug(" ====---- print byte array end----====");
        }
 -
 +      
 +      final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
 +      // for debugging convenience
 +      // TODO: add unittest
 +      public static String bytesToHex(byte[] bytes) {
 +          char[] hexChars = new char[bytes.length * 2];
 +          for ( int j = 0; j < bytes.length; j++ ) {
 +              int v = bytes[j] & 0xFF;
 +              hexChars[j * 2] = hexArray[v >>> 4];
 +              hexChars[j * 2 + 1] = hexArray[v & 0x0F];
 +          }
 +          return new String(hexChars);
 +      }
  
  }
index 0000000,4844d41..f325ad0
mode 000000,100755..100755
--- /dev/null
@@@ -1,0 -1,321 +1,323 @@@
+ /*
+  *  Dynamic Analyzer
+  *
+  * Copyright (c) 2013 Samsung Electronics Co., Ltd. All rights reserved.
+  *
+  * Contact: 
+  * Jaewon Lim <jaewon81.lim@samsung.com>
+  * WooJin Jung <woojin2.jung@samsung.com>
+  * Jooyoul Lee <jy.exe.lee@samsung.com>
+  * Juyoung Kim <j0.kim@samsung.com>
+  *
+  * Licensed under the Apache License, Version 2.0 (the "License");
+  * you may not use this file except in compliance with the License.
+  * You may obtain a copy of the License at
+  *
+  * http://www.apache.org/licenses/LICENSE-2.0
+  *
+  * Unless required by applicable law or agreed to in writing, software
+  * distributed under the License is distributed on an "AS IS" BASIS,
+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  * See the License for the specific language governing permissions and
+  * limitations under the License.
+  * 
+  * Contributors:
+  * - S-Core Co., Ltd
+  * 
+  */
+ package org.tizen.dynamicanalyzer.swap.logparser;
++import static org.tizen.dynamicanalyzer.swap.channel.data.DataChannelConstants.MSG_APP_STARTUP_STAGE;
+ import static org.tizen.dynamicanalyzer.swap.channel.data.DataChannelConstants.MSG_CONTEXT_SWITCH_ENTRY;
+ import static org.tizen.dynamicanalyzer.swap.channel.data.DataChannelConstants.MSG_CONTEXT_SWITCH_EXIT;
+ import static org.tizen.dynamicanalyzer.swap.channel.data.DataChannelConstants.MSG_DATA_RECORD;
+ import static org.tizen.dynamicanalyzer.swap.channel.data.DataChannelConstants.MSG_DATA_SAMPLE;
+ import static org.tizen.dynamicanalyzer.swap.channel.data.DataChannelConstants.MSG_DATA_SYSTEM;
+ import static org.tizen.dynamicanalyzer.swap.channel.data.DataChannelConstants.MSG_FUNCTION_ENTRY;
+ import static org.tizen.dynamicanalyzer.swap.channel.data.DataChannelConstants.MSG_FUNCTION_EXIT;
+ import static org.tizen.dynamicanalyzer.swap.channel.data.DataChannelConstants.MSG_PROBE_SCREENSHOT;
+ import java.util.ArrayDeque;
+ import java.util.ArrayList;
+ import java.util.Deque;
+ import java.util.HashMap;
+ import java.util.List;
+ import java.util.Map;
+ import org.tizen.dynamicanalyzer.common.AnalyzerConstants;
+ import org.tizen.dynamicanalyzer.common.AnalyzerManager;
+ import org.tizen.dynamicanalyzer.common.Global;
+ import org.tizen.dynamicanalyzer.common.SymbolManager;
+ import org.tizen.dynamicanalyzer.communicator.DACommunicator;
+ import org.tizen.dynamicanalyzer.control.DataThread;
+ import org.tizen.dynamicanalyzer.nl.InformationViewLabels;
+ import org.tizen.dynamicanalyzer.swap.channel.data.DataChannelConstants;
+ import org.tizen.dynamicanalyzer.swap.model.data.LogData;
+ import org.tizen.dynamicanalyzer.swap.model.data.ProfileData;
+ import org.tizen.dynamicanalyzer.swap.model.data.ScreenShotData;
+ import org.tizen.dynamicanalyzer.ui.info.callstack.CallStackInserter;
+ import org.tizen.dynamicanalyzer.ui.info.screenshot.SocketClient;
+ import org.tizen.dynamicanalyzer.ui.summary.profiling.FunctionUsageProfiler;
+ import org.tizen.dynamicanalyzer.util.Logger;
+ public class LogParser extends DataThread<List<LogData>> {
+       private static LogParser instance = new LogParser();
+       public static List<LogData> END_OF_QUEUE = new ArrayList<LogData>();
+       // map for matching exit log with entry log
+       private Map<Integer, Deque<Long>> functionEntryStackByTidMap = new HashMap<Integer, Deque<Long>>();
+       // list of image thread
+       private List<Thread> imageThreads = new ArrayList<Thread>();
+       public static LogParser getInstance() {
+               return instance;
+       }
+       @Override
+       protected String getThreadName() {
+               return AnalyzerConstants.LOG_QUEUE_OBSERVING_THREAD;
+       }
+       @Override
+       protected boolean workAfterStart() {
+               return true;
+       }
+       @Override
+       protected boolean workAfterStopNormal() {
+               // wait for all image thread is finished
+               synchronized (imageThreads) {
+                       while (!imageThreads.isEmpty()) {
+                               try {
+                                       imageThreads.wait();
+                               } catch (InterruptedException e) {
+                                       Logger.exception(e);
+                                       return false;
+                               }
+                       }
+               }
+               return true;
+       }
+       @Override
+       protected boolean workAfterStopForced() {
+               // force to stop image thread and
+               // wait for all image thread is finished
+               synchronized (imageThreads) {
+                       for (Thread entry : imageThreads) {
+                               entry.interrupt();
+                       }
+                       while (!imageThreads.isEmpty()) {
+                               try {
+                                       imageThreads.wait();
+                               } catch (InterruptedException e) {
+                                       Logger.exception(e);
+                                       return false;
+                               }
+                       }
+               }
+               return true;
+       }
+       @Override
+       protected void resetBeforeStart() {
+               functionEntryStackByTidMap.clear();
+               imageThreads.clear();
+       }
+       @Override
+       protected void clearAfterStop() {
+               functionEntryStackByTidMap.clear();
+       }
+       public Deque<Long> getFunctionEntryStack(int tid) {
+               Deque<Long> functionEntryStack = functionEntryStackByTidMap.get(tid);
+               if (null == functionEntryStack) {
+                       functionEntryStack = new ArrayDeque<Long>();
+                       functionEntryStackByTidMap.put(tid, functionEntryStack);
+               }
+               return functionEntryStack;
+       }
+       /*** log parsing thread ***/
+       @Override
+       public void run() {
+               Thread curThread = Thread.currentThread();
+               try {
+                       List<LogData> loglist;
+                       while (testThread(curThread)) {
+                               loglist = pollData();
+                               if (loglist == null || loglist == LogParser.END_OF_QUEUE) {
+                                       break;
+                               }
+                               logParsing(loglist);
+                       }
+               } finally {
+                       DataManagerRegistry.updateLog(LogPackage.END_OF_QUEUE);
+                       CallStackInserter.getInstance().pushData(CallStackInserter.END_OF_QUEUE);
+               }
+               Logger.debug("log parsing thread end!!"); //$NON-NLS-1$
+       }
+       private void logParsing(List<LogData> loglist) {
+               int size = loglist.size();
+               LogPackage logPack = new LogPackage();
+               for (int i = 0; i < size; i++) {
+                       LogData log = loglist.get(i);
+                       if (null == log) {
+                               continue;
+                       }
+                       int id = log.getMsgID();
+                       boolean ret;
+                       switch (id) {
+                       case MSG_DATA_SAMPLE:
+                               if (!AnalyzerManager.isProcessInfoArrived()) {
+                                       break;
+                               }
+                               packLog(log, logPack);
+                               break;
+                       case MSG_FUNCTION_ENTRY:
+                       case MSG_FUNCTION_EXIT:
+                               if (!AnalyzerManager.isProcessInfoArrived()) {
+                                       break;
+                               }
+                               ret = processFunctionData((ProfileData) log);
+                               if (ret) {
+                                       packLog(log, logPack);
+                               }
+                               break;
+                       case MSG_DATA_SYSTEM:
+                       case MSG_DATA_RECORD:
+                       case MSG_CONTEXT_SWITCH_ENTRY:
+                       case MSG_CONTEXT_SWITCH_EXIT:
++                      case MSG_APP_STARTUP_STAGE:
+                               packLog(log, logPack);
+                               break;
+                       case MSG_PROBE_SCREENSHOT:
+                               processScreenshotData((ScreenShotData) log);
+                               packLog(log, logPack);
+                               Global.getRuntimeCallstackManager().makeCallstackWithoutBacktrace(log);
+                               break;
+                       default:
+                               packLog(log, logPack);
+                               Global.getRuntimeCallstackManager().makeCallstackWithoutBacktrace(log);
+                               break;
+                       }
+               }
+               updateLog(logPack);
+       }
+       private boolean processFunctionData(ProfileData pData) {
+               int msgID = pData.getMsgID();
+               Deque<Long> functionStack = getFunctionEntryStack(pData.getTid());
+               // entry / exit pair matching
+               if (msgID == DataChannelConstants.MSG_FUNCTION_ENTRY) {
+                       functionStack.addLast(pData.getSeq());
+               } else { // msg_function_exit
+                       if (!functionStack.isEmpty()) {
+                               pData.setEntrySeq(functionStack.removeLast());
+                       } else { // size <= 0 : bug (exit without entry)
+                               Logger.error("function exit log without entry log");
+                       }
+               }
+               if (pData.getProbeType() != AnalyzerConstants.FUNCTION_TYPE_FILE) {
+                       int apiID = SymbolManager.getFuncId(pData, pData.getPcAddr(), pData.getPid(),
+                                       pData.getTime());
+                       if (apiID < 0) {
+                               return false;
+                       } else {
+                               String apiName = Global.getFunctionName(apiID);
+                               if (apiName.equals(InformationViewLabels.CALLSTACK_TABLE_UNKNOWN_FUNCTION)) {
+                                       return false;
+                               } else {
+                                       pData.setApiId(apiID);
+                               }
+                       }
+                       Global.getRuntimeCallstackManager().makeUserCallstack(pData,
+                                       FunctionUsageProfiler.getInstance().getProfileDataMakerByPid(pData.getPid()));
+               }
+               return true;
+       }
+       private void processScreenshotData(ScreenShotData log) {
+               // get image file from target or ecs
+               if (DACommunicator.isTargetEmulator() && SocketClient.getInstance().isConnected()) {
+                       Global.getCurrentDeviceInfo().emulatorScreenshot.send();
+                       String remoteImgPath = Global.getCurrentDeviceInfo().emulatorScreenshot.getFilePath();
+                       processImagefromECS(remoteImgPath, log.getOrientation());
+               } else {
+                       processImage(log.getImageFilePath(), log.getOrientation());
+               }
+       }
+       private void processImage(String from, int angle) {
+               if (angle != 0) {
+                       Logger.debug("[ image rotate : " + angle + " ]");
+               }
+               Thread thread = new Thread(null, new ImageProcessingThread(this, from, angle, false),
+                               AnalyzerConstants.MESSAGE_INTERNAL_IMAGE_THREAD);
+               synchronized (imageThreads) {
+                       imageThreads.add(thread);
+               }
+               // The thread must be started after it is queued
+               thread.start();
+       }
+       private void processImagefromECS(String path, int angle) {
+               if (angle != 0) {
+                       Logger.debug("[ image rotate : " + angle + " ]");
+               }
+               Thread thread = new Thread(null, new ImageProcessingThread(this, path, angle, true),
+                               AnalyzerConstants.MESSAGE_INTERNAL_IMAGE_THREAD);
+               synchronized (imageThreads) {
+                       imageThreads.add(thread);
+               }
+               // The thread must be started after it is queued
+               thread.start();
+       }
+       // notified from image thread that the thread is finished
+       public void setImageThreadFinished(Thread finishedThread) {
+               synchronized (imageThreads) {
+                       imageThreads.remove(finishedThread);
+                       imageThreads.notifyAll();
+               }
+       }
+       private void updateLog(LogPackage logPack) {
+               if (logPack != null && !logPack.isEmpty()) {
+                       DataManagerRegistry.updateLog(logPack);
+               }
+       }
+       private void packLog(LogData logData, LogPackage logPack) {
+               // a special case for file analysis
+               if (logData.getMsgID() == DataChannelConstants.MSG_FUNCTION_ENTRY
+                               || logData.getMsgID() == DataChannelConstants.MSG_FUNCTION_EXIT) {
+                       ProfileData data = (ProfileData) logData;
+                       if (data.getProbeType() == AnalyzerConstants.FUNCTION_TYPE_FILE) {
+                               logPack.setLogs(DataChannelConstants.MSG_FUCNTION_ENTRY_EXIT, logData);
+                               return;
+                       }
+               }
+               logPack.setLogs(logData.getMsgID(), logData);
+       }
+ }
@@@ -524,13 -240,9 +240,10 @@@ public class MessageParser extends Data
                case DataChannelConstants.MSG_CONTEXT_SWITCH_ENTRY:
                case DataChannelConstants.MSG_CONTEXT_SWITCH_EXIT:
                case DataChannelConstants.MSG_DATA_RECORD:
 +              case DataChannelConstants.MSG_APP_STARTUP_STAGE:        
                        if (AnalyzerManager.isProcessInfoArrived()) {
-                               // make log
-                               log = LogDataFactory.createInstance(data);
-                               if (null != log) {
-                                       buffer.add(log);
-                                       messageCount += 1;
+                               if (log.makeDataPublic(Global.getProject().getProfilingStartTime())) {
+                                       sendBuffer.add(log);
                                }
                        }
                        break;
index bd831a6,0000000..1e0448a
mode 100644,000000..100644
--- /dev/null
@@@ -1,108 -1,0 +1,106 @@@
- import org.tizen.dynamicanalyzer.constant.CommonConstants;
- import org.tizen.dynamicanalyzer.swap.logparser.MessageParser;
 +/*
 + *  Dynamic Analyzer
 + *
 + * Copyright (c) 2013 Samsung Electronics Co., Ltd. All rights reserved.
 + *
 + * Contact: 
 + * Heeyoung Hwang <heeyoung1008.hwang@samsung.com>
 + * Juyoung Kim <j0.kim@samsung.com>
 + *
 + * Licensed under the Apache License, Version 2.0 (the "License");
 + * you may not use this file except in compliance with the License.
 + * You may obtain a copy of the License at
 + *
 + * http://www.apache.org/licenses/LICENSE-2.0
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the License is distributed on an "AS IS" BASIS,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the License for the specific language governing permissions and
 + * limitations under the License.
 + * 
 + * Contributors:
 + * - S-Core Co., Ltd
 + * 
 + */
 +package org.tizen.dynamicanalyzer.swap.model.data;
 +
 +import org.tizen.dynamicanalyzer.common.Global;
- import org.tizen.dynamicanalyzer.util.ByteUtil;
 +import org.tizen.dynamicanalyzer.swap.model.DATime;
-       public boolean makeData(byte[] data) {
-               super.makeData(data);
-               index = MessageParser.MSG_HEADER_SIZE;
-               
-               pid = ByteUtil.toInt(data, index);
-               index += CommonConstants.INT_SIZE;
-               
-               stageid = ByteUtil.toInt(data, index);
-               index += CommonConstants.INT_SIZE;
 +import org.tizen.dynamicanalyzer.util.Logger;
 +
 +public class AppStartupData extends LogData {
 +
 +      int pid = 0;
 +      int stageid = 0;
 +      long startTime = 0;
 +      long endTime = 0;
 +      
-               int startSec = ByteUtil.toInt(data, index);
-               index += CommonConstants.INT_SIZE;
-               int startNano = ByteUtil.toInt(data, index);
-               index += CommonConstants.INT_SIZE;
-               startTime = calculateTimeData(startSec, startNano);
++      public AppStartupData() {
++      }
++
++      @Override
++      public AppStartupData clone() throws CloneNotSupportedException {
++              throw new CloneNotSupportedException();
++      }
++      
++      @Override
++      protected boolean makeData(DATime startTime) {
++              super.makeData(startTime);
++
++              pid = getInt();
++              stageid = getInt();
 +              
 +              // start time
-               int endSec = ByteUtil.toInt(data, index);
-               index += CommonConstants.INT_SIZE;
-               int endNano = ByteUtil.toInt(data, index);
-               index += CommonConstants.INT_SIZE;
-               endTime = calculateTimeData(endSec, endNano);
++              int startSec = getInt();
++              int startNano =getInt();
++              this.startTime = calculateTimeData(startSec, startNano);
 +              
 +              // end time
++              int endSec = getInt();
++              int endNano =getInt();
++              this.endTime = calculateTimeData(endSec, endNano);
 +              
 +              Logger.debug("Application startup :" + pid + "," + stageid + "," + startSec + "." + startNano
 +              + ","+ endSec + "." + endNano);
 +              return true;
 +      }
 +
 +      public int getPid() {
 +              return pid;
 +      }
 +
 +      public void setPid(int pid) {
 +              this.pid = pid;
 +      }
 +
 +      public int getStageid() {
 +              return stageid;
 +      }
 +
 +      public void setStageid(int stageid) {
 +              this.stageid = stageid;
 +      }
 +
 +      public long getStartTime() {
 +              return startTime;
 +      }
 +
 +      public void setStartTime(long startTime) {
 +              this.startTime = startTime;
 +      }
 +
 +      public long getEndTime() {
 +              return endTime;
 +      }
 +
 +      public void setEndTime(long endTime) {
 +              this.endTime = endTime;
 +      }
 +      
 +      private long calculateTimeData(int sec, int nano) {
 +              DATime time = new DATime(sec, nano); 
 +              DATime resultTime = time.subtract(Global.getProject().getProfilingStartTime()); 
 +              return resultTime.getLongTime();
 +      }
 +}
@@@ -88,12 -84,10 +85,11 @@@ public class LogDataFactory 
                logIDList.add(MSG_DATA_SAMPLE);
                logIDList.add(MSG_CONTEXT_SWITCH_ENTRY);
                logIDList.add(MSG_CONTEXT_SWITCH_EXIT);
 +              logIDList.add(MSG_APP_STARTUP_STAGE);
        }
  
-       public static LogData createInstance(byte[] data) {
-               boolean result;
-               int id = ByteUtil.toInt(data, 0);
+       public static LogData createInstance(byte[] header) {
+               int id = ByteUtil.toInt(header, DataChannelConstants.MSGID_INDEX);
  
                LogData output = null;
                switch (id) {
                case MSG_CONTEXT_SWITCH_EXIT:
                        output = new ContextSwitchData();
                        break;
 +              case MSG_APP_STARTUP_STAGE:
 +                      output = new AppStartupData();
 +                      break;
                default:
-                       return null;
-               }
-               result = output.makeData(data);
-               if (result == true) {
-                       return output;
-               } else { // error occurred during parse LogData
-                       return null;
+                       output = new LogData();
+                       break;
                }
+               output.init(header);
+               return output;
        }
  
        public static String getLogFormatName(int id) {
index 735280a,0000000..fe7b16e
mode 100644,000000..100644
--- /dev/null
@@@ -1,92 -1,0 +1,91 @@@
- import org.tizen.dynamicanalyzer.database.DBInsertManager;
 +/*
 + *  Dynamic Analyzer
 + *
 + * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved.
 + *
 + * Contact: 
 + * Heeyoung Hwang <heeyoung1008.hwang@samsung.com>
 + * Juyoung Kim <j0.kim@samsung.com>
 + *
 + * Licensed under the Apache License, Version 2.0 (the "License");
 + * you may not use this file except in compliance with the License.
 + * You may obtain a copy of the License at
 + *
 + * http://www.apache.org/licenses/LICENSE-2.0
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the License is distributed on an "AS IS" BASIS,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the License for the specific language governing permissions and
 + * limitations under the License.
 + * 
 + * Contributors:
 + * - S-Core Co., Ltd
 + * 
 + */
 +
 +package org.tizen.dynamicanalyzer.ui.info.appStartup;
 +
 +import java.util.ArrayList;
 +import java.util.List;
 +
-               appStartupDBInserter = DBInsertManager.makeInserter(appStartupDBTable);
 +import org.tizen.dynamicanalyzer.database.DBInserter;
 +import org.tizen.dynamicanalyzer.swap.channel.data.DataChannelConstants;
 +import org.tizen.dynamicanalyzer.swap.logparser.LogPackage;
 +import org.tizen.dynamicanalyzer.swap.logparser.Logs;
 +import org.tizen.dynamicanalyzer.swap.logparser.PageDataManager;
 +import org.tizen.dynamicanalyzer.swap.model.data.LogData;
 +import org.tizen.dynamicanalyzer.swap.model.data.AppStartupData;
 +
 +public class AppStartupDataManager extends PageDataManager {  
 +
 +      private static AppStartupDataManager instance = null;
 +      
 +      private AppStartupDBTable appStartupDBTable = null;
 +      private DBInserter appStartupDBInserter = null;
 +      
 +      private AppStartupDataManager() {
 +              appStartupDBTable = new AppStartupDBTable();
++              appStartupDBInserter = makeInserter(appStartupDBTable);
 +      }
 +
 +      public AppStartupDBTable getAppStartupDBTable() {
 +              return appStartupDBTable;
 +      }
 +
 +      public synchronized static AppStartupDataManager getInstance() {
 +              if (null == instance) {
 +                      instance = new AppStartupDataManager();
 +              }
 +              return instance;
 +      }
 +
 +      @Override
 +      protected void makeData(LogPackage pack) {
 +              Logs entryLogs = pack.getLogs(DataChannelConstants.MSG_APP_STARTUP_STAGE);
 +              if (null != entryLogs && entryLogs.getRawLogs().size() != 0) {
 +                      List<LogData> logList = entryLogs.getLogs();
 +                      List<List<Object>> insertDataList = new ArrayList<List<Object>>();
 +                      int size = logList.size();
 +                      for (int i = 0; i < size; i++) {
 +                              AppStartupData data = (AppStartupData) logList.get(i);
 +                              List<Object> insertRowData = new ArrayList<Object>();
 +
 +                              try {
 +                                      insertRowData.add(new Integer(data.getPid()));
 +                                      insertRowData.add(new Integer(data.getStageid()));
 +                                      insertRowData.add(new Long(data.getStartTime()));
 +                                      insertRowData.add(new Long(data.getEndTime()));
 +                              } catch (ArrayIndexOutOfBoundsException e) {
 +                                      e.printStackTrace();
 +                              }
 +                              insertDataList.add(insertRowData);
 +                      }
 +                      
 +                      // insert table
 +                      if (insertDataList.size() > 0) {
 +                              appStartupDBInserter.pushData(insertDataList);
 +                      }
 +              }
 +      }
 +}