KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > l2 > objectserver > L2ObjectStateManagerImpl


1 /*
2  * All content copyright (c) 2003-2007 Terracotta, Inc., except as may otherwise be noted in a separate copyright
3  * notice. All rights reserved.
4  */

5 package com.tc.l2.objectserver;
6
7 import com.tc.async.api.Sink;
8 import com.tc.l2.context.ManagedObjectSyncContext;
9 import com.tc.logging.TCLogger;
10 import com.tc.logging.TCLogging;
11 import com.tc.net.groups.NodeID;
12 import com.tc.objectserver.api.ObjectManager;
13 import com.tc.util.Assert;
14 import com.tc.util.State;
15 import com.tc.util.concurrent.CopyOnWriteArrayMap;
16
17 import java.util.Arrays JavaDoc;
18 import java.util.HashMap JavaDoc;
19 import java.util.HashSet JavaDoc;
20 import java.util.Iterator JavaDoc;
21 import java.util.List JavaDoc;
22 import java.util.Map JavaDoc;
23 import java.util.Set JavaDoc;
24
25 public class L2ObjectStateManagerImpl implements L2ObjectStateManager {
26
27   private static final TCLogger logger = TCLogging.getLogger(L2ObjectStateManagerImpl.class);
28
29   CopyOnWriteArrayMap nodes = new CopyOnWriteArrayMap();
30
31   public void removeL2(NodeID nodeID) {
32     Object JavaDoc l2State = nodes.remove(nodeID);
33     if (l2State == null) {
34       logger.warn("L2State Not found for " + nodeID);
35     }
36   }
37
38   public int addL2WithObjectIDs(NodeID nodeID, Set JavaDoc oids, ObjectManager objectManager) {
39     L2ObjectStateimpl l2State;
40     synchronized (nodes) {
41       l2State = (L2ObjectStateimpl) nodes.get(nodeID);
42       if (l2State != null) {
43         logger.warn("L2State already present for " + nodeID + ". IGNORING setExistingObjectsList : oids count = "
44                     + oids.size());
45         return 0;
46       }
47       nodes.put(nodeID, l2State = new L2ObjectStateimpl(nodeID));
48     }
49     int missing = l2State.initialize(oids, objectManager);
50     return missing;
51   }
52
53   public ManagedObjectSyncContext getSomeObjectsToSyncContext(NodeID nodeID, int count, Sink sink) {
54     L2ObjectStateimpl l2State = (L2ObjectStateimpl) nodes.get(nodeID);
55     if (l2State != null) {
56       return l2State.getSomeObjectsToSyncContext(count, sink);
57     } else {
58       logger.warn("L2 State Object Not found for " + nodeID);
59       return null;
60     }
61   }
62
63   public void close(ManagedObjectSyncContext mosc) {
64     L2ObjectStateimpl l2State = (L2ObjectStateimpl) nodes.get(mosc.getNodeID());
65     if (l2State != null) {
66       l2State.close(mosc);
67     } else {
68       logger.warn("close() : L2 State Object Not found for " + mosc.getNodeID());
69     }
70   }
71
72   public List JavaDoc getL2ObjectStates() {
73     return Arrays.asList(nodes.valuesArray());
74   }
75
76   private static final class L2ObjectStateimpl implements L2ObjectState {
77
78     private final NodeID nodeID;
79     // XXX:: Tracking just the missing Oids is better in terms of memory overhead, but this might lead to difficult race
80
// conditions. Rethink !!
81
private Set JavaDoc missingOids;
82     private Map missingRoots;
83
84     private State state = UNINITIALIZED;
85
86     private static final State UNINITIALIZED = new State("UNINITALIZED");
87     private static final State NOT_IN_SYNC = new State("NOT_IN_SYNC");
88     private static final State IN_SYNC = new State("IN_SYNC");
89
90     private ManagedObjectSyncContext syncingContext = null;
91
92     public L2ObjectStateimpl(NodeID nodeID) {
93       this.nodeID = nodeID;
94     }
95
96     private synchronized void close(ManagedObjectSyncContext mosc) {
97       Assert.assertTrue(mosc == syncingContext);
98       mosc.close();
99       if (missingOids.isEmpty()) {
100         state = IN_SYNC;
101       }
102       syncingContext = null;
103     }
104
105     private synchronized ManagedObjectSyncContext getSomeObjectsToSyncContext(int count, Sink sink) {
106       Assert.assertTrue(state == NOT_IN_SYNC);
107       Assert.assertNull(syncingContext);
108       if (isRootsMissing()) { return getMissingRootsSynccontext(sink); }
109       Set JavaDoc oids = new HashSet JavaDoc(count);
110       for (Iterator JavaDoc i = missingOids.iterator(); i.hasNext() && --count > 0;) {
111         oids.add(i.next());
112         // XXX::FIXME This has to be commented because ObjectIDSet2 doesnt support remove().
113
// i.remove();
114
}
115       missingOids.removeAll(oids); // @see above comment
116
syncingContext = new ManagedObjectSyncContext(nodeID, oids, !missingOids.isEmpty(), sink);
117       return syncingContext;
118     }
119
120     private ManagedObjectSyncContext getMissingRootsSynccontext(Sink sink) {
121       missingOids.removeAll(this.missingRoots.values());
122       syncingContext = new ManagedObjectSyncContext(nodeID, new HashMap JavaDoc(this.missingRoots), !missingOids.isEmpty(),
123                                                     sink);
124       this.missingRoots.clear();
125       return syncingContext;
126     }
127
128     private boolean isRootsMissing() {
129       return !this.missingRoots.isEmpty();
130     }
131
132     private synchronized int initialize(Set JavaDoc oidsFromL2, ObjectManager objectManager) {
133       this.missingOids = objectManager.getAllObjectIDs();
134       this.missingRoots = objectManager.getRootNamesToIDsMap();
135       int objectCount = missingOids.size();
136       Set JavaDoc missingHere = new HashSet JavaDoc();
137       for (Iterator JavaDoc i = oidsFromL2.iterator(); i.hasNext();) {
138         Object JavaDoc o = i.next();
139         if (!missingOids.remove(o)) {
140           missingHere.add(o);
141         }
142       }
143       missingRoots.values().retainAll(this.missingOids);
144       logger.info(nodeID + " : is missing " + missingOids.size() + " out of " + objectCount + " object of which "
145                   + missingRoots.size() + " are roots");
146       if (!missingHere.isEmpty()) {
147         // XXX:: This is possible because some message (Transaction message with new object creation or object delete
148
// message from GC) from previous active reached the other node and not this node and the active crashed
149
logger.warn("Object IDs MISSING HERE : " + missingHere.size() + " : " + missingHere);
150       }
151       int missingCount = missingOids.size();
152       if (missingCount == 0) {
153         state = IN_SYNC;
154       } else {
155         state = NOT_IN_SYNC;
156       }
157       notifyAll();
158       return missingCount;
159     }
160
161     public NodeID getNodeID() {
162       return nodeID;
163     }
164
165     public synchronized boolean isInSync() {
166       return (state == IN_SYNC);
167     }
168
169     public String JavaDoc toString() {
170       return "L2StateObjectImpl [ " + nodeID + " ] : missing = " + missingOids.size() + " state = " + state;
171     }
172   }
173 }
174
Popular Tags