KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > object > applicator > ConcurrentHashMapApplicator


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

4 package com.tc.object.applicator;
5
6 import com.tc.exception.TCRuntimeException;
7 import com.tc.object.ClientObjectManager;
8 import com.tc.object.ObjectID;
9 import com.tc.object.TCObject;
10 import com.tc.object.TraversedReferences;
11 import com.tc.object.bytecode.ByteCodeUtil;
12 import com.tc.object.bytecode.Manageable;
13 import com.tc.object.dna.api.DNA;
14 import com.tc.object.dna.api.DNACursor;
15 import com.tc.object.dna.api.DNAWriter;
16 import com.tc.object.dna.api.LiteralAction;
17 import com.tc.object.dna.api.LogicalAction;
18 import com.tc.object.dna.api.PhysicalAction;
19 import com.tc.object.dna.impl.DNAEncoding;
20 import com.tc.object.tx.optimistic.OptimisticTransactionManager;
21 import com.tc.object.tx.optimistic.TCObjectClone;
22 import com.tc.util.Assert;
23 import com.tc.util.FieldUtils;
24
25 import java.io.IOException JavaDoc;
26 import java.lang.reflect.Array JavaDoc;
27 import java.lang.reflect.Field JavaDoc;
28 import java.lang.reflect.InvocationTargetException JavaDoc;
29 import java.lang.reflect.Method JavaDoc;
30 import java.util.IdentityHashMap JavaDoc;
31 import java.util.Iterator JavaDoc;
32 import java.util.Map JavaDoc;
33 import java.util.Map.Entry;
34 import java.util.concurrent.ConcurrentHashMap JavaDoc;
35
36 /**
37  * Apply a logical action to an object
38  */

