Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / MyDerby-10.3 / java / engine / org / apache / derby / iapi / services / cache / ClassSize.java
diff --git a/JMCR-Stable/real-world application/MyDerby-10.3/java/engine/org/apache/derby/iapi/services/cache/ClassSize.java b/JMCR-Stable/real-world application/MyDerby-10.3/java/engine/org/apache/derby/iapi/services/cache/ClassSize.java
new file mode 100644 (file)
index 0000000..1e41d85
--- /dev/null
@@ -0,0 +1,300 @@
+/*\r
+\r
+   Derby - Class org.apache.derby.iapi.services.cache.ClassSize\r
+\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to you under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+      http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+\r
+ */\r
+\r
+package org.apache.derby.iapi.services.cache;\r
+\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+\r
+import java.lang.Class;\r
+import java.lang.reflect.Field;\r
+import java.lang.Runtime;\r
+import java.lang.InterruptedException;\r
+import java.lang.reflect.Modifier;\r
+\r
+public class ClassSize\r
+{\r
+    public static final int refSize;\r
+    private static final int objectOverhead = 2; // references, not bytes!\r
+    private static final int booleanSize = 4;\r
+    private static final int charSize = 4; // Unicode\r
+    private static final int shortSize = 4;\r
+    private static final int intSize = 4;\r
+    private static final int longSize = 8;\r
+    private static final int floatSize = 4;\r
+    private static final int doubleSize = 8;\r
+    private static final int minObjectSize;\r
+\r
+    private static boolean dummyCatalog = false; // Used when constructing the catalog to prevent recursion\r
+\r
+    static boolean noGuess = false;\r
+    // noGuess is used in unit testing.\r
+\r
+    static boolean unitTest = false;\r
+    // unitTest is used in unit testing\r
+\r
+    private static final int[] wildGuess = {0,16};\r
+    /* The standard wild guess of the size of an unknown class, the size of 16 references.\r
+     * Used when the security manager will not let us look at the class fields.\r
+     */\r
+\r
+    /* Do not let the compiler see ClassSizeCatalog. Otherwise it will try to\r
+     * compile it. This may fail because ClassSizeCatalog.java is not created\r
+     * until everything else has been compiled. Bury ClassSizeCatalog in a string.\r
+     */\r
+    private static java.util.Hashtable catalog;\r
+    static\r
+    {\r
+        try\r
+        {\r
+            catalog = (java.util.Hashtable)\r
+              Class.forName( "org.apache.derby.iapi.services.cache.ClassSizeCatalog").newInstance();\r
+            //Added by Jeff Huang\r
+            catalog = new org.apache.derby.iapi.services.cache.ClassSizeCatalog();\r
+        }\r
+        catch( Exception e){};\r
+\r
+        // Figure out whether this is a 32 or 64 bit machine.\r
+        Runtime runtime = Runtime.getRuntime();\r
+        long memBase = runtime.totalMemory() - runtime.freeMemory();\r
+        Object[] junk = new Object[10000];\r
+        long memUsed = runtime.totalMemory() - runtime.freeMemory() - memBase;\r
+        int sz = (int)((memUsed + junk.length/2)/junk.length);\r
+        refSize = ( 4 > sz) ? 4 : sz;\r
+        minObjectSize = 4*refSize;\r
+    }\r
+\r
+    /**\r
+     * do not try to use the catalog.\r
+     */\r
+    public static void setDummyCatalog()\r
+    {\r
+        dummyCatalog = true;\r
+    }\r
+    /**\r
+     * Get the estimate of the size of an object reference.\r
+     *\r
+     * @return the estimate in bytes.\r
+     */\r
+    public static int getRefSize()\r
+    {\r
+        return refSize;\r
+    }\r
+\r
+    /**\r
+     * @return the estimate of the size of a primitive int\r
+     */\r
+    public static int getIntSize()\r
+    {\r
+        return intSize;\r
+    }\r
+\r
+    /**\r
+     * The estimate of the size of a class instance depends on whether the JVM uses 32 or 64\r
+     * bit addresses, that is it depends on the size of an object reference. It is a linear\r
+     * function of the size of a reference, e.g.\r
+     *    24 + 5*r\r
+     * where r is the size of a reference (usually 4 or 8 bytes).\r
+     *\r
+     * This method returns the coefficients of the linear function, e.g. {24, 5} in the above\r
+     * example.\r
+     *\r
+     * @param cl A class whose instance size is to be estimated\r
+     * @return an array of 2 integers. The first integer is the constant part of the function,\r
+     *         the second is the reference size coefficient.\r
+     */\r
+    public static int[] getSizeCoefficients( Class cl)\r
+    {\r
+        int[] coeff = {0, objectOverhead};\r
+\r
+\r
+        \r
+        for( ; null != cl; cl = cl.getSuperclass())\r
+        {\r
+           Field[] field = cl.getDeclaredFields();\r
+            if( null != field)\r
+            {\r
+                for( int i = 0; i < field.length; i++)\r
+                {\r
+                    if( ! Modifier.isStatic( field[i].getModifiers()))\r
+                    {\r
+                        Class fieldClass = field[i].getType();\r
+                        if( fieldClass.isArray() || ! fieldClass.isPrimitive())\r
+                            coeff[1]++;\r
+                        else // Is simple primitive\r
+                        {\r
+                            String name = fieldClass.getName();\r
+\r
+                            if( name.equals( "int") || name.equals( "I"))\r
+                                coeff[0] += intSize;\r
+                            else if( name.equals( "long") || name.equals( "J"))\r
+                                coeff[0] += longSize;\r
+                            else if( name.equals( "boolean") || name.equals( "Z"))\r
+                                coeff[0] += booleanSize;\r
+                            else if( name.equals( "short") || name.equals( "S"))\r
+                                coeff[0] += shortSize;\r
+                            else if( name.equals( "byte") || name.equals( "B"))\r
+                                coeff[0] += 1;\r
+                            else if( name.equals( "char") || name.equals( "C"))\r
+                                coeff[0] += charSize;\r
+                            else if( name.equals( "float") || name.equals( "F"))\r
+                                coeff[0] += floatSize;\r
+                            else if( name.equals( "double") || name.equals( "D"))\r
+                                coeff[0] += doubleSize;\r
+                            else // What is this??\r
+                                coeff[1]++; // Make a guess: one reference (?)\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        return coeff;\r
+    } // end of getSizeCoefficients\r
+\r
+    /**\r
+     * Estimate the static space taken up by a class instance given the coefficients\r
+     * returned by getSizeCoefficients.\r
+     *\r
+     * @param coeff the coefficients\r
+     *\r
+     * @return the size estimate, in bytes\r
+     */\r
+    public static int estimateBaseFromCoefficients( int[] coeff)\r
+    {\r
+        int size = coeff[0] + coeff[1]*refSize;\r
+        // Round up to a multiple of 8\r
+        size = (size + 7)/8;\r
+        size *= 8;\r
+        return (size < minObjectSize) ? minObjectSize : size;\r
+    } // end of estimateBaseFromCoefficients\r
+\r
+    /**\r
+     * Estimate the static space taken up by a class instance from cataloged coefficients.\r
+     *\r
+     * @param cls the class\r
+     *\r
+     * @return the size estimate, in bytes\r
+     *\r
+     * @see #estimateBaseFromCoefficients\r
+     * @see #getSizeCoefficients\r
+     * see org.apache.derbyBuild.ClassSizeCrawler\r
+     */\r
+    public static int estimateBaseFromCatalog( Class cls)\r
+    {\r
+        return estimateBaseFromCatalog( cls, false);\r
+    }\r
+    \r
+    private static int estimateBaseFromCatalog( Class cls, boolean addToCatalog)\r
+    {\r
+        if( dummyCatalog)\r
+            return 0;\r
+        \r
+        if( SanityManager.DEBUG)\r
+                       SanityManager.ASSERT( catalog != null, "The class size catalog could not be initialized.");\r
+        \r
+        int[] coeff = (int[]) catalog.get( cls.getName());\r
+        if( coeff == null)\r
+        {\r
+            try\r
+            {\r
+                coeff = getSizeCoefficients( cls);\r
+            }\r
+            catch( Throwable t)\r
+            {\r
+                if( noGuess)\r
+                    return -2;\r
+                coeff = wildGuess;\r
+            }\r
+            if( addToCatalog)\r
+                catalog.put( cls.getName(), coeff);\r
+        }\r
+        return estimateBaseFromCoefficients( coeff);\r
+    } // end of estimateBaseFromCatalog\r
+\r
+\r
+    /**\r
+     * Estimate the static space taken up by a class instance. Save the coefficients\r
+     * in a catalog.\r
+     *\r
+     * @param cls the class\r
+     *\r
+     * @return the size estimate, in bytes\r
+     *\r
+     * @see #estimateBaseFromCoefficients\r
+     * @see #getSizeCoefficients\r
+     * see org.apache.derbyBuild.ClassSizeCrawler\r
+     */\r
+    public static int estimateAndCatalogBase( Class cls)\r
+    {\r
+        return estimateBaseFromCatalog( cls, true);\r
+    } // end of estimateAndCatalogBase\r
+\r
+    /**\r
+     * Estimate the static space taken up by the fields of a class. This includes the space taken\r
+     * up by by references (the pointer) but not by the referenced object. So the estimated\r
+     * size of an array field does not depend on the size of the array. Similarly the size of\r
+     * an object (reference) field does not depend on the object.\r
+     *\r
+     * @return the size estimate in bytes.\r
+     *\r
+     * Note that this method will throw a SecurityException if the SecurityManager does not\r
+     * let this class execute the method Class.getDeclaredFields(). If this is a concern try\r
+     * to compute the size coefficients at build time.\r
+     * see org.apache.derbyBuild.ClassSizeCrawler\r
+     * @see #estimateBaseFromCatalog\r
+     */\r
+    public static int estimateBase( Class cl)\r
+    {\r
+        return estimateBaseFromCoefficients( getSizeCoefficients( cl));\r
+    } // End of estimateBase\r
+\r
+    /**\r
+     * @return the estimated overhead of an array. The estimated size of an x[n] array is\r
+     * estimateArrayOverhead() + n*sizeOf(x).\r
+     */\r
+    public static int estimateArrayOverhead()\r
+    {\r
+        return minObjectSize;\r
+    }\r
+    \r
+    /**\r
+     * Estimate the size of a Hashtable entry. In Java 1.2 we can use Map.entry, but this is not\r
+     * available in earlier versions of Java.\r
+     *\r
+     * @return the estimate, in bytes\r
+     */\r
+    public static int estimateHashEntrySize()\r
+    {\r
+        return objectOverhead + 3*refSize;\r
+    }\r
+\r
+    /**\r
+     * Estimate the size of a string.\r
+     *\r
+     * @return the estimated size, in bytes\r
+     */\r
+    public static int estimateMemoryUsage( String str)\r
+    {\r
+        if( null == str)\r
+            return 0;\r
+        // Since Java uses Unicode assume that each character takes 2 bytes\r
+        return 2*str.length();\r
+    }\r
+}\r