Commit d3905561 authored by danno's avatar danno Committed by Commit bot

[turbolizer] Use locations rather than ranges everywhere

Also convert CodeView to a class and fix a host of selection
bugs in the process, as well as move the logic and data to
"enrich" location with one type of location data with location
data known globally to the whole graph in the selection broker.

Review-Url: https://codereview.chromium.org/2230083004
Cr-Commit-Position: refs/heads/master@{#38544}
parent 63516a8c
This diff is collapsed.
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
"use strict"; "use strict";
class DisassemblyView extends TextView { class DisassemblyView extends TextView {
constructor(id, broker, sortedPositionList) { constructor(id, broker) {
super(id, broker, null, false); super(id, broker, null, false);
let view = this; let view = this;
...@@ -40,9 +40,16 @@ class DisassemblyView extends TextView { ...@@ -40,9 +40,16 @@ class DisassemblyView extends TextView {
let OPCODE_STYLE = { let OPCODE_STYLE = {
css: 'kwd', css: 'kwd',
location: function(text) { location: function(text) {
return { if (BLOCK_HEADER_STYLE.block_id != undefined) {
address: ADDRESS_STYLE.last_address return {
}; address: ADDRESS_STYLE.last_address,
block_id: BLOCK_HEADER_STYLE.block_id
};
} else {
return {
address: ADDRESS_STYLE.last_address
};
}
} }
}; };
const BLOCK_HEADER_STYLE = { const BLOCK_HEADER_STYLE = {
......
...@@ -34,7 +34,7 @@ class GraphView extends View { ...@@ -34,7 +34,7 @@ class GraphView extends View {
broker.clear(selectionHandler); broker.clear(selectionHandler);
}, },
select: function(items, selected) { select: function(items, selected) {
var ranges = []; var locations = [];
for (var d of items) { for (var d of items) {
if (selected) { if (selected) {
d.classList.add("selected"); d.classList.add("selected");
...@@ -42,22 +42,22 @@ class GraphView extends View { ...@@ -42,22 +42,22 @@ class GraphView extends View {
d.classList.remove("selected"); d.classList.remove("selected");
} }
var data = d.__data__; var data = d.__data__;
ranges.push([data.pos, data.pos + 1, data.id]); locations.push({ pos_start: data.pos, pos_end: data.pos + 1, node_id: data.id});
} }
broker.select(selectionHandler, ranges, selected); broker.select(selectionHandler, locations, selected);
}, },
selectionDifference: function(span1, inclusive1, span2, inclusive2) { selectionDifference: function(span1, inclusive1, span2, inclusive2) {
// Should not be called // Should not be called
}, },
brokeredSelect: function(ranges, selected) { brokeredSelect: function(locations, selected) {
var test = [].entries().next(); var test = [].entries().next();
var selection = graph.nodes var selection = graph.nodes
.filter(function(n) { .filter(function(n) {
var pos = n.pos; var pos = n.pos;
for (var range of ranges) { for (var location of locations) {
var start = range[0]; var start = location.pos_start;
var end = range[1]; var end = location.pos_end;
var id = range[2]; var id = location.node_id;
if (end != undefined) { if (end != undefined) {
if (pos >= start && pos < end) { if (pos >= start && pos < end) {
return true; return true;
...@@ -240,6 +240,7 @@ class GraphView extends View { ...@@ -240,6 +240,7 @@ class GraphView extends View {
if (rememberedSelection != null) { if (rememberedSelection != null) {
this.attachSelection(rememberedSelection); this.attachSelection(rememberedSelection);
this.connectVisibleSelectedNodes(); this.connectVisibleSelectedNodes();
this.viewSelection();
} }
this.updateGraphVisibility(); this.updateGraphVisibility();
} }
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
"use strict"; "use strict";
class ScheduleView extends TextView { class ScheduleView extends TextView {
constructor(id, broker, nodePositionMap) { constructor(id, broker) {
super(id, broker, null, false); super(id, broker, null, false);
let view = this; let view = this;
let BLOCK_STYLE = { let BLOCK_STYLE = {
...@@ -103,7 +103,6 @@ class ScheduleView extends TextView { ...@@ -103,7 +103,6 @@ class ScheduleView extends TextView {
] ]
]; ];
this.setPatterns(patterns); this.setPatterns(patterns);
this.setNodePositionMap(nodePositionMap);
} }
initializeContent(data, rememberedSelection) { initializeContent(data, rememberedSelection) {
...@@ -113,14 +112,16 @@ class ScheduleView extends TextView { ...@@ -113,14 +112,16 @@ class ScheduleView extends TextView {
for (var id of rememberedSelection) { for (var id of rememberedSelection) {
locations.push({ node_id : id }); locations.push({ node_id : id });
} }
this.selectLocations(locations, true, false); this.selectLocations(locations, true, true);
} }
detachSelection() { detachSelection() {
var selection = this.selection.detachSelection(); var selection = this.selection.detachSelection();
var s = new Set(); var s = new Set();
for (var i of selection) { for (var i of selection) {
s.add(i.location.node_id); if (i.location.node_id != undefined && i.location.node_id > 0) {
s.add(i.location.node_id);
}
}; };
return s; return s;
} }
......
...@@ -6,25 +6,78 @@ var SelectionBroker = function() { ...@@ -6,25 +6,78 @@ var SelectionBroker = function() {
this.brokers = []; this.brokers = [];
this.dispatching = false; this.dispatching = false;
this.lastDispatchingHandler = null; this.lastDispatchingHandler = null;
this.nodePositionMap = [];
this.sortedPositionList = [];
this.positionNodeMap = [];
}; };
SelectionBroker.prototype.addSelectionHandler = function(handler) { SelectionBroker.prototype.addSelectionHandler = function(handler) {
this.brokers.push(handler); this.brokers.push(handler);
} }
SelectionBroker.prototype.select = function(from, ranges, selected) { SelectionBroker.prototype.setNodePositionMap = function(map) {
if (!this.dispatching) { let broker = this;
this.lastDispatchingHandler = from; if (!map) return;
broker.nodePositionMap = map;
broker.positionNodeMap = [];
broker.sortedPositionList = [];
let next = 0;
for (let i in broker.nodePositionMap) {
broker.sortedPositionList[next] = Number(broker.nodePositionMap[i]);
broker.positionNodeMap[next++] = i;
}
broker.sortedPositionList = sortUnique(broker.sortedPositionList,
function(a,b) { return a - b; });
this.positionNodeMap.sort(function(a,b) {
let result = broker.nodePositionMap[a] - broker.nodePositionMap[b];
if (result != 0) return result;
return a - b;
});
}
SelectionBroker.prototype.select = function(from, locations, selected) {
let broker = this;
if (!broker.dispatching) {
broker.lastDispatchingHandler = from;
try { try {
this.dispatching = true; broker.dispatching = true;
let enrichLocations = function(locations) {
result = [];
for (let location of locations) {
let newLocation = {};
if (location.pos_start != undefined) {
newLocation.pos_start = location.pos_start;
}
if (location.pos_end != undefined) {
newLocation.pos_end = location.pos_end;
}
if (location.node_id != undefined) {
newLocation.node_id = location.node_id;
}
if (location.block_id != undefined) {
newLocation.block_id = location.block_id;
}
if (newLocation.pos_start == undefined &&
newLocation.pos_end == undefined &&
newLocation.node_id != undefined) {
if (broker.nodePositionMap && broker.nodePositionMap[location.node_id]) {
newLocation.pos_start = broker.nodePositionMap[location.node_id];
newLocation.pos_end = location.pos_start + 1;
}
}
result.push(newLocation);
}
return result;
}
locations = enrichLocations(locations);
for (var b of this.brokers) { for (var b of this.brokers) {
if (b != from) { if (b != from) {
b.brokeredSelect(ranges, selected); b.brokeredSelect(locations, selected);
} }
} }
} }
finally { finally {
this.dispatching = false; broker.dispatching = false;
} }
} }
} }
......
...@@ -40,6 +40,7 @@ Selection.prototype.select = function(s, isSelected) { ...@@ -40,6 +40,7 @@ Selection.prototype.select = function(s, isSelected) {
} }
this.selection.add(i); this.selection.add(i);
} }
handler.select(this.selection, true);
} else { } else {
let unselectSet = new Set(); let unselectSet = new Set();
for (let i of s) { for (let i of s) {
...@@ -48,8 +49,8 @@ Selection.prototype.select = function(s, isSelected) { ...@@ -48,8 +49,8 @@ Selection.prototype.select = function(s, isSelected) {
this.selection.delete(i); this.selection.delete(i);
} }
} }
handler.select(unselectSet, false);
} }
handler.select(this.selection, isSelected);
} }
......
...@@ -8,9 +8,7 @@ class TextView extends View { ...@@ -8,9 +8,7 @@ class TextView extends View {
constructor(id, broker, patterns, allowSpanSelection) { constructor(id, broker, patterns, allowSpanSelection) {
super(id, broker); super(id, broker);
let view = this; let view = this;
view.sortedPositionList = []; view.hide();
view.nodePositionMap = [];
view.positionNodeMap = [];
view.textListNode = view.divNode.getElementsByTagName('ul')[0]; view.textListNode = view.divNode.getElementsByTagName('ul')[0];
view.fillerSvgElement = view.divElement.append("svg").attr('version','1.1').attr("width", "0"); view.fillerSvgElement = view.divElement.append("svg").attr('version','1.1').attr("width", "0");
view.patterns = patterns; view.patterns = patterns;
...@@ -29,13 +27,12 @@ class TextView extends View { ...@@ -29,13 +27,12 @@ class TextView extends View {
} }
} }
broker.clear(selectionHandler); broker.clear(selectionHandler);
broker.select(selectionHandler, view.getRanges(items), selected); broker.select(selectionHandler, view.getLocations(items), selected);
}, },
selectionDifference: function(span1, inclusive1, span2, inclusive2) { selectionDifference: function(span1, inclusive1, span2, inclusive2) {
return null; return null;
}, },
brokeredSelect: function(ranges, selected) { brokeredSelect: function(locations, selected) {
let locations = view.rangesToLocations(ranges);
view.selectLocations(locations, selected, true); view.selectLocations(locations, selected, true);
}, },
brokeredClear: function() { brokeredClear: function() {
...@@ -58,36 +55,6 @@ class TextView extends View { ...@@ -58,36 +55,6 @@ class TextView extends View {
} }
} }
rangeToLocation(range) {
return range;
}
rangesToLocations(ranges) {
let view = this;
let nodes = new Set();
let result = [];
for (let range of ranges) {
let start = range[0];
let end = range[1];
let block_id = range[3];
let location = { pos_start: start, pos_end: end, block_id: block_id };
if (range[2] !== null && range[2] != -1) {
location.node_id = range[2];
if (range[0] == -1 && range[1] == -1) {
location.pos_start = view.nodePositionMap[location.node_id];
location.pos_end = location.pos_start + 1;
}
} else {
if (range[0] != undefined) {
location.pos_start = range[0];
location.pos_end = range[1];
}
}
result.push(location);
}
return result;
}
sameLocation(l1, l2) { sameLocation(l1, l2) {
let view = this; let view = this;
if (l1.block_id != undefined && l2.block_id != undefined && if (l1.block_id != undefined && l2.block_id != undefined &&
...@@ -102,7 +69,7 @@ class TextView extends View { ...@@ -102,7 +69,7 @@ class TextView extends View {
let node1 = l1.node_id; let node1 = l1.node_id;
let node2 = l2.node_id; let node2 = l2.node_id;
if (node1 === undefined && node2 == undefined) { if (node1 === undefined || node2 == undefined) {
if (l1.pos_start === undefined || l2.pos_start == undefined) { if (l1.pos_start === undefined || l2.pos_start == undefined) {
return false; return false;
} }
...@@ -116,56 +83,9 @@ class TextView extends View { ...@@ -116,56 +83,9 @@ class TextView extends View {
} }
} }
if (node1 === undefined) {
let lower = lowerBound(view.positionNodeMap, l1.pos_start, undefined, function(a, b) {
var node = a[b];
return view.nodePositionMap[node];
} );
while (++lower < view.positionNodeMap.length &&
view.nodePositionMap[view.positionNodeMap[lower]] < l1.pos_end) {
if (view.positionNodeMap[lower] == node2) {
return true;
}
}
return false;
}
if (node2 === undefined) {
let lower = lowerBound(view.positionNodeMap, l2.pos_start, undefined, function(a, b) {
var node = a[b];
return view.nodePositionMap[node];
} );
while (++lower < view.positionNodeMap.length &&
view.nodePositionMap[view.positionNodeMap[lower]] < l2.pos_end) {
if (view.positionNodeMap[lower] == node1) {
return true;
}
}
return false;
}
return l1.node_id == l2.node_id; return l1.node_id == l2.node_id;
} }
setNodePositionMap(map) {
let view = this;
view.nodePositionMap = map;
view.positionNodeMap = [];
view.sortedPositionList = [];
let next = 0;
for (let i in view.nodePositionMap) {
view.sortedPositionList[next] = Number(view.nodePositionMap[i]);
view.positionNodeMap[next++] = i;
}
view.sortedPositionList = sortUnique(view.sortedPositionList,
function(a,b) { return a - b; });
this.positionNodeMap.sort(function(a,b) {
let result = view.nodePositionMap[a] - view.nodePositionMap[b];
if (result != 0) return result;
return a - b;
});
}
selectLocations(locations, selected, makeVisible) { selectLocations(locations, selected, makeVisible) {
let view = this; let view = this;
let s = new Set(); let s = new Set();
...@@ -180,39 +100,12 @@ class TextView extends View { ...@@ -180,39 +100,12 @@ class TextView extends View {
view.selectCommon(s, selected, makeVisible); view.selectCommon(s, selected, makeVisible);
} }
getRanges(items) { getLocations(items) {
let result = []; let result = [];
let lastObject = null; let lastObject = null;
for (let i of items) { for (let i of items) {
if (i.location) { if (i.location) {
let location = i.location; result.push(i.location);
let start = -1;
let end = -1;
let node_id = -1;
let block_id = -1;
if (location.node_id !== undefined) {
node_id = location.node_id;
}
if (location.block_id !== undefined) {
block_id = location.block_id;
}
if (location.pos_start !== undefined) {
start = location.pos_start;
end = location.pos_end;
} else {
if (this.nodePositionMap && this.nodePositionMap[node_id]) {
start = this.nodePositionMap[node_id];
end = start + 1;
}
}
if (lastObject == null ||
(lastObject[2] != node_id ||
lastObject[0] != start ||
lastObject[1] != end ||
lastObject[3] != block_id)) {
lastObject = [start, end, node_id, block_id];
result.push(lastObject);
}
} }
} }
return result; return result;
...@@ -304,13 +197,13 @@ class TextView extends View { ...@@ -304,13 +197,13 @@ class TextView extends View {
} }
} }
} else if (typeof s[Symbol.iterator] === 'function') { } else if (typeof s[Symbol.iterator] === 'function') {
for (let i of s) { if (firstSelect) {
if (firstSelect) { for (let i of s) {
makeContainerPosVisible(view.parentNode, i.offsetTop); makeContainerPosVisible(view.parentNode, i.offsetTop);
firstSelect = false; break;
} }
view.selection.select(i, selected);
} }
view.selection.select(s, selected);
} else { } else {
if (firstSelect) { if (firstSelect) {
makeContainerPosVisible(view.parentNode, s.offsetTop); makeContainerPosVisible(view.parentNode, s.offsetTop);
......
...@@ -170,9 +170,10 @@ document.onload = (function(d3){ ...@@ -170,9 +170,10 @@ document.onload = (function(d3){
hideCurrentPhase(); hideCurrentPhase();
selectionBroker.setNodePositionMap(jsonObj.nodePositions);
sourceView.initializeCode(jsonObj.source, jsonObj.sourcePosition); sourceView.initializeCode(jsonObj.source, jsonObj.sourcePosition);
disassemblyView.initializeCode(jsonObj.source, jsonObj.sourcePosition); disassemblyView.initializeCode(jsonObj.source);
schedule.setNodePositionMap(jsonObj.nodePositions);
var selectMenu = document.getElementById('display-selector'); var selectMenu = document.getElementById('display-selector');
var disassemblyPhase = null; var disassemblyPhase = null;
...@@ -195,7 +196,6 @@ document.onload = (function(d3){ ...@@ -195,7 +196,6 @@ document.onload = (function(d3){
eventMenu.add(optionElement, null); eventMenu.add(optionElement, null);
} }
disassemblyView.initializePerfProfile(jsonObj.eventCounts); disassemblyView.initializePerfProfile(jsonObj.eventCounts);
disassemblyView.setNodePositionMap(jsonObj.nodePositions);
disassemblyView.show(disassemblyPhase.data, null); disassemblyView.show(disassemblyPhase.data, null);
var initialPhaseIndex = +window.sessionStorage.getItem("lastSelectedPhase"); var initialPhaseIndex = +window.sessionStorage.getItem("lastSelectedPhase");
......
...@@ -9,7 +9,6 @@ class View { ...@@ -9,7 +9,6 @@ class View {
this.divElement = d3.select("#" + id); this.divElement = d3.select("#" + id);
this.divNode = this.divElement[0][0]; this.divNode = this.divElement[0][0];
this.parentNode = this.divNode.parentNode; this.parentNode = this.divNode.parentNode;
this.hide();
} }
isScrollable() { isScrollable() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment