Skip to content

Commit

Permalink
Release Lab 5
Browse files Browse the repository at this point in the history
  • Loading branch information
geoffxy committed Nov 9, 2022
1 parent f8965f6 commit 258760c
Show file tree
Hide file tree
Showing 36 changed files with 9,488 additions and 0 deletions.
Binary file added lab5-merging_internal.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added lab5-merging_leaf.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added lab5-redist_internal.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added lab5-redist_leaf.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added lab5-simple_tree.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added lab5-splitting_internal.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added lab5-splitting_leaf.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
469 changes: 469 additions & 0 deletions lab5.md

Large diffs are not rendered by default.

29 changes: 29 additions & 0 deletions src/java/simpledb/execution/IndexOpIterator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package simpledb.execution;

import simpledb.common.DbException;
import simpledb.transaction.TransactionAbortedException;

import java.util.NoSuchElementException;

/**
* IndexDBIterator is the interface that index access methods
* implement in SimpleDb.
*/
public interface IndexOpIterator extends OpIterator {
/**
* Open the access method such that when getNext is called, it
* iterates through the tuples that satisfy ipred.
*
* @param ipred The predicate that is used to scan the index.
*/
void open(IndexPredicate ipred)
throws NoSuchElementException, DbException, TransactionAbortedException;

/**
* Begin a new index scan with the specified predicate.
*
* @param ipred The predicate that is used to scan the index.
*/
void rewind(IndexPredicate ipred)
throws DbException, TransactionAbortedException;
}
54 changes: 54 additions & 0 deletions src/java/simpledb/execution/IndexPredicate.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package simpledb.execution;

import simpledb.storage.Field;

import java.io.Serializable;

/**
* IndexPredicate compares a field which has index on it against a given value
*
* @see IndexOpIterator
*/
public class IndexPredicate implements Serializable {

private static final long serialVersionUID = 1L;

private final Predicate.Op op;
private final Field fieldvalue;

/**
* Constructor.
*
* @param fvalue The value that the predicate compares against.
* @param op The operation to apply (as defined in Predicate.Op); either
* Predicate.Op.GREATER_THAN, Predicate.Op.LESS_THAN, Predicate.Op.EQUAL,
* Predicate.Op.GREATER_THAN_OR_EQ, or Predicate.Op.LESS_THAN_OR_EQ
* @see Predicate
*/
public IndexPredicate(Predicate.Op op, Field fvalue) {
this.op = op;
this.fieldvalue = fvalue;
}

public Field getField() {
return fieldvalue;
}

public Predicate.Op getOp() {
return op;
}

/**
* Return true if the fieldvalue in the supplied predicate
* is satisfied by this predicate's fieldvalue and
* operator.
*
* @param ipd The field to compare against.
*/
public boolean equals(IndexPredicate ipd) {
if (ipd == null)
return false;
return (op.equals(ipd.op) && fieldvalue.equals(ipd.fieldvalue));
}

}
132 changes: 132 additions & 0 deletions src/java/simpledb/index/BTreeChecker.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
package simpledb.index;

import simpledb.common.DbException;
import simpledb.common.Permissions;
import simpledb.storage.Field;
import simpledb.storage.Page;
import simpledb.storage.PageId;
import simpledb.transaction.TransactionAbortedException;
import simpledb.transaction.TransactionId;

import java.io.IOException;
import java.util.Iterator;
import java.util.Map;

/**
* Created by orm on 10/7/15.
*/
public class BTreeChecker {

/**
* This class is only used for error-checking code.
*/
static class SubtreeSummary {
public int depth;
public BTreePageId ptrLeft;
public BTreePageId leftmostId;
public BTreePageId ptrRight;
public BTreePageId rightmostId;

SubtreeSummary() {
}

SubtreeSummary(BTreeLeafPage base, int depth) {
this.depth = depth;

this.leftmostId = base.getId();
this.rightmostId = base.getId();

this.ptrLeft = base.getLeftSiblingId();
this.ptrRight = base.getRightSiblingId();
}

static SubtreeSummary checkAndMerge(SubtreeSummary accleft, SubtreeSummary right) {
assert (accleft.depth == right.depth);
assert (accleft.ptrRight.equals(right.leftmostId));
assert (accleft.rightmostId.equals(right.ptrLeft));

SubtreeSummary ans = new SubtreeSummary();
ans.depth = accleft.depth;

ans.ptrLeft = accleft.ptrLeft;
ans.leftmostId = accleft.leftmostId;

ans.ptrRight = right.ptrRight;
ans.rightmostId = right.rightmostId;
return ans;
}
}

/**
* checks the integrity of the tree:
* 1) parent pointers.
* 2) sibling pointers.
* 3) range invariants.
* 4) record to page pointers.
* 5) occupancy invariants. (if enabled)
*/
public static void checkRep(BTreeFile bt, TransactionId tid, Map<PageId, Page> dirtypages,
boolean checkOccupancy) throws
DbException, IOException, TransactionAbortedException {
BTreeRootPtrPage rtptr = bt.getRootPtrPage(tid, dirtypages);

if (rtptr.getRootId() == null) { // non existent root is a legal state.
} else {
SubtreeSummary res = checkSubTree(bt, tid, dirtypages,
rtptr.getRootId(), null, null, rtptr.getId(), checkOccupancy, 0);
assert (res.ptrLeft == null);
assert (res.ptrRight == null);
}
}

static SubtreeSummary checkSubTree(BTreeFile bt, TransactionId tid, Map<PageId, Page> dirtypages,
BTreePageId pageId, Field lowerBound, Field upperBound,
BTreePageId parentId, boolean checkOccupancy, int depth) throws
TransactionAbortedException, DbException {
BTreePage page = (BTreePage) bt.getPage(tid, dirtypages, pageId, Permissions.READ_ONLY);
assert (page.getParentId().equals(parentId));

if (page.getId().pgcateg() == BTreePageId.LEAF) {
BTreeLeafPage bpage = (BTreeLeafPage) page;
bpage.checkRep(bt.keyField(), lowerBound, upperBound, checkOccupancy, depth);
return new SubtreeSummary(bpage, depth);
} else if (page.getId().pgcateg() == BTreePageId.INTERNAL) {

BTreeInternalPage ipage = (BTreeInternalPage) page;
ipage.checkRep(lowerBound, upperBound, checkOccupancy, depth);

SubtreeSummary acc = null;
BTreeEntry prev = null;
Iterator<BTreeEntry> it = ipage.iterator();

prev = it.next();
{ // init acc and prev.
acc = checkSubTree(bt, tid, dirtypages, prev.getLeftChild(), lowerBound, prev.getKey(), ipage.getId(),
checkOccupancy, depth + 1);
lowerBound = prev.getKey();
}

assert (acc != null);
BTreeEntry curr = prev; // for one entry case.
while (it.hasNext()) {
curr = it.next();
SubtreeSummary currentSubTreeResult =
checkSubTree(bt, tid, dirtypages, curr.getLeftChild(), lowerBound, curr.getKey(), ipage.getId(),
checkOccupancy, depth + 1);
acc = SubtreeSummary.checkAndMerge(acc, currentSubTreeResult);

// need to move stuff for next iter:
lowerBound = curr.getKey();
}

SubtreeSummary lastRight = checkSubTree(bt, tid, dirtypages, curr.getRightChild(), lowerBound, upperBound,
ipage.getId(), checkOccupancy, depth + 1);
acc = SubtreeSummary.checkAndMerge(acc, lastRight);

return acc;
} else {
assert (false); // no other page types allowed inside the tree.
return null;
}
}
}
144 changes: 144 additions & 0 deletions src/java/simpledb/index/BTreeEntry.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
package simpledb.index;

