Refactored database data model to improve speed and reduce memory
consumption
This commit is contained in:
parent
e687eef42c
commit
93fd192782
|
@ -24,7 +24,7 @@ public class LevelDBLoader implements IWaveformDbLoader {
|
|||
return value.getBytes(UTF_8);
|
||||
}
|
||||
|
||||
private StringDBWrapper levelDb;
|
||||
private TxDBWrapper levelDb;
|
||||
private IWaveformDb db;
|
||||
private Long maxTime=null;
|
||||
private List<RelationType> usedRelationsList = new ArrayList<>();
|
||||
|
@ -33,7 +33,10 @@ public class LevelDBLoader implements IWaveformDbLoader {
|
|||
public boolean load(IWaveformDb db, File inp) throws Exception {
|
||||
try {
|
||||
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) {
|
||||
return false;
|
||||
}
|
||||
|
@ -55,15 +58,15 @@ public class LevelDBLoader implements IWaveformDbLoader {
|
|||
maxTime = 0L;
|
||||
else {
|
||||
String[] token = val.getKey().split("~");
|
||||
maxTime = Long.parseLong(token[2], 16);
|
||||
maxTime = Long.parseLong(token[2], 16)*levelDb.getTimeResolution();
|
||||
}
|
||||
}
|
||||
return maxTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IWaveform<? extends IWaveformEvent>> getAllWaves() {
|
||||
List<IWaveform<? extends IWaveformEvent>> streams=new ArrayList<IWaveform<? extends IWaveformEvent>>();
|
||||
public List<IWaveform> getAllWaves() {
|
||||
List<IWaveform> streams=new ArrayList<IWaveform>();
|
||||
SeekingIterator<String, String> it = levelDb.iterator();
|
||||
it.seek("s~");
|
||||
while(it.hasNext()) {
|
||||
|
|
|
@ -11,17 +11,19 @@ import org.iq80.leveldb.ReadOptions;
|
|||
import org.iq80.leveldb.Snapshot;
|
||||
import org.iq80.leveldb.impl.DbImpl;
|
||||
import org.iq80.leveldb.impl.SeekingIterator;
|
||||
import org.json.*;
|
||||
|
||||
class StringDBWrapper {
|
||||
class TxDBWrapper {
|
||||
private final Options options;
|
||||
private final ReadOptions ro = new ReadOptions();
|
||||
private final File databaseDir;
|
||||
private DbImpl db;
|
||||
private long timeResolution=1L;;
|
||||
|
||||
StringDBWrapper(Options options, File databaseDir) throws IOException {
|
||||
this.options = options.verifyChecksums(true).createIfMissing(false).errorIfExists(false);
|
||||
TxDBWrapper(Options options, File databaseDir) throws IOException {
|
||||
this.options = options.verifyChecksums(true).createIfMissing(false).errorIfExists(false).cacheSize(64*1024*1024);
|
||||
this.databaseDir = databaseDir;
|
||||
this.db = new DbImpl(options, databaseDir);
|
||||
ro.snapshot(db.getSnapshot());
|
||||
}
|
||||
|
||||
public String get(String key) {
|
||||
|
@ -33,11 +35,8 @@ class StringDBWrapper {
|
|||
}
|
||||
|
||||
public String get(String key, Snapshot snapshot) {
|
||||
byte[] slice = db.get(LevelDBLoader.toByteArray(key), new ReadOptions().snapshot(snapshot));
|
||||
if (slice == null) {
|
||||
return null;
|
||||
}
|
||||
return new String(slice, UTF_8);
|
||||
byte[] slice = db.get(LevelDBLoader.toByteArray(key), ro);
|
||||
return slice == null? null : new String(slice, UTF_8);
|
||||
}
|
||||
|
||||
public void put(String key, String value) {
|
||||
|
@ -57,7 +56,10 @@ class StringDBWrapper {
|
|||
}
|
||||
|
||||
public void close() {
|
||||
db.close();
|
||||
try {
|
||||
ro.snapshot().close();
|
||||
db.close();
|
||||
} catch (IOException e) {} // ignore any error
|
||||
}
|
||||
|
||||
public long size(String start, String limit) {
|
||||
|
@ -73,7 +75,16 @@ class StringDBWrapper {
|
|||
}
|
||||
|
||||
public void reopen(Options options) throws IOException {
|
||||
db.close();
|
||||
this.close();
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -10,9 +10,6 @@
|
|||
*******************************************************************************/
|
||||
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.Collection;
|
||||
import java.util.List;
|
||||
|
@ -23,7 +20,6 @@ import org.iq80.leveldb.impl.SeekingIterator;
|
|||
import org.json.JSONObject;
|
||||
|
||||
import java.util.NavigableMap;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.TreeMap;
|
||||
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.IWaveform;
|
||||
import com.minres.scviewer.database.IWaveformDb;
|
||||
import com.minres.scviewer.database.IWaveformEvent;
|
||||
import com.minres.scviewer.database.RelationType;
|
||||
|
||||
public class TxStream extends HierNode implements ITxStream<ITxEvent> {
|
||||
|
||||
private StringDBWrapper levelDb;
|
||||
private TxDBWrapper levelDb;
|
||||
|
||||
private String fullName;
|
||||
|
||||
|
@ -59,7 +54,7 @@ public class TxStream extends HierNode implements ITxStream<ITxEvent> {
|
|||
|
||||
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());
|
||||
this.levelDb=database;
|
||||
this.db=waveformDb;
|
||||
|
@ -93,10 +88,11 @@ public class TxStream extends HierNode implements ITxStream<ITxEvent> {
|
|||
if(generators==null){
|
||||
generators=new TreeMap<Long, TxGenerator>();
|
||||
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()) {
|
||||
Entry<String, String> val = it.next();
|
||||
if(!val.getKey().startsWith("sg~")) break;
|
||||
if(!val.getKey().startsWith(key)) break;
|
||||
JSONObject jVal = new JSONObject(val.getValue());
|
||||
generators.put(jVal.getLong("id"), new TxGenerator(this, jVal));
|
||||
}
|
||||
|
@ -107,7 +103,7 @@ public class TxStream extends HierNode implements ITxStream<ITxEvent> {
|
|||
@Override
|
||||
public int getMaxConcurrency() {
|
||||
if(maxConcurrency==null){
|
||||
maxConcurrency=1;
|
||||
getTransactions();
|
||||
}
|
||||
return maxConcurrency;
|
||||
}
|
||||
|
@ -117,8 +113,9 @@ public class TxStream extends HierNode implements ITxStream<ITxEvent> {
|
|||
if(events==null){
|
||||
events=new TreeMap<Long, List<ITxEvent>>();
|
||||
for(Entry<Long, ITx> entry:getTransactions().entrySet()){
|
||||
putEvent(new TxEvent(TxEvent.Type.BEGIN, entry.getValue()));
|
||||
putEvent(new TxEvent(TxEvent.Type.END, entry.getValue()));
|
||||
ITx tx = entry.getValue();
|
||||
putEvent(new TxEvent(TxEvent.Type.BEGIN, tx));
|
||||
putEvent(new TxEvent(TxEvent.Type.END, tx));
|
||||
}
|
||||
}
|
||||
return events;
|
||||
|
@ -139,16 +136,21 @@ public class TxStream extends HierNode implements ITxStream<ITxEvent> {
|
|||
if(transactions==null){
|
||||
if(generators==null) getGenerators();
|
||||
transactions = new TreeMap<Long, ITx>();
|
||||
maxConcurrency=0;
|
||||
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()) {
|
||||
Entry<String, String> val = it.next();
|
||||
if(!val.getKey().startsWith("sgx~")) break;
|
||||
if(!val.getKey().startsWith(key)) break;
|
||||
String[] token = val.getKey().split("~");
|
||||
long gid = Long.parseLong(token[2], 16); // gen 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;
|
||||
}
|
||||
|
@ -169,7 +171,7 @@ public class TxStream extends HierNode implements ITxStream<ITxEvent> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Boolean equals(IWaveform<? extends IWaveformEvent> other) {
|
||||
public Boolean equals(IWaveform other) {
|
||||
return(other instanceof TxStream && this.getId()==other.getId());
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ package com.minres.scviewer.database.sqlite;
|
|||
import java.beans.IntrospectionException;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
|
@ -60,9 +61,9 @@ public class SQLiteDbLoader implements IWaveformDbLoader {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<IWaveform<? extends IWaveformEvent>> getAllWaves() {
|
||||
public List<IWaveform> getAllWaves() {
|
||||
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 {
|
||||
for(ScvStream scvStream:handler.selectObjects()){
|
||||
TxStream stream = new TxStream(database, db, scvStream);
|
||||
|
@ -81,14 +82,17 @@ public class SQLiteDbLoader implements IWaveformDbLoader {
|
|||
@Override
|
||||
public boolean load(IWaveformDb db, File file) throws Exception {
|
||||
this.db=db;
|
||||
FileInputStream fis = new FileInputStream(file);
|
||||
byte[] buffer = new byte[x.length];
|
||||
int read = fis.read(buffer, 0, x.length);
|
||||
fis.close();
|
||||
if (read == x.length)
|
||||
for (int i = 0; i < x.length; i++)
|
||||
if (buffer[i] != x[i]) return false;
|
||||
|
||||
try {
|
||||
FileInputStream fis = new FileInputStream(file);
|
||||
byte[] buffer = new byte[x.length];
|
||||
int read = fis.read(buffer, 0, x.length);
|
||||
fis.close();
|
||||
if (read == x.length)
|
||||
for (int i = 0; i < x.length; i++)
|
||||
if (buffer[i] != x[i]) return false;
|
||||
} catch(FileNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
database=new SQLiteDatabase(file.getAbsolutePath());
|
||||
database.setData("TIMERESOLUTION", 1L);
|
||||
SQLiteDatabaseSelectHandler<ScvSimProps> handler = new SQLiteDatabaseSelectHandler<ScvSimProps>(ScvSimProps.class, database);
|
||||
|
|
|
@ -29,7 +29,6 @@ import com.minres.scviewer.database.ITxGenerator;
|
|||
import com.minres.scviewer.database.ITxStream;
|
||||
import com.minres.scviewer.database.IWaveform;
|
||||
import com.minres.scviewer.database.IWaveformDb;
|
||||
import com.minres.scviewer.database.IWaveformEvent;
|
||||
import com.minres.scviewer.database.RelationType;
|
||||
import com.minres.scviewer.database.sqlite.db.IDatabase;
|
||||
import com.minres.scviewer.database.sqlite.db.SQLiteDatabaseSelectHandler;
|
||||
|
@ -193,7 +192,7 @@ public class TxStream extends HierNode implements ITxStream<ITxEvent> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Boolean equals(IWaveform<? extends IWaveformEvent> other) {
|
||||
public Boolean equals(IWaveform other) {
|
||||
return(other instanceof TxStream && this.getId()==other.getId());
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ import static org.junit.Assert.assertTrue;
|
|||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
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.IWaveformDb;
|
||||
import com.minres.scviewer.database.IWaveformDbFactory;
|
||||
import com.minres.scviewer.database.vcd.VCDSignal;
|
||||
|
||||
public class DatabaseServicesTest {
|
||||
|
||||
|
@ -54,13 +56,6 @@ public class DatabaseServicesTest {
|
|||
@Before
|
||||
public void setUp() throws Exception {
|
||||
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
|
||||
|
@ -73,8 +68,17 @@ public class DatabaseServicesTest {
|
|||
assertTrue(f.exists());
|
||||
waveformDb.load(f);
|
||||
assertNotNull(waveformDb);
|
||||
assertEquals(14, waveformDb.getAllWaves().size());
|
||||
List<IWaveform> waves= waveformDb.getAllWaves();
|
||||
assertEquals(14, waves.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
|
||||
|
@ -104,18 +108,18 @@ public class DatabaseServicesTest {
|
|||
waveformDb.load(f);
|
||||
assertNotNull(waveformDb);
|
||||
assertEquals(1, waveformDb.getChildNodes().size());
|
||||
List<IWaveform<?>> waves = waveformDb.getAllWaves();
|
||||
List<IWaveform> waves = waveformDb.getAllWaves();
|
||||
assertEquals(3, waves.size());
|
||||
IWaveform<?> wave = waves.get(0);
|
||||
IWaveform wave = waves.get(0);
|
||||
assertTrue(wave instanceof ITxStream<?>);
|
||||
ITxStream<?> stream = (ITxStream<?>) wave;
|
||||
assertEquals(2, stream.getGenerators().size());
|
||||
NavigableMap<Long, List<ITxEvent>> eventsList = stream.getEvents();
|
||||
assertEquals(18, eventsList.size());
|
||||
assertEquals(27, eventsList.size());
|
||||
Entry<Long, List<ITxEvent>> eventEntry = eventsList.firstEntry();
|
||||
assertEquals(100000L, (long) eventEntry.getKey());
|
||||
assertEquals(100000000L, (long) eventEntry.getKey());
|
||||
List<ITxEvent> events = eventEntry.getValue();
|
||||
assertEquals(2, events.size());
|
||||
assertEquals(1, events.size());
|
||||
ITxEvent event = events.get(0);
|
||||
assertEquals(Type.BEGIN, event.getType());
|
||||
ITx tx = event.getTransaction();
|
||||
|
|
|
@ -5,8 +5,7 @@ Bundle-SymbolicName: com.minres.scviewer.database.text
|
|||
Bundle-Version: 1.0.1.qualifier
|
||||
Bundle-Vendor: MINRES Technologies GmbH
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
||||
Import-Package: com.minres.scviewer.database,
|
||||
org.osgi.framework;version="1.3.0"
|
||||
Import-Package: org.osgi.framework;version="1.3.0"
|
||||
Require-Bundle: com.minres.scviewer.database;bundle-version="1.0.0",
|
||||
org.codehaus.groovy;bundle-version="1.8.6",
|
||||
org.eclipse.equinox.util;bundle-version="1.0.500",
|
||||
|
|
|
@ -59,12 +59,14 @@ public class TextDbLoader implements IWaveformDbLoader{
|
|||
boolean load(IWaveformDb db, File file) throws Exception {
|
||||
this.db=db
|
||||
this.streams=[]
|
||||
def gzipped = isGzipped(file)
|
||||
if(isTxfile(gzipped?new GZIPInputStream(new FileInputStream(file)):new FileInputStream(file))){
|
||||
parseInput(gzipped?new GZIPInputStream(new FileInputStream(file)):new FileInputStream(file))
|
||||
calculateConcurrencyIndicees()
|
||||
return true
|
||||
}
|
||||
try {
|
||||
def gzipped = isGzipped(file)
|
||||
if(isTxfile(gzipped?new GZIPInputStream(new FileInputStream(file)):new FileInputStream(file))){
|
||||
parseInput(gzipped?new GZIPInputStream(new FileInputStream(file)):new FileInputStream(file))
|
||||
calculateConcurrencyIndicees()
|
||||
return true
|
||||
}
|
||||
} catch(Exception e) { }
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -109,7 +109,7 @@ class TxStream extends HierNode implements ITxStream {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Boolean equals(IWaveform<? extends IWaveformEvent> other) {
|
||||
public Boolean equals(IWaveform other) {
|
||||
return(other instanceof TxStream && this.getId()==other.getId());
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
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, BitVector.VALUE_1);
|
||||
break;
|
||||
case '1':
|
||||
decodedValues.setValue(convertedIndex, BitValue.ONE);
|
||||
break;
|
||||
|
||||
case '0':
|
||||
decodedValues.setValue(convertedIndex, BitVector.VALUE_0);
|
||||
break;
|
||||
case '0':
|
||||
decodedValues.setValue(convertedIndex, BitValue.ZERO);
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
decodedValues.setValue(convertedIndex, BitVector.VALUE_X);
|
||||
break;
|
||||
case 'x':
|
||||
decodedValues.setValue(convertedIndex, BitValue.X);
|
||||
break;
|
||||
|
||||
default:
|
||||
decodedValues.setValue(convertedIndex, BitVector.VALUE_X);
|
||||
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;
|
||||
|
||||
|
@ -31,9 +30,11 @@ public class VCDSignal<T extends ISignalChange> extends HierNode implements ISig
|
|||
|
||||
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();
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,31 +12,53 @@ package com.minres.scviewer.database;
|
|||
|
||||
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 char[] value;
|
||||
private int[] packedValues;
|
||||
|
||||
public BitVector(int netWidth) {
|
||||
this.width=netWidth;
|
||||
value = new char[netWidth];
|
||||
for(int i=0; i<netWidth; i++) value[i]='0';
|
||||
packedValues = new int[(netWidth+15)/16];
|
||||
for(int i=0; i<packedValues.length; i++) packedValues[i]=0;
|
||||
}
|
||||
|
||||
public void setValue(int i, char value) {
|
||||
this.value[i]=value;
|
||||
public void setValue(int i, BitValue 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() {
|
||||
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) {
|
||||
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() {
|
||||
|
@ -44,67 +66,101 @@ public class BitVector {
|
|||
}
|
||||
|
||||
public String toString(){
|
||||
return new String(value);
|
||||
return new String(getValue());
|
||||
}
|
||||
|
||||
public String toHexString(){
|
||||
int resWidth=(width-1)/4+1;
|
||||
char[] value=getValue();
|
||||
char[] res = new char[resWidth];
|
||||
for(int i=resWidth-1; i>=0; i--){
|
||||
int digit=0;
|
||||
for(int j=3; j>=0; j--){
|
||||
if(value[4*i+j]==VALUE_X ||value[4*i+j]==VALUE_Z ){
|
||||
res[i]=VALUE_X;
|
||||
}
|
||||
if(value[4*i+j]==VALUE_1)
|
||||
BitValue val = BitValue.fromChar(value[4*i+j]);
|
||||
switch(val) {
|
||||
case X:
|
||||
case Z:
|
||||
res[i]=val.toChar();
|
||||
continue;
|
||||
case ONE:
|
||||
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);
|
||||
}
|
||||
|
||||
public long toUnsignedValue() {
|
||||
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;
|
||||
switch (c) {
|
||||
case VALUE_1:
|
||||
switch (currentWord & 3) {
|
||||
case 1:
|
||||
res++;
|
||||
break;
|
||||
case VALUE_X:
|
||||
case VALUE_Z:
|
||||
case 2:
|
||||
case 3:
|
||||
return 0;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
bitOffset += 2;
|
||||
if (bitOffset == 32) {
|
||||
wordOffset++;
|
||||
currentWord = packedValues[wordOffset];
|
||||
bitOffset = 0;
|
||||
} else {
|
||||
currentWord >>= 2;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public long toSignedValue() {
|
||||
Boolean negative=null;
|
||||
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) {
|
||||
switch (c) {
|
||||
case VALUE_1: negative=true; break;
|
||||
case VALUE_0: negative=false; break;
|
||||
case VALUE_X:
|
||||
case VALUE_Z: return 0;
|
||||
switch (currentWord & 3) {
|
||||
case 1: negative=true; break;
|
||||
case 0: negative=false; break;
|
||||
case 2:
|
||||
case 3: return 0;
|
||||
default:
|
||||
}
|
||||
} else {
|
||||
res<<=1;
|
||||
switch (c) {
|
||||
case VALUE_1: if(!negative) res++; break;
|
||||
case VALUE_0: if(negative) res++; break;
|
||||
case VALUE_X:
|
||||
case VALUE_Z: return 0;
|
||||
switch (currentWord & 3) {
|
||||
case 1: if(!negative) res++; break;
|
||||
case 0: if(negative) res++; break;
|
||||
case 2:
|
||||
case 3: return 0;
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
bitOffset += 2;
|
||||
if (bitOffset == 32) {
|
||||
wordOffset++;
|
||||
currentWord = packedValues[wordOffset];
|
||||
bitOffset = 0;
|
||||
} else {
|
||||
currentWord >>= 2;
|
||||
}
|
||||
}
|
||||
return negative?-1*(res+1):res;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,12 +13,14 @@ package com.minres.scviewer.database;
|
|||
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 T getWaveformEventsAtTime(Long time);
|
||||
public T getWaveformValueAtTime(Long time);
|
||||
|
||||
public T getWaveformEventsBeforeTime(Long time);
|
||||
public T getWaveformValueBeforeTime(Long time);
|
||||
|
||||
public Class<?> getType();
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
||||
}
|
|
@ -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();
|
||||
|
||||
}
|
|
@ -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();
|
||||
|
||||
}
|
|
@ -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();
|
||||
|
||||
}
|
|
@ -14,7 +14,7 @@ import java.util.Collection;
|
|||
import java.util.List;
|
||||
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();
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
package com.minres.scviewer.database;
|
||||
|
||||
|
||||
public interface IWaveform<T extends IWaveformEvent> extends IHierNode {
|
||||
public interface IWaveform extends IHierNode {
|
||||
|
||||
public Long getId();
|
||||
|
||||
|
@ -19,6 +19,6 @@ public interface IWaveform<T extends IWaveformEvent> extends IHierNode {
|
|||
|
||||
public IWaveformDb getDb();
|
||||
|
||||
public Boolean equals(IWaveform<? extends IWaveformEvent> other);
|
||||
public Boolean equals(IWaveform other);
|
||||
|
||||
}
|
||||
|
|
|
@ -18,9 +18,9 @@ public interface IWaveformDb extends IHierNode {
|
|||
|
||||
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();
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ public interface IWaveformDbLoader {
|
|||
|
||||
public Long getMaxTime();
|
||||
|
||||
public List<IWaveform<? extends IWaveformEvent>> getAllWaves() ;
|
||||
public List<IWaveform> getAllWaves() ;
|
||||
|
||||
public Collection<RelationType> getAllRelationTypes() ;
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -41,7 +41,7 @@ public class WaveformDb extends HierNode implements IWaveformDb {
|
|||
|
||||
private List<RelationType> relationTypes;
|
||||
|
||||
private Map<String, IWaveform<?>> waveforms;
|
||||
private Map<String, IWaveform> waveforms;
|
||||
|
||||
private Long maxTime;
|
||||
|
||||
|
@ -61,7 +61,7 @@ public class WaveformDb extends HierNode implements IWaveformDb {
|
|||
|
||||
public WaveformDb() {
|
||||
super();
|
||||
waveforms = new HashMap<String, IWaveform<?>>();
|
||||
waveforms = new HashMap<String, IWaveform>();
|
||||
relationTypes=new ArrayList<>();
|
||||
maxTime=0L;
|
||||
}
|
||||
|
@ -72,20 +72,20 @@ public class WaveformDb extends HierNode implements IWaveformDb {
|
|||
}
|
||||
|
||||
@Override
|
||||
public IWaveform<? extends IWaveformEvent> getStreamByName(String name) {
|
||||
public IWaveform getStreamByName(String name) {
|
||||
return waveforms.get(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IWaveform<?>> getAllWaves() {
|
||||
return new ArrayList<IWaveform<?>>(waveforms.values());
|
||||
public List<IWaveform> getAllWaves() {
|
||||
return new ArrayList<IWaveform>(waveforms.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean load(File inp) throws Exception {
|
||||
for(IWaveformDbLoader loader:loaders){
|
||||
if(loader.load(this, inp)){
|
||||
for(IWaveform<?> w:loader.getAllWaves()){
|
||||
for(IWaveform w:loader.getAllWaves()){
|
||||
waveforms.put(w.getFullName(),w);
|
||||
}
|
||||
if(loader.getMaxTime()>maxTime){
|
||||
|
@ -125,8 +125,8 @@ public class WaveformDb extends HierNode implements IWaveformDb {
|
|||
|
||||
private void buildHierarchyNodes() throws InputFormatException{
|
||||
childNodes= new ArrayList<IHierNode>();
|
||||
for(IWaveform<?> stream:getAllWaves()){
|
||||
updateMaxTime(stream);
|
||||
for(IWaveform stream:getAllWaves()){
|
||||
//updateMaxTime(stream);
|
||||
String[] hier = stream.getName().split("\\.");
|
||||
IHierNode node = this;
|
||||
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) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Iterator<?> iter = col.iterator();
|
||||
|
|
Loading…
Reference in New Issue