Skip to content

Commit

Permalink
Schema information spec - part 1.
Browse files Browse the repository at this point in the history
* Defined initial `SchemaOptimizations` interface.
* Defined initial `SchemaInfoSpec` ("local schema without control flow").
  • Loading branch information
aalexandrov authored and jkovacs committed Jul 8, 2016
1 parent c0e9d2d commit 99f666e
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package compiler
import eu.stratosphere.emma.compiler.lang.source.Source
import eu.stratosphere.emma.compiler.lang.AlphaEq
import eu.stratosphere.emma.compiler.lang.core.Core
import eu.stratosphere.emma.compiler.ir.lnf.SchemaOptimizations

import scala.reflect.api.Universe

Expand All @@ -13,7 +14,7 @@ import scala.reflect.api.Universe
* This trait has to be instantiated with an underlying universe and works for both runtime and
* compile time reflection.
*/
trait Compiler extends AlphaEq with Source with Core {
trait Compiler extends AlphaEq with Source with Core with SchemaOptimizations {

/** The underlying universe object. */
override val universe: Universe
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package eu.stratosphere.emma.compiler.ir.lnf

import eu.stratosphere.emma.compiler.ir.CommonIR

trait SchemaOptimizations extends CommonIR {
self: Language =>

import universe._

// ---------------------------------------------------------------------------
// Schema Analysis & Optimizations
// ---------------------------------------------------------------------------

object Schema {

/** Root trait for all fields. */
sealed trait Field

/** A simple field representing a ValDef name. */
case class SimpleField(symbol: Symbol) extends Field

/** A field representing a member selection. */
case class MemberField(symbol: Symbol, member: Symbol) extends Field

/** A class of equivalent fields. */
type FieldClass = Set[Field]

/** Fields can be either */
case class Info(fieldClasses: Set[FieldClass])

/**
* Compute the (local) schema information for a tree fragment.
*
* @param tree The ANF [[Tree]] to be analyzed.
* @return The schema information for the input tree.
*/
private[emma] def global(tree: Tree): Schema.Info = {
Info(Set.empty[FieldClass])
}

/**
* Compute the (global) schema information for an anonymous function.
*
* @param tree The ANF [[Tree]] to be analyzed.
* @return The schema information for the input tree.
*/
private[emma] def local(tree: Function): Schema.Info = {
Info(Set.empty[FieldClass])
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package eu.stratosphere.emma.compiler.ir.lnf

import eu.stratosphere.emma.compiler.BaseCompilerSpec
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner

/**
* A spec for schema information analysis.
*/
@RunWith(classOf[JUnitRunner])
class SchemaInfoSpec extends BaseCompilerSpec {

import compiler.Schema.{Field, Info, MemberField, SimpleField}
import compiler.Term
import eu.stratosphere.emma.testschema.Marketing._

import compiler.universe._

def typeCheck[T](expr: Expr[T]): Tree = {
compiler.typeCheck(expr.tree)
}

def symbolOf(name: String)(tree: Tree): Symbol = tree.collect {
case vd@ValDef(_, TermName(`name`), _, _) => vd.symbol
}.head

"local schema" - {
"without control flow" in {
// ANF representation with `desugared` comprehensinos
val fn = typeCheck(reify {
(c: Click) => {
val t = c.time
val p = t.plusSeconds(600L)
val m = t.minusSeconds(600L)
val a = (c, p, m)
a
}
}).asInstanceOf[Function]

// construct expected local schema

// 1) get schema fields
val fld$c /* */ = SimpleField(symbolOf("c")(fn))
val fld$c$adID /* */ = MemberField(fld$c.symbol, Term.member(fld$c.symbol, TermName("adID")))
val fld$c$userID /**/ = MemberField(fld$c.symbol, Term.member(fld$c.symbol, TermName("userID")))
val fld$c$time /* */ = MemberField(fld$c.symbol, Term.member(fld$c.symbol, TermName("time")))

val fld$t /* */ = SimpleField(symbolOf("t")(fn))
val fld$p /* */ = SimpleField(symbolOf("p")(fn))
val fld$m /* */ = SimpleField(symbolOf("m")(fn))

val fld$a /* */ = SimpleField(symbolOf("a")(fn))
val fld$a$_1 /* */ = MemberField(fld$a.symbol, Term.member(fld$a.symbol, TermName("_1")))
val fld$a$_2 /* */ = MemberField(fld$a.symbol, Term.member(fld$a.symbol, TermName("_2")))
val fld$a$_3 /* */ = MemberField(fld$a.symbol, Term.member(fld$a.symbol, TermName("_3")))

// 2) construct equivalence classes of fields
val cls$01 /* */ = Set[Field](fld$c, fld$a$_1)
val cls$02 /* */ = Set[Field](fld$c$adID)
val cls$03 /* */ = Set[Field](fld$c$userID)
val cls$04 /* */ = Set[Field](fld$c$time, fld$t)
val cls$05 /* */ = Set[Field](fld$p, fld$a$_2)
val cls$06 /* */ = Set[Field](fld$m, fld$a$_3)
val cls$v7 /* */ = Set[Field](fld$a)

// 3) construct the expected local schema information
val exp = Info(Set(cls$01, cls$02, cls$03, cls$01, cls$01, cls$01, cls$01))

// compute actual local schema
val act = compiler.Schema.local(fn)

// match the two
act shouldBe exp
}


"with control flow" in {
// TODO
}
}
}

0 comments on commit 99f666e

Please sign in to comment.