/** * Check the cache for the current URL, and load it if it is valid. * * @param headers for the request * @return true if cached response is used. */ boolean checkCache(Map<String, String> headers) { // Get the cache file name for the current URL CacheResult result = CacheManager.getCacheFile(url(), headers); if (result != null) { CacheLoader cacheLoader = new CacheLoader(this, result); // If I got a cachedUrl and the revalidation header was not // added, then the cached content valid, we should use it. if (!headers.containsKey(CacheManager.HEADER_KEY_IFNONEMATCH) && !headers.containsKey(CacheManager.HEADER_KEY_IFMODIFIEDSINCE)) { if (Config.LOGV) { Log.v(LOGTAG, "FrameLoader: HTTP URL in cache " + "and usable: " + url()); } // Load the cached file cacheLoader.load(); return true; } else { // The contents of the cache need to be revalidated // so just provide the listener with the cache loader // in the case that the server response positively to // the cached content. setCacheLoader(cacheLoader); } } return false; }
/* * This function is used by handleUrlInterecpt and handleCache to * setup a load from the byte stream in a CacheResult. */ private void startCacheLoad(CacheResult result) { if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "FrameLoader: loading from cache: " + mListener.url()); } // Tell the Listener respond with the cache file CacheLoader cacheLoader = new CacheLoader(mListener, result); mListener.setCacheLoader(cacheLoader); cacheLoader.load(); }
public void testEvictBeforeRead() throws CacheLoaderException, ExecutionException, InterruptedException { cache = cacheManager.getCache(); cache.put("a", "b"); assert cache.get("a").equals("b"); CacheLoader cl = TestingUtil.getCacheLoader(cache); assert cl != null; InternalCacheEntry se = cl.load("a"); assert se != null; assert se.getValue().equals("b"); // clear the cache cache.getAdvancedCache().withFlags(SKIP_CACHE_STORE).clear(); se = cl.load("a"); assert se != null; assert se.getValue().equals("b"); // now attempt a concurrent get and evict. ExecutorService e = Executors.newFixedThreadPool(1); sdi.enabled = true; log.info("test::doing the get"); // call the get Future<String> future = e.submit( new Callable<String>() { public String call() throws Exception { return (String) cache.get("a"); } }); // now run the evict. log.info("test::before the evict"); cache.evict("a"); log.info("test::after the evict"); // make sure the get call, which would have gone past the cache loader interceptor first, gets // the correct value. assert future.get().equals("b"); // disable the SlowDownInterceptor sdi.enabled = false; // and check that the key actually has been evicted assert !TestingUtil.extractComponent(cache, DataContainer.class).containsKey("a"); e.shutdownNow(); }
private synchronized void load( final K key, final boolean synchronizeAccess, final boolean lockAccess) { ReentrantLock lock = null; try { synchronized (this) { if (lockAccess) { lock = lock(key); } } if (synchronizeAccess) { put(key, cacheLoader.get(key)); } else { executorService.submit( new Callable<Object>() { public Object call() throws Exception { load(key, true, true); return null; } }); } } finally { if (lock != null) { lock.unlock(); } } }
@Test public void testParallelShutdown() throws Exception { final CacheManager manager = new CacheManager( new Configuration() .name("testEqualsDriver") .cache( new CacheConfiguration() .name("parallel") .maxBytesLocalHeap(64, MemoryUnit.MEGABYTES))); Cache parallel = manager.getCache("parallel"); CacheDriver loadParallel = CacheLoader.load(ehcache(parallel)) .using(StringGenerator.integers(), ByteArrayGenerator.fixedSize(128)) .sequentially() .untilFilled(); final CacheDriver driver = ParallelDriver.inParallel(4, loadParallel); await() .atMost(20, TimeUnit.SECONDS) .until( new Callable<Boolean>() { @Override public Boolean call() throws Exception { driver.run(); return true; } }); manager.shutdown(); }
@CheckForNull public V getNullable(K key) { V value = map.get(key); if (value == null && !map.containsKey(key)) { value = loader.load(key); map.put(key, value); } return value; }
@Test public void testParallelAndSequentialAreEquivalent() { CacheManager manager = new CacheManager( new Configuration() .name("testEqualsDriver") .cache( new CacheConfiguration() .name("sequential") .maxBytesLocalHeap(64, MemoryUnit.MEGABYTES)) .cache( new CacheConfiguration() .name("parallel") .maxBytesLocalHeap(64, MemoryUnit.MEGABYTES))); Cache sequential = manager.getCache("sequential"); Cache parallel = manager.getCache("parallel"); CacheDriver loadSequential = CacheLoader.load(ehcache(sequential)) .using(StringGenerator.integers(), ByteArrayGenerator.fixedSize(128)) .sequentially() .untilFilled(); SequentialDriver.inSequence(loadSequential).run(); long seqHeapSize = sequential.getStatistics().getLocalHeapSize(); long seqOffHeapSize = sequential.getStatistics().getLocalOffHeapSize(); long seqDiskSize = sequential.getStatistics().getLocalDiskSize(); CacheDriver loadParallel = CacheLoader.load(ehcache(parallel)) .using(StringGenerator.integers(), ByteArrayGenerator.fixedSize(128)) .sequentially() .untilFilled(); ParallelDriver.inParallel(4, loadParallel).run(); long parHeapSize = parallel.getStatistics().getLocalHeapSize(); long parOffHeapSize = parallel.getStatistics().getLocalOffHeapSize(); long parDiskSize = parallel.getStatistics().getLocalDiskSize(); Assert.assertEquals(seqHeapSize, parHeapSize); Assert.assertEquals(seqOffHeapSize, parOffHeapSize); Assert.assertEquals(seqDiskSize, parDiskSize); manager.shutdown(); }
/** * Get values associated with keys. All the requested keys are included in the Map result. Value * is null if the key is not found in cache. */ public Map<K, V> getAll(Iterable<K> keys) { List<K> missingKeys = new ArrayList<>(); Map<K, V> result = new HashMap<>(); for (K key : keys) { V value = map.get(key); if (value == null && !map.containsKey(key)) { missingKeys.add(key); } else { result.put(key, value); } } if (!missingKeys.isEmpty()) { Map<K, V> missingValues = loader.loadAll(missingKeys); map.putAll(missingValues); result.putAll(missingValues); for (K missingKey : missingKeys) { if (!map.containsKey(missingKey)) { map.put(missingKey, null); result.put(missingKey, null); } } } return result; }
/** * Event handler's endData call. Send a message to the handler notifying them that the data has * finished. IMPORTANT: as this is called from network thread, can't call native directly */ public void endData() { if (Config.LOGV) { Log.v(LOGTAG, "LoadListener.endData(): url: " + url()); } if (mCancelled) return; switch (mStatusCode) { case HTTP_MOVED_PERMANENTLY: // 301 - permanent redirect mPermanent = true; case HTTP_FOUND: case HTTP_SEE_OTHER: case HTTP_TEMPORARY_REDIRECT: if (mMethod == null && mRequestHandle == null) { Log.e(LOGTAG, "LoadListener.endData(): method is null!"); Log.e(LOGTAG, "LoadListener.endData(): url = " + url()); } // 301, 302, 303, and 307 - redirect if (mStatusCode == HTTP_TEMPORARY_REDIRECT) { if (mRequestHandle != null && mRequestHandle.getMethod().equals("POST")) { sendMessageInternal(obtainMessage(MSG_LOCATION_CHANGED_REQUEST)); } else if (mMethod != null && mMethod.equals("POST")) { sendMessageInternal(obtainMessage(MSG_LOCATION_CHANGED_REQUEST)); } else { sendMessageInternal(obtainMessage(MSG_LOCATION_CHANGED)); } } else { sendMessageInternal(obtainMessage(MSG_LOCATION_CHANGED)); } return; case HTTP_AUTH: case HTTP_PROXY_AUTH: // According to rfc2616, the response for HTTP_AUTH must include // WWW-Authenticate header field and the response for // HTTP_PROXY_AUTH must include Proxy-Authenticate header field. if (mAuthHeader != null && (Network.getInstance(mContext).isValidProxySet() || !mAuthHeader.isProxy())) { Network.getInstance(mContext).handleAuthRequest(this); return; } break; // use default case HTTP_NOT_MODIFIED: // Server could send back NOT_MODIFIED even if we didn't // ask for it, so make sure we have a valid CacheLoader // before calling it. if (mCacheLoader != null) { detachRequestHandle(); mCacheLoader.load(); if (Config.LOGV) { Log.v(LOGTAG, "LoadListener cache load url=" + url()); } return; } break; // use default case HTTP_NOT_FOUND: // Not an error, the server can send back content. default: break; } sendMessageInternal(obtainMessage(MSG_CONTENT_FINISHED)); detachRequestHandle(); }