Compare commits

...

122 Commits

Author SHA1 Message Date
ccc8d80ac2 add help plugin and handler, eclipse help does not start 2021-11-16 18:24:30 +01:00
1af3171b2e cleanup imports 2021-11-16 14:15:33 +01:00
03fd9e154b Merge branch 'master' into develop 2021-11-16 14:13:22 +01:00
3572f683e3 add zoom levels 2021-11-16 14:12:10 +01:00
524ffb189c fix MT race condition 2021-11-16 14:11:30 +01:00
7fac6c8f74 Merge branch 'release/2.14.1' into develop 2021-11-16 11:32:41 +01:00
037c645075 Merge branch 'release/2.14.1' 2021-11-16 11:32:41 +01:00
2f9bd29dc8 update version numbers 2021-11-16 11:32:34 +01:00
92662c546a fix zoom level calculation 2021-11-16 11:28:32 +01:00
efa6544623 cleanup 2021-11-16 11:27:58 +01:00
52cf9daeec unify time printing (#69) 2021-11-16 09:37:50 +01:00
4a315722b1 add help browser window instead of dialog 2021-11-16 09:33:09 +01:00
a52efd1a12 Merge branch 'master' into develop 2021-11-15 22:25:12 +01:00
535df30ada Merge branch 'release/2.14.0' into develop 2021-11-15 21:38:51 +01:00
bad34dd1d1 Merge branch 'release/2.14.0' 2021-11-15 21:38:51 +01:00
5ac7f05f57 Merge branch 'master' of https://git.minres.com/VP-Tools/SCViewer 2021-11-15 21:37:51 +01:00
8353b59a27 update version numbers for release
This release fixes the following tickets:
* #62: Instead of or in addition to the Restore Default Zoom button, add
Full Zoom Out button.
* #64: Load multiple trace files and enable the possibility to view
signals from different files in a single window.
* partial #66: key shortcuts for actions like zoom in/out, go to
next/prev event etc
* #70: add full zoom and zoom between markers (once we had markers)
* #75: marker is often hiding events underneath for highlighting and
getting transaction details
* #82: Implement help for keyboard shortcuts
2021-11-15 21:29:08 +01:00
2c6ca6c376 update version number to 2.14 2021-11-15 21:25:05 +01:00
f4b03cb0e6 extend zoom handling (#70) and hide tx property panes (#58) 2021-11-15 21:23:13 +01:00
c7858997c0 update README.md 2021-11-15 15:18:56 +01:00
bd99ab3992 corrected parent path im poms 2021-11-15 15:14:04 +01:00
66f365d38d externalize string in HelpDialog class 2021-11-15 15:14:04 +01:00
59987f262d update key bindings 2021-11-15 15:14:04 +01:00
452a28362e fix help link 2021-11-15 15:14:04 +01:00
d6805f383b add help dialog 2021-11-15 15:14:04 +01:00
076611eec7 allow multiple loading of same format 2021-11-15 15:14:04 +01:00
e0fa55e2c0 corrected parent path im poms 2021-11-15 14:32:55 +01:00
9ea1994228 update key bindings 2021-11-15 14:16:46 +01:00
36f628c365 add help dialog 2021-11-15 13:07:58 +01:00
ff87e72510 allow multiple loading of same format 2021-11-15 10:52:59 +01:00
aef1e29a53 Merge branch 'release/2.13.2' into develop 2021-07-11 14:22:41 +02:00
1ebf9ba382 update version numbers 2021-07-11 13:47:48 +02:00
929408d08c fix missing gzip txlog file filter in file dialog 2021-07-11 13:47:27 +02:00
f57fb93525 fix reload issues 2021-07-11 13:46:35 +02:00
788065e456 Merge branch 'release/2.13.1' 2021-03-25 21:09:49 +00:00
22b46e0525 fix fit zoom level calculation 2021-03-25 21:07:05 +00:00
b75018239a Merge branch 'master' into develop
Conflicts:
	features/com.minres.scviewer.database.feature/pom.xml
	features/com.minres.scviewer.e4.feature/pom.xml
	features/com.minres.scviewer.e4.platform.feature/pom.xml
	features/com.minres.scviewer.feature/pom.xml
	features/com.minres.scviewer.ui.feature/pom.xml
	plugins/com.minres.scviewer.database.sqlite/pom.xml
	plugins/com.minres.scviewer.database.text/pom.xml
	plugins/com.minres.scviewer.database.ui.swt/pom.xml
	plugins/com.minres.scviewer.database.vcd/pom.xml
	plugins/com.minres.scviewer.database/pom.xml
	plugins/com.minres.scviewer.e4.application/META-INF/MANIFEST.MF
	plugins/com.minres.scviewer.e4.application/pom.xml
	plugins/com.minres.scviewer.ui/pom.xml
	pom.xml
	products/com.minres.scviewer.e4.product/pom.xml
	products/com.minres.scviewer.e4.product/scviewer.product
	releng/com.minres.scviewer.target/pom.xml
	releng/com.minres.scviewer.updateSite/pom.xml
	tests/com.minres.scviewer.database.test/pom.xml
2021-03-25 20:46:30 +00:00
598bb8eec7 Merge remote-tracking branch 'origin/master' 2021-03-25 20:33:25 +00:00
869265fc13 add gzip files to file dialog filter 2021-03-25 20:27:55 +00:00
5ad813527a fix CLI handling 2021-03-25 20:27:55 +00:00
73f8d3d50a fix full name display of generators 2021-03-25 20:27:55 +00:00
da1701195d update version numbers 2021-03-25 20:27:55 +00:00
9b6334509e update version numbers 2021-03-25 20:27:54 +00:00
ac4acc34a4 fix warning and left-overs 2021-03-25 20:27:54 +00:00
b6963f38d6 move interface to primitive types 2021-03-25 20:27:54 +00:00
182a036ade some more refactoring 2021-03-25 20:27:53 +00:00
97f2182290 adapt painter 2021-03-25 20:27:53 +00:00
1986a8c9c3 add explicit event list 2021-03-25 20:27:53 +00:00
6905d96329 add TreeMap facade 2021-03-25 20:27:52 +00:00
818f786b1d add dispose check in case view is closed while loading db 2021-03-25 20:27:52 +00:00
2948c1bd33 update version numbers 2021-03-25 20:22:15 +00:00
78faab404c apply UI fixes
* wrong arrow target of transaction
* wrong zomm factor calculation for zoom fit
* streams and waveforms not visible if at root level
2021-03-25 20:18:50 +00:00
64b10970a8 add gzip files to file dialog filter 2021-03-02 21:55:52 +01:00
6ab8fd232e fix CLI handling 2021-03-02 21:55:52 +01:00
f337a94112 fix full name display of generators 2021-03-02 21:55:52 +01:00
0135631a3e update version numbers 2021-03-02 21:55:52 +01:00
d0e1e8801f update version numbers 2021-03-02 21:55:52 +01:00
d1b3a91979 fix warning and left-overs 2021-03-02 21:55:52 +01:00
45c1396e0e move interface to primitive types 2021-03-02 21:55:51 +01:00
b7301733f0 some more refactoring 2021-03-02 21:55:51 +01:00
5df91dbaa8 adapt painter 2021-03-02 21:55:51 +01:00
68918689e7 add explicit event list 2021-03-02 21:55:51 +01:00
c41dd646da add TreeMap facade 2021-03-02 21:55:51 +01:00
a077389b83 add dispose check in case view is closed while loading db 2021-03-02 21:55:51 +01:00
caa37375c0 add gzip files to file dialog filter 2021-03-02 21:42:54 +01:00
3daea8ab43 fix CLI handling 2021-03-02 19:32:21 +01:00
c5d77af0d0 fix full name display of generators 2021-03-02 19:32:09 +01:00
7f7fdf09f4 update version numbers 2021-02-27 19:13:28 +00:00
7aba6a2ecb update version numbers 2021-02-27 19:13:17 +00:00
012395b933 Merge branch 'feature/eclipse_collections' into develop 2021-02-27 18:47:31 +00:00
787e3accc0 fix warning and left-overs 2021-02-27 14:00:29 +00:00
b778940c83 move interface to primitive types 2021-02-27 13:59:00 +00:00
71297c4e5a some more refactoring 2021-02-27 13:47:37 +00:00
1d2395e00d adapt painter 2021-02-27 13:33:15 +00:00
b69e1886b9 add explicit event list 2021-02-27 13:27:51 +00:00
d65803a4b7 add TreeMap facade 2021-02-26 11:57:54 +00:00
0e49a68e09 add dispose check in case view is closed while loading db 2021-02-24 08:46:19 +00:00
7af5593fd4 Merge branch 'release/2.12.2' into develop 2021-02-24 07:05:00 +00:00
25545dac51 Merge branch 'release/2.12.2' 2021-02-24 07:04:59 +00:00
df77af64ca update version numbers 2021-02-24 07:04:47 +00:00
e264ab2cbe fix name display in waveform view (#6) 2021-02-24 06:56:28 +00:00
8c17ed4146 Merge branch 'release/2.12.1' into develop 2021-02-18 08:19:17 +00:00
4ee2e8bc68 Merge branch 'release/2.12.1' 2021-02-18 08:19:16 +00:00
bdcba613d5 fix version numbers 2021-02-18 08:18:47 +00:00
049de0ddaf add VM arguments for Java > 9 2021-02-18 08:14:12 +00:00
6be3f378d4 renmove deprecated newInstance call 2021-02-18 06:32:14 +00:00
6d8aa33fc9 update language level 2021-02-18 06:26:42 +00:00
b37ba9f2f1 Merge branch 'master' into develop 2021-02-17 21:15:33 +00:00
799f083a74 fix hierarchy display 2021-02-17 21:14:28 +00:00
156abe63cd fix display bug 2021-02-17 20:27:58 +00:00
d38016a03f fix display bug 2021-02-17 20:24:25 +00:00
5604c3ee5e Merge branch 'release/2.12.0' 2021-01-15 16:50:33 +01:00
5adeae15a9 change name of generated product artifacts 2021-01-15 15:52:28 +01:00
bca94ceb9d fix stream row calculation 2021-01-15 15:51:59 +01:00
a42f086339 set max heap to 2GB by default 2021-01-14 23:56:04 +01:00
888edf32be remove ITxGenerator interface 2021-01-14 23:55:47 +01:00
ee5536f1b5 update version numbers 2021-01-14 23:51:18 +01:00
59859e5d90 cache some more infos for stream 2021-01-14 23:36:29 +01:00
5bae086712 fix (Sonarlint) warnings 2021-01-14 23:36:07 +01:00
16de83616a adapt ui to database API 2021-01-14 23:14:22 +01:00
6530362b89 refactor tests 2021-01-14 23:14:05 +01:00
0372e03abb minor database API change 2021-01-14 23:13:11 +01:00
26e8ea8a51 change design browser icons 2021-01-14 21:57:27 +01:00
efd042dd22 fix duplicate version numbers 2021-01-12 20:28:51 +01:00
d06642d51f Merge branch 'release/2.11.2' into develop 2021-01-12 20:25:46 +01:00
f27bcd7109 Merge branch 'release/2.11.2' 2021-01-12 20:25:45 +01:00
eaea5a4653 update version numbers 2021-01-12 20:25:34 +01:00
fa4bd0ddd5 move database to hashmap 2021-01-12 11:46:21 +01:00
3cbbdbee92 reduce default JVM heap size 2021-01-12 11:30:59 +01:00
d674e155e1 fix wrong name extraction 2021-01-12 11:30:37 +01:00
cb3366a559 fix project setup 2021-01-12 07:36:41 +01:00
8de0e11226 Merge branch 'release/2.11.1' 2021-01-12 07:36:02 +01:00
b12232329b Merge branch 'release/2.11.1' into develop 2021-01-12 07:36:02 +01:00
5e63972500 update version numbers 2021-01-12 07:34:36 +01:00
d53db967b3 Merge branch 'hotfix/tx_end_time_fix' into develop 2021-01-12 07:18:25 +01:00
25170d0d83 Merge branch 'hotfix/tx_end_time_fix' 2021-01-12 07:18:24 +01:00
ba6446378a store complete transactions
only complete ScvTx should be put into MapDB otherwise later property
updates might get lost. Since they might not end in the order they start
an additional redirection is need to insert with ascending keys
2021-01-12 07:16:42 +01:00
12b08ca8c6 fix version numbers to adhere to eclipse versioning 2021-01-10 16:26:46 +01:00
bb60f3a9c8 fix bintray repo layout 2021-01-10 15:27:40 +01:00
ba347a258d refactor structure 2021-01-10 14:40:25 +01:00
ac41feff6e cleanup 2021-01-10 14:34:12 +01:00
d2cf13d64b Merge branch 'release/2.11.0' into develop 2021-01-10 13:37:39 +01:00
214 changed files with 2797 additions and 3157 deletions

3
.gitignore vendored
View File

@ -8,4 +8,5 @@ SCViewer.xcf
SCViewer_1.png
copyrightLog.txt
/workspace
?*.launch
?*.launch
/.settings/

View File

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>com.minres.scviewer.parent</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
</natures>
</projectDescription>

View File

@ -18,14 +18,37 @@ The viewer has the following features
- sqlite based
- visualization of transaction relations
To build the plugins the Eclipse SDK or PDE can be used. In both cases the Groovy
eclipse plugin (http://groovy.codehaus.org/Eclipse+Plugin or Market) has to be
installed.
To build the plugins the Eclipse SDK or PDE can be used.
TODO
====
- add more tests
- move to feature based product to allow automatic updates
- improve graphics
- catch-up e3 plugin to functionality of e4 product
- add calculated traces
Key Shortcuts
=============
Legend:
* Left Mouse Button: LMB
* Middle Mouse Button: MMB
* Mouse Scroll wheel: MScrl
* Context any means Name List, Value List or Waveform
| Input | Modifier | Context | Action |
|-----------|----------|----------|-----------------------------------|
| LMB klick | | any | select |
| LMB klick | Shift | Waveform | move selected marker to position |
| LMB klick | Control | Waveform | move cursor to position |
| LMB drag | | Waveform | zoom to range |
| MMB klick | | Waveform | move selected marker to position |
| MScrl | | any | scroll window up/down |
| MScrl | Shift | any | scroll window left/right |
| Key left | | Waveform | scroll window to the left (slow) |
| Key right | | Waveform | scroll window to the right (slow) |
| Key left | Shift | Waveform | scroll window to the left (fast) |
| Key right | Shift | Waveform | scroll window to the right (fast) |
| Key up | | Waveform | move selection up |
| Key down | | Waveform | move selection down |
| Key up | Control | Waveform | move selected track up |
| Key down | Control | Waveform | move selected track down |
| Key + | Control | Waveform | zoom in |
| Key - | Control | Waveform | zoom out |
| Key Pos1 | | Waveform | jump to selected marker |
| Key End | | Waveform | jump to cursor |
| Key Del | | any | delete selected entries |

View File

@ -27,12 +27,12 @@ http://www.eclipse.org/legal/epl-v10.html
</url>
<requires>
<import plugin="org.codehaus.groovy" version="2.5.8" match="greaterOrEqual"/>
<import plugin="org.eclipse.osgi.services" version="3.4.0" match="greaterOrEqual"/>
<import plugin="com.google.guava" version="15.0.0" match="greaterOrEqual"/>
<import plugin="org.eclipse.osgi"/>
<import plugin="com.minres.scviewer.database" version="1.0.0" match="greaterOrEqual"/>
<import plugin="org.eclipse.core.runtime"/>
<import feature="org.eclipse.collections.feature" version="10.4.0.v20200820-2049"/>
</requires>
<plugin

View File

@ -5,8 +5,8 @@
<parent>
<groupId>com.minres.scviewer</groupId>
<artifactId>com.minres.scviewer.parent</artifactId>
<version>2.11.0</version>
<relativePath>../..</relativePath>
<version>2.14.1</version>
<relativePath>../../..</relativePath>
</parent>
<version>3.0.0-SNAPSHOT</version>
</project>

View File

@ -64,4 +64,11 @@
version="0.0.0"
unpack="false"/>
<plugin
id="com.minres.scviewer.help"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
</feature>

View File

@ -5,8 +5,8 @@
<parent>
<groupId>com.minres.scviewer</groupId>
<artifactId>com.minres.scviewer.parent</artifactId>
<version>2.11.0</version>
<relativePath>../..</relativePath>
<version>2.14.1</version>
<relativePath>../../..</relativePath>
</parent>
<version>1.1.0-SNAPSHOT</version>
</project>

View File

@ -29,6 +29,10 @@
id="org.eclipse.emf.common"
version="0.0.0"/>
<includes
id="org.eclipse.collections.feature"
version="0.0.0"/>
<requires>
<import plugin="org.eclipse.core.expressions" version="3.2.0" match="compatible"/>
<import plugin="org.eclipse.core.filesystem" version="1.3.0" match="compatible"/>

View File

@ -5,8 +5,8 @@
<parent>
<groupId>com.minres.scviewer</groupId>
<artifactId>com.minres.scviewer.parent</artifactId>
<version>2.11.0</version>
<relativePath>../..</relativePath>
<version>2.14.1</version>
<relativePath>../../..</relativePath>
</parent>
<version>1.0.0-SNAPSHOT</version>
</project>

View File

@ -5,8 +5,8 @@
<parent>
<groupId>com.minres.scviewer</groupId>
<artifactId>com.minres.scviewer.parent</artifactId>
<version>2.11.0</version>
<relativePath>../..</relativePath>
<version>2.14.1</version>
<relativePath>../../..</relativePath>
</parent>
<version>1.1.0-SNAPSHOT</version>
</project>

View File

@ -5,8 +5,8 @@
<parent>
<groupId>com.minres.scviewer</groupId>
<artifactId>com.minres.scviewer.parent</artifactId>
<version>2.11.0</version>
<relativePath>../..</relativePath>
<version>2.14.1</version>
<relativePath>../../..</relativePath>
</parent>
<version>1.1.0-SNAPSHOT</version>
</project>

View File

@ -1,4 +0,0 @@
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1

View File

@ -1,4 +0,0 @@
/json-20180813-sources.jar
/leveldb-0.11-SNAPSHOT-sources.jar
/bin/
/target/

View File

@ -1,7 +0,0 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.8

View File

@ -1,4 +0,0 @@
eclipse.preferences.version=1
pluginProject.equinox=false
pluginProject.extensions=false
resolve.requirebundle=false

View File

@ -1,5 +0,0 @@
eclipse.preferences.version=1
enabled=true
path=OSGI-INF
validationErrorLevel=error
validationErrorLevel.missingImplicitUnbindMethod=error

View File

@ -1,16 +0,0 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Leveldb
Bundle-SymbolicName: com.minres.scviewer.database.leveldb
Bundle-Version: 1.0.0.qualifier
Bundle-Vendor: MINRES Technologies GmbH
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Import-Package: org.osgi.framework;version="1.3.0"
Automatic-Module-Name: com.minres.scviewer.database.leveldb
Service-Component: OSGI-INF/*.xml
Require-Bundle: com.minres.scviewer.database;bundle-version="1.0.0",
org.eclipse.osgi.services;bundle-version="3.4.0"
Bundle-ActivationPolicy: lazy
Bundle-ClassPath: leveldb-0.11-SNAPSHOT-uber.jar,
.,
json-20180813.jar

View File

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="LevelDbLoader">
<implementation class="com.minres.scviewer.database.leveldb.LevelDBLoader"/>
<service>
<provide interface="com.minres.scviewer.database.IWaveformDbLoader"/>
</service>
</scr:component>

View File

@ -1,7 +0,0 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,\
OSGI-INF/,\
leveldb-0.11-SNAPSHOT-uber.jar,\
json-20180813.jar

View File

@ -1,13 +0,0 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>com.minres.scviewer.database.leveldb</artifactId>
<version>1.0.0-SNAPSHOT</version>
<parent>
<groupId>com.minres.scviewer</groupId>
<artifactId>com.minres.scviewer.parent</artifactId>
<version>2.0.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<packaging>eclipse-plugin</packaging>
</project>

View File

@ -1,87 +0,0 @@
package com.minres.scviewer.database.leveldb;
import static java.nio.charset.StandardCharsets.UTF_8;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map.Entry;
import org.iq80.leveldb.Options;
import org.iq80.leveldb.impl.SeekingIterator;
import org.json.JSONObject;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.IWaveformDb;
import com.minres.scviewer.database.IWaveformDbLoader;
import com.minres.scviewer.database.RelationType;
public class LevelDBLoader implements IWaveformDbLoader {
static byte[] toByteArray(String value) {
return value.getBytes(UTF_8);
}
private TxDBWrapper levelDb;
private IWaveformDb db;
private Long maxTime=null;
private List<RelationType> usedRelationsList = new ArrayList<>();
@Override
public boolean load(IWaveformDb db, File inp) throws Exception {
try {
this.db=db;
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;
}
return true;
}
@Override
public Long getMaxTime() {
if(maxTime==null) {
SeekingIterator<String, String> it = levelDb.iterator();
it.seek("st~");
Entry<String, String> val = null;
while(it.hasNext()) {
Entry<String, String> v = it.next();
if(!v.getKey().startsWith("st~")) continue;
val=v;
}
if(val==null)
maxTime = 0L;
else {
String[] token = val.getKey().split("~");
maxTime = Long.parseLong(token[2], 16)*levelDb.getTimeResolution();
}
}
return maxTime;
}
@Override
public Collection<IWaveform> getAllWaves() {
List<IWaveform> streams=new ArrayList<IWaveform>();
SeekingIterator<String, String> it = levelDb.iterator();
it.seek("s~");
while(it.hasNext()) {
Entry<String, String> val = it.next();
if(!val.getKey().startsWith("s~")) break;
TxStream stream = new TxStream(levelDb, db, new JSONObject(val.getValue()));
stream.setRelationTypeList(usedRelationsList);
streams.add(stream);
}
return streams;
}
@Override
public Collection<RelationType> getAllRelationTypes() {
// return Collections.emptyList();
return usedRelationsList;
}
}

View File

@ -1,51 +0,0 @@
package com.minres.scviewer.database.leveldb;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.iq80.leveldb.shaded.guava.collect.Maps.immutableEntry;
import java.util.Map.Entry;
import org.iq80.leveldb.DBIterator;
import org.iq80.leveldb.impl.SeekingIterator;
class StringDbIterator implements SeekingIterator<String, String> {
private final DBIterator iterator;
StringDbIterator(DBIterator iterator) {
this.iterator = iterator;
}
@Override
public boolean hasNext() {
return iterator.hasNext();
}
@Override
public void seekToFirst() {
iterator.seekToFirst();
}
@Override
public void seek(String targetKey) {
iterator.seek(targetKey.getBytes(UTF_8));
}
@Override
public Entry<String, String> peek() {
return adapt(iterator.peekNext());
}
@Override
public Entry<String, String> next() {
return adapt(iterator.next());
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
private Entry<String, String> adapt(Entry<byte[], byte[]> next) {
return immutableEntry(new String(next.getKey(), UTF_8), new String(next.getValue(), UTF_8));
}
}

View File

@ -1,172 +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.leveldb;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.iq80.leveldb.impl.SeekingIterator;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.minres.scviewer.database.ITx;
import com.minres.scviewer.database.ITxAttribute;
import com.minres.scviewer.database.ITxEvent;
import com.minres.scviewer.database.ITxGenerator;
import com.minres.scviewer.database.ITxRelation;
import com.minres.scviewer.database.ITxStream;
public class Tx implements ITx {
private TxDBWrapper levelDb;
private TxStream trStream;
private TxGenerator trGenerator;
private long id;
private long start_time=0;
private long end_time=0;
private int concurency_index;
private boolean initialized=false;
private List<ITxAttribute> attributes;
private List<ITxRelation> incoming, outgoing;
public Tx(TxDBWrapper levelDb, TxStream trStream, TxGenerator trGenerator, long id) {
this.levelDb=levelDb;
this.trStream=trStream;
this.trGenerator=trGenerator;
this.id=id;
}
@Override
public Long getId() {
return id;
}
@Override
public ITxStream<ITxEvent> getStream() {
return trStream;
}
@Override
public ITxGenerator getGenerator() {
return trGenerator;
}
@Override
public int getConcurrencyIndex() {
if(!initialized) loadFromDb();
return concurency_index;
}
@Override
public Long getBeginTime() {
if(!initialized) loadFromDb();
return start_time;
}
@Override
public Long getEndTime() {
loadFromDb();
return end_time;
}
@Override
public List<ITxAttribute> getAttributes() {
if(attributes==null) {
loadFromDb();
}
return attributes;
}
@Override
public Collection<ITxRelation> getIncomingRelations() {
if(incoming==null) {
incoming = new ArrayList<ITxRelation>();
SeekingIterator<String, String> it = levelDb.iterator();
String key = "ri~"+String.format("%016x", id);
it.seek(key);
while(it.hasNext()) {
String val = it.next().getKey();
if(!val.startsWith(key)) break;;
String[] token = val.split("~");
long otherId = Long.parseLong(token[2], 16);
incoming.add(createRelation(otherId, token[3], false));
}
}
return incoming;
}
@Override
public Collection<ITxRelation> getOutgoingRelations() {
if(outgoing==null) {
outgoing = new ArrayList<ITxRelation>();
SeekingIterator<String, String> it = levelDb.iterator();
String key="ro~"+String.format("%016x", id);
it.seek(key);
while(it.hasNext()) {
String val = it.next().getKey();
if(!val.startsWith(key)) break;
String[] token = val.split("~");
long otherId = Long.parseLong(token[2], 16);
outgoing.add(createRelation(otherId, token[3], true));
}
}
return outgoing;
}
@Override
public int compareTo(ITx o) {
int res = this.getBeginTime().compareTo(o.getBeginTime());
if(res!=0)
return res;
else
return this.getId().compareTo(o.getId());
}
@Override
public String toString() {
return "tx#"+getId()+"["+getBeginTime()/1000000+"ns - "+getEndTime()/1000000+"ns]";
}
private void loadFromDb() throws JSONException {
JSONObject dbVal = new JSONObject(levelDb.get("x~"+ String.format("%016x", id)));
start_time=dbVal.getLong("START_TIME") * levelDb.getTimeResolution();
end_time=dbVal.getLong("END_TIME") * levelDb.getTimeResolution();
concurency_index=dbVal.getInt("conc");
attributes=new ArrayList<>();
JSONArray arr = dbVal.getJSONArray("attr");
arr.forEach(entry -> {
TxAttribute attr = new TxAttribute(this, (JSONObject) entry);
attributes.add(attr);
});
initialized=true;
}
private ITxRelation createRelation(long otherId, String name, boolean outgoing) {
try {
JSONObject otherTxVal = new JSONObject(levelDb.get("x~"+ String.format("%016x", otherId)));
if(otherTxVal.isEmpty()) return null;
JSONObject otherStreamVal = new JSONObject(levelDb.get("s~"+ String.format("%016x", otherTxVal.getLong("s"))));
if(otherStreamVal.isEmpty()) return null;
TxStream tgtStream = (TxStream) trStream.getDb().getStreamByName(otherStreamVal.getString("name"));
Tx that = (Tx) tgtStream.getTransactions().get(otherId);
return outgoing?
new TxRelation(trStream.getRelationType(name), this, that):
new TxRelation(trStream.getRelationType(name), that, this);
} catch (SecurityException | IllegalArgumentException | JSONException e) {
e.printStackTrace();
}
return null;
}
}

View File

@ -1,56 +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.leveldb;
import org.json.JSONObject;
import com.minres.scviewer.database.AssociationType;
import com.minres.scviewer.database.DataType;
import com.minres.scviewer.database.ITxAttribute;
public class TxAttribute implements ITxAttribute{
private String name;
private DataType dataType;
private AssociationType associationType;
private Object value;
public TxAttribute(Tx trTransaction, JSONObject attribute) {
this.name=attribute.getString("name");
this.dataType=DataType.values()[attribute.getInt("type")];
this.associationType=AssociationType.values()[attribute.getInt("assoc")];
this.value=attribute.get("value");
}
@Override
public String getName() {
return name;
}
@Override
public DataType getDataType() {
return dataType;
}
@Override
public AssociationType getType() {
return associationType;
}
@Override
public Object getValue() {
return value;
}
}

View File

@ -1,90 +0,0 @@
package com.minres.scviewer.database.leveldb;
import static java.nio.charset.StandardCharsets.UTF_8;
import java.io.File;
import java.io.IOException;
import org.iq80.leveldb.Options;
import org.iq80.leveldb.Range;
import org.iq80.leveldb.ReadOptions;
import org.iq80.leveldb.Snapshot;
import org.iq80.leveldb.impl.DbImpl;
import org.iq80.leveldb.impl.SeekingIterator;
class TxDBWrapper {
private final Options options;
private final ReadOptions ro = new ReadOptions();
private final File databaseDir;
private DbImpl db;
private long timeResolution=1L;;
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) {
byte[] slice = db.get(LevelDBLoader.toByteArray(key));
if (slice == null) {
return null;
}
return new String(slice, UTF_8);
}
public String get(String key, Snapshot snapshot) {
byte[] slice = db.get(LevelDBLoader.toByteArray(key), ro);
return slice == null? null : new String(slice, UTF_8);
}
public void put(String key, String value) {
db.put(LevelDBLoader.toByteArray(key), LevelDBLoader.toByteArray(value));
}
public void delete(String key) {
db.delete(LevelDBLoader.toByteArray(key));
}
public SeekingIterator<String, String> iterator() {
return new StringDbIterator(db.iterator());
}
public Snapshot getSnapshot() {
return db.getSnapshot();
}
public void close() {
try {
ro.snapshot().close();
db.close();
} catch (IOException e) {} // ignore any error
}
public long size(String start, String limit) {
return db.getApproximateSizes(new Range(LevelDBLoader.toByteArray(start), LevelDBLoader.toByteArray(limit)));
}
public long getMaxNextLevelOverlappingBytes() {
return db.getMaxNextLevelOverlappingBytes();
}
public void reopen() throws IOException {
reopen(options);
}
public void reopen(Options options) throws IOException {
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;
}
}

View File

@ -1,57 +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.leveldb;
import com.minres.scviewer.database.ITx;
import com.minres.scviewer.database.ITxEvent;
import com.minres.scviewer.database.IWaveformEvent;
public class TxEvent implements ITxEvent {
private final Type type;
private ITx tx;
public TxEvent(Type type, ITx tx) {
super();
this.type = type;
this.tx = tx;
}
@Override
public Long getTime() {
return type==Type.BEGIN?tx.getBeginTime():tx.getEndTime();
}
@Override
public IWaveformEvent duplicate() throws CloneNotSupportedException {
return new TxEvent(type, tx);
}
@Override
public int compareTo(IWaveformEvent o) {
return getTime().compareTo(o.getTime());
}
@Override
public ITx getTransaction() {
return tx;
}
@Override
public Type getType() {
return type;
}
@Override
public String toString() {
return type.toString()+"@"+getTime()+" of tx #"+tx.getId();
}
}

View File

@ -1,56 +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.leveldb;
import java.util.List;
import org.json.JSONObject;
import com.minres.scviewer.database.ITx;
import com.minres.scviewer.database.ITxEvent;
import com.minres.scviewer.database.ITxGenerator;
import com.minres.scviewer.database.ITxStream;
public class TxGenerator implements ITxGenerator {
private ITxStream<ITxEvent> stream;
private long id;
private String name;
public TxGenerator(ITxStream<ITxEvent> stream, JSONObject object) {
this.stream=stream;
this.id=object.getLong("id");
this.name=object.getString("name");
}
@Override
public Long getId() {
return id;
}
@Override
public ITxStream<ITxEvent> getStream() {
return stream;
}
@Override
public String getName() {
return name;
}
@Override
public List<ITx> getTransactions() {
return null;
}
}

View File

@ -1,43 +0,0 @@
/*******************************************************************************
* Copyright (c) 2015 MINRES Technologies GmbH and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* MINRES Technologies GmbH - initial API and implementation
*******************************************************************************/
package com.minres.scviewer.database.leveldb;
import com.minres.scviewer.database.ITxRelation;
import com.minres.scviewer.database.ITx;
import com.minres.scviewer.database.RelationType;
public class TxRelation implements ITxRelation {
RelationType relationType;
Tx source, target;
public TxRelation(RelationType relationType, Tx source, Tx target) {
this.source = source;
this.target = target;
this.relationType = relationType;
}
@Override
public RelationType getRelationType() {
return relationType;
}
@Override
public ITx getSource() {
return source;
}
@Override
public ITx getTarget() {
return target;
}
}

View File

@ -1,178 +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.leveldb;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.iq80.leveldb.impl.SeekingIterator;
import org.json.JSONObject;
import java.util.NavigableMap;
import java.util.TreeMap;
import java.util.Vector;
import com.minres.scviewer.database.HierNode;
import com.minres.scviewer.database.ITx;
import com.minres.scviewer.database.ITxEvent;
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.RelationType;
public class TxStream extends HierNode implements ITxStream<ITxEvent> {
private TxDBWrapper levelDb;
private String fullName;
private String kind;
private IWaveformDb db;
private long id;
private TreeMap<Long, TxGenerator> generators;
private TreeMap<Long, ITx> transactions;
private Integer maxConcurrency;
private TreeMap<Long, List<ITxEvent>> events;
private List<RelationType> usedRelationsList;
public TxStream(TxDBWrapper database, IWaveformDb waveformDb, JSONObject object) {
super(object.get("name").toString());
this.levelDb=database;
this.db=waveformDb;
this.fullName=object.getString("name");
this.kind=object.getString("kind");
this.id = object.getLong("id");
}
@Override
public IWaveformDb getDb() {
return db;
}
@Override
public String getFullName() {
return fullName;
}
@Override
public Long getId() {
return id;
}
@Override
public String getKind() {
return kind;
}
@Override
public List<ITxGenerator> getGenerators() {
if(generators==null){
generators=new TreeMap<Long, TxGenerator>();
SeekingIterator<String, String> it = levelDb.iterator();
String key="sg~"+String.format("%016x", id);
it.seek(key);
while(it.hasNext()) {
Entry<String, String> val = it.next();
if(!val.getKey().startsWith(key)) break;
JSONObject jVal = new JSONObject(val.getValue());
generators.put(jVal.getLong("id"), new TxGenerator(this, jVal));
}
}
return new ArrayList<ITxGenerator>(generators.values());
}
@Override
public int getMaxConcurrency() {
if(maxConcurrency==null){
getTransactions();
}
return maxConcurrency;
}
@Override
public NavigableMap<Long, List<ITxEvent>> getEvents(){
if(events==null){
events=new TreeMap<Long, List<ITxEvent>>();
for(Entry<Long, ITx> entry:getTransactions().entrySet()){
ITx tx = entry.getValue();
putEvent(new TxEvent(TxEvent.Type.BEGIN, tx));
putEvent(new TxEvent(TxEvent.Type.END, tx));
}
}
return events;
}
private void putEvent(TxEvent ev){
Long time = ev.getTime();
if(!events.containsKey(time)){
Vector<ITxEvent> vector=new Vector<ITxEvent>();
vector.add(ev);
events.put(time, vector);
} else {
events.get(time).add(ev);
}
}
protected Map<Long, ITx> getTransactions() {
if(transactions==null){
if(generators==null) getGenerators();
transactions = new TreeMap<Long, ITx>();
maxConcurrency=0;
SeekingIterator<String, String> it = levelDb.iterator();
String key = "sgx~"+String.format("%016x", id);
it.seek(key);
while(it.hasNext()) {
Entry<String, String> val = it.next();
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
ITx tx = new Tx(levelDb, this, generators.get(gid), id);
transactions.put(id, tx);
maxConcurrency= Math.max(maxConcurrency, tx.getConcurrencyIndex());
}
maxConcurrency++;
}
return transactions;
}
@Override
public Collection<ITxEvent> getWaveformEventsAtTime(Long time) {
return getEvents().get(time);
}
public void setRelationTypeList(List<RelationType> usedRelationsList){
this.usedRelationsList=usedRelationsList;
}
public RelationType getRelationType(String name) {
RelationType relType=RelationType.create(name);
if(!usedRelationsList.contains(relType)) usedRelationsList.add(relType);
return relType;
}
@Override
public Boolean equals(IWaveform other) {
return(other instanceof TxStream && this.getId()==other.getId());
}
}

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<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.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry exported="true" kind="lib" path="sqlite-jdbc-3.8.7.jar"/>

View File

@ -1,8 +1,10 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
org.eclipse.jdt.core.compiler.compliance=11
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.release=disabled
org.eclipse.jdt.core.compiler.source=1.8
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
org.eclipse.jdt.core.compiler.release=enabled
org.eclipse.jdt.core.compiler.source=11

View File

@ -4,7 +4,7 @@ Bundle-Name: SQLite transaction database
Bundle-SymbolicName: com.minres.scviewer.database.sqlite
Bundle-Version: 1.1.0.qualifier
Bundle-Vendor: MINRES Technologies GmbH
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-RequiredExecutionEnvironment: JavaSE-11
Require-Bundle: com.minres.scviewer.database;bundle-version="1.0.0"
Bundle-ClassPath: .,sqlite-jdbc-3.8.7.jar
Service-Component: OSGI-INF/component.xml

View File

@ -4,8 +4,8 @@
<parent>
<groupId>com.minres.scviewer</groupId>
<artifactId>com.minres.scviewer.parent</artifactId>
<version>2.11.0</version>
<relativePath>../..</relativePath>
<version>2.14.1</version>
<relativePath>../../..</relativePath>
</parent>
<packaging>eclipse-plugin</packaging>
<dependencies>

View File

@ -14,12 +14,13 @@ import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.TreeMap;
import com.minres.scviewer.database.EventEntry;
import com.minres.scviewer.database.EventKind;
import com.minres.scviewer.database.HierNode;
import com.minres.scviewer.database.IEvent;
import com.minres.scviewer.database.IEventList;
import com.minres.scviewer.database.EventList;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.RelationType;
import com.minres.scviewer.database.RelationTypeFactory;
@ -35,18 +36,18 @@ abstract class AbstractTxStream extends HierNode implements IWaveform {
private Integer maxConcurrency;
private TreeMap<Long, IEvent[]> events;
private IEventList events;
private List<RelationType> usedRelationsList;
public AbstractTxStream(IDatabase database, String name, long streamId) {
protected AbstractTxStream(IDatabase database, String name, long streamId) {
super(name);
this.database=database;
this.streamId=streamId;
}
@Override
public int getWidth() {
public int getRowCount() {
if(maxConcurrency==null){
StringBuilder sb = new StringBuilder();
sb.append("SELECT MAX(concurrencyLevel) as concurrencyLevel FROM ScvTx where stream=");
@ -71,9 +72,9 @@ abstract class AbstractTxStream extends HierNode implements IWaveform {
}
@Override
public NavigableMap<Long, IEvent[]> getEvents(){
public IEventList getEvents(){
if(events==null){
events=new TreeMap<>();
events=new EventList();
for(Entry<Integer, ITx> entry:getTransactions().entrySet()){
putEvent(new TxEvent(EventKind.BEGIN, entry.getValue()));
putEvent(new TxEvent(EventKind.END, entry.getValue()));
@ -83,22 +84,13 @@ abstract class AbstractTxStream extends HierNode implements IWaveform {
}
private void putEvent(TxEvent ev){
Long time = ev.getTime();
if(events.containsKey(time)) {
IEvent[] oldV = events.get(time);
IEvent[] newV = new IEvent[oldV.length+1];
System.arraycopy(oldV, 0, newV, 0, oldV.length);
newV[oldV.length]=ev;
events.put(time, newV);
} else {
events.put(time, new IEvent[] {ev});
}
events.put(ev.getTime(), ev);
}
protected abstract Map<Integer, ITx> getTransactions();
@Override
public IEvent[] getEventsAtTime(Long time) {
public IEvent[] getEventsAtTime(long time) {
return getEvents().get(time);
}
@ -113,12 +105,12 @@ abstract class AbstractTxStream extends HierNode implements IWaveform {
}
@Override
public IEvent[] getEventsBeforeTime(Long time) {
Entry<Long, IEvent[]> e = events.floorEntry(time);
public IEvent[] getEventsBeforeTime(long time) {
EventEntry e = events.floorEntry(time);
if(e==null)
return new IEvent[]{};
else
return events.floorEntry(time).getValue();
return events.floorEntry(time).events;
}
@Override
@ -126,4 +118,11 @@ abstract class AbstractTxStream extends HierNode implements IWaveform {
return WaveformType.TRANSACTION;
}
/**
* Calculate concurrency.
*/
public void calculateConcurrency() {
}
}

View File

@ -48,7 +48,7 @@ public class SQLiteDbLoader implements IWaveformDbLoader {
protected PropertyChangeSupport pcs = new PropertyChangeSupport(this);
@Override
public Long getMaxTime() {
public long getMaxTime() {
SQLiteDatabaseSelectHandler<ScvTxEvent> handler = new SQLiteDatabaseSelectHandler<>(ScvTxEvent.class,
database, "time = (SELECT MAX(time) FROM ScvTxEvent)");
try {
@ -56,7 +56,7 @@ public class SQLiteDbLoader implements IWaveformDbLoader {
if(!event.isEmpty())
return event.get(0).getTime()*scvSimProps.getTime_resolution();
} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException
| InvocationTargetException | SQLException | IntrospectionException e) {
| InvocationTargetException | SQLException | IntrospectionException | NoSuchMethodException e) {
e.printStackTrace();
}
return 0L;
@ -73,7 +73,7 @@ public class SQLiteDbLoader implements IWaveformDbLoader {
streams.add(stream);
}
} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException
| InvocationTargetException | SQLException | IntrospectionException e) {
| InvocationTargetException | SQLException | IntrospectionException | NoSuchMethodException e) {
}
return streams;
}
@ -99,7 +99,6 @@ public class SQLiteDbLoader implements IWaveformDbLoader {
@Override
public void load(IWaveformDb db, File file) throws InputFormatException {
dispose();
database=new SQLiteDatabase(file.getAbsolutePath(), db);
database.setData("TIMERESOLUTION", 1L);
SQLiteDatabaseSelectHandler<ScvSimProps> handler = new SQLiteDatabaseSelectHandler<>(ScvSimProps.class, database);
@ -110,7 +109,7 @@ public class SQLiteDbLoader implements IWaveformDbLoader {
}
pcs.firePropertyChange(IWaveformDbLoader.LOADING_FINISHED, null, null);
} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException
| InvocationTargetException | SQLException | IntrospectionException e) {
| InvocationTargetException | SQLException | IntrospectionException | NoSuchMethodException e) {
throw new InputFormatException(e.toString());
}
}

View File

@ -28,7 +28,6 @@ import com.minres.scviewer.database.sqlite.tables.ScvTxEvent;
import com.minres.scviewer.database.sqlite.tables.ScvTxRelation;
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;
public class Tx implements ITx {
@ -38,8 +37,8 @@ public class Tx implements ITx {
private TxGenerator trGenerator;
private ScvTx scvTx;
private List<ITxAttribute> attributes;
private Long begin;
private Long end;
private long begin=-1;
private long end=-1;
private List<ITxRelation> incoming;
private List<ITxRelation> outgoing;
@ -51,7 +50,7 @@ public class Tx implements ITx {
}
@Override
public Long getId() {
public long getId() {
return (long) scvTx.getId();
}
@ -61,18 +60,17 @@ public class Tx implements ITx {
}
@Override
public ITxGenerator getGenerator() {
public IWaveform getGenerator() {
return trGenerator;
}
@Override
public int getConcurrencyIndex() {
int getConcurrencyIndex() {
return scvTx.getConcurrencyLevel();
}
@Override
public Long getBeginTime() {
if(begin==null){
public long getBeginTime() {
if(begin<0){
SQLiteDatabaseSelectHandler<ScvTxEvent> handler = new SQLiteDatabaseSelectHandler<>(ScvTxEvent.class,
database, "tx="+scvTx.getId()+" AND type="+ AssociationType.BEGIN.ordinal());
try {
@ -80,15 +78,15 @@ public class Tx implements ITx {
begin= scvEvent.getTime()*(Long)database.getData("TIMERESOLUTION");
}
} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException
| InvocationTargetException | SQLException | IntrospectionException e) {
| InvocationTargetException | SQLException | IntrospectionException | NoSuchMethodException e) {
}
}
return begin;
}
@Override
public Long getEndTime() {
if(end==null){
public long getEndTime() {
if(end<0){
SQLiteDatabaseSelectHandler<ScvTxEvent> handler = new SQLiteDatabaseSelectHandler<>(ScvTxEvent.class,
database, "tx="+scvTx.getId()+" AND type="+ AssociationType.END.ordinal());
try {
@ -96,7 +94,7 @@ public class Tx implements ITx {
end = scvEvent.getTime()*(Long)database.getData("TIMERESOLUTION");
}
} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException
| InvocationTargetException | SQLException | IntrospectionException e) {
| InvocationTargetException | SQLException | IntrospectionException | NoSuchMethodException e) {
}
}
return end;
@ -114,7 +112,7 @@ public class Tx implements ITx {
}
} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException
| InvocationTargetException | SQLException | IntrospectionException e) {
| InvocationTargetException | SQLException | IntrospectionException | NoSuchMethodException e) {
}
}
return attributes;
@ -131,7 +129,7 @@ public class Tx implements ITx {
incoming.add(createRelation(scvRelation, false));
}
} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException
| InvocationTargetException | SQLException | IntrospectionException e) {
| InvocationTargetException | SQLException | IntrospectionException | NoSuchMethodException e) {
}
}
return incoming;
@ -148,7 +146,7 @@ public class Tx implements ITx {
outgoing.add(createRelation(scvRelation, true));
}
} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException
| InvocationTargetException | SQLException | IntrospectionException e) {
| InvocationTargetException | SQLException | IntrospectionException | NoSuchMethodException e) {
}
}
return outgoing;
@ -171,7 +169,7 @@ public class Tx implements ITx {
else
return new TxRelation(trStream.getRelationType(rel.getName()), that, this);
} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException
| InvocationTargetException | SQLException | IntrospectionException e) {
| InvocationTargetException | SQLException | IntrospectionException | NoSuchMethodException e) {
e.printStackTrace();
}
@ -180,11 +178,11 @@ public class Tx implements ITx {
@Override
public int compareTo(ITx o) {
int res = this.getBeginTime().compareTo(o.getBeginTime());
int res = Long.compare(this.getBeginTime(), o.getBeginTime());
if(res!=0)
return res;
else
return this.getId().compareTo(o.getId());
return Long.compare(this.getId(), o.getId());
}
@Override

View File

@ -28,7 +28,7 @@ public class TxEvent implements ITxEvent {
}
@Override
public Long getTime() {
public long getTime() {
return type==EventKind.BEGIN?tx.getBeginTime():tx.getEndTime();
}
@ -56,4 +56,10 @@ public class TxEvent implements ITxEvent {
public WaveformType getType() {
return WaveformType.TRANSACTION;
}
@Override
public int getRowIndex() {
return ((Tx)tx).getConcurrencyIndex();
}
}

View File

@ -22,9 +22,8 @@ import com.minres.scviewer.database.sqlite.db.SQLiteDatabaseSelectHandler;
import com.minres.scviewer.database.sqlite.tables.ScvGenerator;
import com.minres.scviewer.database.sqlite.tables.ScvTx;
import com.minres.scviewer.database.tx.ITx;
import com.minres.scviewer.database.tx.ITxGenerator;
public class TxGenerator extends AbstractTxStream implements ITxGenerator {
public class TxGenerator extends AbstractTxStream {
private TxStream stream;
@ -40,15 +39,10 @@ public class TxGenerator extends AbstractTxStream implements ITxGenerator {
}
@Override
public Long getId() {
public long getId() {
return (long) scvGenerator.getId();
}
@Override
public IWaveform getStream() {
return stream;
}
@Override
public String getName() {
return scvGenerator.getName();
@ -56,7 +50,7 @@ public class TxGenerator extends AbstractTxStream implements ITxGenerator {
@Override
public boolean isSame(IWaveform other) {
return(other instanceof TxGenerator && this.getId().equals(other.getId()));
return(other instanceof TxGenerator && this.getId() == other.getId());
}
@Override
@ -75,7 +69,7 @@ public class TxGenerator extends AbstractTxStream implements ITxGenerator {
transactions.put(scvTx.getId(), new Tx(database, (TxStream) stream, this, scvTx));
}
} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException
| InvocationTargetException | SQLException | IntrospectionException e) {
| InvocationTargetException | SQLException | IntrospectionException | NoSuchMethodException e) {
e.printStackTrace();
}
}

View File

@ -26,7 +26,6 @@ import com.minres.scviewer.database.sqlite.tables.ScvGenerator;
import com.minres.scviewer.database.sqlite.tables.ScvStream;
import com.minres.scviewer.database.sqlite.tables.ScvTx;
import com.minres.scviewer.database.tx.ITx;
import com.minres.scviewer.database.tx.ITxGenerator;
public class TxStream extends AbstractTxStream {
@ -50,11 +49,11 @@ public class TxStream extends AbstractTxStream {
}
@Override
public Long getId() {
public long getId() {
return (long) scvStream.getId();
}
public List<ITxGenerator> getGenerators() {
public List<IWaveform> getGenerators() {
if(generators==null){
SQLiteDatabaseSelectHandler<ScvGenerator> handler = new SQLiteDatabaseSelectHandler<>(
ScvGenerator.class, database, "stream="+scvStream.getId());
@ -64,7 +63,7 @@ public class TxStream extends AbstractTxStream {
generators.put(scvGenerator.getId(), new TxGenerator(database, this, scvGenerator));
}
} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException
| InvocationTargetException | SQLException | IntrospectionException e) {
| InvocationTargetException | SQLException | IntrospectionException | NoSuchMethodException e) {
e.printStackTrace();
}
}
@ -82,7 +81,7 @@ public class TxStream extends AbstractTxStream {
transactions.put(scvTx.getId(), new Tx(database, this, generators.get(scvTx.getGenerator()), scvTx));
}
} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException
| InvocationTargetException | SQLException | IntrospectionException e) {
| InvocationTargetException | SQLException | IntrospectionException | NoSuchMethodException e) {
e.printStackTrace();
}
}
@ -90,13 +89,13 @@ public class TxStream extends AbstractTxStream {
}
@Override
public IEvent[] getEventsAtTime(Long time) {
public IEvent[] getEventsAtTime(long time) {
return getEvents().get(time);
}
@Override
public boolean isSame(IWaveform other) {
return(other instanceof TxStream && this.getId().equals(other.getId()));
return(other instanceof TxStream && this.getId() == other.getId());
}
@Override

View File

@ -75,10 +75,11 @@ public class SQLiteDatabaseSelectHandler<T> extends AbstractDatabaseHandler<T> {
* @throws IllegalAccessException
* @throws IntrospectionException
* @throws InvocationTargetException
* @throws NoSuchMethodException
*/
public synchronized List<T> selectObjects() throws SQLException,
InstantiationException, IllegalAccessException,
IntrospectionException, InvocationTargetException {
IntrospectionException, InvocationTargetException, IllegalArgumentException, NoSuchMethodException, SecurityException {
Connection connection = null;
Statement statement = null;
@ -113,17 +114,18 @@ public class SQLiteDatabaseSelectHandler<T> extends AbstractDatabaseHandler<T> {
* @throws IllegalAccessException
* @throws IntrospectionException
* @throws InvocationTargetException
* @throws NoSuchMethodException
*/
private List<T> createObjects(ResultSet resultSet)
throws SQLException, InstantiationException,
IllegalAccessException, IntrospectionException,
InvocationTargetException {
InvocationTargetException, IllegalArgumentException, NoSuchMethodException, SecurityException {
List<T> list = new ArrayList<>();
while (resultSet.next()) {
T instance = type.newInstance();
T instance = type.getDeclaredConstructor().newInstance();
for (Field field : type.getDeclaredFields()) {

View File

@ -1,17 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src/"/>
<classpathentry exported="true" kind="lib" path="lib/mapdb-3.0.7.jar" sourcepath="lib/mapdb-3.0.7-sources.jar">
<attributes>
<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/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

@ -1,9 +1,11 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
org.eclipse.jdt.core.compiler.compliance=11
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.release=disabled
org.eclipse.jdt.core.compiler.source=1.8
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
org.eclipse.jdt.core.compiler.release=enabled
org.eclipse.jdt.core.compiler.source=11

View File

@ -2,9 +2,9 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Textual transaction database
Bundle-SymbolicName: com.minres.scviewer.database.text
Bundle-Version: 3.0.0.qualifier
Bundle-Version: 4.0.0.qualifier
Bundle-Vendor: MINRES Technologies GmbH
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-RequiredExecutionEnvironment: JavaSE-11
Import-Package: org.osgi.framework;version="1.3.0"
Require-Bundle: com.minres.scviewer.database,
org.eclipse.osgi.services;bundle-version="3.4.0",

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="TextDbLoader">
<implementation class="com.minres.scviewer.database.text.TextDbLoader"/>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="TextDbLoaderFactory">
<implementation class="com.minres.scviewer.database.text.TextDbLoaderFactory"/>
<service>
<provide interface="com.minres.scviewer.database.IWaveformDbLoader"/>
<provide interface="com.minres.scviewer.database.IWaveformDbLoaderFactory"/>
</service>
</scr:component>

View File

@ -2,44 +2,13 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>com.minres.scviewer.database.text</artifactId>
<version>3.0.0-SNAPSHOT</version>
<version>4.0.0-SNAPSHOT</version>
<parent>
<groupId>com.minres.scviewer</groupId>
<artifactId>com.minres.scviewer.parent</artifactId>
<version>2.11.0</version>
<relativePath>../..</relativePath>
<version>2.14.1</version>
<relativePath>../../..</relativePath>
</parent>
<packaging>eclipse-plugin</packaging>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<compilerId>groovy-eclipse-compiler</compilerId>
<compilerArguments>
<indy/><!-- optional; supported by batch 2.4.12-04+ -->
</compilerArguments>
<!-- set verbose to be true if you want lots of uninteresting messages -->
<!-- <verbose>true</verbose> -->
<source>1.8</source>
<target>1.8</target>
</configuration>
<dependencies>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-eclipse-compiler</artifactId>
<version>${groovy-eclipse-compiler-version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-eclipse-batch</artifactId>
<version>${groovy-eclipse-batch-version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>

View File

@ -12,16 +12,16 @@
package com.minres.scviewer.database.text;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.TreeMap;
import java.util.HashMap;
import com.minres.scviewer.database.EventKind;
import com.minres.scviewer.database.EventEntry;
import com.minres.scviewer.database.EventList;
import com.minres.scviewer.database.HierNode;
import com.minres.scviewer.database.IEvent;
import com.minres.scviewer.database.IEventList;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.WaveformType;
import com.minres.scviewer.database.tx.ITx;
import com.minres.scviewer.database.tx.ITxEvent;
/**
@ -29,6 +29,8 @@ import com.minres.scviewer.database.tx.ITxEvent;
*/
abstract class AbstractTxStream extends HierNode implements IWaveform {
private final String fullName;
/** The id. */
private Long id;
@ -36,10 +38,10 @@ abstract class AbstractTxStream extends HierNode implements IWaveform {
protected TextDbLoader loader;
/** The events. */
TreeMap<Long, IEvent[]> events = new TreeMap<>();
IEventList events = new EventList();
/** The concurrency calculated. */
boolean concurrencyCalculated = false;
/** The max concurrency. */
private int rowCount = -1;
/**
* Instantiates a new abstract tx stream.
@ -48,26 +50,29 @@ abstract class AbstractTxStream extends HierNode implements IWaveform {
* @param id the id
* @param name the name
*/
public AbstractTxStream(TextDbLoader loader, Long id, String name) {
protected AbstractTxStream(TextDbLoader loader, Long id, String name) {
super(name);
fullName=name;
this.loader = loader;
this.id = id;
}
/**
* Gets the full hierarchical name.
*
* @return the full name
*/
@Override
public String getFullName() {
return fullName;
}
/**
* Adds the event.
*
* @param evt the evt
*/
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);
}
events.put(evt.getTime(), evt);
}
/**
@ -76,9 +81,7 @@ abstract class AbstractTxStream extends HierNode implements IWaveform {
* @return the events
*/
@Override
public NavigableMap<Long, IEvent[]> getEvents() {
if (!concurrencyCalculated)
calculateConcurrency();
public IEventList getEvents() {
return events;
}
@ -89,9 +92,7 @@ abstract class AbstractTxStream extends HierNode implements IWaveform {
* @return the events at time
*/
@Override
public IEvent[] getEventsAtTime(Long time) {
if (!concurrencyCalculated)
calculateConcurrency();
public IEvent[] getEventsAtTime(long time) {
return events.get(time);
}
@ -102,14 +103,12 @@ abstract class AbstractTxStream extends HierNode implements IWaveform {
* @return the events before time
*/
@Override
public IEvent[] getEventsBeforeTime(Long time) {
if (!concurrencyCalculated)
calculateConcurrency();
Entry<Long, IEvent[]> e = events.floorEntry(time);
public IEvent[] getEventsBeforeTime(long time) {
EventEntry e = events.floorEntry(time);
if (e == null)
return new IEvent[] {};
else
return events.floorEntry(time).getValue();
return events.floorEntry(time).events;
}
/**
@ -128,32 +127,63 @@ abstract class AbstractTxStream extends HierNode implements IWaveform {
* @return the id
*/
@Override
public Long getId() {
public long getId() {
return id;
}
/**
* Gets the width.
*
* @return the width
*/
@Override
public int getRowCount() {
if (rowCount<0)
calculateConcurrency();
return rowCount;
}
/**
* Calculate concurrency.
*/
synchronized void calculateConcurrency() {
if (concurrencyCalculated)
void calculateConcurrency() {
if (rowCount>=0)
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();
ArrayList<Long> rowEndTime = new ArrayList<>();
HashMap<Long, Integer> rowByTxId = new HashMap<>();
for(EventEntry entry: events) {
for(IEvent evt:entry.events) {
TxEvent txEvt = (TxEvent) evt;
ITx tx = txEvt.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;
switch(evt.getKind()) {
case END:
Long txId = txEvt.getTransaction().getId();
txEvt.setConcurrencyIndex(rowByTxId.get(txId));
rowByTxId.remove(txId);
break;
case SINGLE:
for (; rowIdx < rowEndTime.size() && rowEndTime.get(rowIdx)>tx.getBeginTime(); rowIdx++);
if (rowEndTime.size() <= rowIdx)
rowEndTime.add(tx.getEndTime());
else
rowEndTime.set(rowIdx, tx.getEndTime());
((TxEvent) evt).setConcurrencyIndex(rowIdx);
break;
case BEGIN:
for (; rowIdx < rowEndTime.size() && rowEndTime.get(rowIdx)>tx.getBeginTime(); rowIdx++);
if (rowEndTime.size() <= rowIdx)
rowEndTime.add(tx.getEndTime());
else
rowEndTime.set(rowIdx, tx.getEndTime());
((TxEvent) evt).setConcurrencyIndex(rowIdx);
rowByTxId.put(tx.getId(), rowIdx);
break;
}
}
}
rowCount=rowEndTime.size()>0?rowEndTime.size():1;
getChildNodes().parallelStream().forEach(c -> ((TxGenerator)c).calculateConcurrency());
}
}

View File

@ -28,14 +28,15 @@ import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
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.HTreeMap;
import org.mapdb.Serializer;
import com.google.common.collect.HashMultimap;
@ -55,6 +56,13 @@ import com.minres.scviewer.database.tx.ITx;
*/
public class TextDbLoader implements IWaveformDbLoader {
/** the file size limit of a zipped txlog where the loader starts to use a file mapped database */
private static final long MEMMAP_LIMIT=256l*1024l*1024l;
private static final long MAPDB_INITIAL_ALLOC = 512l*1024l*1024l;
private static final long MAPDB_INCREMENTAL_ALLOC = 128l*1024l*1024l;
/** The max time. */
private Long maxTime = 0L;
@ -97,16 +105,61 @@ public class TextDbLoader implements IWaveformDbLoader {
/** The Constant x. */
static final byte[] x = "scv_tr_stream".getBytes();
/**
* Adds the property change listener.
*
* @param l the l
*/
@Override
public void addPropertyChangeListener(PropertyChangeListener l) {
pcs.addPropertyChangeListener(l);
}
/**
* Removes the property change listener.
*
* @param l the l
*/
@Override
public void removePropertyChangeListener(PropertyChangeListener l) {
pcs.removePropertyChangeListener(l);
}
/**
* Gets the max time.
*
* @return the max time
*/
@Override
public Long getMaxTime() {
public long getMaxTime() {
return maxTime;
}
/**
* Gets the transaction.
*
* @param txId the tx id
* @return the transaction
*/
public ITx getTransaction(long txId) {
if (txCache.containsKey(txId))
return txCache.get(txId);
if(transactions.containsKey(txId)) {
Tx tx = new Tx(this, transactions.get(txId));
txCache.put(txId, tx);
return tx;
} else {
throw new IllegalArgumentException();
}
}
public ScvTx getScvTx(long id) {
if(transactions.containsKey(id))
return transactions.get(id);
else
throw new IllegalArgumentException();
}
/**
* Gets the all waves.
*
@ -114,7 +167,18 @@ public class TextDbLoader implements IWaveformDbLoader {
*/
@Override
public Collection<IWaveform> getAllWaves() {
return new ArrayList<>(txStreams.values());
ArrayList<IWaveform> ret = new ArrayList<>(txStreams.values());
ret.addAll(txGenerators.values());
return ret;
}
/**
* Gets the all relation types.
*
* @return the all relation types
*/
public Collection<RelationType> getAllRelationTypes() {
return relationTypes.values();
}
/**
@ -143,6 +207,22 @@ public class TextDbLoader implements IWaveformDbLoader {
return false;
}
/**
* Checks if is gzipped.
*
* @param f the f
* @return true, if is gzipped
*/
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;
}
}
/**
* Load.
*
@ -156,10 +236,9 @@ public class TextDbLoader implements IWaveformDbLoader {
public void load(IWaveformDb db, File file) throws InputFormatException {
dispose();
boolean gzipped = isGzipped(file);
if (file.length() < 75000000 * (gzipped ? 1 : 10)
if (file.length() < MEMMAP_LIMIT * (gzipped ? 1 : 10)
|| "memory".equals(System.getProperty("ScvBackingDB", "file")))
mapDb = DBMaker.memoryDirectDB().allocateStartSize(512l * 1024l * 1024l)
.allocateIncrement(128l * 1024l * 1024l).cleanerHackEnable().make();
mapDb = DBMaker.memoryDirectDB().make();
else {
File mapDbFile;
try {
@ -169,32 +248,21 @@ public class TextDbLoader implements IWaveformDbLoader {
throw new InputFormatException(e.toString());
}
mapDb = DBMaker.fileDB(mapDbFile).fileMmapEnable() // Always enable mmap
.fileMmapEnableIfSupported().fileMmapPreclearDisable().allocateStartSize(512l * 1024l * 1024l)
.allocateIncrement(128l * 1024l * 1024l).cleanerHackEnable().make();
.fileMmapPreclearDisable().allocateStartSize(MAPDB_INITIAL_ALLOC)
.allocateIncrement(MAPDB_INCREMENTAL_ALLOC).cleanerHackEnable().make();
mapDbFile.deleteOnExit();
}
TextDbParser parser = new TextDbParser(this);
try {
parser.txSink = mapDb.treeMap("transactions", Serializer.LONG, Serializer.JAVA).createFromSink();
parser.txSink = mapDb.hashMap("transactions", Serializer.LONG, Serializer.JAVA).create();
parser.parseInput(gzipped ? new GZIPInputStream(new FileInputStream(file)) : new FileInputStream(file));
transactions = parser.txSink.create();
transactions = parser.txSink;
} catch (IllegalArgumentException | ArrayIndexOutOfBoundsException e) {
} catch (Exception e) {
throw new InputFormatException(e.toString());
}
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();
}
txStreams.values().parallelStream().forEach(TxStream::calculateConcurrency);
}
/**
@ -216,31 +284,6 @@ public class TextDbLoader implements IWaveformDbLoader {
}
}
/**
* Checks if is gzipped.
*
* @param f the f
* @return true, if is gzipped
*/
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;
}
}
/**
* Gets the all relation types.
*
* @return the all relation types
*/
public Collection<RelationType> getAllRelationTypes() {
return relationTypes.values();
}
/**
* The Class TextDbParser.
*/
@ -269,7 +312,7 @@ public class TextDbLoader implements IWaveformDbLoader {
HashMap<Long, ScvTx> transactionById = new HashMap<>();
/** The tx sink. */
TreeMapSink<Long, ScvTx> txSink;
HTreeMap<Long, ScvTx> txSink;
/** The reader. */
BufferedReader reader = null;
@ -306,6 +349,11 @@ public class TextDbLoader implements IWaveformDbLoader {
}
if (curLine != null)
parseLine(curLine, nextLine);
for(Entry<Long, ScvTx> e: transactionById.entrySet()) {
ScvTx scvTx = e.getValue();
scvTx.endTime=loader.maxTime;
txSink.put(e.getKey(), scvTx);
}
}
/**
@ -341,10 +389,9 @@ public class TextDbLoader implements IWaveformDbLoader {
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());
String name = tokens[2].substring(1, tokens[2].length()-1);
DataType type = DataType.valueOf(tokens[3]);
String remaining = tokens.length > 5 ? String.join(" ", Arrays.copyOfRange(tokens, 5, tokens.length))
: "";
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])) {
@ -354,8 +401,6 @@ public class TextDbLoader implements IWaveformDbLoader {
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') {
@ -367,7 +412,6 @@ public class TextDbLoader implements IWaveformDbLoader {
nextLine = reader.readLine();
}
}
txSink.put(id, scvTx);
transactionById.put(id, scvTx);
} else if ("tx_end".equals(tokens[0])) {
Long id = Long.parseLong(tokens[1]);
@ -378,18 +422,14 @@ public class TextDbLoader implements IWaveformDbLoader {
TxGenerator gen = loader.txGenerators.get(scvTx.generatorId);
TxStream stream = loader.txStreams.get(gen.stream.getId());
if (scvTx.beginTime == scvTx.endTime) {
TxEvent evt = new TxEvent(loader, EventKind.SINGLE, id, scvTx.beginTime);
stream.addEvent(evt);
gen.addEvent(evt);
stream.addEvent(new TxEvent(loader, EventKind.SINGLE, id, scvTx.beginTime));
gen.addEvent(new TxEvent(loader, EventKind.SINGLE, id, scvTx.beginTime));
} else {
TxEvent begEvt = new TxEvent(loader, EventKind.BEGIN, id, scvTx.beginTime);
stream.addEvent(begEvt);
gen.addEvent(begEvt);
TxEvent endEvt = new TxEvent(loader, EventKind.END, id, scvTx.endTime);
stream.addEvent(endEvt);
gen.addEvent(endEvt);
stream.addEvent(new TxEvent(loader, EventKind.BEGIN, id, scvTx.beginTime));
gen.addEvent(new TxEvent(loader, EventKind.BEGIN, id, scvTx.beginTime));
stream.addEvent(new TxEvent(loader, EventKind.END, id, scvTx.endTime));
gen.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') {
@ -401,6 +441,8 @@ public class TextDbLoader implements IWaveformDbLoader {
nextLine = reader.readLine();
}
}
txSink.put(scvTx.getId(), scvTx);
transactionById.remove(id);
} else if ("tx_relation".equals(tokens[0])) {
Long tr2 = Long.parseLong(tokens[2]);
Long tr1 = Long.parseLong(tokens[3]);
@ -506,38 +548,4 @@ public class TextDbLoader implements IWaveformDbLoader {
}
/**
* Gets the transaction.
*
* @param txId the tx id
* @return the transaction
*/
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;
}
/**
* Adds the property change listener.
*
* @param l the l
*/
@Override
public void addPropertyChangeListener(PropertyChangeListener l) {
pcs.addPropertyChangeListener(l);
}
/**
* Removes the property change listener.
*
* @param l the l
*/
@Override
public void removePropertyChangeListener(PropertyChangeListener l) {
pcs.removePropertyChangeListener(l);
}
}

View File

@ -0,0 +1,77 @@
/*******************************************************************************
* Copyright (c) 2012 IT Just working.
* Copyright (c) 2020 MINRES Technologies GmbH
* 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.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.GZIPInputStream;
import com.minres.scviewer.database.IWaveformDbLoader;
import com.minres.scviewer.database.IWaveformDbLoaderFactory;
/**
* The Class TextDbLoader.
*/
public class TextDbLoaderFactory implements IWaveformDbLoaderFactory {
/** The Constant x. */
static final byte[] x = "scv_tr_stream".getBytes();
/**
* Checks if f is gzipped.
*
* @param f the f
* @return true, if is gzipped
*/
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;
}
}
/**
* Can load.
*
* @param inputFile the input file
* @return true, if successful
*/
@Override
public boolean canLoad(File inputFile) {
if (!inputFile.isDirectory() && inputFile.exists()) {
boolean gzipped = isGzipped(inputFile);
try(InputStream stream = gzipped ? new GZIPInputStream(new FileInputStream(inputFile)) : new FileInputStream(inputFile)){
byte[] buffer = new byte[x.length];
int readCnt = stream.read(buffer, 0, x.length);
if (readCnt == x.length) {
for (int i = 0; i < x.length; i++)
if (buffer[i] != x[i])
return false;
}
return true;
} catch (Exception e) {
return false;
}
}
return false;
}
@Override
public IWaveformDbLoader getLoader() {
return new TextDbLoader();
}
}

View File

@ -19,7 +19,6 @@ 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;
/**
@ -29,9 +28,15 @@ class Tx implements ITx {
/** The loader. */
private final TextDbLoader loader;
private ScvTx scvTx =null;
/** The id. */
private long id;
private final long id;
private final long generatorId;
private final long streamId;
/** The begin time. */
long beginTime = -1;
@ -39,9 +44,6 @@ class Tx implements ITx {
/** The end time. */
long endTime = -1;
/** The concurrency index. */
private int concurrencyIndex;
/**
* Instantiates a new tx.
*
@ -51,6 +53,10 @@ class Tx implements ITx {
public Tx(TextDbLoader loader, ScvTx scvTx) {
this.loader = loader;
id = scvTx.id;
generatorId=scvTx.generatorId;
streamId=scvTx.streamId;
beginTime=scvTx.beginTime;
endTime=scvTx.endTime;
}
/**
@ -59,9 +65,11 @@ class Tx implements ITx {
* @param loader the loader
* @param txId the tx id
*/
public Tx(TextDbLoader loader, long txId) {
public Tx(TextDbLoader loader, long id, long generatorId, long streamId) {
this.loader = loader;
id = txId;
this.id = id;
this.generatorId=generatorId;
this.streamId = streamId;
}
/**
@ -94,11 +102,11 @@ class Tx implements ITx {
*/
@Override
public int compareTo(ITx o) {
int res = getBeginTime().compareTo(o.getBeginTime());
int res = Long.compare(getBeginTime(), o.getBeginTime());
if (res != 0)
return res;
else
return getId().compareTo(o.getId());
return Long.compare(getId(), o.getId());
}
/**
@ -142,7 +150,7 @@ class Tx implements ITx {
* @return the id
*/
@Override
public Long getId() {
public long getId() {
return getScvTx().id;
}
@ -153,7 +161,7 @@ class Tx implements ITx {
*/
@Override
public IWaveform getStream() {
return loader.txStreams.get(getScvTx().streamId);
return loader.txStreams.get(streamId);
}
/**
@ -162,8 +170,8 @@ class Tx implements ITx {
* @return the generator
*/
@Override
public ITxGenerator getGenerator() {
return loader.txGenerators.get(getScvTx().generatorId);
public IWaveform getGenerator() {
return loader.txGenerators.get(generatorId);
}
/**
@ -172,9 +180,12 @@ class Tx implements ITx {
* @return the begin time
*/
@Override
public Long getBeginTime() {
if (beginTime < 0)
beginTime = getScvTx().beginTime;
public long getBeginTime() {
if (beginTime < 0) {
ScvTx tx = scvTx==null?loader.getScvTx(id):getScvTx();
beginTime = tx.beginTime;
endTime = tx.endTime;
}
return beginTime;
}
@ -184,9 +195,12 @@ class Tx implements ITx {
* @return the end time
*/
@Override
public Long getEndTime() {
if (endTime < 0)
endTime = getScvTx().endTime;
public long getEndTime() {
if (endTime < 0) {
ScvTx tx = scvTx==null?loader.getScvTx(id):getScvTx();
beginTime = tx.beginTime;
endTime = tx.endTime;
}
return endTime;
}
@ -199,25 +213,6 @@ class Tx implements ITx {
getScvTx().endTime = time;
}
/**
* Gets the concurrency index.
*
* @return the concurrency index
*/
@Override
public int getConcurrencyIndex() {
return concurrencyIndex;
}
/**
* Sets the concurrency index.
*
* @param idx the new concurrency index
*/
void setConcurrencyIndex(int idx) {
concurrencyIndex = idx;
}
/**
* Gets the attributes.
*
@ -228,12 +223,9 @@ class Tx implements ITx {
return getScvTx().attributes;
}
/**
* Gets the scv tx.
*
* @return the scv tx
*/
private ScvTx getScvTx() {
return loader.transactions.get(id);
if(scvTx==null)
scvTx=loader.getScvTx(id);
return scvTx;
}
}

View File

@ -32,6 +32,7 @@ class TxEvent implements ITxEvent {
/** The time. */
final long time;
private int concurrencyIdx=-1;
/**
* Instantiates a new tx event.
*
@ -94,7 +95,7 @@ class TxEvent implements ITxEvent {
* @return the time
*/
@Override
public Long getTime() {
public long getTime() {
return time;
}
@ -107,4 +108,13 @@ class TxEvent implements ITxEvent {
public ITx getTransaction() {
return loader.getTransaction(transaction);
}
@Override
public int getRowIndex() {
return concurrencyIdx;
}
public void setConcurrencyIndex(int idx) {
concurrencyIdx=idx;
}
}

View File

@ -15,12 +15,11 @@ import java.util.ArrayList;
import java.util.List;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.tx.ITxGenerator;
/**
* The Class TxGenerator.
*/
class TxGenerator extends AbstractTxStream implements ITxGenerator {
class TxGenerator extends AbstractTxStream {
/** The stream. */
TxStream stream;
@ -45,16 +44,6 @@ class TxGenerator extends AbstractTxStream implements ITxGenerator {
stream.addChild(this);
}
/**
* Gets the stream.
*
* @return the stream
*/
@Override
public IWaveform getStream() {
return stream;
}
/**
* Checks if is same.
*
@ -63,7 +52,7 @@ class TxGenerator extends AbstractTxStream implements ITxGenerator {
*/
@Override
public boolean isSame(IWaveform other) {
return (other instanceof TxGenerator && this.getId().equals(other.getId()));
return (other instanceof TxGenerator && this.getId()==other.getId());
}
/**
@ -93,14 +82,15 @@ class TxGenerator extends AbstractTxStream implements ITxGenerator {
public String getKind() {
return stream.getKind();
}
/**
* Gets the width.
* Gets the full hierarchical name.
*
* @return the width
* @return the full name
*/
@Override
public int getWidth() {
return stream.getWidth();
public String getFullName() {
return ((AbstractTxStream)parent).getFullName()+"."+name;
}
}

View File

@ -42,7 +42,7 @@ class TxStream extends AbstractTxStream {
*/
@Override
public boolean isSame(IWaveform other) {
return (other instanceof TxStream && this.getId().equals(other.getId()));
return (other instanceof TxStream && this.getId() == other.getId());
}
/**
@ -55,40 +55,4 @@ class TxStream extends AbstractTxStream {
return kind;
}
/** The max concurrency. */
private int maxConcurrency = 0;
/** The concurrency. */
private int concurrency = 0;
/**
* Sets the concurrency.
*
* @param concurrency the new concurrency
*/
void setConcurrency(int concurrency) {
this.concurrency = concurrency;
if (concurrency > maxConcurrency)
maxConcurrency = concurrency;
}
/**
* Gets the concurrency.
*
* @return the concurrency
*/
int getConcurrency() {
return this.concurrency;
}
/**
* Gets the width.
*
* @return the width
*/
@Override
public int getWidth() {
return maxConcurrency;
}
}

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<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.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="target/classes"/>

View File

@ -9,8 +9,8 @@ org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nul
org.eclipse.jdt.core.compiler.annotation.nullable.secondary=
org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
org.eclipse.jdt.core.compiler.compliance=11
org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
@ -21,6 +21,7 @@ org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
@ -66,6 +67,7 @@ org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=igno
org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
@ -98,5 +100,5 @@ org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
org.eclipse.jdt.core.compiler.release=disabled
org.eclipse.jdt.core.compiler.source=1.8
org.eclipse.jdt.core.compiler.release=enabled
org.eclipse.jdt.core.compiler.source=11

View File

@ -2,9 +2,9 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: SWT database widget
Bundle-SymbolicName: com.minres.scviewer.database.ui.swt
Bundle-Version: 3.0.0.qualifier
Bundle-Version: 4.0.0.qualifier
Bundle-Vendor: MINRES Technologies GmbH
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-RequiredExecutionEnvironment: JavaSE-11
Require-Bundle: org.eclipse.swt;bundle-version="3.103.1",
com.minres.scviewer.database;bundle-version="1.0.0",
com.google.guava;bundle-version="15.0.0",

View File

@ -5,8 +5,8 @@
<parent>
<groupId>com.minres.scviewer</groupId>
<artifactId>com.minres.scviewer.parent</artifactId>
<version>2.11.0</version>
<relativePath>../..</relativePath>
<version>2.14.1</version>
<relativePath>../../..</relativePath>
</parent>
<version>3.0.0-SNAPSHOT</version>
<version>4.0.0-SNAPSHOT</version>
</project>

View File

@ -27,10 +27,14 @@ import com.minres.scviewer.database.tx.ITx;
public interface IWaveformView extends PropertyChangeListener, ISelectionProvider{
String CURSOR_PROPERTY = "cursor_time";
static final String CURSOR_PROPERTY = "cursor_time";
String MARKER_PROPERTY = "marker_time";
static final String MARKER_PROPERTY = "marker_time";
static final int CURSOR_POS = 0;
static final int MARKER_POS = 1;
public static final RelationType NEXT_PREV_IN_STREAM = RelationTypeFactory.create("Prev/Next in stream");
public void addSelectionChangedListener(ISelectionChangedListener listener);
@ -113,6 +117,8 @@ public interface IWaveformView extends PropertyChangeListener, ISelectionProvide
public void scrollHorizontal(int percent);
public void scrollTo(int pos);
public void addDisposeListener( DisposeListener listener );
public void deleteSelectedTracks();

View File

@ -1,14 +1,36 @@
package com.minres.scviewer.database.ui.swt;
import java.text.DecimalFormat;
public class Constants {
public static final String[] UNIT_STRING={"fs", "ps", "ns", "us", "ms"};//, "s"};
public static final int[] UNIT_MULTIPLIER={1, 3, 10, 30, 100, 300};
public static final long[] UNIT_MULTIPLIER={1, 1000, 1000*1000, 1000*1000*1000, 1000*1000*1000*1000, 1000*1000*1000*1000*1000 };
//public static final int[] UNIT_MULTIPLIER={1, 3, 10, 30, 100, 300};
public static final long[] SCALE_MULTIPLIER={1, 2, 5, 10, 20, 50, 100, 200, 500};
public static final String CONTENT_PROVIDER_TAG = "TOOLTIP_CONTENT_PROVIDER";
public static final String HELP_PROVIDER_TAG = "TOOLTIP_HELP_PROVIDER";
public static final DecimalFormat TIME_FORMAT_FS = new DecimalFormat("#");
public static final DecimalFormat TIME_FORMAT_PS = new DecimalFormat("#");
public static final DecimalFormat TIME_FORMAT_NS = new DecimalFormat("#.0##");
public static final DecimalFormat TIME_FORMAT_US = new DecimalFormat("#.0#####");
public static final DecimalFormat TIME_FORMAT_MS = new DecimalFormat("#.0#####");
public static DecimalFormat getTimeFormatForLevel(int level) {
switch(level/SCALE_MULTIPLIER.length) {
case 0: return TIME_FORMAT_FS;
case 1: return TIME_FORMAT_PS;
case 2: return TIME_FORMAT_NS;
case 3: return TIME_FORMAT_US;
case 4: return TIME_FORMAT_MS;
default:
return TIME_FORMAT_FS;
}
}
private Constants() {}
}

View File

@ -10,9 +10,11 @@
*******************************************************************************/
package com.minres.scviewer.database.ui.swt.internal;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
@ -21,8 +23,11 @@ import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Display;
import com.minres.scviewer.database.IEvent;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.RelationType;
import com.minres.scviewer.database.tx.ITx;
import com.minres.scviewer.database.tx.ITxEvent;
import com.minres.scviewer.database.tx.ITxRelation;
import com.minres.scviewer.database.ui.WaveformColors;
@ -32,7 +37,7 @@ public class ArrowPainter implements IPainter {
private int yCtrlOffset = 30;
private WaveformCanvas waveCanvas;
private final WaveformCanvas waveCanvas;
private ITx tx;
@ -48,8 +53,6 @@ public class ArrowPainter implements IPainter {
long scaleFactor;
boolean deferUpdate;
public ArrowPainter(WaveformCanvas waveCanvas, RelationType relationType) {
this.waveCanvas = waveCanvas;
highlightType=relationType;
@ -78,36 +81,47 @@ public class ArrowPainter implements IPainter {
}
}
protected void calculateGeometries() {
deferUpdate = false;
private int getConcurrencyIndex(ITx tx) {
IEvent[] eventList = tx.getStream().getEventsBeforeTime(tx.getBeginTime());
Optional<Integer> res = Arrays.stream(eventList).map(e -> ((ITxEvent)e).getRowIndex()).findFirst();
return res.isPresent()? res.get():0;
}
protected boolean calculateGeometries() {
iRect.clear();
oRect.clear();
IWaveformPainter painter = waveCanvas.wave2painterMap.get(tx.getStream());
if(painter == null)
painter = waveCanvas.wave2painterMap.get(tx.getGenerator());
if (painter == null) { // stream has been added but painter not yet
// created
deferUpdate = true;
return;
return true;
}
int laneHeight = painter.getHeight() / tx.getStream().getWidth();
int laneHeight = painter.getHeight() / tx.getStream().getRowCount();
txRectangle = new Rectangle((int) (tx.getBeginTime() / scaleFactor),
waveCanvas.rulerHeight + painter.getVerticalOffset() + laneHeight * tx.getConcurrencyIndex(),
waveCanvas.rulerHeight + painter.getVerticalOffset() + laneHeight * getConcurrencyIndex(tx),
(int) ((tx.getEndTime() - tx.getBeginTime()) / scaleFactor), laneHeight);
deriveGeom(tx.getIncomingRelations(), iRect, false);
deriveGeom(tx.getOutgoingRelations(), oRect, true);
return false;
}
protected void deriveGeom(Collection<ITxRelation> relations, List<LinkEntry> res, boolean useTarget) {
for (ITxRelation iTxRelation : relations) {
ITx otherTx = useTarget ? iTxRelation.getTarget() : iTxRelation.getSource();
if (waveCanvas.wave2painterMap.containsKey(otherTx.getStream())) {
IWaveformPainter painter = waveCanvas.wave2painterMap.get(otherTx.getStream());
int height = waveCanvas.styleProvider.getTrackHeight();
Rectangle bb = new Rectangle(
(int) (otherTx.getBeginTime() / scaleFactor),
waveCanvas.rulerHeight + painter.getVerticalOffset() + height * otherTx.getConcurrencyIndex(),
(int) ((otherTx.getEndTime() - otherTx.getBeginTime()) / scaleFactor),
height);
res.add(new LinkEntry(bb, iTxRelation.getRelationType()));
for(IWaveform iWaveform: new IWaveform[]{otherTx.getStream(), otherTx.getGenerator()}) {
if (waveCanvas.wave2painterMap.containsKey(iWaveform)) {
IWaveformPainter painter = waveCanvas.wave2painterMap.get(iWaveform);
if(painter!=null) {
int height = waveCanvas.styleProvider.getTrackHeight();
Rectangle bb = new Rectangle(
(int) (otherTx.getBeginTime() / scaleFactor),
waveCanvas.rulerHeight + painter.getVerticalOffset() + height * getConcurrencyIndex(otherTx),
(int) ((otherTx.getEndTime() - otherTx.getBeginTime()) / scaleFactor),
height);
res.add(new LinkEntry(bb, iTxRelation.getRelationType()));
}
}
}
}
}
@ -119,11 +133,9 @@ public class ArrowPainter implements IPainter {
Color highliteColor = waveCanvas.styleProvider.getColor(WaveformColors.REL_ARROW_HIGHLITE);
if(tx==null) return;
if (!deferUpdate) {
scaleFactor = waveCanvas.getScaleFactor();
calculateGeometries();
}
if(deferUpdate) return;
scaleFactor = waveCanvas.getScaleFactor();
if(calculateGeometries())
return;
int correctionValue = (int)(selectionOffset);
Rectangle correctedTargetRectangle = new Rectangle(txRectangle.x+correctionValue, txRectangle.y, txRectangle.width, txRectangle.height);
for (LinkEntry entry : iRect) {

View File

@ -15,6 +15,7 @@ import org.eclipse.swt.graphics.Rectangle;
import com.minres.scviewer.database.ui.ICursor;
import com.minres.scviewer.database.ui.WaveformColors;
import com.minres.scviewer.database.ui.swt.Constants;
public class CursorPainter implements IPainter, ICursor {
@ -84,7 +85,7 @@ public class CursorPainter implements IPainter, ICursor {
proj.setBackground(drawColor);
proj.setForeground(textColor);
double dTime=time;
proj.drawText((dTime/waveCanvas.getScaleFactorPow10())+waveCanvas.getUnitStr(), x+1, top);
proj.drawText(Constants.getTimeFormatForLevel(waveCanvas.getZoomLevel()).format(dTime/waveCanvas.getScaleFactorPow10())+waveCanvas.getUnitStr(), x+1, top);
}
}
}

View File

@ -10,22 +10,20 @@
*******************************************************************************/
package com.minres.scviewer.database.ui.swt.internal;
import java.text.DecimalFormat;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.wb.swt.SWTResourceManager;
import com.minres.scviewer.database.ui.swt.Constants;
public class RulerPainter implements IPainter {
protected WaveformCanvas waveCanvas;
protected final WaveformCanvas waveCanvas;
static final int RULER_TICK_MINOR = 10;
static final int RULER_TICK_MAJOR = 100;
static final DecimalFormat df = new DecimalFormat("#.00####");
public RulerPainter(WaveformCanvas waveCanvas) {
this.waveCanvas=waveCanvas;
}
@ -40,7 +38,7 @@ public class RulerPainter implements IPainter {
if(headerBgColor.isDisposed())
headerBgColor=SWTResourceManager.getColor(255,255,255);
String unit=waveCanvas.getUnitStr();
int unitMultiplier=waveCanvas.getUnitMultiplier();
long unitMultiplier=waveCanvas.getUnitMultiplier();
long scaleFactor=waveCanvas.getScaleFactor();
long startPos=area.x*scaleFactor;
@ -52,7 +50,7 @@ public class RulerPainter implements IPainter {
int minorTickY = waveCanvas.rulerHeight-5;
int majorTickY = waveCanvas.rulerHeight-15;
int textY=waveCanvas.rulerHeight-20;
int textY=waveCanvas.rulerHeight-30;
int baselineY=waveCanvas.rulerHeight - 1;
int bottom=waveCanvas.rulerHeight - 2;
@ -66,13 +64,22 @@ public class RulerPainter implements IPainter {
gc.fillRectangle(new Rectangle(area.x, area.y, area.width, baselineY));
gc.setForeground(headerFgColor);
gc.drawLine(area.x, area.y+bottom, area.x+area.width, area.y+bottom);
boolean allMarker=true;
for (long pos = startMinorIncrPos, tick = startMinorIncrVal; pos < endPos; pos+= rulerTickMinor, tick += rulerTickMinor) {
if ((tick % rulerTickMajor) == 0) {
String text = Constants.getTimeFormatForLevel(waveCanvas.getZoomLevel()).format(tick/scaleFactor*unitMultiplier);
if(text.length()>8) allMarker=false;
}
}
boolean drawText = true;
for (long pos = startMinorIncrPos, tick = startMinorIncrVal; pos < endPos; pos+= rulerTickMinor, tick += rulerTickMinor) {
int x0Pos = (int) (pos/scaleFactor);
long x0Val = tick/scaleFactor;
if ((tick % rulerTickMajor) == 0) {
gc.drawText(df.format(x0Val*unitMultiplier)+unit, x0Pos, area.y+textY);
if(allMarker || drawText)
gc.drawText(Constants.getTimeFormatForLevel(waveCanvas.getZoomLevel()).format(x0Val*unitMultiplier)+unit, x0Pos, area.y+textY);
gc.drawLine(x0Pos, area.y+majorTickY, x0Pos,area.y+ bottom);
drawText=!drawText;
} else {
gc.drawLine(x0Pos, area.y+minorTickY, x0Pos, area.y+bottom);
}

View File

@ -12,8 +12,6 @@ package com.minres.scviewer.database.ui.swt.internal;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map.Entry;
import java.util.NavigableMap;
import javax.swing.JPanel;
@ -26,7 +24,9 @@ import org.eclipse.swt.graphics.Rectangle;
import com.minres.scviewer.database.BitVector;
import com.minres.scviewer.database.DoubleVal;
import com.minres.scviewer.database.EventEntry;
import com.minres.scviewer.database.IEvent;
import com.minres.scviewer.database.IEventList;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.ui.TrackEntry;
import com.minres.scviewer.database.ui.WaveformColors;
@ -37,16 +37,16 @@ public class SignalPainter extends TrackPainter {
IEvent value;
boolean fromMap;
public SignalChange(Entry<Long, IEvent[]> entry) {
time = entry.getKey();
value = entry.getValue()[0];
public SignalChange(EventEntry entry) {
time = entry.timestamp;
value = entry.events[0];
fromMap = true;
}
public void set(Entry<Long, IEvent[]> entry, Long actTime) {
public void set(EventEntry entry, Long actTime) {
if (entry != null) {
time = entry.getKey();
value = entry.getValue()[0];
time = entry.timestamp;
value = entry.events[0];
fromMap = true;
} else {
time = actTime;
@ -100,21 +100,16 @@ public class SignalPainter extends TrackPainter {
long beginTime = beginPos*scaleFactor;
long endTime = beginTime + area.width*scaleFactor;
Entry<Long, IEvent[]> first = signal.getEvents().floorEntry(beginTime);
Entry<Long, IEvent[]> last = signal.getEvents().floorEntry(endTime);
if (first == null) {
if (last == null)
return;
EventEntry first = signal.getEvents().floorEntry(beginTime);
if (first == null)
first = signal.getEvents().firstEntry();
} else if (last == null) {
last = signal.getEvents().lastEntry();
}
beginTime = first.timestamp;
proj.setForeground(this.waveCanvas.styleProvider.getColor(WaveformColors.LINE));
proj.setLineStyle(SWT.LINE_SOLID);
proj.setLineWidth(1);
NavigableMap<Long, IEvent[]> entries = signal.getEvents().subMap(first.getKey(), false, last.getKey(), true);
SignalChange left = new SignalChange(first);
SignalChange right = new SignalChange(entries.size() > 0 ? entries.firstEntry() : first);
IEventList entries = signal.getEvents().subMap(beginTime, true, endTime);
SignalChange left = new SignalChange(entries.firstEntry());
SignalChange right = new SignalChange(entries.size() > 1 ? entries.higherEntry(left.time) : entries.firstEntry());
maxPosX = area.x + area.width;
yOffsetT = this.waveCanvas.styleProvider.getTrackHeight() / 5 + area.y;
yOffsetM = this.waveCanvas.styleProvider.getTrackHeight() / 2 + area.y;
@ -153,15 +148,15 @@ public class SignalPainter extends TrackPainter {
if (xSigChangeEndPos == xSigChangeBeginPos) {
multiple = true;
long eTime = (xSigChangeBeginPos + 1) * this.waveCanvas.getScaleFactor();
Entry<Long, IEvent[]> entry = entries.floorEntry(eTime);
if(entry!=null && entry.getKey()> right.time)
EventEntry entry = entries.floorEntry(eTime);
if(entry!=null && entry.timestamp> right.time)
right.set(entry, endTime);
xSigChangeEndPos = getXPosEnd(eTime);
}
} while (left.time < endTime);
}
private SignalStencil getStencil(GC gc, SignalChange left, NavigableMap<Long, IEvent[]> entries) {
private SignalStencil getStencil(GC gc, SignalChange left, IEventList entries) {
IEvent val = left.value;
if(val instanceof BitVector) {
BitVector bv = (BitVector) val;
@ -253,15 +248,15 @@ public class SignalPainter extends TrackPainter {
private long maxVal;
private long minVal;
double yRange = (yOffsetB-yOffsetT);
public MultiBitStencilAnalog(NavigableMap<Long, IEvent[]> entries, Object left, boolean continous, boolean signed) {
public MultiBitStencilAnalog(IEventList entries, Object left, boolean continous, boolean signed) {
this.continous=continous;
this.signed=signed;
Collection<IEvent[]> values = entries.values();
Collection<EventEntry> ievents = entries.entrySet();
minVal=signed?((BitVector)left).toSignedValue():((BitVector)left).toUnsignedValue();
if(!values.isEmpty()) {
if(!ievents.isEmpty()) {
maxVal=minVal;
for (IEvent[] tp : entries.values())
for(IEvent e: tp) {
for (EventEntry tp : ievents)
for(IEvent e: tp.events) {
long v = signed?((BitVector)e).toSignedValue():((BitVector)e).toUnsignedValue();
maxVal=Math.max(maxVal, v);
minVal=Math.min(minVal, v);
@ -358,15 +353,15 @@ public class SignalPainter extends TrackPainter {
boolean continous=true;
public RealStencil(NavigableMap<Long, IEvent[]> entries, Object left, boolean continous) {
public RealStencil(IEventList entries, Object left, boolean continous) {
this.continous=continous;
Collection<IEvent[]> values = entries.values();
Collection<EventEntry> values = entries.entrySet();
minVal=(Double) left;
range=2.0;
if(!values.isEmpty()) {
double maxVal=minVal;
for (IEvent[] val : entries.values())
for(IEvent e:val) {
for (EventEntry val : values)
for(IEvent e:val.events) {
double v = ((DoubleVal)e).value;
if(Double.isNaN(maxVal))
maxVal=v;

View File

@ -10,18 +10,17 @@
*******************************************************************************/
package com.minres.scviewer.database.ui.swt.internal;
import java.util.Collection;
import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.TreeSet;
import java.util.TreeMap;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import com.minres.scviewer.database.EventEntry;
import com.minres.scviewer.database.EventKind;
import com.minres.scviewer.database.IEvent;
import com.minres.scviewer.database.IEventList;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.tx.ITx;
import com.minres.scviewer.database.tx.ITxEvent;
@ -37,19 +36,27 @@ public class StreamPainter extends TrackPainter{
private IWaveform stream;
private int txBase;
private int txHeight;
private TreeSet<ITx> seenTx;
// TODO: remove TreeMap usage
private TreeMap<ITx, ITxEvent> seenTx;
public StreamPainter(WaveformCanvas waveCanvas, boolean even, TrackEntry trackEntry) {
super(trackEntry, even);
this.waveCanvas = waveCanvas;
this.stream=trackEntry.waveform;
this.seenTx=new TreeSet<>();
this.seenTx=new TreeMap<>();
}
@SuppressWarnings("unchecked")
public void paintArea(Projection proj, Rectangle area) {
if(stream.getEvents().size()==0) return;
int trackHeight=trackEntry.height/stream.getWidth();
int trackHeight=trackEntry.height/stream.getRowCount();
if(stream.getEvents().size()==0) {
proj.setFillRule(SWT.FILL_EVEN_ODD);
proj.setLineStyle(SWT.LINE_SOLID);
proj.setLineWidth(1);
proj.setForeground(this.waveCanvas.styleProvider.getColor(WaveformColors.LINE));
for( int y1=area.y+trackHeight/2; y1<area.y+trackEntry.height; y1+=trackHeight)
proj.drawLine(area.x, y1, area.x+area.width, y1);
return;
}
txBase=trackHeight/5;
txHeight=trackHeight*3/5;
if(trackEntry.selected) {
@ -65,10 +72,11 @@ public class StreamPainter extends TrackPainter{
long beginTime = beginPos*scaleFactor;
long endTime = beginTime + area.width*scaleFactor;
Entry<Long, ?> firstTx=stream.getEvents().floorEntry(beginTime);
Entry<Long, ?> lastTx=stream.getEvents().ceilingEntry(endTime);
if(firstTx==null) firstTx = stream.getEvents().firstEntry();
if(lastTx==null) lastTx=stream.getEvents().lastEntry();
IEventList events = stream.getEvents();
EventEntry firstTx = events.floorEntry(beginTime);
EventEntry lastTx = events.ceilingEntry(endTime);
if(firstTx==null) firstTx = events.firstEntry();
if(lastTx==null) lastTx = events.lastEntry();
proj.setFillRule(SWT.FILL_EVEN_ODD);
proj.setLineStyle(SWT.LINE_SOLID);
proj.setLineWidth(1);
@ -77,46 +85,50 @@ public class StreamPainter extends TrackPainter{
for( int y1=area.y+trackHeight/2; y1<area.y+trackEntry.height; y1+=trackHeight)
proj.drawLine(area.x, y1, area.x+area.width, y1);
if(firstTx==lastTx) {
for(ITxEvent txEvent:(Collection<? extends ITxEvent>)firstTx.getValue())
drawTx(proj, area, txEvent.getTransaction(), false);
for(IEvent txEvent: firstTx.events)
drawTx(proj, area, ((ITxEvent)txEvent).getTransaction(), ((ITxEvent)txEvent).getRowIndex(), false);
}else{
seenTx.clear();
NavigableMap<Long, IEvent[]> entries = stream.getEvents().subMap(firstTx.getKey(), true, lastTx.getKey(), true);
boolean highlighed=false;
ITxEvent highlighed=null;
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()){
ITx tx = ((ITxEvent) evt).getTransaction();
highlighed|=selectedId==tx.getId();
for(EventEntry entry: events.subMap(firstTx.timestamp, true, lastTx.timestamp))
for(IEvent e:entry.events){
ITxEvent evt = (ITxEvent) e;
ITx tx = evt.getTransaction();
if(selectedId==tx.getId())
highlighed=evt;
switch(evt.getKind()) {
case BEGIN:
seenTx.add(tx);
seenTx.put(tx, evt);
break;
case END:
drawTx(proj, area, tx, evt.getRowIndex(), false);
seenTx.remove(tx);
break;
case SINGLE:
drawTx(proj, area, tx, false);
drawTx(proj, area, tx, evt.getRowIndex(), false);
break;
}
}
for(ITx tx:seenTx){
drawTx(proj, area, tx, false);
}
if(highlighed){
seenTx.entrySet().stream().forEach(e -> {
drawTx(proj, area, e.getKey(), e.getValue().getRowIndex(), false);
});
if(highlighed!=null){
proj.setForeground(this.waveCanvas.styleProvider.getColor(WaveformColors.LINE_HIGHLITE));
drawTx(proj, area, waveCanvas.currentSelection, true);
drawTx(proj, area, highlighed.getTransaction(), highlighed.getRowIndex(), true);
}
}
}
protected void drawTx(Projection proj, Rectangle area, ITx tx, boolean highlighted ) {
protected void drawTx(Projection proj, Rectangle area, ITx tx, int concurrencyIndex, boolean highlighted ) {
// compute colors
Color[] transColor = waveCanvas.styleProvider.computeColor( tx.getGenerator().getName());
proj.setBackground(transColor[highlighted?1:0]);
int offset = tx.getConcurrencyIndex()*this.waveCanvas.styleProvider.getTrackHeight();
int offset = concurrencyIndex*this.waveCanvas.styleProvider.getTrackHeight();
Rectangle bb = new Rectangle(
(int)(tx.getBeginTime()/this.waveCanvas.getScaleFactor()), area.y+offset+txBase,
(int)((tx.getEndTime()-tx.getBeginTime())/this.waveCanvas.getScaleFactor()), txHeight);
@ -143,12 +155,12 @@ public class StreamPainter extends TrackPainter{
public ITx getClicked(Point point) {
int lane=point.y/waveCanvas.styleProvider.getTrackHeight();
Entry<Long, IEvent[]> firstTx=stream.getEvents().floorEntry(point.x*waveCanvas.getScaleFactor());
EventEntry firstTx=stream.getEvents().floorEntry(point.x*waveCanvas.getScaleFactor());
if(firstTx!=null){
do {
ITx tx = getTxFromEntry(lane, point.x, firstTx);
ITx tx = getTxFromEntry(lane, point.x, firstTx.events);
if(tx!=null) return tx;
firstTx=stream.getEvents().lowerEntry(firstTx.getKey());
firstTx=stream.getEvents().lowerEntry(firstTx.timestamp);
}while(firstTx!=null);
}
return null;
@ -162,27 +174,21 @@ public class StreamPainter extends TrackPainter{
this.stream = stream;
}
protected ITx getTxFromEntry(int lane, int offset, Entry<Long, IEvent[]> firstTx) {
protected ITx getTxFromEntry(int lane, int offset, IEvent[] firstTx) {
long timePoint=offset*waveCanvas.getScaleFactor();
for(IEvent evt:firstTx.getValue()){
if(evt instanceof ITxEvent) {
ITx tx=((ITxEvent)evt).getTransaction();
if((evt.getKind()==EventKind.BEGIN || evt.getKind()==EventKind.SINGLE)&&
tx.getConcurrencyIndex()==lane && tx.getBeginTime()<=timePoint && tx.getEndTime()>=timePoint){
return ((ITxEvent)evt).getTransaction();
}
}
}
// now with some fuzziness
timePoint=(offset-5)*waveCanvas.getScaleFactor();
long timePointLow=(offset-5)*waveCanvas.getScaleFactor();
long timePointHigh=(offset+5)*waveCanvas.getScaleFactor();
for(IEvent evt:firstTx.getValue()){
if(evt instanceof ITxEvent) {
ITx tx=((ITxEvent)evt).getTransaction();
if((evt.getKind()==EventKind.BEGIN || evt.getKind()==EventKind.SINGLE) &&
tx.getConcurrencyIndex()==lane && tx.getBeginTime()<=timePointHigh && tx.getEndTime()>=timePoint){
return ((ITxEvent)evt).getTransaction();
}
for(IEvent e:firstTx){
if(e instanceof ITxEvent) {
ITxEvent evt = (ITxEvent) e;
ITx tx=evt.getTransaction();
if(
(evt.getKind()==EventKind.SINGLE && evt.getTime()==timePoint) ||
(evt.getKind()==EventKind.SINGLE && evt.getTime()>timePointLow && evt.getTime()<timePointHigh) ||
(evt.getKind()==EventKind.BEGIN && evt.getRowIndex()==lane && evt.getTime()<=timePoint && tx.getEndTime()>=timePoint)
){
return tx;
}
}
}
return null;

View File

@ -11,10 +11,12 @@
package com.minres.scviewer.database.ui.swt.internal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;
import java.util.Optional;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlAdapter;
@ -32,9 +34,12 @@ import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.ScrollBar;
import com.google.common.collect.Lists;
import com.minres.scviewer.database.EventEntry;
import com.minres.scviewer.database.IEvent;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.RelationType;
import com.minres.scviewer.database.tx.ITx;
import com.minres.scviewer.database.tx.ITxEvent;
import com.minres.scviewer.database.ui.IWaveformStyleProvider;
import com.minres.scviewer.database.ui.IWaveformView;
import com.minres.scviewer.database.ui.TrackEntry;
@ -165,7 +170,7 @@ public class WaveformCanvas extends Canvas {
}
public int getMaxZoomLevel(){
return Constants.UNIT_MULTIPLIER.length*Constants.UNIT_STRING.length-1;
return Constants.SCALE_MULTIPLIER.length*Constants.UNIT_STRING.length-1;
}
public void setZoomLevel(int level) {
@ -174,12 +179,21 @@ public class WaveformCanvas extends Canvas {
}
public void setZoomLevel(int level, long centerTime) {
if(level<0) {
if(level<-1) {
long cTime = getCursorPainters().get(0).getTime();
long time_diff = centerTime>cTime?centerTime-cTime:cTime-centerTime;
level = findFitZoomLevel(time_diff);
centerTime = (centerTime>cTime?cTime:centerTime)+time_diff/2;
} else
level = findFitZoomLevel(maxTime);
if(level<0) level = 0;
}
//FIXME: keep center if zoom-out and cursor is not in view
long oldScaleFactor=scaleFactor;
if(level<0) level = 0;
if(level<Constants.UNIT_MULTIPLIER.length*Constants.UNIT_STRING.length){
this.scaleFactor = (long) Math.pow(10, level/2d);
if(level%2==1) this.scaleFactor*=3;
if(level<Constants.SCALE_MULTIPLIER.length*Constants.UNIT_STRING.length){
int scale = level%Constants.SCALE_MULTIPLIER.length;
int unit = level/Constants.SCALE_MULTIPLIER.length;
this.scaleFactor = Constants.UNIT_MULTIPLIER[unit]*Constants.SCALE_MULTIPLIER[scale];
ITx tx = arrowPainter.getTx();
arrowPainter.setTx(null);
/*
@ -188,8 +202,9 @@ public class WaveformCanvas extends Canvas {
* xcn = tc/newScaleFactor
* t0n = (xcn-xoffs)*scaleFactor
*/
long xc=centerTime/oldScaleFactor; // cursor total x-offset
long xoffs=xc+origin.x; // cursor offset relative to left border
Rectangle clientArea = getClientArea();
long clientAreaWidth = clientArea.width;
long xoffs = clientAreaWidth/2;
long xcn=centerTime/scaleFactor; // new total x-offset
long originX=xcn-xoffs;
if(originX>0) {
@ -204,22 +219,39 @@ public class WaveformCanvas extends Canvas {
}
}
private int findFitZoomLevel(long duration) {
//get area actually capable of displaying data, i.e. area of the receiver which is capable of displaying data
Rectangle clientArea = getClientArea();
long clientAreaWidth = clientArea.width;
//try to find existing zoomlevel where scaleFactor*clientAreaWidth >= maxTime, if one is found set it as new zoomlevel
for(int unitIdx=0; unitIdx<Constants.UNIT_STRING.length; unitIdx++) {
long magnitudeMultiplier = Constants.UNIT_MULTIPLIER[unitIdx];
for (int scaleIdx=0; scaleIdx<Constants.SCALE_MULTIPLIER.length; scaleIdx++){
long scaleFactor = magnitudeMultiplier * Constants.SCALE_MULTIPLIER[scaleIdx];
long range = scaleFactor*clientAreaWidth;
if( range >= duration)
return unitIdx*Constants.SCALE_MULTIPLIER.length+scaleIdx;
}
}
return -1;
}
public long getScaleFactor() {
return scaleFactor;
}
public long getScaleFactorPow10() {
int scale = level/Constants.UNIT_MULTIPLIER.length;
int scale = level/Constants.SCALE_MULTIPLIER.length;
double res = Math.pow(1000, scale);
return (long) res;
}
public String getUnitStr(){
return Constants.UNIT_STRING[level/Constants.UNIT_MULTIPLIER.length];
return Constants.UNIT_STRING[level/Constants.SCALE_MULTIPLIER.length];
}
public int getUnitMultiplier(){
return Constants.UNIT_MULTIPLIER[level%Constants.UNIT_MULTIPLIER.length];
public long getUnitMultiplier(){
return Constants.SCALE_MULTIPLIER[level%Constants.SCALE_MULTIPLIER.length];
}
public long getTimeForOffset(int xOffset){
@ -424,13 +456,17 @@ public class WaveformCanvas extends Canvas {
}
for (IWaveformPainter painter : wave2painterMap.values()) {
if (painter instanceof StreamPainter && ((StreamPainter) painter).getStream() == tx.getStream()) {
int top = painter.getVerticalOffset() + styleProvider.getTrackHeight() * tx.getConcurrencyIndex();
int bottom = top + styleProvider.getTrackHeight();
if (top < -origin.y) {
setOrigin(origin.x, -(top-styleProvider.getTrackHeight()));
} else if (bottom > (size.y - origin.y)) {
setOrigin(origin.x, size.y - bottom);
}
EventEntry entry = tx.getStream().getEvents().floorEntry(tx.getBeginTime());
Optional<IEvent> res = Arrays.stream(entry.events).filter(e -> ((ITxEvent)e).getTransaction().equals(tx)).findFirst();
if(res.isPresent()) {
int top = painter.getVerticalOffset() + styleProvider.getTrackHeight() * ((ITxEvent)res.get()).getRowIndex();
int bottom = top + styleProvider.getTrackHeight();
if (top < -origin.y) {
setOrigin(origin.x, -(top-styleProvider.getTrackHeight()));
} else if (bottom > (size.y - origin.y)) {
setOrigin(origin.x, size.y - bottom);
}
}
}
}
}
@ -467,6 +503,12 @@ public class WaveformCanvas extends Canvas {
}
}
public void centerAt(long time) {
int scaledTime = (int) (time / scaleFactor);
int newX = -scaledTime+getWidth()/2;
setOrigin(newX>0?0:newX, origin.y);
}
public int getRulerHeight() {
return rulerHeight;
}

View File

@ -13,7 +13,6 @@ package com.minres.scviewer.database.ui.swt.internal;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@ -21,7 +20,6 @@ import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.TreeMap;
@ -77,8 +75,10 @@ import org.eclipse.wb.swt.SWTResourceManager;
import com.google.common.collect.Lists;
import com.minres.scviewer.database.BitVector;
import com.minres.scviewer.database.DoubleVal;
import com.minres.scviewer.database.EventEntry;
import com.minres.scviewer.database.EventKind;
import com.minres.scviewer.database.IEvent;
import com.minres.scviewer.database.IEventList;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.RelationType;
import com.minres.scviewer.database.WaveformType;
@ -98,8 +98,6 @@ public class WaveformView implements IWaveformView {
private PropertyChangeSupport pcs;
static final DecimalFormat df = new DecimalFormat("#0.00####");
private ITx currentTxSelection;
private ArrayList<TrackEntry> currentWaveformSelection = new ArrayList<>();
@ -124,6 +122,12 @@ public class WaveformView implements IWaveformView {
protected ObservableList<TrackEntry> streams;
private boolean waveformsContainTx=false;
public boolean isWaveformsContainTx() {
return waveformsContainTx;
}
int selectedMarker = 0;
private int tracksVerticalHeight;
@ -163,7 +167,7 @@ public class WaveformView implements IWaveformView {
setSelection(new StructuredSelection(res), (e.stateMask & SWT.CTRL) != 0, false);
} else
setSelection(new StructuredSelection(entry.getValue()), (e.stateMask & SWT.CTRL) != 0,
false);
false);
} else {
setSelection(new StructuredSelection(entry.getValue()), (e.stateMask & SWT.CTRL) != 0, false);
}
@ -196,88 +200,93 @@ public class WaveformView implements IWaveformView {
down = false;
if (start == null)
return;
if ((e.stateMask & SWT.MODIFIER_MASK & ~SWT.SHIFT) != 0)
return; // don't react on modifier except shift
if (e.button == 1 && Math.abs(e.x - start.x) > 3) {
asyncUpdate(e.widget);
long startTime = waveformCanvas.getTimeForOffset(start.x);
long endTime = waveformCanvas.getTimeForOffset(end.x);
long targetTimeRange = endTime - startTime;
long currentTimeRange = waveformCanvas.getMaxVisibleTime() - waveformCanvas.getMinVisibleTime();
if (targetTimeRange == 0)
return;
long relation = currentTimeRange / targetTimeRange;
long i = 1;
int level = 0;
do {
if (relation < 0) {
if (-relation < i) {
break;
}
level--;
if (-relation < i * 3) {
break;
}
level--;
} else {
if (relation < i) {
break;
}
level++;
if (relation < i * 3) {
break;
}
level++;
}
i = i * 10;
} while (i < 10000);
if (i < 10000) {
int curLevel = waveformCanvas.getZoomLevel();
waveformCanvas.setZoomLevel(curLevel - level, (startTime + endTime) / 2);
}
} else if (e.button == 1 && ((e.stateMask & SWT.SHIFT) == 0)) {
// set cursor (button 1 and no shift)
if (Math.abs(e.x - start.x) < 3 && Math.abs(e.y - start.y) < 3) {
// first set cursor time
setCursorTime(snapOffsetToEvent(start));
// then set selection and reveal
setSelection(new StructuredSelection(initialSelected));
if ((e.stateMask & SWT.MODIFIER_MASK & ~(SWT.SHIFT | SWT.CTRL)) != 0)
return; // don't react on modifier except shift and control
boolean isCtrl = (e.stateMask & SWT.CTRL)!=0;
boolean isShift = (e.stateMask & SWT.SHIFT)!=0;
if (e.button == 1) {
if (Math.abs(e.x - start.x) > 3) { // was drag event
asyncUpdate(e.widget);
long startTime = waveformCanvas.getTimeForOffset(start.x);
long endTime = waveformCanvas.getTimeForOffset(end.x);
long targetTimeRange = endTime - startTime;
long currentTimeRange = waveformCanvas.getMaxVisibleTime() - waveformCanvas.getMinVisibleTime();
if (targetTimeRange == 0)
return;
long relation = currentTimeRange / targetTimeRange;
long i = 1;
int level = 0;
do {
if (relation < 0) {
if (-relation < i) {
break;
}
level--;
if (-relation < i * 3) {
break;
}
level--;
} else {
if (relation < i) {
break;
}
level++;
if (relation < i * 3) {
break;
}
level++;
}
i = i * 10;
} while (i < 10000);
if (i < 10000) {
int curLevel = waveformCanvas.getZoomLevel();
waveformCanvas.setZoomLevel(curLevel - level, (startTime + endTime) / 2);
}
} else if( isShift) { // set marker (button 1 and shift)
setMarkerTime(snapOffsetToEvent(start), selectedMarker);
} else if(isCtrl) { // set cursor (button 1 and ctrl)
setCursorTime(snapOffsetToEvent(start));
} else { // set cursor (button 1 only)
if (Math.abs(e.y - start.y) < 3) {
// first set cursor time
setCursorTime(snapOffsetToEvent(start));
// then set selection and reveal
setSelection(new StructuredSelection(initialSelected));
}
}
} else if (e.button == 2 || (e.button == 1 && (e.stateMask & SWT.SHIFT) != 0)) {
// set marker (button 1 and shift)
} else if (e.button == 2) { // set marker (button 2)
setMarkerTime(snapOffsetToEvent(start), selectedMarker);
asyncUpdate(e.widget);
}
asyncUpdate(e.widget);
}
protected long snapOffsetToEvent(Point p) {
long time = waveformCanvas.getTimeForOffset(p.x);
long scaling = 5 * waveformCanvas.getScaleFactor();
for (Object o : waveformCanvas.getElementsAt(p)) {
Entry<Long, IEvent[]> floorEntry = null;
Entry<Long, IEvent[]> ceilEntry = null;
EventEntry floorEntry = null;
EventEntry ceilEntry = null;
if (o instanceof TrackEntry) {
TrackEntry entry = (TrackEntry) o;
NavigableMap<Long, IEvent[]> map = entry.waveform.getEvents();
IEventList map = entry.waveform.getEvents();
floorEntry = map.floorEntry(time);
ceilEntry = map.ceilingEntry(time);
} else if (o instanceof ITx) {
NavigableMap<Long, IEvent[]> map = ((ITx) o).getStream().getEvents();
IEventList map = ((ITx) o).getStream().getEvents();
floorEntry = map.floorEntry(time);
ceilEntry = map.ceilingEntry(time);
}
if (floorEntry != null && time - floorEntry.getKey() > scaling)
if (floorEntry != null && time - floorEntry.timestamp > scaling)
floorEntry = null;
if (ceilEntry != null && ceilEntry.getKey() - time > scaling)
if (ceilEntry != null && ceilEntry.timestamp - time > scaling)
ceilEntry = null;
if (ceilEntry == null && floorEntry != null) {
time = floorEntry.getKey();
time = floorEntry.timestamp;
} else if (ceilEntry != null && floorEntry == null) {
time = ceilEntry.getKey();
time = ceilEntry.timestamp;
} else if (ceilEntry != null && floorEntry != null) {
time = time - floorEntry.getKey() < ceilEntry.getKey() - time ? floorEntry.getKey()
: ceilEntry.getKey();
time = time - floorEntry.timestamp < ceilEntry.timestamp - time ? floorEntry.timestamp
: ceilEntry.timestamp;
}
}
return time;
@ -286,8 +295,8 @@ public class WaveformView implements IWaveformView {
@Override
public void handleEvent(Event e) {
switch (e.type) {
case SWT.MouseWheel:
break;
// case SWT.MouseWheel:
// break;
case SWT.MouseDown:
start = new Point(e.x, e.y);
end = new Point(e.x, e.y);
@ -509,13 +518,15 @@ public class WaveformView implements IWaveformView {
boolean even = true;
TextLayout tl = new TextLayout(waveformCanvas.getDisplay());
tl.setFont(styleProvider.getNameFont());
waveformsContainTx=false;
for (TrackEntry streamEntry : streams) {
streamEntry.height = styleProvider.getTrackHeight();
streamEntry.vOffset = tracksVerticalHeight;
if (streamEntry.waveform.getType() == WaveformType.TRANSACTION) {
streamEntry.currentValue = "";
streamEntry.height *= streamEntry.waveform.getWidth();
streamEntry.height *= streamEntry.waveform.getRowCount();
painter = new StreamPainter(waveformCanvas, even, streamEntry);
waveformsContainTx=true;
} else if (streamEntry.waveform.getType() == WaveformType.SIGNAL) {
streamEntry.currentValue = "---";
painter = new SignalPainter(waveformCanvas, even, streamEntry);
@ -579,20 +590,21 @@ public class WaveformView implements IWaveformView {
entry.currentValue = Double.toString(val);
}
} else if (entry.waveform.getType() == WaveformType.TRANSACTION) {
ITx[] resultsList = new ITx[entry.waveform.getWidth()];
Entry<Long, IEvent[]> firstTx = entry.waveform.getEvents().floorEntry(time);
ITx[] resultsList = new ITx[entry.waveform.getRowCount()];
EventEntry firstTx = entry.waveform.getEvents().floorEntry(time);
if (firstTx != null) {
do {
for (IEvent evt : firstTx.getValue()) {
if (evt instanceof ITxEvent) {
ITx tx = ((ITxEvent) evt).getTransaction();
for (IEvent e : firstTx.events) {
if (e instanceof ITxEvent) {
ITxEvent evt = ((ITxEvent) e);
ITx tx = evt.getTransaction();
if ((evt.getKind() == EventKind.BEGIN || evt.getKind() == EventKind.SINGLE)
&& tx.getBeginTime() <= time && tx.getEndTime() >= time
&& resultsList[tx.getConcurrencyIndex()] == null)
resultsList[tx.getConcurrencyIndex()] = ((ITxEvent) evt).getTransaction();
&& resultsList[evt.getRowIndex()] == null)
resultsList[evt.getRowIndex()] = evt.getTransaction();
}
}
firstTx = entry.waveform.getEvents().lowerEntry(firstTx.getKey());
firstTx = entry.waveform.getEvents().lowerEntry(firstTx.timestamp);
} while (firstTx != null && !isArrayFull(resultsList));
boolean separator = false;
StringBuilder sb = new StringBuilder();
@ -754,7 +766,7 @@ public class WaveformView implements IWaveformView {
ITx txSel = (ITx) selList.get(0);
TrackEntry trackEntry = selList.size() == 2 && selList.get(1) instanceof TrackEntry
? (TrackEntry) selList.get(1)
: null;
: null;
if (trackEntry == null) {
trackEntry = getEntryFor(txSel);
if (trackEntry == null && addIfNeeded) {
@ -853,11 +865,11 @@ public class WaveformView implements IWaveformView {
}
}
if (transaction == null) {
Entry<Long, IEvent[]> entry = selectedWaveform.waveform.getEvents()
EventEntry entry = selectedWaveform.waveform.getEvents()
.higherEntry(currentTxSelection.getBeginTime());
if (entry != null)
do {
for (IEvent evt : entry.getValue()) {
for (IEvent evt : entry.events) {
if (evt instanceof ITxEvent && (evt.getKind() == EventKind.BEGIN
|| evt.getKind() == EventKind.SINGLE)) {
transaction = ((ITxEvent) evt).getTransaction();
@ -865,7 +877,7 @@ public class WaveformView implements IWaveformView {
}
}
if (transaction == null)
entry = selectedWaveform.waveform.getEvents().higherEntry(entry.getKey());
entry = selectedWaveform.waveform.getEvents().higherEntry(entry.timestamp);
} while (entry != null && transaction == null);
}
} else if (direction == GotoDirection.PREV) {
@ -882,11 +894,11 @@ public class WaveformView implements IWaveformView {
}
}
if (transaction == null) {
Entry<Long, IEvent[]> entry = selectedWaveform.waveform.getEvents()
EventEntry entry = selectedWaveform.waveform.getEvents()
.lowerEntry(currentTxSelection.getBeginTime());
if (entry != null)
do {
for (IEvent evt : Lists.reverse(Arrays.asList(entry.getValue()))) {
for (IEvent evt : Lists.reverse(Arrays.asList(entry.events))) {
if (evt instanceof ITxEvent && (evt.getKind() == EventKind.BEGIN
|| evt.getKind() == EventKind.SINGLE)) {
transaction = ((ITxEvent) evt).getTransaction();
@ -894,7 +906,7 @@ public class WaveformView implements IWaveformView {
}
}
if (transaction == null)
entry = selectedWaveform.waveform.getEvents().lowerEntry(entry.getKey());
entry = selectedWaveform.waveform.getEvents().lowerEntry(entry.timestamp);
} while (entry != null && transaction == null);
}
}
@ -928,7 +940,7 @@ public class WaveformView implements IWaveformView {
return candidates.get(0);
default:
ArrayList<ITxRelation> visibleCandidates = candidates.stream().filter(this::streamsVisible)
.collect(Collectors.toCollection(ArrayList::new));
.collect(Collectors.toCollection(ArrayList::new));
if (visibleCandidates.isEmpty()) {
return new RelSelectionDialog(waveformCanvas.getShell(), candidates, target).open();
} else if (visibleCandidates.size() == 1) {
@ -957,14 +969,14 @@ public class WaveformView implements IWaveformView {
return;
TrackEntry sel = currentWaveformSelection.get(0);
long time = getCursorTime();
NavigableMap<Long, ?> map = null;
IEventList map = null;
if (sel.waveform.getType() == WaveformType.TRANSACTION || sel.waveform.getType() == WaveformType.SIGNAL) {
map = sel.waveform.getEvents();
}
if (map != null) {
Entry<Long, ?> entry = direction == GotoDirection.PREV ? map.lowerEntry(time) : map.higherEntry(time);
EventEntry entry = direction == GotoDirection.PREV ? map.lowerEntry(time) : map.higherEntry(time);
if (entry != null) {
time = entry.getKey();
time = entry.timestamp;
setCursorTime(time);
waveformCanvas.reveal(time);
waveformCanvas.redraw();
@ -1036,7 +1048,7 @@ public class WaveformView implements IWaveformView {
TrackEntry trackEntry = trackVerticalOffset.get(firstKey);
IWaveform w = trackEntry.waveform;
if (w.getType() == WaveformType.TRANSACTION)
subArea.height *= w.getWidth();
subArea.height *= w.getRowCount();
drawTextFormat(gc, subArea, firstKey, w.getFullName(), trackEntry.selected);
} else {
for (Entry<Integer, TrackEntry> entry : trackVerticalOffset.subMap(firstKey, true, lastKey, true)
@ -1044,7 +1056,7 @@ public class WaveformView implements IWaveformView {
IWaveform w = entry.getValue().waveform;
subArea.height = styleProvider.getTrackHeight();
if (w.getType() == WaveformType.TRANSACTION)
subArea.height *= w.getWidth();
subArea.height *= w.getRowCount();
drawTextFormat(gc, subArea, entry.getKey(), w.getFullName(), entry.getValue().selected);
}
}
@ -1065,7 +1077,7 @@ public class WaveformView implements IWaveformView {
TrackEntry trackEntry = trackVerticalOffset.get(firstKey);
IWaveform w = trackEntry.waveform;
if (w.getType() == WaveformType.TRANSACTION)
subArea.height *= w.getWidth();
subArea.height *= w.getRowCount();
drawValue(gc, subArea, firstKey, trackEntry.currentValue, trackEntry.selected);
} else {
for (Entry<Integer, TrackEntry> entry : trackVerticalOffset.subMap(firstKey, true, lastKey, true)
@ -1073,7 +1085,7 @@ public class WaveformView implements IWaveformView {
IWaveform w = entry.getValue().waveform;
subArea.height = styleProvider.getTrackHeight();
if (w.getType() == WaveformType.TRANSACTION)
subArea.height *= w.getWidth();
subArea.height *= w.getRowCount();
drawValue(gc, subArea, entry.getKey(), entry.getValue().currentValue,
entry.getValue().selected);
}
@ -1140,8 +1152,12 @@ public class WaveformView implements IWaveformView {
*/
@Override
public void setZoomLevel(int scale) {
waveformCanvas.setZoomLevel(scale);
waveformCanvas.reveal(getCursorTime());
if(scale<-1) {
waveformCanvas.setZoomLevel(scale, getMarkerTime(selectedMarker));
} else {
waveformCanvas.setZoomLevel(scale);
waveformCanvas.reveal(getCursorTime());
}
}
/*
@ -1228,7 +1244,7 @@ public class WaveformView implements IWaveformView {
if (event.y < tracksVerticalHeight) {
event.doit = true;
LocalSelectionTransfer.getTransfer()
.setSelection(new StructuredSelection(currentWaveformSelection));
.setSelection(new StructuredSelection(currentWaveformSelection));
}
}
@ -1458,7 +1474,7 @@ public class WaveformView implements IWaveformView {
StringBuilder sb = new StringBuilder();
double dTime = time;
double scaledTime = dTime / waveformCanvas.getScaleFactorPow10();
return sb.append(df.format(scaledTime)).append(waveformCanvas.getUnitStr()).toString();
return sb.append(Constants.getTimeFormatForLevel(waveformCanvas.getZoomLevel()).format(scaledTime)).append(waveformCanvas.getUnitStr()).toString();
}
/*
@ -1468,11 +1484,11 @@ public class WaveformView implements IWaveformView {
*/
@Override
public String[] getZoomLevels() {
String[] res = new String[Constants.UNIT_MULTIPLIER.length * Constants.UNIT_STRING.length];
String[] res = new String[Constants.SCALE_MULTIPLIER.length * Constants.UNIT_STRING.length];
int index = 0;
for (String unit : Constants.UNIT_STRING) {
for (int factor : Constants.UNIT_MULTIPLIER) {
res[index++] = Integer.toString(factor) + unit;
for (long factor : Constants.SCALE_MULTIPLIER) {
res[index++] = Long.toString(factor) + unit;
}
}
return res;
@ -1502,6 +1518,22 @@ public class WaveformView implements IWaveformView {
waveformCanvas.redraw();
}
@Override
public void scrollTo(int pos) {
long time = 0;
switch(pos) {
case IWaveformView.CURSOR_POS:
time = getCursorTime();
break;
case IWaveformView.MARKER_POS:
time = getMarkerTime(selectedMarker);
break;
default:
break;
}
waveformCanvas.centerAt(time);
}
public void asyncUpdate(Widget widget) {
widget.getDisplay().asyncExec(() -> {
waveformCanvas.redraw();
@ -1531,5 +1563,4 @@ public class WaveformView implements IWaveformView {
getStreamList().add(idx, e);
return e;
}
}

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<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.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="target/classes"/>

View File

@ -1,8 +1,10 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
org.eclipse.jdt.core.compiler.compliance=11
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.release=disabled
org.eclipse.jdt.core.compiler.source=1.8
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
org.eclipse.jdt.core.compiler.release=enabled
org.eclipse.jdt.core.compiler.source=11

View File

@ -2,9 +2,9 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: VCD signal database
Bundle-SymbolicName: com.minres.scviewer.database.vcd
Bundle-Version: 2.2.0.qualifier
Bundle-Version: 4.0.0.qualifier
Bundle-Vendor: MINRES Technologies GmbH
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-RequiredExecutionEnvironment: JavaSE-11
Require-Bundle: com.minres.scviewer.database;bundle-version="1.0.0",
org.eclipse.osgi.services;bundle-version="3.4.0",
com.google.guava;bundle-version="15.0.0"

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="VCDDbLoader">
<implementation class="com.minres.scviewer.database.vcd.VCDDbLoader"/>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="VCDDbLoaderFactory">
<implementation class="com.minres.scviewer.database.vcd.VCDDbLoaderFactory"/>
<service>
<provide interface="com.minres.scviewer.database.IWaveformDbLoader"/>
<provide interface="com.minres.scviewer.database.IWaveformDbLoaderFactory"/>
</service>
</scr:component>

View File

@ -1,12 +1,12 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>com.minres.scviewer.database.vcd</artifactId>
<version>2.2.0-SNAPSHOT</version>
<version>4.0.0-SNAPSHOT</version>
<parent>
<groupId>com.minres.scviewer</groupId>
<artifactId>com.minres.scviewer.parent</artifactId>
<version>2.11.0</version>
<relativePath>../..</relativePath>
<version>2.14.1</version>
<relativePath>../../..</relativePath>
</parent>
<packaging>eclipse-plugin</packaging>
</project>

View File

@ -20,15 +20,13 @@ import java.util.ArrayDeque;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.NavigableMap;
import java.util.TreeMap;
import java.util.Vector;
import java.util.zip.GZIPInputStream;
import com.google.common.collect.Iterables;
import com.minres.scviewer.database.BitVector;
import com.minres.scviewer.database.DoubleVal;
import com.minres.scviewer.database.IEvent;
import com.minres.scviewer.database.IEventList;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.IWaveformDb;
import com.minres.scviewer.database.IWaveformDbLoader;
@ -115,19 +113,20 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
moduleStack=null;
throw new InputFormatException(e.toString());
}
if(!res) throw new InputFormatException("Could not parse VCD file");
if(!res)
throw new InputFormatException("Could not parse VCD file");
// calculate max time of this database
for(IWaveform waveform:signals) {
NavigableMap<Long, IEvent[]> events =waveform.getEvents();
IEventList events =waveform.getEvents();
if(!events.isEmpty())
maxTime= Math.max(maxTime, events.lastKey());
}
// extend signals to have a last value set at max time
for(IWaveform s:signals){
if(s instanceof VCDSignal<?>) {
TreeMap<Long,?> events = (TreeMap<Long, ?>) ((VCDSignal<?>)s).getEvents();
IEventList events = ((VCDSignal<?>)s).getEvents();
if(events.size()>0 && events.lastKey()<maxTime){
Object val = events.lastEntry().getValue();
Object val = events.lastEntry().events[0];
if(val instanceof BitVector) {
((VCDSignal<BitVector>)s).addSignalChange(maxTime, (BitVector) val);
} else if(val instanceof DoubleVal)
@ -147,7 +146,7 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
* @see com.minres.scviewer.database.ITrDb#getMaxTime()
*/
@Override
public Long getMaxTime() {
public long getMaxTime() {
return maxTime;
}
@ -165,7 +164,8 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
@Override
public void enterModule(String tokenString) {
if(moduleStack.isEmpty()) {
if("SystemC".compareTo(tokenString)!=0) moduleStack.push(tokenString);
if("SystemC".compareTo(tokenString)!=0)
moduleStack.push(tokenString);
} else
moduleStack.push(moduleStack.peek()+"."+tokenString);
@ -204,7 +204,7 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
@Override
public int getNetWidth(int intValue) {
VCDSignal<?> signal = (VCDSignal<?>) signals.get(intValue);
return signal.getWidth();
return signal.getRowCount();
}
/* (non-Javadoc)

View File

@ -0,0 +1,77 @@
/*******************************************************************************
* Copyright (c) 2015-2021 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 java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.GZIPInputStream;
import com.minres.scviewer.database.IWaveformDbLoader;
import com.minres.scviewer.database.IWaveformDbLoaderFactory;
/**
* The Class VCDDb.
*/
public class VCDDbLoaderFactory implements IWaveformDbLoaderFactory {
/**
* Checks if is gzipped.
*
* @param f the f
* @return true, if is gzipped
*/
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;
}
}
/**
* Can load.
*
* @param inputFile the input file
* @return true, if successful
*/
@Override
public boolean canLoad(File inputFile) {
if(!inputFile.isDirectory() || inputFile.exists()) {
String name = inputFile.getName();
if(!(name.endsWith(".vcd") ||
name.endsWith(".vcdz") ||
name.endsWith(".vcdgz") ||
name.endsWith(".vcd.gz")) )
return false;
boolean gzipped = isGzipped(inputFile);
try(InputStream stream = gzipped ? new GZIPInputStream(new FileInputStream(inputFile)) : new FileInputStream(inputFile)){
byte[] buffer = new byte[8];
if (stream.read(buffer, 0, buffer.length) == buffer.length) {
return buffer[0]=='$';
}
} catch (Exception e) {
return false;
}
}
return false;
}
@Override
public IWaveformDbLoader getLoader() {
return new VCDDbLoader();
}
}

View File

@ -10,12 +10,11 @@
*******************************************************************************/
package com.minres.scviewer.database.vcd;
import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.TreeMap;
import com.minres.scviewer.database.EventEntry;
import com.minres.scviewer.database.EventList;
import com.minres.scviewer.database.HierNode;
import com.minres.scviewer.database.IEvent;
import com.minres.scviewer.database.IEventList;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.WaveformType;
@ -27,7 +26,7 @@ public class VCDSignal<T extends IEvent> extends HierNode implements IWaveform {
private final int width;
private NavigableMap<Long, IEvent[]> values;
private IEventList values;
public VCDSignal(String name) {
this(0, name, 1);
@ -42,7 +41,7 @@ public class VCDSignal<T extends IEvent> extends HierNode implements IWaveform {
fullName=name;
this.id=id;
this.width=width;
this.values=new TreeMap<>();
this.values=new EventList();
}
public VCDSignal(VCDSignal<T> o, int id, String name) {
@ -63,44 +62,36 @@ public class VCDSignal<T extends IEvent> extends HierNode implements IWaveform {
}
@Override
public Long getId() {
public long getId() {
return id;
}
public void addSignalChange(Long time, T value){
if(values.containsKey(time)) {
IEvent[] oldV = values.get(time);
IEvent[] newV = new IEvent[oldV.length+1];
System.arraycopy(oldV, 0, newV, 0, oldV.length);
newV[oldV.length]=value;
values.put(time, newV);
} else {
values.put(time, new IEvent[] {value});
}
values.put(time, value);
}
@Override
public NavigableMap<Long, IEvent[]> getEvents() {
public IEventList getEvents() {
return values;
}
@Override
public IEvent[] getEventsAtTime(Long time) {
public IEvent[] getEventsAtTime(long time) {
return values.get(time);
}
@Override
public IEvent[] getEventsBeforeTime(Long time) {
Entry<Long, IEvent[]> e = values.floorEntry(time);
public IEvent[] getEventsBeforeTime(long time) {
EventEntry e = values.floorEntry(time);
if(e==null)
return new IEvent[] {};
else
return values.floorEntry(time).getValue();
return values.floorEntry(time).events;
}
@Override
public boolean isSame(IWaveform other) {
return( other instanceof VCDSignal<?> && this.getId().equals(other.getId()));
return( other instanceof VCDSignal<?> && this.getId() == other.getId());
}
@Override
@ -109,7 +100,7 @@ public class VCDSignal<T extends IEvent> extends HierNode implements IWaveform {
}
@Override
public int getWidth() {
public int getRowCount() {
return width;
}

View File

@ -1,7 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<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.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
<attributes>
<attribute name="module" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src/"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View File

@ -1,9 +1,16 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=11
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.release=disabled
org.eclipse.jdt.core.compiler.source=1.8
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
org.eclipse.jdt.core.compiler.release=enabled
org.eclipse.jdt.core.compiler.source=11

View File

@ -2,9 +2,9 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Waveform database
Bundle-SymbolicName: com.minres.scviewer.database
Bundle-Version: 3.0.0.qualifier
Bundle-Version: 4.0.0.qualifier
Bundle-Vendor: MINRES Technologies GmbH
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-RequiredExecutionEnvironment: JavaSE-11
Export-Package: com.minres.scviewer.database,
com.minres.scviewer.database.tx
Bundle-ActivationPolicy: lazy

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="com.minres.scviewer.database.loader">
<implementation class="com.minres.scviewer.database.internal.WaveformDb"/>
<reference bind="bind" cardinality="1..n" interface="com.minres.scviewer.database.IWaveformDbLoader" name="IWaveformDbLoader" policy="dynamic" unbind="unbind"/>
<reference bind="bind" cardinality="1..n" interface="com.minres.scviewer.database.IWaveformDbLoaderFactory" name="IWaveformDbLoaderFactory" policy="dynamic" unbind="unbind"/>
</scr:component>

View File

@ -4,9 +4,9 @@
<parent>
<groupId>com.minres.scviewer</groupId>
<artifactId>com.minres.scviewer.parent</artifactId>
<version>2.11.0</version>
<relativePath>../..</relativePath>
<version>2.14.1</version>
<relativePath>../../..</relativePath>
</parent>
<packaging>eclipse-plugin</packaging>
<version>3.0.0-SNAPSHOT</version>
<version>4.0.0-SNAPSHOT</version>
</project>

View File

@ -0,0 +1,41 @@
package com.minres.scviewer.database;
import java.util.Arrays;
public class EventEntry implements Comparable<EventEntry>{
public long timestamp; // unsigned
public IEvent[] events = null;
public EventEntry(long timestamp) {
this.timestamp = timestamp;
}
public EventEntry(long timestamp, IEvent[] events) {
this.timestamp = timestamp;
this.events = events;
}
@Override
public int compareTo(EventEntry o) {
return Long.compareUnsigned(timestamp, o.timestamp);
}
@Override
public String toString() {
return String.format("e.%d@%d", events.length,timestamp);
}
public void append(IEvent value) {
if(events.length==0)
events = new IEvent[] {value};
else {
int idx = events.length;
events = Arrays.copyOf(events, idx+1);
events[idx]=value;
}
}
}

View File

@ -0,0 +1,195 @@
package com.minres.scviewer.database;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
public class EventList implements IEventList {
ArrayList<EventEntry> store = new ArrayList<>();
int start = 0;
int end = store.size();
boolean unmodifiable = false;
public class Iterator implements java.util.Iterator<EventEntry> {
EventList list;
private int pos;
public Iterator(EventList list) {
this.list=list;
this.pos=-1;
}
@Override
public boolean hasNext() {
return pos<(list.end-1);
}
@Override
public EventEntry next() {
if(hasNext()) {
pos++;
return list.store.get(pos);
} else
return null;
}
@Override
public void remove() {
list.store.remove(pos);
}
}
public EventList() {
}
private EventList(ArrayList<EventEntry> store , int start, int end) {
this.store=store;
this.start=start;
this.end=end;
this.unmodifiable=true;
}
@Override
public IEventList subMap(long from, boolean includeFrom, long to) {
//the index of the first element greater than the key, or list.size()
int beginIndex = Collections.binarySearch(store, new EventEntry(from));
int startIndex = beginIndex < 0? -(beginIndex + 1): beginIndex;
int endIndex = Collections.binarySearch(store, new EventEntry(to));
endIndex = endIndex < 0? -(endIndex + 1): endIndex+1;
if(beginIndex>0 && !includeFrom)
return new EventList(store, startIndex+1, endIndex);
else
return new EventList(store, startIndex, endIndex);
}
@Override
public int size() {
return end-start;
}
@Override
public boolean containsKey(long key) {
int index = Collections.binarySearch(store, new EventEntry(key));
return index>=0 && index>=start && index<end;
}
@Override
public IEvent[] get(long key) {
int index = Collections.binarySearch(store, new EventEntry(key));
if(index<0) return null;
return index>=start && index<end? store.get(index).events: null;
}
@Override
public void put(long key, IEvent value) {
if(unmodifiable) throw new UnsupportedOperationException();
if(store.size()==0 || store.get(store.size()-1).timestamp < key) {
store.add(new EventEntry(key, new IEvent[] {value}));
} else {
int index = Collections.binarySearch(store, new EventEntry(key));
// < 0 if element is not in the list, see Collections.binarySearch
if (index < 0) {
EventEntry e = new EventEntry(key, new IEvent[] {value});
index = -(index + 1);
store.add(index, e);
} else {
// Insertion index is index of existing element, to add new element behind it increase index
store.get(index).append(value);
}
}
end=store.size();
}
@Override
public Collection<EventEntry> entrySet() {
if(start != 0 || end != store.size())
return Collections.unmodifiableList(store.subList(start, end));
else
return Collections.unmodifiableList(store);
}
@Override
public boolean isEmpty() {
return start==end || store.isEmpty();
}
@Override
public long firstKey() {
return store.get(start).timestamp;
}
@Override
public long lastKey() {
return store.get(end-1).timestamp;
}
// Navigable map functions
@Override
public EventEntry firstEntry() {
return store.get(start);
}
@Override
public EventEntry lastEntry() {
return store.get(end-1);
}
@Override
public EventEntry floorEntry(long key) {
int index = Collections.binarySearch(store, new EventEntry(key));
if(index==-1) return null;
// < 0 if element is not in the list, see Collections.binarySearch
if (index < 0) {
index = -(index + 2);
}
if(index>=end)
return store.get(end-1);
return index<start? null: store.get(index);
}
@Override
public EventEntry ceilingEntry(long key) {
int index = Collections.binarySearch(store, new EventEntry(key));
// < 0 if element is not in the list, see Collections.binarySearch
if (index < 0)
index = -(index + 1);
if(index<start)
return store.get(start);
return index>=end? null: store.get(index);
}
@Override
public EventEntry lowerEntry(long key) {
int index = Collections.binarySearch(store, new EventEntry(key));
// < 0 if element is not in the list, see Collections.binarySearch
if (index < 0)
index = -(index + 1);
index--;
if(index>=end)
return store.get(end-1);
return index>=end || index<start ?null:store.get(index);
}
@Override
public EventEntry higherEntry(long key) {
int index = Collections.binarySearch(store, new EventEntry(key));
// < 0 if element is not in the list, see Collections.binarySearch
if (index < 0)
index = -(index + 1);
else
index++;
if(index<start)
return store.get(start);
return index>=end || index<start ?null:store.get(index);
}
@Override
public java.util.Iterator<EventEntry> iterator() {
return new Iterator(this);
}
}

View File

@ -80,7 +80,7 @@ public class HierNode implements IHierNode {
}
/**
* Gets the full name.
* Gets the full hierarchical name.
*
* @return the full name
*/

View File

@ -0,0 +1,84 @@
package com.minres.scviewer.database;
import java.util.Collection;
public interface IEventList extends Iterable<EventEntry> {
int size();
Collection<EventEntry> entrySet();
boolean containsKey(long key);
IEvent[] get(long key);
void put(long key, IEvent value);
long firstKey();
long lastKey();
boolean isEmpty();
/**
* Returns a key-value mapping associated with the greatest key less
* than or equal to the given key, or null if there is no such key.
*
* @param key
* @return
*/
EventEntry floorEntry(long key);
/**
* Returns a key-value mapping associated with the least key greater
* than or equal to the given key, or null if there is no such key.
*
* @param key
* @return
*/
EventEntry ceilingEntry(long key);
/**
* Returns a key-value mapping associated with the least key in this map,
* or null if the map is empty.
*
* @return
*/
EventEntry firstEntry();
/**
* Returns a key-value mapping associated with the least key in this map,
* or null if the map is empty.
*
* @return
*/
EventEntry lastEntry();
/**
* Returns a key-value mapping associated with the least key strictly greater
* than the given key, or null if there is no such key.
*
* @param key
* @return
*/
EventEntry higherEntry(long key);
/**
* Returns a key-value mapping associated with the greatest key strictly less
* than the given key, or null if there is no such key.
*
* @param key
* @return
*/
EventEntry lowerEntry(long key);
/**
* Returns a view of the portion of this map whose keys range from
* {@code fromKey} to {@code toKey}. If {@code fromKey} and
* {@code toKey} are equal, the returned map is empty unless
* {@code fromInclusive} is true. The
* returned map is backed by this map, so changes in the returned map are
* reflected in this map, and vice-versa. The returned map supports all
* optional map operations that this map supports.
*
* @param fromKey low endpoint of the keys in the returned map
* @param fromInclusive {@code true} if the low endpoint
* is to be included in the returned view
* @param toKey high endpoint of the keys in the returned map (inclusive)
*/
IEventList subMap(long key, boolean b, long key2);
}

View File

@ -10,8 +10,8 @@
*******************************************************************************/
package com.minres.scviewer.database;
import java.util.NavigableMap;
// TODO: Auto-generated Javadoc
/**
* The Interface IWaveform.
*
@ -24,7 +24,7 @@ public interface IWaveform extends IHierNode {
*
* @return the id
*/
public Long getId();
public long getId();
/**
* Checks if is same.
@ -39,7 +39,7 @@ public interface IWaveform extends IHierNode {
*
* @return the events
*/
public NavigableMap<Long, IEvent[]> getEvents();
public IEventList getEvents();
/**
* Gets the events at time.
@ -47,7 +47,7 @@ public interface IWaveform extends IHierNode {
* @param time the time
* @return the events at time
*/
public IEvent[] getEventsAtTime(Long time);
public IEvent[] getEventsAtTime(long time);
/**
* Gets the events before time.
@ -55,7 +55,7 @@ public interface IWaveform extends IHierNode {
* @param time the time
* @return the events before time
*/
public IEvent[] getEventsBeforeTime(Long time);
public IEvent[] getEventsBeforeTime(long time);
/**
* Gets the type.
@ -76,6 +76,6 @@ public interface IWaveform extends IHierNode {
*
* @return the width
*/
public int getWidth();
public int getRowCount();
}

View File

@ -23,7 +23,7 @@ public interface IWaveformDb extends IHierNode {
*
* @return the max time
*/
public Long getMaxTime();
public long getMaxTime();
/**
* Gets the stream by name.
@ -62,9 +62,4 @@ public interface IWaveformDb extends IHierNode {
*/
public boolean isLoaded();
/**
* Clear.
*/
public void clear();
}

View File

@ -69,7 +69,7 @@ public interface IWaveformDbLoader {
*
* @return the max time
*/
public Long getMaxTime();
public long getMaxTime();
/**
* Gets the all waves.

View File

@ -8,20 +8,26 @@
* Contributors:
* MINRES Technologies GmbH - initial API and implementation
*******************************************************************************/
package com.minres.scviewer.database.tx;
package com.minres.scviewer.database;
import com.minres.scviewer.database.IWaveform;
import java.io.File;
/**
* The Interface ITxGenerator.
* A factory for creating IWaveformDb objects.
*/
public interface ITxGenerator extends IWaveform {
public interface IWaveformDbLoaderFactory {
/**
* Gets the stream.
* Check if the loader produced by this factory can load the given file.
*
* @return the stream
* @param inputFile the input file
* @return true, if successful
*/
public IWaveform getStream();
public boolean canLoad(File inputFile);
/**
* Gets the database.
*
* @return the database
*/
IWaveformDbLoader getLoader();
}

View File

@ -15,16 +15,17 @@ import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.minres.scviewer.database.HierNode;
import com.minres.scviewer.database.IHierNode;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.IWaveformDb;
import com.minres.scviewer.database.IWaveformDbLoader;
import com.minres.scviewer.database.IWaveformDbLoaderFactory;
import com.minres.scviewer.database.RelationType;
/**
@ -33,7 +34,7 @@ import com.minres.scviewer.database.RelationType;
public class WaveformDb extends HierNode implements IWaveformDb, PropertyChangeListener {
/** The loaders. */
private static List<IWaveformDbLoader> loaders = new LinkedList<>();
private static List<IWaveformDbLoaderFactory> loaderFactories = new LinkedList<>();
/** The loaded. */
private boolean loaded;
@ -45,15 +46,15 @@ public class WaveformDb extends HierNode implements IWaveformDb, PropertyChangeL
private Map<String, IWaveform> waveforms;
/** The max time. */
private Long maxTime;
private long maxTime = -1;
/**
* Bind.
*
* @param loader the loader
*/
public synchronized void bind(IWaveformDbLoader loader) {
loaders.add(loader);
public synchronized void bind(IWaveformDbLoaderFactory loader) {
loaderFactories.add(loader);
}
/**
@ -61,8 +62,8 @@ public class WaveformDb extends HierNode implements IWaveformDb, PropertyChangeL
*
* @param loader the loader
*/
public synchronized void unbind(IWaveformDbLoader loader) {
loaders.remove(loader);
public synchronized void unbind(IWaveformDbLoaderFactory loader) {
loaderFactories.remove(loader);
}
/**
@ -70,8 +71,8 @@ public class WaveformDb extends HierNode implements IWaveformDb, PropertyChangeL
*
* @return the loaders
*/
public static List<IWaveformDbLoader> getLoaders() {
return Collections.unmodifiableList(loaders);
public static List<IWaveformDbLoaderFactory> getLoaders() {
return Collections.unmodifiableList(loaderFactories);
}
/**
@ -79,7 +80,7 @@ public class WaveformDb extends HierNode implements IWaveformDb, PropertyChangeL
*/
public WaveformDb() {
super();
waveforms = new HashMap<>();
waveforms = new ConcurrentHashMap<>();
relationTypes = new ArrayList<>();
maxTime = 0L;
}
@ -90,7 +91,7 @@ public class WaveformDb extends HierNode implements IWaveformDb, PropertyChangeL
* @return the max time
*/
@Override
public Long getMaxTime() {
public long getMaxTime() {
return maxTime;
}
@ -123,31 +124,32 @@ public class WaveformDb extends HierNode implements IWaveformDb, PropertyChangeL
*/
@Override
public boolean load(File inp) {
for (IWaveformDbLoader loader : loaders) {
if (loader.canLoad(inp)) {
boolean retval = true;
for (IWaveformDbLoaderFactory loaderFactory : loaderFactories) {
if (loaderFactory.canLoad(inp)) {
IWaveformDbLoader loader = loaderFactory.getLoader();
loader.addPropertyChangeListener(this);
try {
loader.addPropertyChangeListener(this);
loader.load(this, inp);
loader.removePropertyChangeListener(this);
for (IWaveform w : loader.getAllWaves()) {
waveforms.put(w.getFullName(), w);
}
if (loader.getMaxTime() > maxTime) {
maxTime = loader.getMaxTime();
}
if (name == null)
name = getFileBasename(inp.getName());
buildHierarchyNodes();
relationTypes.addAll(loader.getAllRelationTypes());
pcs.firePropertyChange(IHierNode.LOADING_FINISHED, null, null);
loaded = true;
return true;
} catch (Exception e) {
return false;
retval=false;
}
loader.removePropertyChangeListener(this);
for (IWaveform w : loader.getAllWaves()) {
waveforms.put(w.getFullName(), w);
}
if (loader.getMaxTime() > maxTime) {
maxTime = loader.getMaxTime();
}
if (name == null)
name = getFileBasename(inp.getName());
buildHierarchyNodes();
relationTypes.addAll(loader.getAllRelationTypes());
}
}
return false;
pcs.firePropertyChange(IHierNode.LOADING_FINISHED, null, null);
loaded = true;
return retval;
}
/**
@ -165,16 +167,6 @@ public class WaveformDb extends HierNode implements IWaveformDb, PropertyChangeL
return ext;
}
/**
* Clear.
*/
@Override
public void clear() {
waveforms.clear();
childNodes.clear();
loaded = false;
}
/**
* Checks if is loaded.
*
@ -189,6 +181,7 @@ public class WaveformDb extends HierNode implements IWaveformDb, PropertyChangeL
if (IWaveformDbLoader.SIGNAL_ADDED.equals(evt.getPropertyName())
|| IWaveformDbLoader.STREAM_ADDED.equals(evt.getPropertyName())) {
IWaveform waveform = (IWaveform) evt.getNewValue();
waveforms.put(waveform.getFullName(), waveform);
putInHierarchy(waveform);
pcs.firePropertyChange(IHierNode.WAVEFORMS, null, waveforms);
pcs.firePropertyChange(IHierNode.CHILDS, null, childNodes);
@ -200,7 +193,7 @@ public class WaveformDb extends HierNode implements IWaveformDb, PropertyChangeL
/**
* Builds the hierarchy nodes.
*/
private void buildHierarchyNodes() {
private synchronized void buildHierarchyNodes() {
boolean needsSorting = false;
for (IWaveform stream : getAllWaves()) {
if (stream.getParent() == null) {
@ -226,14 +219,13 @@ public class WaveformDb extends HierNode implements IWaveformDb, PropertyChangeL
break;
}
}
if (childNode != null) {
if (childNode == null) {
HierNode newNode = new HierNode(name, node);
node.addChild(newNode);
node = newNode;
} else {
node = childNode;
break;
}
HierNode newNode = new HierNode(name, node);
node.addChild(newNode);
node = newNode;
}
node.addChild(waveform);
waveform.setParent(node);

View File

@ -25,7 +25,7 @@ public interface ITx extends Comparable<ITx> {
*
* @return the id
*/
public Long getId();
public long getId();
/**
* Gets the stream.
@ -39,28 +39,21 @@ public interface ITx extends Comparable<ITx> {
*
* @return the generator
*/
public ITxGenerator getGenerator();
public IWaveform getGenerator();
/**
* Gets the begin time.
*
* @return the begin time
*/
public Long getBeginTime();
public long getBeginTime();
/**
* Gets the end time.
*
* @return the end time
*/
public Long getEndTime();
/**
* Gets the concurrency index.
*
* @return the concurrency index
*/
public int getConcurrencyIndex();
public long getEndTime();
/**
* Gets the attributes.

View File

@ -22,7 +22,7 @@ public interface ITxEvent extends IEvent {
*
* @return the time
*/
public Long getTime();
public long getTime();
/**
* Gets the transaction.
@ -30,4 +30,12 @@ public interface ITxEvent extends IEvent {
* @return the transaction
*/
public ITx getTransaction();
/**
* Gets the concurrency index.
*
* @return the concurrency index
*/
public int getRowIndex();
}

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<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.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="target/classes"/>

View File

@ -1,13 +1,15 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.compliance=11
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.release=disabled
org.eclipse.jdt.core.compiler.source=1.8
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
org.eclipse.jdt.core.compiler.release=enabled
org.eclipse.jdt.core.compiler.source=11

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<application:Application xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:advanced="http://www.eclipse.org/ui/2010/UIModel/application/ui/advanced" xmlns:application="http://www.eclipse.org/ui/2010/UIModel/application" xmlns:basic="http://www.eclipse.org/ui/2010/UIModel/application/ui/basic" xmlns:menu="http://www.eclipse.org/ui/2010/UIModel/application/ui/menu" xmlns:ui="http://www.eclipse.org/ui/2010/UIModel/application/ui" xmi:id="_95PfsHNmEeWBq8z1Dv39LA" elementId="org.eclipse.e4.ide.application" bindingContexts="_95PfuXNmEeWBq8z1Dv39LA">
<children xsi:type="basic:TrimmedWindow" xmi:id="_95PfsXNmEeWBq8z1Dv39LA" label="SC Viewer" bindingContexts="_95PfunNmEeWBq8z1Dv39LA" width="1280" height="700">
<children xsi:type="basic:TrimmedWindow" xmi:id="_95PfsXNmEeWBq8z1Dv39LA" elementId="com.minres.scviewer.e4.application.trimmedwindow.main" label="SC Viewer" bindingContexts="_95PfunNmEeWBq8z1Dv39LA" width="1280" height="700">
<children xsi:type="advanced:PerspectiveStack" xmi:id="_95QGxnNmEeWBq8z1Dv39LA">
<children xsi:type="advanced:Perspective" xmi:id="_95QGx3NmEeWBq8z1Dv39LA">
<children xsi:type="basic:PartStack" xmi:id="_95QGyXNmEeWBq8z1Dv39LA" elementId="org.eclipse.editorss" containerData="7500">
@ -9,6 +9,7 @@
</children>
</children>
<children xsi:type="basic:Part" xmi:id="__VNlAIytEeWid7xO48ZBXw" elementId="com.minres.scviewer.e4.application.dialog.aboutscviewer" toBeRendered="false" visible="false" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.parts.AboutDialog" label="About SCViewer" bindingContexts="_95Pfu3NmEeWBq8z1Dv39LA"/>
<children xsi:type="basic:Part" xmi:id="_hXh-kEYFEeyPM8G0E2EYww" elementId="com.minres.scviewer.e4.application.dialog.onlinehelp" toBeRendered="false" visible="false" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.parts.HelpDialog" label="SCViewer Online Help" bindingContexts="_95Pfu3NmEeWBq8z1Dv39LA" closeable="true"/>
<mainMenu xmi:id="_95PfyXNmEeWBq8z1Dv39LA" elementId="menu:org.eclipse.ui.main.menu">
<children xsi:type="menu:Menu" xmi:id="_95QGwHNmEeWBq8z1Dv39LA" elementId="com.minres.scviewer.e4.application.menu.file" label="File">
<children xsi:type="menu:HandledMenuItem" xmi:id="_igsK0BkREeudD5MqrWoETQ" elementId="" label="Open Database" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/folder_database.png" mnemonics="M1+O" command="_95PfwHNmEeWBq8z1Dv39LA"/>
@ -55,7 +56,8 @@
</children>
<children xsi:type="menu:Menu" xmi:id="_95QGxHNmEeWBq8z1Dv39LA" elementId="com.minres.scviewer.e4.application.menu.help" label="Help">
<children xsi:type="menu:HandledMenuItem" xmi:id="_UQRi0B07EeuiP60JNw0iiA" elementId="com.minres.scviewer.e4.application.handledmenuitem.checkforupdate" visible="false" label="Check for Update" enabled="false" command="_-9ED4B06EeuiP60JNw0iiA"/>
<children xsi:type="menu:HandledMenuItem" xmi:id="_95QGxXNmEeWBq8z1Dv39LA" label="About" command="_95PfxnNmEeWBq8z1Dv39LA"/>
<children xsi:type="menu:HandledMenuItem" xmi:id="_95QGxXNmEeWBq8z1Dv39LA" label="Online Help" command="_lqjIYEYEEeyPM8G0E2EYww"/>
<children xsi:type="menu:HandledMenuItem" xmi:id="_4xtmgEYEEeyPM8G0E2EYww" label="About" command="_95PfxnNmEeWBq8z1Dv39LA"/>
</children>
</mainMenu>
<trimBars xmi:id="_95QGy3NmEeWBq8z1Dv39LA" elementId="org.eclipse.ui.main.toolbar">
@ -100,19 +102,25 @@
</children>
</children>
<children xsi:type="menu:ToolBar" xmi:id="_oQdMUHcqEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.toolbar.1">
<children xsi:type="menu:HandledToolItem" xmi:id="_5DrGQHf4EeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.handledtoolitem.zoomfit" label="Zoom out" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/magnifier.png" tooltip="Restore default zoom level" command="_693GoHcqEeWwZ-9vrAR2UQ">
<parameters xmi:id="_5DrGQXf4EeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.parameter.14" name="com.minres.scviewer.e4.application.command.zoomcommand.parameter.level" value="fit"/>
<children xsi:type="menu:HandledToolItem" xmi:id="_LFGfsEZEEeyKK_icsY7Xjg" elementId="com.minres.scviewer.e4.application.handledtoolitem.zoomfull" label="Zoom full" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/zoom_full.png" tooltip="Zoom full range" command="_693GoHcqEeWwZ-9vrAR2UQ">
<parameters xmi:id="_LFGfsUZEEeyKK_icsY7Xjg" elementId="com.minres.scviewer.e4.application.parameter.full" name="com.minres.scviewer.e4.application.command.zoomcommand.parameter.level" value="full"/>
</children>
<children xsi:type="menu:HandledToolItem" xmi:id="_5DrGQHf4EeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.handledtoolitem.zoomfit" label="Zoom fit" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/zoom_fit.png" tooltip="Zoom between cursor and marker" command="_693GoHcqEeWwZ-9vrAR2UQ">
<parameters xmi:id="_5DrGQXf4EeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.parameter.fit" name="com.minres.scviewer.e4.application.command.zoomcommand.parameter.level" value="fit"/>
</children>
<children xsi:type="menu:ToolBarSeparator" xmi:id="_p1AvUHcqEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.toolbarseparator.1"/>
<children xsi:type="menu:HandledToolItem" xmi:id="_XMQPAHcrEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.handledtoolitem.zoomin" label="Zoom in" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/magnifier_zoom_in.png" tooltip="Zoom in by a factor of 3" command="_693GoHcqEeWwZ-9vrAR2UQ">
<parameters xmi:id="_fi5w4HcrEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.parameter.15" name="com.minres.scviewer.e4.application.command.zoomcommand.parameter.level" value="in"/>
<parameters xmi:id="_fi5w4HcrEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.parameter.in" name="com.minres.scviewer.e4.application.command.zoomcommand.parameter.level" value="in"/>
</children>
<children xsi:type="menu:HandledToolItem" xmi:id="_XqTc8HcrEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.handledtoolitem.zoomout" label="Zoom out" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/magifier_zoom_out.png" tooltip="Zoom out by a factor of 3" command="_693GoHcqEeWwZ-9vrAR2UQ">
<parameters xmi:id="_d7OBYHcrEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.parameter.14" name="com.minres.scviewer.e4.application.command.zoomcommand.parameter.level" value="out"/>
<parameters xmi:id="_d7OBYHcrEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.parameter.out" name="com.minres.scviewer.e4.application.command.zoomcommand.parameter.level" value="out"/>
</children>
</children>
<children xsi:type="menu:ToolBar" xmi:id="_fwn8wGtTEeqmlpoaaMHoiw" elementId="com.minres.scviewer.e4.application.toolbar.2">
<children xsi:type="menu:HandledToolItem" xmi:id="_j-XIgGtTEeqmlpoaaMHoiw" elementId="com.minres.scviewer.e4.application.handledtoolitem.hover" label="Hover" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/lightbulb.png" tooltip="Enable hover window in waveform" selected="true" type="Check" command="_uyeyYGtTEeqmlpoaaMHoiw">
<children xsi:type="menu:HandledToolItem" xmi:id="_j-XIgGtTEeqmlpoaaMHoiw" elementId="com.minres.scviewer.e4.application.handledtoolitem.txdetails" label="TX Details" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/application_side_expand.png" tooltip="Show tx details parts" selected="true" type="Check" command="_Fj1gQEYoEeyKK_icsY7Xjg">
<tags>EnableTxDetails</tags>
</children>
<children xsi:type="menu:HandledToolItem" xmi:id="_33tugEYnEeyKK_icsY7Xjg" elementId="com.minres.scviewer.e4.application.handledtoolitem.hover" label="Hover" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/lightbulb.png" tooltip="Enable hover window in waveform" selected="true" type="Check" command="_uyeyYGtTEeqmlpoaaMHoiw">
<tags>EnableHover</tags>
</children>
</children>
@ -126,6 +134,9 @@
</children>
</trimBars>
</children>
<children xsi:type="basic:Window" xmi:id="_Gm0qAEamEeyPDuc8x6Ggxw" elementId="com.minres.scviewer.e4.application.window.help" toBeRendered="false" selectedElement="_M5eT0EamEeyPDuc8x6Ggxw" label="SC Viewer Help" width="800" height="600">
<children xsi:type="basic:Part" xmi:id="_M5eT0EamEeyPDuc8x6Ggxw" elementId="com.minres.scviewer.e4.application.part.container" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.parts.help.HelpBrowser"/>
</children>
<handlers xmi:id="_95PfvXNmEeWBq8z1Dv39LA" elementId="com.minres.scviewer.e4.application.handler.quitCommand" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.QuitHandler" command="_95PfvHNmEeWBq8z1Dv39LA"/>
<handlers xmi:id="_95PfwXNmEeWBq8z1Dv39LA" elementId="com.minres.scviewer.e4.application.handler.openCommand" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.OpenHandler" command="_95PfwHNmEeWBq8z1Dv39LA"/>
<handlers xmi:id="_95PfxHNmEeWBq8z1Dv39LA" elementId="com.minres.scviewer.e4.application.handler.saveCommand" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.SaveHandler" command="_95Pfw3NmEeWBq8z1Dv39LA"/>
@ -135,10 +146,12 @@
<handlers xmi:id="_UUnX8IoNEeWxJ_wPkM6yGQ" elementId="com.minres.scviewer.e4.application.handler.set_them" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.ThemeSetHandler" command="_KlGlsIoNEeWxJ_wPkM6yGQ"/>
<handlers xmi:id="_V4EscIuGEeWid7xO48ZBXw" elementId="com.minres.scviewer.e4.application.handler.setreleationtype" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.SetRelationTypeHandler" command="_E9lUgIt2EeWid7xO48ZBXw"/>
<handlers xmi:id="__99WoJebEeW09eyIbHsdvg" elementId="com.minres.scviewer.e4.application.handler.loadStoreSettings" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.LoadStoreSettingsHandler" command="_7-AIMJebEeW09eyIbHsdvg"/>
<handlers xmi:id="_x4pSEGtTEeqmlpoaaMHoiw" elementId="com.minres.scviewer.e4.application.handler.0" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.EnableHover" command="_uyeyYGtTEeqmlpoaaMHoiw"/>
<handlers xmi:id="_x4pSEGtTEeqmlpoaaMHoiw" elementId="com.minres.scviewer.e4.application.handler.enablehover" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.EnableHover" command="_uyeyYGtTEeqmlpoaaMHoiw"/>
<handlers xmi:id="_h3jU8BkWEeudD5MqrWoETQ" elementId="com.minres.scviewer.e4.application.handler.reloadCommand" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.ReloadHandler" command="_srACsBkREeudD5MqrWoETQ"/>
<handlers xmi:id="_gn_boBlEEeuiP60JNw0iiA" elementId="com.minres.scviewer.e4.application.handler.txSearch" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.SearchHandler" command="_XDxTYBlEEeuiP60JNw0iiA"/>
<handlers xmi:id="_CCEtAB07EeuiP60JNw0iiA" elementId="com.minres.scviewer.e4.application.handler.update" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.UpdateHandler" command="_-9ED4B06EeuiP60JNw0iiA"/>
<handlers xmi:id="_ru2NIEYEEeyPM8G0E2EYww" elementId="com.minres.scviewer.e4.application.handler.helpCommand" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.HelpHandler" command="_lqjIYEYEEeyPM8G0E2EYww"/>
<handlers xmi:id="_TwU0IEYoEeyKK_icsY7Xjg" elementId="com.minres.scviewer.e4.application.handler.enabletxdetails" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.EnableTxDetails" command="_Fj1gQEYoEeyKK_icsY7Xjg"/>
<bindingTables xmi:id="_95PfvnNmEeWBq8z1Dv39LA" bindingContext="_95PfuXNmEeWBq8z1Dv39LA">
<bindings xmi:id="_95Pfv3NmEeWBq8z1Dv39LA" elementId="com.minres.scviewer.e4.application.keybinding.quit" keySequence="M1+Q" command="_95PfvHNmEeWBq8z1Dv39LA">
<tags>type:user</tags>
@ -280,6 +293,8 @@
<commands xmi:id="_srACsBkREeudD5MqrWoETQ" elementId="com.minres.scviewer.e4.application.reload" commandName="Reload Command"/>
<commands xmi:id="_XDxTYBlEEeuiP60JNw0iiA" elementId="com.minres.scviewer.e4.application.txSearch" commandName="Search Command"/>
<commands xmi:id="_-9ED4B06EeuiP60JNw0iiA" elementId="com.minres.scviewer.e4.application.command.update" commandName="Update"/>
<commands xmi:id="_lqjIYEYEEeyPM8G0E2EYww" elementId="org.eclipse.ui.help.helpAction" commandName="Help Command"/>
<commands xmi:id="_Fj1gQEYoEeyKK_icsY7Xjg" elementId="com.minres.scviewer.e4.application.command.enabletxdetails" commandName="Enable Tx Details" description="Show tx details parts"/>
<addons xmi:id="_95PfsnNmEeWBq8z1Dv39LA" elementId="org.eclipse.e4.core.commands.service" contributionURI="bundleclass://org.eclipse.e4.core.commands/org.eclipse.e4.core.commands.CommandServiceAddon"/>
<addons xmi:id="_95Pfs3NmEeWBq8z1Dv39LA" elementId="org.eclipse.e4.ui.contexts.service" contributionURI="bundleclass://org.eclipse.e4.ui.services/org.eclipse.e4.ui.services.ContextServiceAddon"/>
<addons xmi:id="_95PftHNmEeWBq8z1Dv39LA" elementId="org.eclipse.e4.ui.bindings.service" contributionURI="bundleclass://org.eclipse.e4.ui.bindings/org.eclipse.e4.ui.bindings.BindingServiceAddon"/>

View File

@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %Bundle-Name
Bundle-SymbolicName: com.minres.scviewer.e4.application;singleton:=true
Bundle-Version: 2.11.0.qualifier
Bundle-Version: 2.14.1
Bundle-Vendor: %Bundle-Vendor
Require-Bundle: javax.inject;bundle-version="1.0.0",
org.eclipse.core.runtime;bundle-version="3.11.1",
@ -35,8 +35,10 @@ Require-Bundle: javax.inject;bundle-version="1.0.0",
org.eclipse.equinox.p2.core;bundle-version="2.6.300",
org.eclipse.equinox.p2.engine;bundle-version="2.6.600",
org.eclipse.equinox.p2.operations;bundle-version="2.5.700",
org.eclipse.equinox.p2.metadata.repository;bundle-version="1.3.400"
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
org.eclipse.equinox.p2.metadata.repository;bundle-version="1.3.400",
org.eclipse.help.base;bundle-version="4.2.900"
Bundle-RequiredExecutionEnvironment: JavaSE-11
Import-Package: com.minres.scviewer.database,
javax.annotation;version="1.0.0";resolution:=optional,
javax.inject;version="1.0.0"
Automatic-Module-Name: com.minres.scviewer.e4.application

Binary file not shown.

After

Width:  |  Height:  |  Size: 781 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 547 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 581 B

Some files were not shown because too many files have changed in this diff Show More