[关闭]
@w1024020103 2017-03-14T12:38:44.000000Z 字数 3784 阅读 521

Proj2 Operators

CS61B


Operators

运算符

Operators are responsible for the actual execution of the query plan. They implement the operations of the relational algebra. In DB, operators are iterator based; each operator implements the DbIterator interface.
Operators are connected together into a plan by passing lower-level operators into the constructors of higher-level operators, i.e., by 'chaining them together.' Special access method operators at the leaves of the plan are responsible for reading data from the disk (and hence do not have any operators below them).
运算符负责了查询方法的实际执行。他们实施有理代数的运算。在DB里,运算符是以iterator为根基的;每个运算符都implements DbIterator接口。
运算符连接在一起,通过将低级别的运算符传给高级别的运算符的构造器这种方式形成一个查询方法。 换句话说,就是将他们连在一起。处于方法级别的特殊访问权限的运算符负责从磁盘读取数据(所以他们没有低于他们的任何运算符)

At the top of the plan, the program interacting with DB simply calls getNext on the root operator; this operator then calls getNext on its children, and so on, until these leaf operators are called. They fetch tuples from disk and pass them up the tree (as return arguments to getNext); tuples propagate up the plan in this way until they are output at the root or combined or rejected by another operator in the plan.
在plan的顶部,程序通过调用根运算符上的getNext方法与DB互动;然后这个运算符对其子运算符调用getNext,以此类推,知道这些分支运算符被调用。他们从磁盘获取rows然后把这些rows传递给trees(作为getNext返回的参数);rows通过这种方式传播到方法顶端,直到他们从根部输出,或者是被plan里的另一个运算符结合或是拒绝。

For this lab, you will only need to implement one SimpleDB operator.
Exercise 6. Implement the skeleton methods in:
src/java/simpledb/SeqScan.java
This operator sequentially scans all of the tuples from the pages of the table specified by the tableid in the constructor. This operator should access tuples through the DbFile.iterator() method.
At this point, you should be able to complete the ScanTest system test. Good work!
You will fill in other operators in subsequent labs.
SeqScan运算符会按顺序扫描指定table的pages里的所有rows,这个table由构造器里的tableid指定。这个运算符应该通过DbFile.iterator() method来访问row。

注意读题,题目说SeqScan这个运算发要通过DbFile.iterator(),来访问table的pages里面的row。而这个DbFile.iterator()返回的是一个DbFileIterator。所以我们自然地想到该类成员变量有一个DbFile,跟一个DbFileIterator。

  1. public class SeqScan implements DbIterator {
  2. private TransactionId tid;
  3. private int tableid;
  4. private String tableAlias;
  5. private DbFile dbfile;
  6. private DbFileIterator dbFileIterator;

那么应该如何得到这个table对应的DbFile呢?
我们现在又tableid,通过Catalog里的getDbFile(tableid)可以达到目的:

  1. this.dbfile = Database.getCatalog().getDbFile(tableid);
  2. this.dbFileIterator = this.dbfile.iterator(tid);

然后reset(int tableid, String tableAlias)的时候,注意一下相应的DbFile和DbFileIterator也应该相应的重置:

  1. /**
  2. * Reset the tableid, and tableAlias of this operator.
  3. *
  4. */
  5. public void reset(int tableid, String tableAlias) {
  6. // some code goes here
  7. this.tableid = tableid;
  8. this.tableAlias = tableAlias;
  9. this.dbfile = Database.getCatalog().getDbFile(this.tableid);
  10. this.dbFileIterator = this.dbfile.iterator(tid);
  11. }

接下来留意一下getRowDesc这个方法,我一开始没读懂题目,以为要返回的RowDesc是由prefix tableAias和Column names组成,那column type就不在了,那要怎么写啊?事实证明我完全没领会题意,也把事情想复杂了。题目的意思是返回一个RowDesc,要求它的column names要加上一个tableAlias的字符串前缀,并没提到要删除Type,也就是只管返回Column names和Column Types,无非是names现在前面多了个前缀。而且前面人家也下清楚了要求的格式:tableAlias.columnName

  1. @param tableAlias
  2. * the alias of this table (needed by the parser); the returned
  3. * RowDesc should have fields with name tableAlias.fieldName
  4. * (note: this class is not responsible for handling a case where
  5. * tableAlias or fieldName are null. It shouldn't crash if they
  6. * are, but the resulting name can be null.fieldName,
  7. * tableAlias.null, or null.null).

一旦搞清楚题意,写代码很简单:

  1. /**
  2. * Returns the RowDesc with field names from the underlying HeapFile,
  3. * prefixed with the tableAlias string from the constructor. This prefix
  4. * becomes useful when joining tables containing a field(s) with the same
  5. * name.
  6. *
  7. * @return the RowDesc with field names from the underlying HeapFile,
  8. * prefixed with the tableAlias string from the constructor.
  9. */
  10. public RowDesc getRowDesc() {
  11. // some code goes here
  12. RowDesc origRowDesc = Database.getCatalog().getRowDesc(this.tableid);
  13. int rdsize = origRowDesc.numColumns();
  14. Type [] newTypes = new Type[rdsize];
  15. String [] newColNames = new String[rdsize];
  16. for(int i = 0; i < rdsize; i++){
  17. newTypes [i] = origRowDesc.getColumnType(i);
  18. newColNames [i] = tableAlias +"." + origRowDesc.getColumnName(i);
  19. }
  20. return new RowDesc(newTypes, newColNames);
  21. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注