blob: 46f8ebe985eda6b97a796f92e4d9ce82346d36f3 [file] [log] [blame]
package org.eclipse.stem.core.graph.impl;
/*******************************************************************************
* Copyright (c) 2011 IBM Corporation and others.
* 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
import java.util.HashMap;
import java.util.Map;
import java.util.NavigableSet;
import java.util.TreeSet;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.stem.core.common.Identifiable;
import org.eclipse.stem.core.graph.DynamicLabel;
import org.eclipse.stem.core.graph.GraphPackage;
import org.eclipse.stem.core.graph.SimpleGraphPartitioner;
import org.eclipse.stem.core.model.Decorator;
/**
* <!-- begin-user-doc -->
* An implementation of the model object '<em><b>Simple Graph Partitioner</b></em>'.
* <!-- end-user-doc -->
* <p>
* </p>
*
* @generated
*/
public class SimpleGraphPartitionerImpl extends GraphPartitionerImpl implements SimpleGraphPartitioner {
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
protected SimpleGraphPartitionerImpl() {
super();
}
protected Map<Decorator, Map<Integer, EList<DynamicLabel>>> labelPartitionMap = new HashMap<Decorator, Map<Integer, EList<DynamicLabel>>>();
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
protected EClass eStaticClass() {
return GraphPackage.Literals.SIMPLE_GRAPH_PARTITIONER;
}
/**
* Override to clear map
*/
@Override
public void setNumProcesses(int newNumProcesses) {
if(getNumProcesses() != newNumProcesses)
labelPartitionMap.clear();
super.setNumProcesses(newNumProcesses);
}
/**
* Simply divide the labels the decorator is updating equally among the
* processes alphabetically by the node URI. The method is synchronized
* since the labelPartitionMap is shared among the threads, but most of the times
* the method will return right away using the already cached results so performance
* is not a concern.
*/
@SuppressWarnings("boxing")
@Override
public EList<DynamicLabel> partitionDecoratorLabels(Decorator decorator, int processRank) {
synchronized(labelPartitionMap) {
if(labelPartitionMap != null && labelPartitionMap.containsKey(decorator) &&
labelPartitionMap.get(decorator).containsKey(processRank)) {
EList<DynamicLabel> res = labelPartitionMap.get(decorator).get(processRank);
return res;
}
EList<DynamicLabel> temp = new BasicEList<DynamicLabel>();
// Find the node and partition the labels according to their node.
// TreeSet guarantees O(log(n)) add/contains
TreeSet<String>nodeURIs = new TreeSet<String>();
for(DynamicLabel lab:decorator.getLabelsToUpdate()) {
String uri = lab.getIdentifiable().getURI().toString();
if(!nodeURIs.contains(uri)) nodeURIs.add(uri);
}
int size = nodeURIs.size();
if(processRank == 0 || size > 1) { // If size is 1 and processRank is 0 the single node gets assigned to the first CPU.
int nodesPerPartition = size / getNumProcesses();
int start = processRank*nodesPerPartition;
int end;
if(processRank == getNumProcesses() -1) end = size; // The last threads grabs all nodes until the last one
else end = start + nodesPerPartition;
String first=nodeURIs.first();
for(int i=0;i<start;++i) first = nodeURIs.higher(first);
String last = first;
for(int i=start;i<end-1;++i) last = nodeURIs.higher(last);
NavigableSet<String>processURIs = nodeURIs.subSet(first, true, last, true);
for(DynamicLabel dl:decorator.getLabelsToUpdate()) {
if(processURIs.contains(dl.getIdentifiable().getURI().toString())) {
temp.add(dl);
}
}
}
Map<Integer, EList<DynamicLabel>> partitionMap = null;
if(labelPartitionMap.containsKey(decorator))
partitionMap = labelPartitionMap.get(decorator);
else {
partitionMap = new HashMap<Integer, EList<DynamicLabel>>();
labelPartitionMap.put(decorator, partitionMap);
}
partitionMap.put(processRank, temp);
long timeAfter = System.currentTimeMillis();
return temp;
}
}
/**
* Same as above but return all labels handled by this decorator
*/
@Override
public EList<DynamicLabel> partitionDecoratorLabels(Decorator decorator) {
return decorator.getLabelsToUpdate();
}
/**
* Everything is managed by this running STEM instance
*/
@Override
public boolean isManaged(Identifiable identifiable) {
return true;
}
} //SimpleGraphPartitionerImpl