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 @@
"use strict";
class DisassemblyView extends TextView {
constructor(id, broker, sortedPositionList) {
constructor(id, broker) {
super(id, broker, null, false);
let view = this;
......@@ -40,9 +40,16 @@ class DisassemblyView extends TextView {
let OPCODE_STYLE = {
css: 'kwd',
location: function(text) {
return {
address: ADDRESS_STYLE.last_address
};
if (BLOCK_HEADER_STYLE.block_id != undefined) {
return {
address: ADDRESS_STYLE.last_address,
block_id: BLOCK_HEADER_STYLE.block_id
};
} else {
return {
address: ADDRESS_STYLE.last_address
};
}
}
};
const BLOCK_HEADER_STYLE = {
......
......@@ -34,7 +34,7 @@ class GraphView extends View {
broker.clear(selectionHandler);
},
select: function(items, selected) {
var ranges = [];
var locations = [];
for (var d of items) {
if (selected) {
d.classList.add("selected");
......@@ -42,22 +42,22 @@ class GraphView extends View {
d.classList.remove("selected");
}
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) {
// Should not be called
},
brokeredSelect: function(ranges, selected) {
brokeredSelect: function(locations, selected) {
var test = [].entries().next();
var selection = graph.nodes
.filter(function(n) {
var pos = n.pos;
for (var range of ranges) {
var start = range[0];
var end = range[1];
var id = range[2];
for (var location of locations) {
var start = location.pos_start;
var end = location.pos_end;
var id = location.node_id;
if (end != undefined) {
if (pos >= start && pos < end) {
return true;
......@@ -240,6 +240,7 @@ class GraphView extends View {
if (rememberedSelection != null) {
this.attachSelection(rememberedSelection);
this.connectVisibleSelectedNodes();
this.viewSelection();
}
this.updateGraphVisibility();
}
......
......@@ -5,7 +5,7 @@
"use strict";
class ScheduleView extends TextView {
constructor(id, broker, nodePositionMap) {
constructor(id, broker) {
super(id, broker, null, false);
let view = this;
let BLOCK_STYLE = {
......@@ -103,7 +103,6 @@ class ScheduleView extends TextView {
]
];
this.setPatterns(patterns);
this.setNodePositionMap(nodePositionMap);
}
initializeContent(data, rememberedSelection) {
......@@ -113,14 +112,16 @@ class ScheduleView extends TextView {
for (var id of rememberedSelection) {
locations.push({ node_id : id });
}
this.selectLocations(locations, true, false);
this.selectLocations(locations, true, true);
}
detachSelection() {
var selection = this.selection.detachSelection();
var s = new Set();
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;
}
......
......@@ -6,25 +6,78 @@ var SelectionBroker = function() {
this.brokers = [];
this.dispatching = false;
this.lastDispatchingHandler = null;
this.nodePositionMap = [];
this.sortedPositionList = [];
this.positionNodeMap = [];
};
SelectionBroker.prototype.addSelectionHandler = function(handler) {
this.brokers.push(handler);
}
SelectionBroker.prototype.select = function(from, ranges, selected) {
if (!this.dispatching) {
this.lastDispatchingHandler = from;
SelectionBroker.prototype.setNodePositionMap = function(map) {
let broker = this;
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 {
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) {
if (b != from) {
b.brokeredSelect(ranges, selected);
b.brokeredSelect(locations, selected);
}
}
}
finally {
this.dispatching = false;
broker.dispatching = false;
}
}
}
......
......@@ -40,6 +40,7 @@ Selection.prototype.select = function(s, isSelected) {
}
this.selection.add(i);
}
handler.select(this.selection, true);
} else {
let unselectSet = new Set();
for (let i of s) {
......@@ -48,8 +49,8 @@ Selection.prototype.select = function(s, isSelected) {
this.selection.delete(i);
}
}
handler.select(unselectSet, false);
}
handler.select(this.selection, isSelected);
}
......
......@@ -8,9 +8,7 @@ class TextView extends View {
constructor(id, broker, patterns, allowSpanSelection) {
super(id, broker);
let view = this;
view.sortedPositionList = [];
view.nodePositionMap = [];
view.positionNodeMap = [];
view.hide();
view.textListNode = view.divNode.getElementsByTagName('ul')[0];
view.fillerSvgElement = view.divElement.append("svg").attr('version','1.1').attr("width", "0");
view.patterns = patterns;
......@@ -29,13 +27,12 @@ class TextView extends View {
}
}
broker.clear(selectionHandler);
broker.select(selectionHandler, view.getRanges(items), selected);
broker.select(selectionHandler, view.getLocations(items), selected);
},
selectionDifference: function(span1, inclusive1, span2, inclusive2) {
return null;
},
brokeredSelect: function(ranges, selected) {
let locations = view.rangesToLocations(ranges);
brokeredSelect: function(locations, selected) {
view.selectLocations(locations, selected, true);
},
brokeredClear: function() {
......@@ -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) {
let view = this;
if (l1.block_id != undefined && l2.block_id != undefined &&
......@@ -102,7 +69,7 @@ class TextView extends View {
let node1 = l1.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) {
return false;
}
......@@ -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;
}
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) {
let view = this;
let s = new Set();
......@@ -180,39 +100,12 @@ class TextView extends View {
view.selectCommon(s, selected, makeVisible);
}
getRanges(items) {
getLocations(items) {
let result = [];
let lastObject = null;
for (let i of items) {
if (i.location) {
let location = 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);
}
result.push(i.location);
}
}
return result;
......@@ -304,13 +197,13 @@ class TextView extends View {
}
}
} 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);
firstSelect = false;
break;
}
view.selection.select(i, selected);
}
view.selection.select(s, selected);
} else {
if (firstSelect) {
makeContainerPosVisible(view.parentNode, s.offsetTop);
......
......@@ -170,9 +170,10 @@ document.onload = (function(d3){
hideCurrentPhase();
selectionBroker.setNodePositionMap(jsonObj.nodePositions);
sourceView.initializeCode(jsonObj.source, jsonObj.sourcePosition);
disassemblyView.initializeCode(jsonObj.source, jsonObj.sourcePosition);
schedule.setNodePositionMap(jsonObj.nodePositions);
disassemblyView.initializeCode(jsonObj.source);
var selectMenu = document.getElementById('display-selector');
var disassemblyPhase = null;
......@@ -195,7 +196,6 @@ document.onload = (function(d3){
eventMenu.add(optionElement, null);
}
disassemblyView.initializePerfProfile(jsonObj.eventCounts);
disassemblyView.setNodePositionMap(jsonObj.nodePositions);
disassemblyView.show(disassemblyPhase.data, null);
var initialPhaseIndex = +window.sessionStorage.getItem("lastSelectedPhase");
......
......@@ -9,7 +9,6 @@ class View {
this.divElement = d3.select("#" + id);
this.divNode = this.divElement[0][0];
this.parentNode = this.divNode.parentNode;
this.hide();
}
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