From: <tk...@hy...> - 2007-09-21 01:39:28
|
Author: tkeeney Date: 2007-09-20 18:39:23 -0700 (Thu, 20 Sep 2007) New Revision: 5981 URL: http://svn.hyperic.org/?view=rev&root=Hyperic+HQ&revision=5981 Modified: branches/HQ_3_1/src/org/hyperic/hibernate/dialect/HQDialect.java branches/HQ_3_1/src/org/hyperic/hibernate/dialect/MySQL5InnoDBDialect.java branches/HQ_3_1/src/org/hyperic/hibernate/dialect/Oracle9Dialect.java branches/HQ_3_1/src/org/hyperic/hibernate/dialect/PostgreSQLDialect.java branches/HQ_3_1/src/org/hyperic/hq/bizapp/server/session/EventLogBossEJBImpl.java branches/HQ_3_1/src/org/hyperic/hq/events/server/session/EventLogManagerEJBImpl.java branches/HQ_3_1/src/org/hyperic/hq/ui/action/resource/common/monitor/visibility/TimelineAction.java branches/HQ_3_1/src/org/hyperic/hq/ui/beans/TimelineBean.java branches/HQ_3_1/web/resource/common/monitor/visibility/EventLogs.jsp Log: [HQ-953] Optimized event log retrieval for the event/log tracking widget. Instead of retrieving the number of events/logs per interval, we only need to know whether or not there were any events/logs in each interval. Modified: branches/HQ_3_1/src/org/hyperic/hibernate/dialect/HQDialect.java =================================================================== --- branches/HQ_3_1/src/org/hyperic/hibernate/dialect/HQDialect.java 2007-09-21 00:55:59 UTC (rev 5980) +++ branches/HQ_3_1/src/org/hyperic/hibernate/dialect/HQDialect.java 2007-09-21 01:39:23 UTC (rev 5981) @@ -63,4 +63,13 @@ */ public boolean viewExists(Statement stmt, String viewName) throws SQLException; + + /** + * Returns the limit string. + * + * @param num The number of rows to limit by. + * @return The limit string. + */ + public String getLimitString(int num); + } Modified: branches/HQ_3_1/src/org/hyperic/hibernate/dialect/MySQL5InnoDBDialect.java =================================================================== --- branches/HQ_3_1/src/org/hyperic/hibernate/dialect/MySQL5InnoDBDialect.java 2007-09-21 00:55:59 UTC (rev 5980) +++ branches/HQ_3_1/src/org/hyperic/hibernate/dialect/MySQL5InnoDBDialect.java 2007-09-21 01:39:23 UTC (rev 5981) @@ -145,4 +145,9 @@ DBUtil.closeResultSet(logCtx, rs); } } + + public String getLimitString(int num) { + return "LIMIT "+num; + } + } Modified: branches/HQ_3_1/src/org/hyperic/hibernate/dialect/Oracle9Dialect.java =================================================================== --- branches/HQ_3_1/src/org/hyperic/hibernate/dialect/Oracle9Dialect.java 2007-09-21 00:55:59 UTC (rev 5980) +++ branches/HQ_3_1/src/org/hyperic/hibernate/dialect/Oracle9Dialect.java 2007-09-21 01:39:23 UTC (rev 5981) @@ -102,4 +102,9 @@ DBUtil.closeResultSet(logCtx, rs); } } + + public String getLimitString(int num) { + return "ROWNUM <= "+num; + } + } Modified: branches/HQ_3_1/src/org/hyperic/hibernate/dialect/PostgreSQLDialect.java =================================================================== --- branches/HQ_3_1/src/org/hyperic/hibernate/dialect/PostgreSQLDialect.java 2007-09-21 00:55:59 UTC (rev 5980) +++ branches/HQ_3_1/src/org/hyperic/hibernate/dialect/PostgreSQLDialect.java 2007-09-21 01:39:23 UTC (rev 5981) @@ -96,4 +96,9 @@ " (SELECT "+commonKey+" FROM "+joinTables+ " WHERE "+joinKeys+cond+")"; } + + public String getLimitString(int num) { + return "LIMIT "+num; + } + } Modified: branches/HQ_3_1/src/org/hyperic/hq/bizapp/server/session/EventLogBossEJBImpl.java =================================================================== --- branches/HQ_3_1/src/org/hyperic/hq/bizapp/server/session/EventLogBossEJBImpl.java 2007-09-21 00:55:59 UTC (rev 5980) +++ branches/HQ_3_1/src/org/hyperic/hq/bizapp/server/session/EventLogBossEJBImpl.java 2007-09-21 01:39:23 UTC (rev 5981) @@ -165,18 +165,20 @@ return events; } - /** Get an array of log record counts based on entity ID and time range + /** + * Get an array of boolean indicating if logs exist per interval, + * for an entity over a given time range. * * @param aeid the entity ID - * @return array of log record counts + * @return boolean array indicating if logs exist per interval. * * @ejb:interface-method */ - public int[] getLogsCount(int sessionId, AppdefEntityID aeid, - long beginTime, long endTime, int intervals) + public boolean[] logsExistPerInterval(int sessionId, AppdefEntityID aeid, + long beginTime, long endTime, int intervals) throws SessionNotFoundException, SessionTimeoutException { AuthzSubjectValue subject = this.manager.getSubject(sessionId); - return getELM().getLogsCount(aeid, beginTime, endTime, intervals); + return getELM().logsExistPerInterval(aeid, beginTime, endTime, intervals); } /** Modified: branches/HQ_3_1/src/org/hyperic/hq/events/server/session/EventLogManagerEJBImpl.java =================================================================== --- branches/HQ_3_1/src/org/hyperic/hq/events/server/session/EventLogManagerEJBImpl.java 2007-09-21 00:55:59 UTC (rev 5980) +++ branches/HQ_3_1/src/org/hyperic/hq/events/server/session/EventLogManagerEJBImpl.java 2007-09-21 01:39:23 UTC (rev 5981) @@ -26,10 +26,9 @@ package org.hyperic.hq.events.server.session; import java.sql.Connection; -import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; -import java.util.Arrays; +import java.sql.Statement; import java.util.List; import javax.ejb.CreateException; @@ -39,6 +38,7 @@ import org.hibernate.Session; import org.hyperic.dao.DAOFactory; +import org.hyperic.hibernate.Util; import org.hyperic.hq.appdef.shared.AppdefEntityID; import org.hyperic.hq.common.SystemException; import org.hyperic.hq.events.AbstractEvent; @@ -150,56 +150,93 @@ } /** - * Get an array of log record counts based on entity ID and time range + * Get an array of booleans, each element indicating whether or not there + * are log records for that respective interval, for a particular entity + * over a given time range. * + * @param entityId The entity. + * @param begin The begin timestamp for the time range. + * @param end The end timestamp for the time range. + * @param intervals The number of intervals. + * @return The boolean array with length equal to the number of intervals + * specified. * @ejb:interface-method */ - public int[] getLogsCount(AppdefEntityID entityId, long begin, long end, - int intervals) - { - final String sql = - "SELECT i, COUNT(e.id) FROM " + TABLE_EVENT_LOG + " e, EAM_NUMBERS " + - "WHERE i < ? AND entity_type = ? AND entity_id = ? AND " + - "timestamp BETWEEN (? + (? * i)) AND (? + (? * i)) " + - "GROUP BY i ORDER BY i"; - - Connection conn = null; - PreparedStatement stmt = null; - ResultSet rs = null; - Session sess = DAOFactory.getDAOFactory().getCurrentSession(); - - int[] ret = new int[intervals]; - Arrays.fill(ret, 0); - - try { - conn = sess.connection(); - stmt = conn.prepareStatement(sql); - - long interval = (end - begin) / intervals; - - int i = 1; - stmt.setInt(i++, intervals); - stmt.setInt(i++, entityId.getType()); - stmt.setInt(i++, entityId.getID()); - stmt.setLong(i++, begin); - stmt.setLong(i++, interval); - stmt.setLong(i++, begin + interval); - stmt.setLong(i++, interval); - - rs = stmt.executeQuery(); - - while(rs.next()) { - int index = rs.getInt(1); - ret[index] = rs.getInt(2); - } - } catch (SQLException e) { - log.error("SQLException when fetching logs existence", e); - } finally { - DBUtil.closeJDBCObjects(logCtx, null, stmt, rs); - sess.disconnect(); - } - - return ret; + public boolean[] logsExistPerInterval(AppdefEntityID entityId, + long begin, + long end, + int intervals) { + // Execute individual selects for each interval in batch. + // We only care if there is at least one event log per interval. + boolean[] eventLogsInIntervals = new boolean[intervals]; + long interval = (end - begin) / intervals; + + StringBuffer sql = new StringBuffer(); + StringBuffer perIntervalSQL = new StringBuffer(); + int i = 0; + + if (log.isDebugEnabled()) { + log.debug("Checking if logs exist per interval: entity_type="+ + entityId.getType()+", entity_id="+entityId.getID()+ + ", begin="+begin+", end="+end+", intervals="+intervals+ + ", interval="+interval); + } + + for (long cursor = begin; i < intervals; i++, cursor = begin+(interval*i)) { + perIntervalSQL.append("SELECT id FROM ") + .append(TABLE_EVENT_LOG) + .append(" WHERE entity_type = ") + .append(entityId.getType()) + .append(" AND entity_id = ") + .append(entityId.getID()) + .append(" AND timestamp BETWEEN ") + .append(cursor) + .append(" AND ") + .append(cursor+interval-1) + .append(' ') + .append(Util.getHQDialect().getLimitString(1)) + .append(";\n"); + + sql.append(perIntervalSQL); + perIntervalSQL.setLength(0); + } + + Session sess = DAOFactory.getDAOFactory().getCurrentSession(); + Connection conn = null; + Statement stmt = null; + + try { + conn = sess.connection(); + stmt = conn.createStatement(); + stmt.execute(sql.toString()); + + int index = 0; + + do { + ResultSet rs = stmt.getResultSet(); + + if (rs == null) { + break; + } + + if (rs.next()) { + eventLogsInIntervals[index] = true; + } + + index++; + } while (stmt.getMoreResults()); + + assert index == intervals : + "Number of query results="+index+ + " should match number of intervals="+intervals; + } catch (SQLException e) { + log.error("SQLException when fetching logs existence", e); + } finally { + DBUtil.closeJDBCObjects(logCtx, null, stmt, null); + sess.disconnect(); + } + + return eventLogsInIntervals; } /** Modified: branches/HQ_3_1/src/org/hyperic/hq/ui/action/resource/common/monitor/visibility/TimelineAction.java =================================================================== --- branches/HQ_3_1/src/org/hyperic/hq/ui/action/resource/common/monitor/visibility/TimelineAction.java 2007-09-21 00:55:59 UTC (rev 5980) +++ branches/HQ_3_1/src/org/hyperic/hq/ui/action/resource/common/monitor/visibility/TimelineAction.java 2007-09-21 01:39:23 UTC (rev 5981) @@ -75,16 +75,16 @@ EventLogBoss boss = ContextUtils.getEventLogBoss(ctx); AppdefEntityID aeid = RequestUtils.getEntityId(request); - int[] eventsCounts = boss.getLogsCount(user.getSessionId().intValue(), - aeid, begin, end, - intervals.length); + boolean[] logsExist = boss.logsExistPerInterval(user.getSessionId().intValue(), + aeid, begin, end, + intervals.length); // Create the time intervals beans TimelineBean[] beans = new TimelineBean[intervals.length]; long interval = TimeUtil.getInterval(begin, end, Constants.DEFAULT_CHART_POINTS); for (int i = 0; i < intervals.length; i++) { - beans[i] = new TimelineBean(begin + (interval * i),eventsCounts[i]); + beans[i] = new TimelineBean(begin + (interval * i),logsExist[i]); } request.setAttribute(Constants.TIME_INTERVALS_ATTR, beans); Modified: branches/HQ_3_1/src/org/hyperic/hq/ui/beans/TimelineBean.java =================================================================== --- branches/HQ_3_1/src/org/hyperic/hq/ui/beans/TimelineBean.java 2007-09-21 00:55:59 UTC (rev 5980) +++ branches/HQ_3_1/src/org/hyperic/hq/ui/beans/TimelineBean.java 2007-09-21 01:39:23 UTC (rev 5981) @@ -30,22 +30,22 @@ */ public class TimelineBean { private long time; - private int events; + private boolean eventsExist; /** - * Constructor taking in time and events + * Constructor taking in time and whether or not events exist */ - public TimelineBean(long time, int events) { + public TimelineBean(long time, boolean eventsExist) { this.time = time; - this.events = events; + this.eventsExist = eventsExist; } - public int getEvents() { - return events; + public boolean isEventsExist() { + return eventsExist; } - public void setEvents(int events) { - this.events = events; + public void setEventsExist(boolean exist) { + this.eventsExist = exist; } public long getTime() { Modified: branches/HQ_3_1/web/resource/common/monitor/visibility/EventLogs.jsp =================================================================== --- branches/HQ_3_1/web/resource/common/monitor/visibility/EventLogs.jsp 2007-09-21 00:55:59 UTC (rev 5980) +++ branches/HQ_3_1/web/resource/common/monitor/visibility/EventLogs.jsp 2007-09-21 01:39:23 UTC (rev 5981) @@ -5,10 +5,10 @@ <c:set var="count" value="0"/> <c:forEach var="timeTick" items="${timeIntervals}"> - <c:set var="count" value="${count + timeTick.events}"/> + <c:set var="eventsExist" value="${timeTick.eventsExist || eventsExist}"/> </c:forEach> -<c:if test="${count > 0}"> +<c:if test="${eventsExist}"> <script src="<html:rewrite page="/js/effects.js"/>" type="text/javascript"></script> @@ -56,15 +56,12 @@ } </script> - <tr> - <td colspan="<c:out value="${count + 2}"/>" style="height: 2px;"></td> - </tr> - <tr style="height: 12px;"> + <tr style="height: 12px; padding-top: 2px;"> <td></td> <c:forEach var="timeTick" items="${timeIntervals}" varStatus="status"> <c:set var="count" value="${status.count}"/> <td background="<html:rewrite page="/images/no_event.gif"/>" align="center" valign="middle"> - <c:if test="${timeTick.events > 0}"> + <c:if test="${timeTick.eventsExist}"> <div class="eventBlock" onmouseover="this.style.backgroundColor='#0000ff'" onmouseout="this.style.backgroundColor='#003399'" onmousedown="overlay.delayTimePopup(<c:out value="${count - 1}"/>);showEventsDetails(<c:out value="${timeTick.time}"/>);overlay.moveOverlay(this)"></div> </c:if> </td> |