org.eclipse.osee.executor.admin.WorkUtility.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.osee.executor.admin.WorkUtility.java

Source

/*******************************************************************************
 * Copyright (c) 2011 Boeing.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Boeing - initial API and implementation
 *******************************************************************************/
package org.eclipse.osee.executor.admin;

import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import org.eclipse.osee.executor.admin.internal.ExecutorAdminImpl;
import com.google.common.collect.Iterables;

/**
 * @author Roberto E. Escobar
 */
public final class WorkUtility {

    private static final int NUM_PARTITIONS = Math.min(4, Runtime.getRuntime().availableProcessors());

    private WorkUtility() {
        // Utility Class
    }

    public static interface PartitionFactory<INPUT, OUTPUT> {

        Callable<Collection<OUTPUT>> createWorker(Collection<INPUT> toProcess);

    }

    public static <INPUT, OUTPUT> List<Callable<Collection<OUTPUT>>> partitionWork(Iterable<INPUT> work,
            PartitionFactory<INPUT, OUTPUT> factory) throws Exception {
        List<Callable<Collection<OUTPUT>>> callables = new LinkedList<Callable<Collection<OUTPUT>>>();
        int size = Iterables.size(work);
        if (size > 0) {
            int partitionSize = Math.max(1, size / NUM_PARTITIONS);

            List<INPUT> subList = new LinkedList<INPUT>();

            int index = 0;

            Iterator<INPUT> iterator = work.iterator();
            while (iterator.hasNext()) {
                subList.add(iterator.next());

                if (index != 0 && partitionSize != 0 && (index % partitionSize == 0)) {
                    Callable<Collection<OUTPUT>> worker = factory.createWorker(subList);
                    callables.add(worker);
                    subList = new LinkedList<INPUT>();
                }
                index++;
            }
            // Anything left over ?
            if (!subList.isEmpty()) {
                Callable<Collection<OUTPUT>> worker = factory.createWorker(subList);
                callables.add(worker);
            }
        }
        return callables;
    }

    public static <INPUT, OUTPUT> List<Future<Collection<OUTPUT>>> partitionAndScheduleWork(
            ExecutorAdmin executorAdmin, PartitionFactory<INPUT, OUTPUT> factory, Iterable<INPUT> items)
            throws Exception {
        return partitionAndScheduleWork(executorAdmin, ExecutorAdminImpl.DEFAULT_EXECUTOR, factory, items, null);
    }

    public static <INPUT, OUTPUT> List<Future<Collection<OUTPUT>>> partitionAndScheduleWork(
            ExecutorAdmin executorAdmin, PartitionFactory<INPUT, OUTPUT> factory, Iterable<INPUT> items,
            ExecutionCallback<Collection<OUTPUT>> callback) throws Exception {
        return partitionAndScheduleWork(executorAdmin, ExecutorAdminImpl.DEFAULT_EXECUTOR, factory, items,
                callback);
    }

    public static <INPUT, OUTPUT> List<Future<Collection<OUTPUT>>> partitionAndScheduleWork(
            ExecutorAdmin executorAdmin, String executorId, PartitionFactory<INPUT, OUTPUT> factory,
            Iterable<INPUT> items) throws Exception {
        return partitionAndScheduleWork(executorAdmin, executorId, factory, items, null);
    }

    public static <INPUT, OUTPUT> List<Future<Collection<OUTPUT>>> partitionAndScheduleWork(
            ExecutorAdmin executorAdmin, String executorId, PartitionFactory<INPUT, OUTPUT> factory,
            Iterable<INPUT> items, ExecutionCallback<Collection<OUTPUT>> callback) throws Exception {
        List<Future<Collection<OUTPUT>>> futures = new LinkedList<Future<Collection<OUTPUT>>>();
        List<Callable<Collection<OUTPUT>>> callables = partitionWork(items, factory);
        if (!callables.isEmpty()) {
            for (Callable<Collection<OUTPUT>> callable : callables) {
                Future<Collection<OUTPUT>> future = executorAdmin.schedule(executorId, callable, callback);
                futures.add(future);
            }
        }
        return futures;
    }
}