-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMemManager.java
More file actions
212 lines (181 loc) · 5.68 KB
/
MemManager.java
File metadata and controls
212 lines (181 loc) · 5.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
// -------------------------------------------------------------------------
/**
* this class deal with the byte array that need to be inserted into memry pool.
* insert, remove the record to/from memory pool and update the freeblock list.
*
* @author wenfeng ren (rwenfeng)
* @version Sep 8, 2014
*/
public class MemManager
{
// data files
/**
* memory pool array
*/
private MemoryPool pool;
/**
* the freeblock list to track memory pool.
*/
private Freeblock list;
/**
* the initial block size.
*/
private int blockSize;
/**
* the number of time that the pool allocate.
*/
private int numOfAllocate = 0;
private final int sizePlus = 2;
// ----------------------------------------------------------
/**
* Create a new MemManager object. initialize the pool array and freeblock
* list.
*
* @param blockSize
* the size of the block
*/
public MemManager(int blockSize)
{
// initialize the pool array.
pool = new MemoryPool(blockSize);
// initialize the freeblock list, the position is initially 0.
list = new Freeblock(blockSize);
this.blockSize = blockSize;
}
// ----------------------------------------------------------
/**
* Insert a record and return its position handle.
*
* @param space
* contains the record to be inserted
* @param size
* of the record
* @return handle position handle
*/
public Handle insert(byte[] space, int size)
{
// update freeblock list tracking info.
int position = list.findPosition(size + sizePlus);
if (position != -1) // successfully insert the record.
{
pool.store(space, position);
list.updateList(size + sizePlus);
}
else
// no best block fit the record, need to reallocate the pool.
{
while (position == -1)
{
// reallocate the pool and store the record again
pool.reallocate();
numOfAllocate++;
// new free block need to be insert to freeblock list.
Block newFreeBlock =
new Block(blockSize, numOfAllocate * blockSize);
list.insert(newFreeBlock);
// update the list: block size and block positon.
position = list.findPosition(size + sizePlus);
}
pool.store(space, position);
list.updateList(size + sizePlus);
}
// the handle need to be return with position
Handle handle = new Handle(position);
return handle;
}
// ----------------------------------------------------------
/**
* Free a block at the position specified by theHandle. Merge adjacent free
* blocks.
*
* @param handle
* with position of the record that need to be removed
*/
public void remove(Handle handle)
{
int position = handle.getPosition();
// get byte size from pool array and convert to int
int recordSize = pool.read(position) & 0xFFFF;
// after remove record, the free block needs to be insert back to list
Block freeBlock = new Block(recordSize + sizePlus, position);
list.insert(freeBlock);
}
// ----------------------------------------------------------
/**
* Return the record with handle posHandle, up to size bytes, by copying it
* into space. Return the number of bytes actually copied into space.
*
* @param space
* that the record needs to be copied into.
* @param handle
* with the position of the record
* @param size
* the given size of the record
* @return copySize the actual size of the record that copies into the space
*/
public int get(byte[] space, Handle handle, int size)
{
int copySize;
int memSize = pool.read(handle.getPosition()) & 0xFFFF;
if (memSize > size)
{
copySize = size;
}
else
{
copySize = memSize;
}
pool.read(space, handle.getPosition() + sizePlus, size);
return copySize;
}
// ----------------------------------------------------------
/**
* get the String with handle.
*
* @param handle to get the string
* @return string returned by handle
*/
public String get(Handle handle)
{
int size = pool.read(handle.getPosition());
byte[] space = new byte[size];
pool.read(space, handle.getPosition() + sizePlus, size);
return byteToString(space, size);
}
// ----------------------------------------------------------
/**
* printout the freeblock list.
*/
public void dump()
{
System.out.println(list.toString());
}
// ----------------------------------------------------------
/**
* convert byte array to string.
*
* @param data to convert to string
* @param size
* the actual size that used
* @return str converted from data
*/
public String byteToString(byte[] data, int size)
{
String str = null;
// load data to buffer
ByteBuffer buffer = ByteBuffer.wrap(data);
byte[] buf = new byte[size];
buffer.get(buf);
try
{
str = new String(buf, "US-ASCII");
}
catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
return str;
}
}