Refactored database data model to improve speed and reduce memory
consumption
This commit is contained in:
@ -47,15 +47,6 @@ public interface IVCDDatabaseBuilder {
|
||||
*/
|
||||
public int getNetWidth(int netId);
|
||||
|
||||
/**
|
||||
* Append transition.
|
||||
*
|
||||
* @param netId the int value
|
||||
* @param currentTime the current time in ps
|
||||
* @param decodedValues the decoded bit values
|
||||
*/
|
||||
public void appendTransition(int netId, long currentTime, char decodedValue);
|
||||
|
||||
/**
|
||||
* Append transition.
|
||||
*
|
||||
|
@ -12,6 +12,7 @@ package com.minres.scviewer.database.vcd;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@ -22,10 +23,6 @@ import java.util.Vector;
|
||||
|
||||
import com.minres.scviewer.database.BitVector;
|
||||
import com.minres.scviewer.database.ISignal;
|
||||
import com.minres.scviewer.database.ISignalChange;
|
||||
import com.minres.scviewer.database.ISignalChangeBitVector;
|
||||
import com.minres.scviewer.database.ISignalChangeReal;
|
||||
import com.minres.scviewer.database.ISignalChangeBit;
|
||||
import com.minres.scviewer.database.IWaveform;
|
||||
import com.minres.scviewer.database.IWaveformDb;
|
||||
import com.minres.scviewer.database.IWaveformDbLoader;
|
||||
@ -49,7 +46,7 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
|
||||
private Stack<String> moduleStack;
|
||||
|
||||
/** The signals. */
|
||||
private List<IWaveform<? extends IWaveformEvent>> signals;
|
||||
private List<IWaveform> signals;
|
||||
|
||||
/** The max time. */
|
||||
private long maxTime;
|
||||
@ -71,40 +68,41 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
|
||||
public boolean load(IWaveformDb db, File file) throws Exception {
|
||||
this.db=db;
|
||||
this.maxTime=0;
|
||||
FileInputStream fis = new FileInputStream(file);
|
||||
byte[] buffer = new byte[dateBytes.length];
|
||||
int read = fis.read(buffer, 0, dateBytes.length);
|
||||
fis.close();
|
||||
if (read == dateBytes.length)
|
||||
for (int i = 0; i < dateBytes.length; i++)
|
||||
if (buffer[i] != dateBytes[i])
|
||||
return false;
|
||||
try {
|
||||
FileInputStream fis = new FileInputStream(file);
|
||||
byte[] buffer = new byte[dateBytes.length];
|
||||
int read = fis.read(buffer, 0, dateBytes.length);
|
||||
fis.close();
|
||||
if (read == dateBytes.length)
|
||||
for (int i = 0; i < dateBytes.length; i++)
|
||||
if (buffer[i] != dateBytes[i])
|
||||
return false;
|
||||
} catch(FileNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
signals = new Vector<IWaveform<? extends IWaveformEvent>>();
|
||||
signals = new Vector<IWaveform>();
|
||||
moduleStack= new Stack<String>();
|
||||
boolean res = new VCDFileParser(false).load(new FileInputStream(file), this);
|
||||
moduleStack=null;
|
||||
if(!res) throw new InputFormatException();
|
||||
// calculate max time of database
|
||||
for(IWaveform<? extends IWaveformEvent> waveform:signals) {
|
||||
NavigableMap<Long, ? extends ISignalChange> events =((ISignal<? extends ISignalChange>)waveform).getEvents();
|
||||
for(IWaveform waveform:signals) {
|
||||
NavigableMap<Long, ?> events =((ISignal<?>)waveform).getEvents();
|
||||
if(events.size()>0)
|
||||
maxTime= Math.max(maxTime, events.lastKey());
|
||||
}
|
||||
// extend signals to hav a last value set at max time
|
||||
for(IWaveform<? extends IWaveformEvent> waveform:signals){
|
||||
TreeMap<Long,? extends ISignalChange> events = ((VCDSignal<? extends ISignalChange>)waveform).values;
|
||||
if(events.size()>0 && events.lastKey()<maxTime){
|
||||
ISignalChange x = events.lastEntry().getValue();
|
||||
if(x instanceof ISignalChangeBit)
|
||||
((VCDSignal<ISignalChangeBit>)waveform).values.put(maxTime,
|
||||
new VCDSignalChangeBit(maxTime, ((ISignalChangeBit)x).getValue()));
|
||||
else if(x instanceof ISignalChangeBitVector)
|
||||
((VCDSignal<ISignalChangeBitVector>)waveform).values.put(maxTime,
|
||||
new VCDSignalChangeBitVector(maxTime, ((ISignalChangeBitVector)x).getValue()));
|
||||
else if(x instanceof ISignalChangeReal)
|
||||
((VCDSignal<ISignalChangeReal>)waveform).values.put(maxTime,
|
||||
new VCDSignalChangeReal(maxTime, ((ISignalChangeReal)x).getValue()));
|
||||
for(IWaveform s:signals){
|
||||
if(s instanceof VCDSignal<?>) {
|
||||
TreeMap<Long,?> events = (TreeMap<Long, ?>) ((VCDSignal<?>)s).getEvents();
|
||||
if(events.size()>0 && events.lastKey()<maxTime){
|
||||
Object val = events.lastEntry().getValue();
|
||||
if(val instanceof BitVector) {
|
||||
((VCDSignal<BitVector>)s).addSignalChange(maxTime, (BitVector) val);
|
||||
} else if(val instanceof Double)
|
||||
((VCDSignal<Double>)s).addSignalChange(maxTime, (Double) val);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@ -122,7 +120,7 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
|
||||
* @see com.minres.scviewer.database.ITrDb#getAllWaves()
|
||||
*/
|
||||
@Override
|
||||
public List<IWaveform<? extends IWaveformEvent>> getAllWaves() {
|
||||
public List<IWaveform> getAllWaves() {
|
||||
return signals;
|
||||
}
|
||||
|
||||
@ -154,18 +152,14 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
|
||||
public Integer newNet(String name, int i, int width) {
|
||||
String netName = moduleStack.empty()? name: moduleStack.lastElement()+"."+name;
|
||||
int id = signals.size();
|
||||
VCDSignal<? extends IWaveformEvent> signal;
|
||||
if(width<0) {
|
||||
signal = i<0 ? new VCDSignal<ISignalChangeReal>(db, id, netName, width) :
|
||||
new VCDSignal<ISignalChangeReal>((VCDSignal<ISignalChangeReal>)signals.get(i), id, netName);
|
||||
} else if(width==1){
|
||||
signal = i<0 ? new VCDSignal<ISignalChangeBit>(db, id, netName) :
|
||||
new VCDSignal<ISignalChangeBit>((VCDSignal<ISignalChangeBit>)signals.get(i), id, netName);
|
||||
} else {
|
||||
signal = i<0 ? new VCDSignal<ISignalChangeBitVector>(db, id, netName, width) :
|
||||
new VCDSignal<ISignalChangeBitVector>((VCDSignal<VCDSignalChangeBitVector>)signals.get(i), id, netName);
|
||||
};
|
||||
signals.add(signal);
|
||||
assert(width>0);
|
||||
if(width==0) {
|
||||
signals.add( i<0 ? new VCDSignal<Double>(db, id, netName) :
|
||||
new VCDSignal<Double>((VCDSignal<Double>)signals.get(i), id, netName));
|
||||
} else if(width>0){
|
||||
signals.add( i<0 ? new VCDSignal<BitVector>(db, id, netName, width) :
|
||||
new VCDSignal<BitVector>((VCDSignal<BitVector>)signals.get(i), id, netName));
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
@ -174,7 +168,7 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
|
||||
*/
|
||||
@Override
|
||||
public int getNetWidth(int intValue) {
|
||||
VCDSignal<? extends IWaveformEvent> signal = (VCDSignal<? extends IWaveformEvent>) signals.get(intValue);
|
||||
VCDSignal<?> signal = (VCDSignal<?>) signals.get(intValue);
|
||||
return signal.getWidth();
|
||||
}
|
||||
|
||||
@ -183,12 +177,10 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void appendTransition(int signalId, long currentTime, char decodedValues) {
|
||||
VCDSignal<? extends IWaveformEvent> signal = (VCDSignal<? extends IWaveformEvent>) signals.get(signalId);
|
||||
Long time = currentTime*TIME_RES;
|
||||
if(signal.getWidth()==1){
|
||||
((VCDSignal<ISignalChangeBit>)signal).values.put(time, new VCDSignalChangeBit(time, decodedValues));
|
||||
}
|
||||
public void appendTransition(int signalId, long currentTime, BitVector value) {
|
||||
VCDSignal<BitVector> signal = (VCDSignal<BitVector>) signals.get(signalId);
|
||||
Long time = currentTime* TIME_RES;
|
||||
signal.getEvents().put(time, value);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@ -196,24 +188,11 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void appendTransition(int signalId, long currentTime, BitVector decodedValues) {
|
||||
VCDSignal<? extends IWaveformEvent> signal = (VCDSignal<? extends IWaveformEvent>) signals.get(signalId);
|
||||
public void appendTransition(int signalId, long currentTime, double value) {
|
||||
VCDSignal<?> signal = (VCDSignal<?>) signals.get(signalId);
|
||||
Long time = currentTime* TIME_RES;
|
||||
if(signal.getWidth()>1){
|
||||
((VCDSignal<VCDSignalChangeBitVector>)signal).values.put(time, new VCDSignalChangeBitVector(time, decodedValues));
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.minres.scviewer.database.vcd.ITraceBuilder#appendTransition(int, long, com.minres.scviewer.database.vcd.BitVector)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void appendTransition(int signalId, long currentTime, double decodedValue) {
|
||||
VCDSignal<? extends IWaveformEvent> signal = (VCDSignal<? extends IWaveformEvent>) signals.get(signalId);
|
||||
Long time = currentTime* TIME_RES;
|
||||
if(signal.getWidth()<0){
|
||||
((VCDSignal<ISignalChangeReal>)signal).values.put(time, new VCDSignalChangeReal(time, decodedValue));
|
||||
if(signal.getWidth()==0){
|
||||
((VCDSignal<Double>)signal).getEvents().put(time, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@ package com.minres.scviewer.database.vcd;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
import com.minres.scviewer.database.BitValue;
|
||||
import com.minres.scviewer.database.BitVector;
|
||||
|
||||
class VCDFileParser {
|
||||
@ -65,7 +66,7 @@ class VCDFileParser {
|
||||
nextToken(); // size
|
||||
int width = Integer.parseInt(tokenizer.sval);
|
||||
if("real".equals(type))
|
||||
width*=-1;
|
||||
width=0;
|
||||
nextToken();
|
||||
String id = tokenizer.sval;
|
||||
nextToken();
|
||||
@ -183,7 +184,7 @@ class VCDFileParser {
|
||||
}
|
||||
|
||||
int netWidth = traceBuilder.getNetWidth(net);
|
||||
if(netWidth<0) {
|
||||
if(netWidth==0) {
|
||||
if("nan".equals(value))
|
||||
traceBuilder.appendTransition(net, currentTime, Double.NaN);
|
||||
else
|
||||
@ -192,39 +193,40 @@ class VCDFileParser {
|
||||
BitVector decodedValues = new BitVector(netWidth);
|
||||
if (value.equals("z") && netWidth > 1) {
|
||||
for (int i = 0; i < netWidth; i++)
|
||||
decodedValues.setValue(i, BitVector.VALUE_Z);
|
||||
decodedValues.setValue(i, BitValue.Z);
|
||||
} else if (value.equals("x") && netWidth > 1) {
|
||||
for (int i = 0; i < netWidth; i++)
|
||||
decodedValues.setValue(i, BitVector.VALUE_X);
|
||||
decodedValues.setValue(i, BitValue.X);
|
||||
} else {
|
||||
int stringIndex = 0;
|
||||
for (int convertedIndex = netWidth - value.length(); convertedIndex < netWidth; convertedIndex++) {
|
||||
switch (value.charAt(stringIndex++)) {
|
||||
case 'z':
|
||||
decodedValues.setValue(convertedIndex, BitVector.VALUE_Z);
|
||||
break;
|
||||
|
||||
case '1':
|
||||
decodedValues.setValue(convertedIndex, BitVector.VALUE_1);
|
||||
break;
|
||||
|
||||
case '0':
|
||||
decodedValues.setValue(convertedIndex, BitVector.VALUE_0);
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
decodedValues.setValue(convertedIndex, BitVector.VALUE_X);
|
||||
break;
|
||||
|
||||
default:
|
||||
decodedValues.setValue(convertedIndex, BitVector.VALUE_X);
|
||||
for (int convertedIndex = netWidth -1; convertedIndex >=0; convertedIndex--) {
|
||||
if(convertedIndex<value.length()) {
|
||||
switch (value.charAt(stringIndex++)) {
|
||||
case 'z':
|
||||
decodedValues.setValue(convertedIndex, BitValue.Z);
|
||||
break;
|
||||
|
||||
case '1':
|
||||
decodedValues.setValue(convertedIndex, BitValue.ONE);
|
||||
break;
|
||||
|
||||
case '0':
|
||||
decodedValues.setValue(convertedIndex, BitValue.ZERO);
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
decodedValues.setValue(convertedIndex, BitValue.X);
|
||||
break;
|
||||
|
||||
default:
|
||||
decodedValues.setValue(convertedIndex, BitValue.X);
|
||||
}
|
||||
} else {
|
||||
decodedValues.setValue(convertedIndex, BitValue.ZERO);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(netWidth==1)
|
||||
traceBuilder.appendTransition(net, currentTime, decodedValues.getValue()[0]);
|
||||
else
|
||||
traceBuilder.appendTransition(net, currentTime, decodedValues);
|
||||
traceBuilder.appendTransition(net, currentTime, decodedValues);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -16,12 +16,11 @@ import java.util.TreeMap;
|
||||
|
||||
import com.minres.scviewer.database.HierNode;
|
||||
import com.minres.scviewer.database.ISignal;
|
||||
import com.minres.scviewer.database.ISignalChange;
|
||||
import com.minres.scviewer.database.IWaveform;
|
||||
import com.minres.scviewer.database.IWaveformDb;
|
||||
import com.minres.scviewer.database.IWaveformEvent;
|
||||
|
||||
public class VCDSignal<T extends ISignalChange> extends HierNode implements ISignal<T> {
|
||||
public class VCDSignal<T> extends HierNode implements ISignal<T> {
|
||||
|
||||
private long id;
|
||||
|
||||
@ -30,10 +29,12 @@ public class VCDSignal<T extends ISignalChange> extends HierNode implements ISig
|
||||
private final String kind = "signal";
|
||||
|
||||
private final int width;
|
||||
|
||||
private final T dummy = null;
|
||||
|
||||
private IWaveformDb db;
|
||||
|
||||
TreeMap<Long, T> values;
|
||||
private TreeMap<Long, T> values;
|
||||
|
||||
public VCDSignal(IWaveformDb db, String name) {
|
||||
this(db, 0, name, 1);
|
||||
@ -53,7 +54,7 @@ public class VCDSignal<T extends ISignalChange> extends HierNode implements ISig
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public VCDSignal(IWaveform<? extends ISignalChange> other, int id, String name) {
|
||||
public VCDSignal(ISignal<T> other, int id, String name) {
|
||||
super(name);
|
||||
fullName=name;
|
||||
this.id=id;
|
||||
@ -91,8 +92,8 @@ public class VCDSignal<T extends ISignalChange> extends HierNode implements ISig
|
||||
return db;
|
||||
}
|
||||
|
||||
public void addSignalChange(T change){
|
||||
values.put(change.getTime(), change);
|
||||
public void addSignalChange(Long time, T value){
|
||||
values.put(time, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -101,12 +102,12 @@ public class VCDSignal<T extends ISignalChange> extends HierNode implements ISig
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getWaveformEventsAtTime(Long time) {
|
||||
public T getWaveformValueAtTime(Long time) {
|
||||
return values.get(time);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getWaveformEventsBeforeTime(Long time) {
|
||||
public T getWaveformValueBeforeTime(Long time) {
|
||||
Entry<Long, T> e = values.floorEntry(time);
|
||||
if(e==null)
|
||||
return null;
|
||||
@ -115,10 +116,15 @@ public class VCDSignal<T extends ISignalChange> extends HierNode implements ISig
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean equals(IWaveform<? extends IWaveformEvent> other) {
|
||||
public Boolean equals(IWaveform other) {
|
||||
return(other instanceof VCDSignal<?> && this.getId()==other.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getType() {
|
||||
return dummy.getClass();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,37 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 MINRES Technologies GmbH and others.
|
||||
* 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:
|
||||
* MINRES Technologies GmbH - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package com.minres.scviewer.database.vcd;
|
||||
|
||||
import com.minres.scviewer.database.ISignalChangeBit;
|
||||
import com.minres.scviewer.database.SignalChange;
|
||||
|
||||
public class VCDSignalChangeBit extends SignalChange implements ISignalChangeBit, Cloneable {
|
||||
|
||||
private char value;
|
||||
|
||||
public VCDSignalChangeBit(Long time, char value) {
|
||||
super(time);
|
||||
this.value=value;
|
||||
}
|
||||
|
||||
public char getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(char value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value+"@"+getTime();
|
||||
}
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 MINRES Technologies GmbH and others.
|
||||
* 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:
|
||||
* MINRES Technologies GmbH - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package com.minres.scviewer.database.vcd;
|
||||
|
||||
import com.minres.scviewer.database.BitVector;
|
||||
import com.minres.scviewer.database.ISignalChangeBitVector;
|
||||
import com.minres.scviewer.database.SignalChange;
|
||||
|
||||
public class VCDSignalChangeBitVector extends SignalChange implements ISignalChangeBitVector, Cloneable {
|
||||
|
||||
private BitVector value;
|
||||
|
||||
public VCDSignalChangeBitVector(Long time) {
|
||||
super(time);
|
||||
}
|
||||
|
||||
public VCDSignalChangeBitVector(Long time, BitVector decodedValues) {
|
||||
super(time);
|
||||
this.value=decodedValues;
|
||||
}
|
||||
|
||||
public BitVector getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(BitVector value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value.toHexString()+"@"+getTime();
|
||||
}
|
||||
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 MINRES Technologies GmbH and others.
|
||||
* 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:
|
||||
* MINRES Technologies GmbH - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package com.minres.scviewer.database.vcd;
|
||||
|
||||
import com.minres.scviewer.database.ISignalChangeReal;
|
||||
import com.minres.scviewer.database.SignalChange;
|
||||
|
||||
public class VCDSignalChangeReal extends SignalChange implements ISignalChangeReal, Cloneable {
|
||||
|
||||
private double value;
|
||||
|
||||
public VCDSignalChangeReal(Long time, double value) {
|
||||
super(time);
|
||||
this.value=value;
|
||||
}
|
||||
|
||||
public double getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(double value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value+"@"+getTime();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user