Refactored database data model to improve speed and reduce memory
consumption
This commit is contained in:
@ -0,0 +1,68 @@
|
||||
package com.minres.scviewer.database;
|
||||
public enum BitValue {
|
||||
ZERO,
|
||||
ONE,
|
||||
X,
|
||||
Z;
|
||||
|
||||
private static final BitValue[] ORDINAL_TABLE = BitValue.values();
|
||||
|
||||
public static BitValue fromChar(char c) {
|
||||
switch (c) {
|
||||
case '0':
|
||||
return ZERO;
|
||||
case '1':
|
||||
return ONE;
|
||||
case 'x':
|
||||
case 'X':
|
||||
return X;
|
||||
case 'z':
|
||||
case 'Z':
|
||||
return Z;
|
||||
default:
|
||||
throw new NumberFormatException("unknown digit " + c);
|
||||
}
|
||||
}
|
||||
|
||||
public char toChar() {
|
||||
switch (this) {
|
||||
case ZERO:
|
||||
return '0';
|
||||
case ONE:
|
||||
return '1';
|
||||
case X:
|
||||
return 'x';
|
||||
case Z:
|
||||
return 'z';
|
||||
}
|
||||
|
||||
return ' '; // Unreachable?
|
||||
}
|
||||
|
||||
public static BitValue fromInt(int i) {
|
||||
if (i == 0) {
|
||||
return ZERO;
|
||||
} else {
|
||||
return ONE;
|
||||
}
|
||||
}
|
||||
|
||||
public int toInt() {
|
||||
return (this == ONE) ? 1 : 0;
|
||||
}
|
||||
|
||||
public static BitValue fromOrdinal(int ord) {
|
||||
return ORDINAL_TABLE[ord];
|
||||
}
|
||||
|
||||
public int compare(BitValue other) {
|
||||
if (this == ONE && other == ZERO) {
|
||||
return 1;
|
||||
} else if (this == ZERO && other == ONE) {
|
||||
return -1;
|
||||
} else {
|
||||
// Either these are equal, or there is an X and Z, which match everything.
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
@ -12,31 +12,53 @@ package com.minres.scviewer.database;
|
||||
|
||||
public class BitVector {
|
||||
|
||||
public static final char VALUE_X = 'X';
|
||||
public static final char VALUE_Z = 'Z';
|
||||
public static final char VALUE_1 = '1';
|
||||
public static final char VALUE_0 = '0';
|
||||
|
||||
private final int width;
|
||||
|
||||
private char[] value;
|
||||
private int[] packedValues;
|
||||
|
||||
public BitVector(int netWidth) {
|
||||
this.width=netWidth;
|
||||
value = new char[netWidth];
|
||||
for(int i=0; i<netWidth; i++) value[i]='0';
|
||||
packedValues = new int[(netWidth+15)/16];
|
||||
for(int i=0; i<packedValues.length; i++) packedValues[i]=0;
|
||||
}
|
||||
|
||||
public void setValue(int i, char value) {
|
||||
this.value[i]=value;
|
||||
public void setValue(int i, BitValue value) {
|
||||
int bitIndex = i*2;
|
||||
int wordOffset = bitIndex >> 5;
|
||||
int bitOffset = bitIndex & 31;
|
||||
packedValues[wordOffset] &= ~(3 << bitOffset);
|
||||
packedValues[wordOffset] |= value.ordinal() << bitOffset;
|
||||
}
|
||||
|
||||
public char[] getValue() {
|
||||
return value;
|
||||
int bitOffset = 0;
|
||||
int wordOffset = 0;
|
||||
char[] res = new char[width];
|
||||
// Copy values out of packed array
|
||||
for (int i = 0; i < width; i++) {
|
||||
int currentWord = (packedValues[wordOffset] >> bitOffset)&3;
|
||||
res[width-i-1]=BitValue.fromInt(currentWord).toChar();
|
||||
bitOffset += 2;
|
||||
if (bitOffset == 32) {
|
||||
wordOffset++;
|
||||
bitOffset = 0;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public void setValue(char[] value) {
|
||||
this.value = value;
|
||||
int bitIndex = width;
|
||||
int wordOffset = bitIndex >> 4;
|
||||
int bitOffset = (bitIndex * 2) % 32;
|
||||
for (int i = Math.min(value.length, width) - 1; i >= 0; i--) {
|
||||
packedValues[wordOffset] |= BitValue.fromChar(value[i]).ordinal() << bitOffset;
|
||||
bitOffset += 2;
|
||||
if (bitOffset == 32) {
|
||||
wordOffset++;
|
||||
bitOffset = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
@ -44,67 +66,101 @@ public class BitVector {
|
||||
}
|
||||
|
||||
public String toString(){
|
||||
return new String(value);
|
||||
return new String(getValue());
|
||||
}
|
||||
|
||||
public String toHexString(){
|
||||
int resWidth=(width-1)/4+1;
|
||||
char[] value=getValue();
|
||||
char[] res = new char[resWidth];
|
||||
for(int i=resWidth-1; i>=0; i--){
|
||||
int digit=0;
|
||||
for(int j=3; j>=0; j--){
|
||||
if(value[4*i+j]==VALUE_X ||value[4*i+j]==VALUE_Z ){
|
||||
res[i]=VALUE_X;
|
||||
}
|
||||
if(value[4*i+j]==VALUE_1)
|
||||
BitValue val = BitValue.fromChar(value[4*i+j]);
|
||||
switch(val) {
|
||||
case X:
|
||||
case Z:
|
||||
res[i]=val.toChar();
|
||||
continue;
|
||||
case ONE:
|
||||
digit+=1<<(3-j);
|
||||
res[i]=Character.forDigit(digit, 16); //((digit < 10) ? '0' + digit : 'a' + digit -10)
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
res[i]=Character.forDigit(digit, 16); //((digit < 10) ? '0' + digit : 'a' + digit -10)
|
||||
}
|
||||
return new String(res);
|
||||
}
|
||||
|
||||
public long toUnsignedValue() {
|
||||
long res = 0;
|
||||
for(char c:value) {
|
||||
int bitOffset = width * 2;
|
||||
int wordOffset = bitOffset >> 5;
|
||||
bitOffset &= 31;
|
||||
int currentWord = packedValues[wordOffset] >> bitOffset;
|
||||
// Copy values out of packed array
|
||||
for (int i = 0; i < width; i++) {
|
||||
res<<=1;
|
||||
switch (c) {
|
||||
case VALUE_1:
|
||||
switch (currentWord & 3) {
|
||||
case 1:
|
||||
res++;
|
||||
break;
|
||||
case VALUE_X:
|
||||
case VALUE_Z:
|
||||
case 2:
|
||||
case 3:
|
||||
return 0;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
bitOffset += 2;
|
||||
if (bitOffset == 32) {
|
||||
wordOffset++;
|
||||
currentWord = packedValues[wordOffset];
|
||||
bitOffset = 0;
|
||||
} else {
|
||||
currentWord >>= 2;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public long toSignedValue() {
|
||||
Boolean negative=null;
|
||||
long res = 0;
|
||||
for(char c:value) {
|
||||
int bitOffset = width * 2;
|
||||
int wordOffset = bitOffset >> 5;
|
||||
bitOffset &= 31;
|
||||
int currentWord = packedValues[wordOffset] >> bitOffset;
|
||||
// Copy values out of packed array
|
||||
for (int i = 0; i < width; i++) {
|
||||
if(negative == null) {
|
||||
switch (c) {
|
||||
case VALUE_1: negative=true; break;
|
||||
case VALUE_0: negative=false; break;
|
||||
case VALUE_X:
|
||||
case VALUE_Z: return 0;
|
||||
switch (currentWord & 3) {
|
||||
case 1: negative=true; break;
|
||||
case 0: negative=false; break;
|
||||
case 2:
|
||||
case 3: return 0;
|
||||
default:
|
||||
}
|
||||
} else {
|
||||
res<<=1;
|
||||
switch (c) {
|
||||
case VALUE_1: if(!negative) res++; break;
|
||||
case VALUE_0: if(negative) res++; break;
|
||||
case VALUE_X:
|
||||
case VALUE_Z: return 0;
|
||||
switch (currentWord & 3) {
|
||||
case 1: if(!negative) res++; break;
|
||||
case 0: if(negative) res++; break;
|
||||
case 2:
|
||||
case 3: return 0;
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
bitOffset += 2;
|
||||
if (bitOffset == 32) {
|
||||
wordOffset++;
|
||||
currentWord = packedValues[wordOffset];
|
||||
bitOffset = 0;
|
||||
} else {
|
||||
currentWord >>= 2;
|
||||
}
|
||||
}
|
||||
return negative?-1*(res+1):res;
|
||||
}
|
||||
}
|
||||
|
@ -13,12 +13,14 @@ package com.minres.scviewer.database;
|
||||
import java.util.NavigableMap;
|
||||
|
||||
|
||||
public interface ISignal<T extends ISignalChange> extends IWaveform<T>{
|
||||
public interface ISignal<T> extends IWaveform{
|
||||
|
||||
public NavigableMap<Long, T> getEvents();
|
||||
|
||||
public T getWaveformEventsAtTime(Long time);
|
||||
public T getWaveformValueAtTime(Long time);
|
||||
|
||||
public T getWaveformEventsBeforeTime(Long time);
|
||||
public T getWaveformValueBeforeTime(Long time);
|
||||
|
||||
public Class<?> getType();
|
||||
}
|
||||
|
||||
|
@ -1,15 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 MINRES Technologies GmbH and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* MINRES Technologies GmbH - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package com.minres.scviewer.database;
|
||||
|
||||
public interface ISignalChange extends IWaveformEvent {
|
||||
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 MINRES Technologies GmbH and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* MINRES Technologies GmbH - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package com.minres.scviewer.database;
|
||||
|
||||
public interface ISignalChangeBit extends ISignalChange{
|
||||
|
||||
public char getValue();
|
||||
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 MINRES Technologies GmbH and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* MINRES Technologies GmbH - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package com.minres.scviewer.database;
|
||||
|
||||
public interface ISignalChangeBitVector extends ISignalChange {
|
||||
|
||||
public BitVector getValue();
|
||||
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 MINRES Technologies GmbH and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* MINRES Technologies GmbH - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package com.minres.scviewer.database;
|
||||
|
||||
public interface ISignalChangeReal extends ISignalChange{
|
||||
|
||||
public double getValue();
|
||||
|
||||
}
|
@ -14,7 +14,7 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.NavigableMap;
|
||||
|
||||
public interface ITxStream<T extends ITxEvent> extends IWaveform<T> {
|
||||
public interface ITxStream<T extends ITxEvent> extends IWaveform {
|
||||
|
||||
public List<ITxGenerator> getGenerators();
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
package com.minres.scviewer.database;
|
||||
|
||||
|
||||
public interface IWaveform<T extends IWaveformEvent> extends IHierNode {
|
||||
public interface IWaveform extends IHierNode {
|
||||
|
||||
public Long getId();
|
||||
|
||||
@ -19,6 +19,6 @@ public interface IWaveform<T extends IWaveformEvent> extends IHierNode {
|
||||
|
||||
public IWaveformDb getDb();
|
||||
|
||||
public Boolean equals(IWaveform<? extends IWaveformEvent> other);
|
||||
public Boolean equals(IWaveform other);
|
||||
|
||||
}
|
||||
|
@ -18,9 +18,9 @@ public interface IWaveformDb extends IHierNode {
|
||||
|
||||
public Long getMaxTime();
|
||||
|
||||
public IWaveform<? extends IWaveformEvent> getStreamByName(String name);
|
||||
public IWaveform getStreamByName(String name);
|
||||
|
||||
public List<IWaveform<?>> getAllWaves();
|
||||
public List<IWaveform> getAllWaves();
|
||||
|
||||
public List<RelationType> getAllRelationTypes();
|
||||
|
||||
|
@ -20,7 +20,7 @@ public interface IWaveformDbLoader {
|
||||
|
||||
public Long getMaxTime();
|
||||
|
||||
public List<IWaveform<? extends IWaveformEvent>> getAllWaves() ;
|
||||
public List<IWaveform> getAllWaves() ;
|
||||
|
||||
public Collection<RelationType> getAllRelationTypes() ;
|
||||
|
||||
|
@ -1,46 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 MINRES Technologies GmbH and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* MINRES Technologies GmbH - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package com.minres.scviewer.database;
|
||||
|
||||
public class SignalChange implements IWaveformEvent {
|
||||
|
||||
Long time;
|
||||
|
||||
|
||||
public SignalChange() {
|
||||
time=0L;
|
||||
}
|
||||
|
||||
public SignalChange(Long time) {
|
||||
super();
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(IWaveformEvent o) {
|
||||
return time.compareTo(o.getTime());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public void setTime(Long time) {
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IWaveformEvent duplicate() throws CloneNotSupportedException {
|
||||
return (IWaveformEvent) this.clone();
|
||||
}
|
||||
|
||||
}
|
@ -41,7 +41,7 @@ public class WaveformDb extends HierNode implements IWaveformDb {
|
||||
|
||||
private List<RelationType> relationTypes;
|
||||
|
||||
private Map<String, IWaveform<?>> waveforms;
|
||||
private Map<String, IWaveform> waveforms;
|
||||
|
||||
private Long maxTime;
|
||||
|
||||
@ -61,7 +61,7 @@ public class WaveformDb extends HierNode implements IWaveformDb {
|
||||
|
||||
public WaveformDb() {
|
||||
super();
|
||||
waveforms = new HashMap<String, IWaveform<?>>();
|
||||
waveforms = new HashMap<String, IWaveform>();
|
||||
relationTypes=new ArrayList<>();
|
||||
maxTime=0L;
|
||||
}
|
||||
@ -72,20 +72,20 @@ public class WaveformDb extends HierNode implements IWaveformDb {
|
||||
}
|
||||
|
||||
@Override
|
||||
public IWaveform<? extends IWaveformEvent> getStreamByName(String name) {
|
||||
public IWaveform getStreamByName(String name) {
|
||||
return waveforms.get(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IWaveform<?>> getAllWaves() {
|
||||
return new ArrayList<IWaveform<?>>(waveforms.values());
|
||||
public List<IWaveform> getAllWaves() {
|
||||
return new ArrayList<IWaveform>(waveforms.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean load(File inp) throws Exception {
|
||||
for(IWaveformDbLoader loader:loaders){
|
||||
if(loader.load(this, inp)){
|
||||
for(IWaveform<?> w:loader.getAllWaves()){
|
||||
for(IWaveform w:loader.getAllWaves()){
|
||||
waveforms.put(w.getFullName(),w);
|
||||
}
|
||||
if(loader.getMaxTime()>maxTime){
|
||||
@ -125,8 +125,8 @@ public class WaveformDb extends HierNode implements IWaveformDb {
|
||||
|
||||
private void buildHierarchyNodes() throws InputFormatException{
|
||||
childNodes= new ArrayList<IHierNode>();
|
||||
for(IWaveform<?> stream:getAllWaves()){
|
||||
updateMaxTime(stream);
|
||||
for(IWaveform stream:getAllWaves()){
|
||||
//updateMaxTime(stream);
|
||||
String[] hier = stream.getName().split("\\.");
|
||||
IHierNode node = this;
|
||||
List<String> path=new LinkedList<String>();
|
||||
@ -169,16 +169,6 @@ public class WaveformDb extends HierNode implements IWaveformDb {
|
||||
}
|
||||
}
|
||||
|
||||
private void updateMaxTime(IWaveform<?> waveform) {
|
||||
Long last=0L;
|
||||
if(waveform instanceof ITxStream<?> && ((ITxStream<?>)waveform).getEvents().lastEntry()!=null)
|
||||
last=((ITxStream<?>)waveform).getEvents().lastEntry().getKey();
|
||||
else if(waveform instanceof ISignal<?> && ((ISignal<?>)waveform).getEvents().lastEntry()!=null)
|
||||
last=((ISignal<?>)waveform).getEvents().lastEntry().getKey();
|
||||
if(last>maxTime)
|
||||
maxTime=last;
|
||||
}
|
||||
|
||||
private static String join(Collection<?> col, String delim) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Iterator<?> iter = col.iterator();
|
||||
|
Reference in New Issue
Block a user