stevedlawrence commented on a change in pull request #437:
URL: https://github.com/apache/incubator-daffodil/pull/437#discussion_r505643553
##########
File path:
daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/ElementUnparser.scala
##########
@@ -515,35 +567,64 @@ trait OVCStartEndStrategy
Assert.invariant(endEv.isEnd && endEv.erd == erd)
val e = new DISimple(erd)
- state.currentInfosetNode.asComplex.addChild(e, state.tunable)
// Remove any state that was set by what created this event. Later
// code asserts that OVC elements do not have a value
e.resetValue
e
} else {
// Event was optional and didn't exist, create a new InfosetElement
and add it
val e = new DISimple(erd)
- state.currentInfosetNode.asComplex.addChild(e, state.tunable)
e
}
} else {
// Event was hidden and will never exist, create a new InfosetElement
and add it
val e = new DISimple(erd)
e.setHidden()
- state.currentInfosetNode.asComplex.addChild(e, state.tunable)
e
}
- val e = One(elem)
- state.currentInfosetNodeStack.push(e)
+ // We are about to add a new OVC child to this complex element. Before we
+ // do that, if the last child added to this complex is a DIArray, that
+ // implies that the DIArray will have no more children added and should be
+ // marked as final, and we can attempt to free that array.
+ val parentNode = state.currentInfosetNode
+ val parentComplex = parentNode.asComplex
+ val lastChildMaybe = parentComplex.maybeLastChild
+ if (lastChildMaybe.isDefined) {
+ val lastChild = lastChildMaybe.get
+ if (lastChild.isArray) {
+ lastChild.isFinal = true
+ if (state.releaseUnneededInfoset) {
+ parentComplex.freeChildIfNoLongerNeeded(parentComplex.numChildren -
1)
+ }
+ }
+ }
+
+ parentComplex.addChild(ovcElem, state.tunable)
+ state.currentInfosetNodeStack.push(One(ovcElem))
}
protected final override def unparseEnd(state: UState): Unit = {
- state.currentInfosetNodeStack.pop
-
// if an OVC element existed, the start AND end events were consumed in
// unparseBegin. No need to advance the cursor here.
+ // ovcElem is finished, free it if possible. OVC elements are not allow in
+ // arrays, so we can directly get the diParent to get the container DINode
+ if (state.releaseUnneededInfoset) {
+ val ovcElem = state.currentInfosetNodeStack.pop
+ val ovcContainer = ovcElem.get.diParent
+ ovcContainer.freeChildIfNoLongerNeeded(ovcContainer.numChildren - 1)
Review comment:
Correct, that logic has not been imlemented in either parse or unparse.
I don't think we can do that on a global basis because there are many different
array uses where sometimes we can't get away with that. I think it needs to be
per array. Mentioned above, but a proposal is to add a new dfdlx: property that
can be placed on arrarys that are used in expression and Daffodil can use it
has a hint only keep X previous array elements.
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]