<commit_before>package brooklyn.util.task;

import java.util.concurrent.Callable
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import java.util.concurrent.Future
import java.util.concurrent.FutureTask

import brooklyn.management.ExecutionManager
import brooklyn.management.Task


public class BasicExecutionManager implements ExecutionManager {
	
	private static final perThreadCurrentTask = new ThreadLocal<Task>()
	public static Task getCurrentTask() { return perThreadCurrentTask.get() }
	
	private ExecutorService runner = Executors.newCachedThreadPool() 
	
	private Set<Task> knownTasks = new LinkedHashSet()
	private Map<Object,Set<Task>> tasksByTag = new LinkedHashMap()
	//access to the above is synchronized in code in this class, to allow us to preserve order while guaranteeing thread-safe
	//(but more testing is needed before we are sure it is thread-safe!)
	//synch blocks are as finely grained as possible for efficiency
	
	public Set<Task> getTasksWithTag(Object tag) {
		Set<Task> tasksWithTag;
		synchronized (tasksByTag) {
			tasksWithTag = tasksByTag.get(tag)
		}
		if (tasksWithTag==null) return Collections.emptySet()
		synchronized (tasksWithTag) {
			return new LinkedHashSet(tasksWithTag)
		} 
	}
	public Set<Task> getTasksWithAnyTag(Iterable tags) {
		Set result = []
		tags.each { tag -> result.addAll( getTasksWithTag(tag) ) }
		result
	}
	public Set<Task> getTasksWithAllTags(Iterable tags) {
		//NB: for this method retrieval for multiple tags could be made (much) more efficient (if/when it is used with multiple tags!)<commit_msg>rewrote the lazy static initialisation to be correct/safe (well, replaced the double locking with an initialisation on demand holder, which is better for lazy static initialisation)<commit_after>package brooklyn.util.task;

import java.util.concurrent.Callable
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import java.util.concurrent.Future
import java.util.concurrent.FutureTask

import brooklyn.management.ExecutionManager
import brooklyn.management.Task


public class BasicExecutionManager implements ExecutionManager {
	
	private static class PerThreadCurrentTaskHolder {
		public static final perThreadCurrentTask = new ThreadLocal<Task>();
	}
	public static ThreadLocal<Task> getPerThreadCurrentTask() {
		return PerThreadCurrentTaskHolder.perThreadCurrentTask;
	}
	
	public static Task getCurrentTask() { return getPerThreadCurrentTask().get() }
	
	private ExecutorService runner = Executors.newCachedThreadPool() 
	
	private Set<Task> knownTasks = new LinkedHashSet()
	private Map<Object,Set<Task>> tasksByTag = new LinkedHashMap()
	//access to the above is synchronized in code in this class, to allow us to preserve order while guaranteeing thread-safe
	//(but more testing is needed before we are sure it is thread-safe!)
	//synch blocks are as finely grained as possible for efficiency
	
	public Set<Task> getTasksWithTag(Object tag) {
		Set<Task> tasksWithTag;
		synchronized (tasksByTag) {
			tasksWithTag = tasksByTag.get(tag)
		}
		if (tasksWithTag==null) return Collections.emptySet()
		synchronized (tasksWithTag) {
			return new LinkedHashSet(tasksWithTag)
		} 
	}
	public Set<Task> getTasksWithAnyTag(Iterable tags) {
		Set result = []
		tags.each { tag -> result.addAll( getTasksWithTag(tag) ) }
		result
	}
	public Set<Task> getTasksWithAllTags(Iterable tags) {
		//NB: for this method retrieval for multiple tags could be made (much) more efficient (if/when it is used with multiple tags!)
{'fraction_non_alphanumeric': 0.07835400225479143, 'fraction_numerical': 0.0, 'mean_word_length': 5.2592592592592595, 'pattern_counts': {'":': 0, '<': 20, '<?xml version=': 0, '>': 22, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1218670', 'n_tokens_mistral': 1039, 'n_tokens_neox': 978, 'n_words': 322}