/** * Generates a byte array representing the contents of this page. Used to serialize this page to * disk. * * <p>The invariant here is that it should be possible to pass the byte array generated by * getPageData to the HeapPage constructor and have it produce an identical HeapPage object. * * @see #HeapPage * @return A byte array correspond to the bytes of this page. */ public byte[] getPageData() { // int len = header.length*4 + BufferPool.PAGE_SIZE; int len = BufferPool.PAGE_SIZE; ByteArrayOutputStream baos = new ByteArrayOutputStream(len); DataOutputStream dos = new DataOutputStream(baos); // create the header of the page try { dos.write(header.getHeader()); } catch (IOException e) { // this really shouldn't happen e.printStackTrace(); } // create the tuples for (int i = 0; i < numSlots; i++) { // empty slot if (!getSlot(i)) { for (int j = 0; j < td.getSize(); j++) { try { dos.writeByte(0); } catch (IOException e) { e.printStackTrace(); } } continue; } // non-empty slot for (int j = 0; j < td.numFields(); j++) { Field f = tuples[i].getField(j); try { f.serialize(dos); } catch (IOException e) { e.printStackTrace(); } } } // padding int zerolen = BufferPool.PAGE_SIZE - numSlots * td.getSize() - header.length(); byte[] zeroes = new byte[zerolen]; try { dos.write(zeroes, 0, zerolen); } catch (IOException e) { e.printStackTrace(); } try { dos.flush(); } catch (IOException e) { e.printStackTrace(); } return baos.toByteArray(); }
/** * Serializa el registro escribiéndolo en un stream de salida. * * @param stream Stream de salida. * @return Cantidad de bytes escrito. * @throws RecordSerializationException */ public long serialize(OutputStream stream) throws RecordSerializationException { long byteCount = 0; byte hash = 0; try { for (Field field : this.getFields()) { byte[] serialize = field.serialize(); stream.write(serialize); byteCount += serialize.length; // modifica el hash actual con los datos de la serialización del campo hash = calculateHash(hash, serialize); } // graba el hash al final stream.write(new byte[] {hash}); } catch (IOException e) { throw new RecordSerializationException(); } return byteCount; }
/** * Deserializa el registro a partir de un stream de entrada. * * @param stream Stream de entrada. * @return Cantidad de bytes leido. * @throws RecordSerializationException */ public long deserialize(InputStream stream) throws RecordSerializationException { long byteCount = 0; byte calculatedHash = 0; byte deserializedHash = 0; try { for (Field field : this.getFields()) { byteCount += field.deserialize(stream); // agrega al hash actual el hash del campo calculatedHash = calculateHash(calculatedHash, field.serialize()); } // carga el hash serializado deserializedHash = (byte) stream.read(); } catch (IOException e) { throw new RecordSerializationException(e); } if (deserializedHash != calculatedHash) { throw new RecordSerializationCorruptDataException("Record", deserializedHash, calculatedHash); } return byteCount; }