View Javadoc

1   package org.apache.commons.ognl.internal;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  /*
23   * $Id: ClassCacheImpl.java 1194946 2011-10-29 17:47:02Z mcucchiara $
24   */
25  
26  import org.apache.commons.ognl.ClassCacheInspector;
27  
28  import java.util.Arrays;
29  
30  /**
31   * Implementation of {@link ClassCache}.
32   */
33  public class ClassCacheImpl<V>
34      implements ClassCache<V>
35  {
36  
37      /* this MUST be a power of 2 */
38      private static final int TABLE_SIZE = 512;
39  
40      /* ...and now you see why. The table size is used as a mask for generating hashes */
41      private static final int TABLE_SIZE_MASK = TABLE_SIZE - 1;
42  
43      private Entry<Class<?>, V>[] table = new Entry[TABLE_SIZE];
44  
45      private ClassCacheInspector classInspector;
46  
47      private int size = 0;
48  
49      /**
50       * {@inheritDoc}
51       */
52      public void setClassInspector( ClassCacheInspector inspector )
53      {
54          classInspector = inspector;
55      }
56  
57      /**
58       * {@inheritDoc}
59       */
60      public void clear()
61      {
62          for ( int i = 0; i < table.length; i++ )
63          {
64              table[i] = null;
65          }
66  
67          size = 0;
68      }
69  
70      /**
71       * {@inheritDoc}
72       */
73      public int getSize()
74      {
75          return size;
76      }
77  
78      /**
79       * {@inheritDoc}
80       */
81      public final V get( Class<?> key )
82          throws CacheException
83      {
84          int i = key.hashCode() & TABLE_SIZE_MASK;
85  
86          Entry<Class<?>, V> entry = table[i];
87  
88          while ( entry != null )
89          {
90              if ( key == entry.getKey() )
91              {
92                  return entry.getValue();
93              }
94  
95              entry = entry.getNext();
96          }
97          return null;
98      }
99  
100     /**
101      * {@inheritDoc}
102      */
103     public final V put( Class<?> key, V value )
104     {
105         if ( classInspector != null && !classInspector.shouldCache( key ) )
106         {
107             return value;
108         }
109 
110         V result = null;
111         int i = key.hashCode() & TABLE_SIZE_MASK;
112 
113         Entry<Class<?>, V> entry = table[i];
114 
115         if ( entry == null )
116         {
117             table[i] = new Entry<Class<?>, V>( key, value );
118             size++;
119         }
120         else
121         {
122             if ( key == entry.getKey() )
123             {
124                 result = entry.getValue();
125                 entry.setValue( value );
126             }
127             else
128             {
129                 while ( true )
130                 {
131                     if ( key == entry.getKey() )
132                     {
133                         /* replace value */
134                         result = entry.getValue();
135                         entry.setValue( value );
136                         break;
137                     }
138 
139                     if ( entry.getNext() == null )
140                     {
141                         /* add value */
142                         entry.setNext( new Entry<Class<?>, V>( key, value ) );
143                         break;
144                     }
145 
146                     entry = entry.getNext();
147                 }
148             }
149         }
150 
151         return result;
152     }
153 
154     /**
155      * {@inheritDoc}
156      */
157     @Override
158     public String toString()
159     {
160         return "ClassCacheImpl[" + "_table=" + ( table == null ? null : Arrays.asList( table ) ) + '\n'
161             + ", _classInspector=" + classInspector + '\n' + ", _size=" + size + '\n' + ']';
162     }
163 
164 }