cleanup InsertOrdMap (#3466)

* cleanup InsertOrdMap
This commit is contained in:
Remy 2019-11-14 16:27:21 +01:00 committed by GitHub
parent 7744b886dd
commit b7e2c17863
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 27 additions and 46 deletions

View File

@ -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: _*))
} }

View File

@ -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")
} }
} }
} }