1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
|
package forge
import ammonite.ops.ls
import play.api.libs.json.{Format, Json}
import scala.collection.mutable
object PathRef{
implicit def jsonFormatter: Format[PathRef] = Json.format
}
case class PathRef(path: ammonite.ops.Path){
override def hashCode() = {
if (!path.isDir) path.hashCode() + path.mtime.toMillis.toInt
else ls.rec.iter(path)
.filter(_.isFile)
.map(x => x.toString.hashCode + x.mtime.toMillis)
.sum
.toInt
}
}
trait MultiBiMap[K, V]{
def containsValue(v: V): Boolean
def lookupKey(k: K): OSet[V]
def lookupValue(v: V): K
def lookupValueOpt(v: V): Option[K]
def add(k: K, v: V): Unit
def removeAll(k: K): OSet[V]
def addAll(k: K, vs: TraversableOnce[V]): Unit
def keys(): Iterator[K]
def values(): Iterator[OSet[V]]
}
class MutableMultiBiMap[K, V]() extends MultiBiMap[K, V]{
private[this] val valueToKey = mutable.LinkedHashMap.empty[V, K]
private[this] val keyToValues = mutable.LinkedHashMap.empty[K, MutableOSet[V]]
def containsValue(v: V) = valueToKey.contains(v)
def lookupKey(k: K) = keyToValues(k)
def lookupValue(v: V) = valueToKey(v)
def lookupValueOpt(v: V) = valueToKey.get(v)
def add(k: K, v: V): Unit = {
valueToKey(v) = k
keyToValues.getOrElseUpdate(k, new MutableOSet[V]()).append(v)
}
def removeAll(k: K): OSet[V] = keyToValues.get(k) match {
case None => OSet()
case Some(vs) =>
vs.foreach(valueToKey.remove)
keyToValues.remove(k)
vs
}
def addAll(k: K, vs: TraversableOnce[V]): Unit = vs.foreach(this.add(k, _))
def keys() = keyToValues.keysIterator
def values() = keyToValues.valuesIterator
}
/**
* 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]
def collect[T](f: PartialFunction[V, T]): OSet[T]
def zipWithIndex: OSet[(V, Int)]
def reverse: OSet[V]
}
object OSet{
def apply[V](items: V*) = from(items)
def from[V](items: TraversableOnce[V]): OSet[V] = {
val set = new MutableOSet[V]()
items.foreach(set.append)
set
}
}
class MutableOSet[V]() 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 {
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
}
def collect[T](f: PartialFunction[V, T]) = this.filter(f.isDefinedAt).map(x => f(x))
def zipWithIndex = {
var i = 0
this.map{ x =>
i += 1
(x, i-1)
}
}
def reverse = OSet.from(items.reverseIterator)
// 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(", ", ", ")")
}
|