001package org.cache2k.storage; 002 003/* 004 * #%L 005 * cache2k core package 006 * %% 007 * Copyright (C) 2000 - 2015 headissue GmbH, Munich 008 * %% 009 * This program is free software: you can redistribute it and/or modify 010 * it under the terms of the GNU General Public License as 011 * published by the Free Software Foundation, either version 3 of the 012 * License, or (at your option) any later version. 013 * 014 * This program is distributed in the hope that it will be useful, 015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 017 * GNU General Public License for more details. 018 * 019 * You should have received a copy of the GNU General Public 020 * License along with this program. If not, see 021 * <http://www.gnu.org/licenses/gpl-3.0.html>. 022 * #L% 023 */ 024 025import java.io.IOException; 026import java.util.concurrent.ExecutorService; 027 028/** 029 * An interface for persistent or off heap storage for a cache. 030 * 031 * @author Jens Wilke; created: 2014-04-03 032 */ 033public interface CacheStorage { 034 035 /** 036 * Retrieve the entry from the storage. If there is no mapping for the 037 * key, null is returned. 038 * 039 * <p>Depending on the cache configuration, an exception on get is not severe. 040 * The cache will try other sources or return null. 041 */ 042 public StorageEntry get(Object key) throws Exception; 043 044 /** 045 * Stores the entry in the storage. The entry instance is solely for transferring 046 * the data, no reference may be hold within the storage to it. The callee takes 047 * care that the entry data is consistent during the put method call. 048 * 049 * <p/>If a put operation fails an implementation should try to remove an 050 * existing entry bound to the key and then throw the exception. 051 * 052 * @throws IOException may be thrown if hope is lost 053 */ 054 public void put(StorageEntry e) throws Exception; 055 056 public boolean remove(Object key) throws Exception; 057 058 /** 059 * Returns true if there is a mapping for the key. 060 * 061 * <p>An exception on contains is not severe. The cache will try other sources or 062 * return null. 063 */ 064 public boolean contains(Object key) throws Exception; 065 066 /** 067 * Remove all entries from the cache and free resources. This operation is called 068 * when there is no other operation concurrently executed on this storage instance. 069 * 070 * <p/>When a Cache.clear() is initiated there is no obligation to send a 071 * CacheStorage.clear() to the persisted storage. Alternatively, all objects can 072 * be removed via remove(). 073 */ 074 public void clear() throws Exception; 075 076 /** 077 * Free all resources and stop operations immediately. 078 */ 079 public void close() throws Exception; 080 081 /** 082 * Iterate over all stored entries and call the entry visitor. It is generally safe to 083 * return expired entries. If {@link org.cache2k.storage.PurgeableStorage} is not 084 * implemented, returning expired entries is a must, to support the generic purge 085 * algorithm. 086 * 087 * <p/>If the {@link ExecutorService} is used, the method may return immediately without 088 * the waiting for all threads to finish. This is done by the caller, when needed. 089 */ 090 public void visit(VisitContext ctx, EntryFilter f, EntryVisitor v) throws Exception; 091 092 public int getEntryCount(); 093 094 public static interface MultiThreadedContext { 095 096 /** 097 * A private executor service for this operation to run in multiple threads. 098 * The use of {@link ExecutorService#awaitTermination(long, java.util.concurrent.TimeUnit)} ()} 099 * waits only for threads started within the visit operation. Multiple calls to 100 * this method return the identical instance. 101 * 102 * <p>When using {@link java.util.concurrent.Callable} a thrown exception in within the 103 * task leads to an abort of the operation, see {@link #abortOnException(Throwable)}. 104 * 105 * <p>The methods 106 * {@link java.util.concurrent.ExecutorService#invokeAll(java.util.Collection, long, java.util.concurrent.TimeUnit)}, 107 * {@link java.util.concurrent.ExecutorService#invokeAny(java.util.Collection)}, 108 * {@link java.util.concurrent.ExecutorService#invokeAny(java.util.Collection, long, java.util.concurrent.TimeUnit)} 109 * are or may not be supported by the provided implementation. 110 */ 111 ExecutorService getExecutorService(); 112 113 /** 114 * If threads are started by using {@link #getExecutorService()} waits for termination 115 * or tries to stop threads immediately if {@link #shouldStop()} is true. This is also done 116 * automatically when the visit method exists. 117 */ 118 void awaitTermination() throws InterruptedException; 119 120 /** 121 * True if the operation should stop immediately. Used e.g. during 122 * application shutdown. 123 */ 124 boolean shouldStop(); 125 126 /** 127 * If an exception cannot be handled, this method aborts the operation and 128 * propagates the exception to the operation client. Multiple exceptions can 129 * occur, since the operation is multi thread. Only the first is propagated. 130 * After this method is called {@link #shouldStop()} is true. 131 */ 132 void abortOnException(Throwable ex); 133 134 } 135 136 interface EntryFilter { 137 138 boolean shouldInclude(Object _key); 139 140 } 141 142 interface VisitContext extends MultiThreadedContext { 143 144 /** 145 * True if entries should have metadata. If false, only the key will be set. 146 * Storage implementations may ignore this and always send the metadata. 147 */ 148 boolean needMetaData(); 149 150 /** 151 * True if entries should have the value field set with the storage contents. 152 * Storage implementations may ignore this and always send the metadata. 153 */ 154 boolean needValue(); 155 156 } 157 158 interface EntryVisitor { 159 160 void visit(StorageEntry e) throws Exception; 161 162 } 163 164}