简介及类图TupleDesc.javaTuple.javaCatalog.javaBufferPool.javaSeqSacn.java
简介及类图第一个lab主要是熟悉一下项目结构,完善一下几个简单的基础类,除了SeqScan需要自己写Iterator之外难度不大
package simpledb.storage;
import simpledb.common.Type;
import java.io.Serializable;
import java.util.*;
public class TupleDesc implements Serializable {
private final TDItem[] tdItems;
public static class TDItem implements Serializable {
private static final long serialVersionUID = 1L;
public final Type fieldType;
public final String fieldName;
public TDItem(Type t, String n) {
this.fieldName = n;
this.fieldType = t;
}
public String toString() {
return fieldName + "(" + fieldType + ")";
}
}
public Iterator iterator() {
// some code goes here
return null;
}
private static final long serialVersionUID = 1L;
public TupleDesc(Type[] typeAr, String[] fieldAr) {
// some code goes here
tdItems = new TDItem[typeAr.length];
for(int i=0;i< typeAr.length;i++){
tdItems[i] = new TDItem(typeAr[i],fieldAr[i]);
}
}
public TupleDesc(Type[] typeAr) {
// some code goes here
tdItems = new TDItem[typeAr.length];
for(int i=0;i< typeAr.length;i++){
tdItems[i] = new TDItem(typeAr[i],"");
}
}
public int numFields() {
// some code goes here
return tdItems.length;
}
public String getFieldName(int i) throws NoSuchElementException {
// some code goes here
if(i<0||i>= tdItems.length){
throw new NoSuchElementException();
}
return tdItems[i].fieldName;
}
public Type getFieldType(int i) throws NoSuchElementException {
// some code goes here
if(i<0||i>=tdItems.length){
throw new NoSuchElementException();
}
return tdItems[i].fieldType;
}
public int fieldNameToIndex(String name) throws NoSuchElementException {
// some code goes here
for(int i=0;i
Tuple.java
package simpledb.storage;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Iterator;
public class Tuple implements Serializable {
private static final long serialVersionUID = 1L;
private TupleDesc tupleDesc;
private RecordId recordId;
private final Field[] fields;
public Tuple(TupleDesc td) {
// some code goes here
tupleDesc = td;
fields = new Field[td.numFields()];
}
public TupleDesc getTupleDesc() {
// some code goes here
return tupleDesc;
}
public RecordId getRecordId() {
// some code goes here
return recordId;
}
public void setRecordId(RecordId rid) {
// some code goes here
recordId = rid;
}
public void setField(int i, Field f) {
// some code goes here
fields[i] = f;
}
public Field getField(int i) {
// some code goes here
return fields[i];
}
public String toString() {
StringBuilder sb = new StringBuilder();
for(int i=0;i fields()
{
// some code goes here
return Arrays.stream(fields).iterator();
}
public void resetTupleDesc(TupleDesc td)
{
// some code goes here
tupleDesc = td;
}
}
Catalog.java
package simpledb.common;
import simpledb.common.Type;
import simpledb.storage.DbFile;
import simpledb.storage.HeapFile;
import simpledb.storage.TupleDesc;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
public class Catalog {
private static final long serialVersionUID = 1L;
private final ConcurrentHashMap hashTable;
private static class Table{
private static final long serialVersionUID = 1L;
public final DbFile dbFile;
public final String tableName;
public final String pk;
public Table(DbFile file,String name,String pkeyField){
dbFile = file;
tableName = name;
pk = pkeyField;
}
public String toString(){
return tableName + "(" + dbFile.getId() + ":" + pk +")";
}
}
public Catalog() {
hashTable = new ConcurrentHashMap();
}
public void addTable(DbFile file, String name, String pkeyField) {
// some code goes here
Table t = new Table(file,name,pkeyField);
hashTable.put(file.getId(),t);
}
public void addTable(DbFile file, String name) {
addTable(file, name, "");
}
public void addTable(DbFile file) {
addTable(file, (UUID.randomUUID()).toString());
}
public int getTableId(String name) throws NoSuchElementException {
// some code goes here
var ret = hashTable.searchValues(1,value->{
if(value.tableName.equals(name)) return value.dbFile.getId();
return null;
});
return 0;
}
public TupleDesc getTupleDesc(int tableid) throws NoSuchElementException {
// some code goes here
var t = hashTable.getOrDefault(tableid,null);
if(t!=null){
return t.dbFile.getTupleDesc();
}else{
throw new NoSuchElementException();
}
}
public DbFile getDatabaseFile(int tableid) throws NoSuchElementException {
// some code goes here
Table t = hashTable.getOrDefault(tableid,null);
if(t != null){
return t.dbFile;
}else{
throw new NoSuchElementException("not found db file for table " + tableid);
}
}
public String getPrimaryKey(int tableid) {
Table t = hashTable.getOrDefault(tableid,null);
if(t != null){
return t.pk;
}else{
throw new NoSuchElementException("not found primary key for table " + tableid);
}
}
public Iterator tableIdIterator() {
// 返回一个内部引用,并且指向一个内部类对象,该内部类重写了迭代器方法
return hashTable.keySet().iterator();
}
public String getTableName(int id) {
// some code goes here
Table t = hashTable.getOrDefault(id,null);
if(t != null){
return t.tableName;
}else{
throw new NoSuchElementException("not found name for table " + id);
}
}
public void clear() {
// some code goes here
hashTable.clear();
}
public void loadSchema(String catalogFile) {
String line = "";
String baseFolder=new File(new File(catalogFile).getAbsolutePath()).getParent();
try {
BufferedReader br = new BufferedReader(new FileReader(catalogFile));
while ((line = br.readLine()) != null) {
//assume line is of the format name (field type, field type, ...)
String name = line.substring(0, line.indexOf("(")).trim();
//System.out.println("TABLE NAME: " + name);
String fields = line.substring(line.indexOf("(") + 1, line.indexOf(")")).trim();
String[] els = fields.split(",");
ArrayList names = new ArrayList<>();
ArrayList types = new ArrayList<>();
String primaryKey = "";
for (String e : els) {
String[] els2 = e.trim().split(" ");
names.add(els2[0].trim());
if (els2[1].trim().equalsIgnoreCase("int"))
types.add(Type.INT_TYPE);
else if (els2[1].trim().equalsIgnoreCase("string"))
types.add(Type.STRING_TYPE);
else {
System.out.println("Unknown type " + els2[1]);
System.exit(0);
}
if (els2.length == 3) {
if (els2[2].trim().equals("pk"))
primaryKey = els2[0].trim();
else {
System.out.println("Unknown annotation " + els2[2]);
System.exit(0);
}
}
}
Type[] typeAr = types.toArray(new Type[0]);
String[] namesAr = names.toArray(new String[0]);
TupleDesc t = new TupleDesc(typeAr, namesAr);
HeapFile tabHf = new HeapFile(new File(baseFolder+"/"+name + ".dat"), t);
addTable(tabHf,name,primaryKey);
System.out.println("Added table : " + name + " with schema " + t);
}
} catch (IOException e) {
e.printStackTrace();
System.exit(0);
} catch (IndexOutOfBoundsException e) {
System.out.println ("Invalid catalog entry : " + line);
System.exit(0);
}
}
}
BufferPool.java
package simpledb.storage;
import simpledb.common.Database;
import simpledb.common.Permissions;
import simpledb.common.DbException;
import simpledb.common.DeadlockException;
import simpledb.transaction.TransactionAbortedException;
import simpledb.transaction.TransactionId;
import java.io.*;
import java.util.concurrent.ConcurrentHashMap;
public class BufferPool {
private static final int DEFAULT_PAGE_SIZE = 4096;
private static int pageSize = DEFAULT_PAGE_SIZE;
public static final int DEFAULT_PAGES = 50;
private final int numPages;
private final ConcurrentHashMap pageStore;
public BufferPool(int numPages) {
// some code goes here
this.numPages = numPages;
pageStore = new ConcurrentHashMap();
}
public static int getPageSize() {
return pageSize;
}
// THIS FUNCTION SHOULD onLY BE USED FOR TESTING!!
public static void setPageSize(int pageSize) {
BufferPool.pageSize = pageSize;
}
// THIS FUNCTION SHOULD onLY BE USED FOR TESTING!!
public static void resetPageSize() {
BufferPool.pageSize = DEFAULT_PAGE_SIZE;
}
public Page getPage(TransactionId tid, PageId pid, Permissions perm)
throws TransactionAbortedException, DbException {
// some code goes here
Page ret = null;
if(!pageStore.contains(pid.hashCode())){
var dbFile = Database.getCatalog().getDatabaseFile(pid.getTableId());
var page = dbFile.readPage(pid);
ret = page;
pageStore.put(pid.hashCode(),page);
}
return ret==null?pageStore.get(pid.hashCode()):ret;
}
public void unsafeReleasePage(TransactionId tid, PageId pid) {
// some code goes here
// not necessary for lab1|lab2
}
public void transactionComplete(TransactionId tid) {
// some code goes here
// not necessary for lab1|lab2
}
public boolean holdsLock(TransactionId tid, PageId p) {
// some code goes here
// not necessary for lab1|lab2
return false;
}
public void transactionComplete(TransactionId tid, boolean commit) {
// some code goes here
// not necessary for lab1|lab2
}
public void insertTuple(TransactionId tid, int tableId, Tuple t)
throws DbException, IOException, TransactionAbortedException {
// some code goes here
// not necessary for lab1
}
public void deleteTuple(TransactionId tid, Tuple t)
throws DbException, IOException, TransactionAbortedException {
// some code goes here
// not necessary for lab1
}
public synchronized void flushAllPages() throws IOException {
// some code goes here
// not necessary for lab1
}
public synchronized void discardPage(PageId pid) {
// some code goes here
// not necessary for lab1
}
private synchronized void flushPage(PageId pid) throws IOException {
// some code goes here
// not necessary for lab1
}
public synchronized void flushPages(TransactionId tid) throws IOException {
// some code goes here
// not necessary for lab1|lab2
}
private synchronized void evictPage() throws DbException {
// some code goes here
// not necessary for lab1
}
}
SeqSacn.java
package simpledb.execution;
import simpledb.common.Database;
import simpledb.storage.DbFileIterator;
import simpledb.transaction.Transaction;
import simpledb.transaction.TransactionAbortedException;
import simpledb.transaction.TransactionId;
import simpledb.common.DbException;
import simpledb.storage.Tuple;
import simpledb.storage.TupleDesc;
import javax.xml.crypto.Data;
import java.util.*;
public class SeqScan implements OpIterator {
private static final long serialVersionUID = 1L;
private final TransactionId tid;
private int tableId;
private String tableAlias;
private DbFileIterator it;
public SeqScan(TransactionId tid, int tableid, String tableAlias) {
// some code goes here
this.tid = tid;
this.tableId = tableid;
this.tableAlias = tableAlias;
}
public String getTableName() {
return Database.getCatalog().getTableName(tableId);
}
public String getAlias()
{
// some code goes here
return tableAlias;
}
public void reset(int tableid, String tableAlias) {
// some code goes here
this.tableId = tableid;
this.tableAlias = tableAlias;
}
public SeqScan(TransactionId tid, int tableId, Transaction tid1, Transaction tid2, TransactionId tid3) {
this(tid, tableId, Database.getCatalog().getTableName(tableId));
}
public void open() throws DbException, TransactionAbortedException {
// some code goes here
it = Database.getCatalog().getDatabaseFile(tableId).iterator(tid);
it.open();
}
public TupleDesc getTupleDesc() {
// some code goes here
return Database.getCatalog().getTupleDesc(tableId);
}
public boolean hasNext() throws TransactionAbortedException, DbException {
// some code goes here
if(it == null){
return false;
}
return it.hasNext();
}
public Tuple next() throws NoSuchElementException,
TransactionAbortedException, DbException {
// some code goes here
if(it == null){
throw new NoSuchElementException("no next tuple");
}
Tuple t = it.next();
if(t == null){
throw new NoSuchElementException("no next tuple");
}
return t;
}
public void close() {
// some code goes here
it = null;
}
public void rewind() throws DbException, NoSuchElementException,
TransactionAbortedException {
// some code goes here
it.rewind();
}
}