39 public class ConcurrentHashMapApplicator extends HashMapApplicator {
40   private static final String JavaDoc CONCURRENT_HASH_MAP_FIELD_NAME_PREFIX = ConcurrentHashMap JavaDoc.class.getName() + ".";
41   private static final String JavaDoc SEGMENT_MASK_FIELD_NAME = "segmentMask";
42   private static final String JavaDoc SEGMENT_SHIFT_FIELD_NAME = "segmentShift";
43   private static final String JavaDoc SEGMENT_FIELD_NAME = "segments";
44   private static final String JavaDoc TC_PUT_METHOD_NAME = ByteCodeUtil.TC_METHOD_PREFIX + "put";
45
46   private static final Field JavaDoc SEGMENT_MASK_FIELD;
47   private static final Field JavaDoc SEGMENT_SHIFT_FIELD;
48   private static final Field JavaDoc SEGMENT_FIELD;
49   private static final Method JavaDoc TC_PUT_METHOD;
50
51   static {
52     try {
53       SEGMENT_MASK_FIELD = ConcurrentHashMap JavaDoc.class.getDeclaredField(SEGMENT_MASK_FIELD_NAME);
54       SEGMENT_MASK_FIELD.setAccessible(true);
55
56       SEGMENT_SHIFT_FIELD = ConcurrentHashMap JavaDoc.class.getDeclaredField(SEGMENT_SHIFT_FIELD_NAME);
57       SEGMENT_SHIFT_FIELD.setAccessible(true);
58
59       SEGMENT_FIELD = ConcurrentHashMap JavaDoc.class.getDeclaredField(SEGMENT_FIELD_NAME);
60       SEGMENT_FIELD.setAccessible(true);
61
62       TC_PUT_METHOD = ConcurrentHashMap JavaDoc.class.getDeclaredMethod(TC_PUT_METHOD_NAME, new Class JavaDoc[] { Object JavaDoc.class,
63       Object JavaDoc.class });
64       TC_PUT_METHOD.setAccessible(true);
65     } catch (Exception JavaDoc e) {
66       throw new RuntimeException JavaDoc(e);
67     }
68   }
69
70   public ConcurrentHashMapApplicator(DNAEncoding encoding) {
71     super(encoding);
72   }
73
74   public TraversedReferences getPortableObjects(Object JavaDoc pojo, TraversedReferences addTo) {
75     super.getPortableObjects(pojo, addTo);
76     getPhysicalPortableObjects(pojo, addTo);
77     return addTo;
78   }
79
80   public void getPhysicalPortableObjects(Object JavaDoc pojo, TraversedReferences addTo) {
81     try {
82       filterPortableObject(SEGMENT_MASK_FIELD.get(pojo), addTo);
83       filterPortableObject(SEGMENT_SHIFT_FIELD.get(pojo), addTo);
84       Object JavaDoc[] segments = (Object JavaDoc[])SEGMENT_FIELD.get(pojo);
85       for (int i=0; i<segments.length; i++) {
86         filterPortableObject(segments[i], addTo);
87       }
88     } catch (IllegalAccessException JavaDoc e) {
89       throw new TCRuntimeException(e);
90     }
91   }
92
93   private void filterPortableObject(Object JavaDoc value, TraversedReferences addTo) {
94     if (value != null && isPortableReference(value.getClass())) {
95       addTo.addAnonymousReference(value);
96     }
97   }
98
99   public void hydrate(ClientObjectManager objectManager, TCObject tcObject, DNA dna, Object JavaDoc po) throws IOException JavaDoc,
100       ClassNotFoundException JavaDoc {
101     int segmentLength = -1;
102     Object JavaDoc segment = null;
103     Object JavaDoc[] segments = null;
104     int segmentIndex = 0;
105     DNACursor cursor = dna.getCursor();
106
107     while (cursor.next(encoding)) {
108       Object JavaDoc action = cursor.getAction();
109       if (action instanceof LogicalAction) {
110         if (segmentLength != -1) {
111           setSegmentField(segments, po, segmentLength, segmentIndex);
112           segmentLength = -1;
113         }
114
115         LogicalAction logicalAction = cursor.getLogicalAction();
116         int method = logicalAction.getMethod();
117         Object JavaDoc[] params = logicalAction.getParameters();
118         apply(objectManager, po, method, params);
119       } else if (action instanceof LiteralAction) {
120         LiteralAction literalAction = (LiteralAction) action;
121         segmentLength = ((Integer JavaDoc) literalAction.getObject()).intValue();
122       } else if (action instanceof PhysicalAction) {
123         Assert.assertFalse(dna.isDelta()); // Physical fields are shared only when the DNA is not
124
// a delta.
125

126         PhysicalAction physicalAction = cursor.getPhysicalAction();
127
128         Assert.eval(physicalAction.isTruePhysical());
129         String JavaDoc fieldName = physicalAction.getFieldName();
130         Object JavaDoc value = physicalAction.getObject();
131         try {
132           if (fieldName.equals(CONCURRENT_HASH_MAP_FIELD_NAME_PREFIX + SEGMENT_MASK_FIELD_NAME)) {
133             FieldUtils.tcSet(po, value, SEGMENT_MASK_FIELD);
134           } else if (fieldName.equals(CONCURRENT_HASH_MAP_FIELD_NAME_PREFIX + SEGMENT_SHIFT_FIELD_NAME)) {
135             FieldUtils.tcSet(po, value, SEGMENT_SHIFT_FIELD);
136           } else if (fieldName.equals(CONCURRENT_HASH_MAP_FIELD_NAME_PREFIX + SEGMENT_FIELD_NAME + segmentIndex)) {
137             segment = objectManager.lookupObject((ObjectID) value);
138             if (segments == null) {
139               segments = (Object JavaDoc[]) Array.newInstance(segment.getClass(), segmentLength);
140             }
141             segments[segmentIndex] = segment;
142             segmentIndex++;
143           }
144         } catch (IllegalAccessException JavaDoc e) {
145           throw new TCRuntimeException(e);
146         }
147       }
148     }
149     setSegmentField(segments, po, segmentLength, segmentIndex);
150   }
151   
152   private void setSegmentField(Object JavaDoc[] segments, Object JavaDoc po, int segmentLength, int segmentIndex) {
153     if (segmentLength != -1) {
154       Assert.assertEquals(segmentLength, segmentIndex);
155       try {
156         FieldUtils.tcSet(po, segments, SEGMENT_FIELD);
157       } catch (IllegalAccessException JavaDoc e) {
158         throw new TCRuntimeException(e);
159       }
160     }
161   }
162
163   public void dehydrate(ClientObjectManager objectManager, TCObject tcObject, DNAWriter writer, Object JavaDoc pojo) {
164     dehydrateFields(objectManager, tcObject, writer, pojo);
165     super.dehydrate(objectManager, tcObject, writer, pojo);
166   }
167
168   private void dehydrateFields(ClientObjectManager objectManager, TCObject tcObject, DNAWriter writer, Object JavaDoc pojo) {
169     try {
170       Object JavaDoc segmentMask = SEGMENT_MASK_FIELD.get(pojo);
171       segmentMask = getDehydratableObject(segmentMask, objectManager);
172       writer.addPhysicalAction(CONCURRENT_HASH_MAP_FIELD_NAME_PREFIX + SEGMENT_MASK_FIELD_NAME, segmentMask);
173
174       Object JavaDoc segmentShift = SEGMENT_SHIFT_FIELD.get(pojo);
175       segmentShift = getDehydratableObject(segmentShift, objectManager);
176       writer.addPhysicalAction(CONCURRENT_HASH_MAP_FIELD_NAME_PREFIX + SEGMENT_SHIFT_FIELD_NAME, segmentShift);
177
178       Object JavaDoc[] segments = (Object JavaDoc[]) SEGMENT_FIELD.get(pojo);
179       writer.addLiteralValue(new Integer JavaDoc(segments.length));
180       for (int i = 0; i < segments.length; i++) {
181         Object JavaDoc segment = segments[i];
182         segment = getDehydratableObject(segment, objectManager);
183         writer.addPhysicalAction(CONCURRENT_HASH_MAP_FIELD_NAME_PREFIX + SEGMENT_FIELD_NAME + i, segment);
184       }
185     } catch (IllegalAccessException JavaDoc e) {
186       throw new TCRuntimeException(e);
187     }
188   }
189
190   public Map JavaDoc connectedCopy(Object JavaDoc source, Object JavaDoc dest, Map JavaDoc visited, ClientObjectManager objectManager,
191                            OptimisticTransactionManager txManager) {
192     Map JavaDoc cloned = new IdentityHashMap JavaDoc();
193
194     Manageable sourceManageable = (Manageable) source;
195     Manageable destManaged = (Manageable) dest;
196
197     Map JavaDoc sourceMap = (Map JavaDoc) source;
198     Map JavaDoc destMap = (Map JavaDoc) dest;
199
200     for (Iterator JavaDoc i = sourceMap.entrySet().iterator(); i.hasNext();) {
201       Entry e = (Entry) i.next();
202
203       Object JavaDoc copyKey = createCopyIfNecessary(objectManager, visited, cloned, e.getKey());
204       Object JavaDoc copyValue = createCopyIfNecessary(objectManager, visited, cloned, e.getValue());
205       try {
206         TC_PUT_METHOD.invoke(destMap, new Object JavaDoc[] { copyKey, copyValue });
207       } catch (IllegalArgumentException JavaDoc e1) {
208         throw new TCRuntimeException(e1);
209       } catch (IllegalAccessException JavaDoc e1) {
210         throw new TCRuntimeException(e1);
211       } catch (InvocationTargetException JavaDoc e1) {
212         throw new TCRuntimeException(e1);
213       }
214     }
215
216     destManaged.__tc_managed(new TCObjectClone(sourceManageable.__tc_managed(), txManager));
217     return cloned;
218   }
219 }
220
Popular Tags