1. I'd replace the array of longs with explicit fields.
Owen, is this to avoid the array indexing? I kept it this way since the TaskCounter enum already existed, and it seemed simple to have a one-to-one mapping from the enum to the array. Also, in the future if we add another element to the TaskCounter enum, we don't have to explicitly modify TaskMetrics since it would automatically handle that..
2. I'd drop the booleans for whether it has been used.
I kept this so as to retain the existing semantics where an unused counter is not displayed to the user (for e.g., reduce-shuffle-bytes is not displayed as part of map tasks' counters). But I am okay to do without the booleans..
3. The serialization should just be to write the fields in order using vints.
If we remove the booleans, then it will be just writing the long array elements which is already written as vlongs... If we decide to switch to explicit fields for the longs then this part would change slightly..
4. updateFrameworkCounters should just update the counters by using the enum values explicitly.
Again, as i pointed out in (1) above, it helps to iterate over TaskCounter enum.
5. updateFrameworkCounters should set, not increment the related counter.
6. TaskMetrics should be a field in the TaskStatus.
It already is. A little bit of cleanup may be required w.r.t passing the object around in the TaskStatus methods..