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.AtomicBoolean;
20  
21  import net.sf.ehcache.pool.Pool;
22  import net.sf.ehcache.pool.PoolAccessor;
23  import net.sf.ehcache.pool.Role;
24  
25  /***
26   * Abstract PoolAccessor implementation providing pool to store binding functionality.
27   *
28   * @author Chris Dennis
29   *
30   * @param <T> accessing store type
31   */
32  public abstract class AbstractPoolAccessor<T> implements PoolAccessor<T> {
33  
34      private final AtomicBoolean unlinked = new AtomicBoolean();
35      private final Pool<T> pool;
36      private final T store;
37  
38      /***
39       * Creates an accessor for the specified store to access the specified pool.
40       *
41       * @param pool pool to be accessed
42       * @param store accessing store
43       */
44      public AbstractPoolAccessor(Pool<T> pool, T store) {
45          this.pool = pool;
46          this.store = store;
47      }
48  
49      /***
50       * {@inheritDoc}
51       */
52      public long replace(Role role, Object current, Object replacement, boolean force) {
53          checkLinked();
54  
55          long addedSize;
56          long sizeOf = 0;
57          switch (role) {
58              case CONTAINER:
59                  sizeOf += delete(null, null, current);
60                  addedSize = add(null, null, replacement, force);
61                  if (addedSize < 0) {
62                      add(null, null, current, false);
63                      sizeOf = Long.MAX_VALUE;
64                  } else {
65                      sizeOf -= addedSize;
66                  }
67                  break;
68              case KEY:
69                  sizeOf += delete(current, null, null);
70                  addedSize = add(replacement, null, null, force);
71                  if (addedSize < 0) {
72                      add(current, null, null, false);
73                      sizeOf = Long.MAX_VALUE;
74                  } else {
75                      sizeOf -= addedSize;
76                  }
77                  break;
78              case VALUE:
79                  sizeOf += delete(null, current, null);
80                  addedSize = add(null, replacement, null, force);
81                  if (addedSize < 0) {
82                      add(null, current, null, false);
83                      sizeOf = Long.MAX_VALUE;
84                  } else {
85                      sizeOf -= addedSize;
86                  }
87                  break;
88              default:
89                  throw new IllegalArgumentException();
90          }
91          return sizeOf;
92      }
93  
94      /***
95       * {@inheritDoc}
96       */
97      public final void unlink() {
98          if (unlinked.compareAndSet(false, true)) {
99              getPool().removePoolAccessor(this);
100         }
101     }
102 
103     /***
104      * {@inheritDoc}
105      */
106     public final T getStore() {
107         return store;
108     }
109 
110     /***
111      * Throws {@code IllegalStateException} if this accessor is not linked to it's pool.
112      *
113      * @throws IllegalStateException if not linked
114      */
115     protected final void checkLinked() throws IllegalStateException {
116         if (unlinked.get()) {
117             throw new IllegalStateException("BoundedPoolAccessor has been unlinked");
118         }
119     }
120 
121     /***
122      * Return the pool this accessor is associated with.
123      *
124      * @return associated pool
125      */
126     protected final Pool<T> getPool() {
127         return pool;
128     }
129 }