WildcardTypeRepository.java :  » Apache-Harmony-Java-SE » org-package » org » apache » harmony » lang » reflect » repository » Java Open Source

Java Open Source » Apache Harmony Java SE » org package 
org package » org » apache » harmony » lang » reflect » repository » WildcardTypeRepository.java
/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.apache.harmony.lang.reflect.repository;

import java.lang.reflect.WildcardType;

import org.apache.harmony.lang.reflect.parser.*;

/**
 * @author Serguei S. Zapreyev
 */

/**
 * (This all should be considered as an experimental approach which could be changed on
 * java.lang.ref using)
 * 
 * WildcardTypeRepository keeps iformation about wild cards.
 * 
 * For now the following approach for keeping is realized.
 * A concreet WC instance is included into repository if somebody do the *first* request for
 * the reflect's method like Class.getGenericSuperclass()->Class.ReflectionData.initGenericSuperclass()
 * (Field.getGenericType()->Field.FieldData.initGenericType()
 *  Method.getGenericReturnType()->Class.MethodData.initGenericReturnType()
 *  ...
 *  Constructor.getGenericParameterTypes()->Class.ConstructorData.initGenericParameterTypes()
 *  ...
 * ) and there are ParameterizedTypes with wild cards.
 * The wild card creation and allocation within repository is located within AuxiliaryCreator.createTypeArg method.
 * If the identical WC is accessed anyhow then the pointer from repository is used. However,
 * further it can be removed from the repository if the cache is full under the new instance including.
 * Then if reflect's request for such WC using the earlier used interface methods then the pointers
 * to such instance kept within the Method/Constructor/Field/Class instances are returned just if it is
 * absent within repository. But if we access anyhow to some instance of the same WC type which has 
 * been removed from repository then the new exemplar of instance is created and included into 
 * repository and the pointer to it is replicated if it needs.
 * 
 * Maybe, it would be more convinient to realize another repository implementation
 * where the accumulative approach will be used.
 * 
 * Note1. The inserted on 01.27.06 cache3 may significantly slow the algorithm but
 * it needs to provide the functional completeness of repository because we should distinguish
 * the entries with equals signatures if there are TVARs which are only homonym ones, i.e.
 * they are parameters of different generic declarations. 
 */
public final class WildcardTypeRepository {

    static final class WildcardTypeCache {
  
    /**
     * This class realizes the WildcardType repository which
     * is just a cache. When the cache is exceeded at that time this experimental original cache algorithm (which, if
     * it will justify hopes, should be combined in one for all type repositories here) rewrites the worst entity
     * which can't be copied any more only recreated (as equal, of course). If the cache has an entity which
     * the reflect supporting algorithm supposes to include there than the cache's algorithm copies the existing entity.
     * If the cache is not full and an entity does not exist than there the cache's algorithm
     * creates preliminary an entity and inserts it there.
     * So, an earlier created type variable exists while the cache's algorithm has pointer[s] of it
     * within the cache (entity has not removed yet during cleanings)
     * or user's java code keeps pointer[s] of this type variable.
     */

      private static class TVSSynchro {
      };

      private static int cacheLenght = 2048;
      private static String cache[] = new String[cacheLenght];
      private static WildcardType cache2[] = new WildcardType[cacheLenght];
      private static InterimWildcardType cache3[] = new InterimWildcardType[cacheLenght];
      private static Object cache4[] = new Object[cacheLenght];
      private static int counter = 0;
      private static int worth[] = new int[cacheLenght];

      /**
       *   To delete the worst entry.
       */
      static int deleteWildcardType() {
        int min = -1;
        int min2 = -1;

        synchronized (TVSSynchro.class) {
          float minWorth = ((worth[0] >> 16) > 0 ? (worth[0] & 0xFFFF) / worth[0] >> 16 : worth[0]);
          int minWorth2 = worth[0];
          float tmp;
          int i = 0;
          for (; i < cacheLenght; i++) {
            try {
              if ((tmp = (worth[i] & 0xFFFF) / worth[i] >> 16) <= minWorth) {
                min = i;
                minWorth = tmp;
              }
            } catch (ArithmeticException _) {
              if ((tmp = worth[i]) <= minWorth2) {
                min2 = i;
                minWorth2 = (int) tmp;
              }
            }
          }
          if (i == cacheLenght && min == -1) {
            min = min2;
          }
          cache[min] = null;
          cache2[min] = null;
          cache3[min] = null;
          cache4[min] = null;
          worth[min] = 0;
        }
        return min;
      }

      /**
       *  To create new cache entry
       */
      static int insertWildcardType(WildcardType wildcardType, InterimWildcardType prsrdWildcardType, String signature, Object startPoint, int ip) {
        synchronized (TVSSynchro.class) {
          if (ip < 0) {
            for (int ind = 0; ind < cacheLenght ; ind++) {
              if (null == cache[ind]) {
                cache[ind] = signature;
                cache2[ind] = wildcardType;
                cache3[ind] = prsrdWildcardType;
                cache4[ind] = startPoint;
                worth[ind] = 1;
                return ind;
              }
            }
            return insertWildcardType(wildcardType, prsrdWildcardType, signature, startPoint, deleteWildcardType());
          } else {
            cache[ip] = signature;
            cache2[ip] = wildcardType;
            cache3[ip] = prsrdWildcardType;
            cache4[ip] = startPoint;

            boolean flg = false;
            short sv = (short) (worth[ip] & 0xFFFF);
            if (sv == Short.MAX_VALUE - 1){
              flg = true; // to reduce
            }
            worth[ip] = (sv + 1) | (worth[ip] & 0xFFFF0000);
            if (flg) {
              try {
                for (int ind = 0; ind < cacheLenght ; ind++) { // reducing
                  short sv1 = (short) (worth[ind] >> 16);
                  short sv2 = (short) (worth[ind] & 0xFFFF);
                  worth[ind] = (sv2 == 1 ? 1 : sv2 >> 2) | (((sv1 == 1 ? 1 : sv1 >> 2) + 1) << 16);
                }
              } catch (NullPointerException _) {
              }
            }
          }
        }
        return ip;
      }

