/*
 * Copyright 2009-2010 by The Regents of the University of California
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * you may obtain a copy of the License from
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package edu.uci.ics.hyracks.control.cc.dataset;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import edu.uci.ics.hyracks.api.comm.NetworkAddress;
import edu.uci.ics.hyracks.api.dataset.IDatasetDirectoryService;
import edu.uci.ics.hyracks.api.dataset.ResultSetId;
import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
import edu.uci.ics.hyracks.api.job.JobId;

/**
 * TODO: The potential perils of this global dataset directory service implementation is that, the jobs location information
 * is never evicted from the memory and the memory usage grows as the number of jobs in the system grows. What we should
 * possibly do is, add an API call for the client to say that it received everything it has to for the job (after it receives
 * all the results) completely. Then we can just get rid of the location information for that job.
 */
public class DatasetDirectoryService implements IDatasetDirectoryService {
    private final Map<JobId, Map<ResultSetId, DatasetDirectoryRecord[]>> jobResultLocationsMap;

    public DatasetDirectoryService() {
        jobResultLocationsMap = new HashMap<JobId, Map<ResultSetId, DatasetDirectoryRecord[]>>();
    }

    @Override
    public synchronized void registerResultPartitionLocation(JobId jobId, ResultSetId rsId, int partition,
            int nPartitions, NetworkAddress networkAddress) {
        Map<ResultSetId, DatasetDirectoryRecord[]> resultSetsMap = jobResultLocationsMap.get(jobId);
        if (resultSetsMap == null) {
            resultSetsMap = new HashMap<ResultSetId, DatasetDirectoryRecord[]>();
            jobResultLocationsMap.put(jobId, resultSetsMap);
        }

        DatasetDirectoryRecord[] records = resultSetsMap.get(rsId);
        if (records == null) {
            records = new DatasetDirectoryRecord[nPartitions];
            resultSetsMap.put(rsId, records);
        }

        if (records[partition] == null) {
            records[partition] = new DatasetDirectoryRecord();
        }
        records[partition].setNetworkAddress(networkAddress);
        notifyAll();
    }

    @Override
    public synchronized DatasetDirectoryRecord[] getResultPartitionLocations(JobId jobId, ResultSetId rsId,
            DatasetDirectoryRecord[] knownRecords) throws HyracksDataException {
        while (!newRecords(jobId, rsId, knownRecords)) {
            try {
                wait();
            } catch (InterruptedException e) {
                throw new HyracksDataException(e);
            }
        }
        return jobResultLocationsMap.get(jobId).get(rsId);
    }

    private boolean newRecords(JobId jobId, ResultSetId rsId, DatasetDirectoryRecord[] knownRecords) {
        Map<ResultSetId, DatasetDirectoryRecord[]> rsMap = jobResultLocationsMap.get(jobId);
        if (rsMap == null) {
            return false;
        }
        DatasetDirectoryRecord[] records = rsMap.get(rsId);
        return !Arrays.equals(records, knownRecords);
    }
}
@@ -804,16 +804,79 @@
 ddress;%0A
+import edu.uci.ics.hyracks.api.dataset.DatasetDirectoryRecord;%0A
 import e
@@ -932,16 +932,16 @@
 ervice;%0A
-
 import e
@@ -1102,16 +1102,30 @@
 %0A * TODO
+(madhusudancs)
 : The po
@@ -1212,16 +1212,19 @@
 the jobs
+%0A *
  locatio
@@ -1236,19 +1236,16 @@
 ormation
-%0A *
  is neve
@@ -1332,16 +1332,19 @@
 e system
+%0A *
  grows. 
@@ -1357,19 +1357,16 @@
 e should
-%0A *
  possibl
@@ -1449,24 +1449,27 @@
 t has to for
+%0A *
  the job (af
@@ -1483,19 +1483,16 @@
 receives
-%0A *
  all the
@@ -1574,16 +1574,19 @@
 for that
+%0A *
  job.%0A *

Fix a formatting issue with the comment.