/**
   * Create a DbIterator over group aggregate results.
   *
   * @return a DbIterator whose tuples are the pair (groupVal, aggregateVal) if using group, or a
   *     single (aggregateVal) if no grouping. The aggregateVal is determined by the type of
   *     aggregate specified in the constructor.
   */
  public DbIterator iterator() {
    /* TODO: write about iterator() call recalculates all the aggregates, which seems necessary given how the test case is formulated
    (merge one tuple, get iterator, expect the result to be updated). Note that recalculate is not necessary unless the source tuples
    change, but as a simplification here we implement it like this. */
    TupleDesc td;
    ArrayList<Tuple> tuples = new ArrayList<Tuple>();

    if (isGrouping()) {
      Type[] typeAr = new Type[2];
      typeAr[0] = this.gbFieldType;
      typeAr[1] = Type.INT_TYPE;
      td = new TupleDesc(typeAr);

      for (Map.Entry<Field, ArrayList<IntField>> entry : this.tupleStorage.entrySet()) {
        IntField aggregate = this.getAggregate(entry.getValue());
        Tuple tup = new Tuple(td);
        tup.setField(0, entry.getKey());
        tup.setField(1, aggregate);
        tuples.add(tup);
      }
    } else {
      Type[] typeAr = new Type[1];
      typeAr[0] = Type.INT_TYPE;
      td = new TupleDesc(typeAr);

      Tuple tup = new Tuple(td);
      tup.setField(0, this.getAggregate(this.tupleStorageNoGrouping));
      tuples.add(tup);
    }

    TupleIterator iterator = new TupleIterator(td, tuples);
    return iterator;
  }
示例#2
0
  /**
   * Inserts tuples read from child into the tableid specified by the constructor. It returns a one
   * field tuple containing the number of inserted records. Inserts should be passed through
   * BufferPool. An instances of BufferPool is available via Database.getBufferPool(). Note that
   * insert DOES NOT need check to see if a particular tuple is a duplicate before inserting it.
   *
   * @return A 1-field tuple containing the number of inserted records, or null if called more than
   *     once.
   * @see Database#getBufferPool
   * @see BufferPool#insertTuple
   */
  protected Tuple fetchNext() throws TransactionAbortedException, DbException {
    Tuple result = new Tuple(td); // use to store the insertion result
    int count = 0; // use to keep track of numbers of tuple insertion

    if (fetchNextNum
        > 0) // meaning this is not the first time calling fetchNext(), and should not return any
             // tuples
    return null;
    else {
      try {
        while (dbIt.hasNext()) {
          try {
            Database.getBufferPool().insertTuple(tranId, tableId, dbIt.next());
          } catch (IOException e) {
            e.printStackTrace();
          }
          count++;
        }

        result.setField(0, new IntField(count));
        fetchNextNum++;
      } catch (DbException e) {
        e.printStackTrace();
      } catch (TransactionAbortedException e) {
        e.printStackTrace();
      }
    }
    return result;
  }
示例#3
0
  /** 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;
  }
示例#4
0
  /** Unit test for Tuple.getField() and Tuple.setField() */
  @Test
  public void modifyFields() {
    TupleDesc td = Utility.getTupleDesc(2);

    Tuple tup = new Tuple(td);
    tup.setField(0, new IntField(-1));
    tup.setField(1, new IntField(0));

    assertEquals(new IntField(-1), tup.getField(0));
    assertEquals(new IntField(0), tup.getField(1));

    tup.setField(0, new IntField(1));
    tup.setField(1, new IntField(37));

    assertEquals(new IntField(1), tup.getField(0));
    assertEquals(new IntField(37), tup.getField(1));
  }
  /**
   * Create a DbIterator over group aggregate results.
   *
   * @return a DbIterator whose tuples are the pair (groupVal, aggregateVal) if using group, or a
   *     single (aggregateVal) if no grouping. The aggregateVal is determined by the type of
   *     aggregate specified in the constructor.
   */
  public DbIterator iterator() {
    // some code goes here
    // throw new
    // UnsupportedOperationException("please implement me for lab2");

    ArrayList<Tuple> tuplearray = new ArrayList<Tuple>();

    if (m_gbfield == Aggregator.NO_GROUPING) {
      Tuple newtuple = new Tuple(m_td);

      if (m_op == Op.AVG) {
        newtuple.setField(0, new IntField(m_aggmap.get(null).value / m_aggmap.get(null).count));
      } else if (m_op == Op.COUNT) {
        newtuple.setField(0, new IntField(m_aggmap.get(null).count));
      } else {
        newtuple.setField(0, new IntField(m_aggmap.get(null).value));
      }
      tuplearray.add(newtuple);
    } else {
      for (Field fieldkey : m_aggmap.keySet()) {
        Tuple newtuple = new Tuple(m_td);
        newtuple.setField(0, fieldkey);

        // calculate average now
        if (m_op == Op.AVG) {
          newtuple.setField(
              1, new IntField(m_aggmap.get(fieldkey).value / m_aggmap.get(fieldkey).count));
        } else if (m_op == Op.COUNT) {
          newtuple.setField(1, new IntField(m_aggmap.get(fieldkey).count));
        } else newtuple.setField(1, new IntField(m_aggmap.get(fieldkey).value));
        tuplearray.add(newtuple);
      }
    }
    return new TupleIterator(m_td, tuplearray);
  }
