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 org.cache2k.StorageConfiguration; 026 027import java.util.ArrayList; 028import java.util.HashMap; 029import java.util.LinkedHashMap; 030import java.util.List; 031import java.util.Map; 032 033/** 034 * Simple storage implementation, just uses a hashmap. Usable for testing and as a 035 * tiny storage implementation example. 036 * 037 * @author Jens Wilke; created: 2014-06-21 038 */ 039public class ByReferenceHeapStorageImpl implements CacheStorage { 040 041 StorageConfiguration<Void> config; 042 CacheStorageContext context; 043 HashMap<Object, HeapEntry> entries; 044 045 public void open(CacheStorageContext ctx, StorageConfiguration<Void> cfg) { 046 context = ctx; 047 config = cfg; 048 final int entryCapacity = cfg.getEntryCapacity(); 049 if (entryCapacity == Integer.MAX_VALUE) { 050 entries = new HashMap<Object, HeapEntry>(); 051 } else { 052 entries = new LinkedHashMap<Object, HeapEntry>(100, .75F, true) { 053 054 @Override 055 protected boolean removeEldestEntry(Map.Entry<Object, HeapEntry> _eldest) { 056 if (getEntryCount() > entryCapacity) { 057 context.notifyExpired(_eldest.getValue()); 058 return true; 059 } 060 return false; 061 } 062 }; 063 } 064 065 } 066 067 @Override 068 public synchronized StorageEntry get(Object key) throws Exception { 069 return entries.get(key); 070 } 071 072 @Override 073 public void put(StorageEntry e) throws Exception { 074 HeapEntry he = new HeapEntry(); 075 he.key = e.getKey(); 076 he.value = e.getValueOrException(); 077 he.updated = e.getCreatedOrUpdated(); 078 he.entryExpiry = e.getEntryExpiryTime(); 079 he.valueExpiry = e.getValueExpiryTime(); 080 synchronized (this) { 081 entries.put(e.getKey(), he); 082 } 083 } 084 085 @Override 086 public synchronized boolean remove(Object key) throws Exception { 087 return entries.remove(key) != null; 088 } 089 090 @Override 091 public synchronized boolean contains(Object key) throws Exception { 092 return entries.containsKey(key); 093 } 094 095 @Override 096 public synchronized void clear() throws Exception { 097 entries.clear(); 098 } 099 100 @Override 101 public void close() throws Exception { 102 entries = null; 103 } 104 105 @Override 106 public void visit(VisitContext ctx, EntryFilter f, EntryVisitor v) throws Exception { 107 List<StorageEntry> l = new ArrayList<StorageEntry>(); 108 synchronized (this) { 109 for (StorageEntry e : entries.values()) { 110 if (f.shouldInclude(e.getKey())) { 111 l.add(e); 112 } 113 } 114 } 115 for (StorageEntry e : l) { 116 if (f.shouldInclude(e.getKey())) { 117 v.visit(e); 118 } 119 } 120 } 121 122 @Override 123 public synchronized int getEntryCount() { 124 return entries.size(); 125 } 126 127 static class HeapEntry implements StorageEntry { 128 Object key; 129 Object value; 130 long updated; 131 long valueExpiry; 132 long entryExpiry; 133 134 @Override 135 public Object getKey() { 136 return key; 137 } 138 139 @Override 140 public Object getValueOrException() { 141 return value; 142 } 143 144 @Override 145 public long getCreatedOrUpdated() { 146 return updated; 147 } 148 149 @Override 150 public long getValueExpiryTime() { 151 return valueExpiry; 152 } 153 154 @Override 155 public long getEntryExpiryTime() { 156 return entryExpiry; 157 } 158 } 159 160 public static class Provider 161 extends CacheStorageProviderWithVoidConfig implements ByReferenceHeapStorage { 162 163 @Override 164 public ByReferenceHeapStorageImpl create(CacheStorageContext ctx, StorageConfiguration<Void> cfg) { 165 ByReferenceHeapStorageImpl st = new ByReferenceHeapStorageImpl(); 166 st.open(ctx, cfg); 167 return st; 168 } 169 170 } 171 172}