mirror of
https://github.com/digital-asset/daml.git
synced 2024-09-20 01:07:18 +03:00
parent
7744b886dd
commit
b7e2c17863
@ -3,6 +3,9 @@
|
||||
|
||||
package com.digitalasset.daml.lf.data
|
||||
|
||||
import scala.collection.breakOut
|
||||
import scala.collection.immutable.{HashMap, Map, Queue}
|
||||
|
||||
/**
|
||||
* Insert-ordered Map (like ListMap), but with efficient lookups.
|
||||
*
|
||||
@ -12,57 +15,36 @@ package com.digitalasset.daml.lf.data
|
||||
* insert: O(1)
|
||||
* remove: O(n)
|
||||
*/
|
||||
import scala.collection.immutable.{HashMap, Map, Queue}
|
||||
final class InsertOrdMap[Key, +Value] private (
|
||||
override val keys: Queue[Key],
|
||||
hashMap: HashMap[Key, Value]
|
||||
) extends Map[Key, Value] {
|
||||
|
||||
sealed abstract class InsertOrdMap[K, +V] extends Map[K, V] {
|
||||
def _keys: Queue[K]
|
||||
def _hashMap: Map[K, V]
|
||||
override def size: Int = hashMap.size
|
||||
|
||||
override def empty = InsertOrdMap.empty
|
||||
override def iterator: Iterator[(Key, Value)] =
|
||||
keys.iterator.map(k => (k, hashMap(k)))
|
||||
|
||||
override def size: Int = _hashMap.size
|
||||
override def get(key: Key): Option[Value] = hashMap.get(key)
|
||||
|
||||
def iterator: Iterator[(K, V)] =
|
||||
_keys.map(k => (k, _hashMap(k))).reverse.iterator
|
||||
|
||||
def get(key: K): Option[V] = _hashMap.get(key)
|
||||
|
||||
def +[V2 >: V](kv: (K, V2)): InsertOrdMap[K, V2] =
|
||||
if (_hashMap.contains(kv._1))
|
||||
NonEmptyInsertOrdMap(
|
||||
_keys,
|
||||
_hashMap + kv
|
||||
)
|
||||
override def +[V2 >: Value](kv: (Key, V2)): InsertOrdMap[Key, V2] =
|
||||
if (hashMap.contains(kv._1))
|
||||
new InsertOrdMap(keys, hashMap + kv)
|
||||
else
|
||||
NonEmptyInsertOrdMap(
|
||||
kv._1 +: _keys,
|
||||
_hashMap + kv
|
||||
)
|
||||
new InsertOrdMap(keys :+ kv._1, hashMap + kv)
|
||||
|
||||
override def -(k: Key): InsertOrdMap[Key, Value] =
|
||||
new InsertOrdMap(keys.filter(_ != k), hashMap - k)
|
||||
|
||||
def -(k: K): InsertOrdMap[K, V] =
|
||||
NonEmptyInsertOrdMap(
|
||||
_keys.filter(k2 => k != k2),
|
||||
_hashMap - k
|
||||
)
|
||||
}
|
||||
|
||||
@SuppressWarnings(Array("org.wartremover.warts.Any"))
|
||||
final case object EmptyInsertOrdMap extends InsertOrdMap[Any, Nothing] {
|
||||
override def _keys = Queue[Any]()
|
||||
override def _hashMap = HashMap[Any, Nothing]()
|
||||
}
|
||||
|
||||
final case class NonEmptyInsertOrdMap[K, V](
|
||||
override val _keys: Queue[K],
|
||||
override val _hashMap: Map[K, V])
|
||||
extends InsertOrdMap[K, V]
|
||||
|
||||
object InsertOrdMap {
|
||||
def empty[K, V] = EmptyInsertOrdMap.asInstanceOf[InsertOrdMap[K, V]]
|
||||
|
||||
def fromMap[K, V](m: Map[K, V]): InsertOrdMap[K, V] =
|
||||
NonEmptyInsertOrdMap(Queue(m.keys.toSeq: _*), m)
|
||||
private val Empty: InsertOrdMap[Unit, Nothing] = new InsertOrdMap(Queue.empty, HashMap.empty)
|
||||
|
||||
def empty[K, V]: InsertOrdMap[K, V] = Empty.asInstanceOf[InsertOrdMap[K, V]]
|
||||
|
||||
def apply[K, V](entries: (K, V)*): InsertOrdMap[K, V] =
|
||||
new InsertOrdMap(entries.map(_._1)(breakOut), HashMap(entries: _*))
|
||||
|
||||
def fromSeq[K, V](s: Seq[(K, V)]): InsertOrdMap[K, V] =
|
||||
NonEmptyInsertOrdMap(Queue(s.reverse.map(_._1): _*), HashMap(s: _*))
|
||||
}
|
||||
|
@ -9,15 +9,14 @@ class InsertOrdMapTest extends WordSpec with Matchers {
|
||||
"toSeq" should {
|
||||
"preserve order" in {
|
||||
(InsertOrdMap.empty + (1 -> "a") + (2 -> "b")).toSeq shouldEqual Seq(1 -> "a", 2 -> "b")
|
||||
|
||||
(InsertOrdMap.empty + (2 -> "b") + (1 -> "a")).toSeq shouldEqual Seq(2 -> "b", 1 -> "a")
|
||||
}
|
||||
}
|
||||
|
||||
"fromSeq" should {
|
||||
"apply" should {
|
||||
"preserve order" in {
|
||||
InsertOrdMap.fromSeq(Seq(1 -> "a", 2 -> "b")).toSeq shouldEqual Seq(1 -> "a", 2 -> "b")
|
||||
InsertOrdMap.fromSeq(Seq(2 -> "b", 1 -> "a")).toSeq shouldEqual Seq(2 -> "b", 1 -> "a")
|
||||
InsertOrdMap(1 -> "a", 2 -> "b").toSeq shouldEqual Seq(1 -> "a", 2 -> "b")
|
||||
InsertOrdMap(2 -> "b", 1 -> "a").toSeq shouldEqual Seq(2 -> "b", 1 -> "a")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user