[Title] add MSG_PROCESS_COMM for web app, refactor db connection(multi-connection) 46/21646/1
authorgreatim <jaewon81.lim@samsung.com>
Mon, 26 May 2014 03:43:11 +0000 (12:43 +0900)
committergreatim <jaewon81.lim@samsung.com>
Mon, 26 May 2014 03:43:11 +0000 (12:43 +0900)
[Desc.]
[Issue]

Change-Id: Ie46eaba1f7390fc8fbe1b440a8ee6f4cf0c1ebe2

org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/database/SqlConnectionManager.java
org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/channel/data/DataChannelConstants.java
org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/channel/data/ProcessInfoPackage.java
org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/logparser/MessageParser.java
org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/toolbar/ToolbarArea.java

index 2940b73..46f8a6e 100644 (file)
@@ -10,6 +10,8 @@ import java.sql.SQLWarning;
 import java.sql.Statement;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
 
 import org.tizen.dynamicanalyzer.util.CommonUtil;
 import org.tizen.dynamicanalyzer.util.DALogger;
@@ -17,26 +19,77 @@ import org.tizen.dynamicanalyzer.util.DALogger;
 public class SqlConnectionManager {
        private static final DALogger DA_LOG = DALogger.getInstance();
 
-       private static Connection connection = null;
-
+       // apply multi connection of DB
+       private static final int CONNECTION_COUNT_UPDATE = 8;
+       private static final int CONNECTION_COUNT_QUERY = 8;
+       private static BlockingQueue<Connection> updateConnections = null;
+       private static BlockingQueue<Connection> queryConnections = null;
+       private static int realUpdateConnCount = 0;
+       private static int realQueryConnCount = 0;
+
+       // DATABASE state
+       private enum State {
+               NOT_CONNECTED,
+               CONNECTED,
+               TO_BE_CLOSED
+       }
+       
+       private static State state = State.NOT_CONNECTED;
+       
        public static boolean establishConnection(String dbFilePath) {
                boolean result = true;
                try {
                        synchronized (SqlConnectionManager.class) {
-                               if (connection == null) {
+                               if (updateConnections == null && queryConnections == null) {
+                                       updateConnections = new LinkedBlockingQueue<Connection>();
+                                       queryConnections = new LinkedBlockingQueue<Connection>();
+                                       realUpdateConnCount = 0;
+                                       realQueryConnCount = 0;
+
                                        Class.forName("org.hsqldb.jdbcDriver");
                                        String dbUrl = "jdbc:hsqldb:"
                                                        + dbFilePath
-                                                       + ";shutdown=false;hsqldb.default_table_type=cached;hsqldb.large_data=true;hdqldb.log_data=false"; //$NON-NLS-1$
-                                       connection = DriverManager.getConnection(dbUrl, "SA", "");
-                                       SQLWarning warning = connection.getWarnings();
-                                       while (warning != null) {
-                                               DA_LOG.debug("[DB] Message: " + warning.getMessage());
-                                               DA_LOG.debug("[DB] SQL state: " + warning.getSQLState());
-                                               DA_LOG.debug("[DB] Vendor code: "
-                                                               + warning.getErrorCode());
-                                               warning = warning.getNextWarning();
+                                                       + ";shutdown=false;hsqldb.default_table_type=cached"
+                                                       + ";hsqldb.tx=mvcc;hsqldb.large_data=true;hdqldb.log_data=false"; //$NON-NLS-1$
+
+                                       Connection conn;
+                                       // establish update connection pool
+                                       for (int i = 0; i < CONNECTION_COUNT_UPDATE; i++) {
+                                               conn = DriverManager.getConnection(dbUrl, "SA", "");
+                                               updateConnections.offer(conn);
+                                               realUpdateConnCount++;
+
+                                               SQLWarning warning = conn.getWarnings();
+                                               while (warning != null) {
+                                                       DA_LOG.debug("[DB][" + i + "] Message: "
+                                                                       + warning.getMessage());
+                                                       DA_LOG.debug("[DB][" + i + "] SQL state: "
+                                                                       + warning.getSQLState());
+                                                       DA_LOG.debug("[DB][" + i + "] Vendor code: "
+                                                                       + warning.getErrorCode());
+                                                       warning = warning.getNextWarning();
+                                               }
                                        }
+
+                                       // establish query connection pool
+                                       for (int i = 0; i < CONNECTION_COUNT_QUERY; i++) {
+                                               conn = DriverManager.getConnection(dbUrl, "SA", "");
+                                               queryConnections.offer(conn);
+                                               realQueryConnCount++;
+
+                                               SQLWarning warning = conn.getWarnings();
+                                               while (warning != null) {
+                                                       DA_LOG.debug("[DB][" + i + "] Message: "
+                                                                       + warning.getMessage());
+                                                       DA_LOG.debug("[DB][" + i + "] SQL state: "
+                                                                       + warning.getSQLState());
+                                                       DA_LOG.debug("[DB][" + i + "] Vendor code: "
+                                                                       + warning.getErrorCode());
+                                                       warning = warning.getNextWarning();
+                                               }
+                                       }
+
+                                       state = State.CONNECTED;
                                }
                        }
                } catch (ClassNotFoundException e) {
@@ -44,7 +97,7 @@ public class SqlConnectionManager {
                } catch (SQLException e) {
                        e.printStackTrace();
                } finally {
-                       if (connection == null)
+                       if (updateConnections == null || queryConnections == null)
                                result = false;
                        else
                                result = true;
@@ -55,61 +108,162 @@ public class SqlConnectionManager {
 
        public static void closeConnection() {
                synchronized (SqlConnectionManager.class) {
-                       if (connection != null) {
-                               try {
-                                       Statement st = connection.createStatement();
-                                       st.execute("SHUTDOWN");
-                                       CommonUtil.tryClose(st);
-                                       connection.close();
-                               } catch (SQLException se) {
-                                       if (!se.getSQLState().equals("XJ015")) {
-                                               DA_LOG.debug("DB did not shutdown normally");
+                       // set close state
+                       // this value prevent other thread from getting connection
+                       state = State.TO_BE_CLOSED;
+
+                       // close update connection
+                       if (updateConnections != null) {
+                               synchronized (updateConnections) {
+                                       while (updateConnections.size() != realUpdateConnCount) {
+                                               // wait until other execution is finished
+                                               try {
+                                                       updateConnections.wait();
+                                               } catch (InterruptedException e) {
+                                                       e.printStackTrace();
+                                               }
+                                       }
+                               }
+
+                               // close all connection
+                               Connection conn;
+                               while ((conn = updateConnections.poll()) != null) {
+                                       try {
+                                               conn.close();
+                                       } catch (SQLException e) {
+                                               e.printStackTrace();
                                        }
                                }
-                               connection = null;
                        }
+
+                       // close query connection
+                       if (queryConnections != null) {
+                               synchronized (queryConnections) {
+                                       while (queryConnections.size() != realQueryConnCount) {
+                                               // wait until other execution is finished
+                                               try {
+                                                       queryConnections.wait();
+                                               } catch (InterruptedException e) {
+                                                       e.printStackTrace();
+                                               }
+                                       }
+                               }
+
+                               // close all connection
+                               Connection conn;
+                               while ((conn = queryConnections.poll()) != null) {
+                                       // if it is last connection of database
+                                       if(queryConnections.size() == 0) {
+                                               Statement st = null;
+                                               try {
+                                                       st = conn.createStatement();
+                                                       st.execute("SHUTDOWN");
+                                               } catch (SQLException se) {
+                                                       if (!se.getSQLState().equals("XJ015")) {
+                                                               DA_LOG.debug("DB did not shutdown normally");
+                                                       }
+                                               } finally {
+                                                       CommonUtil.tryClose(st);
+                                               }
+                                       }
+                                       
+                                       try {
+                                               conn.close();
+                                       } catch (SQLException e) {
+                                               e.printStackTrace();
+                                       }
+                               }
+                       }
+
+                       updateConnections = null;
+                       queryConnections = null;
+                       
+                       state = State.NOT_CONNECTED;
                }
        }
 
-       public static boolean isConnected() {
-               return (connection != null);
-       }
+       private static Connection getUpdateConnection() {
+               Connection retConn = null;
+               if (state == State.CONNECTED) {
+                       try {
+                               retConn = updateConnections.take();
+                       } catch (InterruptedException e) {
+                               e.printStackTrace();
+                       }
+               }
 
-       private static void semaphoreAcquire() {
+               return retConn;
+       }
 
+       private static void putUpdateConnection(Connection conn) {
+               if (conn != null) {
+                       try {
+                               updateConnections.put(conn);
+                               synchronized (updateConnections) {
+                                       updateConnections.notifyAll();
+                               }
+                       } catch (InterruptedException e) {
+                               e.printStackTrace();
+                       }
+               }
        }
 
-       private static void semaphoreRelease() {
+       private static Connection getQueryConnection() {
+               Connection retConn = null;
+               if (state == State.CONNECTED) {
+                       try {
+                               retConn = queryConnections.take();
+                       } catch (InterruptedException e) {
+                               e.printStackTrace();
+                       }
+               }
+
+               return retConn;
+       }
 
+       private static void putQueryConnection(Connection conn) {
+               if (conn != null) {
+                       try {
+                               queryConnections.put(conn);
+                               synchronized (queryConnections) {
+                                       queryConnections.notifyAll();
+                               }
+                       } catch (InterruptedException e) {
+                               e.printStackTrace();
+                       }
+               }
        }
 
        public static void executeUpdate(String statement) {
+               Connection conn = null;
                Statement sm = null;
                try {
-                       if (connection != null) {
-                               semaphoreAcquire();
-                               sm = connection.createStatement();
+                       conn = getUpdateConnection();
+                       if (conn != null) {
+                               sm = conn.createStatement();
                                sm.executeUpdate(statement);
+                               putUpdateConnection(conn);
                        }
                } catch (SQLException e) {
                        e.printStackTrace();
                } finally {
                        CommonUtil.tryClose(sm);
-                       semaphoreRelease();
                }
        }
 
        public static void executePreparedWithType(String query,
                        List<List<Object>> data, List<String> columnType) {
+               Connection conn = null;
                PreparedStatement prep = null;
 
                if (data.size() == 0)
                        return;
 
                try {
-                       if (connection != null) {
+                       conn = getUpdateConnection();
+                       if (conn != null) {
                                int batchCount = 0;
-                               prep = connection.prepareStatement(query);
+                               prep = conn.prepareStatement(query);
 
                                // count ? in query
                                int questionCount = 0;
@@ -128,7 +282,7 @@ public class SqlConnectionManager {
                                        return;
                                }
 
-                               connection.setAutoCommit(false);
+                               conn.setAutoCommit(false);
 
                                for (int k = 0; k < datasize; k++) {
                                        List<Object> row = data.get(k);
@@ -214,8 +368,10 @@ public class SqlConnectionManager {
 
                                if (batchCount > 0)
                                        prep.executeBatch();
-                               connection.commit();
-                               connection.setAutoCommit(true);
+                               conn.commit();
+                               conn.setAutoCommit(true);
+                               
+                               putUpdateConnection(conn);
                        }
                } catch (SQLException e) {
                        e.printStackTrace();
@@ -230,15 +386,17 @@ public class SqlConnectionManager {
        // (no need to check the type of each column)
        public static void executePreparedWithInterface(String query,
                        List<List<Object>> data, IPreparedStatement ip) {
+               Connection conn = null;
                PreparedStatement prep = null;
 
                if (data.size() == 0)
                        return;
 
                try {
-                       if (connection != null) {
+                       conn = getUpdateConnection();
+                       if (conn != null) {
                                int batchCount = 0;
-                               prep = connection.prepareStatement(query);
+                               prep = conn.prepareStatement(query);
 
                                // count ? in query
                                int questionCount = 0;
@@ -251,7 +409,7 @@ public class SqlConnectionManager {
                                // set data into prepared statement
                                int datasize = data.size();
 
-                               connection.setAutoCommit(false);
+                               conn.setAutoCommit(false);
 
                                for (int k = 0; k < datasize; k++) {
                                        List<Object> row = data.get(k);
@@ -273,8 +431,10 @@ public class SqlConnectionManager {
 
                                if (batchCount > 0)
                                        prep.executeBatch();
-                               connection.commit();
-                               connection.setAutoCommit(true);
+                               conn.commit();
+                               conn.setAutoCommit(true);
+                               
+                               putUpdateConnection(conn);
                        }
                } catch (SQLException e) {
                        e.printStackTrace();
@@ -284,13 +444,15 @@ public class SqlConnectionManager {
        }
 
        public static List<List<Object>> executeQuery(String query) {
+               Connection conn = null;
                Statement sm = null;
                ResultSet rs = null;
                List<List<Object>> result = null;
+               
                try {
-                       if (connection != null) {
-                               semaphoreAcquire();
-                               sm = connection.createStatement();
+                       conn = getQueryConnection();
+                       if (conn != null) {
+                               sm = conn.createStatement();
                                rs = sm.executeQuery(query);
                                if (rs != null) {
                                        result = new ArrayList<List<Object>>();
@@ -326,12 +488,13 @@ public class SqlConnectionManager {
                                                result.add(rowData);
                                        }
                                }
+                               
+                               putQueryConnection(conn);
                        }
                } catch (SQLException e) {
                        e.printStackTrace();
                } finally {
                        CommonUtil.tryClose(sm);
-                       semaphoreRelease();
                }
 
                return result;
index c9dc980..a32ad6a 100644 (file)
@@ -41,6 +41,7 @@ public class DataChannelConstants {
        public final static int MSG_CONTEXT_SWITCH_EXIT = 0x0011;
        public final static int MSG_PROCESS_MAP = 0x0012;
        public final static int MSG_PROCESS_UNMAP = 0x0013;
+       public final static int MSG_PROCESS_COMM = 0x0014;
        
        public static final int LOG_USER_FUNCTION = 0x002C;  //44
        public static final int LOG_CONTEXT_SWITCH = 0x002D;  //45 
index 5d215a6..fb5ea54 100644 (file)
@@ -12,6 +12,7 @@ public class ProcessInfoPackage {
        private String targetBinaryPath = null;
        private int functionEntryInsertLogCount = 0;
        private boolean dropLog = false;
+       private String cmdLineName = null;
 
        private List<ProcessInfo> processSnapshots = new ArrayList<ProcessInfo>();
 
@@ -39,6 +40,14 @@ public class ProcessInfoPackage {
                this.targetBinaryPath = localBinaryPath;
        }
 
+       public String getCmdLineName() {
+               return cmdLineName;
+       }
+
+       public void setCmdLineName(String cmdLineName) {
+               this.cmdLineName = cmdLineName;
+       }
+
        public List<ProcessInfo> getProcessSnapshots() {
                return processSnapshots;
        }
index 13f470d..d3a9593 100755 (executable)
@@ -169,10 +169,13 @@ public class MessageParser {
                long highAddr = 0;
                String targetBinaryPath = null;
                int dependantLibCount = 0;
+               String commandLineName = null;
 
                int index = MSG_HEADER_SIZE;
                pid = ByteUtils.toInt(data, index);
                index += INT_SIZE;
+               commandLineName = ByteUtils.getString(data, index);
+               index += ByteUtils.getStringLength(data, index);
                ppid = ByteUtils.toInt(data, index);
                index += INT_SIZE;
                int sec = ByteUtils.toInt(data, index);
@@ -196,6 +199,7 @@ public class MessageParser {
                        pInfoPack.setPid(pid);
                        pInfoPack.setPpid(ppid);
                        pInfoPack.setTargetBinaryPath(targetBinaryPath);
+                       pInfoPack.setCmdLineName(commandLineName);
                        if (processPkgMap.isEmpty()) {
                                AnalyzerManager.getProject().setMainPid(pid);
                        }
@@ -606,6 +610,24 @@ public class MessageParser {
                                }
                        }
                        break;
+               case DataChannelConstants.MSG_PROCESS_COMM:
+               {
+                       // process command line name is changed (/proc/<pid>/cmdline)
+                       int index = MSG_HEADER_SIZE;
+                       int pid = ByteUtils.toInt(data, index);
+                       index += INT_SIZE;
+                       String name = ByteUtils.getString(data, index);
+                       index += ByteUtils.getStringLength(data, index);
+
+                       HashMap<Integer, ProcessInfoPackage> processPkgMap = AnalyzerManager
+                                       .getProject().getProcessInfoPackHash();
+
+                       ProcessInfoPackage pInfoPack = processPkgMap.get(pid);
+                       if (null != pInfoPack) {
+                               pInfoPack.setCmdLineName(name);
+                       }
+               }
+                       break;
                default: // MSG_PROBE
                        if (AnalyzerManager.isProcessInfoArrived() && id > 0x0100
                                        && id < 0x0200) {
index d11fb89..f13863e 100755 (executable)
@@ -317,11 +317,17 @@ public class ToolbarArea {
                                                .values());
                                for (ProcessInfoPackage pkg : processInfoPkgList) {
                                        // String pid = Integer.toString(pkg.getPid());
-                                       String binPath = pkg.getTargetBinaryPath();
                                        String binName = CommonConstants.EMPTY;
-                                       if (null != binPath && !binPath.isEmpty()) {
-                                               int index = binPath.lastIndexOf(CommonConstants.SLASH);
-                                               binName = binPath.substring(index + 1, binPath.length());
+                                       
+                                       String cmdLineName = pkg.getCmdLineName();
+                                       if(cmdLineName != null && !cmdLineName.isEmpty()) {
+                                               binName = cmdLineName;
+                                       } else {
+                                               String binPath = pkg.getTargetBinaryPath();
+                                               if (null != binPath && !binPath.isEmpty()) {
+                                                       int index = binPath.lastIndexOf(CommonConstants.SLASH);
+                                                       binName = binPath.substring(index + 1, binPath.length());
+                                               }
                                        }
                                        StringBuffer buffer = new StringBuffer();
                                        buffer.append(pkg.getPid()).append(PROCESS_SPLITER);