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 
  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 
 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 
 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 }