(WIP) SPARK-2045 Sort-based shuffle

This adds a new ShuffleManager based on sorting, as described in https://issues.apache.org/jira/browse/SPARK-2045. The bulk of the code is in an ExternalSorter class that is similar to ExternalAppendOnlyMap, but sorts key-value pairs by partition ID and can be used to create a single sorted file with a map task's output. (Longer-term I think this can take on the remaining functionality in ExternalAppendOnlyMap and replace it so we don't have code duplication.)

The main TODOs still left are:
- [x] enabling ExternalSorter to merge across spilled files
- [x] adding more tests (e.g. a version of our shuffle suite that runs on this)
- [ ] rebasing on top of the size-tracking refactoring in #1165 when that is merged

Despite this though, this seems to work pretty well (running successfully in cases where the hash shuffle would OOM, such as 1000 reduce tasks on executors with only 1G memory), and it seems to be comparable in speed or faster than hash-based shuffle (it will create much fewer files for the OS to keep track of). So I'm posting it to get some early feedback.

After these TODOs are done, I'd also like to enable ExternalSorter to sort data within each partition by a key as well, which will allow us to use it to implement external spilling in reduce tasks in `sortByKey`.
I just copied this from ExternalAppendOnlyMap, but it's true that it's probably wrong. I guess the reason it was there is that there's a big non-linear jump in size when the collection doubles. However, with the current code, we may not notice if the values are really large. It's probably better to use estimateSize and leave enough buffer space that doubling just the array won't be a problem.