1 4 package com.tc.objectserver.managedobject; 5 6 import com.tc.object.ObjectID; 7 import com.tc.object.SerializationUtil; 8 import com.tc.object.dna.api.DNACursor; 9 import com.tc.object.dna.api.DNAWriter; 10 import com.tc.object.dna.api.LiteralAction; 11 import com.tc.object.dna.api.LogicalAction; 12 import com.tc.object.dna.api.PhysicalAction; 13 14 import java.io.IOException ; 15 import java.io.ObjectInput ; 16 import java.io.ObjectOutput ; 17 import java.util.Arrays ; 18 import java.util.HashMap ; 19 import java.util.Iterator ; 20 import java.util.Map ; 21 import java.util.Set ; 22 import java.util.Map.Entry; 23 24 27 public class ConcurrentHashMapManagedObjectState extends MapManagedObjectState { 28 private static final String SEGMENT_MASK_FIELD_NAME = "java.util.concurrent.ConcurrentHashMap.segmentMask"; 29 private static final String SEGMENT_SHIFT_FIELD_NAME = "java.util.concurrent.ConcurrentHashMap.segmentShift"; 30 private static final String SEGMENT_FIELD_NAME = "java.util.concurrent.ConcurrentHashMap.segments"; 31 32 private Object segmentMask; 33 private Object segmentShift; 34 private ObjectID[] segments = null; 35 36 protected ConcurrentHashMapManagedObjectState(long classID) { 37 super(classID, new HashMap ()); 38 } 39 40 protected ConcurrentHashMapManagedObjectState(ObjectInput in) throws IOException { 41 super(in); 42 } 43 44 protected ConcurrentHashMapManagedObjectState(long classID, Map map) { 45 super(classID, map); 46 } 47 48 public void apply(ObjectID objectID, DNACursor cursor, BackReferences includeIDs) throws IOException { 49 int segmentIndex = 0; 50 while (cursor.next()) { 51 Object action = cursor.getAction(); 52 if (action instanceof LogicalAction) { 53 LogicalAction logicalAction = (LogicalAction) action; 54 int method = logicalAction.getMethod(); 55 Object [] params = logicalAction.getParameters(); 56 applyMethod(objectID, includeIDs, method, params); 57 } else if (action instanceof LiteralAction) { 58 LiteralAction literalAction = (LiteralAction) action; 59 segments = new ObjectID[((Integer ) literalAction.getObject()).intValue()]; 60 } else if (action instanceof PhysicalAction) { 61 PhysicalAction physicalAction = (PhysicalAction) action; 62 boolean updateSegment = updateReference(physicalAction.getFieldName(), physicalAction.getObject(), segmentIndex); 63 if (updateSegment) { 64 segmentIndex++; 65 } 66 } 67 } 68 } 69 70 private boolean updateReference(String fieldName, Object value, int segmentIndex) { 71 if (SEGMENT_MASK_FIELD_NAME.equals(fieldName)) { 72 segmentMask = value; 73 return false; 74 } else if (SEGMENT_SHIFT_FIELD_NAME.equals(fieldName)) { 75 segmentShift = value; 76 return false; 77 } else if ((SEGMENT_FIELD_NAME + segmentIndex).equals(fieldName)) { 78 segments[segmentIndex] = (ObjectID) value; 81 return true; 82 } else { 83 return false; 84 } 85 } 86 87 protected void addAllObjectReferencesTo(Set refs) { 88 super.addAllObjectReferencesTo(refs); 89 if (segments != null) { 90 for (int i = 0; i < segments.length; i++) { 91 refs.add(segments[i]); 92 } 93 } 94 } 95 96 public void dehydrate(ObjectID objectID, DNAWriter writer) { 97 dehydrateFields(objectID, writer); 98 dehydrateMapKeyValuesPair(objectID, writer); 99 } 100 101 private void dehydrateMapKeyValuesPair(ObjectID objectID, DNAWriter writer) { 102 for (Iterator i = references.entrySet().iterator(); i.hasNext();) { 103 Entry entry = (Entry) i.next(); 104 Object key = entry.getKey(); 105 Object value = entry.getValue(); 106 writer.addLogicalAction(SerializationUtil.PUT, new Object [] { key, value }); 107 } 108 } 109 110 private void dehydrateFields(ObjectID objectID, DNAWriter writer) { 111 writer.addPhysicalAction(SEGMENT_MASK_FIELD_NAME, segmentMask); 112 writer.addPhysicalAction(SEGMENT_SHIFT_FIELD_NAME, segmentShift); 113 114 writer.addLiteralValue(new Integer (segments.length)); 115 for (int i = 0; i < segments.length; i++) { 116 ObjectID segment = segments[i]; 117 writer.addPhysicalAction(SEGMENT_FIELD_NAME + i, segment); 118 } 119 } 120 121 private void writeField(ObjectOutput out, String fieldName, Object fieldValue) throws IOException { 122 out.writeUTF(fieldName); 123 if (fieldValue == null) { 124 out.writeBoolean(false); 125 } else { 126 out.writeBoolean(true); 127 if (fieldValue instanceof ObjectID) { 128 out.writeLong(((ObjectID) fieldValue).toLong()); 129 } else { 130 out.writeObject(fieldValue); 131 } 132 } 133 } 134 135 protected void basicWriteTo(ObjectOutput out) throws IOException { 136 writeField(out, SEGMENT_MASK_FIELD_NAME, segmentMask); 137 writeField(out, SEGMENT_SHIFT_FIELD_NAME, segmentShift); 138 if (segments == null) { 139 out.writeBoolean(false); 140 } else { 141 out.writeBoolean(true); 142 out.writeInt(segments.length); 143 for (int i = 0; i < segments.length; i++) { 144 writeField(out, SEGMENT_FIELD_NAME + i, segments[i]); 145 } 146 } 147 out.writeInt(references.size()); 148 for (Iterator i = references.entrySet().iterator(); i.hasNext();) { 149 Entry entry = (Entry) i.next(); 150 out.writeObject(entry.getKey()); 151 out.writeObject(entry.getValue()); 152 } 153 } 154 155 private static void readField(ObjectInput in, ConcurrentHashMapManagedObjectState mo, int index) 156 throws ClassNotFoundException , IOException { 157 String fieldName = in.readUTF(); 158 boolean fieldExist = in.readBoolean(); 159 if (fieldExist) { 160 if (fieldName.equals(SEGMENT_MASK_FIELD_NAME)) { 161 mo.segmentMask = in.readObject(); 162 } else if (fieldName.equals(SEGMENT_SHIFT_FIELD_NAME)) { 163 mo.segmentShift = in.readObject(); 164 } else if (fieldName.equals((SEGMENT_FIELD_NAME + index))) { 165 mo.segments[index] = new ObjectID(in.readLong()); 166 } else { 167 throw new AssertionError ("Field not recognized in ConcurrentHashMapManagedObjectState.readFrom()."); 168 } 169 } 170 } 171 172 static MapManagedObjectState readFrom(ObjectInput in) throws IOException , ClassNotFoundException { 173 ConcurrentHashMapManagedObjectState mo = new ConcurrentHashMapManagedObjectState(in); 174 readField(in, mo, -1); 175 readField(in, mo, -1); 176 177 boolean segmentExist = in.readBoolean(); 178 if (segmentExist) { 179 int segmentLength = in.readInt(); 180 mo.segments = new ObjectID[segmentLength]; 181 for (int i = 0; i < segmentLength; i++) { 182 readField(in, mo, i); 183 } 184 } 185 186 int size = in.readInt(); 187 Map map = new HashMap (size); 188 for (int i = 0; i < size; i++) { 189 map.put(in.readObject(), in.readObject()); 190 } 191 mo.references = map; 192 return mo; 193 } 194 195 public byte getType() { 196 return CONCURRENT_HASHMAP_TYPE; 197 } 198 199 protected boolean basicEquals(LogicalManagedObjectState o) { 200 ConcurrentHashMapManagedObjectState mo = (ConcurrentHashMapManagedObjectState) o; 201 202 return ((segmentMask == mo.segmentMask) || (segmentMask != null && segmentMask.equals(mo.segmentMask))) 203 && ((segmentShift == mo.segmentShift) || (segmentShift != null && segmentShift.equals(mo.segmentShift))) 204 && ((segments == mo.segments) || (segments != null && Arrays.equals(segments, mo.segments))) 205 && references.equals(mo.references); 206 } 207 } | Popular Tags |