@Override public void process( KeyFilter<? super K> filter, final CacheLoaderTask<K, V> task, Executor executor, final boolean fetchValue, final boolean fetchMetadata) { filter = PersistenceUtil.notNull(filter); ArrayList<KeyValuePair<K, FileEntry>> keysToLoad = new ArrayList<>(entries.size()); synchronized (entries) { for (Map.Entry<K, FileEntry> e : entries.entrySet()) { if (filter.accept(e.getKey())) keysToLoad.add(new KeyValuePair<>(e.getKey(), e.getValue())); } Collections.sort( keysToLoad, new Comparator<KeyValuePair<K, FileEntry>>() { @Override public int compare(KeyValuePair<K, FileEntry> o1, KeyValuePair<K, FileEntry> o2) { long offset1 = o1.getValue().offset; long offset2 = o2.getValue().offset; return offset1 < offset2 ? -1 : offset1 == offset2 ? 0 : 1; } }); // keysToLoad values (i.e. FileEntries) must not be used past this point } ExecutorAllCompletionService eacs = new ExecutorAllCompletionService(executor); final TaskContextImpl taskContext = new TaskContextImpl(); for (KeyValuePair<K, FileEntry> e : keysToLoad) { if (taskContext.isStopped()) break; final K key = e.getKey(); eacs.submit( new Callable<Void>() { @Override public Void call() throws Exception { try { final MarshalledEntry marshalledEntry = _load(key, fetchValue, fetchMetadata); if (marshalledEntry != null) { task.processEntry(marshalledEntry, taskContext); } return null; } catch (Exception e) { log.errorExecutingParallelStoreTask(e); throw e; } } }); } eacs.waitUntilAllCompleted(); if (eacs.isExceptionThrown()) { throw new PersistenceException("Execution exception!", eacs.getFirstException()); } }
@Override public void purge(Executor threadPool, final PurgeListener task) { long now = timeService.wallClockTime(); List<KeyValuePair<Object, FileEntry>> entriesToPurge = new ArrayList<KeyValuePair<Object, FileEntry>>(); synchronized (entries) { for (Iterator<Map.Entry<K, FileEntry>> it = entries.entrySet().iterator(); it.hasNext(); ) { Map.Entry<K, FileEntry> next = it.next(); FileEntry fe = next.getValue(); if (fe.isExpired(now)) { it.remove(); entriesToPurge.add(new KeyValuePair<Object, FileEntry>(next.getKey(), fe)); } } } resizeLock.readLock().lock(); try { for (Iterator<KeyValuePair<Object, FileEntry>> it = entriesToPurge.iterator(); it.hasNext(); ) { KeyValuePair<Object, FileEntry> next = it.next(); FileEntry fe = next.getValue(); if (fe.isExpired(now)) { it.remove(); try { free(fe); } catch (Exception e) { throw new PersistenceException(e); } if (task != null) task.entryPurged(next.getKey()); } } // Disk space optimizations synchronized (freeList) { processFreeEntries(); } } finally { resizeLock.readLock().unlock(); } }