Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 11 additions & 0 deletions core/shared/src/main/scala/sigma/ContextVarsMap.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package sigma

trait ContextVarsMap {

def maxKey: Byte

def getNullable(key: Byte): AnyValue

def anyIterator: Iterator[(Byte, AnyValue)]

}
2 changes: 1 addition & 1 deletion core/shared/src/main/scala/sigma/SigmaDsl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,7 @@ trait Context {
*/
def getVar[T](id: Byte)(implicit cT: RType[T]): Option[T]

def vars: Coll[AnyValue]
def vars: ContextVarsMap

/** Maximum version of ErgoTree currently activated on the network.
* See [[ErgoLikeContext]] class for details. */
Expand Down
40 changes: 29 additions & 11 deletions data/shared/src/main/scala/sigma/interpreter/ContextExtension.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package sigma.interpreter

import debox.cfor
import sigma.ast.{EvaluatedValue, SType}
import sigma.interpreter.ContextExtension.VarBinding
import sigma.serialization.{SigmaByteReader, SigmaByteWriter, SigmaSerializer}

/**
Expand All @@ -15,15 +15,12 @@ import sigma.serialization.{SigmaByteReader, SigmaByteWriter, SigmaSerializer}
*
* @param values internal container of the key-value pairs
*/
case class ContextExtension(values: scala.collection.Map[Byte, EvaluatedValue[_ <: SType]]) {
def add(bindings: VarBinding*): ContextExtension =
ContextExtension(values ++ bindings)
}
case class ContextExtension(values: SigmaMap)

object ContextExtension {
/** Immutable instance of empty ContextExtension, which can be shared to avoid
* allocations. */
val empty = ContextExtension(Map())
val empty: ContextExtension = ContextExtension(SigmaMap.empty)

/** Type of context variable binding. */
type VarBinding = (Byte, EvaluatedValue[_ <: SType])
Expand All @@ -34,16 +31,37 @@ object ContextExtension {
if (size > Byte.MaxValue)
error(s"Number of ContextExtension values $size exceeds ${Byte.MaxValue}.")
w.putUByte(size)
obj.values.foreach { case (id, v) => w.put(id).putValue(v) }
obj.values.iterator.foreach { case (id, v) => w.put(id).putValue(v) }
}

override def parse(r: SigmaByteReader): ContextExtension = {
val extSize = r.getByte()
if (extSize < 0)
if (extSize < 0) {
error(s"Negative amount of context extension values: $extSize")
val values = (0 until extSize)
.map(_ => (r.getByte(), r.getValue().asInstanceOf[EvaluatedValue[_ <: SType]]))
ContextExtension(values.toMap)
}
if (extSize > Byte.MaxValue + 1) {
error(s"Too many context extension values: $extSize")
}
if (extSize == 0) {
ContextExtension.empty
} else {
val size = extSize
val keys = new Array[Byte](size)
val values = new Array[EvaluatedValue[_ <: SType]](size)
var maxKey: Byte = -1
cfor(0)(_ < size, _ + 1) { i =>
val key = r.getByte()
if (key < 0) {
error(s"Negative key in context extension: $key")
}
if (key > maxKey) {
maxKey = key
}
keys(i) = key
values(i) = r.getValue().asInstanceOf[EvaluatedValue[_ <: SType]]
}
ContextExtension(SigmaMap(keys, values, maxKey))
}
}
}
}
Loading
Loading