This is an automated email from the ASF dual-hosted git repository.
olabusayo pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/daffodil.git
The following commit(s) were added to refs/heads/main by this push:
new a25aa1e73 Replace ArrayBuffer[State] with Array[State]
a25aa1e73 is described below
commit a25aa1e73e786a915dcbd5109b016282cdf59cb5
Author: olabusayoT <[email protected]>
AuthorDate: Thu Feb 13 15:23:57 2025 -0500
Replace ArrayBuffer[State] with Array[State]
- currently in 2.13 we are getting a "ReflectiveOperationException durins
deserialzation" error on account of states being a pass by name parameter
leading to lambda serialization, removing that resulted in a ClassCastException
where it was complaining about not being able to cast DefaultSerializationProxy
to ArrayBuffer, which was weird because in a separate example class we were
able to deserialize ArrayBuffer[SomeSerializableClass] just fine. So we set
about converting ArrayBuffer [...]
DAFFODIL-2152
---
.../processors/dfa/CreateDelimiterDFA.scala | 55 ++++++++++---------
.../runtime1/processors/dfa/CreateFieldDFA.scala | 26 +++++----
.../runtime1/processors/dfa/CreatePaddingDFA.scala | 14 +++--
.../daffodil/runtime1/processors/dfa/Rules.scala | 62 ++++++++++------------
4 files changed, 76 insertions(+), 81 deletions(-)
diff --git
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/dfa/CreateDelimiterDFA.scala
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/dfa/CreateDelimiterDFA.scala
index 62a8d56e7..a4ff4270c 100644
---
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/dfa/CreateDelimiterDFA.scala
+++
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/dfa/CreateDelimiterDFA.scala
@@ -17,7 +17,7 @@
package org.apache.daffodil.runtime1.processors.dfa
-import scala.collection.mutable.ArrayBuffer
+import scala.collection.compat.immutable.ArraySeq
import org.apache.daffodil.runtime1.dsom.DPathCompileInfo
import org.apache.daffodil.runtime1.processors.CharDelim
@@ -44,14 +44,14 @@ object CreateDelimiterDFA {
outputNewLine: String
): DFADelimiter = {
- val allStates: ArrayBuffer[State] = ArrayBuffer.empty
+ val allStates: Array[State] = new Array[State](delimiter.length)
buildTransitions(delimiter, allStates, false)
val unparseValue = delimiter.map { _.unparseValue(outputNewLine) }.mkString
new DFADelimiterImplUnparse(
delimType,
- allStates.reverse.toArray,
+ allStates.reverse,
delimiterStr,
unparseValue,
ci.schemaFileLocation
@@ -70,13 +70,13 @@ object CreateDelimiterDFA {
ignoreCase: Boolean
): DFADelimiter = {
- val allStates: ArrayBuffer[State] = ArrayBuffer.empty
+ val allStates: Array[State] = new Array[State](delimiter.length)
buildTransitions(delimiter, allStates, ignoreCase)
new DFADelimiterImpl(
delimType,
- allStates.reverse.toArray,
+ allStates.reverse,
delimiterStr,
ci.schemaFileLocation
)
@@ -95,7 +95,7 @@ object CreateDelimiterDFA {
val d = new Delimiter()
d.compileDelimiter(delimiterStr, ignoreCase)
val db = d.delimBuf
- apply(delimType, ci, db, delimiterStr, ignoreCase)
+ apply(delimType, ci, ArraySeq.unsafeWrapArray(db), delimiterStr,
ignoreCase)
}
/**
@@ -111,7 +111,7 @@ object CreateDelimiterDFA {
val d = new Delimiter()
d.compileDelimiter(delimiterStr, false)
val db = d.delimBuf
- apply(delimType, ci, db, delimiterStr, outputNewLine)
+ apply(delimType, ci, ArraySeq.unsafeWrapArray(db), delimiterStr,
outputNewLine)
}
/**
@@ -147,7 +147,7 @@ object CreateDelimiterDFA {
d: DelimBase,
nextState: Int,
stateNum: Int,
- allStates: ArrayBuffer[State],
+ allStates: Array[State],
ignoreCase: Boolean
): DelimStateBase = {
@@ -176,7 +176,7 @@ object CreateDelimiterDFA {
private def buildTransitions(
delim: Seq[DelimBase],
- allStates: ArrayBuffer[State],
+ allStates: Array[State],
ignoreCase: Boolean
): State = {
assert(!delim.isEmpty)
@@ -186,26 +186,33 @@ object CreateDelimiterDFA {
private def buildTransitions(
nextState: DelimStateBase,
delim: Seq[DelimBase],
- allStates: ArrayBuffer[State],
+ allStates: Array[State],
ignoreCase: Boolean
): State = {
- if (delim.isEmpty && nextState != null) {
- // We are initial state
- nextState.stateName = "StartState" // "PTERM0"
- return nextState
+ var i = 0
+ var remainingDelim = delim
+ var currentNextState = nextState
+
+ while (remainingDelim.nonEmpty) {
+ val currentState = getState(
+ remainingDelim.head,
+ if (currentNextState == null) DFA.FinalState else
currentNextState.stateNum,
+ remainingDelim.length - 1,
+ allStates,
+ ignoreCase
+ )
+ remainingDelim = remainingDelim.tail
+ allStates(i) = currentState
+ currentNextState = currentState
+ i += 1
}
- val currentState = getState(
- delim(0),
- if (nextState == null) DFA.FinalState else nextState.stateNum,
- delim.length - 1,
- allStates,
- ignoreCase
- )
- val rest = delim.tail
+ if (currentNextState != null) {
+ // We are initial state
+ currentNextState.stateName = "StartState" // "PTERM0"
+ }
- allStates += currentState
- return buildTransitions(currentState, rest, allStates, ignoreCase)
+ currentNextState
}
}
diff --git
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/dfa/CreateFieldDFA.scala
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/dfa/CreateFieldDFA.scala
index 73412a9bf..89170d5e2 100644
---
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/dfa/CreateFieldDFA.scala
+++
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/dfa/CreateFieldDFA.scala
@@ -17,8 +17,6 @@
package org.apache.daffodil.runtime1.processors.dfa
-import scala.collection.mutable.ArrayBuffer
-
import org.apache.daffodil.lib.util.MaybeChar
/**
@@ -43,13 +41,13 @@ object CreateFieldDFA {
*/
def apply(): DFAField = {
- val allStates: ArrayBuffer[State] = ArrayBuffer.empty
+ val allStates: Array[State] = new Array[State](1)
val startState = new StartState(allStates, 0)
- allStates.insert(0, startState)
+ allStates(0) = startState
- new DFAFieldImpl(allStates.toArray)
+ new DFAFieldImpl(allStates)
}
/**
@@ -57,17 +55,17 @@ object CreateFieldDFA {
*/
def apply(EC: Char, EEC: MaybeChar): DFAField = {
- val allStates: ArrayBuffer[State] = ArrayBuffer.empty
+ val allStates: Array[State] = new Array(3)
val ecState = new ECState(allStates, EC, 1)
val eecState = new EECState(allStates, EEC, EC, 2)
val startState = new StartStateEscapeChar(allStates, EEC, EC, 0)
- allStates.insert(0, eecState)
- allStates.insert(0, ecState)
- allStates.insert(0, startState)
+ allStates(2) = eecState
+ allStates(1) = ecState
+ allStates(0) = startState
- new DFAFieldImpl(allStates.toArray)
+ new DFAFieldImpl(allStates)
}
/**
@@ -75,15 +73,15 @@ object CreateFieldDFA {
*/
def apply(blockEnd: DFADelimiter, EEC: MaybeChar): DFAField = {
- val allStates: ArrayBuffer[State] = ArrayBuffer.empty
+ val allStates: Array[State] = new Array[State](2)
val eecState = new EECStateBlock(allStates, blockEnd, EEC, 1)
val startState = new StartStateEscapeBlock(allStates, blockEnd, EEC, 0)
- allStates.insert(0, eecState)
- allStates.insert(0, startState)
+ allStates(1) = eecState
+ allStates(0) = startState
- new DFAFieldImpl(allStates.toArray)
+ new DFAFieldImpl(allStates)
}
}
diff --git
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/dfa/CreatePaddingDFA.scala
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/dfa/CreatePaddingDFA.scala
index bc86fd6dc..888421b3c 100644
---
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/dfa/CreatePaddingDFA.scala
+++
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/dfa/CreatePaddingDFA.scala
@@ -17,8 +17,6 @@
package org.apache.daffodil.runtime1.processors.dfa
-import scala.collection.mutable.ArrayBuffer
-
import org.apache.daffodil.runtime1.processors.Delimiter
import org.apache.daffodil.runtime1.processors.TermRuntimeData
import org.apache.daffodil.runtime1.processors.parsers.DelimiterTextType
@@ -33,15 +31,15 @@ object CreatePaddingDFA {
// TODO: In the future we will need to change this because the padChar
isn't necessarily a char.
// One can use it to specify a numeric byte to be used to pad as well.
- val allStates: ArrayBuffer[State] = ArrayBuffer.empty
+ val allStates: Array[State] = new Array[State](1)
val startState = new StartStatePadding(allStates, padChar)
- allStates.insert(0, startState)
+ allStates(0) = startState
new DFADelimiterImpl(
DelimiterTextType.Other,
- allStates.toArray,
+ allStates,
padChar.toString(),
rd.schemaFileLocation
)
@@ -55,11 +53,11 @@ object CreatePaddingDFA {
// TODO: In the future we will need to change this because the padChar
isn't necessarily a char.
// One can use it to specify a numeric byte to be used to pad as well.
- val allStates: ArrayBuffer[State] = ArrayBuffer.empty
+ val allStates: Array[State] = new Array[State](1)
val startState = new StartStatePadding(allStates, padChar)
- allStates.insert(0, startState)
+ allStates(0) = startState
val d = new Delimiter()
d.compileDelimiter(padChar.toString, false)
@@ -68,7 +66,7 @@ object CreatePaddingDFA {
new DFADelimiterImplUnparse(
DelimiterTextType.Other,
- allStates.toArray,
+ allStates,
padChar.toString(),
unparseValue,
rd.schemaFileLocation
diff --git
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/dfa/Rules.scala
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/dfa/Rules.scala
index 5349dcd6f..cc657d1d7 100644
---
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/dfa/Rules.scala
+++
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/dfa/Rules.scala
@@ -33,7 +33,7 @@ import org.apache.daffodil.runtime1.processors.WSP
* This object itself will exist and be a member of the states ArrayBuffer as
well as the other
* states before any access to the lazy val members.
*/
-abstract class State(states: => ArrayBuffer[State]) extends Serializable {
+abstract class State(states: Array[State]) extends Serializable {
def stateNum: Int
def stateName: String
@@ -180,7 +180,7 @@ abstract class State(states: => ArrayBuffer[State]) extends
Serializable {
* 1 1 1 Y
*/
class StartStateUnambiguousEscapeChar(
- states: => ArrayBuffer[State],
+ states: Array[State],
EEC: MaybeChar,
EC: MaybeChar,
val stateNum: Int
@@ -205,14 +205,13 @@ class StartStateUnambiguousEscapeChar(
)
}
-class StartState(states: => ArrayBuffer[State], val stateNum: Int) extends
State(states) {
+class StartState(states: Array[State], val stateNum: Int) extends
State(states) {
val stateName: String = "StartState"
val rules = ArrayBuffer(PauseRule, EndOfDataCharRule, StartStateRule)
}
-class StartStatePadding(states: => ArrayBuffer[State], val padChar: Char)
- extends State(states) {
+class StartStatePadding(states: Array[State], val padChar: Char) extends
State(states) {
val stateName = "StartState"
val stateNum: Int = 0
@@ -239,7 +238,7 @@ class StartStatePadding(states: => ArrayBuffer[State], val
padChar: Char)
* Here compiledDelims should only contain the endBlock DFADelimiter.
*/
class StartStateEscapeBlock(
- states: => ArrayBuffer[State],
+ states: Array[State],
val blockEnd: DFADelimiter,
val EEC: MaybeChar,
val stateNum: Int
@@ -269,12 +268,11 @@ class StartStateEscapeBlock(
}
class StartStateEscapeChar(
- states: => ArrayBuffer[State],
+ states: Array[State],
val EEC: MaybeChar,
val EC: Char,
val stateNum: Int
) extends State(states) {
-
val stateName: String = "StartState"
object NextStateECRule extends Rule {
@@ -443,9 +441,7 @@ class StartStateEscapeChar(
}
-class ECState(states: => ArrayBuffer[State], val EC: Char, val stateNum: Int)
- extends State(states) {
-
+class ECState(states: Array[State], val EC: Char, val stateNum: Int) extends
State(states) {
val stateName = "ECState"
val rules = ArrayBuffer(
// ECState, means that data0 is EC
@@ -497,12 +493,11 @@ class ECState(states: => ArrayBuffer[State], val EC:
Char, val stateNum: Int)
}
class EECState(
- states: => ArrayBuffer[State],
+ states: Array[State],
val EEC: MaybeChar,
val EC: Char,
val stateNum: Int
) extends State(states) {
-
val stateName = "EECState"
val rules = ArrayBuffer(
// Because this is about EC and EEC we can
@@ -531,12 +526,11 @@ class EECState(
}
class EECStateBlock(
- states: => ArrayBuffer[State],
+ states: Array[State],
blockEnd: DFADelimiter,
val EEC: MaybeChar,
val stateNum: Int
) extends State(states) {
-
val stateName = "EECState"
val rules = ArrayBuffer(
// Because this is about EC and EEC we can
@@ -579,7 +573,7 @@ class EECStateBlock(
)
}
-abstract class DelimStateBase(states: => ArrayBuffer[State]) extends
State(states) {
+abstract class DelimStateBase(states: Array[State]) extends State(states) {
var stateName: String = null
def setStateName(name: String) = stateName = name
@@ -596,13 +590,12 @@ abstract class DelimStateBase(states: =>
ArrayBuffer[State]) extends State(state
}
class CharState(
- states: => ArrayBuffer[State],
+ states: Array[State],
char: Char,
val nextState: Int,
val stateNum: Int,
ignoreCase: Boolean
) extends DelimStateBase(states) {
-
stateName = "CharState(" + char + ")"
val rulesToThisState = ArrayBuffer(new Rule {
override def test(r: Registers): Boolean = checkMatch(r.data0)
@@ -640,8 +633,7 @@ class CharState(
}
}
-abstract class WSPBase(states: => ArrayBuffer[State]) extends
DelimStateBase(states) with WSP {
-
+abstract class WSPBase(states: Array[State]) extends DelimStateBase(states)
with WSP {
def checkMatch(charIn: Char): Boolean = {
val result = charIn match {
case CTRL0 | CTRL1 | CTRL2 | CTRL3 | CTRL4 => true
@@ -654,9 +646,8 @@ abstract class WSPBase(states: => ArrayBuffer[State])
extends DelimStateBase(sta
}
}
-class WSPState(states: => ArrayBuffer[State], val nextState: Int, val
stateNum: Int)
+class WSPState(states: Array[State], val nextState: Int, val stateNum: Int)
extends WSPBase(states) {
-
stateName = "WSPState"
val rulesToThisState = ArrayBuffer(new Rule {
override def test(r: Registers): Boolean = checkMatch(r.data0)
@@ -679,11 +670,13 @@ class WSPState(states: => ArrayBuffer[State], val
nextState: Int, val stateNum:
})
}
-abstract class WSPRepeats(states: => ArrayBuffer[State]) extends
WSPBase(states) {}
-
-class WSPPlusState(states: => ArrayBuffer[State], val nextState: Int, val
stateNum: Int)
- extends WSPRepeats(states) {
+abstract class WSPRepeats(states: Array[State]) extends WSPBase(states) {}
+class WSPPlusState(
+ states: Array[State],
+ val nextState: Int,
+ val stateNum: Int
+) extends WSPRepeats(states) {
stateName = "WSPPlusState"
val rulesToThisState = ArrayBuffer(new Rule {
override def test(r: Registers): Boolean = checkMatch(r.data0)
@@ -716,9 +709,11 @@ class WSPPlusState(states: => ArrayBuffer[State], val
nextState: Int, val stateN
)
}
-class WSPStarState(states: => ArrayBuffer[State], val nextState: Int, val
stateNum: Int)
- extends WSPRepeats(states) {
-
+class WSPStarState(
+ states: Array[State],
+ val nextState: Int,
+ val stateNum: Int
+) extends WSPRepeats(states) {
stateName = "WSPStarState"
val rules = ArrayBuffer(
@@ -739,8 +734,7 @@ class WSPStarState(states: => ArrayBuffer[State], val
nextState: Int, val stateN
)
}
-abstract class NLBase(states: => ArrayBuffer[State]) extends
DelimStateBase(states) with NL {
-
+abstract class NLBase(states: Array[State]) extends DelimStateBase(states)
with NL {
def isNLNotCR(charIn: Char): Boolean = {
charIn match {
case LF | NEL | LS => true
@@ -763,9 +757,8 @@ abstract class NLBase(states: => ArrayBuffer[State])
extends DelimStateBase(stat
}
}
-class NLState(states: => ArrayBuffer[State], val nextState: Int, val stateNum:
Int)
+class NLState(states: Array[State], val nextState: Int, val stateNum: Int)
extends NLBase(states) {
-
stateName = "NLState"
val rules = ArrayBuffer(
@@ -807,9 +800,8 @@ class NLState(states: => ArrayBuffer[State], val nextState:
Int, val stateNum: I
def checkMatch(charIn: Char): Boolean = isNLNotCR(charIn) || isCR(charIn)
}
-class ESState(states: => ArrayBuffer[State], val nextState: Int, val stateNum:
Int)
+class ESState(states: Array[State], val nextState: Int, val stateNum: Int)
extends NLBase(states) {
-
stateName = "ESState"
/**