Rev 96 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
import java.nio.ByteBuffer;// Assisting class for converting classes to a byte array and vice versapublic class NodeSerializer {private MemManager memoryManager;// Constructorpublic NodeSerializer(MemManager mem) {memoryManager = mem;}// Removes the handle and subhandles for leaf nodes (city name)public void removeHandle(Handle handle) {PRQuadTreeNode node = handleToNode(handle);if (node instanceof PRQuadTreeNodeFlyweight) {return;} else if (node instanceof PRQuadTreeNodeLeaf) {byte[] array = new byte[memoryManager.getDataBlockSize(handle)];memoryManager.get(array, handle);ByteBuffer buffer = ByteBuffer.wrap(array);int records = (int)buffer.get();records = (int)buffer.get();for (int i = 0; i < records; i++) {// Remove the CityRecord and the name of the cityint addr = buffer.getInt();Handle cityhandle = new Handle(addr);removeCityRecordHandle(cityhandle);}}memoryManager.remove(handle);}public void removeCityRecordHandle(Handle handle) {// Remove the handle to the city namebyte[] data = new byte[memoryManager.getDataBlockSize(handle)];memoryManager.get(data, handle);ByteBuffer cityrecord = ByteBuffer.wrap(data);Handle name = new Handle(cityrecord.getInt(8));memoryManager.remove(name);memoryManager.remove(handle);}// Resets the empty block list in the memory manager to the size of the filepublic void clearMemory() {memoryManager.clear();}// Print debug info from the memory managerpublic void printDebug() {memoryManager.printBuffer();memoryManager.dump();}// Allocates the node onto disk and returns a handle to the nodepublic Handle nodeToHandle(PRQuadTreeNode node) {if (node instanceof PRQuadTreeNodeInternal) {byte[] array = nodeInternalToByteArray((PRQuadTreeNodeInternal)node);Handle ret = memoryManager.insert(array, array.length);return ret;} else if (node instanceof PRQuadTreeNodeLeaf) {byte[] array = nodeLeafToByteArray((PRQuadTreeNodeLeaf)node);Handle ret = memoryManager.insert(array, array.length);return ret;} else {Handle ret = new Handle(-1);return ret;}}// Reads a handle off the disk and returns the correspondingpublic PRQuadTreeNode handleToNode(Handle handle) {if (handle.getAddress() == -1) {PRQuadTreeNodeFlyweight ret = new PRQuadTreeNodeFlyweight();return ret;} else {byte[] array = new byte[memoryManager.getDataBlockSize(handle)];memoryManager.get(array, handle);return byteArrayToNode(array);}}private byte[] stringToByteArray(String str) {// Use ByteBuffer to serialize to bytesbyte[] byteArray = new byte[str.length() + 1];byte[] bstr = str.getBytes();ByteBuffer buffer = ByteBuffer.wrap(byteArray);// Set first byte as the lengthbuffer.put((byte)bstr.length);// Set remaining bytes as the stringbuffer.put(bstr);return byteArray;}private byte[] nodeInternalToByteArray(PRQuadTreeNodeInternal node) {byte[] byteArray = new byte[17];ByteBuffer buffer = ByteBuffer.wrap(byteArray);buffer.put((byte)1);buffer.putInt((int)node.getNW().getAddress());buffer.putInt((int)node.getNE().getAddress());buffer.putInt((int)node.getSW().getAddress());buffer.putInt((int)node.getSE().getAddress());return byteArray;}private byte[] nodeLeafToByteArray(PRQuadTreeNodeLeaf node) {byte[] byteArray = new byte[14];ByteBuffer buffer = ByteBuffer.wrap(byteArray);// Set first byte to indicate leaf nodebuffer.put((byte)0);// Set second byte to hold number of recordsbuffer.put((byte)node.getCount());CityRecord record = (CityRecord) node.getFirst();buffer.putInt((int)cityRecordToHandle(record).getAddress());record = (CityRecord) node.getNext(record);while (record != null) {buffer.putInt((int)cityRecordToHandle(record).getAddress());record = (CityRecord) node.getNext(record);}return byteArray;}private String byteArrayToString(byte[] byteArray) {ByteBuffer buffer = ByteBuffer.wrap(byteArray);byte[] bstr = new byte[(int)buffer.get()];buffer.get(bstr);String str = new String(bstr);return str;}private PRQuadTreeNode byteArrayToNode(byte[] data) {ByteBuffer buffer = ByteBuffer.wrap(data);// Internal nodebyte b = buffer.get();if (b == (byte)1) {PRQuadTreeNodeInternal newNode = new PRQuadTreeNodeInternal(new Handle(-1), this);Handle NW = new Handle(buffer.getInt());Handle NE = new Handle(buffer.getInt());Handle SW = new Handle(buffer.getInt());Handle SE = new Handle(buffer.getInt());newNode.setNW(NW);newNode.setNE(NE);newNode.setSW(SW);newNode.setSE(SE);return newNode;// Leaf node} else if (b == (byte)0) {PRQuadTreeNodeLeaf newNode = new PRQuadTreeNodeLeaf(3);int records = (int)buffer.get();for (int i = 0; i < records; i++) {int address = buffer.getInt();Handle handle = new Handle(address);CityRecord record = handleToCityRecord(handle);newNode.insert(record);}return newNode;} else {return null;}}public Handle cityRecordToHandle(CityRecord record) {byte[] data = new byte[12];ByteBuffer buffer = ByteBuffer.wrap(data);byte[] cityname = stringToByteArray(record.getName());Handle handle = memoryManager.insert(cityname, cityname.length);buffer.putInt(record.getX());buffer.putInt(record.getY());buffer.putInt((int)handle.getAddress());Handle ret = memoryManager.insert(data, 12);return ret;}public CityRecord handleToCityRecord(Handle handle) {byte[] data = new byte[12];memoryManager.get(data, handle);ByteBuffer buffer = ByteBuffer.wrap(data);int x = buffer.getInt();int y = buffer.getInt();int addr = buffer.getInt();Handle cityhandle = new Handle(addr);byte[] city = new byte[memoryManager.getDataBlockSize(cityhandle)];memoryManager.get(city, cityhandle);String cityname = byteArrayToString(city);CityRecord record = new CityRecord(cityname, x, y);return record;}}