prefetch cache: do a single http req per backend

This reduces the number of http calls done between the frontend and backends
by fetching all the requested targets in a single http request.

It work as follows:
  - extract all the pathExpressions (metric name/patterns) from the targets
  - fetch all pathExpressions from all backends using a single http request
  - store the result in a properly keyed hash table:
      cache[backend][originalTarget-start-end] = [ series_from_backend]
  - Store that hash table in the requestContext
  - Continue processing as before (via evaluateTarget -> fetchData)
  - In the fetchData method do a hashtable lookup for the requested data.
      If the data is there use the cached data.
      If there is a cache miss, do a regular remote fetch.
    This last case is pretty rare, it happens when functions needs data out
    of the timerange of the original query.
    For example: timeshift, movingAverage, etc.