/******************************************************************************* * Copyright (c) 2012-2015 INRIA. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Generoso Pagano - initial API and implementation ******************************************************************************/ package fr.inria.soctrace.lib.query.distribution; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import fr.inria.soctrace.lib.model.EventType; import fr.inria.soctrace.lib.model.utils.SoCTraceException; import fr.inria.soctrace.lib.query.ValueListString; import fr.inria.soctrace.lib.storage.TraceDBObject; /** * Implementation of the {@link HEventIterator} interface, * reading events page by page. * * @author "Generoso Pagano <generoso.pagano@inria.fr>" */ class HEventPageIteratorImpl implements HEventIterator { /** * Logger */ private static final Logger logger = LoggerFactory.getLogger(HEventPageIteratorImpl.class); private TraceDBObject traceDB; protected Iterator<HEvent> eIterator; protected List<HEvent> eList; private String typeIds; private int numOfTypes; private long startTimestamp = Long.MIN_VALUE; private long endTimestamp = Long.MIN_VALUE; private long MIN_PAGE = Long.MAX_VALUE; private long MAX_PAGE = Long.MIN_VALUE; private long nextPage = Long.MAX_VALUE; public boolean hasNext() { if (eIterator==null || !eIterator.hasNext()) if (nextPage>MAX_PAGE) return false; return true; } public HEvent getNext() throws SoCTraceException { if (eIterator==null || !eIterator.hasNext()) { if (nextPage>MAX_PAGE) { clear(); return null; } eIterator = null; if (eList!=null) { eList.clear(); eList = null; } eList = getNextPage(traceDB); eIterator = eList.iterator(); } if (eIterator.hasNext()) // in the case an empty list has been loaded return eIterator.next(); return null; } private List<HEvent> getNextPage(TraceDBObject traceDB) throws SoCTraceException { List<HEvent> list = new LinkedList<HEvent>(); try { // prepare query int numberOfTraceTypes = traceDB.getEventTypeCache().getElementMap(EventType.class).values().size(); boolean typecond = (numOfTypes < numberOfTraceTypes); boolean timecond = (startTimestamp!=Long.MIN_VALUE || endTimestamp!=Long.MIN_VALUE); StringBuilder sb = new StringBuilder("SELECT TIMESTAMP FROM EVENT WHERE PAGE="+nextPage+" "); if (typecond) sb.append(" AND EVENT_TYPE_ID IN " + typeIds); if (timecond) sb.append(" AND TIMESTAMP BETWEEN " + startTimestamp + " AND " + endTimestamp); logger.debug(sb.toString()); Statement stm = traceDB.getConnection().createStatement(); ResultSet rs = stm.executeQuery(sb.toString()); while (rs.next()) { HEvent he = new HEvent(); he.timestamp = rs.getLong(1); list.add(he); } stm.close(); nextPage++; } catch (SQLException e) { throw new SoCTraceException(e); } return list; } @Override public void setTraceDB(TraceDBObject traceDB) throws SoCTraceException { this.traceDB = traceDB; this.MIN_PAGE = traceDB.getMinPage(); this.MAX_PAGE = traceDB.getMaxPage(); this.nextPage = MIN_PAGE; } @Override public void setTypes(List<EventType> types) throws SoCTraceException { ValueListString vls = new ValueListString(); Set<Integer> tset = new HashSet<Integer>(); numOfTypes = 0; for (EventType et: types) { if (tset.contains(et.getId())) continue; vls.addValue(String.valueOf(et.getId())); tset.add(et.getId()); numOfTypes++; } this.typeIds = vls.getValueString(); } @Override public void setTimestamps(long startTimestamp, long endTimestamp) { this.startTimestamp = startTimestamp; this.endTimestamp = endTimestamp; } @Override public void clear() { MIN_PAGE = Long.MAX_VALUE; MAX_PAGE = Long.MIN_VALUE; nextPage = Long.MAX_VALUE; startTimestamp = Long.MIN_VALUE; endTimestamp = Long.MIN_VALUE; typeIds = ""; numOfTypes = 0; traceDB = null; eIterator = null; if (eList!=null) { eList.clear(); eList = null; } } }