simplify the implementation of CoarseGrainedSchedulerBackend

There are 5 main data structures in the class, after reading the source code, I found that some of them are actually not used, some of them are not necessary

This PR also fix a bug. When the executor is removed, the original implementation will add the totalcores with freeCores(executorId)...actually, we should add totalCores with the total number of the cores of the executor

* executorAddress

⋅⋅⋅It is actually not used, just add when registering executor and remove when executor was removed

* executorHost

⋅⋅⋅ It is added when register the executor and removed when the executor was removed. It is also used for building WorkerOffer

* WorkerOffer class

⋅⋅⋅ the original implementation build a new WorkerOffer object at every ReviveOffer moment, just because of the change of freeCores

* freeCores

⋅⋅⋅ It is used for building WorkerOffer, we construct a WorkerOffer from the values in freeCores for every execution of ReviveOffer

My proposal:

we can change the cores in WorkerOffer from val to var, keep track the change of that. In this way, we can remove most of data structures and replace them with a HashMap; 

```
workerOffers = new HashMap[String, WorkerOffer]
```