001: package com.jofti.store;
002:
003: import java.nio.ByteBuffer;
004: import java.util.LinkedHashMap;
005: import java.util.Map;
006: import java.util.Properties;
007: import java.util.Map.Entry;
008:
009: import org.apache.commons.logging.Log;
010: import org.apache.commons.logging.LogFactory;
011:
012: import com.jofti.btree.BTree;
013: import com.jofti.btree.IPage;
014: import com.jofti.btree.LeafNodeEntry;
015: import com.jofti.core.IStoreKey;
016: import com.jofti.exception.JoftiException;
017:
018: public class LRUStoreManager extends AbstractStoreManager {
019:
020: private static Log log = LogFactory
021: .getLog(AbstractStoreManager.class);
022:
023: protected Map lruMap = null;
024:
025: private Object objectLock = new Object();
026:
027: public void init(Properties properties) throws JoftiException {
028:
029: if (log.isInfoEnabled()) {
030: log.info("Initialising LRU store manager");
031: }
032:
033: super .init(properties);
034:
035: lruMap = new LinkedHashMap() {
036: protected final int limit = maxNodes;
037:
038: /*
039: * (non-Javadoc)
040: *
041: * @see java.util.LinkedHashMap#removeEldestEntry(java.util.Map.Entry)
042: */
043: protected boolean removeEldestEntry(Entry eldest) {
044: // TODO Auto-generated method stub
045: if (size() > limit) {
046: StoreWrapper wrapper = (StoreWrapper) eldest
047: .getValue();
048: CachedPage page = (CachedPage) wrapper.page;
049: if (!page.hasReferences()) {
050: pageManager.releasePage(page.page);
051: } else {
052: log
053: .debug("reference held - unable to release page "
054: + page.page);
055: }
056: return true;
057: }
058:
059: return false;
060: }
061: };
062:
063: if (log.isInfoEnabled()) {
064: log.info("Initialised LRu store manager");
065: }
066: }
067:
068: public IStoreKey store(IStoreKey key, IPage page)
069: throws JoftiException {
070:
071: StoreWrapper wrapper = null;
072:
073: // get the number of positions we need to store the data
074: int limit = page.getBuffer().limit();
075: FilePositionHolder[] array = allocatePositions(key
076: .getFilePositions(), limit);
077: key.setFilePositions(array);
078:
079: // make sure we are storing a copy here
080: ByteBuffer buf = pageManager.acquireBuffer(limit);
081:
082: doStore(key, page.copyBuffer(buf));
083: // release the buffer we have just stored
084: pageManager.releaseBuffer(buf);
085:
086: wrapper = new StoreWrapper(key, page);
087:
088: // doStore(key,obj);
089: synchronized (objectLock) {
090: ((CachedPage) page).releaseReference();
091: lruMap.put(key, wrapper);
092: }
093:
094: return null;
095: }
096:
097: protected IPage getNewPage(int size) {
098: IPage temp = doGetNewPage(size);
099:
100: // wrap the page
101: CachedPage cPage = new CachedPage(temp);
102: cPage.entries = new LeafNodeEntry[BTree.getMaxNodeSize()];
103: // add a usage reference here
104: cPage.acquireReference();
105: return cPage;
106: }
107:
108: public void releasePage(IStoreKey key, IPage page) {
109: synchronized (objectLock) {
110: ((CachedPage) page).releaseReference();
111: }
112: }
113:
114: public StoreWrapper retrieve(IStoreKey key) throws JoftiException {
115: StoreWrapper obj = null;
116: synchronized (objectLock) {
117: obj = (StoreWrapper) lruMap.get(key);
118: if (obj != null) {
119: ((CachedPage) obj.page).acquireReference();
120: return obj;
121: }
122: }
123:
124: // otherwise replace the val
125:
126: IPage page = doRetrieve(key);
127: // got to get from store
128:
129: CachedPage cPage = new CachedPage(page);
130: cPage.entries = new LeafNodeEntry[BTree.getMaxNodeSize()];
131: cPage.acquireReference();
132:
133: obj = new StoreWrapper(key, cPage);
134: synchronized (objectLock) {
135: lruMap.put(key, obj);
136: }
137: return obj;
138:
139: }
140:
141: public void remove(IStoreKey key, IPage page) throws JoftiException {
142: releasePage(key, page);
143: synchronized (objectLock) {
144:
145: StoreWrapper wrapper = (StoreWrapper) lruMap.remove(key);
146: CachedPage cPage = (CachedPage) wrapper.page;
147: cPage.releaseReference();
148: if (!cPage.hasReferences()) {
149: pageManager.releasePage(cPage.page);
150: }
151: }
152: doRemove(key);
153:
154: }
155:
156: public void removeAll() throws JoftiException {
157: java.util.Iterator it = lruMap.entrySet().iterator();
158: int size = lruMap.size();
159: for (int i = 0; i < size; i++) {
160: Map.Entry entry = (Map.Entry) it.next();
161: StoreWrapper wrap = (StoreWrapper) entry.getValue();
162:
163: CachedPage old = (CachedPage) wrap.page;
164: old.releaseReference();
165: if (!old.hasReferences()) {
166: pageManager.releasePage(old.page);
167: }
168:
169: }
170: lruMap.clear();
171: doRemoveAll();
172: }
173:
174: }
|