Skip to content
Closed
Changes from 1 commit
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
d441794
update API of addMutableState
kiszk Nov 24, 2017
870d106
eliminate initialization with default value
kiszk Nov 25, 2017
24d7087
allocate a global Java array to store a lot of mutable state in a class
kiszk Nov 26, 2017
3eb5842
fix scala style error
kiszk Nov 26, 2017
074d711
fix test failure of ExpressionEncoderSuite.NestedArray
kiszk Nov 27, 2017
eafa3f8
rebase with master
kiszk Nov 30, 2017
90d15f3
address review comments
kiszk Nov 30, 2017
c456c07
add useFreshname parameter to addMutableState
kiszk Nov 30, 2017
9ca5ab3
rebase with master
kiszk Nov 30, 2017
5b36c61
fix test failures
kiszk Dec 1, 2017
fd51d75
drop to creat a loop for initialization
kiszk Dec 7, 2017
effe918
fix test failure
kiszk Dec 8, 2017
9df109c
update comments
kiszk Dec 8, 2017
634d494
address review comment
kiszk Dec 10, 2017
d3438fd
address review comment
kiszk Dec 12, 2017
f4f3754
address review comment
kiszk Dec 12, 2017
f1e1fca
address review comments except test case
kiszk Dec 13, 2017
0937ef2
rebase with master
kiszk Dec 13, 2017
4bfcc1a
Do not use compaction as possible for frequently-accessed variable
kiszk Dec 13, 2017
49119a9
exclude mutable state from argument list for ExpressionCodegn
kiszk Dec 13, 2017
24f49c5
fix test failures
kiszk Dec 14, 2017
15e967e
address review comments
kiszk Dec 14, 2017
d6c1a97
address review comments
kiszk Dec 14, 2017
a9d40e9
address review comments
kiszk Dec 14, 2017
31914c0
address review comments
kiszk Dec 15, 2017
0e45c19
address review comments
kiszk Dec 19, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
drop to creat a loop for initialization
  • Loading branch information
