2018-11-03 17:48:36 +01:00
|
|
|
/*******************************************************************************
|
|
|
|
* 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;
|
2018-11-05 18:16:59 +01:00
|
|
|
import org.iq80.leveldb.impl.SeekingIterator;
|
2018-11-03 17:48:36 +01:00
|
|
|
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 {
|
|
|
|
|
2018-11-05 18:16:59 +01:00
|
|
|
private TxDBWrapper levelDb;
|
2018-11-03 17:48:36 +01:00
|
|
|
private TxStream trStream;
|
|
|
|
private TxGenerator trGenerator;
|
|
|
|
private long id;
|
2018-11-05 18:16:59 +01:00
|
|
|
private long start_time=0;
|
|
|
|
private long end_time=0;
|
|
|
|
private int concurency_index;
|
|
|
|
private boolean initialized=false;
|
2018-11-03 17:48:36 +01:00
|
|
|
private List<ITxAttribute> attributes;
|
|
|
|
private List<ITxRelation> incoming, outgoing;
|
|
|
|
|
2018-11-05 18:16:59 +01:00
|
|
|
public Tx(TxDBWrapper levelDb, TxStream trStream, TxGenerator trGenerator, long id) {
|
2018-11-03 17:48:36 +01:00
|
|
|
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() {
|
2018-11-05 18:16:59 +01:00
|
|
|
if(!initialized) loadFromDb();
|
|
|
|
return concurency_index;
|
2018-11-03 17:48:36 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Long getBeginTime() {
|
2018-11-05 18:16:59 +01:00
|
|
|
if(!initialized) loadFromDb();
|
|
|
|
return start_time;
|
2018-11-03 17:48:36 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Long getEndTime() {
|
2018-11-05 18:16:59 +01:00
|
|
|
loadFromDb();
|
|
|
|
return end_time;
|
2018-11-03 17:48:36 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public List<ITxAttribute> getAttributes() {
|
|
|
|
if(attributes==null) {
|
2018-11-05 18:16:59 +01:00
|
|
|
loadFromDb();
|
2018-11-03 17:48:36 +01:00
|
|
|
}
|
|
|
|
return attributes;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Collection<ITxRelation> getIncomingRelations() {
|
2018-11-05 18:16:59 +01:00
|
|
|
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));
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2018-11-03 17:48:36 +01:00
|
|
|
return incoming;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Collection<ITxRelation> getOutgoingRelations() {
|
2018-11-05 18:16:59 +01:00
|
|
|
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));
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2018-11-03 17:48:36 +01:00
|
|
|
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]";
|
|
|
|
}
|
2018-11-05 18:16:59 +01:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2018-11-03 17:48:36 +01:00
|
|
|
}
|