/******************************************************************************* * 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.util.LinkedList; import java.util.List; import fr.inria.soctrace.lib.model.EventType; import fr.inria.soctrace.lib.model.utils.SoCTraceException; import fr.inria.soctrace.lib.storage.TraceDBObject; /** * Implementation of the {@link HistogramLoader} interface. * * @author "Generoso Pagano <generoso.pagano@inria.fr>" */ class HistogramLoaderImpl implements HistogramLoader { private TraceDBObject traceDB; private HEventIterator iterator; private long minTs = Long.MIN_VALUE; private long maxTs = Long.MIN_VALUE; /** * Constructor. * @param traceDB the trace DB object, the ownership is to the client. */ public HistogramLoaderImpl(TraceDBObject traceDB, HEventIterator iterator) { if (traceDB == null) throw new IllegalArgumentException("Null DB object passed"); if (iterator == null) throw new IllegalArgumentException("Null iterator passed"); this.traceDB = traceDB; this.iterator = iterator; } @Override public Histogram loadHistogram(long startTimestamp, long endTimestamp, List<EventType> types, int buckets) throws SoCTraceException { // resolve timestamps if needed boolean allTrace = true; if (startTimestamp == MIN_TIMESTAMP) startTimestamp = getMinTimestamp(); else allTrace = false; if (endTimestamp == MAX_TIMESTAMP) endTimestamp = getMaxTimestamp(); else allTrace = false; // check arguments if (startTimestamp >= endTimestamp) throw new IllegalArgumentException("Start-timestamp must be smaller than end-timestamp"); if (startTimestamp < 0) throw new IllegalArgumentException("Start timestamp must be positive"); if (endTimestamp < 0) throw new IllegalArgumentException("End timestamp must be positive"); if (types==null || types.isEmpty()) throw new IllegalArgumentException("Null or empty list of event types passed"); if (buckets<MIN_BUCKETS || buckets>MAX_BUCKETS) throw new IllegalArgumentException("Illegal number of buckets"); // load histogram Long duration = endTimestamp - startTimestamp; // for small durations, check the buckets value if (duration <= Integer.MAX_VALUE) buckets = Math.min(buckets, duration.intValue()); long uppers[] = new long[buckets]; long delta = Math.max((endTimestamp-startTimestamp+1)/(buckets), 1); uppers[buckets-1] = endTimestamp; for (int i=buckets-2; i>=0; i--) { uppers[i] = uppers[i+1] - delta; } Histogram histogram = DistributionFactory.INSTANCE.createHistogram(uppers); iterator.clear(); iterator.setTraceDB(traceDB); iterator.setTypes(types); if (!allTrace) iterator.setTimestamps(startTimestamp, endTimestamp); while(iterator.hasNext()) { HEvent eh = iterator.getNext(); if (eh==null) break; histogram.addObservation(eh.timestamp); } iterator.clear(); return histogram; } @Override public Histogram loadHistogram(long startTimestamp, long endTimestamp, EventType type, int buckets) throws SoCTraceException { if (type == null) throw new IllegalArgumentException("Null type passed"); List<EventType> types = new LinkedList<EventType>(); types.add(type); return loadHistogram(startTimestamp, endTimestamp, types, buckets); } @Override public long getMinTimestamp() throws SoCTraceException { if (minTs == Long.MIN_VALUE) minTs = Math.max(traceDB.getMinTimestamp(), 0); return minTs; } @Override public long getMaxTimestamp() throws SoCTraceException { if (maxTs == Long.MIN_VALUE) maxTs = Math.max(traceDB.getMaxTimestamp(), 0); return maxTs; } /** * Debug print * @param verbose */ public void print(HistogramImpl histogram, boolean verbose){ System.out.println(histogram); if (!verbose) return; for (int i=0; i<histogram.getSize(); i++) { StringBuilder sb = new StringBuilder(); for (int j=0; j<histogram.getCountAt(i); j++) { sb.append("*"); } System.out.println(sb.toString()); } } }