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 com.versant.core.common.OID;
014: import com.versant.core.common.State;
015:
016: import java.util.HashSet;
017: import java.util.Collection;
018: import java.util.HashMap;
019: import java.util.Map;
020:
021: import com.versant.core.common.BindingSupportImpl;
022:
023: /**
024: *
025: */
026: public class AttachStateContainer {
027:
028: private static final int INITIAL_SIZE = 16;
029:
030: private OID[] oids = new OID[INITIAL_SIZE];
031: private VersantDetachable[] detachables = new VersantDetachable[INITIAL_SIZE];
032: private PCStateMan[] stateMans = new PCStateMan[INITIAL_SIZE];
033: private Map oidMap = new HashMap();
034: private int capacity = INITIAL_SIZE;
035: private int size;
036: private VersantPersistenceManagerImp pm;
037: private HashSet deleted = new HashSet();
038:
039: public AttachStateContainer(VersantPersistenceManagerImp pm) {
040: this .pm = pm;
041: }
042:
043: public int addVersantDetachable(VersantDetachable detachable) {
044: VersantDetachedStateManager sm = detachable
045: .versantGetDetachedStateManager();
046: if (sm != null) {
047: Collection delOIDs = ((VersantDetachedStateManager) sm)
048: .versantGetDeleted();
049: if (!delOIDs.isEmpty()) {
050: deleted.addAll(delOIDs);
051: delOIDs.clear();
052: }
053: }
054: OID oid = pm.getOID(detachable);
055: Integer integer = (Integer) oidMap.get(oid);
056: if (integer != null) {
057: int index = integer.intValue();
058: VersantDetachable oldDetachable = detachables[index];
059: if (oldDetachable == detachable)
060: return index;
061: if (detachable.versantIsDirty()) {
062: if (oldDetachable.versantIsDirty()) {
063: throw BindingSupportImpl.getInstance()
064: .concurrentUpdate(
065: "Duplicate oid(" + oid
066: + ") in attach graph", oid);
067: } else {
068: detachables[index] = detachable;
069: }
070: } else {
071: return index;
072: }
073: }
074: if (size == capacity) {
075: capacity = (capacity * 3) / 2 + 1;
076: VersantDetachable[] nd = new VersantDetachable[capacity];
077: System.arraycopy(detachables, 0, nd, 0, size);
078: detachables = nd;
079: OID[] noids = new OID[capacity];
080: System.arraycopy(oids, 0, noids, 0, size);
081: oids = noids;
082: PCStateMan[] nsm = new PCStateMan[capacity];
083: System.arraycopy(stateMans, 0, nsm, 0, size);
084: stateMans = nsm;
085: }
086: oids[size] = oid;
087: detachables[size] = detachable;
088: oidMap.put(oid, new Integer(size));
089: return size++;
090: }
091:
092: public int getDetachedSize() {
093: return size;
094: }
095:
096: public VersantDetachable getVersantDetachable(int c) {
097: return detachables[c];
098: }
099:
100: public OID[] getOIDs() {
101: return oids;
102: }
103:
104: public State getState(int c) {
105: return null;
106: }
107:
108: public OID getOID(int c) {
109: return oids[c];
110: }
111:
112: public State getState(int c, VersantPersistenceManagerImp pm) {
113: return pm.getStateFromLocalCacheById(getOID(c));
114:
115: }
116:
117: public void addPCStateMan(OID oid, PCStateMan sm) {
118: Integer integer = (Integer) oidMap.get(oid);
119: if (integer != null) {
120: stateMans[integer.intValue()] = sm;
121: }
122: }
123:
124: public HashSet getDeleted() {
125: return deleted;
126: }
127: }
|