Update instruments import to use integeruniquer.index file (#64)

I knew early on that `integeruniquer.index` could be used to index into `integeruniquer.data`, but I initially thought it was an optimization rather than a necessity. It seems like if there's data past the 1MB threshold in `integeruniquer.data`, then `integeruniquer.index` is actually quite useful.

The file seems to contain `[byte offset, MB offset]` pairs encoded as two 32 bit unsigned little endian integers. Using that to decode the integer arrays encoded in `integeruniquer.data` allows the file in #63 to load.

Fixes #63
This commit is contained in:
Jamie Wong
2018-06-20 00:51:22 -07:00
committed by GitHub
parent 7846cce806
commit aaac0ad7e3
3 changed files with 48 additions and 16 deletions
+28 -9
View File
@@ -264,6 +264,9 @@ class BinReader {
hasMore() {
return this.bytePos < this.view.byteLength
}
bytesLeft() {
return this.view.byteLength - this.bytePos
}
readUint8() {
this.bytePos++
if (this.bytePos > this.view.byteLength) return 0
@@ -344,10 +347,11 @@ async function getRawSampleList(core: TraceDirectoryTree): Promise<Sample[]> {
async function getIntegerArrays(samples: Sample[], core: TraceDirectoryTree): Promise<number[][]> {
const uniquing = getOrThrow(core.subdirectories, 'uniquing')
const arrayUniquer = getOrThrow(uniquing.subdirectories, 'arrayUniquer')
const integeruniquer = getOrThrow(arrayUniquer.files, 'integeruniquer.data')
const reader = new BinReader(await readAsArrayBuffer(integeruniquer))
const integeruniquerindex = getOrThrow(arrayUniquer.files, 'integeruniquer.index')
const integeruniquerdata = getOrThrow(arrayUniquer.files, 'integeruniquer.data')
let arrays: number[][] = []
// integeruniquer.index is a binary file containing an array of [byte offset, MB offset] pairs
// that indicate where array data starts in the .data file
// integeruniquer.data is a binary file containing an array of arrays of 64 bit integer.
// The schema is a 32 byte header followed by a stream of arrays.
@@ -355,14 +359,30 @@ async function getIntegerArrays(samples: Sample[], core: TraceDirectoryTree): Pr
// This table contains the memory addresses of stack frames
// Header we don't care about
reader.seek(32)
const indexreader = new BinReader(await readAsArrayBuffer(integeruniquerindex))
const datareader = new BinReader(await readAsArrayBuffer(integeruniquerdata))
while (reader.hasMore()) {
let length = reader.readUint32()
// Header we don't care about
indexreader.seek(32)
let arrays: number[][] = []
while (indexreader.hasMore()) {
const byteOffset = indexreader.readUint32() + indexreader.readUint32() * (1024 * 1024)
if (byteOffset === 0) {
// The first entry in the index table seems to just indicate the offset of
// the header into the data file
continue
}
datareader.seek(byteOffset)
let length = datareader.readUint32()
let array: number[] = []
while (length--) {
array.push(reader.readUint64())
array.push(datareader.readUint64())
}
arrays.push(array)
}
@@ -453,7 +473,6 @@ export async function importFromInstrumentsTrace(
const core = getCoreDirForRun(tree, selectedRun)
let samples = await getRawSampleList(core)
const arrays = await getIntegerArrays(samples, core)
const backtraceIDtoStack = new Map<number, FrameInfo[]>()
const profile = new StackListProfileBuilder(lastOf(samples)!.timestamp)
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<ufwb version="1.17">
<grammar name="Integer Uniquer Data" start="id:165" author="Jamie Wong">
<grammar name="Integer Uniquer Data" start="id:1" author="Jamie Wong">
<description>Grammar for my file format</description>
<structure name="Root" id="165" encoding="ISO_8859-1:1987" endian="little" signed="no">
<binary name="Header" id="166" length="32"/>
<structure name="Array" id="167" repeatmax="-1">
<number name="Size" id="168" fillcolor="CEFFD2" type="integer" length="4"/>
<structure name="Data" id="169" repeatmin="Size" repeatmax="Size">
<number name="Value" id="170" type="integer" length="8"/>
<structure name="Root" id="1" encoding="ISO_8859-1:1987" endian="little" signed="no">
<binary name="integeruniquer.data file" id="2" length="32"/>
<structure name="Array" id="3" repeatmax="-1">
<number name="Size" id="4" fillcolor="CEFFD2" type="integer" length="4"/>
<structure name="Data" id="5" repeatmin="Size" repeatmax="Size">
<number name="Value" id="6" type="integer" length="8"/>
</structure>
</structure>
</structure>
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<ufwb version="1.17">
<grammar name="INDEX grammar" start="id:10" author="Jamie Wong" fileextension="index">
<description>Grammar for INDEX files</description>
<structure name="integeruniquer.index file" id="10" encoding="ISO_8859-1:1987" endian="big" signed="no">
<binary name="Header" id="12" length="32"/>
<structure name="Entry" id="16" length="8" repeatmax="-1">
<number name="ByteOffset" id="15" type="integer" length="4" endian="little"/>
<number name="MegabyteOffset" id="18" type="integer" length="4" endian="little"/>
</structure>
</structure>
</grammar>
</ufwb>