| Index: pkg/analysis_server/test/performance/input_converter.dart
|
| diff --git a/pkg/analysis_server/test/performance/input_converter.dart b/pkg/analysis_server/test/performance/input_converter.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..d2167fb140e2aa0d5cb62e71cc2f07b66efc255d
|
| --- /dev/null
|
| +++ b/pkg/analysis_server/test/performance/input_converter.dart
|
| @@ -0,0 +1,115 @@
|
| +library input.transformer;
|
| +
|
| +import 'dart:convert';
|
| +
|
| +import 'instrumentation_input_converter.dart';
|
| +import 'operation.dart';
|
| +
|
| +final int NINE = '9'.codeUnitAt(0);
|
| +final int ZERO = '0'.codeUnitAt(0);
|
| +
|
| +/**
|
| + * [InputConverter] converts an input stream
|
| + * into a series of operations to be sent to the analysis server.
|
| + * The input stream can be either an instrumenation or log file.
|
| + */
|
| +class InputConverter extends Converter<String, Operation> {
|
| +
|
| + /**
|
| + * The number of lines read before the underlying converter was determined
|
| + * or the end of file was reached.
|
| + */
|
| + int headerLineCount = 0;
|
| +
|
| + /**
|
| + * The underlying converter used to translate lines into operations
|
| + * or `null` if it has not yet been determined.
|
| + */
|
| + Converter<String, Operation> converter;
|
| +
|
| + @override
|
| + Operation convert(String line) {
|
| + if (converter != null) {
|
| + return converter.convert(line);
|
| + }
|
| + if (headerLineCount == 20) {
|
| + throw 'Failed to determine input file format';
|
| + }
|
| + if (InstrumentationInputConverter.isFormat(line)) {
|
| + converter = new InstrumentationInputConverter();
|
| + } else if (LogFileInputConverter.isFormat(line)) {
|
| + converter = new LogFileInputConverter();
|
| + }
|
| + if (converter != null) {
|
| + return converter.convert(line);
|
| + }
|
| + print(line);
|
| + return null;
|
| + }
|
| +
|
| + @override
|
| + _InputSink startChunkedConversion(outSink) {
|
| + return new _InputSink(this, outSink);
|
| + }
|
| +}
|
| +
|
| +/**
|
| + * [LogFileInputConverter] converts a log file stream
|
| + * into a series of operations to be sent to the analysis server.
|
| + */
|
| +class LogFileInputConverter extends Converter<String, Operation> {
|
| + @override
|
| + Operation convert(String line) {
|
| + throw 'not implemented yet';
|
| + }
|
| +
|
| + /**
|
| + * Determine if the given line is from an instrumentation file.
|
| + * For example:
|
| + * `1428347977499 <= {"event":"server.connected","params":{"version":"1.6.0"}}`
|
| + */
|
| + static bool isFormat(String line) {
|
| + String timeStampString = _parseTimeStamp(line);
|
| + int start = timeStampString.length;
|
| + int end = start + 5;
|
| + return start > 10 &&
|
| + line.length > end &&
|
| + line.substring(start, end) == ' <= {"event":"server.connected"';
|
| + }
|
| +
|
| + /**
|
| + * Parse the given line and return the millisecond timestamp or `null`
|
| + * if it cannot be determined.
|
| + */
|
| + static String _parseTimeStamp(String line) {
|
| + int index = 0;
|
| + while (index < line.length) {
|
| + int code = line.codeUnitAt(index);
|
| + if (code < ZERO || NINE < code) {
|
| + return line.substring(0, index);
|
| + }
|
| + ++index;
|
| + }
|
| + return line;
|
| + }
|
| +}
|
| +
|
| +class _InputSink extends ChunkedConversionSink<String> {
|
| + final Converter<String, Operation> converter;
|
| + final outSink;
|
| +
|
| + _InputSink(this.converter, this.outSink);
|
| +
|
| + @override
|
| + void add(String line) {
|
| + Operation op = converter.convert(line);
|
| + if (op != null) {
|
| + outSink.add(op);
|
| + }
|
| + }
|
| +
|
| + @override
|
| + void close() {
|
| + outSink.close();
|
| + }
|
| +}
|
|
|