summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/library/scala/collection/mutable/FlatHashTable.scala15
-rw-r--r--test/files/run/bug978.scala38
2 files changed, 51 insertions, 2 deletions
diff --git a/src/library/scala/collection/mutable/FlatHashTable.scala b/src/library/scala/collection/mutable/FlatHashTable.scala
index 0c9ec9c4d6..aeab7cd2ea 100644
--- a/src/library/scala/collection/mutable/FlatHashTable.scala
+++ b/src/library/scala/collection/mutable/FlatHashTable.scala
@@ -18,6 +18,8 @@ trait FlatHashTable[A] {
*/
protected def initialSize: Int = 16
+ private final val tableDebug = false
+
/** The actual hash table.
*/
protected var table: Array[AnyRef] =
@@ -69,8 +71,9 @@ trait FlatHashTable[A] {
}
def removeEntry(elem: A) {
+ checkConsistent()
def precedes(i: int, j: int) = {
- val d = table.length >> 2
+ val d = table.length >> 1
if (i <= j) j - i < d
else i - j > d
}
@@ -82,7 +85,7 @@ trait FlatHashTable[A] {
var h1 = (h0 + 1) % table.length
while (null != table(h1)) {
val h2 = index(elemHashCode(table(h1).asInstanceOf[A]))
- //Console.println("shift at "+h1+":"+table(h1)+" with h2 = "+h2+"?")
+ //Console.println("shift at "+h1+":"+table(h1)+" with h2 = "+h2+"? "+(h2 != h1)+precedes(h2, h0)+table.length)
if (h2 != h1 && precedes(h2, h0)) {
//Console.println("shift "+h1+" to "+h0+"!")
table(h0) = table(h1)
@@ -92,6 +95,7 @@ trait FlatHashTable[A] {
}
table(h0) = null
tableSize = tableSize - 1
+ if (tableDebug) checkConsistent()
return
}
h = (h + 1) % table.length
@@ -121,6 +125,13 @@ trait FlatHashTable[A] {
if (null != entry) addEntry(entry.asInstanceOf[A])
i = i + 1
}
+ if (tableDebug) checkConsistent()
+ }
+
+ private def checkConsistent() {
+ for (val i <- 0 until table.length)
+ if (table(i) != null && !containsEntry(table(i).asInstanceOf[A]))
+ assert(false, i+" "+table(i)+" "+table.toString)
}
protected def elemHashCode(elem: A) = elem.hashCode()
diff --git a/test/files/run/bug978.scala b/test/files/run/bug978.scala
new file mode 100644
index 0000000000..72dfdbae0a
--- /dev/null
+++ b/test/files/run/bug978.scala
@@ -0,0 +1,38 @@
+class Foo(val n: Int) {
+ override def hashCode = n % 2 // pretty bad hash
+ override def equals(other: Any): Boolean = other match {
+ case f: Foo => f.n == n
+ case _ => false
+ }
+
+ override def toString = "" + n
+}
+
+object Test extends Application {
+ val set = new collection.mutable.HashSet[Foo]
+// val set = new collection.jcl.HashSet[Foo]
+
+ val max = 200
+ for (val x <- 1 to max)
+ set += new Foo(x)
+
+ testRemove(2)
+ testExists(2)
+
+ def testRemove(m: Int) {
+ for (val x <- 1 to max; x % m == 0) {
+ val f = new Foo(x)
+ set -= f
+ assert(!(set contains f))
+ testExists(m)
+ }
+ }
+
+ def testExists(m: Int) {
+ for (val x <- 1 to max; x % m == 1) {
+ val f = new Foo(x)
+ assert(set contains f, "For element: " + f + " set: " + set)
+ }
+ }
+
+}