1 46 51 package org.mr.core.persistent; 52 53 import java.io.IOException ; 54 import java.util.Collection ; 55 import java.util.HashMap ; 56 import java.util.Iterator ; 57 import java.util.LinkedHashMap ; 58 import java.util.LinkedList ; 59 import java.util.Map ; 60 import java.util.Set ; 61 62 63 import org.apache.commons.logging.Log; 64 import org.apache.commons.logging.LogFactory; 65 66 import org.mr.core.util.byteable.Byteable; 67 import org.mr.core.util.byteable.ByteableMapEntry; 68 69 75 public class PersistentMap implements Map { 76 private Log log; 78 private int itemsCount = 0; 80 private HashMap entryToFileMap = new HashMap (); 82 private LinkedHashMap delegated = new LinkedHashMap (); 84 private boolean defaultPersistent ; 86 87 private LinkedList freeList = new LinkedList (); 88 89 private PersistentManager persistentManager ; 90 91 97 public PersistentMap(String name ,boolean defaultPersistent, boolean blocking){ 98 super(); 99 try { 100 this.defaultPersistent = defaultPersistent; 101 log=LogFactory.getLog("PersistentMap"); 102 persistentManager = PersistentManagerFactory.getPersistentManager(name); 103 recover(name); 104 } catch (Throwable e) { 105 if(log.isFatalEnabled()){ 106 log.fatal("Can not init persistent stracture. ",e); 107 } 108 } 109 } 111 116 private void recover(String name) throws IOException { 117 118 persistentManager.recover(); 119 int[] keySet = persistentManager.getKeys(); 120 if(log.isInfoEnabled()&& keySet.length >0 ){ 121 log.info("Starting to recover "+name+". There are "+keySet.length+" elements to recover, this might take time."); 122 } 123 124 for(int index =0 ; index < keySet.length ; index++){ 125 126 127 ByteableMapEntry entry =(ByteableMapEntry)persistentManager.getPersistentObject(keySet[index]); 128 129 if(entry!= null){ 130 Integer fileKey = new Integer (keySet[index]); 131 entryToFileMap.put(entry.getKey() ,fileKey); 132 delegated.put(entry.getKey() ,entry.getValue() ); 133 itemsCount++; 134 }else{ 135 if(log.isFatalEnabled()){ 136 log.fatal("Could not recover "+name+":"+keySet[index]+"."); 137 } } 139 } 140 if(log.isInfoEnabled()&& keySet.length >0 ){ 141 log.info("Recovery of " + name + " is complete."); 142 } 143 144 } 147 148 151 public final synchronized Object put(Object key, Object value){ 152 return put( (String )key, (Byteable)value , defaultPersistent); 153 } 154 155 165 public final synchronized Object put(String key, Byteable value , boolean persisnent){ 166 if(persisnent){ 167 ByteableMapEntry entry = null; 168 try{ 169 Integer freeKey = (Integer )entryToFileMap.remove(key); 171 if(freeKey != null) 172 freeList.add(freeKey); 173 174 int fileName = getValidFreePersistentName(); 176 Integer fileKey = new Integer (fileName); 177 entryToFileMap.put(key ,fileKey); 178 entry = new ByteableMapEntry(key,value); 180 181 persistentManager.savePersistentObject(fileName ,entry ); 182 }catch(Exception io){ 183 if(log.isFatalEnabled()){ 184 log.fatal("Can not save entry "+entry+"." , io ); 185 } 186 } 187 } return delegated.put(key ,value ); 189 } 191 192 195 private final int getValidFreePersistentName(){ 196 if(!freeList.isEmpty()){ 198 return ((Integer )freeList.removeFirst()).intValue(); 199 } 200 int result = itemsCount; 201 itemsCount++; 202 if(itemsCount >= PersistentManager.MAX_FILES_PER_STORAGE){ 203 throw new IllegalStateException ("MAP IS FULL CAN NOT ALLOCATE MORE PERSISTENT SPACE."); 204 } 205 return result; 206 } 207 208 211 public final synchronized Object remove(Object key){ 212 213 Integer freeKey = (Integer )entryToFileMap.remove(key); 214 if(freeKey != null){ 215 persistentManager.deletePersistentObject(freeKey.intValue()); 216 freeList.add(freeKey); 217 } 218 return delegated.remove(key); 219 } 220 221 public final synchronized void removeAll(){ 222 Object key; 223 Integer freeKey; 224 Iterator i = entryToFileMap.keySet().iterator(); 225 while (i.hasNext()) { 226 key = i.next(); 227 freeKey = (Integer )entryToFileMap.get(key); 228 i.remove(); 229 if(freeKey != null){ 230 persistentManager.deletePersistentObject(freeKey.intValue()); 231 freeList.add(freeKey); 232 } 233 delegated.remove(key); 234 } 235 } 236 237 241 public final synchronized void clear() { 242 try { 243 persistentManager.clearStorage(); 244 } catch (IOException e) { 245 if(log.isFatalEnabled()){ 246 log.fatal("Can not clear map "+persistentManager.getStorageName()+"." , e ); 247 } 248 } 249 entryToFileMap.clear(); 250 delegated.clear(); 251 freeList.clear(); 252 } 253 254 257 public final synchronized int size() { 258 return delegated.size(); 259 } 260 261 264 public final synchronized boolean isEmpty() { 265 266 return delegated.isEmpty(); 267 } 268 269 272 public final synchronized boolean containsKey(Object key) { 273 return delegated.containsKey(key); 274 } 275 276 279 public final synchronized boolean containsValue(Object value) { 280 281 return delegated.containsValue(value); 282 } 283 284 287 public final synchronized Collection values() { 288 return delegated.values(); 289 } 290 291 294 public final synchronized void putAll(Map t) { 295 Iterator i = t.entrySet().iterator(); 296 while (i.hasNext()) { 297 Map.Entry e = (Map.Entry ) i.next(); 298 put(e.getKey(), e.getValue()); 299 } 300 301 } 302 303 306 public final synchronized Set entrySet() { 307 return delegated.entrySet(); 308 } 309 310 313 public final synchronized Set keySet() { 314 return delegated.keySet(); 315 } 316 317 320 public final synchronized Object get(Object key) { 321 return delegated.get(key); 322 } 323 } 324 | Popular Tags |