Rev 96 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
import java.nio.ByteBuffer;// Memory manager that operates on the buffer poolpublic class MemManager {private LRUBuffer buffer; // Buffer pool interfacing to diskprivate int blockSize = 0; // Size of each blockprivate long fileLength = 0; // Current length of the fileprivate DoubleLinkedList emptyBlockList; // List of free blocks// Constructorpublic MemManager(LRUBuffer buffer, int blockSize) {// Initialize buffer pool and list of free blocksthis.buffer = buffer;emptyBlockList = new DoubleLinkedList();this.blockSize = blockSize;}// Insert a record and return its position handle.public Handle insert(byte[] data, int length) {// There are no free blocksif (emptyBlockList.getFirstEntry() == null) {// Create a new free block of size blockSizeLinkedListBlock newEntry = new LinkedListBlock(0, blockSize - 1, blockSize);emptyBlockList.insert(newEntry);fileLength = blockSize;}// Size to insert is greater than size of largest free blockif ((length + 1) > emptyBlockList.getFirstEntry().getSize()) {// Calculate how many new free blocks needs to be created to hold the byte arrayint blocks = length / blockSize;if (length % blockSize != 0) {blocks++;}for (int i = 0; i < blocks; i++) {// Create a new free block and insert it into the list of empty blockLinkedListBlock newEntry = new LinkedListBlock(fileLength, fileLength + blockSize - 1, blockSize);emptyBlockList.insert(newEntry);fileLength += blockSize;}}// Find the first free block that can hold the byte arrayLinkedListBlock start = emptyBlockList.getFirstEntry();while (start != null) {// Current block is last block in list, insert into current blockif (start.getNextBlock() == null) {Handle newHandle = insertDataIntoMemPool(start, data, length);return newHandle;// Best fit block found, insert into current block} else if ((length + 1) > start.getNextBlock().getSize()) {Handle newHandle = insertDataIntoMemPool(start, data, length);return newHandle;}// Otherwise keep searching for best fit blockstart = start.getNextBlock();}return null;}// Free a block at address. Merge adjacent blocks if appropriate.public void remove(Handle handle) {short size = getDataBlockSize(handle);// Needs to create a new empty block at the specified addressLinkedListBlock newEntry = new LinkedListBlock(handle.getAddress(), handle.getAddress() + size, size + 1);emptyBlockList.insert(newEntry);}// Return the record with handle posHandle, up to size bytes.public void get(byte[] data, Handle handle) {// Get bytes from bufferbuffer.getBytes(data, 0, handle.getAddress() + 1, getDataBlockSize(handle));}// Returns the value of the first byte for the data entry (size)public short getDataBlockSize(Handle handle) {byte[] shortArr = new byte[2];// Get the first byte at the addressbuffer.getBytes(shortArr, 1, handle.getAddress(), 1);ByteBuffer shortBuffer = ByteBuffer.wrap(shortArr);short size = shortBuffer.getShort();return size;}// Copies the passed byte array into the bufferprivate Handle insertDataIntoMemPool(LinkedListBlock entry, byte[] data, int length) {// Insert the size of the array into the first bytebyte[] size = new byte[1];ByteBuffer buff = ByteBuffer.wrap(size);buff.put((byte)length);buffer.putBytes(size, 0, entry.getStartAddress(), 1);// Insert the arraybuffer.putBytes(data, 0, entry.getStartAddress() + 1, length);// Create a new free block with remaining free spaceif (entry.getSize() - (length + 1) != 0) {long startAddress = entry.getStartAddress() + length + 1;long newSize = entry.getSize() - (length + 1);long endAddress = startAddress + newSize - 1;LinkedListBlock newEntry = new LinkedListBlock(startAddress, endAddress, newSize);emptyBlockList.remove(entry.getStartAddress());emptyBlockList.insert(newEntry);} else {emptyBlockList.remove(entry.getStartAddress());LinkedListBlock newEntry = new LinkedListBlock(fileLength, fileLength + blockSize - 1, blockSize);emptyBlockList.insert(newEntry);fileLength += blockSize;}Handle newHandle = new Handle(entry.getStartAddress());return newHandle;}// Dump a printout of the freeblock listpublic void dump() {LinkedListBlock head = emptyBlockList.getFirstEntry();while (head != null) {System.out.printf("Empty block at address %d to %d\n", head.getStartAddress(), head.getStartAddress() + head.getSize() - 1);head = head.getNextBlock();}}public void printBuffer() {buffer.printBlockIDs();}public void clear() {LinkedListBlock head = emptyBlockList.getFirstEntry();while (head != null) {emptyBlockList.remove(head.getStartAddress());head = head.getNextBlock();}LinkedListBlock newEntry = new LinkedListBlock(0, fileLength-1, fileLength);emptyBlockList.insert(newEntry);}}