/*
 * Java Genetic Algorithm Library (@!identifier!@).
 * Copyright (c) @!year!@ Franz Wilhelmstötter
 *  
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Author:
 *     Franz Wilhelmstötter (franz.wilhelmstoetter@gmx.at)
 *     
 */
package org.jenetics.util;

import java.util.List;
import java.util.RandomAccess;

import jsr166y.ForkJoinPool;
import jsr166y.RecursiveAction;

/**
 * @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
 * @version $Id: ForkJoinEvaluator.java,v 1.2 2010-01-12 15:17:30 fwilhelm Exp $
 */
public class ForkJoinEvaluator implements Evaluator {
	private static final int DEFAULT_TASK_SIZE = 5;
	
	private final int _numberOfThreads;
	private final int _taskSize;
	private final ForkJoinPool _pool;
	
	/**
	 * Create a threaded evaluator object where the number of concurrent threads
	 * is equal to the number of available cores.
	 * 
	 * @param pool the executor service (thread pool).
	 * @throws NullPointerException if the given thread pool is {@code null}.
	 */
	public ForkJoinEvaluator(final ForkJoinPool pool) {
		this(pool, Runtime.getRuntime().availableProcessors());
	}
	
	/**
	 * Create a concurrent evaluator object with the given number of concurrent
	 * threads.
	 * 
	 * @param numberOfThreads the number of concurrent threads.
	 * @param pool the executor service (thread pool).
	 * @throws NullPointerException if the given thread pool is {@code null}.
	 */
	public ForkJoinEvaluator(final ForkJoinPool pool, final int numberOfThreads) {
		this(pool, numberOfThreads, DEFAULT_TASK_SIZE);
	}
	
	public ForkJoinEvaluator(final ForkJoinPool pool, final int numberOfThreads, final int taskSize) {
		Validator.notNull(pool, "Thread pool");
		
		_numberOfThreads = Math.max(numberOfThreads, 1);
		_pool = pool;
		_taskSize = taskSize;
	}
	
	@Override
	public void evaluate(final List<? extends Runnable> runnables) {
		Validator.notNull(runnables, "Runnables");
		_pool.invoke(new EvaluatorTask(runnables, 0, runnables.size(), _taskSize));
	}

	@Override
	public int getParallelTasks() {
		return _numberOfThreads;
	}
	
	
	private static class EvaluatorTask extends RecursiveAction {
		private static final long serialVersionUID = -7886596400215187705L;
		
		private final List<? extends Runnable> _runnables;
		private final int _from;
		private final int _to;
		private final int _taskSize;
		
		EvaluatorTask(
			final List<? extends Runnable> runnables, 
			final int from, 
			final int to, 
			final int taskSize
		) {
			assert (runnables != null);
			_runnables = runnables;
			_from = from;
			_to = to;
			_taskSize = taskSize;
		}
		
		
		private void exec(final int from, final int to) {
			if (_runnables instanceof RandomAccess) {
				for (int i = _from; i < _to; ++i) {
					_runnables.get(i).run();
				}
			} else {
				for (Runnable runnable : _runnables.subList(_from, _to)) {
					runnable.run();
				}
			}
		}
		
		@Override
		protected void compute() {
			if (_to - _from <= _taskSize) {
				exec(_from, _to);
			} else {
				final int mid = (_from + _to) >>> 1;
				invokeAll(
						new EvaluatorTask(_runnables, _from, mid, _taskSize), 
						new EvaluatorTask(_runnables, mid, _to, _taskSize)
					);
			}
		}
		
	}

}

@@ -1199,17 +1199,17 @@
 ava,v 1.
-2
+3
  2010-01
@@ -1219,13 +1219,13 @@
  15:
-17:30
+58:26
  fwi
@@ -1349,45 +1349,8 @@
 ;%0A%09%0A
-%09private final int _numberOfThreads;%0A
 %09pri
@@ -1748,461 +1748,8 @@
 ool,
- Runtime.getRuntime().availableProcessors());%0A%09%7D%0A%09%0A%09/**%0A%09 * Create a concurrent evaluator object with the given number of concurrent%0A%09 * threads.%0A%09 * %0A%09 * @param numberOfThreads the number of concurrent threads.%0A%09 * @param pool the executor service (thread pool).%0A%09 * @throws NullPointerException if the given thread pool is %7B@code null%7D.%0A%09 */%0A%09public ForkJoinEvaluator(final ForkJoinPool pool, final int numberOfThreads) %7B%0A%09%09this(pool, numberOfThreads,
  DEF
@@ -1824,35 +1824,8 @@
 ool,
- final int numberOfThreads,
  fin
@@ -1892,59 +1892,8 @@
 %0A%09%09%0A
-%09%09_numberOfThreads = Math.max(numberOfThreads, 1);%0A
 %09%09_p
@@ -2195,23 +2195,29 @@
 rn _
-numberOfThreads
+pool.getParallelism()
 ;%0A%09%7D

Remove _numberOfTasks field. Makes no sense in ForkJoinEvaluator.