1 11 package org.eclipse.ui.internal.texteditor.rulers; 12 13 import java.util.Collections ; 14 import java.util.Iterator ; 15 import java.util.LinkedHashMap ; 16 import java.util.LinkedHashSet ; 17 import java.util.Map ; 18 import java.util.Set ; 19 20 import org.eclipse.core.runtime.Assert; 21 22 27 public final class DAG { 28 31 private static final class MultiMap { 32 private final Map fMap= new LinkedHashMap (); 33 34 42 public void put(Object key, Object val) { 43 Set values= (Set ) fMap.get(key); 44 if (values == null) { 45 values= new LinkedHashSet (); 46 fMap.put(key, values); 47 } 48 if (val != null) 49 values.add(val); 50 } 51 52 58 public Set get(Object key) { 59 Set values= (Set ) fMap.get(key); 60 return values == null ? Collections.EMPTY_SET : values; 61 } 62 63 public Set keySet() { 64 return fMap.keySet(); 65 } 66 67 74 public Set removeAll(Object key) { 75 Set values= (Set ) fMap.remove(key); 76 return values == null ? Collections.EMPTY_SET : values; 77 } 78 79 86 public void remove(Object key, Object val) { 87 Set values= (Set ) fMap.get(key); 88 if (values != null) 89 values.remove(val); 90 } 91 92 95 public String toString() { 96 return fMap.toString(); 97 } 98 } 99 100 private final MultiMap fOut= new MultiMap(); 101 private final MultiMap fIn= new MultiMap(); 102 103 114 public boolean addEdge(Object origin, Object target) { 115 Assert.isLegal(origin != null); 116 Assert.isLegal(target != null); 117 118 if (hasPath(target, origin)) 119 return false; 120 121 fOut.put(origin, target); 122 fOut.put(target, null); 123 fIn.put(target, origin); 124 fIn.put(origin, null); 125 return true; 126 } 127 128 134 public void addVertex(Object vertex) { 135 Assert.isLegal(vertex != null); 136 fOut.put(vertex, null); 137 fIn.put(vertex, null); 138 } 139 140 145 public void removeVertex(Object vertex) { 146 Set targets= fOut.removeAll(vertex); 147 for (Iterator it= targets.iterator(); it.hasNext();) 148 fIn.remove(it.next(), vertex); 149 Set origins= fIn.removeAll(vertex); 150 for (Iterator it= origins.iterator(); it.hasNext();) 151 fOut.remove(it.next(), vertex); 152 } 153 154 160 public Set getSources() { 161 return computeZeroEdgeVertices(fIn); 162 } 163 164 170 public Set getSinks() { 171 return computeZeroEdgeVertices(fOut); 172 } 173 174 private Set computeZeroEdgeVertices(MultiMap map) { 175 Set candidates= map.keySet(); 176 Set roots= new LinkedHashSet (candidates.size()); 177 for (Iterator it= candidates.iterator(); it.hasNext();) { 178 Object candidate= it.next(); 179 if (map.get(candidate).isEmpty()) 180 roots.add(candidate); 181 } 182 return roots; 183 } 184 185 191 public Set getChildren(Object vertex) { 192 return Collections.unmodifiableSet(fOut.get(vertex)); 193 } 194 195 private boolean hasPath(Object start, Object end) { 196 if (start == end) 198 return true; 199 200 Set children= fOut.get(start); 201 for (Iterator it= children.iterator(); it.hasNext();) 202 if (hasPath(it.next(), end)) 204 return true; 205 return false; 206 } 207 208 212 public String toString() { 213 return "Out: " + fOut.toString() + " In: " + fIn.toString(); } 215 } | Popular Tags |