Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SigmaMap implementation #951

Open
wants to merge 18 commits into
base: v5.0.15-RC
Choose a base branch
from
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