001: /*
002: * Copyright (c) 1998 - 2005 Versant Corporation
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * Versant Corporation - initial API and implementation
010: */
011: package com.versant.core.jdo;
012:
013: import java.lang.ref.Reference;
014: import java.lang.ref.ReferenceQueue;
015:
016: import com.versant.core.common.*;
017:
018: /**
019: * This is a wrapper instance used to represent an entry in the pm ManagedCache.
020: * It can either represent a OID-State pair or an OID-PCStateMan pair.
021: * It both cases the reference type can be weak or soft or hard.
022: */
023: public class PMCacheEntry {
024:
025: /**
026: * The soft, weak or hard ref.
027: */
028: private Object ref;
029: /**
030: * This is a linked list of items to process at the end of the tx.
031: */
032: public PMCacheEntry processListNext;
033: public PMCacheEntry processListPrev;
034:
035: public PMCacheEntry next;
036: public PMCacheEntry prev;
037:
038: public int hash;
039: /**
040: * The type of ref(soft, weak or hard)
041: * @see com.versant.core.jdo.VersantPersistenceManager.PM_CACHE_REF_TYPE_WEAK
042: * @see com.versant.core.jdo.VersantPersistenceManager.PM_CACHE_REF_TYPE_SOFT
043: * @see com.versant.core.jdo.VersantPersistenceManager.PM_CACHE_REF_TYPE_STRONG
044: */
045: private int type;
046: /**
047: * The oid this mapping is done on.
048: */
049: public OID mappedOID;
050:
051: public PMCacheEntry() {
052: }
053:
054: public PMCacheEntry(int type, PCStateMan sm, ReferenceQueue queue) {
055: LocalPMCache.checkRefType(type);
056: this .type = type;
057: if (sm.oid.getRealOID() == null) {
058: this .hash = sm.oid.hashCode();
059: this .mappedOID = sm.oid;
060: } else {
061: this .mappedOID = sm.oid.getRealOID();
062: this .hash = sm.oid.getRealOID().hashCode();
063: }
064:
065: switch (type) {
066: case VersantPersistenceManager.PM_CACHE_REF_TYPE_STRONG:
067: ref = sm;
068: break;
069: case VersantPersistenceManager.PM_CACHE_REF_TYPE_SOFT:
070: ref = new SoftCacheEntryRef(sm, queue, this );
071: break;
072: case VersantPersistenceManager.PM_CACHE_REF_TYPE_WEAK:
073: ref = new WeakCacheEntryRef(sm, queue, this );
074: break;
075: default:
076: throw BindingSupportImpl.getInstance().internal(
077: "Unknown option: " + type);
078: }
079: }
080:
081: public PMCacheEntry(int type, OID oid, State state,
082: ReferenceQueue queue) {
083: LocalPMCache.checkRefType(type);
084: this .type = type;
085: this .hash = oid.hashCode();
086: this .mappedOID = oid;
087: if (mappedOID == null) {
088: throw BindingSupportImpl.getInstance().internal("");
089: }
090: switch (type) {
091: case VersantPersistenceManager.PM_CACHE_REF_TYPE_STRONG:
092: ref = state;
093: break;
094: case VersantPersistenceManager.PM_CACHE_REF_TYPE_SOFT:
095: ref = new SoftCacheEntryRef(state, queue, this );
096: break;
097: case VersantPersistenceManager.PM_CACHE_REF_TYPE_WEAK:
098: ref = new WeakCacheEntryRef(state, queue, this );
099: break;
100: default:
101: throw BindingSupportImpl.getInstance().internal(
102: "Unknown option: " + type);
103: }
104: }
105:
106: public void unlinkProcessList() {
107: if (processListNext != null) {
108: processListNext.processListPrev = null;
109: }
110: if (processListPrev != null) {
111: processListPrev.processListNext = null;
112: }
113:
114: processListNext = null;
115: processListPrev = null;
116: }
117:
118: public void unlinkNextList() {
119: if (prev != null) {
120: prev.next = next;
121: }
122: if (next != null) {
123: next.prev = prev;
124: }
125: next = null;
126: prev = null;
127: }
128:
129: /**
130: * Upgrade the ref from a oid-state pair to a oid-pcstateman pair.
131: */
132: public PCStateMan upgradeToSm(PCStateMan sm, ReferenceQueue queue) {
133: sm.cacheEntry = this ;
134: switch (type) {
135: case VersantPersistenceManager.PM_CACHE_REF_TYPE_STRONG:
136: ref = sm;
137: break;
138: case VersantPersistenceManager.PM_CACHE_REF_TYPE_SOFT:
139: ((Reference) ref).clear();
140: ref = new SoftCacheEntryRef(sm, queue, this );
141: break;
142: case VersantPersistenceManager.PM_CACHE_REF_TYPE_WEAK:
143: ((Reference) ref).clear();
144: ref = new WeakCacheEntryRef(sm, queue, this );
145: break;
146: default:
147: throw BindingSupportImpl.getInstance().internal(
148: "Unknown option: " + type);
149: }
150: return sm;
151: }
152:
153: public void setNext(PMCacheEntry nextEntry) {
154: if (Debug.DEBUG) {
155: if (nextEntry == this ) {
156: throw BindingSupportImpl.getInstance().internal("");
157: }
158: }
159: next = nextEntry;
160: if (next != null) {
161: next.prev = this ;
162: }
163: }
164:
165: public int hashCode() {
166: return hash;
167: }
168:
169: /**
170: * Called when this is being remapped with a real oid.
171: */
172: public void reHash(OID newOID) {
173: mappedOID = newOID;
174: hash = newOID.hashCode();
175: }
176:
177: /**
178: * Return the referenced instance.
179: * Either state of sm.
180: */
181: public Object get() {
182: if (ref instanceof Reference) {
183: return ((Reference) ref).get();
184: }
185: return ref;
186: }
187:
188: public boolean hasReference(Object obj) {
189: return (obj == ref);
190: }
191:
192: public void clear() {
193: if (ref instanceof Reference) {
194: ((Reference) ref).clear();
195: }
196: ref = null;
197: }
198:
199: public void reset() {
200: clear();
201: next = null;
202: prev = null;
203: processListNext = null;
204: processListPrev = null;
205: }
206:
207: public String toString() {
208: return "CacheEntryBase@"
209: + System.identityHashCode(this )
210: + " oid "
211: + (mappedOID == null ? "null" : mappedOID.toStringImp());
212: }
213:
214: public void changeToRefType(ReferenceQueue queue, int newType) {
215: LocalPMCache.checkRefType(newType);
216:
217: if (this .type == newType)
218: return;
219: Object oldRef = get();
220: clear();
221:
222: this .type = newType;
223: switch (newType) {
224: case VersantPersistenceManager.PM_CACHE_REF_TYPE_STRONG:
225: ref = oldRef;
226: break;
227: case VersantPersistenceManager.PM_CACHE_REF_TYPE_SOFT:
228: ref = new SoftCacheEntryRef(oldRef, queue, this );
229: break;
230: case VersantPersistenceManager.PM_CACHE_REF_TYPE_WEAK:
231: ref = new WeakCacheEntryRef(oldRef, queue, this );
232: break;
233: default:
234: throw BindingSupportImpl.getInstance().internal(
235: "Unknown option: " + type);
236: }
237: }
238: }
|