Dynamic chunk sizing

Introducing `Doxport\Util\Chunk`:

The contract is:
 - The caller provides an initial estimate of the chunk size
 - The caller provides a *target* (wallclock) time, each chunk should take about this long to perform
 - The critical/timed section is wrapped in `begin()`/`end()` calls
 
Given this, `getEstimatedSize()` will return a suitable exponentially-weighted moving average of the size of chunk to attempt. The size estimate will vary to try and keep the time taken within the critical section to the target.
These defaults could be constants with a bit of a description why you've chosen them (why they are logical defaults).