Skip to content
Snippets Groups Projects
Commit 8f9369ec authored by Simon Könnecke's avatar Simon Könnecke
Browse files

snapshot based histograms

parent b2653e3f
No related branches found
No related tags found
No related merge requests found
...@@ -3,3 +3,4 @@ ...@@ -3,3 +3,4 @@
.idea/ .idea/
*.iml *.iml
.DS_Store .DS_Store
snapshots
\ No newline at end of file
...@@ -62,6 +62,12 @@ ...@@ -62,6 +62,12 @@
<artifactId>jgraphx</artifactId> <artifactId>jgraphx</artifactId>
<version>1.10.1.3</version> <version>1.10.1.3</version>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/org.jfree/jfreechart -->
<dependency>
<groupId>org.jfree</groupId>
<artifactId>jfreechart</artifactId>
<version>1.0.14</version>
</dependency>
<dependency> <dependency>
<groupId>it.unimi.dsi</groupId> <groupId>it.unimi.dsi</groupId>
<artifactId>fastutil</artifactId> <artifactId>fastutil</artifactId>
......
package fucoin.actions.control;
import akka.actor.ActorRef;
import akka.actor.UntypedActorContext;
import fucoin.actions.ClientAction;
import fucoin.wallet.AbstractWallet;
import java.time.LocalDateTime;
/**
* Ask Wallet x for his known neighbours.
*/
public class ActionWalletGetSnapshot extends ClientAction {
private final LocalDateTime time;
public ActionWalletGetSnapshot(LocalDateTime time) {
this.time = time;
}
@Override
protected void onAction(ActorRef sender, ActorRef self, UntypedActorContext context, AbstractWallet abstractNode) {
sender.tell(new ActionWalletGetSnapshotAnswer(abstractNode, time), self);
}
}
package fucoin.actions.control;
import akka.actor.ActorRef;
import akka.actor.UntypedActorContext;
import fucoin.actions.ClientAction;
import fucoin.wallet.AbstractWallet;
import fucoin.wallet.Snapshot;
import java.time.LocalDateTime;
import java.util.HashMap;
/**
* Tell
*/
public class ActionWalletGetSnapshotAnswer extends ClientAction {
private final Snapshot snapshot;
public ActionWalletGetSnapshotAnswer(AbstractWallet wallet, LocalDateTime time) {
snapshot = wallet.readSnapShot(time);
}
@Override
protected void onAction(ActorRef sender, ActorRef self, UntypedActorContext context, AbstractWallet abstractNode) {
}
public Snapshot getSnapshot() {
return snapshot;
}
}
...@@ -12,7 +12,7 @@ public class MassWalletConfiguration extends AbstractConfiguration { ...@@ -12,7 +12,7 @@ public class MassWalletConfiguration extends AbstractConfiguration {
public void run() { public void run() {
//Config //Config
remainingWalletsToSpawn = 5; remainingWalletsToSpawn = 5;
remainingTransactions = 100; remainingTransactions = 10;
//Start SuperVisor //Start SuperVisor
initSupervisor(); initSupervisor();
......
package fucoin.gui; package fucoin.gui;
import akka.actor.ActorRef;
import com.mxgraph.swing.mxGraphComponent; import com.mxgraph.swing.mxGraphComponent;
import com.mxgraph.view.mxGraph; import com.mxgraph.view.mxGraph;
import fucoin.wallet.Snapshot;
import javax.swing.*; import javax.swing.*;
import java.util.*; import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Vector;
/** /**
* *
*/ */
public class SuperVisorGraphGUI extends JFrame { public class SuperVisorGraphGUI extends JFrame {
private SuperVisorGuiControlImpl superVisorGuiControl; private final SuperVisorGuiControlImpl superVisorGuiControl;
private final LocalDateTime time;
private static final int width = 1200; private static final int width = 1200;
private static final int height = 800; private static final int height = 800;
...@@ -23,9 +26,10 @@ public class SuperVisorGraphGUI extends JFrame { ...@@ -23,9 +26,10 @@ public class SuperVisorGraphGUI extends JFrame {
private HashMap<String, Object> vertex = new HashMap<>(); private HashMap<String, Object> vertex = new HashMap<>();
public SuperVisorGraphGUI(SuperVisorGuiControlImpl superVisorGuiControl) { public SuperVisorGraphGUI(SuperVisorGuiControlImpl superVisorGuiControl, LocalDateTime time) {
super("Distributed Network Graph"); super("Distributed Network Graph (Snapshot: " + time + ")");
this.superVisorGuiControl = superVisorGuiControl; this.superVisorGuiControl = superVisorGuiControl;
this.time = time;
setVisible(true); setVisible(true);
setSize(width, height); setSize(width, height);
} }
...@@ -51,10 +55,10 @@ public class SuperVisorGraphGUI extends JFrame { ...@@ -51,10 +55,10 @@ public class SuperVisorGraphGUI extends JFrame {
} }
} }
for (Map.Entry<String, HashMap<String, ActorRef>> item1 : for (Snapshot item1 :
superVisorGuiControl.getNodeNeighbourList().entrySet()) { superVisorGuiControl.getSnapshots()) {
for (Map.Entry<String, ActorRef> item2: item1.getValue().entrySet()) { for (String item2 : item1.getKnownNeighbour()) {
graph.insertEdge(parent, null, "", vertex.get(item1.getKey()), vertex.get(item2.getKey())); graph.insertEdge(parent, null, "", vertex.get(item1.getName()), vertex.get(item2));
} }
} }
} finally { } finally {
......
...@@ -4,17 +4,18 @@ import akka.actor.ActorRef; ...@@ -4,17 +4,18 @@ import akka.actor.ActorRef;
import akka.pattern.Patterns; import akka.pattern.Patterns;
import akka.util.Timeout; import akka.util.Timeout;
import fucoin.actions.control.ActionWalletCreateSnapshot; import fucoin.actions.control.ActionWalletCreateSnapshot;
import fucoin.actions.control.ActionWalletGetNeighbours; import fucoin.actions.control.ActionWalletGetSnapshot;
import fucoin.actions.control.ActionWalletGetNeighboursAnswer; import fucoin.actions.control.ActionWalletGetSnapshotAnswer;
import fucoin.supervisor.AmountTableModel; import fucoin.supervisor.AmountTableModel;
import fucoin.supervisor.SuperVisorImpl; import fucoin.supervisor.SuperVisorImpl;
import fucoin.wallet.Snapshot;
import scala.concurrent.Await; import scala.concurrent.Await;
import scala.concurrent.Future; import scala.concurrent.Future;
import scala.concurrent.duration.Duration; import scala.concurrent.duration.Duration;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List;
import java.util.Map; import java.util.Map;
public class SuperVisorGuiControlImpl implements SuperVisorGuiControl { public class SuperVisorGuiControlImpl implements SuperVisorGuiControl {
...@@ -22,14 +23,16 @@ public class SuperVisorGuiControlImpl implements SuperVisorGuiControl { ...@@ -22,14 +23,16 @@ public class SuperVisorGuiControlImpl implements SuperVisorGuiControl {
private AmountTableModel amountTableModel; private AmountTableModel amountTableModel;
private HashMap<String, HashMap<String, ActorRef>> nodeNeighbours = new HashMap<>(); private List<Snapshot> loadedSnapshotsOfWallets = new LinkedList<>();
private LinkedList<LocalDateTime> snapshotTimes = new LinkedList<>(); private LinkedList<LocalDateTime> snapshotTimes = new LinkedList<>();
private LocalDateTime loadedSnapshotDateTime;
private SuperVisorThreadGUI threadGUI; private SuperVisorThreadGUI threadGUI;
private boolean logActive = false; private boolean logActive = false;
public SuperVisorGuiControlImpl(SuperVisorImpl sv) { public SuperVisorGuiControlImpl(SuperVisorImpl sv) {
superVisor = sv; superVisor = sv;
init(); init();
...@@ -52,27 +55,35 @@ public class SuperVisorGuiControlImpl implements SuperVisorGuiControl { ...@@ -52,27 +55,35 @@ public class SuperVisorGuiControlImpl implements SuperVisorGuiControl {
} }
} }
public void updateNodeNeighbourList() { public void loadSnapshot(LocalDateTime time) {
if (loadedSnapshotDateTime != null &&
loadedSnapshotDateTime.equals(time) &&
loadedSnapshotsOfWallets.size() > 0) {
return;
}
loadedSnapshotsOfWallets.clear();
loadedSnapshotDateTime = time;
try { try {
Timeout timeout = new Timeout(Duration.create(10, "seconds")); Timeout timeout = new Timeout(Duration.create(10, "seconds"));
for (Map.Entry<String, ActorRef> item : superVisor.getKnownNeighbors().entrySet()) { for (Map.Entry<String, ActorRef> item : superVisor.getKnownNeighbors().entrySet()) {
Future<Object> futureNeighbour = Patterns.ask(item.getValue(), new ActionWalletGetNeighbours(), timeout); Future<Object> futureNeighbour = Patterns.ask(item.getValue(), new ActionWalletGetSnapshot(time), timeout);
ActionWalletGetNeighboursAnswer neighboursAnswer = (ActionWalletGetNeighboursAnswer) ActionWalletGetSnapshotAnswer snapshot = (ActionWalletGetSnapshotAnswer)
Await.result(futureNeighbour, timeout.duration()); Await.result(futureNeighbour, timeout.duration());
addNodeNeighbourList(item.getKey(), neighboursAnswer.getNeighbour()); addSnapshot(snapshot.getSnapshot());
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
public void addNodeNeighbourList(String name, HashMap<String, ActorRef> list) { public void addSnapshot(Snapshot snapshot) {
nodeNeighbours.put(name, list); loadedSnapshotsOfWallets.add(snapshot);
} }
public HashMap<String, HashMap<String, ActorRef>> getNodeNeighbourList() { public List<Snapshot> getSnapshots() {
return nodeNeighbours; return loadedSnapshotsOfWallets;
} }
public void guiTerminated() { public void guiTerminated() {
......
package fucoin.gui;
import fucoin.wallet.QDigest;
import fucoin.wallet.Snapshot;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.IntervalMarker;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.xy.IntervalXYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.ui.Layer;
import org.jfree.ui.RectangleAnchor;
import org.jfree.ui.TextAnchor;
import javax.swing.*;
import java.awt.*;
import java.time.LocalDateTime;
/**
*
*/
public class SuperVisorHistogramGUI extends JFrame {
private final SuperVisorGuiControlImpl superVisorGuiControl;
private final LocalDateTime time;
private static final int width = 1200;
private static final int height = 800;
public SuperVisorHistogramGUI(SuperVisorGuiControlImpl superVisorGuiControl, LocalDateTime time) {
super("Histogram of distributed granted commit (Snapshot " + time + ")");
this.superVisorGuiControl = superVisorGuiControl;
this.time = time;
setVisible(true);
setSize(width, height);
}
private JFreeChart createChart(IntervalXYDataset dataset) {
final JFreeChart chart = ChartFactory.createXYBarChart(
"",
"Transaction size [FUCoins]",
false,
"Frequency",
dataset,
PlotOrientation.VERTICAL,
true,
true,
false
);
XYPlot plot = (XYPlot) chart.getPlot();
final IntervalMarker target = new IntervalMarker(400.0, 700.0);
target.setLabel("Target Range");
target.setLabelFont(new Font("SansSerif", Font.ITALIC, 11));
target.setLabelAnchor(RectangleAnchor.LEFT);
target.setLabelTextAnchor(TextAnchor.CENTER_LEFT);
target.setPaint(new Color(222, 222, 255, 128));
plot.addRangeMarker(target, Layer.BACKGROUND);
return chart;
}
public void init() {
QDigest qDigest = null;
for (Snapshot item : superVisorGuiControl.getSnapshots()) {
if (qDigest == null) {
qDigest = item.getqDigest();
} else {
qDigest = QDigest.unionOf(qDigest, item.getqDigest());
}
}
final XYSeries series = new XYSeries("Transactions");
for (long[] item : qDigest.toAscRanges()) {
series.add(item[1], item[2]);
}
final XYSeriesCollection dataset = new XYSeriesCollection(series);
JFreeChart chart = createChart(dataset);
final ChartPanel chartPanel = new ChartPanel(chart);
setContentPane(chartPanel);
}
}
...@@ -84,11 +84,20 @@ public class SuperVisorThreadGUI { ...@@ -84,11 +84,20 @@ public class SuperVisorThreadGUI {
JButton showGraphBtn = new JButton("Show Graph"); JButton showGraphBtn = new JButton("Show Graph");
showGraphBtn.addActionListener(e -> { showGraphBtn.addActionListener(e -> {
superVisorGuiControl.updateNodeNeighbourList(); LocalDateTime time = (LocalDateTime) dropdown.getSelectedItem();
new SuperVisorGraphGUI(superVisorGuiControl).init(); superVisorGuiControl.loadSnapshot(time);
new SuperVisorGraphGUI(superVisorGuiControl, time).init();
}); });
btnPanel.add(showGraphBtn); btnPanel.add(showGraphBtn);
JButton showHistogramBtn = new JButton("Show Histogram");
showHistogramBtn.addActionListener(e -> {
LocalDateTime time = (LocalDateTime) dropdown.getSelectedItem();
superVisorGuiControl.loadSnapshot(time);
new SuperVisorHistogramGUI(superVisorGuiControl, time).init();
});
btnPanel.add(showHistogramBtn);
JButton createSnapshot = new JButton("Create Snapshot"); JButton createSnapshot = new JButton("Create Snapshot");
createSnapshot.addActionListener(e -> { createSnapshot.addActionListener(e -> {
LocalDateTime time = LocalDateTime.now(); LocalDateTime time = LocalDateTime.now();
......
...@@ -14,7 +14,7 @@ import java.time.LocalDateTime; ...@@ -14,7 +14,7 @@ import java.time.LocalDateTime;
*/ */
public abstract class AbstractWallet extends AbstractNode implements Serializable, TransactionLogger { public abstract class AbstractWallet extends AbstractNode implements Serializable, TransactionLogger {
private static final double sCompression = 0.1; private static final double sCompression = 5;
private QDigest qDigest = new QDigest(sCompression); private QDigest qDigest = new QDigest(sCompression);
/** /**
......
...@@ -11,7 +11,7 @@ public class Snapshot implements Serializable { ...@@ -11,7 +11,7 @@ public class Snapshot implements Serializable {
private final String name; private final String name;
private final int amount; private final int amount;
private final Set<String> knownNeighbour; private final Set<String> knownNeighbour;
private final HashMap<ActorRef, Integer> knownNeighbourAmounts; private final HashMap<String, Integer> knownNeighbourAmounts = new HashMap<>();
private final List<long[]> qDigestVal; private final List<long[]> qDigestVal;
private final byte[] qDigest; private final byte[] qDigest;
...@@ -22,7 +22,9 @@ public class Snapshot implements Serializable { ...@@ -22,7 +22,9 @@ public class Snapshot implements Serializable {
this.qDigest = QDigest.serialize(wallet.getqDigest()); this.qDigest = QDigest.serialize(wallet.getqDigest());
this.qDigestVal = wallet.getqDigest().toAscRanges(); this.qDigestVal = wallet.getqDigest().toAscRanges();
this.knownNeighbour = wallet.getKnownNeighbors().keySet(); this.knownNeighbour = wallet.getKnownNeighbors().keySet();
this.knownNeighbourAmounts = wallet.amounts; wallet.amounts.forEach((actorRef, amount) -> {
knownNeighbourAmounts.put(actorRef.toString(), amount);
});
} }
public String getName() { public String getName() {
...@@ -33,6 +35,18 @@ public class Snapshot implements Serializable { ...@@ -33,6 +35,18 @@ public class Snapshot implements Serializable {
return amount; return amount;
} }
public Set<String> getKnownNeighbour() {
return knownNeighbour;
}
public HashMap<String, Integer> getKnownNeighbourAmounts() {
return knownNeighbourAmounts;
}
public List<long[]> getqDigestVal() {
return qDigestVal;
}
public QDigest getqDigest() { public QDigest getqDigest() {
return QDigest.deserialize(this.qDigest); return QDigest.deserialize(this.qDigest);
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment