Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(597)

Side by Side Diff: chrome/browser/resources/profiler.js

Issue 8676023: Change the order of merging on about:profiler. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 var g_browserBridge; 5 var g_browserBridge;
6 var g_mainView; 6 var g_mainView;
7 7
8 // TODO(eroman): The handling of "max" across snapshots is not correct. 8 // TODO(eroman): The handling of "max" across snapshots is not correct.
9 // For starters the browser needs to be aware to generate new maximums. 9 // For starters the browser needs to be aware to generate new maximums.
10 // Secondly, we need to take into account the "max" of intermediary snapshots, 10 // Secondly, we need to take into account the "max" of intermediary snapshots,
(...skipping 848 matching lines...) Expand 10 before | Expand all | Expand 10 after
859 } 859 }
860 860
861 /** 861 /**
862 * Merges the rows in |origRows|, by collapsing the columns listed in 862 * Merges the rows in |origRows|, by collapsing the columns listed in
863 * |mergeKeys|. Returns an array with the merged rows (in no particular 863 * |mergeKeys|. Returns an array with the merged rows (in no particular
864 * order). 864 * order).
865 * 865 *
866 * If |mergeSimilarThreads| is true, then threads with a similar name will be 866 * If |mergeSimilarThreads| is true, then threads with a similar name will be
867 * considered equivalent. For instance, "WorkerThread-1" and "WorkerThread-2" 867 * considered equivalent. For instance, "WorkerThread-1" and "WorkerThread-2"
868 * will be remapped to "WorkerThread-*". 868 * will be remapped to "WorkerThread-*".
869 *
870 * If |outputAsDictionary| is false then the merged rows will be returned as a
871 * flat list. Otherwise the result will be a dictionary, where each row
872 * has a unique key.
869 */ 873 */
870 function mergeRows(origRows, mergeKeys, mergeSimilarThreads) { 874 function mergeRows(origRows, mergeKeys, mergeSimilarThreads,
875 outputAsDictionary) {
871 // Define a translation function for each property. Normally we copy over 876 // Define a translation function for each property. Normally we copy over
872 // properties as-is, but if we have been asked to "merge similar threads" we 877 // properties as-is, but if we have been asked to "merge similar threads" we
873 // we will remap the thread names that end in a numeric suffix. 878 // we will remap the thread names that end in a numeric suffix.
874 var propertyGetterFunc; 879 var propertyGetterFunc;
875 880
876 if (mergeSimilarThreads) { 881 if (mergeSimilarThreads) {
877 propertyGetterFunc = function(row, key) { 882 propertyGetterFunc = function(row, key) {
878 var value = row[key]; 883 var value = row[key];
879 // If the property is a thread name, try to remap it. 884 // If the property is a thread name, try to remap it.
880 if (key == KEY_BIRTH_THREAD || key == KEY_DEATH_THREAD) { 885 if (key == KEY_BIRTH_THREAD || key == KEY_DEATH_THREAD) {
881 var m = /^(.*[^\d])(\d+)$/.exec(value); 886 var m = /^(.*[^\d])(\d+)$/.exec(value);
882 if (m) 887 if (m)
883 value = m[1] + '*'; 888 value = m[1] + '*';
884 } 889 }
885 return value; 890 return value;
886 } 891 }
887 } else { 892 } else {
888 propertyGetterFunc = function(row, key) { return row[key]; }; 893 propertyGetterFunc = function(row, key) { return row[key]; };
889 } 894 }
890 895
891 // Determine which sets of properties a row needs to match on to be 896 // Determine which sets of properties a row needs to match on to be
892 // considered identical to another row. 897 // considered identical to another row.
893 var identityKeys = IDENTITY_KEYS.slice(0); 898 var identityKeys = IDENTITY_KEYS.slice(0);
894 deleteValuesFromArray(identityKeys, mergeKeys); 899 deleteValuesFromArray(identityKeys, mergeKeys);
895 900
896 // Set |aggregateKeys| to everything else, since we will be aggregating 901 // Set |aggregateKeys| to everything else, since we will be aggregating
897 // their value as part of the merge. 902 // their value as part of the merge.
898 var aggregateKeys = ALL_KEYS.slice(0); 903 var aggregateKeys = ALL_KEYS.slice(0);
899 deleteValuesFromArray(aggregateKeys, IDENTITY_KEYS); 904 deleteValuesFromArray(aggregateKeys, IDENTITY_KEYS);
905 deleteValuesFromArray(aggregateKeys, mergeKeys);
900 906
901 // Group all the identical rows together, bucketed into |identicalRows|. 907 // Group all the identical rows together, bucketed into |identicalRows|.
902 var identicalRows = 908 var identicalRows =
903 bucketIdenticalRows(origRows, identityKeys, propertyGetterFunc); 909 bucketIdenticalRows(origRows, identityKeys, propertyGetterFunc);
904 910
905 var mergedRows = []; 911 var mergedRows = outputAsDictionary ? {} : [];
906 912
907 // Merge the rows and save the results to |mergedRows|. 913 // Merge the rows and save the results to |mergedRows|.
908 for (var k in identicalRows) { 914 for (var k in identicalRows) {
909 // We need to smash the list |l| down to a single row... 915 // We need to smash the list |l| down to a single row...
910 var l = identicalRows[k]; 916 var l = identicalRows[k];
911 917
912 var newRow = []; 918 var newRow = [];
913 mergedRows.push(newRow); 919
920 if (outputAsDictionary) {
921 mergedRows[k] = newRow;
922 } else {
923 mergedRows.push(newRow);
924 }
914 925
915 // Copy over all the identity columns to the new row (since they 926 // Copy over all the identity columns to the new row (since they
916 // were the same for each row matched). 927 // were the same for each row matched).
917 for (var i = 0; i < identityKeys.length; ++i) 928 for (var i = 0; i < identityKeys.length; ++i)
918 newRow[identityKeys[i]] = propertyGetterFunc(l[0], identityKeys[i]); 929 newRow[identityKeys[i]] = propertyGetterFunc(l[0], identityKeys[i]);
919 930
920 // Compute aggregates for the other columns. 931 // Compute aggregates for the other columns.
921 var aggregates = initializeAggregates(aggregateKeys); 932 var aggregates = initializeAggregates(aggregateKeys);
922 933
923 // Feed the rows to the aggregators. 934 // Feed the rows to the aggregators.
924 for (var i = 0; i < l.length; ++i) 935 for (var i = 0; i < l.length; ++i)
925 consumeAggregates(aggregates, l[i]); 936 consumeAggregates(aggregates, l[i]);
926 937
927 // Suck out the data generated by the aggregators. 938 // Suck out the data generated by the aggregators.
928 for (var aggregateKey in aggregates) 939 for (var aggregateKey in aggregates)
929 newRow[aggregateKey] = aggregates[aggregateKey].getValue(); 940 newRow[aggregateKey] = aggregates[aggregateKey].getValue();
930 } 941 }
931 942
932 return mergedRows; 943 return mergedRows;
933 } 944 }
934 945
935 /** 946 /**
936 * Takes two flat lists data1 and data2, and returns a new flat list which 947 * Takes two dictionaries data1 and data2, and returns a new flat list which
937 * represents the difference between them. The exact meaning of "difference" 948 * represents the difference between them. The exact meaning of "difference"
938 * is column specific, but for most numeric fields (like the count, or total 949 * is column specific, but for most numeric fields (like the count, or total
939 * time), it is found by subtracting. 950 * time), it is found by subtracting.
940 * 951 *
941 * TODO(eroman): Some of this code is duplicated from mergeRows(). 952 * Rows in data1 and data2 are expected to use the same scheme for the keys.
953 * In other words, data1[k] is considered the analagous row to data2[k].
942 */ 954 */
943 function subtractSnapshots(data1, data2) { 955 function subtractSnapshots(data1, data2, columnsToExclude) {
jar (doing other things) 2011/12/06 01:54:36 nit: rather than data1, and data2, perhaps data_ne
eroman 2011/12/06 19:21:25 I'll leave this to a follow-up change (since it to
944 // These columns are computed from the other columns. We won't bother 956 // These columns are computed from the other columns. We won't bother
945 // diffing/aggregating these, but rather will derive them again from the 957 // diffing/aggregating these, but rather will derive them again from the
946 // final row. 958 // final row.
947 var COMPUTED_AGGREGATE_KEYS = [KEY_AVG_QUEUE_TIME, KEY_AVG_RUN_TIME]; 959 var COMPUTED_AGGREGATE_KEYS = [KEY_AVG_QUEUE_TIME, KEY_AVG_RUN_TIME];
948 960
949 // These are the keys which determine row equality. Since we are not doing 961 // These are the keys which determine row equality. Since we are not doing
950 // any merging yet at this point, it is simply the list of all identity 962 // any merging yet at this point, it is simply the list of all identity
951 // columns. 963 // columns.
952 var identityKeys = IDENTITY_KEYS; 964 var identityKeys = IDENTITY_KEYS.slice(0);
965 deleteValuesFromArray(identityKeys, columnsToExclude);
953 966
954 // The columns to compute via aggregation is everything else. 967 // The columns to compute via aggregation is everything else.
955 var aggregateKeys = ALL_KEYS.slice(0); 968 var aggregateKeys = ALL_KEYS.slice(0);
956 deleteValuesFromArray(aggregateKeys, IDENTITY_KEYS); 969 deleteValuesFromArray(aggregateKeys, IDENTITY_KEYS);
957 deleteValuesFromArray(aggregateKeys, COMPUTED_AGGREGATE_KEYS); 970 deleteValuesFromArray(aggregateKeys, COMPUTED_AGGREGATE_KEYS);
958 971 deleteValuesFromArray(aggregateKeys, columnsToExclude);
959 // Group all the identical rows for each list together.
960 var propertyGetterFunc = function(row, key) { return row[key]; };
961 var identicalRows1 =
962 bucketIdenticalRows(data1, identityKeys, propertyGetterFunc);
963 var identicalRows2 =
964 bucketIdenticalRows(data2, identityKeys, propertyGetterFunc);
965 972
966 var diffedRows = []; 973 var diffedRows = [];
967 974
968 for (var k in identicalRows2) { 975 for (var rowId in data2) {
969 var rows2 = identicalRows2[k]; 976 var row1 = data1[rowId];
970 var rows1 = identicalRows1[k]; 977 var row2 = data2[rowId];
971 if (rows1 == undefined)
972 rows1 = [];
973 978
974 var newRow = []; 979 var newRow = [];
975 980
976 // Copy over all the identity columns to the new row (since they 981 // Copy over all the identity columns to the new row (since they
977 // were the same for each row matched). 982 // were the same for each row matched).
978 for (var i = 0; i < identityKeys.length; ++i) 983 for (var i = 0; i < identityKeys.length; ++i)
979 newRow[identityKeys[i]] = propertyGetterFunc(rows2[0], identityKeys[i]); 984 newRow[identityKeys[i]] = row2[identityKeys[i]];
980 985
981 // The raw data for each snapshot *may* have contained duplicate rows, so 986 // Diff the two rows.
982 // smash them down into a single row using our aggregation functions. 987 if (row1) {
983 var aggregates1 = initializeAggregates(aggregateKeys); 988 for (var i = 0; i < aggregateKeys.length; ++i) {
984 var aggregates2 = initializeAggregates(aggregateKeys); 989 var aggregateKey = aggregateKeys[i];
985 for (var i = 0; i < rows1.length; ++i) 990 var a = row1[aggregateKey];
986 consumeAggregates(aggregates1, rows1[i]); 991 var b = row2[aggregateKey];
987 for (var i = 0; i < rows2.length; ++i)
988 consumeAggregates(aggregates2, rows2[i]);
989 992
990 // Finally, diff the two merged rows. 993 var diffFunc = KEY_PROPERTIES[aggregateKey].diff;
991 for (var aggregateKey in aggregates2) { 994 newRow[aggregateKey] = diffFunc(a, b);
992 var a = aggregates1[aggregateKey].getValue(); 995 }
993 var b = aggregates2[aggregateKey].getValue(); 996 } else {
994 997 // If the the row doesn't appear in snapshot1, then there is nothing to
995 var diffFunc = KEY_PROPERTIES[aggregateKey].diff; 998 // diff, so just copy row2 as is.
996 newRow[aggregateKey] = diffFunc(a, b); 999 for (var i = 0; i < aggregateKeys.length; ++i) {
1000 var aggregateKey = aggregateKeys[i];
1001 newRow[aggregateKey] = row2[aggregateKey];
1002 }
997 } 1003 }
998 1004
999 if (newRow[KEY_COUNT] == 0) { 1005 if (newRow[KEY_COUNT] == 0) {
1000 // If a row's count has gone to zero, it means there were no new 1006 // If a row's count has gone to zero, it means there were no new
1001 // occurrences of it in the second snapshot, so remove it. 1007 // occurrences of it in the second snapshot, so remove it.
1002 continue; 1008 continue;
1003 } 1009 }
1004 1010
1005 // Since we excluded the averages during diffing phase, re-compute them 1011 // Since we excluded the averages during the diffing phase, re-compute
1006 // using the diffed totals. 1012 // them using the diffed totals.
1007 computeDataRowAverages(newRow); 1013 computeDataRowAverages(newRow);
1008 diffedRows.push(newRow); 1014 diffedRows.push(newRow);
1009 } 1015 }
1010 1016
1011 return diffedRows; 1017 return diffedRows;
1012 } 1018 }
1013 1019
1014 // -------------------------------------------------------------------------- 1020 // --------------------------------------------------------------------------
1015 // HTML drawing code 1021 // HTML drawing code
1016 // -------------------------------------------------------------------------- 1022 // --------------------------------------------------------------------------
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
1226 1232
1227 // Add our computed properties. 1233 // Add our computed properties.
1228 augmentDataRow(newRow); 1234 augmentDataRow(newRow);
1229 1235
1230 snapshot.flatData.push(newRow); 1236 snapshot.flatData.push(newRow);
1231 } 1237 }
1232 1238
1233 if (!arrayToSet(this.getSelectedSnapshotIndexes_())[snapshotIndex]) { 1239 if (!arrayToSet(this.getSelectedSnapshotIndexes_())[snapshotIndex]) {
1234 // Optimization: If this snapshot is not a data dependency for the 1240 // Optimization: If this snapshot is not a data dependency for the
1235 // current display, then don't bother updating anything. 1241 // current display, then don't bother updating anything.
1236 return; 1242 return;
jar (doing other things) 2011/12/06 01:54:36 This may be a dangerous optimization. I think it i
eroman 2011/12/06 19:21:25 I'll leave this to a follow-up change (since I wan
1237 } 1243 }
1238 1244
1239 // We may end up calling addDataToSnapshot_() repeatedly (once for each 1245 // We may end up calling addDataToSnapshot_() repeatedly (once for each
1240 // process). To avoid this from slowing us down we do bulk updates on a 1246 // process). To avoid this from slowing us down we do bulk updates on a
1241 // timer. 1247 // timer.
1242 this.updateFlatDataSoon_(); 1248 this.updateMergedDataSoon_();
1243 }, 1249 },
1244 1250
1245 updateFlatDataSoon_: function() { 1251 updateMergedDataSoon_: function() {
eroman 2011/11/23 22:33:28 this is just a rename "flatData" -> "mergedData"
1246 if (this.updateFlatDataPending_) { 1252 if (this.updateMergedDataPending_) {
1247 // If a delayed task has already been posted to re-merge the data, 1253 // If a delayed task has already been posted to re-merge the data,
1248 // then we don't need to do anything extra. 1254 // then we don't need to do anything extra.
1249 return; 1255 return;
1250 } 1256 }
1251 1257
1252 // Otherwise schedule updateFlatData_() to be called later. We want it to 1258 // Otherwise schedule updateMergedData_() to be called later. We want it
1253 // be called no more than once every PROCESS_DATA_DELAY_MS milliseconds. 1259 // to be called no more than once every PROCESS_DATA_DELAY_MS
1260 // milliseconds.
1254 1261
1255 if (this.lastUpdateFlatDataTime_ == undefined) 1262 if (this.lastUpdateMergedDataTime_ == undefined)
1256 this.lastUpdateFlatDataTime_ = 0; 1263 this.lastUpdateMergedDataTime_ = 0;
1257 1264
1258 var timeSinceLastMerge = getTimeMillis() - this.lastUpdateFlatDataTime_; 1265 var timeSinceLastMerge = getTimeMillis() - this.lastUpdateMergedDataTime_;
1259 var timeToWait = Math.max(0, PROCESS_DATA_DELAY_MS - timeSinceLastMerge); 1266 var timeToWait = Math.max(0, PROCESS_DATA_DELAY_MS - timeSinceLastMerge);
1260 1267
1261 var functionToRun = function() { 1268 var functionToRun = function() {
1262 // Do the actual update. 1269 // Do the actual update.
1263 this.updateFlatData_(); 1270 this.updateMergedData_();
1264 // Keep track of when we last ran. 1271 // Keep track of when we last ran.
1265 this.lastUpdateFlatDataTime_ = getTimeMillis(); 1272 this.lastUpdateMergedDataTime_ = getTimeMillis();
1266 this.updateFlatDataPending_ = false; 1273 this.updateMergedDataPending_ = false;
1267 }.bind(this); 1274 }.bind(this);
1268 1275
1269 this.updateFlatDataPending_ = true; 1276 this.updateMergedDataPending_ = true;
1270 window.setTimeout(functionToRun, timeToWait); 1277 window.setTimeout(functionToRun, timeToWait);
1271 }, 1278 },
1272 1279
1273 /** 1280 /**
1274 * Returns a list of the currently selected snapshots. This list is 1281 * Returns a list of the currently selected snapshots. This list is
1275 * guaranteed to be of length 1 or 2. 1282 * guaranteed to be of length 1 or 2.
1276 */ 1283 */
1277 getSelectedSnapshotIndexes_: function() { 1284 getSelectedSnapshotIndexes_: function() {
1278 var indexes = this.getSelectedSnapshotBoxes_(); 1285 var indexes = this.getSelectedSnapshotBoxes_();
1279 for (var i = 0; i < indexes.length; ++i) 1286 for (var i = 0; i < indexes.length; ++i)
1280 indexes[i] = indexes[i].__index; 1287 indexes[i] = indexes[i].__index;
1281 return indexes; 1288 return indexes;
1282 }, 1289 },
1283 1290
1284 /** 1291 /**
1285 * Same as getSelectedSnapshotIndexes_(), only it returns the actual 1292 * Same as getSelectedSnapshotIndexes_(), only it returns the actual
1286 * checkbox input DOM nodes rather than the snapshot ID. 1293 * checkbox input DOM nodes rather than the snapshot ID.
1287 */ 1294 */
1288 getSelectedSnapshotBoxes_: function() { 1295 getSelectedSnapshotBoxes_: function() {
1289 // Figure out which snaphots to use for our data. 1296 // Figure out which snaphots to use for our data.
1290 var boxes = []; 1297 var boxes = [];
1291 for (var i = 0; i < this.snapshots_.length; ++i) { 1298 for (var i = 0; i < this.snapshots_.length; ++i) {
1292 var box = this.getSnapshotCheckbox_(i); 1299 var box = this.getSnapshotCheckbox_(i);
1293 if (box.checked) 1300 if (box.checked)
1294 boxes.push(box); 1301 boxes.push(box);
1295 } 1302 }
1296 return boxes; 1303 return boxes;
1297 }, 1304 },
1298 1305
1299 /** 1306 updateSnapshotSelectionSummaryDiv_: function() {
1300 * This function should be called any time a snapshot dependency for what is
1301 * being displayed on the screen has changed. It will re-calculate the
1302 * difference between the two snapshots and update flatData_.
jar (doing other things) 2011/12/06 01:54:36 nit: It would be good to update the comment, rathe
eroman 2011/12/06 19:21:25 Done. (I initially omitted the comment since I fe
1303 */
1304 updateFlatData_: function() {
1305 var summaryDiv = $(SNAPSHOT_SELECTION_SUMMARY_ID); 1307 var summaryDiv = $(SNAPSHOT_SELECTION_SUMMARY_ID);
1306 1308
1307 var selectedSnapshots = this.getSelectedSnapshotIndexes_(); 1309 var selectedSnapshots = this.getSelectedSnapshotIndexes_();
1308 if (selectedSnapshots.length == 1) { 1310 if (selectedSnapshots.length == 1) {
1309 // If only one snapshot is chosen then we will display that snapshot's
1310 // data in its entirety.
1311 this.flatData_ = this.snapshots_[selectedSnapshots[0]].flatData;
1312
1313 // Don't bother displaying any text when just 1 snapshot is selected, 1311 // Don't bother displaying any text when just 1 snapshot is selected,
1314 // since it is obvious what this should do. 1312 // since it is obvious what this should do.
1315 summaryDiv.innerText = ''; 1313 summaryDiv.innerText = '';
1316 } else if (selectedSnapshots.length == 2) { 1314 } else if (selectedSnapshots.length == 2) {
1317 // Otherwise if two snapshots were chosen, show the difference between 1315 // Otherwise if two snapshots were chosen, show the difference between
1318 // them. 1316 // them.
1319 var snapshot1 = this.snapshots_[selectedSnapshots[0]]; 1317 var snapshot1 = this.snapshots_[selectedSnapshots[0]];
1320 var snapshot2 = this.snapshots_[selectedSnapshots[1]]; 1318 var snapshot2 = this.snapshots_[selectedSnapshots[1]];
1321 1319
1322 this.flatData_ =
1323 subtractSnapshots(snapshot1.flatData, snapshot2.flatData);
1324
1325 var timeDeltaInSeconds = 1320 var timeDeltaInSeconds =
1326 ((snapshot2.time - snapshot1.time) / 1000).toFixed(0); 1321 ((snapshot2.time - snapshot1.time) / 1000).toFixed(0);
1327 1322
1328 // Explain that what is being shown is the difference between two 1323 // Explain that what is being shown is the difference between two
1329 // snapshots. 1324 // snapshots.
1330 summaryDiv.innerText = 1325 summaryDiv.innerText =
1331 'Showing the difference between snapshots #' + 1326 'Showing the difference between snapshots #' +
1332 selectedSnapshots[0] + ' and #' + 1327 selectedSnapshots[0] + ' and #' +
1333 selectedSnapshots[1] + ' (' + timeDeltaInSeconds + 1328 selectedSnapshots[1] + ' (' + timeDeltaInSeconds +
1334 ' seconds worth of data)'; 1329 ' seconds worth of data)';
1335 } else { 1330 } else {
1336 // This shouldn't be possible... 1331 // This shouldn't be possible...
1337 throw 'Unexpected number of selected snapshots'; 1332 throw 'Unexpected number of selected snapshots';
1338 } 1333 }
1339
1340 // Recompute mergedData_ (since it is derived from flatData_)
1341 this.updateMergedData_();
1342 }, 1334 },
1343 1335
1344 updateMergedData_: function() { 1336 updateMergedData_: function() {
1345 // Recompute mergedData_. 1337 // Retrieve the merge options.
1346 this.mergedData_ = mergeRows(this.flatData_, 1338 var mergeColumns = this.getMergeColumns_();
1347 this.getMergeColumns_(), 1339 var shouldMergeSimilarThreads = this.shouldMergeSimilarThreads_();
1348 this.shouldMergeSimilarThreads_()); 1340
1341 var selectedSnapshots = this.getSelectedSnapshotIndexes_();
1342
1343 // We do merges a bit differently depending if we are displaying the diffs
1344 // between two snapshots, or just displaying a single snapshot.
1345 if (selectedSnapshots.length == 1) {
1346 var snapshot = this.snapshots_[selectedSnapshots[0]];
1347 this.mergedData_ = mergeRows(snapshot.flatData,
1348 mergeColumns,
1349 shouldMergeSimilarThreads,
1350 false);
1351
1352 } else if (selectedSnapshots.length == 2) {
1353 var snapshot1 = this.snapshots_[selectedSnapshots[0]];
1354 var snapshot2 = this.snapshots_[selectedSnapshots[1]];
1355
1356 // Merge the data for snapshot1.
1357 var mergedRows1 = mergeRows(snapshot1.flatData,
1358 mergeColumns,
1359 shouldMergeSimilarThreads,
1360 true);
1361
1362 // Merge the data for snapshot2.
1363 var mergedRows2 = mergeRows(snapshot2.flatData,
1364 mergeColumns,
1365 shouldMergeSimilarThreads,
1366 true);
1367
1368 // Do a diff between the two snapshots.
1369 this.mergedData_ = subtractSnapshots(mergedRows1,
1370 mergedRows2,
1371 mergeColumns);
1372 } else {
1373 throw 'Unexpected number of selected snapshots';
1374 }
1349 1375
1350 // Recompute filteredData_ (since it is derived from mergedData_) 1376 // Recompute filteredData_ (since it is derived from mergedData_)
1351 this.updateFilteredData_(); 1377 this.updateFilteredData_();
1352 }, 1378 },
1353 1379
1354 updateFilteredData_: function() { 1380 updateFilteredData_: function() {
1355 // Recompute filteredData_. 1381 // Recompute filteredData_.
1356 this.filteredData_ = []; 1382 this.filteredData_ = [];
1357 var filterFunc = this.getFilterFunction_(); 1383 var filterFunc = this.getFilterFunction_();
1358 for (var i = 0; i < this.mergedData_.length; ++i) { 1384 for (var i = 0; i < this.mergedData_.length; ++i) {
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
1670 // constants.) 1696 // constants.)
1671 // (2) We "augment" each row by adding some extra computed columns 1697 // (2) We "augment" each row by adding some extra computed columns
1672 // (like averages). 1698 // (like averages).
1673 // (3) The rows are merged using current merge settings. 1699 // (3) The rows are merged using current merge settings.
1674 // (4) The rows that don't match current search expression are 1700 // (4) The rows that don't match current search expression are
1675 // tossed out. 1701 // tossed out.
1676 // (5) The rows are organized into "groups" based on current settings, 1702 // (5) The rows are organized into "groups" based on current settings,
1677 // and aggregate values are computed for each resulting group. 1703 // and aggregate values are computed for each resulting group.
1678 // (6) The rows within each group are sorted using current settings. 1704 // (6) The rows within each group are sorted using current settings.
1679 // (7) The grouped rows are drawn to the screen. 1705 // (7) The grouped rows are drawn to the screen.
1680 this.flatData_ = [];
1681 this.mergedData_ = []; 1706 this.mergedData_ = [];
1682 this.filteredData_ = []; 1707 this.filteredData_ = [];
1683 this.groupedData_ = {}; 1708 this.groupedData_ = {};
1684 this.sortedGroupKeys_ = []; 1709 this.sortedGroupKeys_ = [];
1685 1710
1686 this.groupDisplaySettings_ = {}; 1711 this.groupDisplaySettings_ = {};
1687 1712
1688 this.fillSelectionCheckboxes_($(COLUMN_TOGGLES_CONTAINER_ID)); 1713 this.fillSelectionCheckboxes_($(COLUMN_TOGGLES_CONTAINER_ID));
1689 this.fillMergeCheckboxes_($(COLUMN_MERGE_TOGGLES_CONTAINER_ID)); 1714 this.fillMergeCheckboxes_($(COLUMN_MERGE_TOGGLES_CONTAINER_ID));
1690 1715
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
1786 checked[i].checked = false; 1811 checked[i].checked = false;
1787 checked.length = 2; 1812 checked.length = 2;
1788 } 1813 }
1789 1814
1790 // We should always have at least 1 selection. Prevent the user from 1815 // We should always have at least 1 selection. Prevent the user from
1791 // unselecting the final box. 1816 // unselecting the final box.
1792 if (checked.length == 0) 1817 if (checked.length == 0)
1793 event.target.checked = true; 1818 event.target.checked = true;
1794 1819
1795 this.updateSnapshotCheckboxStyling_(); 1820 this.updateSnapshotCheckboxStyling_();
1821 this.updateSnapshotSelectionSummaryDiv_();
1796 1822
1797 // Recompute flatData_ (since it is derived from selected snapshots). 1823 // Recompute mergedData_ (since it is derived from selected snapshots).
1798 this.updateFlatData_(); 1824 this.updateMergedData_();
1799 }, 1825 },
1800 1826
1801 fillSelectionCheckboxes_: function(parent) { 1827 fillSelectionCheckboxes_: function(parent) {
1802 this.selectionCheckboxes_ = {}; 1828 this.selectionCheckboxes_ = {};
1803 1829
1804 var onChangeFunc = this.onSelectCheckboxChanged_.bind(this); 1830 var onChangeFunc = this.onSelectCheckboxChanged_.bind(this);
1805 1831
1806 for (var i = 0; i < ALL_TABLE_COLUMNS.length; ++i) { 1832 for (var i = 0; i < ALL_TABLE_COLUMNS.length; ++i) {
1807 var key = ALL_TABLE_COLUMNS[i]; 1833 var key = ALL_TABLE_COLUMNS[i];
1808 var checkbox = addLabeledCheckbox(parent, getNameForKey(key)); 1834 var checkbox = addLabeledCheckbox(parent, getNameForKey(key));
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
2053 groupKey.push(entry); 2079 groupKey.push(entry);
2054 } 2080 }
2055 2081
2056 return JSON.stringify(groupKey); 2082 return JSON.stringify(groupKey);
2057 }; 2083 };
2058 }, 2084 },
2059 }; 2085 };
2060 2086
2061 return MainView; 2087 return MainView;
2062 })(); 2088 })();
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698