001: package com.jofti.store;
002:
003: import java.nio.ByteBuffer;
004:
005: import com.jofti.btree.BTree;
006: import com.jofti.btree.IPage;
007: import com.jofti.core.IStoreManager;
008: import com.jofti.exception.JoftiException;
009:
010: import edu.emory.mathcs.backport.java.util.concurrent.LinkedBlockingQueue;
011:
012: /**
013: * @author xenephon
014: *
015: * TODO To change the template for this generated type comment go to Window -
016: * Preferences - Java - Code Style - Code Templates
017: */
018: public class PageManager {
019:
020: /**
021: *
022: */
023: /**
024: *
025: */
026: LinkedBlockingQueue bufQueue = null;
027:
028: LinkedBlockingQueue largeBufQueue = null;
029:
030: LinkedBlockingQueue pageQueue = null;
031:
032: private int blockSize = 0;
033:
034: private int maxPages = 100;
035:
036: private int pageNumber = 10;
037:
038: long waitingTime = 0;
039:
040: private long newPages = 0;
041:
042: long accesses = 0;
043:
044: long newBuffers = 0;
045:
046: long bufferAccesses = 0;
047:
048: IStoreManager manager = null;
049: IEntrySerializer serializer = null;
050:
051: public PageManager() {
052: super ();
053: }
054:
055: public void init(int blockSize, int maxPages, int pageNumber,
056: IStoreManager manager, IEntrySerializer serializer)
057: throws JoftiException {
058: // allocate all the free buffers to the freeQueue
059: this .blockSize = blockSize;
060: this .maxPages = maxPages;
061: this .manager = manager;
062: this .serializer = serializer;
063:
064: // set up the buffer pools
065: bufQueue = new LinkedBlockingQueue(maxPages);
066: largeBufQueue = new LinkedBlockingQueue(maxPages);
067: pageQueue = new LinkedBlockingQueue(maxPages);
068:
069: //allocate pages
070: for (int i = 0; i < pageNumber; i++) {
071: int[] arr = new int[BTree.getMaxNodeSize()];
072: for (int j = 0; j < arr.length; j++) {
073: arr[j] = -1;
074: }
075: ByteBuffer buf = ByteBuffer.allocate(blockSize);
076: buf.flip();
077: Page page = new Page(arr, buf, manager, serializer);
078: pageQueue.add(page);
079: }
080:
081: //allocate normal buffers
082: for (int i = 0; i < pageNumber; i++) {
083: ByteBuffer buf = ByteBuffer.allocate(blockSize);
084: buf.flip();
085: bufQueue.add(buf);
086: }
087:
088: //allocate large buffers
089: for (int i = 0; i < pageNumber; i++) {
090: ByteBuffer buf = ByteBuffer.allocate(blockSize * 2);
091: buf.flip();
092: largeBufQueue.add(buf);
093: }
094: this .pageNumber = pageNumber;
095:
096: }
097:
098: public IPage acquirePage(int size) throws JoftiException {
099:
100: accesses++;
101:
102: Page page = (Page) pageQueue.poll();
103:
104: // we must be out of buffers so we can create one
105: if (page == null) {
106:
107: ++newPages;
108: // create a new buffer and nset up the pointers
109: int[] arr = new int[BTree.getMaxNodeSize()];
110: for (int j = 0; j < arr.length; j++) {
111: arr[j] = -1;
112: }
113:
114: page = new Page(arr, acquireBuffer(size), manager,
115: serializer);
116:
117: } else {
118: if ((size > blockSize && page.buf.capacity() == blockSize)
119: || (size <= blockSize && page.buf.capacity() > blockSize)) {
120: // offer the old buffer back to the pool
121: bufQueue.offer(page.buf);
122: page.buf = acquireBuffer(size);
123: }
124: }
125: return page;
126: }
127:
128: /**
129: * releases a buffer into the freeQueue
130: *
131: * @param buffer
132: * LogBuffer to be released
133: */
134: public void releasePage(IPage page) {
135:
136: page.reset();
137:
138: if (!pageQueue.offer(page)) {
139: releaseBuffer(page.getBuffer());
140: }
141:
142: }
143:
144: public ByteBuffer acquireBuffer(int size) {
145: ++bufferAccesses;
146: ByteBuffer buf = null;
147: if (size > blockSize) {
148: buf = (ByteBuffer) largeBufQueue.poll();
149: if (buf == null || size > buf.capacity()) {
150: ++newBuffers;
151: buf = ByteBuffer.allocate(size);
152: buf.flip();
153: }
154:
155: } else {
156: buf = (ByteBuffer) bufQueue.poll();
157: if (buf == null) {
158: ++newBuffers;
159: buf = ByteBuffer.allocate(blockSize);
160: buf.flip();
161: }
162: }
163: return buf;
164: }
165:
166: public void releaseBuffer(ByteBuffer buf) {
167: buf.clear();
168: buf.flip();
169: if (buf.capacity() <= blockSize) {
170: bufQueue.offer(buf);
171: } else {
172: largeBufQueue.offer(buf);
173: }
174: }
175:
176: }
|