TransientObjectManager.java revision 608:7e06bf1dcb09
1/*
2 * Copyright (c) 1996, 2003, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25/*
26 * Licensed Materials - Property of IBM
27 * RMI-IIOP v1.0
28 * Copyright IBM Corp. 1998 1999  All Rights Reserved
29 *
30 */
31
32package com.sun.corba.se.impl.oa.toa;
33
34import com.sun.corba.se.impl.orbutil.ORBUtility ;
35import com.sun.corba.se.spi.orb.ORB ;
36
37public final class TransientObjectManager {
38    private ORB orb ;
39    private int maxSize = 128;
40    private Element[] elementArray;
41    private Element freeList;
42
43    void dprint( String msg ) {
44        ORBUtility.dprint( this, msg ) ;
45    }
46
47    public TransientObjectManager( ORB orb )
48    {
49        this.orb = orb ;
50
51        elementArray = new Element[maxSize];
52        elementArray[maxSize-1] = new Element(maxSize-1,null);
53        for ( int i=maxSize-2; i>=0; i-- )
54            elementArray[i] = new Element(i,elementArray[i+1]);
55        freeList = elementArray[0];
56    }
57
58    public synchronized byte[] storeServant(java.lang.Object servant, java.lang.Object servantData)
59    {
60        if ( freeList == null )
61            doubleSize();
62
63        Element elem = freeList;
64        freeList = (Element)freeList.servant;
65
66        byte[] result = elem.getKey(servant, servantData);
67        if (orb.transientObjectManagerDebugFlag)
68            dprint( "storeServant returns key for element " + elem ) ;
69        return result ;
70    }
71
72    public synchronized java.lang.Object lookupServant(byte transientKey[])
73    {
74        int index = ORBUtility.bytesToInt(transientKey,0);
75        int counter = ORBUtility.bytesToInt(transientKey,4);
76
77        if (orb.transientObjectManagerDebugFlag)
78            dprint( "lookupServant called with index=" + index + ", counter=" + counter ) ;
79
80        if (elementArray[index].counter == counter &&
81            elementArray[index].valid ) {
82            if (orb.transientObjectManagerDebugFlag)
83                dprint( "\tcounter is valid" ) ;
84            return elementArray[index].servant;
85        }
86
87        // servant not found
88        if (orb.transientObjectManagerDebugFlag)
89            dprint( "\tcounter is invalid" ) ;
90        return null;
91    }
92
93    public synchronized java.lang.Object lookupServantData(byte transientKey[])
94    {
95        int index = ORBUtility.bytesToInt(transientKey,0);
96        int counter = ORBUtility.bytesToInt(transientKey,4);
97
98        if (orb.transientObjectManagerDebugFlag)
99            dprint( "lookupServantData called with index=" + index + ", counter=" + counter ) ;
100
101        if (elementArray[index].counter == counter &&
102            elementArray[index].valid ) {
103            if (orb.transientObjectManagerDebugFlag)
104                dprint( "\tcounter is valid" ) ;
105            return elementArray[index].servantData;
106        }
107
108        // servant not found
109        if (orb.transientObjectManagerDebugFlag)
110            dprint( "\tcounter is invalid" ) ;
111        return null;
112    }
113
114    public synchronized void deleteServant(byte transientKey[])
115    {
116        int index = ORBUtility.bytesToInt(transientKey,0);
117        if (orb.transientObjectManagerDebugFlag)
118            dprint( "deleting servant at index=" + index ) ;
119
120        elementArray[index].delete(freeList);
121        freeList = elementArray[index];
122    }
123
124    public synchronized byte[] getKey(java.lang.Object servant)
125    {
126        for ( int i=0; i<maxSize; i++ )
127            if ( elementArray[i].valid &&
128                 elementArray[i].servant == servant )
129                return elementArray[i].toBytes();
130
131        // if we come here Object does not exist
132        return null;
133    }
134
135    private void doubleSize()
136    {
137        // Assume caller is synchronized
138
139        Element old[] = elementArray;
140        int oldSize = maxSize;
141        maxSize *= 2;
142        elementArray = new Element[maxSize];
143
144        for ( int i=0; i<oldSize; i++ )
145            elementArray[i] = old[i];
146
147        elementArray[maxSize-1] = new Element(maxSize-1,null);
148        for ( int i=maxSize-2; i>=oldSize; i-- )
149            elementArray[i] = new Element(i,elementArray[i+1]);
150        freeList = elementArray[oldSize];
151    }
152}
153
154
155final class Element {
156    java.lang.Object servant=null;     // also stores "next pointer" in free list
157    java.lang.Object servantData=null;
158    int index=-1;
159    int counter=0;
160    boolean valid=false; // valid=true if this Element contains
161    // a valid servant
162
163    Element(int i, java.lang.Object next)
164    {
165        servant = next;
166        index = i;
167    }
168
169    byte[] getKey(java.lang.Object servant, java.lang.Object servantData)
170    {
171        this.servant = servant;
172        this.servantData = servantData;
173        this.valid = true;
174
175        return toBytes();
176    }
177
178    byte[] toBytes()
179    {
180        // Convert the index+counter into an 8-byte (big-endian) key.
181
182        byte key[] = new byte[8];
183        ORBUtility.intToBytes(index, key, 0);
184        ORBUtility.intToBytes(counter, key, 4);
185
186        return key;
187    }
188
189    void delete(Element freeList)
190    {
191        if ( !valid )    // prevent double deletion
192            return;
193        counter++;
194        servantData = null;
195        valid = false;
196
197        // add this to freeList
198        servant = freeList;
199    }
200
201    public String toString()
202    {
203        return "Element[" + index + ", " + counter + "]" ;
204    }
205}
206