Merge branch 'feature/factor_out_groovy' into develop

This commit is contained in:
Eyck Jentzsch 2021-01-09 10:36:25 +01:00
commit 5ea0d6446a
48 changed files with 1113 additions and 840 deletions

View File

@ -31,6 +31,11 @@
<repository location="http://download.eclipse.org/nebula/releases/latest"/>
<unit id="org.eclipse.nebula.widgets.xviewer.feature.feature.group" version="1.1.0.202011020719"/>
</location>
<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
<repository location="http://download.eclipse.org/collections/10.4.0/repository"/>
<unit id="org.eclipse.collections.feature.feature.group" version="0.0.0"/>
<unit id="org.eclipse.collections.feature.source.feature.group" version="0.0.0"/>
</location>
</locations>
<targetJRE path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<launcherArgs>

View File

@ -58,12 +58,6 @@ http://www.eclipse.org/legal/epl-v10.html
version="0.0.0"
unpack="false"/>
<plugin
id="org.codehaus.groovy"
download-size="0"
install-size="0"
version="0.0.0"/>
<plugin
id="com.minres.scviewer.database.vcd"
download-size="0"

View File

@ -8,5 +8,4 @@
<version>2.0.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<version>2.0.0-SNAPSHOT</version>
</project>

View File

@ -37,8 +37,6 @@ public class SQLiteDbLoader implements IWaveformDbLoader {
protected IDatabase database;
private List<RelationType> usedRelationsList = new ArrayList<>();
private IWaveformDb db;
private ScvSimProps scvSimProps;
@ -63,7 +61,7 @@ public class SQLiteDbLoader implements IWaveformDbLoader {
List<IWaveform> streams=new ArrayList<>();
try {
for(ScvStream scvStream:handler.selectObjects()){
TxStream stream = new TxStream(database, db, scvStream);
TxStream stream = new TxStream(database, scvStream);
stream.setRelationTypeList(usedRelationsList);
streams.add(stream);
}
@ -77,8 +75,8 @@ public class SQLiteDbLoader implements IWaveformDbLoader {
@Override
public boolean load(IWaveformDb db, File file) throws InputFormatException {
dispose();
if(file.isDirectory() || !file.exists()) return false;
this.db=db;
try(FileInputStream fis = new FileInputStream(file)) {
byte[] buffer = new byte[x.length];
int read = fis.read(buffer, 0, x.length);
@ -88,7 +86,7 @@ public class SQLiteDbLoader implements IWaveformDbLoader {
} catch(IOException e) {
return false;
}
database=new SQLiteDatabase(file.getAbsolutePath());
database=new SQLiteDatabase(file.getAbsolutePath(), db);
database.setData("TIMERESOLUTION", 1L);
SQLiteDatabaseSelectHandler<ScvSimProps> handler = new SQLiteDatabaseSelectHandler<>(ScvSimProps.class, database);
try {
@ -103,7 +101,12 @@ public class SQLiteDbLoader implements IWaveformDbLoader {
}
return false;
}
public void dispose() {
database=null;
usedRelationsList=null;
}
@Override
public Collection<RelationType> getAllRelationTypes(){
return usedRelationsList;

View File

@ -164,7 +164,7 @@ public class Tx implements ITx {
List<ScvStream> streams = new SQLiteDatabaseSelectHandler<ScvStream>(ScvStream.class, database,
"id="+res.get(0).getStream()).selectObjects();
if(streams.size()!=1) return null;
TxStream tgtStream = (TxStream) trStream.getDb().getStreamByName(streams.get(0).getName());
TxStream tgtStream = (TxStream) database.getWaveformDb().getStreamByName(streams.get(0).getName());
Tx that = (Tx) tgtStream.getTransactions().get(otherId);
if(outgoing)
return new TxRelation(trStream.getRelationType(rel.getName()), this, that);

View File

@ -10,12 +10,8 @@
*******************************************************************************/
package com.minres.scviewer.database.sqlite;
import java.util.ArrayList;
import java.util.List;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.sqlite.tables.ScvGenerator;
import com.minres.scviewer.database.tx.ITx;
import com.minres.scviewer.database.tx.ITxGenerator;
public class TxGenerator implements ITxGenerator {
@ -44,9 +40,4 @@ public class TxGenerator implements ITxGenerator {
return scvGenerator.getName();
}
@Override
public List<ITx> getTransactions() {
return new ArrayList<>();
}
}

View File

@ -24,8 +24,8 @@ import com.minres.scviewer.database.EventKind;
import com.minres.scviewer.database.HierNode;
import com.minres.scviewer.database.IEvent;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.IWaveformDb;
import com.minres.scviewer.database.RelationType;
import com.minres.scviewer.database.RelationTypeFactory;
import com.minres.scviewer.database.WaveformType;
import com.minres.scviewer.database.sqlite.db.IDatabase;
import com.minres.scviewer.database.sqlite.db.SQLiteDatabaseSelectHandler;
@ -41,8 +41,6 @@ public class TxStream extends HierNode implements IWaveform {
private String fullName;
private IWaveformDb db;
private ScvStream scvStream;
private TreeMap<Integer, TxGenerator> generators;
@ -55,17 +53,11 @@ public class TxStream extends HierNode implements IWaveform {
private List<RelationType> usedRelationsList;
public TxStream(IDatabase database, IWaveformDb waveformDb, ScvStream scvStream) {
public TxStream(IDatabase database, ScvStream scvStream) {
super(scvStream.getName());
this.database=database;
fullName=scvStream.getName();
this.scvStream=scvStream;
db=waveformDb;
}
@Override
public IWaveformDb getDb() {
return db;
}
@Override
@ -173,7 +165,7 @@ public class TxStream extends HierNode implements IWaveform {
}
public RelationType getRelationType(String name) {
RelationType relType=RelationType.create(name);
RelationType relType=RelationTypeFactory.create(name);
if(!usedRelationsList.contains(relType)) usedRelationsList.add(relType);
return relType;
}

View File

@ -16,6 +16,8 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import com.minres.scviewer.database.IWaveformDb;
/**
*
* Creates a connection to a database.
@ -58,4 +60,6 @@ public interface IDatabase {
public void setData(String name, Object value);
public Object getData(String name);
public IWaveformDb getWaveformDb();
}

View File

@ -20,10 +20,14 @@ import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import com.minres.scviewer.database.IWaveformDb;
public class SQLiteDatabase implements IDatabase {
protected String dbFileName;
protected IWaveformDb waveformDb;
protected HashMap<String, Object> props;
static {
@ -39,9 +43,10 @@ public class SQLiteDatabase implements IDatabase {
}
}
public SQLiteDatabase(String dbFileName) {
public SQLiteDatabase(String dbFileName, IWaveformDb waveformDb) {
super();
this.dbFileName = dbFileName;
this.waveformDb = waveformDb;
props = new HashMap<String, Object>();
}
@ -89,4 +94,9 @@ public class SQLiteDatabase implements IDatabase {
return props.get(name);
}
@Override
public IWaveformDb getWaveformDb() {
return waveformDb;
}
}

View File

@ -11,10 +11,7 @@
<attribute name="javadoc_location" value="jar:platform:/resource/com.minres.scviewer.database.text/lib/mapdb-3.0.7-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="src/"/>
<classpathentry exported="true" kind="lib" path="lib/eclipse-collections-9.2.0.jar"/>
<classpathentry exported="true" kind="lib" path="lib/eclipse-collections-api-9.2.0.jar"/>
<classpathentry exported="true" kind="lib" path="lib/eclipse-collections-forkjoin-9.2.0.jar"/>
<classpathentry kind="src" path="src"/>
<classpathentry exported="true" kind="lib" path="lib/kotlin-stdlib-1.2.42.jar"/>
<classpathentry exported="true" kind="lib" path="lib/lz4-1.3.0.jar"/>
<classpathentry exported="true" kind="lib" path="lib/elsa-3.0.0-M5.jar"/>

View File

@ -33,7 +33,6 @@
</buildSpec>
<natures>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>org.eclipse.jdt.groovy.core.groovyNature</nature>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>

View File

@ -7,17 +7,14 @@ Bundle-Vendor: MINRES Technologies GmbH
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Import-Package: org.osgi.framework;version="1.3.0"
Require-Bundle: com.minres.scviewer.database,
org.codehaus.groovy;bundle-version="2.5.8",
org.eclipse.osgi.services;bundle-version="3.4.0",
com.google.guava;bundle-version="15.0.0"
com.google.guava;bundle-version="15.0.0",
org.eclipse.collections;bundle-version="10.4.0"
Service-Component: OSGI-INF/component.xml
Bundle-ActivationPolicy: lazy
Automatic-Module-Name: com.minres.scviewer.database.text
Bundle-ClassPath: lib/mapdb-3.0.7.jar,
.,
lib/eclipse-collections-9.2.0.jar,
lib/eclipse-collections-api-9.2.0.jar,
lib/eclipse-collections-forkjoin-9.2.0.jar,
Bundle-ClassPath: .,
lib/mapdb-3.0.7.jar,
lib/kotlin-stdlib-1.2.42.jar,
lib/lz4-1.3.0.jar,
lib/elsa-3.0.0-M5.jar

View File

@ -13,9 +13,6 @@ bin.includes = META-INF/,\
OSGI-INF/,\
lib/,\
lib/mapdb-3.0.7.jar,\
lib/eclipse-collections-9.2.0.jar,\
lib/eclipse-collections-api-9.2.0.jar,\
lib/eclipse-collections-forkjoin-9.2.0.jar,\
lib/kotlin-stdlib-1.2.42.jar,\
lib/lz4-1.3.0.jar,\
lib/elsa-3.0.0-M5.jar

View File

@ -0,0 +1,25 @@
package com.minres.scviewer.database.text;
import java.io.Serializable;
import com.minres.scviewer.database.RelationType;
class ScvRelation implements Serializable {
/**
*
*/
private static final long serialVersionUID = -347668857680574140L;
final long source;
final long target;
final RelationType relationType;
public ScvRelation(RelationType relationType, long source, long target) {
this.source = source;
this.target = target;
this.relationType = relationType;
}
}

View File

@ -0,0 +1,47 @@
/*******************************************************************************
* Copyright (c) 2012 IT Just working.
* 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:
* IT Just working - initial API and implementation
*******************************************************************************/
package com.minres.scviewer.database.text;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import com.minres.scviewer.database.tx.ITxAttribute;
class ScvTx implements Serializable{
/**
*
*/
private static final long serialVersionUID = -855200240003328221L;
final long id;
final long generatorId;
final long streamId;
long beginTime;
long endTime;
final List<ITxAttribute> attributes = new ArrayList<>();
ScvTx(long id, long streamId, long generatorId, long begin){
this.id=id;
this.streamId=streamId;
this.generatorId=generatorId;
this.beginTime=begin;
this.endTime=begin;
}
Long getId() {return id;}
}

View File

@ -1,245 +0,0 @@
/*******************************************************************************
* Copyright (c) 2012 IT Just working.
* 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:
* IT Just working - initial API and implementation
*******************************************************************************/
package com.minres.scviewer.database.text;
import java.nio.charset.CharsetDecoder;
import java.util.Collection;
import java.util.zip.GZIPInputStream
import org.codehaus.groovy.ast.stmt.CatchStatement
import org.mapdb.DB
import org.mapdb.DBMaker
import groovy.io.FileType
import com.minres.scviewer.database.AssociationType
import com.minres.scviewer.database.DataType
import com.minres.scviewer.database.IWaveform
import com.minres.scviewer.database.IWaveformDb
import com.minres.scviewer.database.IWaveformDbLoader
import com.minres.scviewer.database.InputFormatException
import com.minres.scviewer.database.RelationType
import com.minres.scviewer.database.tx.ITxGenerator
public class TextDbLoader implements IWaveformDbLoader{
private Long maxTime;
IWaveformDb db;
def streams = []
def relationTypes=[:]
DB mapDb
public TextDbLoader() {
}
@Override
public Long getMaxTime() {
return maxTime;
}
@Override
public Collection<IWaveform> getAllWaves() {
return streams;
}
public Map<Long, ITxGenerator> getGeneratorsById() {
TreeMap<Long, ITxGenerator> res = new TreeMap<Long, ITxGenerator>();
streams.each{TxStream stream -> stream.generators.each{res.put(it.id, id)} }
return res;
}
static final byte[] x = "scv_tr_stream".bytes
@Override
boolean load(IWaveformDb db, File file) throws InputFormatException {
if(file.isDirectory() || !file.exists()) return false;
this.db=db
this.streams=[]
try {
def gzipped = isGzipped(file)
if(isTxfile(gzipped?new GZIPInputStream(new FileInputStream(file)):new FileInputStream(file))){
def mapDbFile = File.createTempFile("."+file.name, null /*"tmp"*/, null /*file.parentFile*/)
mapDbFile.delete()
mapDbFile.deleteOnExit()
this.mapDb = DBMaker
.fileDB(mapDbFile)
.fileMmapEnableIfSupported()
.fileMmapPreclearDisable()
.cleanerHackEnable()
.allocateStartSize(64*1024*1024)
.allocateIncrement(64*1024*1024)
.make()
// NPE here --->
parseInput(gzipped?new GZIPInputStream(new FileInputStream(file)):new FileInputStream(file))
streams.each{ TxStream stream -> stream.getWidth() }
return true
}
} catch (IndexOutOfBoundsException e) {
return false
} catch (IllegalArgumentException e) {
return false
} catch (NumberFormatException e) {
return false
} catch(EOFException e) {
return true;
} catch(Exception e) {
System.out.println("---->>> Exception "+e.toString()+" caught while loading database");
//System.out.println("---->>> Exception "+e.toString()+" caught while loading database. StackTrace following... ");
//e.printStackTrace()
} catch(Error e) {
System.out.println("---->>> Exception "+e.toString()+" caught while loading database. StackTrace following... ");
e.printStackTrace()
}
return false;
}
private static boolean isTxfile(InputStream istream) {
byte[] buffer = new byte[x.size()]
def readCnt = istream.read(buffer, 0, x.size())
istream.close()
if(readCnt==x.size()){
for(int i=0; i<x.size(); i++)
if(buffer[i]!=x[i]) return false
}
return true
}
private static boolean isGzipped(File f) {
InputStream is = null;
try {
is = new FileInputStream(f);
byte [] signature = new byte[2];
int nread = is.read( signature ); //read the gzip signature
return nread == 2 && signature[ 0 ] == (byte) 0x1f && signature[ 1 ] == (byte) 0x8b;
} catch (IOException e) {
return false;
} finally {
if(is!=null) is.close()
}
}
private stringToScale(String scale){
switch(scale.trim()){
case "fs":return 1L
case "ps":return 1000L
case "ns":return 1000000L
case "us":return 1000000000L
case "ms":return 1000000000000L
case "s": return 1000000000000000L
}
return 1L
}
private def parseInput(InputStream inputStream){
def streamsById = [:]
def generatorsById = [:]
def transactionsById = [:]
TxGenerator generator
Tx transaction
boolean endTransaction=false
def matcher
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
long lineCnt=0;
reader.eachLine { line ->
def tokens = line.split(/\s+/) as ArrayList
switch(tokens[0]){
case "scv_tr_stream":
if ((matcher = line =~ /^scv_tr_stream\s+\(ID (\d+),\s+name\s+"([^"]+)",\s+kind\s+"([^"]+)"\)$/)) {
def id = Integer.parseInt(matcher[0][1])
def stream = new TxStream(this, id, matcher[0][2], matcher[0][3])
streams<<stream
streamsById[id]=stream
}
break;
case "scv_tr_generator":
if ((matcher = line =~ /^scv_tr_generator\s+\(ID\s+(\d+),\s+name\s+"([^"]+)",\s+scv_tr_stream\s+(\d+),$/)) {
def id = Integer.parseInt(matcher[0][1])
TxStream stream=streamsById[Integer.parseInt(matcher[0][3])] as TxStream
generator=new TxGenerator(id, stream, matcher[0][2])
stream.generators<<generator
generatorsById[id]=generator
}
break;
case "begin_attribute":
if ((matcher = line =~ /^begin_attribute \(ID (\d+), name "([^"]+)", type "([^"]+)"\)$/)) {
generator.begin_attrs << TxAttributeType.getAttrType(matcher[0][2], DataType.valueOf(matcher[0][3]), AssociationType.BEGIN)
}
break;
case "end_attribute":
if ((matcher = line =~ /^end_attribute \(ID (\d+), name "([^"]+)", type "([^"]+)"\)$/)) {
generator.end_attrs << TxAttributeType.getAttrType(matcher[0][2], DataType.valueOf(matcher[0][3]), AssociationType.END)
}
break;
case ")":
generator=null
break
case "tx_begin"://matcher = line =~ /^tx_begin\s+(\d+)\s+(\d+)\s+(\d+)\s+([munpf]?s)/
def id = Integer.parseInt(tokens[1])
TxGenerator gen=generatorsById[Integer.parseInt(tokens[2])]
transaction = new Tx(id, gen.stream, gen, Long.parseLong(tokens[3])*stringToScale(tokens[4]))
gen.transactions << transaction
transactionsById[id]= transaction
gen.begin_attrs_idx=0;
maxTime = maxTime>transaction.beginTime?maxTime:transaction.beginTime
endTransaction=false
break
case "tx_end"://matcher = line =~ /^tx_end\s+(\d+)\s+(\d+)\s+(\d+)\s+([munpf]?s)/
def id = Integer.parseInt(tokens[1])
transaction = transactionsById[id]
assert Integer.parseInt(tokens[2])==transaction.generator.id
transaction.endTime = Long.parseLong(tokens[3])*stringToScale(tokens[4])
transaction.generator.end_attrs_idx=0;
maxTime = maxTime>transaction.endTime?maxTime:transaction.endTime
endTransaction=true
break
case "tx_record_attribute"://matcher = line =~ /^tx_record_attribute\s+(\d+)\s+"([^"]+)"\s+(\S+)\s*=\s*(.+)$/
def id = Integer.parseInt(tokens[1])
def name = tokens[2][1..-2]
def type = tokens[3] as DataType
def remaining = tokens.size()>5?tokens[5..-1].join(' '):""
transactionsById[id].attributes<<new TxAttribute(name, type, AssociationType.RECORD, remaining)
break
case "a"://matcher = line =~ /^a\s+(.+)$/
if(endTransaction){
transaction.attributes << new TxAttribute(transaction.generator.end_attrs[transaction.generator.end_attrs_idx], tokens[1])
transaction.generator.end_attrs_idx++
} else {
transaction.attributes << new TxAttribute(transaction.generator.begin_attrs[transaction.generator.begin_attrs_idx], tokens[1])
transaction.generator.begin_attrs_idx++
}
break
case "tx_relation"://matcher = line =~ /^tx_relation\s+\"(\S+)\"\s+(\d+)\s+(\d+)$/
Tx tr2= transactionsById[Integer.parseInt(tokens[2])]
Tx tr1= transactionsById[Integer.parseInt(tokens[3])]
def relType=tokens[1][1..-2]
if(!relationTypes.containsKey(relType)) relationTypes[relType]=RelationType.create(relType)
def rel = new TxRelation(relationTypes[relType], tr1, tr2)
tr1.outgoingRelations<<rel
tr2.incomingRelations<<rel
break
default:
println "Don't know what to do with: '$line'"
}
lineCnt++
}
}
public Collection<RelationType> getAllRelationTypes(){
return relationTypes.values();
}
}

View File

@ -0,0 +1,385 @@
/*******************************************************************************
* Copyright (c) 2012 IT Just working.
* 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:
* IT Just working - initial API and implementation
*******************************************************************************/
package com.minres.scviewer.database.text;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.GZIPInputStream;
import org.eclipse.collections.impl.map.mutable.UnifiedMap;
import org.mapdb.DB;
import org.mapdb.DB.TreeMapSink;
import org.mapdb.DBMaker;
import org.mapdb.Serializer;
import com.google.common.collect.HashMultimap;
import com.minres.scviewer.database.AssociationType;
import com.minres.scviewer.database.DataType;
import com.minres.scviewer.database.EventKind;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.IWaveformDb;
import com.minres.scviewer.database.IWaveformDbLoader;
import com.minres.scviewer.database.InputFormatException;
import com.minres.scviewer.database.RelationType;
import com.minres.scviewer.database.RelationTypeFactory;
import com.minres.scviewer.database.tx.ITx;
public class TextDbLoader implements IWaveformDbLoader{
private Long maxTime=0L;
DB mapDb=null;
final List<String> attrValues = new ArrayList<>();
final Map<String, RelationType> relationTypes = UnifiedMap.newMap();
final Map<Long, TxStream> txStreams = UnifiedMap.newMap();
final Map<Long, TxGenerator> txGenerators = UnifiedMap.newMap();
Map<Long, ScvTx> transactions = null;
final Map<String, TxAttributeType> attributeTypes = UnifiedMap.newMap();
final HashMultimap<Long, ScvRelation> relationsIn = HashMultimap.create();
final HashMultimap<Long, ScvRelation> relationsOut = HashMultimap.create();
HashMap<Long, Tx> txCache = new HashMap<>();
List<Thread> threads = new ArrayList<>();
@Override
public Long getMaxTime() {
return maxTime;
}
@Override
public Collection<IWaveform> getAllWaves() {
return new ArrayList<>(txStreams.values());
}
static final byte[] x = "scv_tr_stream".getBytes();
@SuppressWarnings("unchecked")
@Override
public boolean load(IWaveformDb db, File file) throws InputFormatException {
dispose();
if(file.isDirectory() || !file.exists()) return false;
TextDbParser parser = new TextDbParser(this);
boolean gzipped = isGzipped(file);
try {
if(!isTxfile(gzipped?new GZIPInputStream(new FileInputStream(file)):new FileInputStream(file)))
return false;
} catch(Exception e) {
throw new InputFormatException();
}
if(file.length() < 75000000*(gzipped?1:10) || "memory".equals(System.getProperty("ScvBackingDB", "file")))
mapDb = DBMaker
.memoryDirectDB()
.allocateStartSize(512l*1024l*1024l)
.allocateIncrement(128l*1024l*1024l)
.cleanerHackEnable()
.make();
else {
File mapDbFile;
try {
mapDbFile = File.createTempFile("."+file.getName(), ".mapdb", null /*file.parentFile*/);
Files.delete(Paths.get(mapDbFile.getPath()));
} catch (IOException e1) {
return false;
}
mapDb = DBMaker
.fileDB(mapDbFile)
.fileMmapEnable() // Always enable mmap
.fileMmapEnableIfSupported()
.fileMmapPreclearDisable()
.allocateStartSize(512l*1024l*1024l)
.allocateIncrement(128l*1024l*1024l)
.cleanerHackEnable()
.make();
mapDbFile.deleteOnExit();
}
try {
parser.txSink = mapDb.treeMap("transactions", Serializer.LONG,Serializer.JAVA).createFromSink();
parser.parseInput(gzipped?new GZIPInputStream(new FileInputStream(file)):new FileInputStream(file));
transactions = parser.txSink.create();
} catch(IllegalArgumentException|ArrayIndexOutOfBoundsException e) {
} catch(Exception e) {
System.out.println("---->>> Exception "+e.toString()+" caught while loading database");
e.printStackTrace();
return false;
}
for(TxStream stream:txStreams.values()) {
Thread t = new Thread() {
@Override
public void run() {
try {
stream.calculateConcurrency();
} catch (Exception e) {/* don't let exceptions bubble up */ }
}
};
threads.add(t);
t.start();
}
return true;
}
@Override
public void dispose() {
attrValues.clear();
relationTypes.clear();
txStreams.clear();
txGenerators.clear();
transactions = null;
attributeTypes.clear();
relationsIn.clear();
relationsOut.clear();
if(mapDb!=null) {
mapDb.close();
mapDb=null;
}
}
private static boolean isTxfile(InputStream istream) {
byte[] buffer = new byte[x.length];
try {
int readCnt = istream.read(buffer, 0, x.length);
istream.close();
if(readCnt==x.length){
for(int i=0; i<x.length; i++)
if(buffer[i]!=x[i]) return false;
}
return true;
} catch (IOException e) {
return false;
}
}
private static boolean isGzipped(File f) {
try(InputStream is = new FileInputStream(f)) {
byte [] signature = new byte[2];
int nread = is.read( signature ); //read the gzip signature
return nread == 2 && signature[ 0 ] == (byte) 0x1f && signature[ 1 ] == (byte) 0x8b;
} catch (IOException e) {
return false;
}
}
public Collection<RelationType> getAllRelationTypes(){
return relationTypes.values();
}
static class TextDbParser {
static final Pattern scv_tr_stream = Pattern.compile("^scv_tr_stream\\s+\\(ID (\\d+),\\s+name\\s+\"([^\"]+)\",\\s+kind\\s+\"([^\"]+)\"\\)$");
static final Pattern scv_tr_generator = Pattern.compile("^scv_tr_generator\\s+\\(ID\\s+(\\d+),\\s+name\\s+\"([^\"]+)\",\\s+scv_tr_stream\\s+(\\d+),$");
static final Pattern begin_attribute = Pattern.compile("^begin_attribute \\(ID (\\d+), name \"([^\"]+)\", type \"([^\"]+)\"\\)$");
static final Pattern end_attribute = Pattern.compile("^end_attribute \\(ID (\\d+), name \"([^\"]+)\", type \"([^\"]+)\"\\)$");
final TextDbLoader loader;
HashMap<Long, ScvTx> transactionById = new HashMap<>();
TreeMapSink<Long, ScvTx> txSink;
BufferedReader reader = null;
TxGenerator generator=null;
Map<String, Integer> attrValueLut = new HashMap<>();
public TextDbParser(TextDbLoader loader) {
super();
this.loader = loader;
}
void parseInput(InputStream inputStream) throws IOException{
reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
String curLine = reader.readLine();
String nextLine = null;
while((nextLine=reader.readLine())!=null && curLine!=null) {
curLine=parseLine(curLine, nextLine);
}
if(curLine!=null)
parseLine(curLine, nextLine);
}
private TxAttributeType getAttrType(String name, DataType dataType, AssociationType type){
String key =name+"-"+dataType.toString();
TxAttributeType res;
if(loader.attributeTypes.containsKey(key)){
res=loader.attributeTypes.get(key);
} else {
res=new TxAttributeType(name, dataType, type);
loader.attributeTypes.put(key, res);
}
return res;
}
private String parseLine(String curLine, String nextLine) throws IOException{
String[] tokens = curLine.split("\\s+");
if("tx_record_attribute".equals(tokens[0])){
Long id = Long.parseLong(tokens[1]);
String name = tokens[2].substring(1, tokens[2].length());
DataType type = DataType.valueOf(tokens[3]);
String remaining = tokens.length>5?String.join(" ", Arrays.copyOfRange(tokens, 5, tokens.length)):"";
TxAttributeType attrType = getAttrType(name, type, AssociationType.RECORD);
transactionById.get(id).attributes.add(new TxAttribute(attrType, getAttrString(attrType, remaining)));
} else if("tx_begin".equals(tokens[0])){
Long id = Long.parseLong(tokens[1]);
Long genId = Long.parseLong(tokens[2]);
TxGenerator gen=loader.txGenerators.get(genId);
ScvTx scvTx = new ScvTx(id, gen.stream.getId(), genId, Long.parseLong(tokens[3])*stringToScale(tokens[4]));
loader.maxTime = loader.maxTime>scvTx.beginTime?loader.maxTime:scvTx.beginTime;
TxStream stream = loader.txStreams.get(gen.stream.getId());
stream.setConcurrency(stream.getConcurrency()+1);
if(nextLine!=null && nextLine.charAt(0)=='a') {
int idx=0;
while(nextLine!=null && nextLine.charAt(0)=='a') {
String[] attrTokens=nextLine.split("\\s+");
TxAttributeType attrType = gen.beginAttrs.get(idx);
TxAttribute attr = new TxAttribute(attrType, getAttrString(attrType, attrTokens[1]));
scvTx.attributes.add(attr);
idx++;
nextLine=reader.readLine();
}
}
txSink.put(id, scvTx);
transactionById.put(id, scvTx);
} else if("tx_end".equals(tokens[0])){
Long id = Long.parseLong(tokens[1]);
ScvTx scvTx = transactionById.get(id);
assert Long.parseLong(tokens[2])==scvTx.generatorId;
scvTx.endTime=Long.parseLong(tokens[3])*stringToScale(tokens[4]);
loader.maxTime = loader.maxTime>scvTx.endTime?loader.maxTime:scvTx.endTime;
TxGenerator gen = loader.txGenerators.get(scvTx.generatorId);
TxStream stream = loader.txStreams.get(gen.stream.getId());
if(scvTx.beginTime==scvTx.endTime)
stream.addEvent(new TxEvent(loader, EventKind.SINGLE, id, scvTx.beginTime));
else {
stream.addEvent(new TxEvent(loader, EventKind.BEGIN, id, scvTx.beginTime));
stream.addEvent(new TxEvent(loader, EventKind.END, id, scvTx.endTime));
}
stream.setConcurrency(stream.getConcurrency()-1);
if(nextLine!=null && nextLine.charAt(0)=='a') {
int idx=0;
while(nextLine!=null && nextLine.charAt(0)=='a') {
String[] attrTokens=nextLine.split("\\s+");
TxAttributeType attrType = gen.endAttrs.get(idx);
TxAttribute attr = new TxAttribute(attrType, getAttrString(attrType, attrTokens[1]));
scvTx.attributes.add(attr);
idx++;
nextLine=reader.readLine();
}
}
} else if("tx_relation".equals(tokens[0])){
Long tr2= Long.parseLong(tokens[2]);
Long tr1= Long.parseLong(tokens[3]);
String relType=tokens[1].substring(1, tokens[1].length()-1);
if(!loader.relationTypes.containsKey(relType))
loader.relationTypes.put(relType, RelationTypeFactory.create(relType));
ScvRelation rel = new ScvRelation(loader.relationTypes.get(relType), tr1, tr2);
loader.relationsOut.put(tr1, rel);
loader.relationsIn.put(tr2, rel);
} else if("scv_tr_stream".equals(tokens[0])){
Matcher matcher = scv_tr_stream.matcher(curLine);
if (matcher.matches()) {
Long id = Long.parseLong(matcher.group(1));
TxStream stream = new TxStream(loader, id, matcher.group(2), matcher.group(3));
loader.txStreams.put(id, stream);
}
} else if("scv_tr_generator".equals(tokens[0])){
Matcher matcher = scv_tr_generator.matcher(curLine);
if ((matcher.matches())) {
Long id = Long.parseLong(matcher.group(1));
TxStream stream=loader.txStreams.get(Long.parseLong(matcher.group(3)));
generator=new TxGenerator(id, stream, matcher.group(2));
loader.txGenerators.put(id, generator);
}
} else if("begin_attribute".equals(tokens[0])){
Matcher matcher = begin_attribute.matcher(curLine);
if ((matcher.matches())) {
TxAttributeType attrType = getAttrType(matcher.group(2), DataType.valueOf(matcher.group(3)), AssociationType.BEGIN);
generator.beginAttrs.add(attrType);
}
} else if("end_attribute".equals(tokens[0])){
Matcher matcher = end_attribute.matcher(curLine);
if ((matcher.matches())) {
TxAttributeType attrType = getAttrType(matcher.group(2), DataType.valueOf(matcher.group(3)), AssociationType.END);
generator.endAttrs.add(attrType);
}
} else if(")".equals(tokens[0])){
generator=null;
} else if("a".equals(tokens[0])){//matcher = line =~ /^a\s+(.+)$/
System.out.println("Don't know what to do with: '"+curLine+"'");
} else
System.out.println("Don't know what to do with: '"+curLine+"'");
return nextLine;
}
private String getAttrString(TxAttributeType attrType, String string) {
String value;
switch(attrType.getDataType()){
case STRING:
case ENUMERATION:
value=string.substring(1, string.length()-1);
break;
default:
value=string;
}
if(attrValueLut.containsKey(value)){
return loader.attrValues.get(attrValueLut.get(value));
} else {
attrValueLut.put(value, loader.attrValues.size());
loader.attrValues.add(value);
return value;
}
}
private long stringToScale(String scale){
String cmp = scale.trim();
if("fs".equals(cmp)) return 1L;
if("ps".equals(cmp)) return 1000L;
if("ns".equals(cmp)) return 1000000L;
if("us".equals(cmp)) return 1000000000L;
if("ms".equals(cmp)) return 1000000000000L;
if("s".equals(cmp) ) return 1000000000000000L;
return 1L;
}
}
public ITx getTransaction(long txId) {
if(txCache.containsKey(txId))
return txCache.get(txId);
Tx tx = new Tx(this, txId);
txCache.put(txId, tx);
return tx;
}
}

View File

@ -1,70 +0,0 @@
/*******************************************************************************
* Copyright (c) 2012 IT Just working.
* 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:
* IT Just working - initial API and implementation
*******************************************************************************/
package com.minres.scviewer.database.text
import com.minres.scviewer.database.*
import com.minres.scviewer.database.tx.ITx
import com.minres.scviewer.database.tx.ITxAttribute
import com.minres.scviewer.database.tx.ITxRelation
class Tx implements ITx {
Long id
TxGenerator generator
TxStream stream
int concurrencyIndex
Long beginTime
Long endTime
ArrayList<ITxAttribute> attributes = new ArrayList<ITxAttribute>()
def incomingRelations =[]
def outgoingRelations =[]
Tx(int id, TxStream stream, TxGenerator generator, Long begin){
this.id=id
this.stream=stream
this.generator=generator
this.beginTime=begin
this.endTime=begin
}
@Override
public Collection<ITxRelation> getIncomingRelations() {
return incomingRelations;
}
@Override
public Collection<ITxRelation> getOutgoingRelations() {
return outgoingRelations;
}
@Override
public int compareTo(ITx o) {
def res =beginTime.compareTo(o.beginTime)
if(res!=0)
return res
else
return id.compareTo(o.id)
}
@Override
public String toString() {
return "tx#"+getId()+"["+getBeginTime()/1000000+"ns - "+getEndTime()/1000000+"ns]";
}
}

View File

@ -0,0 +1,132 @@
/*******************************************************************************
* Copyright (c) 2012 IT Just working.
* 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:
* IT Just working - initial API and implementation
*******************************************************************************/
package com.minres.scviewer.database.text;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.tx.ITx;
import com.minres.scviewer.database.tx.ITxAttribute;
import com.minres.scviewer.database.tx.ITxGenerator;
import com.minres.scviewer.database.tx.ITxRelation;
class Tx implements ITx {
private final TextDbLoader loader;
private long id;
long beginTime=-1;
long endTime=-1;
private int concurrencyIndex;
public Tx(TextDbLoader loader, ScvTx scvTx) {
this.loader=loader;
id=scvTx.id;
}
public Tx(TextDbLoader loader, long txId) {
this.loader=loader;
id=txId;
}
@Override
public Collection<ITxRelation> getIncomingRelations() {
Set<ScvRelation> rels = loader.relationsIn.get(id);
return rels.stream().map(rel -> new TxRelation(loader, rel)).collect(Collectors.toList());
}
@Override
public Collection<ITxRelation> getOutgoingRelations() {
Set<ScvRelation> rels = loader.relationsOut.get(id);
return rels.stream().map(rel -> new TxRelation(loader, rel)).collect(Collectors.toList());
}
@Override
public int compareTo(ITx o) {
int res =getBeginTime().compareTo(o.getBeginTime());
if(res!=0)
return res;
else
return getId().compareTo(o.getId());
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
return this.getScvTx().equals(((Tx) obj).getScvTx());
}
@Override
public int hashCode() {
return getScvTx().hashCode();
}
@Override
public String toString() {
return "tx#"+getId()+"["+getBeginTime()/1000000+"ns - "+getEndTime()/1000000+"ns]";
}
@Override
public Long getId() {
return getScvTx().id;
}
@Override
public IWaveform getStream() {
return loader.txStreams.get(getScvTx().streamId);
}
@Override
public ITxGenerator getGenerator() {
return loader.txGenerators.get(getScvTx().generatorId);
}
@Override
public Long getBeginTime() {
if(beginTime<0) beginTime=getScvTx().beginTime;
return beginTime;
}
@Override
public Long getEndTime() {
if(endTime<0) endTime=getScvTx().endTime;
return endTime;
}
void setEndTime(Long time) {
getScvTx().endTime=time;
}
@Override
public int getConcurrencyIndex() {
return concurrencyIndex;
}
void setConcurrencyIndex(int idx) {
concurrencyIndex=idx;
}
@Override
public List<ITxAttribute> getAttributes() {
return getScvTx().attributes;
}
private ScvTx getScvTx() {
return loader.transactions.get(id);
}
}

View File

@ -8,37 +8,28 @@
* Contributors:
* IT Just working - initial API and implementation
*******************************************************************************/
package com.minres.scviewer.database.text
package com.minres.scviewer.database.text;
import java.io.Serializable;
import com.minres.scviewer.database.AssociationType;
import com.minres.scviewer.database.DataType;
import com.minres.scviewer.database.tx.ITxAttribute
import com.minres.scviewer.database.tx.ITxAttributeType
import com.minres.scviewer.database.tx.ITxAttribute;
class TxAttribute implements ITxAttribute{
public class TxAttribute implements ITxAttribute, Serializable {
TxAttributeType attributeType
/**
*
*/
private static final long serialVersionUID = 4767726016651807152L;
def value
TxAttribute(String name, DataType dataType, AssociationType type, value){
attributeType = TxAttributeTypeFactory.instance.getAttrType(name, dataType, type)
switch(dataType){
case DataType.STRING:
case DataType.ENUMERATION:
this.value=value[1..-2]
break;
default:
this.value=value
}
}
private final TxAttributeType attributeType;
TxAttribute(TxAttributeType other){
attributeType=other
}
private final String value;
TxAttribute(TxAttributeType other, value){
this(other.name, other.dataType, other.type, value)
TxAttribute(TxAttributeType type, String value){
this.attributeType=type;
this.value=value;
}
@Override
@ -48,12 +39,17 @@ class TxAttribute implements ITxAttribute{
@Override
public AssociationType getType() {
attributeType.type;
return attributeType.getType();
}
@Override
public DataType getDataType() {
attributeType.dataType;
return attributeType.getDataType();
}
@Override
public Object getValue() {
return value;
}
}

View File

@ -8,24 +8,44 @@
* Contributors:
* IT Just working - initial API and implementation
*******************************************************************************/
package com.minres.scviewer.database.text
package com.minres.scviewer.database.text;
import java.io.Serializable;
import com.minres.scviewer.database.AssociationType;
import com.minres.scviewer.database.DataType;
import com.minres.scviewer.database.tx.ITxAttributeType
import com.minres.scviewer.database.tx.ITxAttributeType;
class TxAttributeType implements ITxAttributeType {
String name
DataType dataType
AssociationType type
class TxAttributeType implements ITxAttributeType, Serializable {
/**
*
*/
private static final long serialVersionUID = 7159721937208946828L;
static TxAttributeType getAttrType(String name, DataType dataType, AssociationType type){
TxAttributeTypeFactory.instance.getAttrType(name, dataType, type)
}
private String name;
private DataType dataType;
private AssociationType type;
TxAttributeType(String name, DataType dataType, AssociationType type){
this.name=name
this.dataType=dataType
this.type=type
this.name=name;
this.dataType=dataType;
this.type=type;
}
@Override
public String getName() {
return name;
}
@Override
public DataType getDataType() {
return dataType;
}
@Override
public AssociationType getType() {
return type;
}
}

View File

@ -1,38 +0,0 @@
/*******************************************************************************
* Copyright (c) 2012 IT Just working.
* 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:
* IT Just working - initial API and implementation
*******************************************************************************/
package com.minres.scviewer.database.text
import com.minres.scviewer.database.AssociationType;
import com.minres.scviewer.database.DataType
import com.minres.scviewer.database.tx.ITxAttribute
import com.minres.scviewer.database.tx.ITxAttributeType
class TxAttributeTypeFactory {
static final TxAttributeTypeFactory instance = new TxAttributeTypeFactory()
def attributes = [:]
private TxAttributeTypeFactory() {
TxAttributeTypeFactory.metaClass.constructor = {-> instance }
}
ITxAttributeType getAttrType(String name, DataType dataType, AssociationType type){
def key = name+":"+dataType.toString()
ITxAttributeType res
if(attributes.containsKey(key)){
res=attributes[key]
} else {
res=new TxAttributeType(name, dataType, type)
attributes[key]=res
}
return res
}
}

View File

@ -7,21 +7,16 @@ import com.minres.scviewer.database.tx.ITxEvent;
class TxEvent implements ITxEvent {
final TextDbLoader loader;
final EventKind kind;
final ITx transaction;
final Long transaction;
final Long time;
TxEvent(EventKind kind, ITx transaction) {
super();
this.kind = kind;
this.transaction = transaction;
this.time = kind==EventKind.BEGIN?transaction.getBeginTime():transaction.getEndTime();
}
public TxEvent(EventKind kind, ITx transaction, Long time) {
super();
TxEvent(TextDbLoader loader, EventKind kind, Long transaction, Long time) {
this.loader=loader;
this.kind = kind;
this.transaction = transaction;
this.time = time;
@ -30,13 +25,13 @@ class TxEvent implements ITxEvent {
@Override
public
ITxEvent duplicate() throws CloneNotSupportedException {
return new TxEvent(kind, transaction, time);
return new TxEvent(loader, kind, transaction, time);
}
@Override
public
String toString() {
return kind.toString()+"@"+time+" of tx #"+transaction.getId();
return kind.toString()+"@"+time+" of tx #"+transaction;
}
@Override
@ -56,6 +51,6 @@ class TxEvent implements ITxEvent {
@Override
public ITx getTransaction() {
return transaction;
return loader.getTransaction(transaction);
}
}

View File

@ -1,50 +0,0 @@
/*******************************************************************************
* Copyright (c) 2012 IT Just working.
* 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:
* IT Just working - initial API and implementation
*******************************************************************************/
package com.minres.scviewer.database.text
import java.util.ArrayList;
import java.util.List;
import com.minres.scviewer.database.IWaveform
import com.minres.scviewer.database.tx.ITx
import com.minres.scviewer.database.tx.ITxAttribute
import com.minres.scviewer.database.tx.ITxAttributeType
import com.minres.scviewer.database.tx.ITxGenerator
class TxGenerator implements ITxGenerator{
Long id
IWaveform stream
String name
Boolean active = false
ArrayList<ITx> transactions=[]
ArrayList<ITxAttributeType> begin_attrs = []
int begin_attrs_idx = 0
ArrayList<ITxAttributeType> end_attrs= []
int end_attrs_idx = 0
TxGenerator(int id, TxStream stream, name){
this.id=id
this.stream=stream
this.name=name
}
IWaveform getStream(){
return stream;
}
List<ITx> getTransactions(){
return transactions
}
Boolean isActive() {return active};
}

View File

@ -0,0 +1,63 @@
/*******************************************************************************
* Copyright (c) 2012 IT Just working.
* 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:
* IT Just working - initial API and implementation
*******************************************************************************/
package com.minres.scviewer.database.text;
import java.util.ArrayList;
import java.util.List;
import com.minres.scviewer.database.HierNode;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.tx.ITxGenerator;
class TxGenerator extends HierNode implements ITxGenerator {
Long id;
IWaveform stream;
Boolean active = false;
List<TxAttributeType> beginAttrs = new ArrayList<>();
List<TxAttributeType> endAttrs= new ArrayList<>();
TxGenerator(Long id, TxStream stream, String name){
super(name, stream);
this.id=id;
this.stream=stream;
}
@Override
public Long getId() {
return id;
}
@Override
public IWaveform getStream(){
return stream;
}
@Override
public String getName() {
return name;
}
public List<TxAttributeType> getBeginAttrs() {
return beginAttrs;
}
public List<TxAttributeType> getEndAttrs() {
return endAttrs;
}
Boolean isActive() {return active;}
}

View File

@ -5,31 +5,29 @@ import com.minres.scviewer.database.tx.ITx;
import com.minres.scviewer.database.tx.ITxRelation;
class TxRelation implements ITxRelation {
final Tx source;
final TextDbLoader loader;
final Tx target;
final ScvRelation scvRelation;
final RelationType relationType;
public TxRelation(RelationType relationType, Tx source, Tx target) {
this.source = source;
this.target = target;
this.relationType = relationType;
public TxRelation(TextDbLoader loader, ScvRelation scvRelation) {
this.loader = loader;
this.scvRelation = scvRelation;
}
@Override
public RelationType getRelationType() {
return relationType;
return scvRelation.relationType;
}
@Override
public ITx getSource() {
return source;
return loader.getTransaction(scvRelation.source);
}
@Override
public ITx getTarget() {
return target;
return loader.getTransaction(scvRelation.target);
}
}

View File

@ -1,135 +0,0 @@
/*******************************************************************************
* Copyright (c) 2012 IT Just working.
* 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:
* IT Just working - initial API and implementation
*******************************************************************************/
package com.minres.scviewer.database.text
import java.beans.PropertyChangeListener;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.NavigableMap;
import java.util.Map.Entry
import org.mapdb.Serializer
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.IWaveformDb
import com.minres.scviewer.database.WaveformType
import com.minres.scviewer.database.tx.ITx
import com.minres.scviewer.database.tx.ITxEvent
import com.minres.scviewer.database.tx.ITxGenerator
import com.minres.scviewer.database.EventKind
import com.minres.scviewer.database.HierNode;
import com.minres.scviewer.database.IEvent
import com.minres.scviewer.database.IHierNode
class TxStream extends HierNode implements IWaveform {
Long id
IWaveformDb database
String fullName
def generators = []
int maxConcurrency
private TreeMap<Long, IEvent[]> events
TxStream(TextDbLoader loader, int id, String name, String kind){
super(name)
this.id=id
this.database=loader.db
this.fullName=name
this.maxConcurrency=0
//events = new TreeMap<Long, List<ITxEvent>>()
events = loader.mapDb.treeMap(name).keySerializer(Serializer.LONG).createOrOpen();
}
List<ITxGenerator> getGenerators(){
return generators as List<ITxGenerator>
}
@Override
public IWaveformDb getDb() {
return database
}
@Override
public int getWidth() {
if(!maxConcurrency){
generators.each {TxGenerator generator ->
generator.transactions.each{ Tx tx ->
putEvent(new TxEvent(EventKind.BEGIN, tx))
putEvent(new TxEvent(EventKind.END, tx))
}
}
def rowendtime = [0]
events.keySet().each{long time ->
def value=events.get(time)
def starts=value.findAll{IEvent event ->event.kind==EventKind.BEGIN}
starts.each {ITxEvent event ->
Tx tx = event.transaction
def rowIdx = 0
for(rowIdx=0; rowIdx<rowendtime.size() && rowendtime[rowIdx]>tx.beginTime; rowIdx++);
if(rowendtime.size<=rowIdx)
rowendtime<<tx.endTime
else
rowendtime[rowIdx]=tx.endTime
tx.concurrencyIndex=rowIdx
}
}
maxConcurrency=rowendtime.size()
}
return maxConcurrency
}
private putEvent(ITxEvent event){
if(!events.containsKey(event.time))
events.put(event.time, [event] as IEvent[])
else {
def entries = events[event.time] as List
entries<<event
events.put(event.time, entries as IEvent[])
}
}
@Override
public NavigableMap<Long, IEvent[]> getEvents() {
return events;
}
@Override
public IEvent[] getEventsAtTime(Long time) {
return events.get(time);
}
@Override
public boolean isSame(IWaveform other) {
return(other instanceof TxStream && this.getId()==other.getId());
}
@Override
public IEvent[] getEventsBeforeTime(Long time) {
Entry<Long, IEvent[]> e = events.floorEntry(time);
if(e==null)
return null;
else
return events.floorEntry(time).getValue();
}
@Override
public WaveformType getType() {
return WaveformType.TRANSACTION;
}
}

View File

@ -0,0 +1,138 @@
/*******************************************************************************
* Copyright (c) 2012 IT Just working.
* 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:
* IT Just working - initial API and implementation
*******************************************************************************/
package com.minres.scviewer.database.text;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.TreeMap;
import com.minres.scviewer.database.EventKind;
import com.minres.scviewer.database.HierNode;
import com.minres.scviewer.database.IEvent;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.WaveformType;
import com.minres.scviewer.database.tx.ITxEvent;
import com.minres.scviewer.database.tx.ITxGenerator;
class TxStream extends HierNode implements IWaveform {
private Long id;
private TextDbLoader loader;
final String kind;
private int maxConcurrency = 0;
private int concurrency = 0;
boolean concurrencyCalculated = false;
void setConcurrency(int concurrency) {
this.concurrency = concurrency;
if(concurrency>maxConcurrency)
maxConcurrency = concurrency;
}
int getConcurrency() {
return this.concurrency;
}
TreeMap<Long, IEvent[]> events = new TreeMap<>();
TxStream(TextDbLoader loader, Long id, String name, String kind){
super(name);
this.id=id;
this.loader=loader;
this.kind=kind;
}
List<ITxGenerator> getGenerators(){
return new ArrayList<>(loader.txGenerators.values());
}
@Override
public int getWidth() {
return maxConcurrency;
}
public void addEvent(ITxEvent evt) {
if(!events.containsKey(evt.getTime()))
events.put(evt.getTime(), new IEvent[] {evt});
else {
IEvent[] evts = events.get(evt.getTime());
IEvent[] newEvts = Arrays.copyOf(evts, evts.length+1);
newEvts[evts.length]=evt;
events.put(evt.getTime(), newEvts);
}
}
@Override
public NavigableMap<Long, IEvent[]> getEvents() {
if(!concurrencyCalculated) calculateConcurrency();
return events;
}
@Override
public IEvent[] getEventsAtTime(Long time) {
if(!concurrencyCalculated) calculateConcurrency();
return events.get(time);
}
@Override
public boolean isSame(IWaveform other) {
return(other instanceof TxStream && this.getId().equals(other.getId()));
}
@Override
public IEvent[] getEventsBeforeTime(Long time) {
if(!concurrencyCalculated)
calculateConcurrency();
Entry<Long, IEvent[]> e = events.floorEntry(time);
if(e==null)
return new IEvent[] {};
else
return events.floorEntry(time).getValue();
}
@Override
public WaveformType getType() {
return WaveformType.TRANSACTION;
}
@Override
public Long getId() {
return id;
}
synchronized void calculateConcurrency() {
if(concurrencyCalculated) return;
ArrayList<Long> rowendtime = new ArrayList<>();
events.entrySet().stream().forEach( entry -> {
IEvent[] values = entry.getValue();
Arrays.asList(values).stream().filter(e->e.getKind()==EventKind.BEGIN).forEach(evt -> {
Tx tx = (Tx) ((TxEvent)evt).getTransaction();
int rowIdx = 0;
for(; rowIdx<rowendtime.size() && rowendtime.get(rowIdx)>tx.getBeginTime(); rowIdx++);
if(rowendtime.size()<=rowIdx)
rowendtime.add(tx.getEndTime());
else
rowendtime.set(rowIdx, tx.getEndTime());
tx.setConcurrencyIndex(rowIdx);
});
});
concurrencyCalculated=true;
}
}

View File

@ -22,6 +22,7 @@ import org.eclipse.swt.widgets.Control;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.RelationType;
import com.minres.scviewer.database.RelationTypeFactory;
public interface IWaveformView extends PropertyChangeListener, ISelectionProvider{
@ -29,7 +30,7 @@ public interface IWaveformView extends PropertyChangeListener, ISelectionProvide
String MARKER_PROPERTY = "marker_time";
public static final RelationType NEXT_PREV_IN_STREAM = RelationType.create("Prev/Next in stream");
public static final RelationType NEXT_PREV_IN_STREAM = RelationTypeFactory.create("Prev/Next in stream");
public void addSelectionChangedListener(ISelectionChangedListener listener);

View File

@ -84,17 +84,20 @@ public class StreamPainter extends TrackPainter{
NavigableMap<Long, IEvent[]> entries = stream.getEvents().subMap(firstTx.getKey(), true, lastTx.getKey(), true);
boolean highlighed=false;
proj.setForeground(this.waveCanvas.styleProvider.getColor(WaveformColors.LINE));
long selectedId=waveCanvas.currentSelection!=null? waveCanvas.currentSelection.getId():-1;
for(Entry<Long, IEvent[]> entry: entries.entrySet())
for(IEvent evt:entry.getValue()){
ITxEvent txEvent = (ITxEvent) evt;
if(txEvent.getKind()==EventKind.BEGIN)
seenTx.add(txEvent.getTransaction());
if(txEvent.getKind()==EventKind.END){
ITx tx = txEvent.getTransaction();
highlighed|=waveCanvas.currentSelection!=null && waveCanvas.currentSelection.equals(tx);
drawTx(proj, area, tx, false);
ITx tx = ((ITxEvent) evt).getTransaction();
highlighed|=selectedId==tx.getId();
switch(evt.getKind()) {
case BEGIN:
seenTx.add(tx);
break;
case END:
seenTx.remove(tx);
case SINGLE:
drawTx(proj, area, tx, false);
break;
}
}
for(ITx tx:seenTx){
@ -164,7 +167,8 @@ public class StreamPainter extends TrackPainter{
for(IEvent evt:firstTx.getValue()){
if(evt instanceof ITxEvent) {
ITx tx=((ITxEvent)evt).getTransaction();
if(evt.getKind()==EventKind.BEGIN && tx.getConcurrencyIndex()==lane && tx.getBeginTime()<=timePoint && tx.getEndTime()>=timePoint){
if((evt.getKind()==EventKind.BEGIN || evt.getKind()==EventKind.SINGLE)&&
tx.getConcurrencyIndex()==lane && tx.getBeginTime()<=timePoint && tx.getEndTime()>=timePoint){
return ((ITxEvent)evt).getTransaction();
}
}
@ -175,7 +179,8 @@ public class StreamPainter extends TrackPainter{
for(IEvent evt:firstTx.getValue()){
if(evt instanceof ITxEvent) {
ITx tx=((ITxEvent)evt).getTransaction();
if(evt.getKind()==EventKind.BEGIN && tx.getConcurrencyIndex()==lane && tx.getBeginTime()<=timePointHigh && tx.getEndTime()>=timePoint){
if((evt.getKind()==EventKind.BEGIN || evt.getKind()==EventKind.SINGLE) &&
tx.getConcurrencyIndex()==lane && tx.getBeginTime()<=timePointHigh && tx.getEndTime()>=timePoint){
return ((ITxEvent)evt).getTransaction();
}
}

View File

@ -116,9 +116,9 @@ public class WaveformView implements IWaveformView {
final WaveformCanvas waveformCanvas;
final ToolTipHandler toolTipHandler;
private boolean revealSelected=false;
private Composite top;
protected ObservableList<TrackEntry> streams;
@ -128,13 +128,13 @@ public class WaveformView implements IWaveformView {
private int tracksVerticalHeight;
private TreeMap<Integer, TrackEntry> trackVerticalOffset;
private IWaveformStyleProvider styleProvider;
protected TrackEntry lastClickedEntry;
protected MouseListener nameValueMouseListener = new MouseAdapter() {
@Override
public void mouseDown(MouseEvent e) {
if (e.button == 1) {
@ -146,7 +146,7 @@ public class WaveformView implements IWaveformView {
if(topMenu!=null) topMenu.setVisible(true);
}
}
@Override
public void mouseUp(MouseEvent e) {
if (e.button == 1) {
@ -168,7 +168,7 @@ public class WaveformView implements IWaveformView {
}
}
};
class WaveformMouseListener implements PaintListener, Listener {
Point start;
Point end;
@ -178,13 +178,13 @@ public class WaveformView implements IWaveformView {
@Override
public void paintControl(PaintEvent e) {
if(down) {
GC gc = e.gc;
gc.setAlpha(128);
int minX = Math.min(start.x, end.x);
int width = Math.max(start.x, end.x) - minX;
int yTop = waveformCanvas.getRulerHeight();
int yBottom = waveformCanvas.getSize().y;
gc.fillRectangle(minX, yTop, width,yBottom);
GC gc = e.gc;
gc.setAlpha(128);
int minX = Math.min(start.x, end.x);
int width = Math.max(start.x, end.x) - minX;
int yTop = waveformCanvas.getRulerHeight();
int yBottom = waveformCanvas.getSize().y;
gc.fillRectangle(minX, yTop, width,yBottom);
}
}
@ -243,7 +243,7 @@ public class WaveformView implements IWaveformView {
asyncUpdate(e.widget);
}
}
protected long snapOffsetToEvent(Point p) {
long time= waveformCanvas.getTimeForOffset(p.x);
long scaling=5*waveformCanvas.getScaleFactor();
@ -304,7 +304,7 @@ public class WaveformView implements IWaveformView {
default:
break;
}
}
}
@ -312,7 +312,7 @@ public class WaveformView implements IWaveformView {
public WaveformView(Composite parent, IWaveformStyleProvider styleProvider) {
this.styleProvider=styleProvider;
pcs=new PropertyChangeSupport(this);
trackVerticalOffset = new TreeMap<>();
@ -326,7 +326,7 @@ public class WaveformView implements IWaveformView {
SashForm topSash = new SashForm(top, SWT.SMOOTH);
topSash.setBackground(topSash.getDisplay().getSystemColor(SWT.COLOR_GRAY));
Composite namePane = new Composite(topSash, SWT.NONE);
Composite rightPane = new Composite(topSash, SWT.NONE);
rightPane.setLayout(new FillLayout(SWT.HORIZONTAL));
@ -339,7 +339,7 @@ public class WaveformView implements IWaveformView {
// create the name pane
createTextPane(namePane, "Name");
namePaneHeader= namePane.getChildren()[0];
namePane.setBackground(SWTResourceManager.getColor(SWT.COLOR_WIDGET_BACKGROUND));
@ -373,7 +373,7 @@ public class WaveformView implements IWaveformView {
nameListScrolled.setContent(nameList);
createTextPane(valuePane, "Value");
valuePane.setBackground(SWTResourceManager.getColor(SWT.COLOR_WIDGET_BACKGROUND));
valueListScrolled = new ScrolledComposite(valuePane, SWT.H_SCROLL | SWT.V_SCROLL);
valueListScrolled.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
@ -410,7 +410,7 @@ public class WaveformView implements IWaveformView {
waveformCanvas.addListener(SWT.MouseUp,waveformMouseListener);
waveformCanvas.addListener(SWT.MouseMove,waveformMouseListener);
waveformCanvas.addListener(SWT.MouseWheel, waveformMouseListener);
nameListScrolled.getVerticalBar().addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
@ -446,7 +446,7 @@ public class WaveformView implements IWaveformView {
createStreamDropTarget(valueList);
createWaveformDragSource(waveformCanvas);
createWaveformDropTarget(waveformCanvas);
toolTipHandler = new ToolTipHandler(parent.getShell());
toolTipHandler.activateHoverHelp(waveformCanvas);
}
@ -478,10 +478,10 @@ public class WaveformView implements IWaveformView {
if ("size".equals(pce.getPropertyName()) || "content".equals(pce.getPropertyName())) {
if(revealSelected) {
waveformCanvas.getDisplay().asyncExec(() ->{
update();
currentWaveformSelection.stream().forEach(e -> waveformCanvas.reveal(e.waveform));
valueList.redraw();
nameList.redraw();
update();
currentWaveformSelection.stream().forEach(e -> waveformCanvas.reveal(e.waveform));
valueList.redraw();
nameList.redraw();
});
revealSelected=false;
} else
@ -574,11 +574,11 @@ public class WaveformView implements IWaveformView {
do {
for(IEvent evt:firstTx.getValue()){
if(evt instanceof ITxEvent) {
ITx tx=((ITxEvent)evt).getTransaction();
if(evt.getKind()==EventKind.BEGIN && tx.getBeginTime()<=time && tx.getEndTime()>=time){
if(resultsList[tx.getConcurrencyIndex()]==null)
resultsList[tx.getConcurrencyIndex()]= ((ITxEvent)evt).getTransaction();
}
ITx tx=((ITxEvent)evt).getTransaction();
if((evt.getKind()==EventKind.BEGIN || evt.getKind()==EventKind.SINGLE) && tx.getBeginTime()<=time && tx.getEndTime()>=time){
if(resultsList[tx.getConcurrencyIndex()]==null)
resultsList[tx.getConcurrencyIndex()]= ((ITxEvent)evt).getTransaction();
}
}
}
firstTx=entry.waveform.getEvents().lowerEntry(firstTx.getKey());
@ -600,8 +600,8 @@ public class WaveformView implements IWaveformView {
valueListScrolled.setMinSize(width, tracksVerticalHeight);
valueListScrolled.redraw();
}
private boolean isArrayFull(Object[] array){
for(Object o:array){
if(o==null) return false;
@ -691,7 +691,7 @@ public class WaveformView implements IWaveformView {
public void addToSelection(ISelection selection, boolean showIfNeeded) {
setSelection(selection, true, showIfNeeded);
}
public void setSelection(ISelection selection, boolean add, boolean addIfNeeded) {
boolean selectionChanged = false;
currentWaveformSelection.forEach(e->e.selected=false);
@ -703,7 +703,7 @@ public class WaveformView implements IWaveformView {
} else {
if(!add) currentWaveformSelection.clear();
for(Object sel:((IStructuredSelection) selection).toArray()){
if (sel instanceof ITx && currentTxSelection != sel){
if (sel instanceof ITx){
ITx txSel = (ITx) sel;
TrackEntry trackEntry = getEntryForStream(txSel.getStream());
if(trackEntry==null && addIfNeeded){
@ -711,6 +711,8 @@ public class WaveformView implements IWaveformView {
streams.add(trackEntry);
}
currentTxSelection = txSel;
currentWaveformSelection.clear();
currentWaveformSelection.add(trackEntry);
selectionChanged = true;
} else if (sel instanceof TrackEntry && !currentWaveformSelection.contains(sel)) {
currentWaveformSelection.add((TrackEntry)sel);
@ -754,12 +756,12 @@ public class WaveformView implements IWaveformView {
moveSelection(direction, NEXT_PREV_IN_STREAM) ;
else {
if(currentWaveformSelection.size()==1) {
int idx = streams.indexOf(currentWaveformSelection.get(0));
if(direction==GotoDirection.UP && idx>0) {
setSelection(new StructuredSelection(streams.get(idx-1)));
} else if(direction==GotoDirection.DOWN && idx<(streams.size()-1)) {
setSelection(new StructuredSelection(streams.get(idx+1)));
}
int idx = streams.indexOf(currentWaveformSelection.get(0));
if(direction==GotoDirection.UP && idx>0) {
setSelection(new StructuredSelection(streams.get(idx-1)));
} else if(direction==GotoDirection.DOWN && idx<(streams.size()-1)) {
setSelection(new StructuredSelection(streams.get(idx+1)));
}
}
}
}
@ -769,32 +771,29 @@ public class WaveformView implements IWaveformView {
*/
@Override
public void moveSelection(GotoDirection direction, RelationType relationType) {
TrackEntry selectedWaveform=null;
if(currentTxSelection!=null)
selectedWaveform = getEntryForStream(currentTxSelection.getStream());
else if(currentWaveformSelection.size()!=1) return;
if(selectedWaveform==null)
selectedWaveform = currentWaveformSelection.get(1);
if (selectedWaveform!=null && selectedWaveform.waveform.getType()==WaveformType.TRANSACTION && currentTxSelection!=null) {
if(currentWaveformSelection.size() !=1 && currentTxSelection==null) return;
TrackEntry selectedWaveform=currentWaveformSelection.size() == 1?
currentWaveformSelection.get(0) : getEntryForStream(currentTxSelection.getStream());
if(selectedWaveform.waveform.getType()==WaveformType.TRANSACTION && currentTxSelection!=null) {
if(relationType.equals(IWaveformView.NEXT_PREV_IN_STREAM)){
ITx transaction = null;
if (direction == GotoDirection.NEXT) {
ITxEvent[] thisEntryList = (ITxEvent[]) selectedWaveform.waveform.getEvents().get(currentTxSelection.getBeginTime());
IEvent[] eventsList = selectedWaveform.waveform.getEvents().get(currentTxSelection.getBeginTime());
boolean meFound=false;
for (ITxEvent evt : thisEntryList) {
if (evt.getKind() == EventKind.BEGIN) {
for (IEvent evt : eventsList) {
if (evt instanceof ITxEvent && evt.getKind() == EventKind.BEGIN || evt.getKind()==EventKind.SINGLE) {
if(meFound){
transaction = evt.getTransaction();
transaction = ((ITxEvent)evt).getTransaction();
break;
}
meFound|= evt.getTransaction().equals(currentTxSelection);
meFound|= ((ITxEvent)evt).getTransaction().equals(currentTxSelection);
}
}
if (transaction == null){
Entry<Long, IEvent[]> entry = selectedWaveform.waveform.getEvents().higherEntry(currentTxSelection.getBeginTime());
if (entry != null) do {
for (IEvent evt : entry.getValue()) {
if (evt instanceof ITxEvent && evt.getKind() == EventKind.BEGIN) {
if (evt instanceof ITxEvent && (evt.getKind() == EventKind.BEGIN || evt.getKind()==EventKind.SINGLE)) {
transaction = ((ITxEvent)evt).getTransaction();
break;
}
@ -804,10 +803,10 @@ public class WaveformView implements IWaveformView {
} while (entry != null && transaction == null);
}
} else if (direction == GotoDirection.PREV) {
IEvent[] thisEntryList = selectedWaveform.waveform.getEvents().get(currentTxSelection.getBeginTime());
IEvent[] eventsList = selectedWaveform.waveform.getEvents().get(currentTxSelection.getBeginTime());
boolean meFound=false;
for (IEvent evt : Lists.reverse(Arrays.asList(thisEntryList))) {
if (evt instanceof ITxEvent && evt.getKind() == EventKind.BEGIN) {
for (IEvent evt : Lists.reverse(Arrays.asList(eventsList))) {
if (evt instanceof ITxEvent && (evt.getKind() == EventKind.BEGIN || evt.getKind()==EventKind.SINGLE)) {
if(meFound){
transaction = ((ITxEvent)evt).getTransaction();
break;
@ -817,31 +816,33 @@ public class WaveformView implements IWaveformView {
}
if (transaction == null){
Entry<Long, IEvent[]> entry = selectedWaveform.waveform.getEvents().lowerEntry(currentTxSelection.getBeginTime());
if (entry != null)
do {
for (IEvent evt : Lists.reverse(Arrays.asList(thisEntryList))) {
if (evt instanceof ITxEvent && evt.getKind() == EventKind.BEGIN) {
transaction = ((ITxEvent)evt).getTransaction();
break;
}
if (entry != null) do {
for (IEvent evt : Lists.reverse(Arrays.asList(entry.getValue()))) {
if (evt instanceof ITxEvent && (evt.getKind() == EventKind.BEGIN || evt.getKind()==EventKind.SINGLE)) {
transaction = ((ITxEvent)evt).getTransaction();
break;
}
if (transaction == null)
entry = selectedWaveform.waveform.getEvents().lowerEntry(entry.getKey());
} while (entry != null && transaction == null);
}
if (transaction == null)
entry = selectedWaveform.waveform.getEvents().lowerEntry(entry.getKey());
} while (entry != null && transaction == null);
}
}
if (transaction != null) {
setSelection(new StructuredSelection(transaction));
}
} else {
ITxRelation tx = null;
if (direction == GotoDirection.NEXT) {
Collection<ITxRelation> outRel=currentTxSelection.getOutgoingRelations();
ITxRelation tx = selectTxToNavigateTo(outRel, relationType, true);
if(tx!=null) setSelection(new StructuredSelection(tx.getTarget()), true);
tx = selectTxToNavigateTo(outRel, relationType, true);
if(tx!=null)
setSelection(new StructuredSelection(tx.getTarget()), true);
} else if (direction == GotoDirection.PREV) {
Collection<ITxRelation> inRel=currentTxSelection.getIncomingRelations();
ITxRelation tx = selectTxToNavigateTo(inRel, relationType, false);
if(tx!=null) setSelection(new StructuredSelection(tx.getSource()), true);
tx = selectTxToNavigateTo(inRel, relationType, false);
if(tx!=null)
setSelection(new StructuredSelection(tx.getSource()), true);
}
}
}
@ -863,7 +864,7 @@ public class WaveformView implements IWaveformView {
}
}
}
private boolean streamsVisible(ITxRelation relation) {
final IWaveform src = relation.getSource().getStream();
final IWaveform tgt = relation.getTarget().getStream();
@ -1175,7 +1176,7 @@ public class WaveformView implements IWaveformView {
public List<Object> getElementsAt(Point pt){
return waveformCanvas.getElementsAt(pt);
}
private void createWaveformDragSource(final Canvas canvas) {
Transfer[] types = new Transfer[] { LocalSelectionTransfer.getTransfer() };
DragSource dragSource = new DragSource(canvas, DND.DROP_MOVE);
@ -1201,15 +1202,15 @@ public class WaveformView implements IWaveformView {
}
}
});
// int style = SWT.MULTI | SWT.WRAP | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER;
// final StyledText text = new StyledText(waveformCanvas, style);
// text.setText("Dragging");
// dragSource.setDragSourceEffect(new DragSourceEffect(text) {
// @Override
// public void dragStart(DragSourceEvent event) {
// event.image = waveformCanvas.getDisplay().getSystemImage(SWT.ICON_WARNING);
// }
// });
// int style = SWT.MULTI | SWT.WRAP | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER;
// final StyledText text = new StyledText(waveformCanvas, style);
// text.setText("Dragging");
// dragSource.setDragSourceEffect(new DragSourceEffect(text) {
// @Override
// public void dragStart(DragSourceEvent event) {
// event.image = waveformCanvas.getDisplay().getSystemImage(SWT.ICON_WARNING);
// }
// });
}
private void createWaveformDropTarget(final Canvas canvas) {
@ -1348,7 +1349,7 @@ public class WaveformView implements IWaveformView {
origin.x=(int) (-time/waveformCanvas.getScaleFactorPow10());
waveformCanvas.setOrigin(origin);
}
@Override
public void scrollHorizontal(int percent) {
if(percent<-100) percent=-100;
@ -1365,7 +1366,7 @@ public class WaveformView implements IWaveformView {
updateValueList();
});
}
/// probably not the way it should be done
@Override
public void addDisposeListener(DisposeListener listener ) {

View File

@ -41,9 +41,6 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
/** The Constant TIME_RES. */
private static final Long TIME_RES = 1000L; // ps
/** The db. */
private IWaveformDb db;
/** The module stack. */
private ArrayDeque<String> moduleStack;
@ -71,8 +68,8 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
@SuppressWarnings("unchecked")
@Override
public boolean load(IWaveformDb db, File file) throws InputFormatException {
dispose();
if(file.isDirectory() || !file.exists()) return false;
this.db=db;
this.maxTime=0;
boolean res = false;
try {
@ -114,6 +111,11 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
return true;
}
public void dispose() {
moduleStack=null;
signals=null;
}
/* (non-Javadoc)
* @see com.minres.scviewer.database.ITrDb#getMaxTime()
*/
@ -159,10 +161,10 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
String netName = moduleStack.isEmpty()? name: moduleStack.peek()+"."+name;
int id = signals.size();
if(width==0) {
signals.add( i<0 ? new VCDSignal<DoubleVal>(db, id, netName, width) :
signals.add( i<0 ? new VCDSignal<DoubleVal>(id, netName, width) :
new VCDSignal<DoubleVal>((VCDSignal<DoubleVal>)signals.get(i), id, netName));
} else if(width>0){
signals.add( i<0 ? new VCDSignal<BitVector>(db, id, netName, width) :
signals.add( i<0 ? new VCDSignal<BitVector>(id, netName, width) :
new VCDSignal<BitVector>((VCDSignal<BitVector>)signals.get(i), id, netName));
}
return id;

View File

@ -17,7 +17,6 @@ import java.util.TreeMap;
import com.minres.scviewer.database.HierNode;
import com.minres.scviewer.database.IEvent;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.IWaveformDb;
import com.minres.scviewer.database.WaveformType;
public class VCDSignal<T extends IEvent> extends HierNode implements IWaveform {
@ -28,21 +27,18 @@ public class VCDSignal<T extends IEvent> extends HierNode implements IWaveform {
private final int width;
private IWaveformDb db;
private NavigableMap<Long, IEvent[]> values;
public VCDSignal(IWaveformDb db, String name) {
this(db, 0, name, 1);
public VCDSignal(String name) {
this(0, name, 1);
}
public VCDSignal(IWaveformDb db, int id, String name) {
this(db, id,name,1);
public VCDSignal(int id, String name) {
this(id,name,1);
}
public VCDSignal(IWaveformDb db, int id, String name, int width) {
public VCDSignal(int id, String name, int width) {
super(name);
this.db=db;
fullName=name;
this.id=id;
this.width=width;
@ -55,7 +51,6 @@ public class VCDSignal<T extends IEvent> extends HierNode implements IWaveform {
this.id=id;
this.width=o.width;
this.values=o.values;
this.db=o.getDb();
}
@Override
@ -72,11 +67,6 @@ public class VCDSignal<T extends IEvent> extends HierNode implements IWaveform {
return id;
}
@Override
public IWaveformDb getDb() {
return db;
}
public void addSignalChange(Long time, T value){
if(values.containsKey(time)) {
IEvent[] oldV = values.get(time);

View File

@ -8,5 +8,4 @@
<relativePath>../..</relativePath>
</parent>
<packaging>eclipse-plugin</packaging>
<version>2.0.0-SNAPSHOT</version>
</project>

View File

@ -16,8 +16,6 @@ public interface IWaveform extends IHierNode {
public Long getId();
public IWaveformDb getDb();
public boolean isSame(IWaveform other);
public NavigableMap<Long, IEvent[]> getEvents();

View File

@ -14,7 +14,7 @@ import java.io.File;
import java.util.Collection;
public interface IWaveformDbLoader {
public boolean load(IWaveformDb db, File inp) throws InputFormatException;
public Long getMaxTime();
@ -23,4 +23,5 @@ public interface IWaveformDbLoader {
public Collection<RelationType> getAllRelationTypes() ;
public void dispose();
}

View File

@ -10,26 +10,17 @@
*******************************************************************************/
package com.minres.scviewer.database;
import java.util.HashMap;
import java.io.Serializable;
public class RelationType implements Serializable {
/**
*
*/
private static final long serialVersionUID = 6394859077558971735L;
public class RelationType {
private static HashMap<String, RelationType> registry = new HashMap<>();
private String name;
public static RelationType create(String name){
if(registry.containsKey(name)){
return registry.get(name);
}else{
RelationType relType = new RelationType(name);
registry.put(name, relType);
return relType;
}
}
private RelationType(String name) {
RelationType(String name) {
super();
this.name = name;
}
@ -53,6 +44,9 @@ public class RelationType {
@Override
public boolean equals(Object obj) {
return name.equals(obj);
if(obj instanceof RelationType)
return name.equals(((RelationType)obj).name);
else
return false;
}
}

View File

@ -0,0 +1,22 @@
package com.minres.scviewer.database;
import java.util.HashMap;
public class RelationTypeFactory {
public static RelationType create(String name){
if(registry.containsKey(name)){
return registry.get(name);
}else{
RelationType relType = new RelationType(name);
registry.put(name, relType);
return relType;
}
}
private RelationTypeFactory() {}
private static HashMap<String, RelationType> registry = new HashMap<>();
}

View File

@ -10,13 +10,10 @@
*******************************************************************************/
package com.minres.scviewer.database.tx;
import java.util.List;
import com.minres.scviewer.database.IWaveform;
public interface ITxGenerator {
public Long getId();
public IWaveform getStream();
public String getName();
public List<ITx> getTransactions();
}

View File

@ -30,6 +30,7 @@ import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import com.minres.scviewer.database.RelationType;
import com.minres.scviewer.database.RelationTypeFactory;
import com.minres.scviewer.database.tx.ITx;
import com.minres.scviewer.e4.application.Messages;
import com.minres.scviewer.e4.application.parts.PartListener;
@ -50,7 +51,7 @@ public class RelationTypeToolControl extends PartListener implements ISelectionC
WaveformViewer waveformViewerPart;
/** The dummy. */
RelationType dummy = RelationType.create(Messages.RelationTypeToolControl_0);
RelationType dummy = RelationTypeFactory.create(Messages.RelationTypeToolControl_0);
/**
* Instantiates a new relation type tool control.

View File

@ -13,16 +13,12 @@ import org.eclipse.jface.databinding.viewers.ObservableListContentProvider;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.FillLayout;
@ -83,16 +79,16 @@ public class TransactionList extends Composite {
private TableViewer tableViewer = null;
private TableColumn valueColumn = null;
private AttributeLabelProvider valueLabelProvider = null;
private IWaveform stream;
private ObservableList<AttributeNameBean> attrNames = new WritableList<AttributeNameBean>();
private ObservableList<AttributeNameBean> attrNames = new WritableList<>();
private List<ITx> eventList = new ArrayList<ITx>();
private List<ITx> eventList = new ArrayList<>();
private List<ITx> emptyList = new ArrayList<ITx>();
private List<ITx> emptyList = new ArrayList<>();
TxFilter txFilter;
@ -115,6 +111,7 @@ public class TransactionList extends Composite {
searchPropComboViewer = new ComboViewer(this, SWT.NONE);
searchPropComboViewer.setLabelProvider(new LabelProvider() {
@Override
public String getText(Object element) {
AttributeNameBean entry = (AttributeNameBean) element;
return entry.getName()+" ["+entry.getType().toString()+"]";
@ -123,20 +120,19 @@ public class TransactionList extends Composite {
searchPropComboViewer.setContentProvider(new ObservableListContentProvider<AttributeNameBean>());
searchPropComboViewer.setInput(attrNames);
Combo searchPropCombo = searchPropComboViewer.getCombo();
GridData gd_searchProp = new GridData(SWT.LEFT, SWT.FILL, false, false, 1, 1);
gd_searchProp.widthHint=100;
searchPropCombo.setLayoutData(gd_searchProp);
GridData gdSearchProp = new GridData(SWT.LEFT, SWT.FILL, false, false, 1, 1);
gdSearchProp.widthHint=100;
searchPropCombo.setLayoutData(gdSearchProp);
searchPropCombo.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
int idx = searchPropCombo.getSelectionIndex();
if(idx<0) return;
AttributeNameBean sel = attrNames.get(idx);
txFilter.setSearchProp(sel.getName(), sel.getType());
tableViewer.refresh();
extracted(searchPropCombo);
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
extracted(searchPropCombo);
}
private void extracted(Combo searchPropCombo) {
int idx = searchPropCombo.getSelectionIndex();
if(idx<0) return;
AttributeNameBean sel = attrNames.get(idx);
@ -146,15 +142,12 @@ public class TransactionList extends Composite {
});
searchPropValue = new Text(this, SWT.BORDER);
GridData gd_searchPropValue = new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1);
gd_searchPropValue.minimumWidth = 50;
searchPropValue.setLayoutData(gd_searchPropValue);
searchPropValue.addModifyListener(new ModifyListener() {
@Override
public void modifyText(ModifyEvent e) {
txFilter.setSearchValue(((Text) e.widget).getText());
tableViewer.refresh();
}
GridData gdSearchPropValue = new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1);
gdSearchPropValue.minimumWidth = 50;
searchPropValue.setLayoutData(gdSearchPropValue);
searchPropValue.addModifyListener(e -> {
txFilter.setSearchValue(((Text) e.widget).getText());
tableViewer.refresh();
});
Label lbl2 = new Label(this, SWT.NONE);
@ -164,6 +157,7 @@ public class TransactionList extends Composite {
viewPropComboViewer = new ComboViewer(this, SWT.NONE);
viewPropComboViewer.setLabelProvider(new LabelProvider() {
@Override
public String getText(Object element) {
AttributeNameBean entry = (AttributeNameBean) element;
return entry.getName()+" ["+entry.getType().toString()+"]";
@ -172,9 +166,9 @@ public class TransactionList extends Composite {
viewPropComboViewer.setContentProvider(new ObservableListContentProvider<AttributeNameBean>());
viewPropComboViewer.setInput(attrNames);
Combo viewPropCombo = viewPropComboViewer.getCombo();
GridData gd_viewProp = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
gd_viewProp.widthHint=100;
viewPropCombo.setLayoutData(gd_viewProp);
GridData gdviewProp = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
gdviewProp.widthHint=100;
viewPropCombo.setLayoutData(gdviewProp);
viewPropCombo.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
@ -184,7 +178,7 @@ public class TransactionList extends Composite {
tableViewer.refresh(true);
}
@Override
public void widgetDefaultSelected(SelectionEvent e) { }
public void widgetDefaultSelected(SelectionEvent e) { /* do nothing */ }
});
tableViewer = new TableViewer(this);
@ -200,21 +194,18 @@ public class TransactionList extends Composite {
}
});
tableViewer.addFilter(txFilter);
tableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
@Override
public void selectionChanged(SelectionChangedEvent event) {
ISelection treeSelection = event.getSelection();
if(treeSelection instanceof IStructuredSelection) {
Object selected = ((IStructuredSelection)treeSelection).getFirstElement();
if(selected instanceof ITx){
waveformViewer.setSelection(new StructuredSelection(selected));
} else if(selected instanceof TransactionTreeNode && ((TransactionTreeNode)selected).type == TransactionTreeNodeType.TX) {
waveformViewer.setSelection(new StructuredSelection(((TransactionTreeNode)selected).element));
}
tableViewer.addSelectionChangedListener(event -> {
ISelection treeSelection = event.getSelection();
if(treeSelection instanceof IStructuredSelection) {
Object selected = ((IStructuredSelection)treeSelection).getFirstElement();
if(selected instanceof ITx){
waveformViewer.setSelection(new StructuredSelection(selected));
} else if(selected instanceof TransactionTreeNode && ((TransactionTreeNode)selected).type == TransactionTreeNodeType.TX) {
waveformViewer.setSelection(new StructuredSelection(((TransactionTreeNode)selected).element));
}
}
});
Table table = tableViewer.getTable();
table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 5, 1));
@ -250,11 +241,11 @@ public class TransactionList extends Composite {
if(trackEntry==null || trackEntry.waveform.getType()!=WaveformType.TRANSACTION) {
attrNames.clear();
tableViewer.setInput(emptyList);
} else {
} else if(stream != trackEntry.waveform) {
stream=trackEntry.waveform;
tableViewer.setInput(emptyList);
new Thread() {
private ConcurrentHashMap<String, DataType> propNames=new ConcurrentHashMap<String, DataType>();
private ConcurrentHashMap<String, DataType> propNames=new ConcurrentHashMap<>();
private List<AttributeNameBean> getEntries() {
return propNames.entrySet().stream()
@ -263,11 +254,12 @@ public class TransactionList extends Composite {
.collect(Collectors.toList());
}
@Override
public void run() {
Collection<IEvent[]> values = stream.getEvents().values();
eventList = values.parallelStream().map(Arrays::asList)
.flatMap(List::stream)
.filter(evt -> evt.getKind()==EventKind.BEGIN)
.filter(evt -> evt.getKind()==EventKind.BEGIN || evt.getKind()==EventKind.SINGLE)
.map(evt-> {
ITx tx = ((ITxEvent)evt).getTransaction();
for(ITxAttribute attr: tx.getAttributes()) {
@ -283,20 +275,21 @@ public class TransactionList extends Composite {
tableViewer.setInput(eventList);
attrNames.clear();
attrNames.addAll(getEntries());
if(attrNames.size()>0)
if(!attrNames.isEmpty())
txFilter.setSearchProp(attrNames.get(0).getName(), attrNames.get(0).getType());
if (searchPropComboViewer!=null) {
searchPropComboViewer.setInput(attrNames);
searchPropComboViewer.setSelection(new StructuredSelection(searchPropComboViewer.getElementAt(0)));
Object sel = searchPropComboViewer.getElementAt(0);
if(sel!=null) searchPropComboViewer.setSelection(new StructuredSelection(sel));
}
tableViewer.refresh(true);
}
});
}
}.run();
}.start();
}
}
public void setSearchProps(String propName, DataType type, String propValue) {
for(int i=0; i<attrNames.size(); ++i) {
AttributeNameBean e = attrNames.get(i);

View File

@ -87,6 +87,7 @@ import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.IWaveformDb;
import com.minres.scviewer.database.IWaveformDbFactory;
import com.minres.scviewer.database.RelationType;
import com.minres.scviewer.database.RelationTypeFactory;
import com.minres.scviewer.database.tx.ITx;
import com.minres.scviewer.database.tx.ITxAttribute;
import com.minres.scviewer.database.tx.ITxEvent;
@ -1237,7 +1238,7 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis
* @param relationName the new navigation relation type
*/
public void setNavigationRelationType(String relationName) {
setNavigationRelationType(RelationType.create(relationName));
setNavigationRelationType(RelationTypeFactory.create(relationName));
}
/**

View File

@ -3,5 +3,6 @@
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src/"/>
<classpathentry kind="con" path="GROOVY_DSL_SUPPORT"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View File

@ -2,3 +2,11 @@
/.my_db.txlog*
/EyeQ6_mem_platform.txlog
/EyeQ6_mem_platform.vcd
/hw_cfg7.txlog
/hw_cfg7.vcd
/hw_cfg_2_gen.txlog
/hw_cfg_2_gen.vcd
/hw_cfg_2_nc.txlog
/hw_cfg_2_nc.vcd
/test_05.txlog
/test_05.vcd

View File

@ -93,8 +93,18 @@ public class DatabaseServicesTest {
assertTrue(f.exists());
waveformDb.load(f);
assertNotNull(waveformDb);
assertEquals(3, waveformDb.getAllWaves().size());
List<IWaveform> waveforms = waveformDb.getAllWaves();
assertEquals(3, waveforms.size());
assertEquals(1, waveformDb.getChildNodes().size());
for(IWaveform w:waveforms) {
if(w.getId().equals(1l)) {
assertEquals(2, w.getWidth());
} else if(w.getId().equals(2l)) {
assertEquals(1, w.getWidth());
} else if(w.getId().equals(3l)) {
assertEquals(1, w.getWidth());
}
}
}
@Test