/** Unit test for TupleDesc.combine() */ @Test public void combine() { TupleDesc td1, td2, td3; td1 = Utility.getTupleDesc(1, "td1"); td2 = Utility.getTupleDesc(2, "td2"); // test td1.combine(td2) td3 = TupleDesc.merge(td1, td2); assertEquals(3, td3.numFields()); assertEquals(3 * Type.INT_TYPE.getLen(), td3.getSize()); for (int i = 0; i < 3; ++i) assertEquals(Type.INT_TYPE, td3.getFieldType(i)); assertEquals(combinedStringArrays(td1, td2, td3), true); // test td2.combine(td1) td3 = TupleDesc.merge(td2, td1); assertEquals(3, td3.numFields()); assertEquals(3 * Type.INT_TYPE.getLen(), td3.getSize()); for (int i = 0; i < 3; ++i) assertEquals(Type.INT_TYPE, td3.getFieldType(i)); assertEquals(combinedStringArrays(td2, td1, td3), true); // test td2.combine(td2) td3 = TupleDesc.merge(td2, td2); assertEquals(4, td3.numFields()); assertEquals(4 * Type.INT_TYPE.getLen(), td3.getSize()); for (int i = 0; i < 4; ++i) assertEquals(Type.INT_TYPE, td3.getFieldType(i)); assertEquals(combinedStringArrays(td2, td2, td3), true); }
/** * 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(); }
/** Suck up tuples from the source file. */ private Tuple readNextTuple(DataInputStream dis, int slotId) throws NoSuchElementException { // if associated bit is not set, read forward to the next tuple, and // return null. if (!getSlot(slotId)) { for (int i = 0; i < td.getSize(); i++) { try { dis.readByte(); } catch (IOException e) { throw new NoSuchElementException("error reading empty tuple"); } } return null; } // read fields in the tuple Tuple t = new Tuple(td); RecordID rid = new RecordID(pid, slotId); t.setRecordID(rid); try { for (int j = 0; j < td.numFields(); j++) { Field f = td.getType(j).parse(dis); t.setField(j, f); } } catch (java.text.ParseException e) { // e.printStackTrace(); throw new NoSuchElementException("parsing error!"); } return t; }
// Test mix of INT_TYPE and STRING_TYPE. @Test public void new_getSizeTest() { Type[] typeAr = new Type[] {Type.INT_TYPE, Type.INT_TYPE, Type.STRING_TYPE, Type.STRING_TYPE}; String[] fieldAr = new String[] {"number0", "number1", "string0", "string1"}; TupleDesc td = new TupleDesc(typeAr, fieldAr); int length = 2 * Type.INT_TYPE.getLen() + 2 * Type.STRING_TYPE.getLen(); assertEquals(length, td.getSize()); }
/** Unit test for TupleDesc.getSize() */ @Test public void getSize() { int[] lengths = new int[] {1, 2, 1000}; for (int len : lengths) { TupleDesc td = Utility.getTupleDesc(len); assertEquals(len * Type.INT_TYPE.getLen(), td.getSize()); } }
/** * Helper constructor to create a heap page to be used as buffer. * * @param data - Data to be put in tmp page * @param td - Tuple description for the corresponding table. * @throws IOException */ private HeapPage(byte[] data, TupleDesc td) throws IOException { this.pid = null; // No need of a pid here as this page serves as a dummy buffer page and is meant to be // used independent of BufferManager. this.td = td; this.numSlots = (BufferPool.PAGE_SIZE * 8) / ((td.getSize() * 8) + 1); DataInputStream dis = new DataInputStream(new ByteArrayInputStream(data)); this.header = new Header(dis); try { // allocate and read the actual records of this page tuples = new Tuple[numSlots]; for (int i = 0; i < numSlots; i++) { tuples[i] = readNextTuple(dis, i); } } catch (NoSuchElementException e) { e.printStackTrace(); } dis.close(); }
/** * Create a HeapPage from a set of bytes of data read from disk. The format of a HeapPage is a set * of 32-bit header words indicating the slots of the page that are in use, plus * (BufferPool.PAGE_SIZE/tuple size) tuple slots, where tuple size is the size of tuples in this * database table, which can be determined via {@link Catalog#getTupleDesc}. * * <p>The number of 32-bit header words is equal to: * * <p>(no. tuple slots / 32) + 1 * * <p> * * @see Database#getCatalog * @see Catalog#getTupleDesc * @see BufferPool#PAGE_SIZE */ public HeapPage(HeapPageId id, byte[] data) throws IOException { this.pid = id; this.td = Database.getCatalog().getTupleDesc(id.tableid()); // this.numSlots = (BufferPool.PAGE_SIZE) / (td.getSize()); this.numSlots = (BufferPool.PAGE_SIZE * 8) / ((td.getSize() * 8) + 1); // System.out.println(this.numSlots); DataInputStream dis = new DataInputStream(new ByteArrayInputStream(data)); // allocate and read the header slots of this page header = new Header(dis); try { // allocate and read the actual records of this page tuples = new Tuple[numSlots]; for (int i = 0; i < numSlots; i++) { tuples[i] = readNextTuple(dis, i); } } catch (NoSuchElementException e) { // e.printStackTrace(); } dis.close(); }
/** * Retrieve the number of tuples on this page. * * @return the number of tuples on this page */ private int getNumTuples() { // some code goes here int tupsPerPage = (BufferPool.PAGE_SIZE * 8) / ((td.getSize() * 8) + 1); // default to be floor return tupsPerPage; }
/** * Retrieve the number of tuples on this page. * * @return the number of tuples on this page */ private int getNumTuples() { // hdj return BufferPool.PAGE_SIZE * 8 / (td.getSize() * 8 + 1); }