Refactored database data model to improve speed and reduce memory

consumption
This commit is contained in:
2018-11-05 18:21:54 +01:00
parent e687eef42c
commit 93fd192782
29 changed files with 360 additions and 471 deletions

View File

@ -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.
*

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}