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"
 
   /**

Reply via email to