kiszk committed Dec 14, 2017
commit fd51d750a0ad89770377248487149d577fe6e6fc
Original file line number Diff line number Diff line change
Expand Up @@ -159,15 +159,16 @@ class CodegenContext {
var mutableStateArrayIdx: mutable.Map[(String, String), Int] =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From the below code, looks like this is keyed by (javaType, arrayName), instead of (javaType, initCode)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, old comment still exists there. Thanks

mutable.Map.empty[(String, String), Int]

// An array keyed by the tuple of mutable states' types and initialization code, holds the
// An array keyed by the tuple of mutable states' types, holds the
// current name of the mutableStateArray into which state of the given key will be compacted
var mutableStateArrayCurrentNames: mutable.Map[(String, String), String] =
mutable.Map.empty[(String, String), String]
var mutableStateArrayCurrentNames: mutable.Map[String, String] =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's not needed

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch

mutable.Map.empty[String, String]

// An array keyed by the tuple of mutable states' types, array names and initialization code,
// holds the code that will initialize the mutableStateArray when initialized in loops
var mutableStateArrayInitCodes: mutable.ArrayBuffer[(String, String, String)] =
mutable.ArrayBuffer.empty[(String, String, String)]
// An array keyed by the tuple of mutable states' types, array names, array index, and
// initialization code, holds the code that will initialize the mutableStateArray when
// initialized in loops
var mutableStateArrayInitCodes: mutable.ArrayBuffer[String] =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why var?

mutable.ArrayBuffer.empty[String]

/**
* Add a mutable state as a field to the generated class. c.f. the comments above.
Expand Down Expand Up @@ -202,42 +203,36 @@ class CodegenContext {
inline: Boolean = false,
useFreshName: Boolean = true): String = {
val varName = if (useFreshName) freshName(variableName) else variableName
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of calling freshName here and adding a useFreshName parameter, can we follow the previous style and ask the caller side to guarantee the given name is unique? i.e. call freshName at caller side

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since I noticed that most of caller sides executes freshName, I decided to use the new style that can simply caller code. If a developer want to guarantee the given name is unique at caller site (currently, they are only several cases), it is OK by using useFreshName = true.

Do we need redundant code at caller side? WDYT? @cloud-fan

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't it an existing problem? Let's fix it in another PR to make this PR more consistent with the previous code.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, let us discuss in another PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this can be moved in the if for clarity

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch

val initCode = codeFunctions(varName)
if (javaType.contains("[][]")) {
Thread.dumpStack()
}

if (inline ||
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

val canInlinePrimitive = isPrimitiveType(javaType) &&
  mutableStates.length < CodeGenerator.OUTER_CLASS_VARIABLES_THRESHOLD
if (forceInline || canInlinePrimitive || javaType.contains("[][]")) ...

// want to put a primitive type variable at outerClass for performance
isPrimitiveType(javaType) &&
(mutableStates.length < CodeGenerator.OUTER_CLASS_VARIABLES_THRESHOLD) ||
// type is multi-dimensional array
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why can't support multi-dimensional array?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are changing a declared type for compaction (i.e. adding one dimension at the first dimension) at declareMutableStates. In the logic at declareMutableStates assumes that a given variable is scalar or one-dimensional array.
We could support multi-dimensional array. However, it requires slightly complicated string operations. Should we support multi-dimensional array or keep it simple?

@cloud-fan WDYT?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok let's leave it

javaType.contains("[][]")) {
val initCode = codeFunctions(varName)
mutableStates += ((javaType, varName, initCode))
varName
} else {
// Create an initialization code agnostic to the actual variable name which we can key by
val initCodeKey = initCode.replaceAll(varName, "*VALUE*")

val arrayName = mutableStateArrayCurrentNames.getOrElse((javaType, initCodeKey), "")
val arrayName = mutableStateArrayCurrentNames.getOrElse(javaType, "")
val prevIdx = mutableStateArrayIdx.getOrElse((javaType, arrayName), -1)
if (0 <= prevIdx && prevIdx < CodeGenerator.MUTABLESTATEARRAY_SIZE_LIMIT - 1) {
// a mutableStateArray for the given type and initialization has already been declared,
// a mutableStateArray for the given type and name has already been declared,
// update the max index of the array and return an array element
val idx = prevIdx + 1
val initCode = codeFunctions(s"$arrayName[$idx]")
mutableStateArrayInitCodes += initCode
mutableStateArrayIdx.update((javaType, arrayName), idx)
s"$arrayName[$idx]"
} else {
// mutableStateArray has not been declared yet for the given type and initialization code.
// mutableStateArray has not been declared yet for the given type and name.
// Create a new name for the array, and add an entry to keep track of current array name
// for type and initialized code. In addition, type, array name, and qualified initialized
// code is stored for code generation
// for type and initialized code. In addition, init code is stored for code generation
val arrayName = freshName("mutableStateArray")
val qualifiedInitCode = initCode.replaceAll(
varName, s"$arrayName[${CodeGenerator.INIT_LOOP_VARIABLE_NAME}]")
mutableStateArrayCurrentNames += (javaType, initCodeKey) -> arrayName
mutableStateArrayInitCodes += ((javaType, arrayName, qualifiedInitCode))
mutableStateArrayCurrentNames += javaType -> arrayName
val idx = 0
val initCode = codeFunctions(s"$arrayName[$idx]")
mutableStateArrayInitCodes += initCode
mutableStateArrayIdx += (javaType, arrayName) -> idx
s"$arrayName[$idx]"
}
Expand Down Expand Up @@ -266,7 +261,7 @@ class CodegenContext {
s"private $javaType $variableName;"
}

val arrayStates = mutableStateArrayInitCodes.map { case (javaType, arrayName, _) =>
val arrayStates = mutableStateArrayIdx.keys.map { case (javaType, arrayName) =>
val length = mutableStateArrayIdx((javaType, arrayName)) + 1
if (javaType.matches("^.*\\[\\]$")) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shall we just check javaType.contains("[]")?

// initializer had an one-dimensional array variable
Expand All @@ -285,20 +280,8 @@ class CodegenContext {
// It's possible that we add same mutable state twice, e.g. the `mergeExpressions` in
// `TypedAggregateExpression`, we should call `distinct` here to remove the duplicated ones.
val initCodes = mutableStates.distinct.map(_._3 + "\n")
// array state is initialized in loops
val arrayInitCodes = mutableStateArrayInitCodes.map {
case (javaType, arrayName, qualifiedInitCode) =>
if (qualifiedInitCode == "") {
""
} else {
val loopIdxVar = CodeGenerator.INIT_LOOP_VARIABLE_NAME
s"""
for (int $loopIdxVar = 0; $loopIdxVar < $arrayName.length; $loopIdxVar++) {
$qualifiedInitCode
}
"""
}
}
// statements for array element initialization
val arrayInitCodes = mutableStateArrayInitCodes.distinct.map(_ + "\n")

// The generated initialization code may exceed 64kb function size limit in JVM if there are too
// many mutable states, so split it into multiple functions.
Expand Down