示例#6
0
  /**
   * Create a DbIterator over group aggregate results.
   *
   * @return a DbIterator whose tuples are the pair (groupVal, aggregateVal) if using group, or a
   *     single (aggregateVal) if no grouping. The aggregateVal is determined by the type of
   *     aggregate specified in the constructor.
   */
  public DbIterator iterator() {
    // TODO: This current shares a ton of code of with StringAggregator.
    // Refactor?
    ArrayList<Tuple> aggregateTuples = new ArrayList<Tuple>();
    TupleDesc tupleDesc = this.getTupleDesc();

    for (Map.Entry<Field, Integer> entry : this.groups.entrySet()) {
      Field key = entry.getKey();
      Integer value = entry.getValue();
      if (this.op == Op.AVG) {
        value /= this.counts.get(key);
      }
      Tuple tuple = new Tuple(tupleDesc);

      if (this.groupByField == NO_GROUPING) {
        tuple.setField(0, new IntField(value));
      } else {
        tuple.setField(0, key);
        tuple.setField(1, new IntField(value));
      }
      aggregateTuples.add(tuple);
    }
    return new TupleIterator(tupleDesc, aggregateTuples);
  }
示例#7
0
 public Tuple getNext() throws NoSuchElementException, TransactionAbortedException {
   try {
     Tuple tuple = new Tuple(td);
     for (int i = 0; i < td.numFields(); i++) {
       IntField intf = IntField.createIntField(in.readInt());
       tuple.setField(i, intf);
     }
     return tuple;
   } catch (EOFException eof) {
     throw new NoSuchElementException(eof.getMessage());
   } catch (Exception e) {
     e.printStackTrace();
     BufferPool.Instance().abortTransaction(tid);
     closeConnection();
     throw new TransactionAbortedException(e);
   }
 }
示例#8
0
  /** Unit test for fields() iterator */
  @Test
  public void fields() {

    int numfields = 4;
    TupleDesc td = Utility.getTupleDesc(numfields);

    // set up the tuple
    Tuple tup = new Tuple(td);
    for (int i = 0; i < numfields; i++) tup.setField(i, new IntField(i));

    // use the iterator, make sure get the same number of fields out
    Iterator<Field> iter = tup.fields();
    int count = 0;
    while (iter.hasNext()) {
      iter.next();
      count++;
    }
    assertEquals(numfields, count);
  }
  @Test
  public void new_toStringTest() {
    int length = 10;
    String name = "td";
    Tuple t = new Tuple(Utility.getTupleDesc(length, name));
    for (int i = 0; i < length; i++) {
      t.setField(i, new TestField());
    }

    String tString = t.toString();

    // Last character should be \n.
    assertEquals("\n", tString.substring(tString.length() - 1));

    // Only last character is \n.
    assertFalse(tString.substring(0, tString.length() - 1).contains("\n"));

    // Split string on any white character.
    String[] tStringAr = tString.substring(0, tString.length() - 1).split("\\s+");
    assertEquals(length, tStringAr.length);
  }
示例#10
0
 /**
  * Inserts tuples read from child into the relation with the tableid specified by the constructor.
  * It returns a one field tuple containing the number of inserted records (even if there are 0!).
  * Insertions should be passed through BufferPool.insertTuple() with the TransactionId from the
  * constructor. An instance of BufferPool is available via Database.getBufferPool(). Note that
  * insert DOES NOT need to check to see if a particular tuple is a duplicate before inserting it.
  *
  * <p>This operator should keep track if its fetchNext() has already been called, returning null
  * if called multiple times.
  *
  * @return A 1-field tuple containing the number of inserted records, or null if called more than
  *     once.
  * @see Database#getBufferPool
  * @see BufferPool#insertTuple
  */
 protected Tuple fetchNext() throws TransactionAbortedException, DbException {
   if (!hasFetched) {
     this.hasFetched = true;
     int numInserts = 0;
     while (this.child.hasNext()) {
       Tuple t = this.child.next();
       try {
         Database.getBufferPool().insertTuple(this.tid, this.tableid, t);
         numInserts += 1;
       } catch (IOException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
       }
     }
     Type[] fields = new Type[1];
     fields[0] = Type.INT_TYPE;
     TupleDesc td = new TupleDesc(fields);
     Tuple newTuple = new Tuple(td);
     newTuple.setField(0, new IntField(numInserts));
     return newTuple;
   } else {
     return null;
   }
 }