View Javadoc

1   /***
2    *  Copyright 2003-2010 Terracotta, Inc.
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   */
16  
17  package net.sf.ehcache.pool.impl;
18  
19  import java.util.concurrent.atomic.AtomicLong;
20  
21  import net.sf.ehcache.pool.Pool;
22  import net.sf.ehcache.pool.PoolableStore;
23  import net.sf.ehcache.pool.SizeOfEngine;
24  
25  /***
26   * The PoolAccessor class of the BoundedPool
27   *
28   * @author Chris Dennis
29   * @author Ludovic Orban
30   */
31  final class AtomicPoolAccessor extends AbstractPoolAccessor<PoolableStore> {
32  
33      private final SizeOfEngine sizeOfEngine;
34      private final AtomicLong size;
35  
36      /***
37       * Creates an atomic pool accessor with the specified properties.
38       *
39       * @param pool pool to be accessed
40       * @param store accessing store
41       * @param sizeOfEngine engine used to size objects
42       * @param currentSize initial size of the store
43       */
44      AtomicPoolAccessor(Pool<PoolableStore> pool, PoolableStore store, SizeOfEngine sizeOfEngine, long currentSize) {
45          super(pool, store);
46          this.sizeOfEngine = sizeOfEngine;
47          this.size = new AtomicLong(currentSize);
48      }
49  
50      /***
51       * {@inheritDoc}
52       */
53      public long add(Object key, Object value, Object container, boolean force) {
54          checkLinked();
55  
56          long sizeOf = sizeOfEngine.sizeOf(key, value, container);
57  
58          long newSize = getPool().getSize() + sizeOf;
59  
60          if (newSize <= getPool().getMaxSize()) {
61              // there is enough room => add & approve
62              size.addAndGet(sizeOf);
63              return sizeOf;
64          } else {
65              // check that the element isn't too big
66              if (!force && sizeOf > getPool().getMaxSize()) {
67                  // this is too big to fit in the pool
68                  return -1;
69              }
70  
71              // if there is not enough room => evict
72              long missingSize = newSize - getPool().getMaxSize();
73  
74              if (getPool().getEvictor().freeSpace(getPool().getPoolableStores(), missingSize) || force) {
75                  size.addAndGet(sizeOf);
76                  return sizeOf;
77              } else {
78                  // cannot free enough bytes
79                  return -1;
80              }
81          }
82      }
83  
84      /***
85       * {@inheritDoc}
86       */
87      public boolean canAddWithoutEvicting(Object key, Object value, Object container) {
88          long sizeOf = sizeOfEngine.sizeOf(key, value, container);
89  
90          long newSize = getPool().getSize() + sizeOf;
91          return newSize <= getPool().getMaxSize();
92      }
93  
94      /***
95       * {@inheritDoc}
96       */
97      public long delete(Object key, Object value, Object container) {
98          checkLinked();
99  
100         long sizeOf = sizeOfEngine.sizeOf(key, value, container);
101 
102         size.addAndGet(-sizeOf);
103 
104         return sizeOf;
105     }
106 
107     /***
108      * {@inheritDoc}
109      */
110     public long getSize() {
111         return size.get();
112     }
113 
114     /***
115      * {@inheritDoc}
116      */
117     public void clear() {
118         size.set(0);
119     }
120 }