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.store;
18  
19  import net.sf.ehcache.CacheException;
20  import net.sf.ehcache.Ehcache;
21  import net.sf.ehcache.distribution.RemoteCacheException;
22  import org.slf4j.Logger;
23  import org.slf4j.LoggerFactory;
24  
25  import java.util.Iterator;
26  
27  /***
28   * @author Alex Snaps
29   */
30  public class DiskStoreBootstrapCacheLoader extends MemoryLimitedCacheLoader {
31  
32      private static final Logger LOG = LoggerFactory.getLogger(DiskStoreBootstrapCacheLoader.class);
33  
34      private final boolean asynchronous;
35      private final long delay;
36      private volatile boolean doneLoading;
37      private volatile int loadedElements;
38  
39      /***
40       * Constructor for testing purposes
41       * Will delay before starting the asynchronous load process
42       * @param delay in milliseconds
43       */
44      DiskStoreBootstrapCacheLoader(final long delay) {
45          asynchronous = true;
46          this.delay = delay;
47      }
48  
49      /***
50       * Constructor for loader
51       * @param asynchronous whether load is asynchronous or synchronous
52       */
53      public DiskStoreBootstrapCacheLoader(final boolean asynchronous) {
54          this.asynchronous = asynchronous;
55          delay = 0;
56      }
57  
58      /***
59       * {@inheritDoc}
60       */
61      public void load(final Ehcache cache) throws CacheException {
62          if (cache.getCacheConfiguration().isDiskPersistent()) {
63              if (asynchronous) {
64                  BootstrapThread thread = new BootstrapThread(cache);
65                  thread.start();
66              } else {
67                  doLoad(cache);
68              }
69          } else {
70              LOG.warn("Cache '" + cache.getName() + "' isn't disk persistent, nothing to laod from!");
71          }
72      }
73  
74      private void doLoad(Ehcache cache) {
75          loadedElements = 0;
76          try {
77              final Iterator iterator = cache.getKeys().iterator();
78              while (iterator.hasNext() && !isInMemoryLimitReached(cache, loadedElements)) {
79                  if (cache.get(iterator.next()) != null) {
80                      ++loadedElements;
81                  }
82              }
83          } finally {
84              doneLoading = true;
85          }
86          LOG.debug("Loaded {} elements from disk into heap for cache {}", loadedElements, cache.getName());
87      }
88  
89      /***
90       * {@inheritDoc}
91       */
92      public boolean isAsynchronous() {
93          return asynchronous;
94      }
95  
96      /***
97       * Checks whether we're done loading yet
98       * @return true if done, false if still loading
99       */
100     boolean isDoneLoading() {
101         return doneLoading;
102     }
103 
104     /***
105      * Amount of elements loaded by the instance
106      * @return elements loaded
107      */
108     int getLoadedElements() {
109         return loadedElements;
110     }
111 
112     /***
113      * {@inheritDoc}
114      */
115     @Override
116     public Object clone() throws CloneNotSupportedException {
117         return super.clone();
118     }
119 
120     /***
121      * A background daemon thread that asynchronously calls doLoad
122      */
123     private final class BootstrapThread extends Thread {
124         private Ehcache cache;
125 
126         public BootstrapThread(Ehcache cache) {
127             super("Bootstrap Thread for cache " + cache.getName());
128             this.cache = cache;
129             setDaemon(true);
130             setPriority(Thread.NORM_PRIORITY);
131         }
132 
133         /***
134          * RemoteDebugger thread method.
135          */
136         public final void run() {
137             try {
138                 sleep(delay);
139                 try {
140                     doLoad(cache);
141                 } catch (RemoteCacheException e) {
142                     LOG.warn("Error asynchronously performing bootstrap. The cause was: " + e.getMessage(), e);
143                 }
144             } catch (InterruptedException e) {
145                 interrupted();
146             } finally {
147                 cache = null;
148             }
149         }
150     }
151 }