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.ArrayList;
20 import java.util.Collection;
21 import java.util.Collections;
22 import java.util.Iterator;
23 import java.util.List;
24
25 import net.sf.ehcache.pool.Pool;
26 import net.sf.ehcache.pool.PoolAccessor;
27 import net.sf.ehcache.pool.PoolEvictor;
28 import net.sf.ehcache.pool.SizeOfEngine;
29
30 /***
31 * An abstract pool implementation.
32 * <p>
33 * This contains all the logic of a pool except for the actual creation of accessor instances.
34 *
35 * @author Chris Dennis
36 *
37 * @param <T> the pool store type
38 */
39 public abstract class AbstractPool<T> implements Pool<T> {
40
41 private volatile long maximumPoolSize;
42 private final PoolEvictor<T> evictor;
43 private final List<PoolAccessor<? extends T>> poolAccessors;
44 private final SizeOfEngine defaultSizeOfEngine;
45
46 /***
47 * Create an AbstractPool instance
48 *
49 * @param maximumPoolSize the maximum size of the pool, in bytes.
50 * @param evictor the pool evictor, for cross-store eviction.
51 * @param defaultSizeOfEngine the default SizeOf engine used by the accessors.
52 */
53 public AbstractPool(long maximumPoolSize, PoolEvictor<T> evictor, SizeOfEngine defaultSizeOfEngine) {
54 this.maximumPoolSize = maximumPoolSize;
55 this.evictor = evictor;
56 this.defaultSizeOfEngine = defaultSizeOfEngine;
57 this.poolAccessors = Collections.synchronizedList(new ArrayList<PoolAccessor<? extends T>>());
58 }
59
60 /***
61 * {@inheritDoc}
62 */
63 public long getSize() {
64 long total = 0L;
65 for (PoolAccessor poolAccessor : poolAccessors) {
66 total += poolAccessor.getSize();
67 }
68 return total;
69 }
70
71 /***
72 * {@inheritDoc}
73 */
74 public long getMaxSize() {
75 return maximumPoolSize;
76 }
77
78 /***
79 * {@inheritDoc}
80 */
81 public void setMaxSize(long newSize) {
82 long oldSize = this.maximumPoolSize;
83 this.maximumPoolSize = newSize;
84 long sizeToEvict = oldSize - newSize;
85
86 if (sizeToEvict > 0) {
87 evictor.freeSpace(getPoolableStores(), sizeToEvict);
88 }
89 }
90
91 /***
92 * {@inheritDoc}
93 */
94 public PoolAccessor<T> createPoolAccessor(T store) {
95 return createPoolAccessor(store, defaultSizeOfEngine);
96 }
97
98 /***
99 * {@inheritDoc}
100 */
101 public void registerPoolAccessor(PoolAccessor<? extends T> accessor) {
102 poolAccessors.add(accessor);
103 }
104
105 /***
106 * {@inheritDoc}
107 */
108 public void removePoolAccessor(PoolAccessor<?> accessor) {
109 Iterator<PoolAccessor<? extends T>> iterator = poolAccessors.iterator();
110 while (iterator.hasNext()) {
111 if (iterator.next() == accessor) {
112 iterator.remove();
113 return;
114 }
115 }
116 }
117
118 /***
119 * {@inheritDoc}
120 */
121 public Collection<T> getPoolableStores() {
122 Collection<T> poolableStores = new ArrayList<T>();
123 for (PoolAccessor<? extends T> poolAccessor : poolAccessors) {
124 poolableStores.add(poolAccessor.getStore());
125 }
126 return poolableStores;
127 }
128
129 /***
130 * {@inheritDoc}
131 */
132 public PoolEvictor<T> getEvictor() {
133 return evictor;
134 }
135
136 }