diff --git a/plugins/com.minres.scviewer.database.sqlite/src/com/minres/scviewer/database/sqlite/AbstractTxStream.java b/plugins/com.minres.scviewer.database.sqlite/src/com/minres/scviewer/database/sqlite/AbstractTxStream.java index 8186585..2132faa 100644 --- a/plugins/com.minres.scviewer.database.sqlite/src/com/minres/scviewer/database/sqlite/AbstractTxStream.java +++ b/plugins/com.minres.scviewer.database.sqlite/src/com/minres/scviewer/database/sqlite/AbstractTxStream.java @@ -15,6 +15,7 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; +import com.minres.scviewer.database.EventEntry; import com.minres.scviewer.database.EventKind; import com.minres.scviewer.database.HierNode; import com.minres.scviewer.database.IEvent; @@ -35,7 +36,7 @@ abstract class AbstractTxStream extends HierNode implements IWaveform { private Integer maxConcurrency; - private IEventList events; + private IEventList events; private List usedRelationsList; @@ -71,9 +72,9 @@ abstract class AbstractTxStream extends HierNode implements IWaveform { } @Override - public IEventList getEvents(){ + public IEventList getEvents(){ if(events==null){ - events=new EventList<>(); + events=new EventList(); for(Entry entry:getTransactions().entrySet()){ putEvent(new TxEvent(EventKind.BEGIN, entry.getValue())); putEvent(new TxEvent(EventKind.END, entry.getValue())); @@ -114,11 +115,11 @@ abstract class AbstractTxStream extends HierNode implements IWaveform { @Override public IEvent[] getEventsBeforeTime(Long time) { - Entry e = events.floorEntry(time); + EventEntry e = events.floorEntry(time); if(e==null) return new IEvent[]{}; else - return events.floorEntry(time).getValue(); + return events.floorEntry(time).events; } @Override diff --git a/plugins/com.minres.scviewer.database.text/src/com/minres/scviewer/database/text/AbstractTxStream.java b/plugins/com.minres.scviewer.database.text/src/com/minres/scviewer/database/text/AbstractTxStream.java index 7c6371c..562de54 100644 --- a/plugins/com.minres.scviewer.database.text/src/com/minres/scviewer/database/text/AbstractTxStream.java +++ b/plugins/com.minres.scviewer.database.text/src/com/minres/scviewer/database/text/AbstractTxStream.java @@ -14,8 +14,8 @@ package com.minres.scviewer.database.text; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; -import java.util.Map.Entry; +import com.minres.scviewer.database.EventEntry; import com.minres.scviewer.database.EventList; import com.minres.scviewer.database.HierNode; import com.minres.scviewer.database.IEvent; @@ -39,7 +39,7 @@ abstract class AbstractTxStream extends HierNode implements IWaveform { protected TextDbLoader loader; /** The events. */ - IEventList events = new EventList(); + IEventList events = new EventList(); /** The max concurrency. */ private int rowCount = -1; @@ -89,7 +89,7 @@ abstract class AbstractTxStream extends HierNode implements IWaveform { * @return the events */ @Override - public IEventList getEvents() { + public IEventList getEvents() { return events; } @@ -112,11 +112,11 @@ abstract class AbstractTxStream extends HierNode implements IWaveform { */ @Override public IEvent[] getEventsBeforeTime(Long time) { - Entry e = events.floorEntry(time); + EventEntry e = events.floorEntry(time); if (e == null) return new IEvent[] {}; else - return events.floorEntry(time).getValue(); + return events.floorEntry(time).events; } /** @@ -159,8 +159,8 @@ abstract class AbstractTxStream extends HierNode implements IWaveform { return; ArrayList rowEndTime = new ArrayList<>(); HashMap rowByTxId = new HashMap<>(); - for(Entry entry: events.entrySet()) { - for(IEvent evt:entry.getValue()) { + for(EventEntry entry: events) { + for(IEvent evt:entry.events) { TxEvent txEvt = (TxEvent) evt; ITx tx = txEvt.getTransaction(); int rowIdx = 0; diff --git a/plugins/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/ui/swt/internal/SignalPainter.java b/plugins/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/ui/swt/internal/SignalPainter.java index d4469c2..8bfd10a 100644 --- a/plugins/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/ui/swt/internal/SignalPainter.java +++ b/plugins/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/ui/swt/internal/SignalPainter.java @@ -12,7 +12,6 @@ package com.minres.scviewer.database.ui.swt.internal; import java.util.Arrays; import java.util.Collection; -import java.util.Map.Entry; import javax.swing.JPanel; @@ -25,6 +24,7 @@ import org.eclipse.swt.graphics.Rectangle; import com.minres.scviewer.database.BitVector; import com.minres.scviewer.database.DoubleVal; +import com.minres.scviewer.database.EventEntry; import com.minres.scviewer.database.IEvent; import com.minres.scviewer.database.IEventList; import com.minres.scviewer.database.IWaveform; @@ -37,16 +37,16 @@ public class SignalPainter extends TrackPainter { IEvent value; boolean fromMap; - public SignalChange(Entry entry) { - time = entry.getKey(); - value = entry.getValue()[0]; + public SignalChange(EventEntry entry) { + time = entry.timestamp; + value = entry.events[0]; fromMap = true; } - public void set(Entry entry, Long actTime) { + public void set(EventEntry entry, Long actTime) { if (entry != null) { - time = entry.getKey(); - value = entry.getValue()[0]; + time = entry.timestamp; + value = entry.events[0]; fromMap = true; } else { time = actTime; @@ -100,8 +100,8 @@ public class SignalPainter extends TrackPainter { long beginTime = beginPos*scaleFactor; long endTime = beginTime + area.width*scaleFactor; - Entry first = signal.getEvents().floorEntry(beginTime); - Entry last = signal.getEvents().floorEntry(endTime); + EventEntry first = signal.getEvents().floorEntry(beginTime); + EventEntry last = signal.getEvents().floorEntry(endTime); if (first == null) { if (last == null) return; @@ -112,7 +112,7 @@ public class SignalPainter extends TrackPainter { proj.setForeground(this.waveCanvas.styleProvider.getColor(WaveformColors.LINE)); proj.setLineStyle(SWT.LINE_SOLID); proj.setLineWidth(1); - IEventList entries = signal.getEvents().subMap(first.getKey(), false, last.getKey(), true); + IEventList entries = signal.getEvents().subMap(first.timestamp, false, last.timestamp); SignalChange left = new SignalChange(first); SignalChange right = new SignalChange(entries.size() > 0 ? entries.firstEntry() : first); maxPosX = area.x + area.width; @@ -153,15 +153,15 @@ public class SignalPainter extends TrackPainter { if (xSigChangeEndPos == xSigChangeBeginPos) { multiple = true; long eTime = (xSigChangeBeginPos + 1) * this.waveCanvas.getScaleFactor(); - Entry entry = entries.floorEntry(eTime); - if(entry!=null && entry.getKey()> right.time) + EventEntry entry = entries.floorEntry(eTime); + if(entry!=null && entry.timestamp> right.time) right.set(entry, endTime); xSigChangeEndPos = getXPosEnd(eTime); } } while (left.time < endTime); } - private SignalStencil getStencil(GC gc, SignalChange left, IEventList entries) { + private SignalStencil getStencil(GC gc, SignalChange left, IEventList entries) { IEvent val = left.value; if(val instanceof BitVector) { BitVector bv = (BitVector) val; @@ -253,15 +253,15 @@ public class SignalPainter extends TrackPainter { private long maxVal; private long minVal; double yRange = (yOffsetB-yOffsetT); - public MultiBitStencilAnalog(IEventList entries, Object left, boolean continous, boolean signed) { + public MultiBitStencilAnalog(IEventList entries, Object left, boolean continous, boolean signed) { this.continous=continous; this.signed=signed; - Collection values = entries.values(); + Collection ievents = entries.entrySet(); minVal=signed?((BitVector)left).toSignedValue():((BitVector)left).toUnsignedValue(); - if(!values.isEmpty()) { + if(!ievents.isEmpty()) { maxVal=minVal; - for (IEvent[] tp : entries.values()) - for(IEvent e: tp) { + for (EventEntry tp : ievents) + for(IEvent e: tp.events) { long v = signed?((BitVector)e).toSignedValue():((BitVector)e).toUnsignedValue(); maxVal=Math.max(maxVal, v); minVal=Math.min(minVal, v); @@ -358,15 +358,15 @@ public class SignalPainter extends TrackPainter { boolean continous=true; - public RealStencil(IEventList entries, Object left, boolean continous) { + public RealStencil(IEventList entries, Object left, boolean continous) { this.continous=continous; - Collection values = entries.values(); + Collection values = entries.entrySet(); minVal=(Double) left; range=2.0; if(!values.isEmpty()) { double maxVal=minVal; - for (IEvent[] val : entries.values()) - for(IEvent e:val) { + for (EventEntry val : values) + for(IEvent e:val.events) { double v = ((DoubleVal)e).value; if(Double.isNaN(maxVal)) maxVal=v; diff --git a/plugins/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/ui/swt/internal/StreamPainter.java b/plugins/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/ui/swt/internal/StreamPainter.java index 33a4d9f..39c96f2 100644 --- a/plugins/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/ui/swt/internal/StreamPainter.java +++ b/plugins/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/ui/swt/internal/StreamPainter.java @@ -10,7 +10,6 @@ *******************************************************************************/ package com.minres.scviewer.database.ui.swt.internal; -import java.util.Map.Entry; import java.util.TreeMap; import org.eclipse.swt.SWT; @@ -18,9 +17,9 @@ import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; +import com.minres.scviewer.database.EventEntry; import com.minres.scviewer.database.EventKind; import com.minres.scviewer.database.IEvent; -import com.minres.scviewer.database.IEventList; import com.minres.scviewer.database.IWaveform; import com.minres.scviewer.database.tx.ITx; import com.minres.scviewer.database.tx.ITxEvent; @@ -72,8 +71,8 @@ public class StreamPainter extends TrackPainter{ long beginTime = beginPos*scaleFactor; long endTime = beginTime + area.width*scaleFactor; - Entry firstTx=stream.getEvents().floorEntry(beginTime); - Entry lastTx=stream.getEvents().ceilingEntry(endTime); + EventEntry firstTx=stream.getEvents().floorEntry(beginTime); + EventEntry lastTx=stream.getEvents().ceilingEntry(endTime); if(firstTx==null) firstTx = stream.getEvents().firstEntry(); if(lastTx==null) lastTx=stream.getEvents().lastEntry(); proj.setFillRule(SWT.FILL_EVEN_ODD); @@ -84,16 +83,15 @@ public class StreamPainter extends TrackPainter{ for( int y1=area.y+trackHeight/2; y1 entries = stream.getEvents().subMap(firstTx.getKey(), true, lastTx.getKey(), true); ITxEvent highlighed=null; proj.setForeground(this.waveCanvas.styleProvider.getColor(WaveformColors.LINE)); long selectedId=waveCanvas.currentSelection!=null? waveCanvas.currentSelection.getId():-1; - for(Entry entry: entries.entrySet()) - for(IEvent e:entry.getValue()){ + for(EventEntry entry: stream.getEvents().subMap(firstTx.timestamp, true, lastTx.timestamp)) + for(IEvent e:entry.events){ ITxEvent evt = (ITxEvent) e; ITx tx = evt.getTransaction(); if(selectedId==tx.getId()) @@ -155,12 +153,12 @@ public class StreamPainter extends TrackPainter{ public ITx getClicked(Point point) { int lane=point.y/waveCanvas.styleProvider.getTrackHeight(); - Entry firstTx=stream.getEvents().floorEntry(point.x*waveCanvas.getScaleFactor()); + EventEntry firstTx=stream.getEvents().floorEntry(point.x*waveCanvas.getScaleFactor()); if(firstTx!=null){ do { - ITx tx = getTxFromEntry(lane, point.x, firstTx.getValue()); + ITx tx = getTxFromEntry(lane, point.x, firstTx.events); if(tx!=null) return tx; - firstTx=stream.getEvents().lowerEntry(firstTx.getKey()); + firstTx=stream.getEvents().lowerEntry(firstTx.timestamp); }while(firstTx!=null); } return null; diff --git a/plugins/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/ui/swt/internal/WaveformCanvas.java b/plugins/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/ui/swt/internal/WaveformCanvas.java index fb5d59f..e96ee6c 100644 --- a/plugins/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/ui/swt/internal/WaveformCanvas.java +++ b/plugins/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/ui/swt/internal/WaveformCanvas.java @@ -34,6 +34,7 @@ import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.ScrollBar; import com.google.common.collect.Lists; +import com.minres.scviewer.database.EventEntry; import com.minres.scviewer.database.IEvent; import com.minres.scviewer.database.IWaveform; import com.minres.scviewer.database.RelationType; @@ -427,8 +428,8 @@ public class WaveformCanvas extends Canvas { } for (IWaveformPainter painter : wave2painterMap.values()) { if (painter instanceof StreamPainter && ((StreamPainter) painter).getStream() == tx.getStream()) { - Entry entry = tx.getStream().getEvents().floorEntry(tx.getBeginTime()); - Optional res = Arrays.stream(entry.getValue()).filter(e -> ((ITxEvent)e).getTransaction().equals(tx)).findFirst(); + EventEntry entry = tx.getStream().getEvents().floorEntry(tx.getBeginTime()); + Optional res = Arrays.stream(entry.events).filter(e -> ((ITxEvent)e).getTransaction().equals(tx)).findFirst(); if(res.isPresent()) { int top = painter.getVerticalOffset() + styleProvider.getTrackHeight() * ((ITxEvent)res.get()).getRowIndex(); int bottom = top + styleProvider.getTrackHeight(); diff --git a/plugins/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/ui/swt/internal/WaveformView.java b/plugins/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/ui/swt/internal/WaveformView.java index 2f10f9e..9158736 100644 --- a/plugins/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/ui/swt/internal/WaveformView.java +++ b/plugins/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/ui/swt/internal/WaveformView.java @@ -76,6 +76,7 @@ import org.eclipse.wb.swt.SWTResourceManager; import com.google.common.collect.Lists; import com.minres.scviewer.database.BitVector; import com.minres.scviewer.database.DoubleVal; +import com.minres.scviewer.database.EventEntry; import com.minres.scviewer.database.EventKind; import com.minres.scviewer.database.IEvent; import com.minres.scviewer.database.IEventList; @@ -255,29 +256,29 @@ public class WaveformView implements IWaveformView { long time = waveformCanvas.getTimeForOffset(p.x); long scaling = 5 * waveformCanvas.getScaleFactor(); for (Object o : waveformCanvas.getElementsAt(p)) { - Entry floorEntry = null; - Entry ceilEntry = null; + EventEntry floorEntry = null; + EventEntry ceilEntry = null; if (o instanceof TrackEntry) { TrackEntry entry = (TrackEntry) o; - IEventList map = entry.waveform.getEvents(); + IEventList map = entry.waveform.getEvents(); floorEntry = map.floorEntry(time); ceilEntry = map.ceilingEntry(time); } else if (o instanceof ITx) { - IEventList map = ((ITx) o).getStream().getEvents(); + IEventList map = ((ITx) o).getStream().getEvents(); floorEntry = map.floorEntry(time); ceilEntry = map.ceilingEntry(time); } - if (floorEntry != null && time - floorEntry.getKey() > scaling) + if (floorEntry != null && time - floorEntry.timestamp > scaling) floorEntry = null; - if (ceilEntry != null && ceilEntry.getKey() - time > scaling) + if (ceilEntry != null && ceilEntry.timestamp - time > scaling) ceilEntry = null; if (ceilEntry == null && floorEntry != null) { - time = floorEntry.getKey(); + time = floorEntry.timestamp; } else if (ceilEntry != null && floorEntry == null) { - time = ceilEntry.getKey(); + time = ceilEntry.timestamp; } else if (ceilEntry != null && floorEntry != null) { - time = time - floorEntry.getKey() < ceilEntry.getKey() - time ? floorEntry.getKey() - : ceilEntry.getKey(); + time = time - floorEntry.timestamp < ceilEntry.timestamp - time ? floorEntry.timestamp + : ceilEntry.timestamp; } } return time; @@ -580,10 +581,10 @@ public class WaveformView implements IWaveformView { } } else if (entry.waveform.getType() == WaveformType.TRANSACTION) { ITx[] resultsList = new ITx[entry.waveform.getRowCount()]; - Entry firstTx = entry.waveform.getEvents().floorEntry(time); + EventEntry firstTx = entry.waveform.getEvents().floorEntry(time); if (firstTx != null) { do { - for (IEvent e : firstTx.getValue()) { + for (IEvent e : firstTx.events) { if (e instanceof ITxEvent) { ITxEvent evt = ((ITxEvent) e); ITx tx = evt.getTransaction(); @@ -593,7 +594,7 @@ public class WaveformView implements IWaveformView { resultsList[evt.getRowIndex()] = evt.getTransaction(); } } - firstTx = entry.waveform.getEvents().lowerEntry(firstTx.getKey()); + firstTx = entry.waveform.getEvents().lowerEntry(firstTx.timestamp); } while (firstTx != null && !isArrayFull(resultsList)); boolean separator = false; StringBuilder sb = new StringBuilder(); @@ -854,11 +855,11 @@ public class WaveformView implements IWaveformView { } } if (transaction == null) { - Entry entry = selectedWaveform.waveform.getEvents() + EventEntry entry = selectedWaveform.waveform.getEvents() .higherEntry(currentTxSelection.getBeginTime()); if (entry != null) do { - for (IEvent evt : entry.getValue()) { + for (IEvent evt : entry.events) { if (evt instanceof ITxEvent && (evt.getKind() == EventKind.BEGIN || evt.getKind() == EventKind.SINGLE)) { transaction = ((ITxEvent) evt).getTransaction(); @@ -866,7 +867,7 @@ public class WaveformView implements IWaveformView { } } if (transaction == null) - entry = selectedWaveform.waveform.getEvents().higherEntry(entry.getKey()); + entry = selectedWaveform.waveform.getEvents().higherEntry(entry.timestamp); } while (entry != null && transaction == null); } } else if (direction == GotoDirection.PREV) { @@ -883,11 +884,11 @@ public class WaveformView implements IWaveformView { } } if (transaction == null) { - Entry entry = selectedWaveform.waveform.getEvents() + EventEntry entry = selectedWaveform.waveform.getEvents() .lowerEntry(currentTxSelection.getBeginTime()); if (entry != null) do { - for (IEvent evt : Lists.reverse(Arrays.asList(entry.getValue()))) { + for (IEvent evt : Lists.reverse(Arrays.asList(entry.events))) { if (evt instanceof ITxEvent && (evt.getKind() == EventKind.BEGIN || evt.getKind() == EventKind.SINGLE)) { transaction = ((ITxEvent) evt).getTransaction(); @@ -895,7 +896,7 @@ public class WaveformView implements IWaveformView { } } if (transaction == null) - entry = selectedWaveform.waveform.getEvents().lowerEntry(entry.getKey()); + entry = selectedWaveform.waveform.getEvents().lowerEntry(entry.timestamp); } while (entry != null && transaction == null); } } @@ -958,14 +959,14 @@ public class WaveformView implements IWaveformView { return; TrackEntry sel = currentWaveformSelection.get(0); long time = getCursorTime(); - IEventList map = null; + IEventList map = null; if (sel.waveform.getType() == WaveformType.TRANSACTION || sel.waveform.getType() == WaveformType.SIGNAL) { map = sel.waveform.getEvents(); } if (map != null) { - Entry entry = direction == GotoDirection.PREV ? map.lowerEntry(time) : map.higherEntry(time); + EventEntry entry = direction == GotoDirection.PREV ? map.lowerEntry(time) : map.higherEntry(time); if (entry != null) { - time = entry.getKey(); + time = entry.timestamp; setCursorTime(time); waveformCanvas.reveal(time); waveformCanvas.redraw(); diff --git a/plugins/com.minres.scviewer.database.vcd/src/com/minres/scviewer/database/vcd/VCDDbLoader.java b/plugins/com.minres.scviewer.database.vcd/src/com/minres/scviewer/database/vcd/VCDDbLoader.java index ee5ce50..3a8c39f 100644 --- a/plugins/com.minres.scviewer.database.vcd/src/com/minres/scviewer/database/vcd/VCDDbLoader.java +++ b/plugins/com.minres.scviewer.database.vcd/src/com/minres/scviewer/database/vcd/VCDDbLoader.java @@ -26,7 +26,6 @@ import java.util.zip.GZIPInputStream; import com.google.common.collect.Iterables; import com.minres.scviewer.database.BitVector; import com.minres.scviewer.database.DoubleVal; -import com.minres.scviewer.database.IEvent; import com.minres.scviewer.database.IEventList; import com.minres.scviewer.database.IWaveform; import com.minres.scviewer.database.IWaveformDb; @@ -117,16 +116,16 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder { if(!res) throw new InputFormatException("Could not parse VCD file"); // calculate max time of this database for(IWaveform waveform:signals) { - IEventList events =waveform.getEvents(); + IEventList events =waveform.getEvents(); if(!events.isEmpty()) maxTime= Math.max(maxTime, events.lastKey()); } // extend signals to have a last value set at max time for(IWaveform s:signals){ if(s instanceof VCDSignal) { - IEventList events = ((VCDSignal)s).getEvents(); + IEventList events = ((VCDSignal)s).getEvents(); if(events.size()>0 && events.lastKey())s).addSignalChange(maxTime, (BitVector) val); } else if(val instanceof DoubleVal) diff --git a/plugins/com.minres.scviewer.database.vcd/src/com/minres/scviewer/database/vcd/VCDSignal.java b/plugins/com.minres.scviewer.database.vcd/src/com/minres/scviewer/database/vcd/VCDSignal.java index 46ab266..6bfd9fd 100644 --- a/plugins/com.minres.scviewer.database.vcd/src/com/minres/scviewer/database/vcd/VCDSignal.java +++ b/plugins/com.minres.scviewer.database.vcd/src/com/minres/scviewer/database/vcd/VCDSignal.java @@ -10,8 +10,7 @@ *******************************************************************************/ package com.minres.scviewer.database.vcd; -import java.util.Map.Entry; - +import com.minres.scviewer.database.EventEntry; import com.minres.scviewer.database.EventList; import com.minres.scviewer.database.HierNode; import com.minres.scviewer.database.IEvent; @@ -27,7 +26,7 @@ public class VCDSignal extends HierNode implements IWaveform { private final int width; - private IEventList values; + private IEventList values; public VCDSignal(String name) { this(0, name, 1); @@ -42,7 +41,7 @@ public class VCDSignal extends HierNode implements IWaveform { fullName=name; this.id=id; this.width=width; - this.values=new EventList<>(); + this.values=new EventList(); } public VCDSignal(VCDSignal o, int id, String name) { @@ -80,7 +79,7 @@ public class VCDSignal extends HierNode implements IWaveform { } @Override - public IEventList getEvents() { + public IEventList getEvents() { return values; } @@ -91,11 +90,11 @@ public class VCDSignal extends HierNode implements IWaveform { @Override public IEvent[] getEventsBeforeTime(Long time) { - Entry e = values.floorEntry(time); + EventEntry e = values.floorEntry(time); if(e==null) return new IEvent[] {}; else - return values.floorEntry(time).getValue(); + return values.floorEntry(time).events; } @Override diff --git a/plugins/com.minres.scviewer.database/META-INF/MANIFEST.MF b/plugins/com.minres.scviewer.database/META-INF/MANIFEST.MF index 952a33d..ce92e9f 100644 --- a/plugins/com.minres.scviewer.database/META-INF/MANIFEST.MF +++ b/plugins/com.minres.scviewer.database/META-INF/MANIFEST.MF @@ -10,3 +10,4 @@ Export-Package: com.minres.scviewer.database, Bundle-ActivationPolicy: lazy Service-Component: OSGI-INF/component.xml,OSGI-INF/component2.xml Automatic-Module-Name: com.minres.scviewer.database +Require-Bundle: org.eclipse.collections;bundle-version="10.4.0" diff --git a/plugins/com.minres.scviewer.database/src/com/minres/scviewer/database/EventEntry.java b/plugins/com.minres.scviewer.database/src/com/minres/scviewer/database/EventEntry.java new file mode 100644 index 0000000..b719625 --- /dev/null +++ b/plugins/com.minres.scviewer.database/src/com/minres/scviewer/database/EventEntry.java @@ -0,0 +1,28 @@ +package com.minres.scviewer.database; + +public class EventEntry implements Comparable{ + public long timestamp; // unsigned + public IEvent[] events = null; + + + public EventEntry(long timestamp) { + this.timestamp = timestamp; + } + + + public EventEntry(long timestamp, IEvent[] events) { + this.timestamp = timestamp; + this.events = events; + } + + + @Override + public int compareTo(EventEntry o) { + return Long.compareUnsigned(timestamp, o.timestamp); + } + + @Override + public String toString() { + return String.format("e.%d@%d", events.length,timestamp); + } +} diff --git a/plugins/com.minres.scviewer.database/src/com/minres/scviewer/database/EventList.java b/plugins/com.minres.scviewer.database/src/com/minres/scviewer/database/EventList.java index f059d35..74cb340 100644 --- a/plugins/com.minres.scviewer.database/src/com/minres/scviewer/database/EventList.java +++ b/plugins/com.minres.scviewer.database/src/com/minres/scviewer/database/EventList.java @@ -1,100 +1,196 @@ package com.minres.scviewer.database; +import java.util.ArrayList; import java.util.Collection; -import java.util.Map.Entry; -import java.util.NavigableMap; -import java.util.TreeMap; +import java.util.Collections; -public class EventList implements IEventList{ +public class EventList implements IEventList { - NavigableMap backing ; + ArrayList store = new ArrayList<>(); + int start = 0; + int end = store.size(); + boolean unmodifiable = false; + + public class Iterator implements java.util.Iterator { + + EventList list; + + private int pos; + + public Iterator(EventList list) { + this.list=list; + this.pos=-1; + } + @Override + public boolean hasNext() { + return pos<(list.end-1); + } + + @Override + public EventEntry next() { + if(hasNext()) { + pos++; + return list.store.get(pos); + } else + return null; + } + + @Override + public void remove() { + list.store.remove(pos); + } + + } + public EventList() { - backing=new TreeMap<>(); } - public EventList(NavigableMap subMap) { - backing=subMap; + private EventList(ArrayList store , int start, int end) { + this.store=store; + this.start=start; + this.end=end; + this.unmodifiable=true; } @Override - public Entry floorEntry(K key) { - return backing.floorEntry(key); + public IEventList subMap(long from, boolean includeFrom, long to) { + //the index of the first element greater than the key, or list.size() + int beginIndex = Collections.binarySearch(store, new EventEntry(from)); + int startIndex = beginIndex < 0? -(beginIndex + 1): beginIndex; + int endIndex = Collections.binarySearch(store, new EventEntry(to)); + endIndex = endIndex < 0? -(endIndex + 1): endIndex+1; + if(beginIndex>0 && !includeFrom) + return new EventList(store, startIndex+1, endIndex); + else + return new EventList(store, startIndex, endIndex); } - - @Override - public Entry ceilingEntry(K key) { - return backing.ceilingEntry(key); - } - - @Override - public Entry firstEntry() { - return backing.firstEntry(); - } - - @Override - public Entry lastEntry() { - return backing.lastEntry(); - } - - @Override - public V get(K key) { - return backing.get(key); - } - - @Override - public Entry higherEntry(K key) { - return backing.higherEntry(key); - } - - @Override - public Entry lowerEntry(K key) { - return backing.lowerEntry(key); - } - - @Override - public IEventList subMap(K key, boolean b, K key2, boolean c) { - return new EventList( backing.subMap(key, b, key2, c)); - } - + @Override public int size() { - return backing.size(); + return end-start; } @Override - public Collection keys() { - return backing.keySet(); + public boolean containsKey(long key) { + int index = Collections.binarySearch(store, new EventEntry(key)); + return index>=0 && index>=start && index values() { - return backing.values(); + public IEvent[] get(long key) { + int index = Collections.binarySearch(store, new EventEntry(key)); + if(index<0) return null; + return index>=start && index> entrySet() { - return backing.entrySet(); + public Collection entrySet() { + if(start != 0 || end != store.size()) + return Collections.unmodifiableList(store.subList(start, end)); + else + return Collections.unmodifiableList(store); } @Override public boolean isEmpty() { - return backing.isEmpty(); + return start==end || store.isEmpty(); } @Override - public K lastKey() { - return backing.lastKey(); + public long firstKey() { + return store.get(start).timestamp; + } + + @Override + public long lastKey() { + return store.get(end-1).timestamp; + } + + // Navigable map functions + @Override + public EventEntry firstEntry() { + return store.get(start); + } + + @Override + public EventEntry lastEntry() { + return store.get(end-1); + } + + @Override + public EventEntry floorEntry(long key) { + int index = Collections.binarySearch(store, new EventEntry(key)); + if(index==-1) return null; + // < 0 if element is not in the list, see Collections.binarySearch + if (index < 0) { + index = -(index + 2); + } + if(index>=end) + return store.get(end-1); + return index=end? null: store.get(index); + } + + @Override + public EventEntry lowerEntry(long key) { + int index = Collections.binarySearch(store, new EventEntry(key)); + // < 0 if element is not in the list, see Collections.binarySearch + if (index < 0) + index = -(index + 1); + index--; + if(index>=end) + return store.get(end-1); + return index>=end || index=end || index iterator() { + return new Iterator(this); } } diff --git a/plugins/com.minres.scviewer.database/src/com/minres/scviewer/database/IEventList.java b/plugins/com.minres.scviewer.database/src/com/minres/scviewer/database/IEventList.java index d94e81a..ddc2459 100644 --- a/plugins/com.minres.scviewer.database/src/com/minres/scviewer/database/IEventList.java +++ b/plugins/com.minres.scviewer.database/src/com/minres/scviewer/database/IEventList.java @@ -1,40 +1,84 @@ package com.minres.scviewer.database; import java.util.Collection; -import java.util.Map.Entry; -public interface IEventList { - - Entry floorEntry(K key); - - Entry ceilingEntry(K key); - - Entry firstEntry(); - - Entry lastEntry(); - - V get(K key); - - Entry higherEntry(K key); - - Entry lowerEntry(K key); - - IEventList subMap(K key, boolean b, K key2, boolean c); +public interface IEventList extends Iterable { int size(); - Collection keys(); - - Collection values(); + Collection entrySet(); - boolean containsKey(K key); + boolean containsKey(long key); - V put(K key, V value); + IEvent[] get(long key); - Collection> entrySet(); + IEvent[] put(long key, IEvent[] value); + + long firstKey(); + + long lastKey(); boolean isEmpty(); - - K lastKey(); - + /** + * Returns a key-value mapping associated with the greatest key less + * than or equal to the given key, or null if there is no such key. + * + * @param key + * @return + */ + EventEntry floorEntry(long key); + /** + * Returns a key-value mapping associated with the least key greater + * than or equal to the given key, or null if there is no such key. + * + * @param key + * @return + */ + EventEntry ceilingEntry(long key); + /** + * Returns a key-value mapping associated with the least key in this map, + * or null if the map is empty. + * + * @return + */ + EventEntry firstEntry(); + /** + * Returns a key-value mapping associated with the least key in this map, + * or null if the map is empty. + * + * @return + */ + EventEntry lastEntry(); + /** + * Returns a key-value mapping associated with the least key strictly greater + * than the given key, or null if there is no such key. + * + * @param key + * @return + */ + EventEntry higherEntry(long key); + /** + * Returns a key-value mapping associated with the greatest key strictly less + * than the given key, or null if there is no such key. + * + * @param key + * @return + */ + EventEntry lowerEntry(long key); + /** + * Returns a view of the portion of this map whose keys range from + * {@code fromKey} to {@code toKey}. If {@code fromKey} and + * {@code toKey} are equal, the returned map is empty unless + * {@code fromInclusive} is true. The + * returned map is backed by this map, so changes in the returned map are + * reflected in this map, and vice-versa. The returned map supports all + * optional map operations that this map supports. + * + * @param fromKey low endpoint of the keys in the returned map + * @param fromInclusive {@code true} if the low endpoint + * is to be included in the returned view + * @param toKey high endpoint of the keys in the returned map (inclusive) + */ + IEventList subMap(long key, boolean b, long key2); + } diff --git a/plugins/com.minres.scviewer.database/src/com/minres/scviewer/database/IWaveform.java b/plugins/com.minres.scviewer.database/src/com/minres/scviewer/database/IWaveform.java index a35ddd5..ef3b2ee 100644 --- a/plugins/com.minres.scviewer.database/src/com/minres/scviewer/database/IWaveform.java +++ b/plugins/com.minres.scviewer.database/src/com/minres/scviewer/database/IWaveform.java @@ -39,7 +39,7 @@ public interface IWaveform extends IHierNode { * * @return the events */ - public IEventList getEvents(); + public IEventList getEvents(); /** * Gets the events at time. diff --git a/plugins/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/elements/WaveformPopupMenuContribution.java b/plugins/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/elements/WaveformPopupMenuContribution.java index 58cf2a2..b85191a 100644 --- a/plugins/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/elements/WaveformPopupMenuContribution.java +++ b/plugins/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/elements/WaveformPopupMenuContribution.java @@ -40,7 +40,7 @@ public class WaveformPopupMenuContribution { if(elem instanceof TrackEntry) { TrackEntry e = (TrackEntry) elem; if(e.waveform.getType() == WaveformType.SIGNAL) { - Object o = e.waveform.getEvents().firstEntry().getValue()[0]; + Object o = e.waveform.getEvents().firstEntry().events[0]; if(checkForDouble && o instanceof DoubleVal) return true; else if(o instanceof BitVector && ((BitVector)o).getWidth()>1) diff --git a/plugins/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/parts/TransactionList.java b/plugins/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/parts/TransactionList.java index be0abe4..805af8b 100644 --- a/plugins/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/parts/TransactionList.java +++ b/plugins/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/parts/TransactionList.java @@ -32,8 +32,8 @@ import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.Text; import com.minres.scviewer.database.DataType; +import com.minres.scviewer.database.EventEntry; import com.minres.scviewer.database.EventKind; -import com.minres.scviewer.database.IEvent; import com.minres.scviewer.database.IWaveform; import com.minres.scviewer.database.WaveformType; import com.minres.scviewer.database.tx.ITx; @@ -249,8 +249,10 @@ public class TransactionList extends Composite { }catch(SecurityException e){} updateThread = new Thread(()-> { final ConcurrentHashMap propNames=new ConcurrentHashMap<>(); - Collection values = stream.getEvents().values(); - final List txList = values.parallelStream().map(Arrays::asList) + Collection values = stream.getEvents().entrySet(); + final List txList = values.parallelStream() + .map(e->e.events) + .map(Arrays::asList) .flatMap(List::stream) .filter(evt -> evt.getKind()==EventKind.BEGIN || evt.getKind()==EventKind.SINGLE) .map(evt-> { diff --git a/plugins/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/parts/WaveformViewer.java b/plugins/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/parts/WaveformViewer.java index d6ede73..e629583 100644 --- a/plugins/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/parts/WaveformViewer.java +++ b/plugins/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/parts/WaveformViewer.java @@ -815,9 +815,18 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis String trackentryName = state.get(SELECTED_TRACKENTRY_NAME); //get TrackEntry Object based on name and TX Object by id and put into selectionList trackEntries.stream().filter(e->trackentryName.equals(e.waveform.getFullName())).forEach(trackEntry -> - trackEntry.waveform.getEvents().values().stream().filter(Objects::nonNull).forEach(entries-> - Arrays.stream(entries).filter(e->e instanceof ITxEvent && txId.equals(((ITxEvent)e).getTransaction().getId())).forEach(event -> - waveformPane.setSelection(new StructuredSelection(new Object[] {((ITxEvent)event).getTransaction(), trackEntry}))))); + trackEntry.waveform.getEvents().entrySet().stream() + .map(e->e.events) + .filter(Objects::nonNull) + .forEach(entries-> + Arrays.stream(entries) + .filter(e->e instanceof ITxEvent && txId.equals(((ITxEvent)e).getTransaction().getId())) + .forEach(event -> + waveformPane.setSelection(new StructuredSelection( + new Object[] {((ITxEvent)event).getTransaction(), trackEntry})) + ) + ) + ); } catch (NumberFormatException e) { } } diff --git a/tests/com.minres.scviewer.database.test/src/com/minres/scviewer/database/test/DatabaseServicesTest.java b/tests/com.minres.scviewer.database.test/src/com/minres/scviewer/database/test/DatabaseServicesTest.java index 35b9c93..53e02a5 100644 --- a/tests/com.minres.scviewer.database.test/src/com/minres/scviewer/database/test/DatabaseServicesTest.java +++ b/tests/com.minres.scviewer.database.test/src/com/minres/scviewer/database/test/DatabaseServicesTest.java @@ -16,13 +16,12 @@ import static org.junit.Assert.assertTrue; import java.io.File; import java.util.List; -import java.util.Map.Entry; import org.junit.After; import org.junit.Before; import org.junit.Test; -import com.minres.scviewer.database.IEvent; +import com.minres.scviewer.database.EventEntry; import com.minres.scviewer.database.IWaveform; import com.minres.scviewer.database.IWaveformDb; @@ -50,11 +49,11 @@ public class DatabaseServicesTest { assertEquals(14, waves.size()); assertEquals(2, waveformDb.getChildNodes().size()); IWaveform bus_data_wave = waves.get(0); - Entry bus_data_entry = bus_data_wave.getEvents().floorEntry(1400000000L); - assertEquals("01111000", bus_data_entry.getValue()[0].toString()); + EventEntry bus_data_entry = bus_data_wave.getEvents().floorEntry(1400000000L); + assertEquals("01111000", bus_data_entry.events[0].toString()); IWaveform rw_wave = waves.get(2); - Entry rw_entry = rw_wave.getEvents().floorEntry(2360000000L); - assertEquals("1", rw_entry.getValue()[0].toString()); + EventEntry rw_entry = rw_wave.getEvents().floorEntry(2360000000L); + assertEquals("1", rw_entry.events[0].toString()); } @Test diff --git a/tests/com.minres.scviewer.database.test/src/com/minres/scviewer/database/test/EventListTest.java b/tests/com.minres.scviewer.database.test/src/com/minres/scviewer/database/test/EventListTest.java new file mode 100644 index 0000000..f82faa1 --- /dev/null +++ b/tests/com.minres.scviewer.database.test/src/com/minres/scviewer/database/test/EventListTest.java @@ -0,0 +1,198 @@ +package com.minres.scviewer.database.test; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.util.stream.Collectors; + +import org.junit.Test; + +import com.minres.scviewer.database.EventList; +import com.minres.scviewer.database.IEvent; +import com.minres.scviewer.database.IEventList; + +public class EventListTest { + + EventList createList(int[] times) { + EventList list = new EventList(); + for(int time: times) + list.put(time, new IEvent[] {}); + return list; + } + + Long[] getTimestamps(IEventList list) { + return list.entrySet().stream().map(e->e.timestamp).collect(Collectors.toList()).toArray(new Long[] {}); + } + + @Test + public void testInsertion() throws Exception { + IEventList list = createList(new int[] {5, 7, 3, 6, 2, 0}); + assertEquals(6, list.size()); + assertArrayEquals(new Long[]{0L, 2L, 3L, 5L, 6L, 7L}, getTimestamps(list)); + } + + @Test + public void testSublist() throws Exception { + IEventList list = createList(new int[] {5, 7, 3, 8, 2, 0}); + { + IEventList subList = list.subMap(3, true, 5); + assertEquals(2, subList.size()); + assertArrayEquals(new Long[]{3L, 5L}, getTimestamps(subList)); + } { + IEventList subList = list.subMap(3, false, 5); + assertEquals(1, subList.size()); + assertArrayEquals(new Long[]{5L}, getTimestamps(subList)); + } { + IEventList subList = list.subMap(4, true, 6); + assertEquals(1, subList.size()); + assertArrayEquals(new Long[]{5L}, getTimestamps(subList)); + } { + IEventList subList = list.subMap(4, false, 6); + assertEquals(1, subList.size()); + assertArrayEquals(new Long[]{5L}, getTimestamps(subList)); + } { + IEventList subList = list.subMap(4, true, 9); + assertEquals(3, subList.size()); + assertArrayEquals(new Long[]{5L, 7L, 8L}, getTimestamps(subList)); + } { + IEventList subList = list.subMap(4, false, 9); + assertEquals(3, subList.size()); + assertArrayEquals(new Long[]{5L, 7L, 8L}, getTimestamps(subList)); + } + } + + @Test + public void testEntries() throws Exception { + IEventList list = createList(new int[] {2, 5, 8, 11}); + assertEquals(2, list.firstEntry().timestamp); + assertEquals(11, list.lastEntry().timestamp); + + assertNull(list.floorEntry(1)); + assertEquals(2, list.floorEntry(2).timestamp); + assertEquals(2, list.floorEntry(3).timestamp); + assertEquals(2, list.floorEntry(4).timestamp); + assertEquals(5, list.floorEntry(5).timestamp); + assertEquals(5, list.floorEntry(6).timestamp); + assertEquals(8, list.floorEntry(10).timestamp); + assertEquals(11, list.floorEntry(11).timestamp); + assertEquals(11, list.floorEntry(12).timestamp); + + assertEquals(2, list.ceilingEntry(1).timestamp); + assertEquals(2, list.ceilingEntry(2).timestamp); + assertEquals(5, list.ceilingEntry(3).timestamp); + assertEquals(5, list.ceilingEntry(4).timestamp); + assertEquals(5, list.ceilingEntry(5).timestamp); + assertEquals(8, list.ceilingEntry(6).timestamp); + assertEquals(11, list.ceilingEntry(10).timestamp); + assertEquals(11, list.ceilingEntry(11).timestamp); + assertNull(list.ceilingEntry(12)); + + assertNull(list.lowerEntry(1)); + assertNull(list.lowerEntry(2)); + assertEquals(2, list.lowerEntry(3).timestamp); + assertEquals(2, list.lowerEntry(4).timestamp); + assertEquals(2, list.lowerEntry(5).timestamp); + assertEquals(5, list.lowerEntry(6).timestamp); + assertEquals(8, list.lowerEntry(10).timestamp); + assertEquals(8, list.lowerEntry(11).timestamp); + assertEquals(11, list.lowerEntry(12).timestamp); + + assertEquals(2, list.higherEntry(1).timestamp); + assertEquals(5, list.higherEntry(2).timestamp); + assertEquals(5, list.higherEntry(3).timestamp); + assertEquals(5, list.higherEntry(4).timestamp); + assertEquals(8, list.higherEntry(5).timestamp); + assertEquals(8, list.higherEntry(6).timestamp); + assertEquals(11, list.higherEntry(10).timestamp); + assertNull(list.higherEntry(11)); + assertNull(list.higherEntry(12)); + } + + @Test + public void testSubListEntries() throws Exception { + IEventList fullList = createList(new int[] {2, 5, 8, 11}); + IEventList list = fullList.subMap(5, true, 8); + + assertEquals(5, list.firstEntry().timestamp); + assertEquals(8, list.lastEntry().timestamp); + + assertNull(list.floorEntry(1)); + assertNull(list.floorEntry(2)); + assertNull(list.floorEntry(3)); + assertNull(list.floorEntry(4)); + assertEquals(5, list.floorEntry(5).timestamp); + assertEquals(5, list.floorEntry(6).timestamp); + assertEquals(8, list.floorEntry(10).timestamp); + assertEquals(8, list.floorEntry(11).timestamp); + assertEquals(8, list.floorEntry(12).timestamp); + + assertEquals(5, list.ceilingEntry(1).timestamp); + assertEquals(5, list.ceilingEntry(2).timestamp); + assertEquals(5, list.ceilingEntry(3).timestamp); + assertEquals(5, list.ceilingEntry(4).timestamp); + assertEquals(5, list.ceilingEntry(5).timestamp); + assertEquals(8, list.ceilingEntry(6).timestamp); + assertEquals(8, list.ceilingEntry(8).timestamp); + assertNull(list.ceilingEntry(10)); + assertNull(list.ceilingEntry(11)); + assertNull(list.ceilingEntry(12)); + + assertNull(list.lowerEntry(1)); + assertNull(list.lowerEntry(2)); + assertNull(list.lowerEntry(3)); + assertNull(list.lowerEntry(4)); + assertNull(list.lowerEntry(5)); + assertEquals(5, list.lowerEntry(6).timestamp); + assertEquals(8, list.lowerEntry(10).timestamp); + assertEquals(8, list.lowerEntry(11).timestamp); + assertEquals(8, list.lowerEntry(12).timestamp); + + assertEquals(5, list.higherEntry(1).timestamp); + assertEquals(5, list.higherEntry(2).timestamp); + assertEquals(5, list.higherEntry(3).timestamp); + assertEquals(5, list.higherEntry(4).timestamp); + assertEquals(8, list.higherEntry(5).timestamp); + assertEquals(8, list.higherEntry(6).timestamp); + assertNull(list.higherEntry(8)); + assertNull(list.higherEntry(10)); + assertNull(list.higherEntry(11)); + assertNull(list.higherEntry(12)); + } + + @Test + public void testInterface() throws Exception { + EventList emptyList = new EventList(); + IEventList populatedList = createList(new int[] {0, 2, 3, 5, 6, 7}); + assertEquals(0, emptyList.size()); + assertEquals(6, populatedList.size()); + assertTrue(emptyList.isEmpty()); + assertFalse(populatedList.isEmpty()); + assertFalse(emptyList.containsKey(5)); + assertTrue(populatedList.containsKey(5)); + assertFalse(populatedList.containsKey(8)); + assertNull(emptyList.get(5)); + assertNotNull(populatedList.get(5)); + assertNull(populatedList.get(8)); + } + + @Test + public void testInterfaceSublist() throws Exception { + IEventList fullList = createList(new int[] {0, 2, 3, 5, 6, 7}); + IEventList emptyList = fullList.subMap(3, false, 4); + IEventList populatedList = fullList.subMap(2, true, 6); + assertEquals(0, emptyList.size()); + assertEquals(4, populatedList.size()); + assertTrue(emptyList.isEmpty()); + assertFalse(populatedList.isEmpty()); + assertFalse(emptyList.containsKey(5)); + assertTrue(populatedList.containsKey(5)); + assertFalse(populatedList.containsKey(8)); + assertNull(emptyList.get(5)); + assertNotNull(populatedList.get(5)); + assertNull(populatedList.get(7)); + } +}