forked from facebook/react-native
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Pull aggrow from facebookincubator/tracery-prerelease
Reviewed By: bnham Differential Revision: D4250937 fbshipit-source-id: b5f2cfdeb06c04399670e463b8b2498e2fe0074b
- Loading branch information
Showing
20 changed files
with
25,271 additions
and
5 deletions.
There are no files selected for viewing
22,673 changes: 22,673 additions & 0 deletions
22,673
local-cli/server/middleware/heapCapture/bundle.js
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
{ | ||
"name": "jsc-heap-capture", | ||
"version": "1.0.0", | ||
"description": "processes captured heaps from javascript core", | ||
"main": "bundle.js", | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1", | ||
"build": "webpack" | ||
}, | ||
"author": "cwdick", | ||
"devDependencies": { | ||
"babel-core": "^6.17.0", | ||
"babel-loader": "^6.2.5", | ||
"babel-plugin-transform-class-properties": "^6.16.0", | ||
"babel-preset-es2015": "^6.16.0", | ||
"babel-preset-react": "^6.16.0", | ||
"react": "^0.14.1", | ||
"react-dom": "^0.14.1", | ||
"webpack": "^1.13.2" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,190 @@ | ||
// @flow | ||
|
||
import invariant from 'invariant'; | ||
|
||
import AggrowData, { | ||
AggrowDoubleColumn, | ||
AggrowIntColumn, | ||
AggrowStackColumn, | ||
AggrowStringColumn } from './AggrowData'; | ||
import AggrowExpander from './AggrowExpander'; | ||
import type { FlattenedStack } from './StackRegistry'; | ||
import StackRegistry from './StackRegistry'; | ||
|
||
export type FocusConfig = { | ||
pattern: RegExp, | ||
firstMatch: boolean, | ||
leftSide: boolean, | ||
} | ||
type FocusPredicate = (frameId: number) => boolean; | ||
|
||
export default class Aggrow { | ||
data: AggrowData; | ||
expander: AggrowExpander; | ||
|
||
constructor(aggrowData: AggrowData) { | ||
aggrowData.flattenStacks(); | ||
this.data = aggrowData; | ||
this.expander = new AggrowExpander(aggrowData.rowCount); | ||
} | ||
|
||
addSumAggregator(aggregatorName: string, columnName: string): number { | ||
const column = this.data.getColumn(columnName); | ||
|
||
invariant(column, `Column ${columnName} does not exist.`); | ||
invariant(column instanceof AggrowIntColumn || column instanceof AggrowDoubleColumn, | ||
`Sum aggregator does not support ${column.constructor.name} columns!`); | ||
return this.expander.addAggregator( | ||
aggregatorName, | ||
(indices: Int32Array): number => { | ||
let size = 0; | ||
indices.forEach((i: number) => { size += column.get(i); }); | ||
return size; | ||
}, | ||
(value: any): string => value.toLocaleString(), | ||
(a: number, b: number): number => b - a, | ||
); | ||
} | ||
|
||
addCountAggregator(aggregatorName: string): number { | ||
return this.expander.addAggregator( | ||
aggregatorName, | ||
(indices: Int32Array): number => indices.length, | ||
(value: any): string => value.toLocaleString(), | ||
(a: number, b: number): number => b - a, | ||
); | ||
} | ||
|
||
addStringExpander(expanderName: string, columnName: string): number { | ||
const column = this.data.getColumn(columnName); | ||
invariant(column, `Column ${columnName} does not exist.`); | ||
invariant(column instanceof AggrowStringColumn, 'String expander needs a string column.'); | ||
const strings = column.strings; | ||
return this.expander.addFieldExpander( | ||
expanderName, | ||
(rowA: number, rowB: number): number => column.get(rowA) - column.get(rowB), | ||
(row: number): string => strings.get(column.get(row)), | ||
(s: string): string => s, | ||
); | ||
} | ||
|
||
addNumberExpander(expanderName: string, columnName: string): number { | ||
const column = this.data.getColumn(columnName); | ||
invariant(column, `Column ${columnName} does not exist.`); | ||
invariant( | ||
column instanceof AggrowIntColumn || column instanceof AggrowDoubleColumn, | ||
`Number expander does not support ${column.constructor.name} columns.`); | ||
return this.expander.addFieldExpander( | ||
expanderName, | ||
(rowA: number, rowB: number): number => column.get(rowA) - column.get(rowB), | ||
(row: number): number => column.get(row), | ||
(n: any): string => n.toLocaleString(), | ||
); | ||
} | ||
|
||
addPointerExpander(expanderName: string, columnName: string): number { | ||
const column = this.data.getColumn(columnName); | ||
invariant(column, `Column ${columnName} does not exist.`); | ||
invariant( | ||
column instanceof AggrowIntColumn, | ||
`Pointer expander does not support ${column.constructor.name} columns.`); | ||
return this.expander.addFieldExpander( | ||
expanderName, | ||
(rowA: number, rowB: number): number => column.get(rowA) - column.get(rowB), | ||
(row: number): number => column.get(row), | ||
(p: number): string => `0x${(p >>> 0).toString(16)}`, // eslint-disable-line no-bitwise | ||
); | ||
} | ||
|
||
addStackExpander( | ||
expanderName: string, | ||
columnName: string, | ||
reverse: boolean, | ||
focus: ?FocusConfig): number { | ||
const column = this.data.getColumn(columnName); | ||
invariant(column, `Column ${columnName} does not exist.`); | ||
invariant( | ||
column instanceof AggrowStackColumn, | ||
`Stack expander does not support ${column.constructor.name} columns.`); | ||
let stacks = column.stacks; | ||
const getter = column.getter; | ||
const formatter = column.formatter; | ||
if (focus) { | ||
const re = focus.pattern; | ||
const predicate = (frameId: number): boolean => re.test(formatter(getter(frameId))); | ||
stacks = focusStacks(stacks, predicate, focus.firstMatch, focus.leftSide); | ||
} | ||
return this.expander.addStackExpander( | ||
expanderName, | ||
stacks.maxDepth, | ||
(row: number): FlattenedStack => stacks.get(column.get(row)), | ||
getter, | ||
formatter, | ||
!!reverse, | ||
); | ||
} | ||
} | ||
|
||
function focusStacks( | ||
stacks: StackRegistry, | ||
predicate: FocusPredicate, | ||
firstMatch: boolean, | ||
leftSide: boolean): FocusedStackRegistry { | ||
let stackMapper; | ||
if (firstMatch && leftSide) { | ||
stackMapper = (stack: FlattenedStack): FlattenedStack => { | ||
for (let i = 0; i < stack.length; i++) { | ||
if (predicate(stack[i])) { | ||
return stack.subarray(0, i + 1); | ||
} | ||
} | ||
return stack.subarray(0, 0); | ||
}; | ||
} else if (firstMatch && !leftSide) { | ||
stackMapper = (stack: FlattenedStack): FlattenedStack => { | ||
for (let i = 0; i < stack.length; i++) { | ||
if (predicate(stack[i])) { | ||
return stack.subarray(i, stack.length); | ||
} | ||
} | ||
return stack.subarray(0, 0); | ||
}; | ||
} else if (!firstMatch && leftSide) { | ||
stackMapper = (stack: FlattenedStack): FlattenedStack => { | ||
for (let i = stack.length - 1; i >= 0; i--) { | ||
if (predicate(stack[i])) { | ||
return stack.subarray(0, i + 1); | ||
} | ||
} | ||
return stack.subarray(0, 0); | ||
}; | ||
} else { // !firstMatch && !leftSide | ||
stackMapper = (stack: FlattenedStack): FlattenedStack => { | ||
for (let i = stack.length - 1; i >= 0; i--) { | ||
if (predicate(stack[i])) { | ||
return stack.subarray(i, stack.length); | ||
} | ||
} | ||
return stack.subarray(0, 0); | ||
}; | ||
} | ||
|
||
invariant(stacks.stackIdMap, 'Stacks were not flattened.'); | ||
return new FocusedStackRegistry( | ||
stacks.stackIdMap.map(stackMapper), | ||
stacks.maxDepth); | ||
} | ||
|
||
class FocusedStackRegistry { | ||
maxDepth: number; | ||
stackIdMap: Array<FlattenedStack>; | ||
|
||
constructor(stackIdMap: Array<FlattenedStack>, maxDepth: number) { | ||
this.maxDepth = maxDepth; | ||
this.stackIdMap = stackIdMap; | ||
} | ||
|
||
get(id: number): FlattenedStack { | ||
return this.stackIdMap[id]; | ||
} | ||
} |
Oops, something went wrong.