
scala.reactive.container.ReactHashSet.scala Maven / Gradle / Ivy
The newest version!
package scala.reactive
package container
import scala.reflect.ClassTag
class ReactHashSet[@spec(Int, Long, Double) T](
implicit val arrayable: Arrayable[T]
) extends ReactContainer[T] with ReactBuilder[T, ReactHashSet[T]] {
self =>
private var table: Array[T] = null
private var sz = 0
private[reactive] var insertsEmitter: Reactive.Emitter[T] = null
private[reactive] var removesEmitter: Reactive.Emitter[T] = null
protected def init(ee: Arrayable[T]) {
table = arrayable.newArray(ReactHashSet.initSize)
insertsEmitter = new Reactive.Emitter[T]
removesEmitter = new Reactive.Emitter[T]
}
init(arrayable)
def inserts: Reactive[T] = insertsEmitter
def removes: Reactive[T] = removesEmitter
def builder: ReactBuilder[T, ReactHashSet[T]] = this
def +=(elem: T) = {
self add elem
}
def -=(elem: T) = {
self remove elem
}
def container = self
val react = new ReactHashSet.Lifted[T](this)
def foreach(f: T => Unit) {
var i = 0
while (i < table.length) {
val k = table(i)
if (k != arrayable.nil) {
f(k)
}
i += 1
}
}
private def lookup(k: T): Boolean = {
var pos = index(k)
val nil = arrayable.nil
var curr = table(pos)
while (curr != nil && curr != k) {
pos = (pos + 1) % table.length
curr = table(pos)
}
if (curr == nil) false
else true
}
private def insert(k: T, notify: Boolean = true): Boolean = {
checkResize()
var pos = index(k)
val nil = arrayable.nil
var curr = table(pos)
assert(k != nil)
while (curr != nil && curr != k) {
pos = (pos + 1) % table.length
curr = table(pos)
}
table(pos) = k
val added = curr == nil
if (added) sz += 1
else removesEmitter += k
if (notify) insertsEmitter += k
added
}
private def delete(k: T): Boolean = {
var pos = index(k)
val nil = arrayable.nil
var curr = table(pos)
while (curr != nil && curr != k) {
pos = (pos + 1) % table.length
curr = table(pos)
}
if (curr == nil) false
else {
var h0 = pos
var h1 = (h0 + 1) % table.length
while (table(h1) != nil) {
val h2 = index(table(h1))
if (h2 != h1 && before(h2, h0)) {
table(h0) = table(h1)
h0 = h1
}
h1 = (h1 + 1) % table.length
}
table(h0) = arrayable.nil
sz -= 1
removesEmitter += k
true
}
}
private def checkResize() {
if (sz * 1000 / ReactHashSet.loadFactor > table.length) {
val otable = table
val ncapacity = table.length * 2
table = arrayable.newArray(ncapacity)
sz = 0
var pos = 0
val nil = arrayable.nil
while (pos < otable.length) {
val curr = otable(pos)
if (curr != nil) {
insert(curr, false)
}
pos += 1
}
}
}
private def before(i: Int, j: Int) = {
val d = table.length >> 1
if (i <= j) j - i < d
else i - j > d
}
private def index(k: T): Int = {
val hc = k.##
math.abs(scala.util.hashing.byteswap32(hc)) % table.length
}
def apply(key: T): Boolean = lookup(key)
def contains(key: T): Boolean = lookup(key)
def add(key: T): Boolean = insert(key)
def remove(key: T): Boolean = delete(key)
def clear() {
var pos = 0
val nil = arrayable.nil
while (pos < table.length) {
val elem = table(pos)
if (elem != nil) {
table(pos) = arrayable.nil
sz -= 1
removesEmitter += elem
}
pos += 1
}
}
def size: Int = sz
}
object ReactHashSet {
def apply[@spec(Int, Long, Double) T: Arrayable]() = new ReactHashSet[T]
class Lifted[@spec(Int, Long, Double) T](val container: ReactHashSet[T]) extends ReactContainer.Lifted[T]
val initSize = 16
val loadFactor = 450
implicit def factory[@spec(Int, Long, Double) T: Arrayable] = new ReactBuilder.Factory[T, ReactHashSet[T]] {
def apply() = ReactHashSet[T]
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy