Subversion Repositories Code-Repo

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
93 Kevin 1
import java.nio.ByteBuffer;
2
 
3
// Memory manager that operates on the memory pool
4
public class MemManager {
5
 
6
	private byte[] memoryPool;	// Byte array representing the memory pool
7
	private DoubleLinkedList emptyBlockList;	// List of free blocks
8
 
9
	// Constructor
10
	public MemManager(int poolsize) {
11
		// Initialize memory pool and list of free blocks
12
		memoryPool = new byte[poolsize];
13
		emptyBlockList = new DoubleLinkedList();
14
 
15
		// Create the first empty block of the pool size
16
		LinkedListEntry newEntry = new LinkedListEntry(0, poolsize - 1, poolsize);
17
		emptyBlockList.insert(newEntry);
18
	}
19
 
20
	// Insert a record and return its position handle.
21
	// space contains the record to be inserted, of length size.
22
	public Handle insert(byte[] space, int size) {
23
		LinkedListEntry start = emptyBlockList.getFirstEntry();
24
		if (start == null) {
25
			// There are no free blocks
26
			return null;
27
		}
28
		if ((size + 1) > start.getSize()) {
29
			// Size to insert is greater than size of largest free block
30
			return null;
31
		}
32
		while (start != null) {
33
			if (start.getNextBlock() == null) {
34
				// Current block is last block in list, insert into current block
35
				Handle newHandle = insertDataIntoMemPool(start, space, size);
36
				return newHandle;
37
			} else if ((size + 1) > start.getNextBlock().getSize()) {
38
				// Best fit block found, insert into current block
39
				Handle newHandle = insertDataIntoMemPool(start, space, size);
40
				return newHandle;
41
			}
42
			// Otherwise keep searching for best fit block
43
			start = start.getNextBlock();
44
		}
45
		return null;
46
	}
47
 
48
	// Free a block at address. Merge adjacent blocks if appropriate.
49
	public void remove(Handle handle) {
50
		short size = getDataBlockSize(handle.getAddress());
51
 
52
		// Needs to create a new empty block at the specified address
53
		LinkedListEntry newEntry = new LinkedListEntry(handle.getAddress(), handle.getAddress() + size, size + 1);
54
		emptyBlockList.insert(newEntry);
55
	}
56
 
57
	// Return the record with handle posHandle, up to size bytes.
58
	// Data to be returned is copied to space.
59
	public void get(byte[] space, Handle handle, int size) {
60
		short shSize = getDataBlockSize(handle.getAddress());
61
 
62
		// Find max number of bytes to copy to byte array
63
		int toRead;
64
		if (size < shSize) {
65
			toRead = size;
66
		} else {
67
			toRead = shSize;
68
		}
69
 
70
		// Copy bytes from memory pool to byte array
71
		ByteBuffer memPool = ByteBuffer.wrap(memoryPool, handle.getAddress() + 1, toRead);
72
		ByteBuffer dest = ByteBuffer.wrap(space);
73
		dest.put(memPool);
74
	}
75
 
76
	// Dump a printout of the freeblock list
77
	public void dump() {
78
		LinkedListEntry head = emptyBlockList.getFirstEntry();
79
		while (head != null) {
80
			System.out.printf("Empty block at address %d of size %d\n", head.getStartAddress(), head.getSize());
81
			head = head.getNextBlock();
82
		}
83
	}
84
 
85
	// Returns the value of the first byte for the data entry (size)
86
	private short getDataBlockSize(int address) {
87
		byte[] shortArr = new byte[2];
88
		ByteBuffer shortBuffer = ByteBuffer.wrap(shortArr, 1, 1);
89
		shortBuffer.put(memoryPool[address]);
90
		shortBuffer = ByteBuffer.wrap(shortArr);
91
		short size = shortBuffer.getShort();
92
		return size;
93
	}
94
 
95
	// Copies the passed byte array into a free block in the memory pool
96
	private Handle insertDataIntoMemPool(LinkedListEntry entry, byte[] space, int size) {
97
		// Insert the data at the address of the given free block
98
		ByteBuffer memBuffer = ByteBuffer.wrap(memoryPool, entry.getStartAddress(), size + 1);
99
		memBuffer.put((byte)size);
100
		memBuffer.put(space);
101
 
102
		// Create a new free block with remaining free space
103
		if (entry.getSize() - (size + 1) != 0) {
104
			int startAddress = entry.getStartAddress() + size + 1;
105
			int newSize = entry.getSize() - (size + 1);
106
			int endAddress = startAddress + newSize - 1;
107
			LinkedListEntry newEntry = new LinkedListEntry(startAddress, endAddress, newSize);
108
			emptyBlockList.remove(entry.getStartAddress());
109
			emptyBlockList.insert(newEntry);
110
		} else {
111
			emptyBlockList.remove(entry.getStartAddress());
112
		}
113
 
114
		Handle newHandle = new Handle(entry.getStartAddress());
115
		return newHandle;
116
	}
117
}