Refactored database data model to improve speed and reduce memory

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

View File

@ -24,7 +24,7 @@ public class LevelDBLoader implements IWaveformDbLoader {
return value.getBytes(UTF_8); return value.getBytes(UTF_8);
} }
private StringDBWrapper levelDb; private TxDBWrapper levelDb;
private IWaveformDb db; private IWaveformDb db;
private Long maxTime=null; private Long maxTime=null;
private List<RelationType> usedRelationsList = new ArrayList<>(); private List<RelationType> usedRelationsList = new ArrayList<>();
@ -33,7 +33,10 @@ public class LevelDBLoader implements IWaveformDbLoader {
public boolean load(IWaveformDb db, File inp) throws Exception { public boolean load(IWaveformDb db, File inp) throws Exception {
try { try {
this.db=db; this.db=db;
levelDb = new StringDBWrapper(new Options(), inp); levelDb = new TxDBWrapper(new Options(), inp);
JSONObject configVal = new JSONObject(levelDb.get("__config"));
if(!configVal.isEmpty())
levelDb.setTimeResolution(configVal.getLong("resolution"));
} catch(Exception e) { } catch(Exception e) {
return false; return false;
} }
@ -55,15 +58,15 @@ public class LevelDBLoader implements IWaveformDbLoader {
maxTime = 0L; maxTime = 0L;
else { else {
String[] token = val.getKey().split("~"); String[] token = val.getKey().split("~");
maxTime = Long.parseLong(token[2], 16); maxTime = Long.parseLong(token[2], 16)*levelDb.getTimeResolution();
} }
} }
return maxTime; return maxTime;
} }
@Override @Override
public List<IWaveform<? extends IWaveformEvent>> getAllWaves() { public List<IWaveform> getAllWaves() {
List<IWaveform<? extends IWaveformEvent>> streams=new ArrayList<IWaveform<? extends IWaveformEvent>>(); List<IWaveform> streams=new ArrayList<IWaveform>();
SeekingIterator<String, String> it = levelDb.iterator(); SeekingIterator<String, String> it = levelDb.iterator();
it.seek("s~"); it.seek("s~");
while(it.hasNext()) { while(it.hasNext()) {

View File

@ -11,17 +11,19 @@ import org.iq80.leveldb.ReadOptions;
import org.iq80.leveldb.Snapshot; import org.iq80.leveldb.Snapshot;
import org.iq80.leveldb.impl.DbImpl; import org.iq80.leveldb.impl.DbImpl;
import org.iq80.leveldb.impl.SeekingIterator; import org.iq80.leveldb.impl.SeekingIterator;
import org.json.*;
class StringDBWrapper { class TxDBWrapper {
private final Options options; private final Options options;
private final ReadOptions ro = new ReadOptions();
private final File databaseDir; private final File databaseDir;
private DbImpl db; private DbImpl db;
private long timeResolution=1L;;
StringDBWrapper(Options options, File databaseDir) throws IOException { TxDBWrapper(Options options, File databaseDir) throws IOException {
this.options = options.verifyChecksums(true).createIfMissing(false).errorIfExists(false); this.options = options.verifyChecksums(true).createIfMissing(false).errorIfExists(false).cacheSize(64*1024*1024);
this.databaseDir = databaseDir; this.databaseDir = databaseDir;
this.db = new DbImpl(options, databaseDir); this.db = new DbImpl(options, databaseDir);
ro.snapshot(db.getSnapshot());
} }
public String get(String key) { public String get(String key) {
@ -33,11 +35,8 @@ class StringDBWrapper {
} }
public String get(String key, Snapshot snapshot) { public String get(String key, Snapshot snapshot) {
byte[] slice = db.get(LevelDBLoader.toByteArray(key), new ReadOptions().snapshot(snapshot)); byte[] slice = db.get(LevelDBLoader.toByteArray(key), ro);
if (slice == null) { return slice == null? null : new String(slice, UTF_8);
return null;
}
return new String(slice, UTF_8);
} }
public void put(String key, String value) { public void put(String key, String value) {
@ -57,7 +56,10 @@ class StringDBWrapper {
} }
public void close() { public void close() {
try {
ro.snapshot().close();
db.close(); db.close();
} catch (IOException e) {} // ignore any error
} }
public long size(String start, String limit) { public long size(String start, String limit) {
@ -73,7 +75,16 @@ class StringDBWrapper {
} }
public void reopen(Options options) throws IOException { public void reopen(Options options) throws IOException {
db.close(); this.close();
db = new DbImpl(options.verifyChecksums(true).createIfMissing(false).errorIfExists(false), databaseDir); db = new DbImpl(options.verifyChecksums(true).createIfMissing(false).errorIfExists(false), databaseDir);
ro.snapshot(db.getSnapshot());
}
public long getTimeResolution() {
return timeResolution;
}
public void setTimeResolution(long resolution) {
this.timeResolution = resolution;
} }
} }

View File

@ -10,9 +10,6 @@
*******************************************************************************/ *******************************************************************************/
package com.minres.scviewer.database.leveldb; package com.minres.scviewer.database.leveldb;
import java.beans.IntrospectionException;
import java.lang.reflect.InvocationTargetException;
import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
@ -23,7 +20,6 @@ import org.iq80.leveldb.impl.SeekingIterator;
import org.json.JSONObject; import org.json.JSONObject;
import java.util.NavigableMap; import java.util.NavigableMap;
import java.util.StringTokenizer;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.Vector; import java.util.Vector;
@ -34,12 +30,11 @@ import com.minres.scviewer.database.ITxGenerator;
import com.minres.scviewer.database.ITxStream; import com.minres.scviewer.database.ITxStream;
import com.minres.scviewer.database.IWaveform; import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.IWaveformDb; import com.minres.scviewer.database.IWaveformDb;
import com.minres.scviewer.database.IWaveformEvent;
import com.minres.scviewer.database.RelationType; import com.minres.scviewer.database.RelationType;
public class TxStream extends HierNode implements ITxStream<ITxEvent> { public class TxStream extends HierNode implements ITxStream<ITxEvent> {
private StringDBWrapper levelDb; private TxDBWrapper levelDb;
private String fullName; private String fullName;
@ -59,7 +54,7 @@ public class TxStream extends HierNode implements ITxStream<ITxEvent> {
private List<RelationType> usedRelationsList; private List<RelationType> usedRelationsList;
public TxStream(StringDBWrapper database, IWaveformDb waveformDb, JSONObject object) { public TxStream(TxDBWrapper database, IWaveformDb waveformDb, JSONObject object) {
super(object.get("name").toString()); super(object.get("name").toString());
this.levelDb=database; this.levelDb=database;
this.db=waveformDb; this.db=waveformDb;
@ -93,10 +88,11 @@ public class TxStream extends HierNode implements ITxStream<ITxEvent> {
if(generators==null){ if(generators==null){
generators=new TreeMap<Long, TxGenerator>(); generators=new TreeMap<Long, TxGenerator>();
SeekingIterator<String, String> it = levelDb.iterator(); SeekingIterator<String, String> it = levelDb.iterator();
it.seek("sg~"+String.format("%016x", id)); String key="sg~"+String.format("%016x", id);
it.seek(key);
while(it.hasNext()) { while(it.hasNext()) {
Entry<String, String> val = it.next(); Entry<String, String> val = it.next();
if(!val.getKey().startsWith("sg~")) break; if(!val.getKey().startsWith(key)) break;
JSONObject jVal = new JSONObject(val.getValue()); JSONObject jVal = new JSONObject(val.getValue());
generators.put(jVal.getLong("id"), new TxGenerator(this, jVal)); generators.put(jVal.getLong("id"), new TxGenerator(this, jVal));
} }
@ -107,7 +103,7 @@ public class TxStream extends HierNode implements ITxStream<ITxEvent> {
@Override @Override
public int getMaxConcurrency() { public int getMaxConcurrency() {
if(maxConcurrency==null){ if(maxConcurrency==null){
maxConcurrency=1; getTransactions();
} }
return maxConcurrency; return maxConcurrency;
} }
@ -117,8 +113,9 @@ public class TxStream extends HierNode implements ITxStream<ITxEvent> {
if(events==null){ if(events==null){
events=new TreeMap<Long, List<ITxEvent>>(); events=new TreeMap<Long, List<ITxEvent>>();
for(Entry<Long, ITx> entry:getTransactions().entrySet()){ for(Entry<Long, ITx> entry:getTransactions().entrySet()){
putEvent(new TxEvent(TxEvent.Type.BEGIN, entry.getValue())); ITx tx = entry.getValue();
putEvent(new TxEvent(TxEvent.Type.END, entry.getValue())); putEvent(new TxEvent(TxEvent.Type.BEGIN, tx));
putEvent(new TxEvent(TxEvent.Type.END, tx));
} }
} }
return events; return events;
@ -139,16 +136,21 @@ public class TxStream extends HierNode implements ITxStream<ITxEvent> {
if(transactions==null){ if(transactions==null){
if(generators==null) getGenerators(); if(generators==null) getGenerators();
transactions = new TreeMap<Long, ITx>(); transactions = new TreeMap<Long, ITx>();
maxConcurrency=0;
SeekingIterator<String, String> it = levelDb.iterator(); SeekingIterator<String, String> it = levelDb.iterator();
it.seek("sgx~"+String.format("%016x", id)); String key = "sgx~"+String.format("%016x", id);
it.seek(key);
while(it.hasNext()) { while(it.hasNext()) {
Entry<String, String> val = it.next(); Entry<String, String> val = it.next();
if(!val.getKey().startsWith("sgx~")) break; if(!val.getKey().startsWith(key)) break;
String[] token = val.getKey().split("~"); String[] token = val.getKey().split("~");
long gid = Long.parseLong(token[2], 16); // gen id long gid = Long.parseLong(token[2], 16); // gen id
long id = Long.parseLong(token[3], 16); // tx id long id = Long.parseLong(token[3], 16); // tx id
transactions.put(id, new Tx(levelDb, this, generators.get(gid), id)); ITx tx = new Tx(levelDb, this, generators.get(gid), id);
transactions.put(id, tx);
maxConcurrency= Math.max(maxConcurrency, tx.getConcurrencyIndex());
} }
maxConcurrency++;
} }
return transactions; return transactions;
} }
@ -169,7 +171,7 @@ public class TxStream extends HierNode implements ITxStream<ITxEvent> {
} }
@Override @Override
public Boolean equals(IWaveform<? extends IWaveformEvent> other) { public Boolean equals(IWaveform other) {
return(other instanceof TxStream && this.getId()==other.getId()); return(other instanceof TxStream && this.getId()==other.getId());
} }

View File

@ -13,6 +13,7 @@ package com.minres.scviewer.database.sqlite;
import java.beans.IntrospectionException; import java.beans.IntrospectionException;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
@ -60,9 +61,9 @@ public class SQLiteDbLoader implements IWaveformDbLoader {
} }
@Override @Override
public List<IWaveform<? extends IWaveformEvent>> getAllWaves() { public List<IWaveform> getAllWaves() {
SQLiteDatabaseSelectHandler<ScvStream> handler = new SQLiteDatabaseSelectHandler<ScvStream>(ScvStream.class, database); SQLiteDatabaseSelectHandler<ScvStream> handler = new SQLiteDatabaseSelectHandler<ScvStream>(ScvStream.class, database);
List<IWaveform<? extends IWaveformEvent>> streams=new ArrayList<IWaveform<? extends IWaveformEvent>>(); List<IWaveform> streams=new ArrayList<IWaveform>();
try { try {
for(ScvStream scvStream:handler.selectObjects()){ for(ScvStream scvStream:handler.selectObjects()){
TxStream stream = new TxStream(database, db, scvStream); TxStream stream = new TxStream(database, db, scvStream);
@ -81,6 +82,7 @@ public class SQLiteDbLoader implements IWaveformDbLoader {
@Override @Override
public boolean load(IWaveformDb db, File file) throws Exception { public boolean load(IWaveformDb db, File file) throws Exception {
this.db=db; this.db=db;
try {
FileInputStream fis = new FileInputStream(file); FileInputStream fis = new FileInputStream(file);
byte[] buffer = new byte[x.length]; byte[] buffer = new byte[x.length];
int read = fis.read(buffer, 0, x.length); int read = fis.read(buffer, 0, x.length);
@ -88,7 +90,9 @@ public class SQLiteDbLoader implements IWaveformDbLoader {
if (read == x.length) if (read == x.length)
for (int i = 0; i < x.length; i++) for (int i = 0; i < x.length; i++)
if (buffer[i] != x[i]) return false; if (buffer[i] != x[i]) return false;
} catch(FileNotFoundException e) {
return false;
}
database=new SQLiteDatabase(file.getAbsolutePath()); database=new SQLiteDatabase(file.getAbsolutePath());
database.setData("TIMERESOLUTION", 1L); database.setData("TIMERESOLUTION", 1L);
SQLiteDatabaseSelectHandler<ScvSimProps> handler = new SQLiteDatabaseSelectHandler<ScvSimProps>(ScvSimProps.class, database); SQLiteDatabaseSelectHandler<ScvSimProps> handler = new SQLiteDatabaseSelectHandler<ScvSimProps>(ScvSimProps.class, database);

View File

@ -29,7 +29,6 @@ import com.minres.scviewer.database.ITxGenerator;
import com.minres.scviewer.database.ITxStream; import com.minres.scviewer.database.ITxStream;
import com.minres.scviewer.database.IWaveform; import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.IWaveformDb; import com.minres.scviewer.database.IWaveformDb;
import com.minres.scviewer.database.IWaveformEvent;
import com.minres.scviewer.database.RelationType; import com.minres.scviewer.database.RelationType;
import com.minres.scviewer.database.sqlite.db.IDatabase; import com.minres.scviewer.database.sqlite.db.IDatabase;
import com.minres.scviewer.database.sqlite.db.SQLiteDatabaseSelectHandler; import com.minres.scviewer.database.sqlite.db.SQLiteDatabaseSelectHandler;
@ -193,7 +192,7 @@ public class TxStream extends HierNode implements ITxStream<ITxEvent> {
} }
@Override @Override
public Boolean equals(IWaveform<? extends IWaveformEvent> other) { public Boolean equals(IWaveform other) {
return(other instanceof TxStream && this.getId()==other.getId()); return(other instanceof TxStream && this.getId()==other.getId());
} }

View File

@ -16,6 +16,7 @@ import static org.junit.Assert.assertTrue;
import java.io.File; import java.io.File;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.NavigableMap; import java.util.NavigableMap;
@ -33,6 +34,7 @@ import com.minres.scviewer.database.ITxStream;
import com.minres.scviewer.database.IWaveform; import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.IWaveformDb; import com.minres.scviewer.database.IWaveformDb;
import com.minres.scviewer.database.IWaveformDbFactory; import com.minres.scviewer.database.IWaveformDbFactory;
import com.minres.scviewer.database.vcd.VCDSignal;
public class DatabaseServicesTest { public class DatabaseServicesTest {
@ -54,13 +56,6 @@ public class DatabaseServicesTest {
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
waveformDb=waveformDbFactory.getDatabase(); waveformDb=waveformDbFactory.getDatabase();
// Wait for OSGi dependencies
// for (int i = 0; i < 10; i++) {
// if (waveformDb.size() == 3) // Dependencies fulfilled
// return;
// Thread.sleep(1000);
// }
// assertEquals("OSGi dependencies unfulfilled", 3, WaveformDb.getLoaders().size());
} }
@After @After
@ -73,8 +68,17 @@ public class DatabaseServicesTest {
assertTrue(f.exists()); assertTrue(f.exists());
waveformDb.load(f); waveformDb.load(f);
assertNotNull(waveformDb); assertNotNull(waveformDb);
assertEquals(14, waveformDb.getAllWaves().size()); List<IWaveform> waves= waveformDb.getAllWaves();
assertEquals(14, waves.size());
assertEquals(2, waveformDb.getChildNodes().size()); assertEquals(2, waveformDb.getChildNodes().size());
IWaveform bus_data_wave = waves.get(0);
VCDSignal<?> bus_data_sig = (VCDSignal<?>) bus_data_wave;
Entry<Long, ?> bus_data_entry = bus_data_sig.getEvents().floorEntry(1400000000L);
assertTrue("01111000".equals(bus_data_entry.getValue().toString()));
IWaveform rw_wave = waves.get(2);
VCDSignal<?> rw_sig = (VCDSignal<?>) rw_wave;
Entry<Long, ?> rw_entry = rw_sig.getEvents().floorEntry(2360000000L);
assertTrue("1".equals(rw_entry.getValue().toString()));
} }
@Test @Test
@ -104,18 +108,18 @@ public class DatabaseServicesTest {
waveformDb.load(f); waveformDb.load(f);
assertNotNull(waveformDb); assertNotNull(waveformDb);
assertEquals(1, waveformDb.getChildNodes().size()); assertEquals(1, waveformDb.getChildNodes().size());
List<IWaveform<?>> waves = waveformDb.getAllWaves(); List<IWaveform> waves = waveformDb.getAllWaves();
assertEquals(3, waves.size()); assertEquals(3, waves.size());
IWaveform<?> wave = waves.get(0); IWaveform wave = waves.get(0);
assertTrue(wave instanceof ITxStream<?>); assertTrue(wave instanceof ITxStream<?>);
ITxStream<?> stream = (ITxStream<?>) wave; ITxStream<?> stream = (ITxStream<?>) wave;
assertEquals(2, stream.getGenerators().size()); assertEquals(2, stream.getGenerators().size());
NavigableMap<Long, List<ITxEvent>> eventsList = stream.getEvents(); NavigableMap<Long, List<ITxEvent>> eventsList = stream.getEvents();
assertEquals(18, eventsList.size()); assertEquals(27, eventsList.size());
Entry<Long, List<ITxEvent>> eventEntry = eventsList.firstEntry(); Entry<Long, List<ITxEvent>> eventEntry = eventsList.firstEntry();
assertEquals(100000L, (long) eventEntry.getKey()); assertEquals(100000000L, (long) eventEntry.getKey());
List<ITxEvent> events = eventEntry.getValue(); List<ITxEvent> events = eventEntry.getValue();
assertEquals(2, events.size()); assertEquals(1, events.size());
ITxEvent event = events.get(0); ITxEvent event = events.get(0);
assertEquals(Type.BEGIN, event.getType()); assertEquals(Type.BEGIN, event.getType());
ITx tx = event.getTransaction(); ITx tx = event.getTransaction();

View File

@ -5,8 +5,7 @@ Bundle-SymbolicName: com.minres.scviewer.database.text
Bundle-Version: 1.0.1.qualifier Bundle-Version: 1.0.1.qualifier
Bundle-Vendor: MINRES Technologies GmbH Bundle-Vendor: MINRES Technologies GmbH
Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Import-Package: com.minres.scviewer.database, Import-Package: org.osgi.framework;version="1.3.0"
org.osgi.framework;version="1.3.0"
Require-Bundle: com.minres.scviewer.database;bundle-version="1.0.0", Require-Bundle: com.minres.scviewer.database;bundle-version="1.0.0",
org.codehaus.groovy;bundle-version="1.8.6", org.codehaus.groovy;bundle-version="1.8.6",
org.eclipse.equinox.util;bundle-version="1.0.500", org.eclipse.equinox.util;bundle-version="1.0.500",

View File

@ -59,12 +59,14 @@ public class TextDbLoader implements IWaveformDbLoader{
boolean load(IWaveformDb db, File file) throws Exception { boolean load(IWaveformDb db, File file) throws Exception {
this.db=db this.db=db
this.streams=[] this.streams=[]
try {
def gzipped = isGzipped(file) def gzipped = isGzipped(file)
if(isTxfile(gzipped?new GZIPInputStream(new FileInputStream(file)):new FileInputStream(file))){ if(isTxfile(gzipped?new GZIPInputStream(new FileInputStream(file)):new FileInputStream(file))){
parseInput(gzipped?new GZIPInputStream(new FileInputStream(file)):new FileInputStream(file)) parseInput(gzipped?new GZIPInputStream(new FileInputStream(file)):new FileInputStream(file))
calculateConcurrencyIndicees() calculateConcurrencyIndicees()
return true return true
} }
} catch(Exception e) { }
return false; return false;
} }

View File

@ -109,7 +109,7 @@ class TxStream extends HierNode implements ITxStream {
} }
@Override @Override
public Boolean equals(IWaveform<? extends IWaveformEvent> other) { public Boolean equals(IWaveform other) {
return(other instanceof TxStream && this.getId()==other.getId()); return(other instanceof TxStream && this.getId()==other.getId());
} }

View File

@ -47,15 +47,6 @@ public interface IVCDDatabaseBuilder {
*/ */
public int getNetWidth(int netId); 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. * Append transition.
* *

View File

@ -12,6 +12,7 @@ package com.minres.scviewer.database.vcd;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -22,10 +23,6 @@ import java.util.Vector;
import com.minres.scviewer.database.BitVector; import com.minres.scviewer.database.BitVector;
import com.minres.scviewer.database.ISignal; 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.IWaveform;
import com.minres.scviewer.database.IWaveformDb; import com.minres.scviewer.database.IWaveformDb;
import com.minres.scviewer.database.IWaveformDbLoader; import com.minres.scviewer.database.IWaveformDbLoader;
@ -49,7 +46,7 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
private Stack<String> moduleStack; private Stack<String> moduleStack;
/** The signals. */ /** The signals. */
private List<IWaveform<? extends IWaveformEvent>> signals; private List<IWaveform> signals;
/** The max time. */ /** The max time. */
private long maxTime; private long maxTime;
@ -71,6 +68,7 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
public boolean load(IWaveformDb db, File file) throws Exception { public boolean load(IWaveformDb db, File file) throws Exception {
this.db=db; this.db=db;
this.maxTime=0; this.maxTime=0;
try {
FileInputStream fis = new FileInputStream(file); FileInputStream fis = new FileInputStream(file);
byte[] buffer = new byte[dateBytes.length]; byte[] buffer = new byte[dateBytes.length];
int read = fis.read(buffer, 0, dateBytes.length); int read = fis.read(buffer, 0, dateBytes.length);
@ -79,32 +77,32 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
for (int i = 0; i < dateBytes.length; i++) for (int i = 0; i < dateBytes.length; i++)
if (buffer[i] != dateBytes[i]) if (buffer[i] != dateBytes[i])
return false; return false;
} catch(FileNotFoundException e) {
return false;
}
signals = new Vector<IWaveform<? extends IWaveformEvent>>(); signals = new Vector<IWaveform>();
moduleStack= new Stack<String>(); moduleStack= new Stack<String>();
boolean res = new VCDFileParser(false).load(new FileInputStream(file), this); boolean res = new VCDFileParser(false).load(new FileInputStream(file), this);
moduleStack=null; moduleStack=null;
if(!res) throw new InputFormatException(); if(!res) throw new InputFormatException();
// calculate max time of database // calculate max time of database
for(IWaveform<? extends IWaveformEvent> waveform:signals) { for(IWaveform waveform:signals) {
NavigableMap<Long, ? extends ISignalChange> events =((ISignal<? extends ISignalChange>)waveform).getEvents(); NavigableMap<Long, ?> events =((ISignal<?>)waveform).getEvents();
if(events.size()>0) if(events.size()>0)
maxTime= Math.max(maxTime, events.lastKey()); maxTime= Math.max(maxTime, events.lastKey());
} }
// extend signals to hav a last value set at max time // extend signals to hav a last value set at max time
for(IWaveform<? extends IWaveformEvent> waveform:signals){ for(IWaveform s:signals){
TreeMap<Long,? extends ISignalChange> events = ((VCDSignal<? extends ISignalChange>)waveform).values; if(s instanceof VCDSignal<?>) {
TreeMap<Long,?> events = (TreeMap<Long, ?>) ((VCDSignal<?>)s).getEvents();
if(events.size()>0 && events.lastKey()<maxTime){ if(events.size()>0 && events.lastKey()<maxTime){
ISignalChange x = events.lastEntry().getValue(); Object val = events.lastEntry().getValue();
if(x instanceof ISignalChangeBit) if(val instanceof BitVector) {
((VCDSignal<ISignalChangeBit>)waveform).values.put(maxTime, ((VCDSignal<BitVector>)s).addSignalChange(maxTime, (BitVector) val);
new VCDSignalChangeBit(maxTime, ((ISignalChangeBit)x).getValue())); } else if(val instanceof Double)
else if(x instanceof ISignalChangeBitVector) ((VCDSignal<Double>)s).addSignalChange(maxTime, (Double) val);
((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()));
} }
} }
return true; return true;
@ -122,7 +120,7 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
* @see com.minres.scviewer.database.ITrDb#getAllWaves() * @see com.minres.scviewer.database.ITrDb#getAllWaves()
*/ */
@Override @Override
public List<IWaveform<? extends IWaveformEvent>> getAllWaves() { public List<IWaveform> getAllWaves() {
return signals; return signals;
} }
@ -154,18 +152,14 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
public Integer newNet(String name, int i, int width) { public Integer newNet(String name, int i, int width) {
String netName = moduleStack.empty()? name: moduleStack.lastElement()+"."+name; String netName = moduleStack.empty()? name: moduleStack.lastElement()+"."+name;
int id = signals.size(); int id = signals.size();
VCDSignal<? extends IWaveformEvent> signal; assert(width>0);
if(width<0) { if(width==0) {
signal = i<0 ? new VCDSignal<ISignalChangeReal>(db, id, netName, width) : signals.add( i<0 ? new VCDSignal<Double>(db, id, netName) :
new VCDSignal<ISignalChangeReal>((VCDSignal<ISignalChangeReal>)signals.get(i), id, netName); new VCDSignal<Double>((VCDSignal<Double>)signals.get(i), id, netName));
} else if(width==1){ } else if(width>0){
signal = i<0 ? new VCDSignal<ISignalChangeBit>(db, id, netName) : signals.add( i<0 ? new VCDSignal<BitVector>(db, id, netName, width) :
new VCDSignal<ISignalChangeBit>((VCDSignal<ISignalChangeBit>)signals.get(i), id, netName); new VCDSignal<BitVector>((VCDSignal<BitVector>)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);
return id; return id;
} }
@ -174,7 +168,7 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
*/ */
@Override @Override
public int getNetWidth(int intValue) { public int getNetWidth(int intValue) {
VCDSignal<? extends IWaveformEvent> signal = (VCDSignal<? extends IWaveformEvent>) signals.get(intValue); VCDSignal<?> signal = (VCDSignal<?>) signals.get(intValue);
return signal.getWidth(); return signal.getWidth();
} }
@ -183,12 +177,10 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public void appendTransition(int signalId, long currentTime, char decodedValues) { public void appendTransition(int signalId, long currentTime, BitVector value) {
VCDSignal<? extends IWaveformEvent> signal = (VCDSignal<? extends IWaveformEvent>) signals.get(signalId); VCDSignal<BitVector> signal = (VCDSignal<BitVector>) signals.get(signalId);
Long time = currentTime*TIME_RES; Long time = currentTime* TIME_RES;
if(signal.getWidth()==1){ signal.getEvents().put(time, value);
((VCDSignal<ISignalChangeBit>)signal).values.put(time, new VCDSignalChangeBit(time, decodedValues));
}
} }
/* (non-Javadoc) /* (non-Javadoc)
@ -196,24 +188,11 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public void appendTransition(int signalId, long currentTime, BitVector decodedValues) { public void appendTransition(int signalId, long currentTime, double value) {
VCDSignal<? extends IWaveformEvent> signal = (VCDSignal<? extends IWaveformEvent>) signals.get(signalId); VCDSignal<?> signal = (VCDSignal<?>) signals.get(signalId);
Long time = currentTime* TIME_RES; Long time = currentTime* TIME_RES;
if(signal.getWidth()>1){ if(signal.getWidth()==0){
((VCDSignal<VCDSignalChangeBitVector>)signal).values.put(time, new VCDSignalChangeBitVector(time, decodedValues)); ((VCDSignal<Double>)signal).getEvents().put(time, value);
}
}
/* (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));
} }
} }

View File

@ -13,6 +13,7 @@ package com.minres.scviewer.database.vcd;
import java.io.*; import java.io.*;
import java.util.*; import java.util.*;
import com.minres.scviewer.database.BitValue;
import com.minres.scviewer.database.BitVector; import com.minres.scviewer.database.BitVector;
class VCDFileParser { class VCDFileParser {
@ -65,7 +66,7 @@ class VCDFileParser {
nextToken(); // size nextToken(); // size
int width = Integer.parseInt(tokenizer.sval); int width = Integer.parseInt(tokenizer.sval);
if("real".equals(type)) if("real".equals(type))
width*=-1; width=0;
nextToken(); nextToken();
String id = tokenizer.sval; String id = tokenizer.sval;
nextToken(); nextToken();
@ -183,7 +184,7 @@ class VCDFileParser {
} }
int netWidth = traceBuilder.getNetWidth(net); int netWidth = traceBuilder.getNetWidth(net);
if(netWidth<0) { if(netWidth==0) {
if("nan".equals(value)) if("nan".equals(value))
traceBuilder.appendTransition(net, currentTime, Double.NaN); traceBuilder.appendTransition(net, currentTime, Double.NaN);
else else
@ -192,38 +193,39 @@ class VCDFileParser {
BitVector decodedValues = new BitVector(netWidth); BitVector decodedValues = new BitVector(netWidth);
if (value.equals("z") && netWidth > 1) { if (value.equals("z") && netWidth > 1) {
for (int i = 0; i < netWidth; i++) 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) { } else if (value.equals("x") && netWidth > 1) {
for (int i = 0; i < netWidth; i++) for (int i = 0; i < netWidth; i++)
decodedValues.setValue(i, BitVector.VALUE_X); decodedValues.setValue(i, BitValue.X);
} else { } else {
int stringIndex = 0; int stringIndex = 0;
for (int convertedIndex = netWidth - value.length(); convertedIndex < netWidth; convertedIndex++) { for (int convertedIndex = netWidth -1; convertedIndex >=0; convertedIndex--) {
if(convertedIndex<value.length()) {
switch (value.charAt(stringIndex++)) { switch (value.charAt(stringIndex++)) {
case 'z': case 'z':
decodedValues.setValue(convertedIndex, BitVector.VALUE_Z); decodedValues.setValue(convertedIndex, BitValue.Z);
break; break;
case '1': case '1':
decodedValues.setValue(convertedIndex, BitVector.VALUE_1); decodedValues.setValue(convertedIndex, BitValue.ONE);
break; break;
case '0': case '0':
decodedValues.setValue(convertedIndex, BitVector.VALUE_0); decodedValues.setValue(convertedIndex, BitValue.ZERO);
break; break;
case 'x': case 'x':
decodedValues.setValue(convertedIndex, BitVector.VALUE_X); decodedValues.setValue(convertedIndex, BitValue.X);
break; break;
default: default:
decodedValues.setValue(convertedIndex, BitVector.VALUE_X); 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);
} }
} }

View File

@ -16,12 +16,11 @@ import java.util.TreeMap;
import com.minres.scviewer.database.HierNode; import com.minres.scviewer.database.HierNode;
import com.minres.scviewer.database.ISignal; import com.minres.scviewer.database.ISignal;
import com.minres.scviewer.database.ISignalChange;
import com.minres.scviewer.database.IWaveform; import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.IWaveformDb; import com.minres.scviewer.database.IWaveformDb;
import com.minres.scviewer.database.IWaveformEvent; 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; private long id;
@ -31,9 +30,11 @@ public class VCDSignal<T extends ISignalChange> extends HierNode implements ISig
private final int width; private final int width;
private final T dummy = null;
private IWaveformDb db; private IWaveformDb db;
TreeMap<Long, T> values; private TreeMap<Long, T> values;
public VCDSignal(IWaveformDb db, String name) { public VCDSignal(IWaveformDb db, String name) {
this(db, 0, name, 1); this(db, 0, name, 1);
@ -53,7 +54,7 @@ public class VCDSignal<T extends ISignalChange> extends HierNode implements ISig
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public VCDSignal(IWaveform<? extends ISignalChange> other, int id, String name) { public VCDSignal(ISignal<T> other, int id, String name) {
super(name); super(name);
fullName=name; fullName=name;
this.id=id; this.id=id;
@ -91,8 +92,8 @@ public class VCDSignal<T extends ISignalChange> extends HierNode implements ISig
return db; return db;
} }
public void addSignalChange(T change){ public void addSignalChange(Long time, T value){
values.put(change.getTime(), change); values.put(time, value);
} }
@Override @Override
@ -101,12 +102,12 @@ public class VCDSignal<T extends ISignalChange> extends HierNode implements ISig
} }
@Override @Override
public T getWaveformEventsAtTime(Long time) { public T getWaveformValueAtTime(Long time) {
return values.get(time); return values.get(time);
} }
@Override @Override
public T getWaveformEventsBeforeTime(Long time) { public T getWaveformValueBeforeTime(Long time) {
Entry<Long, T> e = values.floorEntry(time); Entry<Long, T> e = values.floorEntry(time);
if(e==null) if(e==null)
return null; return null;
@ -115,10 +116,15 @@ public class VCDSignal<T extends ISignalChange> extends HierNode implements ISig
} }
@Override @Override
public Boolean equals(IWaveform<? extends IWaveformEvent> other) { public Boolean equals(IWaveform other) {
return(other instanceof VCDSignal<?> && this.getId()==other.getId()); 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();
}
}

View File

@ -0,0 +1,68 @@
package com.minres.scviewer.database;
public enum BitValue {
ZERO,
ONE,
X,
Z;
private static final BitValue[] ORDINAL_TABLE = BitValue.values();
public static BitValue fromChar(char c) {
switch (c) {
case '0':
return ZERO;
case '1':
return ONE;
case 'x':
case 'X':
return X;
case 'z':
case 'Z':
return Z;
default:
throw new NumberFormatException("unknown digit " + c);
}
}
public char toChar() {
switch (this) {
case ZERO:
return '0';
case ONE:
return '1';
case X:
return 'x';
case Z:
return 'z';
}
return ' '; // Unreachable?
}
public static BitValue fromInt(int i) {
if (i == 0) {
return ZERO;
} else {
return ONE;
}
}
public int toInt() {
return (this == ONE) ? 1 : 0;
}
public static BitValue fromOrdinal(int ord) {
return ORDINAL_TABLE[ord];
}
public int compare(BitValue other) {
if (this == ONE && other == ZERO) {
return 1;
} else if (this == ZERO && other == ONE) {
return -1;
} else {
// Either these are equal, or there is an X and Z, which match everything.
return 0;
}
}
}

View File

@ -12,31 +12,53 @@ package com.minres.scviewer.database;
public class BitVector { public class BitVector {
public static final char VALUE_X = 'X';
public static final char VALUE_Z = 'Z';
public static final char VALUE_1 = '1';
public static final char VALUE_0 = '0';
private final int width; private final int width;
private char[] value; private int[] packedValues;
public BitVector(int netWidth) { public BitVector(int netWidth) {
this.width=netWidth; this.width=netWidth;
value = new char[netWidth]; packedValues = new int[(netWidth+15)/16];
for(int i=0; i<netWidth; i++) value[i]='0'; for(int i=0; i<packedValues.length; i++) packedValues[i]=0;
} }
public void setValue(int i, char value) { public void setValue(int i, BitValue value) {
this.value[i]=value; int bitIndex = i*2;
int wordOffset = bitIndex >> 5;
int bitOffset = bitIndex & 31;
packedValues[wordOffset] &= ~(3 << bitOffset);
packedValues[wordOffset] |= value.ordinal() << bitOffset;
} }
public char[] getValue() { public char[] getValue() {
return value; int bitOffset = 0;
int wordOffset = 0;
char[] res = new char[width];
// Copy values out of packed array
for (int i = 0; i < width; i++) {
int currentWord = (packedValues[wordOffset] >> bitOffset)&3;
res[width-i-1]=BitValue.fromInt(currentWord).toChar();
bitOffset += 2;
if (bitOffset == 32) {
wordOffset++;
bitOffset = 0;
}
}
return res;
} }
public void setValue(char[] value) { public void setValue(char[] value) {
this.value = value; int bitIndex = width;
int wordOffset = bitIndex >> 4;
int bitOffset = (bitIndex * 2) % 32;
for (int i = Math.min(value.length, width) - 1; i >= 0; i--) {
packedValues[wordOffset] |= BitValue.fromChar(value[i]).ordinal() << bitOffset;
bitOffset += 2;
if (bitOffset == 32) {
wordOffset++;
bitOffset = 0;
}
}
} }
public int getWidth() { public int getWidth() {
@ -44,40 +66,61 @@ public class BitVector {
} }
public String toString(){ public String toString(){
return new String(value); return new String(getValue());
} }
public String toHexString(){ public String toHexString(){
int resWidth=(width-1)/4+1; int resWidth=(width-1)/4+1;
char[] value=getValue();
char[] res = new char[resWidth]; char[] res = new char[resWidth];
for(int i=resWidth-1; i>=0; i--){ for(int i=resWidth-1; i>=0; i--){
int digit=0; int digit=0;
for(int j=3; j>=0; j--){ for(int j=3; j>=0; j--){
if(value[4*i+j]==VALUE_X ||value[4*i+j]==VALUE_Z ){ BitValue val = BitValue.fromChar(value[4*i+j]);
res[i]=VALUE_X; switch(val) {
} case X:
if(value[4*i+j]==VALUE_1) case Z:
res[i]=val.toChar();
continue;
case ONE:
digit+=1<<(3-j); digit+=1<<(3-j);
res[i]=Character.forDigit(digit, 16); //((digit < 10) ? '0' + digit : 'a' + digit -10) break;
default:
break;
} }
} }
res[i]=Character.forDigit(digit, 16); //((digit < 10) ? '0' + digit : 'a' + digit -10)
}
return new String(res); return new String(res);
} }
public long toUnsignedValue() { public long toUnsignedValue() {
long res = 0; long res = 0;
for(char c:value) { int bitOffset = width * 2;
int wordOffset = bitOffset >> 5;
bitOffset &= 31;
int currentWord = packedValues[wordOffset] >> bitOffset;
// Copy values out of packed array
for (int i = 0; i < width; i++) {
res<<=1; res<<=1;
switch (c) { switch (currentWord & 3) {
case VALUE_1: case 1:
res++; res++;
break; break;
case VALUE_X: case 2:
case VALUE_Z: case 3:
return 0; return 0;
default: default:
break; break;
} }
bitOffset += 2;
if (bitOffset == 32) {
wordOffset++;
currentWord = packedValues[wordOffset];
bitOffset = 0;
} else {
currentWord >>= 2;
}
} }
return res; return res;
} }
@ -85,25 +128,38 @@ public class BitVector {
public long toSignedValue() { public long toSignedValue() {
Boolean negative=null; Boolean negative=null;
long res = 0; long res = 0;
for(char c:value) { int bitOffset = width * 2;
int wordOffset = bitOffset >> 5;
bitOffset &= 31;
int currentWord = packedValues[wordOffset] >> bitOffset;
// Copy values out of packed array
for (int i = 0; i < width; i++) {
if(negative == null) { if(negative == null) {
switch (c) { switch (currentWord & 3) {
case VALUE_1: negative=true; break; case 1: negative=true; break;
case VALUE_0: negative=false; break; case 0: negative=false; break;
case VALUE_X: case 2:
case VALUE_Z: return 0; case 3: return 0;
default: default:
} }
} else { } else {
res<<=1; res<<=1;
switch (c) { switch (currentWord & 3) {
case VALUE_1: if(!negative) res++; break; case 1: if(!negative) res++; break;
case VALUE_0: if(negative) res++; break; case 0: if(negative) res++; break;
case VALUE_X: case 2:
case VALUE_Z: return 0; case 3: return 0;
default: default:
} }
} }
bitOffset += 2;
if (bitOffset == 32) {
wordOffset++;
currentWord = packedValues[wordOffset];
bitOffset = 0;
} else {
currentWord >>= 2;
}
} }
return negative?-1*(res+1):res; return negative?-1*(res+1):res;
} }

View File

@ -13,12 +13,14 @@ package com.minres.scviewer.database;
import java.util.NavigableMap; import java.util.NavigableMap;
public interface ISignal<T extends ISignalChange> extends IWaveform<T>{ public interface ISignal<T> extends IWaveform{
public NavigableMap<Long, T> getEvents(); public NavigableMap<Long, T> getEvents();
public T getWaveformEventsAtTime(Long time); public T getWaveformValueAtTime(Long time);
public T getWaveformEventsBeforeTime(Long time); public T getWaveformValueBeforeTime(Long time);
public Class<?> getType();
} }

View File

@ -1,15 +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;
public interface ISignalChange extends IWaveformEvent {
}

View File

@ -1,17 +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;
public interface ISignalChangeBit extends ISignalChange{
public char getValue();
}

View File

@ -1,17 +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;
public interface ISignalChangeBitVector extends ISignalChange {
public BitVector getValue();
}

View File

@ -1,17 +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;
public interface ISignalChangeReal extends ISignalChange{
public double getValue();
}

View File

@ -14,7 +14,7 @@ import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.NavigableMap; import java.util.NavigableMap;
public interface ITxStream<T extends ITxEvent> extends IWaveform<T> { public interface ITxStream<T extends ITxEvent> extends IWaveform {
public List<ITxGenerator> getGenerators(); public List<ITxGenerator> getGenerators();

View File

@ -11,7 +11,7 @@
package com.minres.scviewer.database; package com.minres.scviewer.database;
public interface IWaveform<T extends IWaveformEvent> extends IHierNode { public interface IWaveform extends IHierNode {
public Long getId(); public Long getId();
@ -19,6 +19,6 @@ public interface IWaveform<T extends IWaveformEvent> extends IHierNode {
public IWaveformDb getDb(); public IWaveformDb getDb();
public Boolean equals(IWaveform<? extends IWaveformEvent> other); public Boolean equals(IWaveform other);
} }

View File

@ -18,9 +18,9 @@ public interface IWaveformDb extends IHierNode {
public Long getMaxTime(); public Long getMaxTime();
public IWaveform<? extends IWaveformEvent> getStreamByName(String name); public IWaveform getStreamByName(String name);
public List<IWaveform<?>> getAllWaves(); public List<IWaveform> getAllWaves();
public List<RelationType> getAllRelationTypes(); public List<RelationType> getAllRelationTypes();

View File

@ -20,7 +20,7 @@ public interface IWaveformDbLoader {
public Long getMaxTime(); public Long getMaxTime();
public List<IWaveform<? extends IWaveformEvent>> getAllWaves() ; public List<IWaveform> getAllWaves() ;
public Collection<RelationType> getAllRelationTypes() ; public Collection<RelationType> getAllRelationTypes() ;

View File

@ -1,46 +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;
public class SignalChange implements IWaveformEvent {
Long time;
public SignalChange() {
time=0L;
}
public SignalChange(Long time) {
super();
this.time = time;
}
@Override
public int compareTo(IWaveformEvent o) {
return time.compareTo(o.getTime());
}
@Override
public Long getTime() {
return time;
}
public void setTime(Long time) {
this.time = time;
}
@Override
public IWaveformEvent duplicate() throws CloneNotSupportedException {
return (IWaveformEvent) this.clone();
}
}

View File

@ -41,7 +41,7 @@ public class WaveformDb extends HierNode implements IWaveformDb {
private List<RelationType> relationTypes; private List<RelationType> relationTypes;
private Map<String, IWaveform<?>> waveforms; private Map<String, IWaveform> waveforms;
private Long maxTime; private Long maxTime;
@ -61,7 +61,7 @@ public class WaveformDb extends HierNode implements IWaveformDb {
public WaveformDb() { public WaveformDb() {
super(); super();
waveforms = new HashMap<String, IWaveform<?>>(); waveforms = new HashMap<String, IWaveform>();
relationTypes=new ArrayList<>(); relationTypes=new ArrayList<>();
maxTime=0L; maxTime=0L;
} }
@ -72,20 +72,20 @@ public class WaveformDb extends HierNode implements IWaveformDb {
} }
@Override @Override
public IWaveform<? extends IWaveformEvent> getStreamByName(String name) { public IWaveform getStreamByName(String name) {
return waveforms.get(name); return waveforms.get(name);
} }
@Override @Override
public List<IWaveform<?>> getAllWaves() { public List<IWaveform> getAllWaves() {
return new ArrayList<IWaveform<?>>(waveforms.values()); return new ArrayList<IWaveform>(waveforms.values());
} }
@Override @Override
public boolean load(File inp) throws Exception { public boolean load(File inp) throws Exception {
for(IWaveformDbLoader loader:loaders){ for(IWaveformDbLoader loader:loaders){
if(loader.load(this, inp)){ if(loader.load(this, inp)){
for(IWaveform<?> w:loader.getAllWaves()){ for(IWaveform w:loader.getAllWaves()){
waveforms.put(w.getFullName(),w); waveforms.put(w.getFullName(),w);
} }
if(loader.getMaxTime()>maxTime){ if(loader.getMaxTime()>maxTime){
@ -125,8 +125,8 @@ public class WaveformDb extends HierNode implements IWaveformDb {
private void buildHierarchyNodes() throws InputFormatException{ private void buildHierarchyNodes() throws InputFormatException{
childNodes= new ArrayList<IHierNode>(); childNodes= new ArrayList<IHierNode>();
for(IWaveform<?> stream:getAllWaves()){ for(IWaveform stream:getAllWaves()){
updateMaxTime(stream); //updateMaxTime(stream);
String[] hier = stream.getName().split("\\."); String[] hier = stream.getName().split("\\.");
IHierNode node = this; IHierNode node = this;
List<String> path=new LinkedList<String>(); List<String> path=new LinkedList<String>();
@ -169,16 +169,6 @@ public class WaveformDb extends HierNode implements IWaveformDb {
} }
} }
private void updateMaxTime(IWaveform<?> waveform) {
Long last=0L;
if(waveform instanceof ITxStream<?> && ((ITxStream<?>)waveform).getEvents().lastEntry()!=null)
last=((ITxStream<?>)waveform).getEvents().lastEntry().getKey();
else if(waveform instanceof ISignal<?> && ((ISignal<?>)waveform).getEvents().lastEntry()!=null)
last=((ISignal<?>)waveform).getEvents().lastEntry().getKey();
if(last>maxTime)
maxTime=last;
}
private static String join(Collection<?> col, String delim) { private static String join(Collection<?> col, String delim) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
Iterator<?> iter = col.iterator(); Iterator<?> iter = col.iterator();