Created
November 12, 2015 16:33
-
-
Save pchiusano/a5603289a61ea3bd27df to your computer and use it in GitHub Desktop.
Simple purely functional map that efficiently tracks insertion order
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* A Map which tracks the insertion order of entries, so that entries may be | |
* traversed in the order they were inserted. Uses just two purely functional | |
* maps. | |
*/ | |
import scala.collection.immutable.LongMap | |
class LinkedMap[K,V]( | |
entries: Map[K,(V,Long)], | |
insertionOrder: LongMap[K], | |
nextID: Long) { | |
def get(k: K): Option[V] = entries.get(k).map(_._1) | |
/** Insert an entry into this map, overriding any previous entry for the given `K`. */ | |
def updated(k: K, v: V): LinkedMap[K,V] = | |
new LinkedMap(entries.updated(k, (v,nextID)), insertionOrder.updated(nextID, k), nextID+1) | |
/** Remove this key from this map. */ | |
def -(k: K) = new LinkedMap( | |
entries - k, | |
entries.get(k).map { case (_,id) => insertionOrder - id }.getOrElse(insertionOrder), | |
nextID) | |
/** The keys of this map, in the order they were added. */ | |
def keys: Iterable[K] = insertionOrder.values | |
/** The values in this map, in the order they were added. */ | |
def values: Iterable[V] = keys.flatMap(k => entries.get(k).toList.map(_._1)) | |
} | |
object LinkedMap { | |
def empty[K,V] = new LinkedMap[K,V](Map.empty, LongMap.empty, 0) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Why not make ctor private and
LinkedMap
a case class?