2 * JCarder -- cards Java programs to keep threads disentangled
4 * Copyright (C) 2006-2007 Enea AB
5 * Copyright (C) 2007 Ulrik Svensson
6 * Copyright (C) 2007 Joel Rosdahl
8 * This program is made available under the GNU GPL version 2, with a special
9 * exception for linking with JUnit. See the accompanying file LICENSE.txt for
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE.
17 package com.enea.jcarder.analyzer;
19 import java.util.HashMap;
23 import net.jcip.annotations.NotThreadSafe;
25 import com.enea.jcarder.common.contexts.ContextReaderIfc;
28 * A LockNode instance represents a lock in a graph.
32 enum CycleType { NO_CYCLE, SINGLE_THREADED_CYCLE, CYCLE };
34 private final int mLockId;
35 private Map<LockEdge, LockEdge> mOutgoingEdges;
36 private CycleType mCycleType = CycleType.NO_CYCLE;
38 LockNode(final int lockId) {
40 mOutgoingEdges = new HashMap<LockEdge, LockEdge>();
47 CycleType getCycleType() {
51 void raiseCycleType(CycleType newCycleType) {
52 if (newCycleType.compareTo(mCycleType) > 0) {
53 mCycleType = newCycleType;
57 void addOutgoingEdge(LockEdge newEdge) {
58 LockEdge existingEdge = mOutgoingEdges.get(newEdge);
59 if (existingEdge == null) {
60 mOutgoingEdges.put(newEdge, newEdge);
62 existingEdge.merge(newEdge);
66 void populateContextIdTranslationMap(Map<Integer, Integer> translationMap) {
67 for (LockEdge edge : mOutgoingEdges.values()) {
68 translationMap.put(edge.getSourceLockingContextId(),
69 edge.getSourceLockingContextId());
70 translationMap.put(edge.getTargetLockingContextId(),
71 edge.getTargetLockingContextId());
75 void translateContextIds(Map<Integer, Integer> translation) {
76 Map<LockEdge, LockEdge> oldEdges = mOutgoingEdges;
77 mOutgoingEdges = new HashMap<LockEdge, LockEdge>(oldEdges.size());
78 for (LockEdge edge : oldEdges.values()) {
79 edge.translateContextIds(translation);
80 addOutgoingEdge(edge);
84 Set<LockEdge> getOutgoingEdges() {
85 return mOutgoingEdges.keySet();
88 public String toString() {
89 return "L_" + mLockId;
92 long numberOfUniqueEdges() {
93 return mOutgoingEdges.size();
96 long numberOfDuplicatedEdges() {
97 long numberOfDuplicatedEdges = 0;
98 for (LockEdge edge : mOutgoingEdges.values()) {
99 numberOfDuplicatedEdges += edge.getDuplicates();
101 return numberOfDuplicatedEdges;
104 boolean alike(LockNode other, ContextReaderIfc reader) {
105 // TODO Maybe introduce some kind of cache to improve performance?
106 String thisClassName = reader.readLock(mLockId).getClassName();
107 String otherClassName = reader.readLock(other.mLockId).getClassName();
108 return thisClassName.equals(otherClassName);