Skip to content

Commit

Permalink
Lab 2 initial release
Browse files Browse the repository at this point in the history
  • Loading branch information
SylviaZiyuZhang authored and Valerie Kwek committed Oct 13, 2024
1 parent dba5234 commit 96bdb2a
Show file tree
Hide file tree
Showing 47 changed files with 4,483 additions and 2 deletions.
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ replace github.com/srmadden/godb => ./godb
require (
github.com/chzyer/readline v1.5.1
github.com/srmadden/godb v0.0.0-00010101000000-000000000000
golang.org/x/exp v0.0.0-20240529005216-23cca8864a10
)

require (
Expand Down
15 changes: 15 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
github.com/chzyer/logex v1.2.1 h1:XHDu3E6q+gdHgsdTPH6ImJMIp436vR6MPtH8gP05QzM=
github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ=
github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI=
github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk=
github.com/chzyer/test v1.0.0 h1:p3BQDXSxOhOG0P9z6/hGnII4LGiEPOYBhs8asl/fC04=
github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8=
github.com/d4l3k/messagediff v1.2.1 h1:ZcAIMYsUg0EAp9X+tt8/enBE/Q8Yd5kzPynLyKptt9U=
github.com/d4l3k/messagediff v1.2.1/go.mod h1:Oozbb1TVXFac9FtSIxHBMnBCq2qeH/2KkEQxENCrlLo=
github.com/tylertreat/BoomFilters v0.0.0-20210315201527-1a82519a3e43 h1:QEePdg0ty2r0t1+qwfZmQ4OOl/MB2UXIeJSpIZv56lg=
github.com/tylertreat/BoomFilters v0.0.0-20210315201527-1a82519a3e43/go.mod h1:OYRfF6eb5wY9VRFkXJH8FFBi3plw2v+giaIu7P054pM=
github.com/xwb1989/sqlparser v0.0.0-20180606152119-120387863bf2 h1:zzrxE1FKn5ryBNl9eKOeqQ58Y/Qpo3Q9QNxKHX5uzzQ=
github.com/xwb1989/sqlparser v0.0.0-20180606152119-120387863bf2/go.mod h1:hzfGeIUDq/j97IG+FhNqkowIyEcD88LrW6fyU3K3WqY=
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
173 changes: 173 additions & 0 deletions godb/agg_op.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
package godb

import (
"fmt"
)

type Aggregator struct {
// Expressions that when applied to tuples from the child operators,
// respectively, return the value of the group by key tuple
groupByFields []Expr

// Aggregation states that serves as a template as to which types of
// aggregations in which order are to be computed for every group.
newAggState []AggState

child Operator // the child operator for the inputs to aggregate
}

type AggType int

const (
IntAggregator AggType = iota
StringAggregator AggType = iota
)

const DefaultGroup int = 0 // for handling the case of no group-by

// Construct an aggregator with a group-by.
func NewGroupedAggregator(emptyAggState []AggState, groupByFields []Expr, child Operator) *Aggregator {
return &Aggregator{groupByFields, emptyAggState, child}
}

// Construct an aggregator with no group-by.
func NewAggregator(emptyAggState []AggState, child Operator) *Aggregator {
return &Aggregator{nil, emptyAggState, child}
}

// Return a TupleDescriptor for this aggregation.
//
// If the aggregator has no group-by, the returned descriptor should contain the
// union of the fields in the descriptors of the aggregation states. If the
// aggregator has a group-by, the returned descriptor will additionally start
// with the group-by fields, and then the aggregation states descriptors like
// that without group-by.
//
// HINT: for groupByFields, you can use [Expr.GetExprType] to get the FieldType.
//
// HINT: use [TupleDesc.merge] to merge the two [TupleDesc]s.
func (a *Aggregator) Descriptor() *TupleDesc {
// TODO: some code goes here
return &TupleDesc{} //replace me
}

// Returns an iterator over the results of the aggregate. The aggregate should
// be the result of aggregating each group's tuples and the iterator should
// iterate through each group's result. In the case where there is no group-by,
// the iterator simply iterates through only one tuple, representing the
// aggregation of all child tuples.
func (a *Aggregator) Iterator(tid TransactionID) (func() (*Tuple, error), error) {
// the child iterator
childIter, err := a.child.Iterator(tid)
if err != nil {
return nil, err
}
if childIter == nil {
return nil, GoDBError{MalformedDataError, "child iter unexpectedly nil"}
}

// the map that stores the aggregation state of each group
aggState := make(map[any]*[]AggState)
if a.groupByFields == nil {
var newAggState []AggState
for _, as := range a.newAggState {
copy := as.Copy()
if copy == nil {
return nil, GoDBError{MalformedDataError, "aggState Copy unexpectedly returned nil"}
}
newAggState = append(newAggState, copy)
}

aggState[DefaultGroup] = &newAggState
}

// the list of group key tuples
var groupByList []*Tuple
// the iterator for iterating thru the finalized aggregation results for each group
var finalizedIter func() (*Tuple, error)

return func() (*Tuple, error) {
// iterates thru all child tuples
for t, err := childIter(); t != nil || err != nil; t, err = childIter() {
if err != nil {
return nil, err
}
if t == nil {
return nil, nil
}

if a.groupByFields == nil { // adds tuple to the aggregation in the case of no group-by
for i := 0; i < len(a.newAggState); i++ {
(*aggState[DefaultGroup])[i].AddTuple(t)
}
} else { // adds tuple to the aggregation with grouping
keygenTup, err := extractGroupByKeyTuple(a, t)
if err != nil {
return nil, err
}

key := keygenTup.tupleKey()
if aggState[key] == nil {
asNew := make([]AggState, len(a.newAggState))
aggState[key] = &asNew
groupByList = append(groupByList, keygenTup)
}

addTupleToGrpAggState(a, t, aggState[key])
}
}

if finalizedIter == nil { // builds the iterator for iterating thru the finalized aggregation results for each group
if a.groupByFields == nil {
var tup *Tuple
for i := 0; i < len(a.newAggState); i++ {
newTup := (*aggState[DefaultGroup])[i].Finalize()
tup = joinTuples(tup, newTup)
}
finalizedIter = func() (*Tuple, error) { return nil, nil }
return tup, nil
} else {
finalizedIter = getFinalizedTuplesIterator(a, groupByList, aggState)
}
}
return finalizedIter()
}, nil
}

// Given a tuple t from a child iterator, return a tuple that identifies t's
// group. The returned tuple should contain the fields from the groupByFields
// list passed into the aggregator constructor. The ith field can be extracted
// from the supplied tuple using the EvalExpr method on the ith expression of
// groupByFields.
//
// If there is any error during expression evaluation, return the error.
func extractGroupByKeyTuple(a *Aggregator, t *Tuple) (*Tuple, error) {
// TODO: some code goes here
return &Tuple{}, fmt.Errorf("extractGroupByKeyTuple not implemented.") // replace me
}

// Given a tuple t from child and (a pointer to) the array of partially computed
// aggregates grpAggState, add t into all partial aggregations using
// [AggState.AddTuple]. If any of the array elements is of grpAggState is null
// (i.e., because this is the first invocation of this method, create a new
// aggState using [aggState.Copy] on appropriate element of the a.newAggState
// field and add the new aggState to grpAggState.
func addTupleToGrpAggState(a *Aggregator, t *Tuple, grpAggState *[]AggState) {
// TODO: some code goes here
}

// Given that all child tuples have been added, return an iterator that iterates
// through the finalized aggregate result one group at a time. The returned
// tuples should be structured according to the TupleDesc returned from the
// Descriptor() method.
//
// HINT: you can call [aggState.Finalize] to get the field for each AggState.
// Then, you should get the groupByTuple and merge it with each of the AggState
// tuples using the joinTuples function in tuple.go you wrote in lab 1.
func getFinalizedTuplesIterator(a *Aggregator, groupByList []*Tuple, aggState map[any]*[]AggState) func() (*Tuple, error) {
// TODO: some code goes here
return func() (*Tuple, error) {
// TODO: some code goes here
return nil, fmt.Errorf("getFinalizedTuplesIterator not implemented.") // replace me
}
}
Loading

0 comments on commit 96bdb2a

Please sign in to comment.