      /**
       *  To return WildcardType of cache.
       */
      static WildcardType valueWildcardType(InterimWildcardType wildcard, String signature, Object startPoint) {
        synchronized (TVSSynchro.class) {
          boolean flg = false;
          if (counter == cacheLenght) { // Do smoke, it's time for reordering
            try {
              for (int ind = 0; ind < cacheLenght ; ind++) {
                short sv1 = (short) (worth[ind] >> 16);
                if (sv1 == Short.MAX_VALUE - 1){
                  flg = true; // to reduce
                }
                worth[ind] = worth[ind] & 0xFFFF | ((sv1 + 1) << 16);
              }
            } catch(NullPointerException _) {
            }
            if (flg) {
              try {
                for (int ind = 0; ind < cacheLenght ; ind++) { // reducing
                  short sv1 = (short) (worth[ind] >> 16);
                  short sv2 = (short) (worth[ind] & 0xFFFF);
                  worth[ind] = (sv2 == 1 ? 1 : sv2 >> 2) | (((sv1 == 1 ? 1 : sv1 >> 2) + 1) << 16);
                }
              } catch (NullPointerException _) {
              }
            }
            counter = 0;
          } else {
            counter++;
          }
        }
        try {
          for (int ind = 0; ind < cacheLenght ; ind++) {
            if (signature.equals(cache[ind]) && areWCEqual(cache3[ind], cache4[ind], wildcard, startPoint)) {
              return cache2[ind];
            }
          }
        } catch (NullPointerException _) {
        }
        return null;
      }
    }
  
    /**
     * This method provides the comparing of two InterimWildcardType entities.
     * 
     * @param wildcard1 a InterimWildcardType entity.
     * @param startPoint1 a generic declaration which the seeking of any type variable definition used within wildcard1 should be started from.
     * @param wildcard2 another InterimWildcardType entity.
     * @param startPoint2 a generic declaration which the seeking of any type variable definition used within wildcard2 should be started from.
     */
  static boolean areWCEqual(InterimWildcardType wildcard1, Object startPoint1, InterimWildcardType wildcard2, Object startPoint2) {
    // Remember that the signatures for being compared InterimWildcardType-s are equal!
    
    // So, we need to compare only the rests:
    InterimType bounds1[] = wildcard1.bounds;
    InterimType bounds2[] = wildcard2.bounds;
    for (int i = 0; i < bounds1.length; i++) {
      if (bounds1[i] instanceof InterimTypeVariable && !ParameterizedTypeRepository.areTVEqual((InterimTypeVariable)bounds1[i], startPoint1, (InterimTypeVariable)bounds2[i], startPoint2)) {
        return false;
      } else if (bounds1[i] instanceof InterimParameterizedType && !ParameterizedTypeRepository.arePTEqual((InterimParameterizedType)bounds1[i], startPoint1, (InterimParameterizedType)bounds1[i], startPoint2)) {
        return false;
      }
    }
    return true;
  }
  
    /**
     * This method returns a registered type variable if it exists within the repository.
     * 
     * @param WildcardTypeName a name of a type variable.
     * @param startPoint an instance of the Class, Method, Constructor or Field type to start the search
     *        of a type variable declaration place.
     * @return the found type variable or null if it does not exist within repository.
     */
  public static WildcardType findWildcardType(InterimWildcardType wildcard, String signature, Object startPoint) {
    return WildcardTypeCache.valueWildcardType(wildcard, signature, startPoint);
  }
  
    /**
     * This method returns a registered type variable if it exists within the repository.
     * 
     * @param WildcardTypeName a name of a type variable.
     * @param startPoint an instance of the Class, Method, Constructor or Field type to start the search
     *        of a type variable declaration place.
     * @return the found type variable or null if it does not exist within repository.
     */
  public static String recoverWildcardSignature(InterimWildcardType wildcard) {
    String res = "";
    res = res+(wildcard.boundsType == true ? "+" : "-");
    if (wildcard.bounds[0] instanceof InterimParameterizedType) {
      res = res+((InterimParameterizedType)wildcard.bounds[0]).signature;
    } else if (wildcard.bounds[0] instanceof InterimTypeVariable) {
      res = res+((InterimTypeVariable) wildcard.bounds[0]).typeVariableName;
    } else { //ClassType
      res = res+((InterimClassType) wildcard.bounds[0]).classTypeName;
    }
    return res;
  }
  
    /**
     * This method registers a type variable within the repository.
     * 
     * @param WildcardType a type variable.
     * @param WildcardTypeName a name of a type variable.
     * @param startPoint an instance of the Class, Method, Constructor or Field type to start the search
     *        of a type variable declaration place.
     */
  public static void registerWildcardType(WildcardType wildcard, InterimWildcardType prsrdWildcardType, String signature, Object startPoint) {
    WildcardTypeCache.insertWildcardType(wildcard, prsrdWildcardType, signature, startPoint, -1);    
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.