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 
32 package com.sun.corba.se.impl.oa.toa;
33 
34 import com.sun.corba.se.impl.orbutil.ORBUtility ;
35 import com.sun.corba.se.spi.orb.ORB ;
36 
37 public final class TransientObjectManager {
38     private ORB orb ;
39     private int maxSize = 128;
40     private Element[] elementArray;
41     private Element freeList;
42 
dprint( String msg )43     void dprint( String msg ) {
44         ORBUtility.dprint( this, msg ) ;
45     }
46 
TransientObjectManager( ORB orb )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 
storeServant(java.lang.Object servant, java.lang.Object servantData)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 
lookupServant(byte transientKey[])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 
lookupServantData(byte transientKey[])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 
deleteServant(byte transientKey[])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 
getKey(java.lang.Object servant)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 
doubleSize()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 
155 final 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 
Element(int i, java.lang.Object next)163     Element(int i, java.lang.Object next)
164     {
165         servant = next;
166         index = i;
167     }
168 
getKey(java.lang.Object servant, java.lang.Object servantData)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 
toBytes()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 
delete(Element freeList)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 
toString()201     public String toString()
202     {
203         return "Element[" + index + ", " + counter + "]" ;
204     }
205 }
206