import simpledb.storage.Field;
import simpledb.storage.RecordId;

import java.io.Serializable;

/**
* Each instance of BTreeEntry stores one key and two child page ids. It is used
* by BTreeInternalPage as an abstraction to iterate through the entries stored inside.
* All of the entries or tuples in the left child page should be less than or equal to
* the key, and all of the entries or tuples in the right child page should be greater
* than or equal to the key.
* <p>
* Note that updating a BTreeEntry does not actually change the data stored on the page
* identified by its recordId. After updating a BTreeEntry object, you must call
* BTreeInternalPage.updateEntry() in order for the changes to take effect.
*
* @see BTreeInternalPage
* @see BTreeInternalPage#updateEntry(BTreeEntry)
*/
public class BTreeEntry implements Serializable {

private static final long serialVersionUID = 1L;

/**
* The key of this entry
*/
private Field key;

/**
* The left child page id
*/
private BTreePageId leftChild;

/**
* The right child page id
*/
private BTreePageId rightChild;

/**
* The record id of this entry
*/
private RecordId rid; // null if not stored on any page

/**
* Constructor to create a new BTreeEntry
*
* @param key - the key
* @param leftChild - page id of the left child
* @param rightChild - page id of the right child
*/
public BTreeEntry(Field key, BTreePageId leftChild, BTreePageId rightChild) {
this.key = key;
this.leftChild = leftChild;
this.rightChild = rightChild;
}

/**
* @return the key
*/
public Field getKey() {
return key;
}

/**
* @return the left child page id
*/
public BTreePageId getLeftChild() {
return leftChild;
}

/**
* @return the right child page id
*/
public BTreePageId getRightChild() {
return rightChild;
}

/**
* @return the record id of this entry, representing the location of this entry
* in a BTreeFile. May be null if this entry is not stored on any page in the file
*/
public RecordId getRecordId() {
return rid;
}

/**
* Set the key for this entry. Note that updating a BTreeEntry does not
* actually change the data stored on the page identified by its recordId. After
* calling this method, you must call BTreeInternalPage.updateEntry() in order for
* it to take effect.
*
* @param key - the new key
* @see BTreeInternalPage#updateEntry(BTreeEntry)
*/
public void setKey(Field key) {
this.key = key;
}

/**
* Set the left child id for this entry. Note that updating a BTreeEntry does not
* actually change the data stored on the page identified by its recordId. After
* calling this method, you must call BTreeInternalPage.updateEntry() in order for
* it to take effect.
*
* @param leftChild - the new left child
* @see BTreeInternalPage#updateEntry(BTreeEntry)
*/
public void setLeftChild(BTreePageId leftChild) {
this.leftChild = leftChild;
}

/**
* Set the right child id for this entry. Note that updating a BTreeEntry does not
* actually change the data stored on the page identified by its recordId. After
* calling this method, you must call BTreeInternalPage.updateEntry() in order for
* it to take effect.
*
* @param rightChild - the new right child
* @see BTreeInternalPage#updateEntry(BTreeEntry)
*/
public void setRightChild(BTreePageId rightChild) {
this.rightChild = rightChild;
}

/**
* set the record id for this entry
*
* @param rid - the new record id
*/
public void setRecordId(RecordId rid) {
this.rid = rid;
}

/**
* Prints a representation of this BTreeEntry
*/
public String toString() {
return "[" + leftChild.getPageNumber() + "|" + key + "|" + rightChild.getPageNumber() + "]";
}

}

Loading

0 comments on commit 258760c

Please sign in to comment.