001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
003: */
004: package com.tc.objectserver.managedobject;
005:
006: import com.tc.object.ObjectID;
007: import com.tc.objectserver.core.api.ManagedObject;
008: import com.tc.objectserver.impl.ManagedObjectReference;
009: import com.tc.util.Assert;
010:
011: import java.util.HashMap;
012: import java.util.HashSet;
013: import java.util.Iterator;
014: import java.util.Map;
015: import java.util.Set;
016: import java.util.Map.Entry;
017:
018: public class ManagedObjectTraverser {
019:
020: private static final String PROCESSED = "PROCESSED";
021: private static final String REACHABLE = "REACHABLE";
022: private static final String REQUIRED = "REQUIRED";
023: private static final String LOOKUP_REQUIRED = "LOOKUP_REQUIRED";
024: private static final String LOOKUP_REACHABLE = "LOOKUP_REACHABLE";
025:
026: private int maxReachableObjects;
027: private final Map oids = new HashMap();
028:
029: public ManagedObjectTraverser(int maxReachableObjects) {
030: this .maxReachableObjects = maxReachableObjects;
031: }
032:
033: public void traverse(Set objects) {
034: markProcessed(objects, true);
035: }
036:
037: private void markProcessed(Set objects, boolean traverse) {
038: for (Iterator i = objects.iterator(); i.hasNext();) {
039: ManagedObjectReference ref = (ManagedObjectReference) i
040: .next();
041: ManagedObject mo = ref.getObject();
042: oids.put(mo.getID(), PROCESSED);
043: maxReachableObjects--;
044: if (traverse) {
045: mo.addObjectReferencesTo(this );
046: }
047: }
048: }
049:
050: public Set getObjectsToLookup() {
051: HashSet oidsToLookup = new HashSet(oids.size() < 512 ? oids
052: .size() : 512);
053: for (Iterator i = oids.entrySet().iterator(); i.hasNext();) {
054: Entry e = (Entry) i.next();
055: Object _state = e.getValue();
056: if (_state == REQUIRED) {
057: oidsToLookup.add(e.getKey());
058: e.setValue(LOOKUP_REQUIRED);
059: } else if (maxReachableObjects - oidsToLookup.size() > 0
060: && _state == REACHABLE) {
061: oidsToLookup.add(e.getKey());
062: e.setValue(LOOKUP_REACHABLE);
063: }
064: }
065: return oidsToLookup;
066: }
067:
068: public Set getPendingObjectsToLookup(Set lookedUpObjects) {
069: if (lookedUpObjects.size() > 0) {
070: markProcessed(lookedUpObjects, false);
071: }
072: HashSet oidsToLookup = new HashSet(oids.size() < 512 ? oids
073: .size() : 512);
074: for (Iterator i = oids.entrySet().iterator(); i.hasNext();) {
075: Entry e = (Entry) i.next();
076: Object _state = e.getValue();
077: Assert.assertTrue(_state != REQUIRED);
078: if (_state == LOOKUP_REQUIRED) {
079: oidsToLookup.add(e.getKey());
080: }
081: }
082: return oidsToLookup;
083: }
084:
085: public void addRequiredObjectIDs(Set objectReferences) {
086: for (Iterator i = objectReferences.iterator(); i.hasNext();) {
087: ObjectID oid = (ObjectID) i.next();
088: if (oid.isNull())
089: continue;
090: Object state = oids.get(oid);
091: if (state == null || state == REACHABLE) {
092: oids.put(oid, REQUIRED);
093: }
094: }
095: }
096:
097: public void addReachableObjectIDs(Set objectReferences) {
098: if (maxReachableObjects <= 0)
099: return;
100: for (Iterator i = objectReferences.iterator(); i.hasNext();) {
101: ObjectID oid = (ObjectID) i.next();
102: if (oid.isNull())
103: continue;
104: Object state = oids.get(oid);
105: if (state == null) {
106: oids.put(oid, REACHABLE);
107: }
108: }
109: }
110:
111: }
|