diff options
author | Li Haoyi <haoyi.sg@gmail.com> | 2017-10-27 08:15:01 -0700 |
---|---|---|
committer | Li Haoyi <haoyi.sg@gmail.com> | 2017-10-27 08:15:01 -0700 |
commit | f53db8482c86f30c917d16b6312ad4804b37f2df (patch) | |
tree | 8758d12808473a6f77e3465243ee848d55272e75 /src/main/scala/forge/Util.scala | |
parent | afd5de935cb11394848c5040909f2f02fc26335f (diff) | |
download | mill-f53db8482c86f30c917d16b6312ad4804b37f2df.tar.gz mill-f53db8482c86f30c917d16b6312ad4804b37f2df.tar.bz2 mill-f53db8482c86f30c917d16b6312ad4804b37f2df.zip |
Migrate everything which shouldn't have duplicates over to a new `OSet` data structure
Diffstat (limited to 'src/main/scala/forge/Util.scala')
-rw-r--r-- | src/main/scala/forge/Util.scala | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/src/main/scala/forge/Util.scala b/src/main/scala/forge/Util.scala index 15d3e176..e558e975 100644 --- a/src/main/scala/forge/Util.scala +++ b/src/main/scala/forge/Util.scala @@ -32,6 +32,84 @@ class MultiBiMap[K, V](){ keyToValues(k) = vs ++: keyToValues.getOrElse(k, Nil) } } + +/** + * A collection with enforced uniqueness, fast contains and deterministic + * ordering. When a duplicate happens, it can be configured to either remove + * it automatically or to throw an exception and fail loudly + */ +trait OSet[V] extends TraversableOnce[V]{ + def contains(v: V): Boolean + def items: IndexedSeq[V] + def flatMap[T](f: V => TraversableOnce[T]): OSet[T] + def map[T](f: V => T): OSet[T] + def filter(f: V => Boolean): OSet[V] + + +} +object OSet{ + def apply[V](items: V*) = from(items) + def dedup[V](items: V*) = from(items, dedup = true) + + def from[V](items: TraversableOnce[V], dedup: Boolean = false): OSet[V] = { + val set = new MutableOSet[V](dedup) + items.foreach(set.append) + set + } +} +class MutableOSet[V](dedup: Boolean = false) extends OSet[V]{ + private[this] val items0 = mutable.ArrayBuffer.empty[V] + private[this] val set0 = mutable.Set.empty[V] + def contains(v: V) = set0.contains(v) + def append(v: V) = if (!contains(v)){ + set0.add(v) + items0.append(v) + }else if (!dedup) { + throw new Exception("Duplicated item inserted into OrderedSet: " + v) + } + def appendAll(vs: Seq[V]) = vs.foreach(append) + def items: IndexedSeq[V] = items0 + def set: collection.Set[V] = set0 + + def map[T](f: V => T): OSet[T] = { + val output = new MutableOSet[T] + for(i <- items) output.append(f(i)) + output + } + def flatMap[T](f: V => TraversableOnce[T]): OSet[T] = { + val output = new MutableOSet[T] + for(i <- items) for(i0 <- f(i)) output.append(i0) + output + } + def filter(f: V => Boolean): OSet[V] = { + val output = new MutableOSet[V] + for(i <- items) if (f(i)) output.append(i) + output + } + + // Members declared in scala.collection.GenTraversableOnce + def isTraversableAgain: Boolean = items.isTraversableAgain + def toIterator: Iterator[V] = items.toIterator + def toStream: Stream[V] = items.toStream + + // Members declared in scala.collection.TraversableOnce + def copyToArray[B >: V](xs: Array[B],start: Int,len: Int): Unit = items.copyToArray(xs, start, len) + def exists(p: V => Boolean): Boolean = items.exists(p) + def find(p: V => Boolean): Option[V] = items.find(p) + def forall(p: V => Boolean): Boolean = items.forall(p) + def foreach[U](f: V => U): Unit = items.foreach(f) + def hasDefiniteSize: Boolean = items.hasDefiniteSize + def isEmpty: Boolean = items.isEmpty + def seq: scala.collection.TraversableOnce[V] = items + def toTraversable: Traversable[V] = items + + override def hashCode() = items.hashCode() + override def equals(other: Any) = other match{ + case s: OSet[_] => items.equals(s.items) + case _ => super.equals(other) + } + override def toString = items.mkString("OSet(", ", ", ")") +} object Util{ def compileAll(sources: Target[Seq[jnio.Path]]) (implicit defCtx: DefCtx) = { |