blob: 1efca4403f769ee565485068910d1a2dfeea1ded [file] [log] [blame]
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:math';
/// Decodes [input] in a chunked way and yields to the event loop
/// as soon as [maxMicroseconds] have elapsed.
Future<dynamic> decodeJsonChunked(String input, int maxMicroseconds) {
const chunkCount = 100; // Actually one more.
var result;
var outSink = new ChunkedConversionSink.withCallback((x) {
result = x[0];
});
var inSink = JSON.decoder.startChunkedConversion(outSink);
var chunkSize = input.length ~/ chunkCount;
int i = 0;
Future<dynamic> addChunks() {
var sw = new Stopwatch()..start();
while (i < 100) {
inSink.addSlice(input, i * chunkSize, (i + 1) * chunkSize, false);
i++;
if (sw.elapsedMicroseconds > maxMicroseconds) {
// Usually one has to pay attention not to chain too many futures,
// but here we know that there are at most chunkCount linked futures.
return new Future(addChunks);
}
}
inSink.addSlice(input, i * chunkSize, input.length, true);
return new Future.value(result);
}
return addChunks();
}
main() {
var input = new File("big.json").readAsStringSync();
var sw = new Stopwatch()..start();
bool done = false;
// Show that the event-loop is free to do something:
new Timer.periodic(const Duration(milliseconds: 2), (timer) {
print(".");
if (done) timer.cancel();
});
var future = decodeJsonChunked(input, 500);
future.then((result) {
print("done after ${sw.elapsedMicroseconds}us.");
done = true;
});
}