mirror of
https://github.com/digital-asset/daml.git
synced 2024-09-20 09:17:43 +03:00
parent
7744b886dd
commit
b7e2c17863
@ -3,6 +3,9 @@
|
|||||||
|
|
||||||
package com.digitalasset.daml.lf.data
|
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.
|
* Insert-ordered Map (like ListMap), but with efficient lookups.
|
||||||
*
|
*
|
||||||
@ -12,57 +15,36 @@ package com.digitalasset.daml.lf.data
|
|||||||
* insert: O(1)
|
* insert: O(1)
|
||||||
* remove: O(n)
|
* 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] {
|
override def size: Int = hashMap.size
|
||||||
def _keys: Queue[K]
|
|
||||||
def _hashMap: Map[K, V]
|
|
||||||
|
|
||||||
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)] =
|
override def +[V2 >: Value](kv: (Key, V2)): InsertOrdMap[Key, V2] =
|
||||||
_keys.map(k => (k, _hashMap(k))).reverse.iterator
|
if (hashMap.contains(kv._1))
|
||||||
|
new InsertOrdMap(keys, hashMap + kv)
|
||||||
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
|
|
||||||
)
|
|
||||||
else
|
else
|
||||||
NonEmptyInsertOrdMap(
|
new InsertOrdMap(keys :+ kv._1, hashMap + kv)
|
||||||
kv._1 +: _keys,
|
|
||||||
_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 {
|
object InsertOrdMap {
|
||||||
def empty[K, V] = EmptyInsertOrdMap.asInstanceOf[InsertOrdMap[K, V]]
|
|
||||||
|
|
||||||
def fromMap[K, V](m: Map[K, V]): InsertOrdMap[K, V] =
|
private val Empty: InsertOrdMap[Unit, Nothing] = new InsertOrdMap(Queue.empty, HashMap.empty)
|
||||||
NonEmptyInsertOrdMap(Queue(m.keys.toSeq: _*), m)
|
|
||||||
|
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 {
|
"toSeq" should {
|
||||||
"preserve order" in {
|
"preserve order" in {
|
||||||
(InsertOrdMap.empty + (1 -> "a") + (2 -> "b")).toSeq shouldEqual Seq(1 -> "a", 2 -> "b")
|
(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")
|
(InsertOrdMap.empty + (2 -> "b") + (1 -> "a")).toSeq shouldEqual Seq(2 -> "b", 1 -> "a")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"fromSeq" should {
|
"apply" should {
|
||||||
"preserve order" in {
|
"preserve order" in {
|
||||||
InsertOrdMap.fromSeq(Seq(1 -> "a", 2 -> "b")).toSeq shouldEqual Seq(1 -> "a", 2 -> "b")
|
InsertOrdMap(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(2 -> "b", 1 -> "a").toSeq shouldEqual Seq(2 -> "b", 1 -> "a")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user