Subversion Repositories Code-Repo

Rev

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

Rev Author Line No. Line
96 Kevin 1
import java.nio.ByteBuffer;
2
 
3
// Assisting class for converting classes to a byte array and vice versa
4
public class NodeSerializer {
5
	private MemManager memoryManager;
6
 
7
	// Constructor
8
	public NodeSerializer(MemManager mem) {
9
		memoryManager = mem;
10
	}
11
 
12
	// Removes the handle and subhandles for leaf nodes (city name)
13
	public void removeHandle(Handle handle) {
14
		PRQuadTreeNode node = handleToNode(handle);
15
		if (node instanceof PRQuadTreeNodeFlyweight) {
16
			return;
17
		} else if (node instanceof PRQuadTreeNodeLeaf) {
18
			byte[] array = new byte[memoryManager.getDataBlockSize(handle)];
19
			memoryManager.get(array, handle);
20
 
21
			ByteBuffer buffer = ByteBuffer.wrap(array);
22
			int records = (int)buffer.get();
23
			records = (int)buffer.get();
24
 
25
			for (int i = 0; i < records; i++) {
26
				// Remove the CityRecord and the name of the city
27
				int addr = buffer.getInt();
28
				Handle cityhandle = new Handle(addr);
29
 
30
				removeCityRecordHandle(cityhandle);
31
			}
32
		} 
33
		memoryManager.remove(handle);
34
	}
35
 
36
	public void removeCityRecordHandle(Handle handle) {
37
		// Remove the handle to the city name
38
		byte[] data = new byte[memoryManager.getDataBlockSize(handle)];
39
		memoryManager.get(data, handle);
40
		ByteBuffer cityrecord = ByteBuffer.wrap(data);
41
		Handle name = new Handle(cityrecord.getInt(8));
42
		memoryManager.remove(name);
43
		memoryManager.remove(handle);
44
	}
45
 
46
	// Resets the empty block list in the memory manager to the size of the file
47
	public void clearMemory() {
48
		memoryManager.clear();
49
	}
50
 
51
	// Print debug info from the memory manager
52
	public void printDebug() {
53
		memoryManager.printBuffer();
54
		memoryManager.dump();
55
	}
56
 
57
	// Allocates the node onto disk and returns a handle to the node
58
	public Handle nodeToHandle(PRQuadTreeNode node) {
59
		if (node instanceof PRQuadTreeNodeInternal) {
60
			byte[] array = nodeInternalToByteArray((PRQuadTreeNodeInternal)node);
61
			Handle ret = memoryManager.insert(array, array.length);
62
			return ret;
63
		} else if (node instanceof PRQuadTreeNodeLeaf) {
64
			byte[] array = nodeLeafToByteArray((PRQuadTreeNodeLeaf)node);
65
			Handle ret = memoryManager.insert(array, array.length);
66
			return ret;
67
		} else {
68
			Handle ret = new Handle(-1);
69
			return ret;
70
		}
71
	}
72
 
73
	// Reads a handle off the disk and returns the corresponding
74
	public PRQuadTreeNode handleToNode(Handle handle) {
75
		if (handle.getAddress() == -1) {
76
			PRQuadTreeNodeFlyweight ret = new PRQuadTreeNodeFlyweight();
77
			return ret;
78
		} else {
79
			byte[] array = new byte[memoryManager.getDataBlockSize(handle)];
80
			memoryManager.get(array, handle);
81
			return byteArrayToNode(array);
82
		}
83
	}
84
 
85
 
86
 
87
	private byte[] stringToByteArray(String str) {
88
		// Use ByteBuffer to serialize to bytes
89
		byte[] byteArray = new byte[str.length() + 1];
90
		byte[] bstr = str.getBytes();
91
 
92
		ByteBuffer buffer = ByteBuffer.wrap(byteArray);
93
 
94
		// Set first byte as the length
95
		buffer.put((byte)bstr.length);
96
		// Set remaining bytes as the string
97
		buffer.put(bstr);
98
 
99
		return byteArray;
100
	}
101
 
102
	private byte[] nodeInternalToByteArray(PRQuadTreeNodeInternal node) {
103
		byte[] byteArray = new byte[17];
104
		ByteBuffer buffer = ByteBuffer.wrap(byteArray);
105
 
106
		buffer.put((byte)1);
107
		buffer.putInt((int)node.getNW().getAddress());
108
		buffer.putInt((int)node.getNE().getAddress());
109
		buffer.putInt((int)node.getSW().getAddress());
110
		buffer.putInt((int)node.getSE().getAddress());
111
 
112
		return byteArray;
113
	}
114
 
115
	private byte[] nodeLeafToByteArray(PRQuadTreeNodeLeaf node) {
116
		byte[] byteArray = new byte[14];
117
		ByteBuffer buffer = ByteBuffer.wrap(byteArray);
118
 
119
		// Set first byte to indicate leaf node
120
		buffer.put((byte)0);
121
		// Set second byte to hold number of records
122
		buffer.put((byte)node.getCount());
123
 
124
		CityRecord record = (CityRecord) node.getFirst();
125
		buffer.putInt((int)cityRecordToHandle(record).getAddress());
126
		record = (CityRecord) node.getNext(record);
127
		while (record != null) {
128
			buffer.putInt((int)cityRecordToHandle(record).getAddress());
129
 
130
			record = (CityRecord) node.getNext(record);
131
		}
132
 
133
		return byteArray;
134
	}
135
 
136
	private String byteArrayToString(byte[] byteArray) {
137
		ByteBuffer buffer = ByteBuffer.wrap(byteArray);
138
 
139
		byte[] bstr = new byte[(int)buffer.get()];
140
		buffer.get(bstr);
141
 
142
		String str = new String(bstr);
143
 
144
		return str;
145
	}
146
 
147
	private PRQuadTreeNode byteArrayToNode(byte[] data) {
148
		ByteBuffer buffer = ByteBuffer.wrap(data);
149
		// Internal node
150
		byte b = buffer.get();
151
		if (b == (byte)1) {
152
			PRQuadTreeNodeInternal newNode = new PRQuadTreeNodeInternal(new Handle(-1), this);
153
			Handle NW = new Handle(buffer.getInt());
154
			Handle NE = new Handle(buffer.getInt());
155
			Handle SW = new Handle(buffer.getInt());
156
			Handle SE = new Handle(buffer.getInt());
157
 
158
			newNode.setNW(NW);
159
			newNode.setNE(NE);
160
			newNode.setSW(SW);
161
			newNode.setSE(SE);
162
 
163
			return newNode;
164
		// Leaf node
165
		} else if (b == (byte)0) {
166
			PRQuadTreeNodeLeaf newNode = new PRQuadTreeNodeLeaf(3);
167
			int records = (int)buffer.get();
168
 
169
			for (int i = 0; i < records; i++) {
170
				int address = buffer.getInt();
171
 
172
				Handle handle = new Handle(address);
173
				CityRecord record = handleToCityRecord(handle);
174
 
175
				newNode.insert(record);
176
			}
177
 
178
			return newNode;
179
		} else {
180
			return null;
181
		}
182
	}
183
 
184
	public Handle cityRecordToHandle(CityRecord record) {
185
		byte[] data = new byte[12];
186
		ByteBuffer buffer = ByteBuffer.wrap(data);
187
 
188
		byte[] cityname = stringToByteArray(record.getName());
189
		Handle handle = memoryManager.insert(cityname, cityname.length);
190
 
191
		buffer.putInt(record.getX());
192
		buffer.putInt(record.getY());
193
		buffer.putInt((int)handle.getAddress());
194
 
195
		Handle ret = memoryManager.insert(data, 12);
196
		return ret;
197
	}
198
 
199
	public CityRecord handleToCityRecord(Handle handle) {
200
		byte[] data = new byte[12];
201
		memoryManager.get(data, handle);
202
 
203
		ByteBuffer buffer = ByteBuffer.wrap(data);
204
		int x = buffer.getInt();
205
		int y = buffer.getInt();
206
		int addr = buffer.getInt();
207
 
208
		Handle cityhandle = new Handle(addr);
209
		byte[] city = new byte[memoryManager.getDataBlockSize(cityhandle)];
210
		memoryManager.get(city, cityhandle);
211
		String cityname = byteArrayToString(city);
212
 
213
		CityRecord record = new CityRecord(cityname, x, y);
214
		return record;
215
	}
216
}